home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / space / software / unix / xanim / xanim_ct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-04  |  12.3 KB  |  468 lines

  1.  
  2.  
  3. /*
  4.  * xanim_act.c
  5.  *
  6.  * Copyright (C) 1990,1991,1992 by Mark Podlipec. 
  7.  * All rights reserved.
  8.  *
  9.  * This software may be freely copied, modified and redistributed
  10.  * without fee provided that this copyright notice is preserved 
  11.  * intact on all copies and modified copies.
  12.  * 
  13.  * There is no warranty or other guarantee of fitness of this software.
  14.  * It is provided solely "as is". The author(s) disclaim(s) all
  15.  * responsibility and liability with respect to this software's usage
  16.  * or its effect upon hardware or computer systems.
  17.  *
  18.  */
  19.  
  20. #include "xanim.h"
  21. #include "xanim_act.h"
  22.  
  23. int ColorComp();
  24. void ACT_Setup_CMAP();
  25. void ACT_Setup_Mapped();
  26. void ACT_Setup_Packed();
  27. void ACT_Get_Next_Action();
  28. void qsort();
  29.  
  30. ACTION *act_first_cmap = 0;
  31. ACTION *act_cur_cmap = 0;
  32. static LONG cur_index;
  33.  
  34. /*
  35.  *
  36.  */
  37. int ColorComp(c1,c2)
  38. ColorReg *c1,*c2;
  39. {
  40.  long val1,val2;
  41.  
  42.   val1 = (3 * c1->red) + (4 * c1->green) + (2 * c1->blue);
  43.   val2 = (3 * c2->red) + (4 * c2->green) + (2 * c2->blue);
  44.   if (val1 != val2) return( val2 - val1 );
  45.   else if (c1->green != c2->green) return( c2->green - c1->green );
  46.   else if (c1->red   != c2->red  ) return( c2->red   - c1->red   );
  47.   else return( c2->blue - c1->blue );
  48. }
  49.  
  50. /*
  51.  *
  52.  */
  53. int CMAP_Find_Closest(r,g,b,t_cmap,csize)
  54. ULONG r,g,b;
  55. ColorReg *t_cmap;
  56. ULONG csize;
  57. {
  58.   register ULONG i,min_diff,diff,tmp;
  59.   register int cmap_entry;
  60.  
  61.   diff = min_diff = 32 * 256 * 256 * 2;
  62.   i = csize;
  63.   while( (i > 0) && (diff != 0) )
  64.   {
  65.     i--;
  66.     tmp = r - (ULONG)(t_cmap[i].red);   tmp *= tmp;  diff  = 11 * tmp;
  67.     tmp = g - (ULONG)(t_cmap[i].green); tmp *= tmp;  diff += 16 * tmp;
  68.     tmp = b - (ULONG)(t_cmap[i].blue);  tmp *= tmp;  diff +=  5 * tmp;
  69.  
  70.     if (diff < min_diff) {min_diff = diff; cmap_entry = i;}
  71.   }
  72.   return(cmap_entry);
  73. }
  74.  
  75. /*
  76.  *
  77.  */
  78. int CMAP_Find_Exact(r,g,b,cmap,csize)
  79. ULONG r,g,b;
  80. ColorReg *cmap;
  81. ULONG csize;
  82. {
  83.   register int i,match;
  84.  
  85.   match = -1;
  86.   i = csize;
  87.   while( (i > 0) && (match < 0) )
  88.   {
  89.     i--;
  90.     if (   (r == (ULONG)(cmap[i].red))
  91.         && (g == (ULONG)(cmap[i].green))
  92.         && (b == (ULONG)(cmap[i].blue))  ) match = i;
  93.   }
  94.   return(match);
  95. }
  96.  
  97. /*
  98.  *
  99.  */
  100. void
  101. ACT_Setup_CMAP(new_cmap,csize,offset,cmap_function)
  102. ColorReg new_cmap[];
  103. ULONG csize,*offset,cmap_function;
  104. {
  105.   ACTION *act;
  106.   ColorReg *act_cmap;
  107.   CMAP_HDR *cmap_hdr;
  108.   LONG i,off,new_cmap_flag;
  109.  
  110.   if (   (x11_display_type == TRUE_COLOR)
  111.       || (x11_cmap_flag == FALSE) )
  112.   {
  113.     act = &action[action_cnt];
  114.     action_cnt++;
  115.     act->type = ACT_CMAP;
  116.     act->time = 0;
  117.     cmap_hdr = (CMAP_HDR *)
  118.                  malloc( csize * sizeof(ColorReg) + sizeof(CMAP_HDR));
  119.     if (cmap_hdr == 0) TheEnd1("ACT_Setup_CMAP: malloc failed\n");
  120.     act->data = (UBYTE *)cmap_hdr;
  121.     act_cmap = (ColorReg *)cmap_hdr->data;
  122.     cmap_hdr->cmap_size = csize;
  123.  
  124.     for(i=0; i<csize; i++)
  125.     {
  126.       act_cmap[i].red   = new_cmap[i].red;
  127.       act_cmap[i].green = new_cmap[i].green;
  128.       act_cmap[i].blue  = new_cmap[i].blue;
  129.       if ( (x11_display_type == TRUE_COLOR) && (anm_map_flag == TRUE) )
  130.          act_cmap[i].map = new_cmap[i].map = X11_Get_True_Color(
  131.          new_cmap[i].red, new_cmap[i].green, new_cmap[i].blue, 8);
  132.       else act_cmap[i].map = new_cmap[i].map = i;
  133.     }
  134.     return;
  135.   }
  136.  
  137.   new_cmap_flag = TRUE;
  138.   if (   (cmap_function & CMAP_ALLOW_REMAP) 
  139.       && (cmap_try_to_1st == TRUE) 
  140.       && (act_first_cmap != 0) )
  141.   {
  142.     LONG j,match;
  143.  
  144.     DEBUG_LEVEL1 fprintf(stderr,"CMAP: <%ld> remapping %ld\n",cur_index,csize);
  145.     new_cmap_flag = FALSE;
  146.  
  147.     cmap_hdr = (CMAP_HDR *) act_cur_cmap->data;
  148.     act_cmap = (ColorReg *) cmap_hdr->data;
  149.  
  150.     for(i=0; i<csize; i++)
  151.     {
  152.       match = -i;
  153.       j = 0;
  154.       while( (match < 0) && (j < cur_index) && (j < x11_cmap_size) )
  155.       {
  156.         if (    (new_cmap[i].red   == act_cmap[j].red)
  157.              && (new_cmap[i].green == act_cmap[j].green)
  158.              && (new_cmap[i].blue  == act_cmap[j].blue)
  159.             ) match = new_cmap[i].map = act_cmap[j].map;
  160.         j++;
  161.       }
  162.       if (match < 0)
  163.       {
  164.         if (cur_index < x11_cmap_size) 
  165.         {
  166.           act_cmap[cur_index].red   = new_cmap[i].red; 
  167.           act_cmap[cur_index].green = new_cmap[i].green; 
  168.           act_cmap[cur_index].blue  = new_cmap[i].blue; 
  169.  
  170.           act_cmap[cur_index].map = new_cmap[i].map = 
  171.                 x11_cmap_size - 1 - cur_index;
  172.           cmap_hdr->cmap_size++;
  173.           cur_index++;
  174.         }
  175.         else new_cmap_flag = TRUE;
  176.       }
  177.     } /* end of for i */
  178.     DEBUG_LEVEL1 fprintf(stderr,"<%ld>\n",cur_index);
  179.     if (new_cmap_flag == FALSE) return;
  180.   }
  181.  
  182.   /* If above try_to_fit routine failed or wasn't called then
  183.    * forcibly remap new cmap into old one if appropriate.
  184.    */
  185.   if (   (cmap_function & CMAP_ALLOW_REMAP) 
  186.       && (cmap_map_to_1st == TRUE) 
  187.       && (act_first_cmap != 0) )
  188.   {
  189.     LONG match;
  190.  
  191.     cmap_hdr = (CMAP_HDR *) act_cur_cmap->data;
  192.     act_cmap = (ColorReg *) cmap_hdr->data;
  193.  
  194.     for(i=0; i<csize; i++)
  195.     {
  196.       match = CMAP_Find_Closest( (ULONG)(new_cmap[i].red), 
  197.         (ULONG)(new_cmap[i].green),
  198.               (ULONG)(new_cmap[i].blue),act_cmap,cmap_hdr->cmap_size);
  199.       new_cmap[i].map = act_cmap[match].map;
  200.     }
  201.     return;
  202.   }
  203.  
  204.   /* Create a new cmap and CMAP action
  205.    */
  206.   if (   (new_cmap_flag == TRUE)
  207.       || (act_first_cmap == 0) )
  208.   {
  209.    int *remap;
  210.  
  211.     DEBUG_LEVEL1 fprintf(stderr,"CMAP: new %ld\n",csize);
  212.     act = &action[action_cnt]; action_cnt++;
  213.  
  214.     remap = 0;
  215.     act_cur_cmap = act;
  216.     if (act_first_cmap == 0) act_first_cmap = act_cur_cmap;
  217.  
  218.     act->type = ACT_CMAP;
  219.     act->time = 0;
  220.     cmap_hdr = (CMAP_HDR *)
  221.                  malloc( x11_cmap_size * sizeof(ColorReg) + sizeof(CMAP_HDR));
  222.     if (cmap_hdr == 0) TheEnd1("ACT_Setup_CMAP: malloc failed\n");
  223.     act->data = (UBYTE *)cmap_hdr;
  224.     act_cmap = (ColorReg *)cmap_hdr->data;
  225.     cmap_hdr->cmap_size = csize;
  226.  
  227.     remap = (int *) malloc( csize * sizeof( int ) );
  228.     if (remap == 0) TheEnd1("CMAP_ACT: malloc error\n");
  229.     for(i=0; i<csize; i++) remap[i] = i;
  230.     for(i=0; i<csize; i++) new_cmap[i].map = i;
  231.  
  232.     if (   (cmap_function & CMAP_ALLOW_REMAP)  /* allow remapping */ 
  233.     && (cmap_luma_sort == TRUE) )    /* qsort on */
  234.     {
  235.       qsort( (char *)new_cmap, csize, sizeof(ColorReg), ColorComp);
  236.       for(i=0; i<csize; i++) remap[ new_cmap[i].map ] = i;
  237.     }
  238.  
  239.    /* NOTE: NEED TO DO BETTER TO PRESERVE ORIGINAL CMAP */
  240.     for(cur_index = 0; cur_index < csize; cur_index++)
  241.     {
  242.       ULONG k;
  243.     /* need to put RGB back in original order */
  244.       k = new_cmap[cur_index].map;
  245.       cmap[k].red   = act_cmap[k].red   = new_cmap[cur_index].red;
  246.       cmap[k].green = act_cmap[k].green = new_cmap[cur_index].green;
  247.       cmap[k].blue  = act_cmap[k].blue  = new_cmap[cur_index].blue;
  248.     }
  249.  
  250.     for(cur_index = 0; cur_index < csize; cur_index++)
  251.     {
  252.       new_cmap[cur_index].red   = act_cmap[cur_index].red;
  253.       new_cmap[cur_index].green = act_cmap[cur_index].green;
  254.       new_cmap[cur_index].blue  = act_cmap[cur_index].blue;
  255.       if (cmap_function & CMAP_ALLOW_REMAP)
  256.       {
  257.          act_cmap[cur_index].map = cmap[cur_index].map =
  258.      new_cmap[cur_index].map =
  259.              x11_cmap_size - 1 - remap[cur_index];
  260.       } 
  261.       else
  262.          cmap[cur_index].map = act_cmap[cur_index].map 
  263.                    = new_cmap[cur_index].map = cur_index;
  264.     }
  265.     if (remap != 0) free(remap);
  266.     cur_index = csize;
  267.   } /* end of new action */
  268. }
  269.  
  270. /*
  271.  *
  272.  */
  273. void
  274. ACT_Get_Next_Action(act)
  275. ACTION **act;
  276. {
  277.  *act = &action[action_cnt];
  278.  action_cnt++;
  279.  (*act)->data = 0;
  280. }
  281.  
  282. /*
  283.  *
  284.  */
  285. void
  286. ACT_Setup_Packed(act,time,xpos,ypos,xsize,ysize,dsize,image_ptr)
  287. ACTION *act;
  288. LONG time;
  289. LONG xpos,ypos;
  290. LONG xsize,ysize,dsize;
  291. UBYTE *image_ptr;
  292. {
  293.   ACT_PACKED_HDR *act_pk_hdr; 
  294.   ULONG pk_size,pk_image_size;
  295.   UBYTE *t_pic;
  296.  
  297.   if (dsize == 3) pk_size = 4;
  298.   else pk_size = dsize;
  299.   pk_image_size = xsize * ysize;
  300.   if (pk_image_size % pk_size) pk_image_size = (pk_image_size/pk_size) + 1;
  301.   else pk_image_size /= pk_size;
  302.  
  303.   act_pk_hdr = (ACT_PACKED_HDR *) malloc( sizeof(ACT_PACKED_HDR) );
  304.   if (act_pk_hdr == 0) TheEnd1("ACT Setup PACKED: can't allocate memory.\n");
  305.  
  306.   UTIL_Pack_Image(act_pk_hdr->data,image_ptr,xsize,ysize,dsize);
  307.   free(image_ptr);
  308.  
  309.   act->type = ACT_PACKED;
  310.   act->time = time;
  311.   act->data = (UBYTE *) act_pk_hdr;
  312.   act_pk_hdr->xpos = xpos;
  313.   act_pk_hdr->ypos = ypos;
  314.   act_pk_hdr->xsize = xsize;
  315.   act_pk_hdr->ysize = ysize;
  316. }
  317.  
  318. /*
  319.  *
  320.  */
  321. void
  322. ACT_Setup_Mapped(act,time,image_ptr,map,map_size,xpos,ypos,xsize,ysize,
  323.         already_mapped,clip_ptr)
  324. ACTION *act;
  325. LONG time;
  326. UBYTE *image_ptr;
  327. ColorReg *map;
  328. LONG map_size;
  329. LONG xpos,ypos,xsize,ysize;
  330. ULONG already_mapped;
  331. UBYTE *clip_ptr;
  332. {
  333.   ULONG line_size;
  334.   ULONG pixmap_type;
  335.   XImage *image;
  336.   UBYTE *t_pic;
  337.  
  338. /*
  339.   if (pack_flag) 
  340.     ACT_Setup_Packed(act,time,image_ptr,map,map_size,xpos,ypos,xsize,ysize);
  341. */
  342.  
  343.   line_size = X11_Get_Line_Size(xsize);
  344.   if (x11_display_type == MONOCHROME)
  345.   {
  346.     pixmap_type = XYPixmap;
  347.     t_pic = (UBYTE *) malloc(ysize * line_size);
  348.     if (t_pic == 0) TheEnd1("X11_Get_Image: t_pic malloc failed.\n");
  349.     if (already_mapped == FALSE)
  350.       UTIL_Mapped_To_Bitmap(t_pic,image_ptr,map,map_size,xsize,ysize,line_size);
  351.     else memcpy((char *)t_pic,(char *)image_ptr,(ysize*line_size) );
  352.     free(image_ptr);
  353.     image_ptr = t_pic;
  354.   }
  355.   else 
  356.   {
  357.     pixmap_type = ZPixmap;
  358.     if ( (x11_display_type == TRUE_COLOR) && (already_mapped == FALSE) )
  359.     {
  360.       t_pic = (UBYTE *) malloc(ysize * line_size);
  361.       if (t_pic == 0) TheEnd1("X11_Get_Image: t_pic malloc failed.\n");
  362.       UTIL_Sub_Mapped_To_True(t_pic,image_ptr,map,xsize,ysize,0,0,xsize);
  363.       free(image_ptr);
  364.       image_ptr = t_pic;
  365.     }
  366.   }
  367.  
  368.   if (anim_flags & ANIM_LACE)
  369.   {
  370.     if ((ypos & 0x01) && (ysize <= 1))  /* if odd single line then NOP */
  371.     {
  372.       free(image_ptr);
  373.       act->type = ACT_NOP;
  374.       act->data = 0;
  375.       return;
  376.     }
  377.     else
  378.     {
  379.       ULONG tmp_ysize;
  380.  
  381.       tmp_ysize = ysize>>1;
  382.       if ( !(ypos & 0x01) && (ysize & 0x01) ) tmp_ysize++;
  383.  
  384.       if (clip_ptr != 0) /* reduce clip in half */
  385.       {
  386.     ULONG tmp_xsize,typos,tysize;
  387.  
  388.         typos = ypos; tysize = ysize;
  389.     tmp_xsize = imagex/8; if (imagex % 8) tmp_xsize++;
  390.         t_pic = (UBYTE *)malloc( tmp_ysize * tmp_xsize );
  391.         if (t_pic == 0) TheEnd1("X11_Get_Image: lace clip malloc failed.\n");
  392.         UTIL_Half_Image_Height(t_pic,clip_ptr,xpos,&typos,
  393.                     xsize,&tysize,tmp_xsize);
  394.         free(clip_ptr);
  395.         clip_ptr = t_pic;
  396.        
  397.       }
  398.  
  399.       t_pic = (UBYTE *)malloc( tmp_ysize * line_size );
  400.       if (t_pic == 0) TheEnd1("X11_Get_Image: lace t_pic malloc failed.\n");
  401.       UTIL_Half_Image_Height(t_pic,image_ptr,xpos,&ypos,
  402.                     xsize,&ysize,line_size);
  403.       free(image_ptr);
  404.       image_ptr = t_pic;
  405.  
  406.     }
  407.   }
  408.  
  409.   image = XCreateImage(theDisp, DefaultVisual(theDisp,DefaultScreen(theDisp)),
  410.     x11_depth,pixmap_type,0,NULL,xsize,ysize,x11_bytes_pixel, line_size);
  411.   if (image == 0) TheEnd1("ACT_Setup_Mapped: can't create Image.\n");
  412.   image->data = (char *)image_ptr;
  413.  
  414.   act->time = time;
  415.  
  416.   if (clip_ptr != 0)
  417.   {
  418.     ACT_CLIP_HDR *act_cp_hdr;
  419.     act_cp_hdr = (ACT_CLIP_HDR *) malloc( sizeof(ACT_CLIP_HDR) );
  420.     if (act_cp_hdr == 0) TheEnd1("ACT_Setup_Mapped: can't malloc for clip.\n");
  421.  
  422.     act->type = ACT_CLIP;
  423.     act->data = (UBYTE *) act_cp_hdr;
  424.     act_cp_hdr->xpos = xpos;
  425.     act_cp_hdr->ypos = ypos;
  426.     act_cp_hdr->xsize = xsize;
  427.     act_cp_hdr->ysize = ysize;
  428.     act_cp_hdr->image = image;
  429.     act_cp_hdr->clip_ptr = clip_ptr;
  430.   }
  431.   else
  432.   if (pixmap_flag == FALSE)
  433.   {
  434.     ACT_IMAGE_HDR *act_im_hdr; 
  435.     act_im_hdr = (ACT_IMAGE_HDR *) malloc( sizeof(ACT_IMAGE_HDR) );
  436.     if (act_im_hdr == 0) TheEnd1("ACT Setup IMAGE: can't allocate memory.\n");
  437.  
  438.     act->type = ACT_IMAGE;
  439.     act->data = (UBYTE *) act_im_hdr;
  440.     act_im_hdr->xpos = xpos;
  441.     act_im_hdr->ypos = ypos;
  442.     act_im_hdr->xsize = xsize;
  443.     act_im_hdr->ysize = ysize;
  444.     act_im_hdr->image = image;
  445.   }
  446.   else
  447.   {
  448.     ACT_PIXMAP_HDR *act_pm_hdr;
  449.     act_pm_hdr = (ACT_PIXMAP_HDR *) malloc( sizeof(ACT_PIXMAP_HDR) );
  450.     if (act_pm_hdr == 0) TheEnd1("ACT_SETUP_PIXMAP: can't allocate memory.\n");
  451.  
  452.     act->type = ACT_PIXMAP;
  453.     act->data = (UBYTE *) act_pm_hdr;
  454.     act_pm_hdr->xpos = xpos;
  455.     act_pm_hdr->ypos = ypos;
  456.     act_pm_hdr->xsize = xsize;
  457.     act_pm_hdr->ysize = ysize;
  458.     act_pm_hdr->pixmap = XCreatePixmap(theDisp,
  459.     DefaultRootWindow(theDisp), xsize, ysize, x11_depth);
  460.     /* NOTE: should make sure CreatePixmap was successful */
  461.     DEBUG_LEVEL1 fprintf(stderr,"PIXMAP pixmap = %lx\n",act_pm_hdr->pixmap);
  462.     XPutImage(theDisp, act_pm_hdr->pixmap, theGC, image, 0,0,0,0,xsize,ysize);
  463.     XDestroyImage(image);
  464.   }
  465.  
  466. }
  467.  
  468.