home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1391 / encode.c next >
C/C++ Source or Header  |  1990-12-28  |  12KB  |  357 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                                                                             %
  4. %                                                                             %
  5. %                                                                             %
  6. %                 EEEEE  N   N   CCCC   OOO   DDDD    EEEEE                   %
  7. %                 E      NN  N  C      O   O  D   D   E                       %
  8. %                 EEE    N N N  C      O   O  D   D   EEES                    %
  9. %                 E      N  NN  C      O   O  D   D   E                       %
  10. %                 EEEEE  N   N   CCCC   OOO   DDDD    EEEEE                   %
  11. %                                                                             %
  12. %                                                                             %
  13. %                  Encode or Decode Color Runlength Packets                   %
  14. %                                                                             %
  15. %                                                                             %
  16. %                                                                             %
  17. %                           Software Design                                   %
  18. %                             John Cristy                                     %
  19. %                            January  1990                                    %
  20. %                                                                             %
  21. %                                                                             %
  22. %  Copyright 1990 E. I. Dupont de Nemours & Company                           %
  23. %                                                                             %
  24. %  Permission to use, copy, modify, distribute, and sell this software and    %
  25. %  its documentation for any purpose is hereby granted without fee,           %
  26. %  provided that the above copyright notice appear in all copies and that     %
  27. %  both that copyright notice and this permission notice appear in            %
  28. %  supporting documentation, and that the name of E. I. Dupont de Nemours     %
  29. %  & Company not be used in advertising or publicity pertaining to            %
  30. %  distribution of the software without specific, written prior               %
  31. %  permission.  E. I. Dupont de Nemours & Company makes no representations    %
  32. %  about the suitability of this software for any purpose.  It is provided    %
  33. %  "as is" without express or implied warranty.                               %
  34. %                                                                             %
  35. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  36. %  to this software, including all implied warranties of merchantability      %
  37. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  38. %  liable for any special, indirect or consequential damages or any           %
  39. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  40. %  in an action of contract, negligence or other tortious action, arising     %
  41. %  out of or in connection with the use or performance of this software.      %
  42. %                                                                             %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. %
  45. %
  46. %
  47. */
  48.  
  49. #include "display.h"
  50.  
  51. /*
  52.   Define declarations.
  53. */
  54. #define MaxChannels  8
  55.  
  56. /*
  57.   Typedef declarations.
  58. */
  59. typedef struct ChannelDescriptor
  60. {
  61.   RunlengthPacket
  62.     color,
  63.     *packet;
  64.  
  65.   unsigned int
  66.     color_count,
  67.     runlength;
  68. } ChannelDescriptor;
  69.  
  70. /*
  71.   Global variables.
  72. */
  73. static ChannelDescriptor
  74.   channels[MaxChannels];
  75.  
  76. /*
  77. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  78. %                                                                             %
  79. %                                                                             %
  80. %                                                                             %
  81. %  I n i t i a l i z e C h a n n e l                                          %
  82. %                                                                             %
  83. %                                                                             %
  84. %                                                                             %
  85. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  86. %
  87. %  Function InitializeChannel allocates a global buffer to help keep track
  88. %  of reading or writing runlength packets into image memory.  An integer
  89. %  value is returned that specifies the channel number to read or write the
  90. %  run-length encoded image.
  91. %
  92. %  The format of the InitializeChannel routine is:
  93. %
  94. %      channel_number=InitializeChannel(image);
  95. %
  96. %  A description of each parameter follows.
  97. %
  98. %    o channel_number:  The InitializeChannel routine returns this integer
  99. %      value.  Use it as the channel parameter when invoking the ReadPacket
  100. %      or WritePacket routines.
  101. %
  102. %    o image:  The address of a byte (8 bits) array of the run-length
  103. %      encoded image.
  104. %
  105. %
  106. */
  107. unsigned int InitializeChannel(image)
  108. RunlengthPacket
  109.   *image;
  110. {
  111.   static unsigned char
  112.     channel_number = 0;
  113.  
  114.   channel_number++;
  115.   channel_number%=MaxChannels;
  116.   channels[channel_number].packet=image;
  117.   channels[channel_number].color_count=image->length+1;
  118.   channels[channel_number].runlength=0;
  119.   return(channel_number);
  120. }
  121.  
  122. /*
  123. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  124. %                                                                             %
  125. %                                                                             %
  126. %                                                                             %
  127. %  R e a d P a c k e t                                                        %
  128. %                                                                             %
  129. %                                                                             %
  130. %                                                                             %
  131. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  132. %
  133. %  Function ReadPacket reads one pixel runlength packet from the image buffer.
  134. %  Pixel packets are read until the max_count have been read or a pixel of
  135. %  another color is encountered.  The integer value returned is the number of
  136. %  pixels read.
  137. %
  138. %  The format of the ReadPacket routine is:
  139. %
  140. %      count=ReadPacket(channel_number,max_count,&red,&green,&blue,&index)
  141. %
  142. %  A description of each parameter follows.
  143. %
  144. %    o count:  The ReadPacket routine returns this integer value.  It is
  145. %      the actual number of contiguous pixels read from image memory of the
  146. %      same red, green, and blue value.
  147. %
  148. %    o channel_number:  An integer value that specifies the channel to
  149. %      read the run-length encoded image.  This value is assigned by the
  150. %      InitializeChannel routine.
  151. %
  152. %    o max_count:  An integer value that is the maximum number of pixels
  153. %      to read from image memory of this combination of red, green, and
  154. %      blue.
  155. %
  156. %    o red:  The address of a byte value representing the measure of the
  157. %      red contribution.
  158. %
  159. %    o green:  The address of a byte value representing the measure of
  160. %      the green contribution.
  161. %
  162. %    o blue:  The address of a byte value representing the measure of the
  163. %      blue contribution.
  164. %
  165. %    o index:  A byte value representing the colormap index of the
  166. %      red, green, and blue contribution.
  167. %
  168. %
  169. */
  170. unsigned int ReadPacket(channel_number,max_count,red,green,blue,index)
  171. register unsigned char
  172.   channel_number;
  173.  
  174. register unsigned int
  175.   max_count;
  176.  
  177. unsigned char
  178.   *red,
  179.   *green,
  180.   *blue;
  181.  
  182. unsigned short
  183.   *index;
  184. {
  185.   register ChannelDescriptor
  186.     *c;
  187.  
  188.   static unsigned int
  189.     number_pixels;
  190.  
  191.   /*
  192.     Read runlength packets until the maximum count or different color.
  193.   */
  194.   c=channels+channel_number;
  195.   while (c->runlength < max_count)
  196.   {
  197.     if (c->color_count == 0)
  198.       {
  199.         /*
  200.           Get next runlength packet.
  201.         */
  202.         c->packet++;
  203.         c->color_count=c->packet->length+1;
  204.       }
  205.     if (c->runlength == 0)
  206.       {
  207.         c->color.red=c->packet->red;
  208.         c->color.green=c->packet->green;
  209.         c->color.blue=c->packet->blue;
  210.         c->color.index=c->packet->index;
  211.         c->runlength=c->color_count;
  212.         c->color_count=0;
  213.       }
  214.     else
  215.       if ((c->color.red == c->packet->red) &&
  216.           (c->color.green == c->packet->green) &&
  217.           (c->color.blue == c->packet->blue))
  218.         {
  219.           c->runlength+=c->color_count;
  220.           c->color_count=0;
  221.         }
  222.       else
  223.         break;
  224.   }
  225.   *red=c->color.red;
  226.   *green=c->color.green;
  227.   *blue=c->color.blue;
  228.   *index=c->color.index;
  229.   number_pixels=Min(c->runlength,max_count);
  230.   c->runlength-=number_pixels;
  231.   return(number_pixels);
  232. }
  233.  
  234. /*
  235. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  236. %                                                                             %
  237. %                                                                             %
  238. %                                                                             %
  239. %  W r i t e P a c k e t                                                      %
  240. %                                                                             %
  241. %                                                                             %
  242. %                                                                             %
  243. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  244. %
  245. %  Function WritePacket encodes RBG values into run-length packets.  The
  246. %  function writes the packets on the specified channel and returns the
  247. %  number of packets encoded.
  248. %
  249. %  The format of the WritePacket routine is:
  250. %
  251. %      number_packets=WritePacket(channel_number,red,green,blue,index,count)
  252. %
  253. %  A description of each parameter follows.
  254. %
  255. %    o number_packets:  An integer value that indicates the number of
  256. %      packets encoded.  Note, this value may be zero is if the current
  257. %      packet is only partially complete.
  258. %
  259. %    o channel_number:  An integer value that specifies the channel to
  260. %      write the run-length encoded image.  This value is assigned by the
  261. %      InitializeChannel routine.
  262. %
  263. %    o red:  A byte value representing the measure of the red
  264. %      contribution.
  265. %
  266. %    o green:  A byte value representing the measure of the green
  267. %      contribution.
  268. %
  269. %    o blue:  A byte value representing the measure of the blue
  270. %      contribution.
  271. %
  272. %    o index:  A byte value representing the colormap index of the 
  273. %      red, green, and blue contribution.
  274. %
  275. %    o count:  An integer value that is the number of pixels to write to
  276. %      image memory of this combination of red, green, and blue.
  277. %
  278. %
  279. */
  280. unsigned int WritePacket(channel_number,red,green,blue,index,count)
  281. register unsigned int
  282.   channel_number;
  283.  
  284. register unsigned char
  285.   red,
  286.   green,
  287.   blue;
  288.  
  289. register unsigned short
  290.   index;
  291.  
  292. register unsigned int
  293.   count;
  294. {
  295.   register ChannelDescriptor
  296.     *c;
  297.  
  298.   register unsigned int
  299.     packets;
  300.  
  301.   packets=0;
  302.   c=channels+channel_number;
  303.   if (c->runlength == 0)
  304.     {
  305.       /*
  306.         Runlength is zero so copy pixels now.
  307.       */
  308.       c->runlength=count;
  309.       c->packet->red=red;
  310.       c->packet->green=green;
  311.       c->packet->blue=blue;
  312.       c->packet->index=index;
  313.       packets++;
  314.     }
  315.   else
  316.     if ((red == c->packet->red) &&
  317.         (green == c->packet->green) &&
  318.         (blue == c->packet->blue))
  319.       c->runlength+=count;
  320.     else
  321.       {
  322.         /*
  323.           Transfer new group of pixels.
  324.         */
  325.         c->packet->length=(c->runlength-1);
  326.         c->packet++;
  327.         c->runlength=count;
  328.         c->packet->red=red;
  329.         c->packet->green=green;
  330.         c->packet->blue=blue;
  331.         c->packet->index=index;
  332.         packets++;
  333.       }
  334.   if (c->runlength > MaxRgb)
  335.     {
  336.       /*
  337.         Split up pixels if the runlength exceeds MaxRgb.
  338.       */
  339.       do
  340.       {
  341.         c->runlength-=(MaxRgb+1);
  342.         c->packet->length=MaxRgb;
  343.         c->packet++;
  344.         c->packet->red=red;
  345.         c->packet->green=green;
  346.         c->packet->blue=blue;
  347.         c->packet->index=index;
  348.         packets++;
  349.       }
  350.       while (c->runlength > MaxRgb);
  351.       if (c->runlength == 0)
  352.         packets--;
  353.   }
  354.   c->packet->length=c->runlength-1;
  355.   return(packets);
  356. }
  357.