home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / ImageMagick / magick / decode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  267.1 KB  |  9,666 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                                                                             %
  4. %                                                                             %
  5. %                                                                             %
  6. %                   DDDD   EEEEE   CCCC   OOO   DDDD   EEEEE                  %
  7. %                   D   D  E      C      O   O  D   D  E                      %
  8. %                   D   D  EEE    C      O   O  D   D  EEE                    %
  9. %                   D   D  E      C      O   O  D   D  E                      %
  10. %                   DDDD   EEEEE   CCCC   OOO   DDDD   EEEEE                  %
  11. %                                                                             %
  12. %                                                                             %
  13. %                    Utility Routines to Read Image Formats                   %
  14. %                                                                             %
  15. %                                                                             %
  16. %                                                                             %
  17. %                             Software Design                                 %
  18. %                               John Cristy                                   %
  19. %                              January 1992                                   %
  20. %                                                                             %
  21. %                                                                             %
  22. %  Copyright 1994 E. I. du Pont 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. du Pont 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. du Pont 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. du Pont 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. du Pont 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 tortuous action, arising     %
  41. %  out of or in connection with the use or performance of this software.      %
  42. %                                                                             %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. %
  45. %  Functions in this library convert to and from `alien' image formats to the
  46. %  MIFF image format.
  47. %
  48. %
  49. */
  50.  
  51. /*
  52.   Include declarations.
  53. */
  54. #include "magick.h"
  55. #include "image.h"
  56. #include "compress.h"
  57. #include "utility.h"
  58. #include "X.h"
  59. #include "XWDFile.h"
  60.  
  61. /*
  62.   Forward declarations.
  63. */
  64. static Image
  65.   *ReadMIFFImage _Declare((ImageInfo *)),
  66.   *ReadPNMImage _Declare((ImageInfo *));
  67.  
  68. /*
  69. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  70. %                                                                             %
  71. %                                                                             %
  72. %                                                                             %
  73. %  R e a d A L P H A I m a g e                                                %
  74. %                                                                             %
  75. %                                                                             %
  76. %                                                                             %
  77. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  78. %
  79. %  Function ReadALPHAImage reads an image of raw alpha bytes and returns it.
  80. %  It allocates the memory necessary for the new Image structure and returns a
  81. %  pointer to the new image.
  82. %
  83. %  The format of the ReadALPHAImage routine is:
  84. %
  85. %      image=ReadALPHAImage(image_info)
  86. %
  87. %  A description of each parameter follows:
  88. %
  89. %    o image:  Function ReadALPHAImage returns a pointer to the image after
  90. %      reading.  A null image is returned if there is a a memory shortage or
  91. %      if the image cannot be read.
  92. %
  93. %    o image_info: Specifies a pointer to an ImageInfo structure.
  94. %
  95. %
  96. */
  97. static Image *ReadALPHAImage(image_info)
  98. ImageInfo
  99.   *image_info;
  100. {
  101.   Image
  102.     *image;
  103.  
  104.   int
  105.     x,
  106.     y;
  107.  
  108.   register int
  109.     i;
  110.  
  111.   register RunlengthPacket
  112.     *q;
  113.  
  114.   register unsigned char
  115.     index,
  116.     *p;
  117.  
  118.   unsigned char
  119.     *alpha_pixels;
  120.  
  121.   unsigned int
  122.     height,
  123.     width;
  124.  
  125.   /*
  126.     Allocate image structure.
  127.   */
  128.   image=AllocateImage(image_info);
  129.   if (image == (Image *) NULL)
  130.     return((Image *) NULL);
  131.   /*
  132.     Open image file.
  133.   */
  134.   OpenImage(image,"r");
  135.   if (image->file == (FILE *) NULL)
  136.     {
  137.       Warning("Unable to open file",image->filename);
  138.       DestroyImage(image);
  139.       return((Image *) NULL);
  140.     }
  141.   /*
  142.     Determine width and height, e.g. 640x512.
  143.   */
  144.   width=512;
  145.   height=512;
  146.   if (image_info->geometry != (char *) NULL)
  147.     (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  148.   /*
  149.     Initialize image structure.
  150.   */
  151.   image->alpha=True;
  152.   image->columns=width;
  153.   image->rows=height;
  154.   image->packets=image->columns*image->rows;
  155.   alpha_pixels=(unsigned char *) malloc(image->packets*sizeof(unsigned char));
  156.   image->pixels=(RunlengthPacket *)
  157.     malloc(image->packets*sizeof(RunlengthPacket));
  158.   if ((alpha_pixels == (unsigned char *) NULL) ||
  159.       (image->pixels == (RunlengthPacket *) NULL))
  160.     {
  161.       Warning("Memory allocation error",(char *) NULL);
  162.       DestroyImage(image);
  163.       return((Image *) NULL);
  164.     }
  165.   /*
  166.     Convert raster image to runlength-encoded packets.
  167.   */
  168.   (void) ReadData((char *) alpha_pixels,1,(int) image->packets,image->file);
  169.   p=alpha_pixels;
  170.   q=image->pixels;
  171.   for (i=0; i < image->packets; i++)
  172.   {
  173.     index=(*p++);
  174.     q->red=0;
  175.     q->green=0;
  176.     q->blue=0;
  177.     q->index=(unsigned short) index;
  178.     q->length=0;
  179.     q++;
  180.   }
  181.   (void) free((char *) alpha_pixels);
  182.   CloseImage(image);
  183.   return(image);
  184. }
  185.  
  186. /*
  187. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  188. %                                                                             %
  189. %                                                                             %
  190. %                                                                             %
  191. %  R e a d A V S I m a g e                                                    %
  192. %                                                                             %
  193. %                                                                             %
  194. %                                                                             %
  195. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  196. %
  197. %  Function ReadAVSImage reads a AVS X image file and returns it.  It
  198. %  allocates the memory necessary for the new Image structure and returns a
  199. %  pointer to the new image.
  200. %
  201. %  The format of the ReadAVSImage routine is:
  202. %
  203. %      image=ReadAVSImage(image_info)
  204. %
  205. %  A description of each parameter follows:
  206. %
  207. %    o image:  Function ReadAVSImage returns a pointer to the image after
  208. %      reading. A null image is returned if there is a a memory shortage or if
  209. %      the image cannot be read.
  210. %
  211. %    o image_info: Specifies a pointer to an ImageInfo structure.
  212. %
  213. %
  214. */
  215. static Image *ReadAVSImage(image_info)
  216. ImageInfo
  217.   *image_info;
  218. {
  219.   typedef struct _AVSHeader
  220.   {
  221.     int
  222.       width,
  223.       height;
  224.   } AVSHeader;
  225.  
  226.   AVSHeader
  227.     avs_header;
  228.  
  229.   Image
  230.     *image;
  231.  
  232.   register int
  233.     i;
  234.  
  235.   register unsigned char
  236.     *p;
  237.  
  238.   register RunlengthPacket
  239.     *q;
  240.  
  241.   unsigned char
  242.     *avs_pixels;
  243.  
  244.   unsigned int
  245.     status;
  246.  
  247.   /*
  248.     Allocate image structure.
  249.   */
  250.   image=AllocateImage(image_info);
  251.   if (image == (Image *) NULL)
  252.     return((Image *) NULL);
  253.   /*
  254.     Open image file.
  255.   */
  256.   OpenImage(image,"r");
  257.   if (image->file == (FILE *) NULL)
  258.     {
  259.       Warning("Unable to open file",image->filename);
  260.       DestroyImage(image);
  261.       return((Image *) NULL);
  262.     }
  263.   /*
  264.     Read AVS image.
  265.   */
  266.   status=ReadData((char *) &avs_header,1,sizeof(AVSHeader),image->file);
  267.   if (status == False)
  268.     {
  269.       Warning("Not a AVS image file",(char *) NULL);
  270.       DestroyImage(image);
  271.       return((Image *) NULL);
  272.     }
  273.   do
  274.   {
  275.     /*
  276.       Initialize image structure.
  277.     */
  278.     image->alpha=True;
  279.     image->columns=avs_header.width;
  280.     image->rows=avs_header.height;
  281.     image->packets=image->columns*image->rows;
  282.     avs_pixels=(unsigned char *) malloc(4*image->packets*sizeof(unsigned char));
  283.     image->pixels=(RunlengthPacket *)
  284.       malloc(image->packets*sizeof(RunlengthPacket));
  285.     if ((avs_pixels == (unsigned char *) NULL) ||
  286.         (image->pixels == (RunlengthPacket *) NULL))
  287.       {
  288.         Warning("Memory allocation error",(char *) NULL);
  289.         DestroyImages(image);
  290.         return((Image *) NULL);
  291.       }
  292.     /*
  293.       Convert AVS raster image to runlength-encoded packets.
  294.     */
  295.     (void) ReadData((char *) avs_pixels,4,(int) image->packets,image->file);
  296.     p=avs_pixels;
  297.     q=image->pixels;
  298.     for (i=0; i < image->packets; i++)
  299.     {
  300.       q->index=(unsigned char) (*p++);
  301.       q->red=(*p++);
  302.       q->green=(*p++);
  303.       q->blue=(*p++);
  304.       q->length=0;
  305.       q++;
  306.     }
  307.     (void) free((char *) avs_pixels);
  308.     status=ReadData((char *) &avs_header,1,sizeof(AVSHeader),image->file);
  309.     if (status == True)
  310.       {
  311.         /*
  312.           Allocate image structure.
  313.         */
  314.         image->next=AllocateImage(image_info);
  315.         if (image->next == (Image *) NULL)
  316.           {
  317.             DestroyImages(image);
  318.             return((Image *) NULL);
  319.           }
  320.         (void) strcpy(image->next->filename,image_info->filename);
  321.         image->next->file=image->file;
  322.         image->next->scene=image->scene+1;
  323.         image->next->previous=image;
  324.         image=image->next;
  325.       }
  326.   } while (status == True);
  327.   while (image->previous != (Image *) NULL)
  328.     image=image->previous;
  329.   CloseImage(image);
  330.   return(image);
  331. }
  332.  
  333. /*
  334. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  335. %                                                                             %
  336. %                                                                             %
  337. %                                                                             %
  338. %  R e a d B M P I m a g e                                                    %
  339. %                                                                             %
  340. %                                                                             %
  341. %                                                                             %
  342. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  343. %
  344. %  Function ReadBMPImage reads a Microsoft Windows bitmap image file and
  345. %  returns it.  It allocates the memory necessary for the new Image structure
  346. %  and returns a pointer to the new image.
  347. %
  348. %  The format of the ReadBMPImage routine is:
  349. %
  350. %      image=ReadBMPImage(image_info)
  351. %
  352. %  A description of each parameter follows:
  353. %
  354. %    o image:  Function ReadBMPImage returns a pointer to the image after
  355. %      reading.  A null image is returned if there is a a memory shortage or
  356. %      if the image cannot be read.
  357. %
  358. %    o image_info: Specifies a pointer to an ImageInfo structure.
  359. %
  360. %
  361. */
  362. static Image *ReadBMPImage(image_info)
  363. ImageInfo
  364.   *image_info;
  365. {
  366.   typedef struct _BMPHeader
  367.   {
  368.     unsigned long
  369.       file_size;
  370.  
  371.     unsigned short
  372.       reserved[2];
  373.  
  374.     unsigned long
  375.       offset_bits,
  376.       size,
  377.       width,
  378.       height;
  379.  
  380.     unsigned short
  381.       planes,
  382.       bit_count;
  383.  
  384.     unsigned long
  385.       compression,
  386.       image_size,
  387.       x_pixels,
  388.       y_pixels,
  389.       number_colors,
  390.       colors_important;
  391.   } BMPHeader;
  392.  
  393.   BMPHeader
  394.     bmp_header;
  395.  
  396.   Image
  397.     *image;
  398.  
  399.   register int
  400.     bit,
  401.     i,
  402.     x,
  403.     y;
  404.  
  405.   register RunlengthPacket
  406.     *q;
  407.  
  408.   register unsigned char
  409.     *p;
  410.  
  411.   unsigned char
  412.     *bmp_data,
  413.     *bmp_pixels,
  414.     magick[12];
  415.  
  416.   unsigned int
  417.     bytes_per_line,
  418.     status;
  419.  
  420.   /*
  421.     Allocate image structure.
  422.   */
  423.   image=AllocateImage(image_info);
  424.   if (image == (Image *) NULL)
  425.     return((Image *) NULL);
  426.   /*
  427.     Open image file.
  428.   */
  429.   OpenImage(image,"r");
  430.   if (image->file == (FILE *) NULL)
  431.     {
  432.       Warning("Unable to open file",image->filename);
  433.       DestroyImage(image);
  434.       return((Image *) NULL);
  435.     }
  436.   /*
  437.     Determine if this is a BMP file.
  438.   */
  439.   status=ReadData((char *) magick,1,2,image->file);
  440.   do
  441.   {
  442.     /*
  443.       Verify BMP identifier.
  444.     */
  445.     if ((status == False) || (strncmp((char *) magick,"BM",2) != 0))
  446.       {
  447.         Warning("Not a BMP image file",(char *) NULL);
  448.         DestroyImages(image);
  449.         return((Image *) NULL);
  450.       }
  451.     bmp_header.file_size=LSBFirstReadLong(image->file);
  452.     bmp_header.reserved[0]=LSBFirstReadShort(image->file);
  453.     bmp_header.reserved[1]=LSBFirstReadShort(image->file);
  454.     bmp_header.offset_bits=LSBFirstReadLong(image->file);
  455.     bmp_header.size=LSBFirstReadLong(image->file);
  456.     if (bmp_header.size == 12)
  457.       {
  458.         /*
  459.           OS/2 BMP image file.
  460.         */
  461.         bmp_header.width=(unsigned long) LSBFirstReadShort(image->file);
  462.         bmp_header.height=(unsigned long) LSBFirstReadShort(image->file);
  463.         bmp_header.planes=LSBFirstReadShort(image->file);
  464.         bmp_header.bit_count=LSBFirstReadShort(image->file);
  465.         bmp_header.number_colors=0;
  466.         bmp_header.compression=0;
  467.         bmp_header.image_size=0;
  468.       }
  469.     else
  470.       {
  471.         /*
  472.           Microsoft Windows BMP image file.
  473.         */
  474.         bmp_header.width=LSBFirstReadLong(image->file);
  475.         bmp_header.height=LSBFirstReadLong(image->file);
  476.         bmp_header.planes=LSBFirstReadShort(image->file);
  477.         bmp_header.bit_count=LSBFirstReadShort(image->file);
  478.         bmp_header.compression=LSBFirstReadLong(image->file);
  479.         bmp_header.image_size=LSBFirstReadLong(image->file);
  480.         bmp_header.x_pixels=LSBFirstReadLong(image->file);
  481.         bmp_header.y_pixels=LSBFirstReadLong(image->file);
  482.         bmp_header.number_colors=LSBFirstReadLong(image->file);
  483.         bmp_header.colors_important=LSBFirstReadLong(image->file);
  484.         for (i=0; i < ((int) bmp_header.size-40); i++)
  485.           (void) fgetc(image->file);
  486.       }
  487.     if (bmp_header.bit_count < 24)
  488.       {
  489.         unsigned char
  490.           *bmp_colormap;
  491.  
  492.         unsigned int
  493.           packet_size;
  494.  
  495.         /*
  496.           Read BMP raster colormap.
  497.         */
  498.         image->class=PseudoClass;
  499.         image->colors=bmp_header.number_colors;
  500.         if (image->colors == 0)
  501.           image->colors=1 << bmp_header.bit_count;
  502.         image->colormap=(ColorPacket *)
  503.           malloc(image->colors*sizeof(ColorPacket));
  504.         bmp_colormap=(unsigned char *)
  505.           malloc(4*image->colors*sizeof(unsigned char));
  506.         if ((image->colormap == (ColorPacket *) NULL) ||
  507.             (bmp_colormap == (unsigned char *) NULL))
  508.           {
  509.             Warning("Memory allocation error",(char *) NULL);
  510.             DestroyImages(image);
  511.             return((Image *) NULL);
  512.           }
  513.         packet_size=4;
  514.         if (bmp_header.size == 12)
  515.           packet_size=3;
  516.         (void) ReadData((char *) bmp_colormap,(int) packet_size,
  517.           (int) image->colors,image->file);
  518.         p=bmp_colormap;
  519.         for (i=0; i < image->colors; i++)
  520.         {
  521.           image->colormap[i].blue=(*p++);
  522.           image->colormap[i].green=(*p++);
  523.           image->colormap[i].red=(*p++);
  524.           if (bmp_header.size != 12)
  525.             p++;
  526.         }
  527.         (void) free((char *) bmp_colormap);
  528.       }
  529.     /*
  530.       Read image data.
  531.     */
  532.     if (bmp_header.image_size == 0)
  533.       bmp_header.image_size=
  534.         ((bmp_header.width*bmp_header.bit_count+31)/32)*4*bmp_header.height;
  535.     bmp_data=(unsigned char *)
  536.       malloc(bmp_header.image_size*sizeof(unsigned char));
  537.     if (bmp_data == (unsigned char *) NULL)
  538.       {
  539.         Warning("Memory allocation error",(char *) NULL);
  540.         DestroyImages(image);
  541.         return((Image *) NULL);
  542.       }
  543.     status=ReadData((char *) bmp_data,1,(int) bmp_header.image_size,
  544.       image->file);
  545.     if (status == False)
  546.       {
  547.         Warning("Unable to read image data",image_info->filename);
  548.         DestroyImages(image);
  549.         return((Image *) NULL);
  550.       }
  551.     bmp_pixels=bmp_data;
  552.     if (bmp_header.compression != 0)
  553.       {
  554.         unsigned int
  555.           packets;
  556.  
  557.         /*
  558.           Convert run-length encoded raster pixels.
  559.         */
  560.         packets=
  561.           ((bmp_header.width*bmp_header.bit_count+31)/32)*4*bmp_header.height;
  562.         if (bmp_header.compression == 2)
  563.           packets<<=1;
  564.         bmp_pixels=(unsigned char *) malloc(packets*sizeof(unsigned char));
  565.         if (bmp_pixels == (unsigned char *) NULL)
  566.           {
  567.             Warning("Memory allocation error",(char *) NULL);
  568.             DestroyImages(image);
  569.             return((Image *) NULL);
  570.           }
  571.         (void) BMPDecodeImage(bmp_data,bmp_pixels,
  572.           (unsigned int) bmp_header.compression,(unsigned int) bmp_header.width,
  573.           (unsigned int) bmp_header.height);
  574.         if (bmp_header.compression == 2)
  575.           bmp_header.bit_count<<=1;
  576.         (void) free((char *) bmp_data);
  577.       }
  578.     /*
  579.       Initialize image structure.
  580.     */
  581.     image->columns=bmp_header.width;
  582.     image->rows=bmp_header.height;
  583.     image->packets=image->columns*image->rows;
  584.     image->pixels=(RunlengthPacket *)
  585.       malloc(image->packets*sizeof(RunlengthPacket));
  586.     if (image->pixels == (RunlengthPacket *) NULL)
  587.       {
  588.         Warning("Memory allocation error",(char *) NULL);
  589.         DestroyImages(image);
  590.         return((Image *) NULL);
  591.       }
  592.     /*
  593.       Convert BMP raster image to runlength-encoded packets.
  594.     */
  595.     bytes_per_line=((image->columns*bmp_header.bit_count+31)/32)*4;
  596.     switch (bmp_header.bit_count)
  597.     {
  598.       case 1:
  599.       {
  600.         /*
  601.           Convert bitmap scanline to runlength-encoded color packets.
  602.         */
  603.         for (y=image->rows-1; y >= 0; y--)
  604.         {
  605.           p=bmp_pixels+(image->rows-y-1)*bytes_per_line;
  606.           q=image->pixels+(y*image->columns);
  607.           for (x=0; x < (image->columns-7); x+=8)
  608.           {
  609.             for (bit=0; bit < 8; bit++)
  610.             {
  611.               q->index=((*p) & (0x80 >> bit) ? 0x00 : 0x01);
  612.               q->length=0;
  613.               q++;
  614.             }
  615.             p++;
  616.           }
  617.           if ((image->columns % 8) != 0)
  618.             {
  619.               for (bit=0; bit < (8-(image->columns % 8)); bit++)
  620.               {
  621.                 q->index=((*p) & (0x80 >> bit) ? 0x00 : 0x01);
  622.                 q->length=0;
  623.                 q++;
  624.               }
  625.               p++;
  626.             }
  627.         }
  628.         SyncImage(image);
  629.         break;
  630.       }
  631.       case 4:
  632.       {
  633.         /*
  634.           Convert PseudoColor scanline to runlength-encoded color packets.
  635.         */
  636.         for (y=image->rows-1; y >= 0; y--)
  637.         {
  638.           p=bmp_pixels+(image->rows-y-1)*bytes_per_line;
  639.           q=image->pixels+(y*image->columns);
  640.           for (x=0; x < (image->columns-1); x+=2)
  641.           {
  642.             q->index=(*p >> 4) & 0xf;
  643.             q->length=0;
  644.             q++;
  645.             q->index=(*p) & 0xf;
  646.             q->length=0;
  647.             p++;
  648.             q++;
  649.           }
  650.           if ((image->columns % 2) != 0)
  651.             {
  652.               q->index=(*p >> 4) & 0xf;
  653.               q->length=0;
  654.               q++;
  655.               p++;
  656.             }
  657.         }
  658.         SyncImage(image);
  659.         CompressColormap(image);
  660.         break;
  661.       }
  662.       case 8:
  663.       {
  664.         /*
  665.           Convert PseudoColor scanline to runlength-encoded color packets.
  666.         */
  667.         for (y=image->rows-1; y >= 0; y--)
  668.         {
  669.           p=bmp_pixels+(image->rows-y-1)*bytes_per_line;
  670.           q=image->pixels+(y*image->columns);
  671.           for (x=0; x < image->columns; x++)
  672.           {
  673.             q->index=(*p++);
  674.             q->length=0;
  675.             q++;
  676.           }
  677.         }
  678.         SyncImage(image);
  679.         CompressColormap(image);
  680.         break;
  681.       }
  682.       case 24:
  683.       {
  684.         /*
  685.           Convert DirectColor scanline to runlength-encoded color packets.
  686.         */
  687.         for (y=image->rows-1; y >= 0; y--)
  688.         {
  689.           p=bmp_pixels+(image->rows-y-1)*bytes_per_line;
  690.           q=image->pixels+(y*image->columns);
  691.           for (x=0; x < image->columns; x++)
  692.           {
  693.             q->index=(unsigned short) (image->alpha ? (*p++) : 0);
  694.             q->blue=(*p++);
  695.             q->green=(*p++);
  696.             q->red=(*p++);
  697.             q->length=0;
  698.             q++;
  699.           }
  700.         }
  701.         break;
  702.       }
  703.       default:
  704.       {
  705.         Warning("Not a BMP image file",(char *) NULL);
  706.         DestroyImages(image);
  707.         return((Image *) NULL);
  708.       }
  709.     }
  710.     (void) free((char *) bmp_pixels);
  711.     /*
  712.       Proceed to next image.
  713.     */
  714.     status=ReadData((char *) magick,1,2,image->file);
  715.     if ((status == True) && (strncmp((char *) magick,"BM",2) == 0))
  716.       {
  717.         /*
  718.           Allocate image structure.
  719.         */
  720.         image->next=AllocateImage(image_info);
  721.         if (image->next == (Image *) NULL)
  722.           {
  723.             DestroyImages(image);
  724.             return((Image *) NULL);
  725.           }
  726.         (void) strcpy(image->next->filename,image_info->filename);
  727.         image->next->file=image->file;
  728.         image->next->scene=image->scene+1;
  729.         image->next->previous=image;
  730.         image=image->next;
  731.       }
  732.   } while ((status == True) && (strncmp((char *) magick,"BM",2) == 0));
  733.   while (image->previous != (Image *) NULL)
  734.     image=image->previous;
  735.   CloseImage(image);
  736.   return(image);
  737. }
  738.  
  739. /*
  740. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  741. %                                                                             %
  742. %                                                                             %
  743. %                                                                             %
  744. %  R e a d C M Y K I m a g e                                                  %
  745. %                                                                             %
  746. %                                                                             %
  747. %                                                                             %
  748. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  749. %
  750. %  Function ReadCMYKImage reads an image of raw cyan, magenta, yellow, and
  751. %  black bytes and returns it.  It allocates the memory necessary for the new
  752. %  Image structure and returns a pointer to the new image.
  753. %
  754. %  The format of the ReadCMYKImage routine is:
  755. %
  756. %      image=ReadCMYKImage(image_info)
  757. %
  758. %  A description of each parameter follows:
  759. %
  760. %    o image:  Function ReadCMYKImage returns a pointer to the image after
  761. %      reading.  A null image is returned if there is a a memory shortage or
  762. %      if the image cannot be read.
  763. %
  764. %    o image_info: Specifies a pointer to an ImageInfo structure.
  765. %
  766. %
  767. */
  768. static Image *ReadCMYKImage(image_info)
  769. ImageInfo
  770.   *image_info;
  771. {
  772.   Image
  773.     *image;
  774.  
  775.   int
  776.     x,
  777.     y;
  778.  
  779.   register int
  780.     i;
  781.  
  782.   register RunlengthPacket
  783.     *q;
  784.  
  785.   register unsigned char
  786.     *p;
  787.  
  788.   unsigned char
  789.     black,
  790.     *cmyk_pixels,
  791.     cyan,
  792.     magenta,
  793.     yellow;
  794.  
  795.   unsigned int
  796.     height,
  797.     width;
  798.  
  799.   /*
  800.     Allocate image structure.
  801.   */
  802.   image=AllocateImage(image_info);
  803.   if (image == (Image *) NULL)
  804.     return((Image *) NULL);
  805.   /*
  806.     Open image file.
  807.   */
  808.   OpenImage(image,"r");
  809.   if (image->file == (FILE *) NULL)
  810.     {
  811.       Warning("Unable to open file",image->filename);
  812.       DestroyImage(image);
  813.       return((Image *) NULL);
  814.     }
  815.   /*
  816.     Determine width and height, e.g. 640x512.
  817.   */
  818.   width=512;
  819.   height=512;
  820.   if (image_info->geometry != (char *) NULL)
  821.     (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  822.   /*
  823.     Initialize image structure.
  824.   */
  825.   image->columns=width;
  826.   image->rows=height;
  827.   image->packets=image->columns*image->rows;
  828.   cmyk_pixels=(unsigned char *) malloc(4*image->packets*sizeof(unsigned char));
  829.   image->pixels=(RunlengthPacket *)
  830.     malloc(image->packets*sizeof(RunlengthPacket));
  831.   if ((cmyk_pixels == (unsigned char *) NULL) ||
  832.       (image->pixels == (RunlengthPacket *) NULL))
  833.     {
  834.       Warning("Unable to open file",image->filename);
  835.       DestroyImage(image);
  836.       return((Image *) NULL);
  837.     }
  838.   /*
  839.     Convert raster image to runlength-encoded packets.
  840.   */
  841.   (void) ReadData((char *) cmyk_pixels,4,(int) image->packets,image->file);
  842.   p=cmyk_pixels;
  843.   switch (image_info->interlace)
  844.   {
  845.     case NoneInterlace:
  846.     default:
  847.     {
  848.       /*
  849.         No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
  850.       */
  851.       q=image->pixels;
  852.       for (i=0; i < image->packets; i++)
  853.       {
  854.         q->red=(*p++);
  855.         q->green=(*p++);
  856.         q->blue=(*p++);
  857.         q->index=(*p++);
  858.         q->length=0;
  859.         q++;
  860.       }
  861.       break;
  862.     }
  863.     case LineInterlace:
  864.     {
  865.       /*
  866.         Line interlacing:  CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
  867.       */
  868.       for (y=0; y < image->rows; y++)
  869.       {
  870.         q=image->pixels+y*image->columns;
  871.         for (x=0; x < image->columns; x++)
  872.         {
  873.           q->red=(*p++);
  874.           q->length=0;
  875.           q++;
  876.         }
  877.         q=image->pixels+y*image->columns;
  878.         for (x=0; x < image->columns; x++)
  879.         {
  880.           q->green=(*p++);
  881.           q++;
  882.         }
  883.         q=image->pixels+y*image->columns;
  884.         for (x=0; x < image->columns; x++)
  885.         {
  886.           q->blue=(*p++);
  887.           q++;
  888.         }
  889.         q=image->pixels+y*image->columns;
  890.         for (x=0; x < image->columns; x++)
  891.         {
  892.           q->index=(*p++);
  893.           q++;
  894.         }
  895.       }
  896.       break;
  897.     }
  898.     case PlaneInterlace:
  899.     {
  900.       /*
  901.         Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
  902.       */
  903.       q=image->pixels;
  904.       for (i=0; i < image->packets; i++)
  905.       {
  906.         q->red=(*p++);
  907.         q->length=0;
  908.         q++;
  909.       }
  910.       q=image->pixels;
  911.       for (i=0; i < image->packets; i++)
  912.       {
  913.         q->green=(*p++);
  914.         q++;
  915.       }
  916.       q=image->pixels;
  917.       for (i=0; i < image->packets; i++)
  918.       {
  919.         q->blue=(*p++);
  920.         q++;
  921.       }
  922.       q=image->pixels;
  923.       for (i=0; i < image->packets; i++)
  924.       {
  925.         q->index=(*p++);
  926.         q++;
  927.       }
  928.       break;
  929.     }
  930.   }
  931.   /*
  932.     Transform image to CMYK.
  933.   */
  934.   q=image->pixels;
  935.   for (i=0; i < image->packets; i++)
  936.   {
  937.     cyan=q->red;
  938.     magenta=q->green;
  939.     yellow=q->blue;
  940.     black=q->index;
  941.     if ((unsigned int) (cyan+black) > MaxRGB)
  942.       q->red=0;
  943.     else
  944.       q->red=MaxRGB-(cyan+black);
  945.     if ((unsigned int) (magenta+black) > MaxRGB)
  946.       q->green=0;
  947.     else
  948.       q->green=MaxRGB-(magenta+black);
  949.     if ((unsigned int) (yellow+black) > MaxRGB)
  950.       q->blue=0;
  951.     else
  952.       q->blue=MaxRGB-(yellow+black);
  953.     q->index=0;
  954.     q->length=0;
  955.     q++;
  956.   }
  957.   (void) free((char *) cmyk_pixels);
  958.   CloseImage(image);
  959.   return(image);
  960. }
  961.  
  962. /*
  963. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  964. %                                                                             %
  965. %                                                                             %
  966. %                                                                             %
  967. %  R e a d F A X I m a g e                                                    %
  968. %                                                                             %
  969. %                                                                             %
  970. %                                                                             %
  971. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  972. %
  973. %  Function ReadFAXImage reads a Group 3 FAX image file and returns it.  It
  974. %  allocates the memory necessary for the new Image structure and returns a
  975. %  pointer to the new image.
  976. %
  977. %  The format of the ReadFAXImage routine is:
  978. %
  979. %      image=ReadFAXImage(image_info)
  980. %
  981. %  A description of each parameter follows:
  982. %
  983. %    o image:  Function ReadFAXImage returns a pointer to the image after
  984. %      reading.  A null image is returned if there is a a memory shortage or
  985. %      if the image cannot be read.
  986. %
  987. %    o image_info: Specifies a pointer to an ImageInfo structure.
  988. %
  989. %
  990. */
  991. static Image *ReadFAXImage(image_info)
  992. ImageInfo
  993.   *image_info;
  994. {
  995.   Image
  996.     *image;
  997.  
  998.   unsigned int
  999.     status;
  1000.  
  1001.   /*
  1002.     Allocate image structure.
  1003.   */
  1004.   image=AllocateImage(image_info);
  1005.   if (image == (Image *) NULL)
  1006.     return((Image *) NULL);
  1007.   /*
  1008.     Open image file.
  1009.   */
  1010.   OpenImage(image,"r");
  1011.   if (image->file == (FILE *) NULL)
  1012.     {
  1013.       Warning("Unable to open file",image->filename);
  1014.       DestroyImage(image);
  1015.       return((Image *) NULL);
  1016.     }
  1017.   /*
  1018.     Initialize image structure.
  1019.   */
  1020.   image->class=PseudoClass;
  1021.   image->columns=1728;
  1022.   image->rows=2156;
  1023.   image->packets=image->columns*image->rows;
  1024.   image->pixels=(RunlengthPacket *)
  1025.     malloc(image->packets*sizeof(RunlengthPacket));
  1026.   image->colors=2;
  1027.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  1028.   if ((image->pixels == (RunlengthPacket *) NULL) ||
  1029.       (image->colormap == (ColorPacket *) NULL))
  1030.     {
  1031.       Warning("Memory allocation error",(char *) NULL);
  1032.       DestroyImage(image);
  1033.       return((Image *) NULL);
  1034.     }
  1035.   /*
  1036.     Monochrome colormap.
  1037.   */
  1038.   image->colormap[0].red=MaxRGB;
  1039.   image->colormap[0].green=MaxRGB;
  1040.   image->colormap[0].blue=MaxRGB;
  1041.   image->colormap[1].red=0;
  1042.   image->colormap[1].green=0;
  1043.   image->colormap[1].blue=0;
  1044.   status=HuffmanDecodeImage(image);
  1045.   if (status == False)
  1046.     {
  1047.       Warning("Unable to read image data",(char *) NULL);
  1048.       DestroyImage(image);
  1049.       return((Image *) NULL);
  1050.     }
  1051.   SyncImage(image);
  1052.   CompressImage(image);
  1053.   CloseImage(image);
  1054.   return(image);
  1055. }
  1056.  
  1057. /*
  1058. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1059. %                                                                             %
  1060. %                                                                             %
  1061. %                                                                             %
  1062. %   R e a d F I T S I m a g e                                                 %
  1063. %                                                                             %
  1064. %                                                                             %
  1065. %                                                                             %
  1066. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1067. %
  1068. %  Function ReadFITSImage reads a FITS image file and returns it.  It
  1069. %  allocates the memory necessary for the new Image structure and returns a
  1070. %  pointer to the new image.
  1071. %
  1072. %  The format of the ReadFITSImage routine is:
  1073. %
  1074. %      image=ReadFITSImage(image_info)
  1075. %
  1076. %  A description of each parameter follows:
  1077. %
  1078. %    o image: Function ReadFITSImage returns a pointer to the image after
  1079. %      reading.  A null image is returned if there is a a memory shortage or if
  1080. %      the image cannot be read.
  1081. %
  1082. %    o filename: Specifies the name of the image to read.
  1083. %
  1084. %
  1085. */
  1086. static Image *ReadFITSImage(image_info)
  1087. ImageInfo
  1088.   *image_info;
  1089. {
  1090.   typedef struct _FITSHeader
  1091.   {
  1092.     unsigned int
  1093.       simple;
  1094.  
  1095.     int
  1096.       bits_per_pixel;
  1097.  
  1098.     unsigned int
  1099.       number_of_axis,
  1100.       columns,
  1101.       rows,
  1102.       depth;
  1103.  
  1104.     double
  1105.       min_data,
  1106.       max_data,
  1107.       zero,
  1108.       scale;
  1109.   } FITSHeader;
  1110.  
  1111.   char
  1112.     keyword[MaxTextLength],
  1113.     value[MaxTextLength];
  1114.  
  1115.   double
  1116.     pixel,
  1117.     scaled_pixel;
  1118.  
  1119.   FITSHeader
  1120.     fits_header;
  1121.  
  1122.   Image
  1123.     *image;
  1124.  
  1125.   int
  1126.     packet_size;
  1127.  
  1128.   long
  1129.     count,
  1130.     quantum;
  1131.  
  1132.   register int
  1133.     c,
  1134.     i,
  1135.     j;
  1136.  
  1137.   register RunlengthPacket
  1138.     *q;
  1139.  
  1140.   register unsigned char
  1141.     *p;
  1142.  
  1143.   unsigned char
  1144.     *fits_pixels;
  1145.  
  1146.   unsigned int
  1147.     status,
  1148.     value_expected;
  1149.  
  1150.   /*
  1151.     Allocate image structure.
  1152.   */
  1153.   image=AllocateImage(image_info);
  1154.   if (image == (Image *) NULL)
  1155.     return((Image *) NULL);
  1156.   /*
  1157.     Open image file.
  1158.   */
  1159.   OpenImage(image,"r");
  1160.   if (image->file == (FILE *) NULL)
  1161.     {
  1162.       Warning("Unable to open file",image->filename);
  1163.       DestroyImage(image);
  1164.       return((Image *) NULL);
  1165.     }
  1166.   /*
  1167.     Initialize image header.
  1168.   */
  1169.   fits_header.simple=False;
  1170.   fits_header.bits_per_pixel=8;
  1171.   fits_header.columns=1;
  1172.   fits_header.rows=1;
  1173.   fits_header.depth=1;
  1174.   fits_header.min_data=0.0;
  1175.   fits_header.max_data=0.0;
  1176.   fits_header.zero=0.0;
  1177.   fits_header.scale=1.0;
  1178.   /*
  1179.     Decode image header.
  1180.   */
  1181.   c=fgetc(image->file);
  1182.   count=1;
  1183.   if (c == EOF)
  1184.     {
  1185.       DestroyImage(image);
  1186.       return((Image *) NULL);
  1187.     }
  1188.   while (count < 2880)
  1189.   {
  1190.     if (!isalnum(c))
  1191.       {
  1192.         c=fgetc(image->file);
  1193.         count++;
  1194.       }
  1195.     else
  1196.       {
  1197.         register char
  1198.           *p;
  1199.  
  1200.         /*
  1201.           Determine a keyword and its value.
  1202.         */
  1203.         p=keyword;
  1204.         do
  1205.         {
  1206.           if ((p-keyword) < (MaxTextLength-1))
  1207.             *p++=(char) c;
  1208.           c=fgetc(image->file);
  1209.           count++;
  1210.         } while (isalnum(c) || (c == '_'));
  1211.         *p='\0';
  1212.         if (strcmp(keyword,"END") == 0)
  1213.           break;
  1214.         value_expected=False;
  1215.         while (isspace(c) || (c == '='))
  1216.         {
  1217.           if (c == '=')
  1218.             value_expected=True;
  1219.           c=fgetc(image->file);
  1220.           count++;
  1221.         }
  1222.         if (value_expected == False)
  1223.           continue;
  1224.         p=value;
  1225.         while (isalnum(c) || (c == '-') || (c == '+') || (c == '.'))
  1226.         {
  1227.           if ((p-value) < (MaxTextLength-1))
  1228.             *p++=(char) c;
  1229.           c=fgetc(image->file);
  1230.           count++;
  1231.         }
  1232.         *p='\0';
  1233.         /*
  1234.           Assign a value to the specified keyword.
  1235.         */
  1236.         if (strcmp(keyword,"SIMPLE") == 0)
  1237.           fits_header.simple=(*value == 'T') || (*value == 't');
  1238.         if (strcmp(keyword,"BITPIX") == 0)
  1239.           fits_header.bits_per_pixel=(unsigned int) atoi(value);
  1240.         if (strcmp(keyword,"NAXIS") == 0)
  1241.           fits_header.number_of_axis=(unsigned int) atoi(value);
  1242.         if (strcmp(keyword,"NAXIS1") == 0)
  1243.           fits_header.columns=(unsigned int) atoi(value);
  1244.         if (strcmp(keyword,"NAXIS2") == 0)
  1245.           fits_header.rows=(unsigned int) atoi(value);
  1246.         if (strcmp(keyword,"NAXIS3") == 0)
  1247.           fits_header.depth=(unsigned int) atoi(value);
  1248.         if (strcmp(keyword,"DATAMAX") == 0)
  1249.           fits_header.max_data=atof(value);
  1250.         if (strcmp(keyword,"DATAMIN") == 0)
  1251.           fits_header.min_data=atof(value);
  1252.         if (strcmp(keyword,"BZERO") == 0)
  1253.           fits_header.zero=atof(value);
  1254.         if (strcmp(keyword,"BSCALE") == 0)
  1255.           fits_header.scale=atof(value);
  1256.       }
  1257.     while (isspace(c) && (count < 2880))
  1258.     {
  1259.       c=fgetc(image->file);
  1260.       count++;
  1261.     }
  1262.   }
  1263.   for ( ; count < 2880; count++)
  1264.     (void) fgetc(image->file);
  1265.   /*
  1266.     Verify that required image information is defined.
  1267.   */
  1268.   if ((!fits_header.simple) || (fits_header.number_of_axis < 1) ||
  1269.       (fits_header.number_of_axis > 3) ||
  1270.       (fits_header.columns*fits_header.rows) == 0)
  1271.     {
  1272.       Warning("Unable to read FITS image","image type not supported");
  1273.       DestroyImage(image);
  1274.       return((Image *) NULL);
  1275.     }
  1276.   /*
  1277.     Create linear colormap.
  1278.   */
  1279.   image->columns=fits_header.columns;
  1280.   image->rows=fits_header.rows;
  1281.   image->class=PseudoClass;
  1282.   image->colors=MaxRGB+1;
  1283.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  1284.   if (image->colormap == (ColorPacket *) NULL)
  1285.     {
  1286.       Warning("Memory allocation error",(char *) NULL);
  1287.       DestroyImage(image);
  1288.       return((Image *) NULL);
  1289.     }
  1290.   for (i=0; i < image->colors; i++)
  1291.   {
  1292.     image->colormap[i].red=(unsigned char) i;
  1293.     image->colormap[i].green=(unsigned char) i;
  1294.     image->colormap[i].blue=(unsigned char) i;
  1295.   }
  1296.   /*
  1297.     Initialize image structure.
  1298.   */
  1299.   image->packets=image->columns*image->rows;
  1300.   image->pixels=(RunlengthPacket *)
  1301.     malloc(image->packets*sizeof(RunlengthPacket));
  1302.   packet_size=fits_header.bits_per_pixel/8;
  1303.   if (packet_size < 0)
  1304.     packet_size=(-packet_size);
  1305.   fits_pixels=(unsigned char *)
  1306.     malloc(image->packets*packet_size*sizeof(unsigned char));
  1307.   if ((image->pixels == (RunlengthPacket *) NULL) ||
  1308.       (fits_pixels == (unsigned char *) NULL))
  1309.     {
  1310.       Warning("Memory allocation error",(char *) NULL);
  1311.       DestroyImage(image);
  1312.       return((Image *) NULL);
  1313.     }
  1314.   /*
  1315.     Convert FITS pixels to runlength-encoded packets.
  1316.   */
  1317.   status=ReadData((char *) fits_pixels,(int) packet_size,(int) image->packets,
  1318.     image->file);
  1319.   if (status == False)
  1320.     Warning("Insufficient image data in file",image->filename);
  1321.   if ((fits_header.min_data == 0.0) && (fits_header.max_data == 0.0))
  1322.     {
  1323.       /*
  1324.         Determine minimum and maximum intensity.
  1325.       */
  1326.       p=fits_pixels;
  1327.       quantum=(*p++);
  1328.       for (j=0; j < (packet_size-1); j++)
  1329.         quantum=(quantum << 8) | (*p++);
  1330.       pixel=(double) quantum;
  1331.       if (fits_header.bits_per_pixel == -32)
  1332.         pixel=(double) (*((float *) &quantum));
  1333.       fits_header.min_data=pixel*fits_header.scale+fits_header.zero;
  1334.       fits_header.max_data=pixel*fits_header.scale+fits_header.zero;
  1335.       for (i=1; i < image->packets; i++)
  1336.       {
  1337.         quantum=(*p++);
  1338.         for (j=0; j < (packet_size-1); j++)
  1339.           quantum=(quantum << 8) | (*p++);
  1340.         pixel=(double) quantum;
  1341.         if (fits_header.bits_per_pixel == -32)
  1342.           pixel=(double) (*((float *) &quantum));
  1343.         scaled_pixel=pixel*fits_header.scale+fits_header.zero;
  1344.         if (scaled_pixel < fits_header.min_data)
  1345.           fits_header.min_data=scaled_pixel;
  1346.         if (scaled_pixel > fits_header.max_data)
  1347.           fits_header.max_data=scaled_pixel;
  1348.       }
  1349.     }
  1350.   /*
  1351.     Convert FITS pixels to runlength-encoded packets.
  1352.   */
  1353.   p=fits_pixels;
  1354.   q=image->pixels;
  1355.   for (i=0; i < image->packets; i++)
  1356.   {
  1357.     quantum=(*p++);
  1358.     for (j=0; j < (packet_size-1); j++)
  1359.       quantum=(quantum << 8) | (*p++);
  1360.     pixel=(double) quantum;
  1361.     if (fits_header.bits_per_pixel == -32)
  1362.       pixel=(double) (*((float *) &quantum));
  1363.     scaled_pixel=MaxRGB*(pixel*fits_header.scale+fits_header.zero+
  1364.       fits_header.min_data)/(fits_header.max_data-fits_header.min_data);
  1365.     q->index=(unsigned short) scaled_pixel;
  1366.     q->length=0;
  1367.     q++;
  1368.   }
  1369.   (void) free((char *) fits_pixels);
  1370.   SyncImage(image);
  1371.   CompressColormap(image);
  1372.   CloseImage(image);
  1373.   return(image);
  1374. }
  1375.  
  1376. /*
  1377. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1378. %                                                                             %
  1379. %                                                                             %
  1380. %                                                                             %
  1381. %  R e a d G I F I m a g e                                                    %
  1382. %                                                                             %
  1383. %                                                                             %
  1384. %                                                                             %
  1385. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1386. %
  1387. %  Function ReadGIFImage reads a Compuserve Graphics image file and returns it.
  1388. %  It allocates the memory necessary for the new Image structure and returns a
  1389. %  pointer to the new image.
  1390. %
  1391. %  The format of the ReadGIFImage routine is:
  1392. %
  1393. %      image=ReadGIFImage(image_info)
  1394. %
  1395. %  A description of each parameter follows:
  1396. %
  1397. %    o image:  Function ReadGIFImage returns a pointer to the image after
  1398. %      reading.  A null image is returned if there is a a memory shortage or
  1399. %      an error occurs.
  1400. %
  1401. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1402. %
  1403. %
  1404. */
  1405. static Image *ReadGIFImage(image_info)
  1406. ImageInfo
  1407.   *image_info;
  1408. {
  1409. #define BitSet(byte,bit)  (((byte) & (bit)) == (bit))
  1410. #define LSBFirstOrder(x,y)  (((y) << 8) | (x))
  1411.  
  1412.   Image
  1413.     *image;
  1414.  
  1415.   int
  1416.     pass,
  1417.     status,
  1418.     transparency_index,
  1419.     x,
  1420.     y;
  1421.  
  1422.   register int
  1423.     i;
  1424.  
  1425.   register RunlengthPacket
  1426.     *q;
  1427.  
  1428.   register unsigned char
  1429.     *p;
  1430.  
  1431.   unsigned char
  1432.     c,
  1433.     *global_colormap,
  1434.     header[MaxTextLength],
  1435.     magick[12];
  1436.  
  1437.   unsigned int
  1438.     global_colors,
  1439.     image_count,
  1440.     interlace,
  1441.     local_colormap;
  1442.  
  1443.   /*
  1444.     Allocate image structure.
  1445.   */
  1446.   image=AllocateImage(image_info);
  1447.   if (image == (Image *) NULL)
  1448.     return((Image *) NULL);
  1449.   /*
  1450.     Open image file.
  1451.   */
  1452.   OpenImage(image,"r");
  1453.   if (image->file == (FILE *) NULL)
  1454.     {
  1455.       Warning("Unable to open file",image->filename);
  1456.       DestroyImage(image);
  1457.       return((Image *) NULL);
  1458.     }
  1459.   /*
  1460.     Determine if this is a GIF file.
  1461.   */
  1462.   status=ReadData((char *) magick,1,6,image->file);
  1463.   if ((status == False) || ((strncmp((char *) magick,"GIF87",5) != 0) &&
  1464.       (strncmp((char *) magick,"GIF89",5) != 0)))
  1465.     {
  1466.       Warning("Not a GIF image file",image->filename);
  1467.       DestroyImage(image);
  1468.       return((Image *) NULL);
  1469.     }
  1470.   /*
  1471.     Read the screen descriptor.
  1472.   */
  1473.   status=ReadData((char *) header,1,7,image->file);
  1474.   if (status == False)
  1475.     {
  1476.       Warning("Failed to read screen descriptor",(char *) NULL );
  1477.       DestroyImage(image);
  1478.       return((Image *) NULL);
  1479.     }
  1480.   global_colors=0;
  1481.   global_colormap=(unsigned char *) NULL;
  1482.   if (BitSet(header[4],0x80))
  1483.     {
  1484.       /*
  1485.         Read global colormap.
  1486.       */
  1487.       global_colors=1 << ((header[4] & 0x07)+1);
  1488.       global_colormap=(unsigned char *)
  1489.         malloc(3*global_colors*sizeof(unsigned char));
  1490.       if (global_colormap == (unsigned char *) NULL)
  1491.         {
  1492.           Warning("Unable to read image colormap","Memory allocation failed");
  1493.           DestroyImage(image);
  1494.           return((Image *) NULL);
  1495.         }
  1496.       (void) ReadData((char *) global_colormap,1,(int) (3*global_colors),
  1497.         image->file);
  1498.     }
  1499.   transparency_index=(-1);
  1500.   image_count=0;
  1501.   for ( ; ; )
  1502.   {
  1503.     status=ReadData((char *) &c,1,1,image->file);
  1504.     if (status == False)
  1505.       break;
  1506.     if (c == ';')
  1507.       break;  /* terminator */
  1508.     if (c == '!')
  1509.       {
  1510.         /*
  1511.           GIF Extension block.
  1512.         */
  1513.         status=ReadData((char *) &c,1,1,image->file);
  1514.         if (status == False)
  1515.           {
  1516.             Warning("Unable to read extention block",(char *) NULL);
  1517.             DestroyImages(image);
  1518.             return((Image *) NULL);
  1519.           }
  1520.         switch (c)
  1521.         {
  1522.           case 0xf9:
  1523.           {
  1524.             /*
  1525.               Transparency extension block.
  1526.             */
  1527.             while (ReadDataBlock((char *) header,image->file) != 0);
  1528.             if ((header[0] & 0x01) == 1)
  1529.               transparency_index=header[3];
  1530.             break;
  1531.           }
  1532.           case 0xfe:
  1533.           {
  1534.             int
  1535.               length;
  1536.  
  1537.             /*
  1538.               Comment extension block.
  1539.             */
  1540.             for ( ; ; )
  1541.             {
  1542.               length=ReadDataBlock((char *) header,image->file);
  1543.               if (length == 0)
  1544.                 break;
  1545.               if (image->comments != (char *) NULL)
  1546.                 image->comments=(char *) realloc((char *) image->comments,
  1547.                   (strlen(image->comments)+length+1)*sizeof(char));
  1548.               else
  1549.                 {
  1550.                   image->comments=(char *) malloc(length*sizeof(char));
  1551.                   if (image->comments != (char *) NULL)
  1552.                     *image->comments='\0';
  1553.                 }
  1554.               if (image->comments == (char *) NULL)
  1555.                 {
  1556.                   Warning("Memory allocation error",(char *) NULL);
  1557.                   DestroyImages(image);
  1558.                   return((Image *) NULL);
  1559.                 }
  1560.               header[length]='\0';
  1561.               (void) strcat(image->comments,(char *) header);
  1562.             }
  1563.             break;
  1564.           }
  1565.           default:
  1566.           {
  1567.             while (ReadDataBlock((char *) header,image->file) != 0);
  1568.             break;
  1569.           }
  1570.         }
  1571.       }
  1572.     if (c != ',')
  1573.       continue;
  1574.     /*
  1575.       Read image attributes.
  1576.     */
  1577.     if (image_count != 0)
  1578.       {
  1579.         /*
  1580.           Allocate image structure.
  1581.         */
  1582.         image->next=AllocateImage(image_info);
  1583.         if (image->next == (Image *) NULL)
  1584.           {
  1585.             DestroyImages(image);
  1586.             return((Image *) NULL);
  1587.           }
  1588.         (void) strcpy(image->next->filename,image_info->filename);
  1589.         image->next->file=image->file;
  1590.         image->next->scene=image->scene+1;
  1591.         image->next->previous=image;
  1592.         image=image->next;
  1593.       }
  1594.     image_count++;
  1595.     status=ReadData((char *) header,1,9,image->file);
  1596.     if (status == False)
  1597.       {
  1598.         Warning("Unable to read left/top/width/height",(char *) NULL);
  1599.         DestroyImages(image);
  1600.         return((Image *) NULL);
  1601.       }
  1602.     interlace=BitSet(header[8],0x40);
  1603.     local_colormap=BitSet(header[8],0x80);
  1604.     /*
  1605.       Allocate image.
  1606.     */
  1607.     image->columns=LSBFirstOrder(header[4],header[5]);
  1608.     image->rows=LSBFirstOrder(header[6],header[7]);
  1609.     image->packets=image->columns*image->rows;
  1610.     if (image->pixels != (RunlengthPacket *) NULL)
  1611.       (void) free((char *) image->pixels);
  1612.     image->pixels=(RunlengthPacket *)
  1613.       malloc(image->packets*sizeof(RunlengthPacket));
  1614.     if (image->pixels == (RunlengthPacket *) NULL)
  1615.       {
  1616.         Warning("Unable to read image","Memory allocation failed");
  1617.         DestroyImages(image);
  1618.         return((Image *) NULL);
  1619.       }
  1620.     /*
  1621.       Inititialize colormap.
  1622.     */
  1623.     image->class=PseudoClass;
  1624.     image->colors=!local_colormap ? global_colors : 1 << ((header[8] & 0x07)+1);
  1625.     image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  1626.     if (image->colormap == (ColorPacket *) NULL)
  1627.       {
  1628.         Warning("Unable to read image","Memory allocation failed");
  1629.         DestroyImages(image);
  1630.         return((Image *) NULL);
  1631.       }
  1632.     if (!local_colormap)
  1633.       {
  1634.         /*
  1635.           Use global colormap.
  1636.         */
  1637.         p=global_colormap;
  1638.         for (i=0; i < image->colors; i++)
  1639.         {
  1640.           image->colormap[i].red=(*p++);
  1641.           image->colormap[i].green=(*p++);
  1642.           image->colormap[i].blue=(*p++);
  1643.         }
  1644.       }
  1645.     else
  1646.       {
  1647.         unsigned char
  1648.           *colormap;
  1649.  
  1650.         /*
  1651.           Read local colormap.
  1652.         */
  1653.         colormap=(unsigned char *)
  1654.           malloc(3*image->colors*sizeof(unsigned char));
  1655.         if (colormap == (unsigned char *) NULL)
  1656.           {
  1657.             Warning("Unable to read local colormap","Memory allocation failed");
  1658.             DestroyImages(image);
  1659.             return((Image *) NULL);
  1660.           }
  1661.         (void) ReadData((char *) colormap,1,(int) image->colors*3,image->file);
  1662.         p=colormap;
  1663.         for (i=0; i < image->colors; i++)
  1664.         {
  1665.           image->colormap[i].red=(*p++);
  1666.           image->colormap[i].green=(*p++);
  1667.           image->colormap[i].blue=(*p++);
  1668.         }
  1669.         (void) free((char *) colormap);
  1670.       }
  1671.     /*
  1672.       Decode image.
  1673.     */
  1674.     status=LZWDecodeImage(image);
  1675.     if (status == False)
  1676.       {
  1677.         Warning("Unable to read image data",(char *) NULL);
  1678.         DestroyImages(image);
  1679.         return((Image *) NULL);
  1680.       }
  1681.     if (interlace)
  1682.       {
  1683.         Image
  1684.           *interlaced_image;
  1685.  
  1686.         register RunlengthPacket
  1687.           *p;
  1688.  
  1689.         static int
  1690.           interlace_rate[4] = { 8, 8, 4, 2 },
  1691.           interlace_start[4] = { 0, 4, 2, 1 };
  1692.  
  1693.         /*
  1694.           Interlace image.
  1695.         */
  1696.         image->orphan=True;
  1697.         interlaced_image=CopyImage(image,image->columns,image->rows,True);
  1698.         image->orphan=False;
  1699.         if (interlaced_image == (Image *) NULL)
  1700.           {
  1701.             Warning("Unable to read image","Memory allocation failed");
  1702.             DestroyImages(image);
  1703.             return((Image *) NULL);
  1704.           }
  1705.         p=interlaced_image->pixels;
  1706.         q=image->pixels;
  1707.         for (pass=0; pass < 4; pass++)
  1708.         {
  1709.           y=interlace_start[pass];
  1710.           while (y < image->rows)
  1711.           {
  1712.             q=image->pixels+(y*image->columns);
  1713.             for (x=0; x < image->columns; x++)
  1714.             {
  1715.               *q=(*p);
  1716.               p++;
  1717.               q++;
  1718.             }
  1719.             y+=interlace_rate[pass];
  1720.           }
  1721.         }
  1722.         DestroyImage(interlaced_image);
  1723.       }
  1724.     if (transparency_index >= 0)
  1725.       {
  1726.         /*
  1727.           Create alpha channel.
  1728.         */
  1729.         q=image->pixels;
  1730.         for (i=0; i < image->packets; i++)
  1731.         {
  1732.           if (q->index != transparency_index)
  1733.             q->index=0;
  1734.           else
  1735.             q->index=MaxRGB;
  1736.           q++;
  1737.         }
  1738.         transparency_index=(-1);
  1739.         image->class=DirectClass;
  1740.         image->alpha=True;
  1741.       }
  1742.   }
  1743.   (void) free((char *) global_colormap);
  1744.   while (image->previous != (Image *) NULL)
  1745.     image=image->previous;
  1746.   CloseImage(image);
  1747.   return(image);
  1748. }
  1749.  
  1750. /*
  1751. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1752. %                                                                             %
  1753. %                                                                             %
  1754. %                                                                             %
  1755. %  R e a d G R A Y I m a g e                                                  %
  1756. %                                                                             %
  1757. %                                                                             %
  1758. %                                                                             %
  1759. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1760. %
  1761. %  Function ReadGRAYImage reads an image of raw grayscale bytes and returns it.
  1762. %  It allocates the memory necessary for the new Image structure and returns a
  1763. %  pointer to the new image.
  1764. %
  1765. %  The format of the ReadGRAYImage routine is:
  1766. %
  1767. %      image=ReadGRAYImage(image_info)
  1768. %
  1769. %  A description of each parameter follows:
  1770. %
  1771. %    o image:  Function ReadGRAYImage returns a pointer to the image after
  1772. %      reading.  A null image is returned if there is a a memory shortage or
  1773. %      if the image cannot be read.
  1774. %
  1775. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1776. %
  1777. %
  1778. */
  1779. static Image *ReadGRAYImage(image_info)
  1780. ImageInfo
  1781.   *image_info;
  1782. {
  1783.   Image
  1784.     *image;
  1785.  
  1786.   int
  1787.     x,
  1788.     y;
  1789.  
  1790.   register int
  1791.     i;
  1792.  
  1793.   register RunlengthPacket
  1794.     *q;
  1795.  
  1796.   register unsigned char
  1797.     index,
  1798.     *p;
  1799.  
  1800.   unsigned char
  1801.     *gray_pixels;
  1802.  
  1803.   unsigned int
  1804.     height,
  1805.     width;
  1806.  
  1807.   /*
  1808.     Allocate image structure.
  1809.   */
  1810.   image=AllocateImage(image_info);
  1811.   if (image == (Image *) NULL)
  1812.     return((Image *) NULL);
  1813.   /*
  1814.     Open image file.
  1815.   */
  1816.   OpenImage(image,"r");
  1817.   if (image->file == (FILE *) NULL)
  1818.     {
  1819.       Warning("Unable to open file",image->filename);
  1820.       DestroyImage(image);
  1821.       return((Image *) NULL);
  1822.     }
  1823.   /*
  1824.     Create linear colormap.
  1825.   */
  1826.   image->class=PseudoClass;
  1827.   image->colors=256;
  1828.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  1829.   if (image->colormap == (ColorPacket *) NULL)
  1830.     {
  1831.       Warning("Memory allocation error",(char *) NULL);
  1832.       DestroyImage(image);
  1833.       return((Image *) NULL);
  1834.     }
  1835.   for (i=0; i < image->colors; i++)
  1836.   {
  1837.     image->colormap[i].red=(unsigned char) i;
  1838.     image->colormap[i].green=(unsigned char) i;
  1839.     image->colormap[i].blue=(unsigned char) i;
  1840.   }
  1841.   /*
  1842.     Determine width and height, e.g. 640x512.
  1843.   */
  1844.   width=512;
  1845.   height=512;
  1846.   if (image_info->geometry != (char *) NULL)
  1847.     (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  1848.   /*
  1849.     Initialize image structure.
  1850.   */
  1851.   image->columns=width;
  1852.   image->rows=height;
  1853.   image->packets=image->columns*image->rows;
  1854.   gray_pixels=(unsigned char *) malloc(image->packets*sizeof(unsigned char));
  1855.   image->pixels=(RunlengthPacket *)
  1856.     malloc(image->packets*sizeof(RunlengthPacket));
  1857.   if ((gray_pixels == (unsigned char *) NULL) ||
  1858.       (image->pixels == (RunlengthPacket *) NULL))
  1859.     {
  1860.       Warning("Memory allocation error",(char *) NULL);
  1861.       DestroyImage(image);
  1862.       return((Image *) NULL);
  1863.     }
  1864.   /*
  1865.     Convert raster image to runlength-encoded packets.
  1866.   */
  1867.   (void) ReadData((char *) gray_pixels,1,(int) image->packets,image->file);
  1868.   p=gray_pixels;
  1869.   q=image->pixels;
  1870.   for (i=0; i < image->packets; i++)
  1871.   {
  1872.     index=(*p++);
  1873.     q->red=index;
  1874.     q->green=index;
  1875.     q->blue=index;
  1876.     q->index=(unsigned short) index;
  1877.     q->length=0;
  1878.     q++;
  1879.   }
  1880.   (void) free((char *) gray_pixels);
  1881.   CompressColormap(image);
  1882.   CloseImage(image);
  1883.   return(image);
  1884. }
  1885.  
  1886. /*
  1887. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1888. %                                                                             %
  1889. %                                                                             %
  1890. %                                                                             %
  1891. %  R e a d H I S T O G R A M I m a g e                                        %
  1892. %                                                                             %
  1893. %                                                                             %
  1894. %                                                                             %
  1895. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1896. %
  1897. %  Function ReadHISTOGRAMImage reads a HISTOGRAM image file and returns it.  It
  1898. %  allocates the memory necessary for the new Image structure and returns a
  1899. %  pointer to the new image.
  1900. %
  1901. %  The format of the ReadHISTOGRAMImage routine is:
  1902. %
  1903. %      image=ReadHISTOGRAMImage(image_info)
  1904. %
  1905. %  A description of each parameter follows:
  1906. %
  1907. %    o image:  Function ReadHISTOGRAMImage returns a pointer to the image after
  1908. %      reading.  A null image is returned if there is a a memory shortage or
  1909. %      if the image cannot be read.
  1910. %
  1911. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1912. %
  1913. %
  1914. */
  1915. static Image *ReadHISTOGRAMImage(image_info)
  1916. ImageInfo
  1917.   *image_info;
  1918. {
  1919.   Image
  1920.     *image;
  1921.  
  1922.   Warning("Cannot read HISTOGRAM images",image_info->filename);
  1923.   image=ReadMIFFImage(image_info);
  1924.   return(image);
  1925. }
  1926.  
  1927. /*
  1928. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1929. %                                                                             %
  1930. %                                                                             %
  1931. %                                                                             %
  1932. %  R e a d I R I S I m a g e                                                  %
  1933. %                                                                             %
  1934. %                                                                             %
  1935. %                                                                             %
  1936. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1937. %
  1938. %  Function ReadIRISImage reads a SGI RGB image file and returns it.  It
  1939. %  allocates the memory necessary for the new Image structure and returns a
  1940. %  pointer to the new image.
  1941. %
  1942. %  The format of the ReadIRISImage routine is:
  1943. %
  1944. %      image=ReadIRISImage(image_info)
  1945. %
  1946. %  A description of each parameter follows:
  1947. %
  1948. %    o image:  Function ReadIRISImage returns a pointer to the image after
  1949. %      reading.  A null image is returned if there is a a memory shortage or
  1950. %      if the image cannot be read.
  1951. %
  1952. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1953. %
  1954. %
  1955. */
  1956.  
  1957. static void IRISDecode(packets,pixels)
  1958. unsigned char
  1959.   *packets,
  1960.   *pixels;
  1961. {
  1962.   unsigned char
  1963.     count,
  1964.     pixel;
  1965.  
  1966.   for ( ; ;)
  1967.   {
  1968.     pixel=(*packets++);
  1969.     count=pixel & 0x7f;
  1970.     if (count == 0)
  1971.       break;
  1972.     if (pixel & 0x80)
  1973.       for ( ; count != 0; count--)
  1974.       {
  1975.         *pixels=(*packets++);
  1976.         pixels+=4;
  1977.       }
  1978.     else
  1979.       {
  1980.         pixel=(*packets++);
  1981.         for ( ; count != 0; count--)
  1982.         {
  1983.           *pixels=pixel;
  1984.           pixels+=4;
  1985.         }
  1986.       }
  1987.   }
  1988. }
  1989.  
  1990. static Image *ReadIRISImage(image_info)
  1991. ImageInfo
  1992.   *image_info;
  1993. {
  1994.   typedef struct _IRISHeader
  1995.   {
  1996.     unsigned short
  1997.       magic;
  1998.  
  1999.     unsigned char
  2000.       storage,
  2001.       bytes_per_pixel;
  2002.  
  2003.     unsigned short
  2004.       dimension,
  2005.       columns,
  2006.       rows,
  2007.       depth;
  2008.  
  2009.     unsigned long
  2010.       minimum_value,
  2011.       maximum_value;
  2012.  
  2013.     unsigned char
  2014.       filler[492];
  2015.   } IRISHeader;
  2016.  
  2017.   Image
  2018.     *image;
  2019.  
  2020.   IRISHeader
  2021.     iris_header;
  2022.  
  2023.   register int
  2024.     i,
  2025.     x,
  2026.     y,
  2027.     z;
  2028.  
  2029.   register RunlengthPacket
  2030.     *q;
  2031.  
  2032.   register unsigned char
  2033.     *p;
  2034.  
  2035.   unsigned char
  2036.     *iris_pixels;
  2037.  
  2038.   /*
  2039.     Allocate image structure.
  2040.   */
  2041.   image=AllocateImage(image_info);
  2042.   if (image == (Image *) NULL)
  2043.     return((Image *) NULL);
  2044.   /*
  2045.     Open image file.
  2046.   */
  2047.   OpenImage(image,"r");
  2048.   if (image->file == (FILE *) NULL)
  2049.     {
  2050.       Warning("Unable to open file",image->filename);
  2051.       DestroyImage(image);
  2052.       return((Image *) NULL);
  2053.     }
  2054.   /*
  2055.     Read IRIS raster header.
  2056.   */
  2057.   iris_header.magic=MSBFirstReadShort(image->file);
  2058.   do
  2059.   {
  2060.     /*
  2061.       Verify IRIS identifier.
  2062.     */
  2063.     if (iris_header.magic != 0x01DA)
  2064.       {
  2065.         Warning("Not a IRIS RGB image,",image->filename);
  2066.         DestroyImages(image);
  2067.         return((Image *) NULL);
  2068.       }
  2069.     iris_header.storage=fgetc(image->file);
  2070.     iris_header.bytes_per_pixel=fgetc(image->file);
  2071.     if (iris_header.bytes_per_pixel != 1)
  2072.       {
  2073.         Warning("Image must have 1 byte per pixel channel,",image->filename);
  2074.         DestroyImages(image);
  2075.         return((Image *) NULL);
  2076.       }
  2077.     iris_header.dimension=MSBFirstReadShort(image->file);
  2078.     iris_header.columns=MSBFirstReadShort(image->file);
  2079.     iris_header.rows=MSBFirstReadShort(image->file);
  2080.     iris_header.depth=MSBFirstReadShort(image->file);
  2081.     iris_header.minimum_value=MSBFirstReadLong(image->file);
  2082.     iris_header.maximum_value=MSBFirstReadLong(image->file);
  2083.     (void) ReadData((char *) iris_header.filler,1,sizeof(iris_header.filler),
  2084.       image->file);
  2085.     /*
  2086.       Allocate IRIS pixels.
  2087.     */
  2088.     iris_pixels=(unsigned char *)
  2089.       malloc(4*iris_header.columns*iris_header.rows*sizeof(unsigned char));
  2090.     if (iris_pixels == (unsigned char *) NULL)
  2091.       {
  2092.         Warning("Memory allocation error",image->filename);
  2093.         DestroyImages(image);
  2094.         return((Image *) NULL);
  2095.       }
  2096.     if (iris_header.storage != 0x01)
  2097.       {
  2098.         unsigned char
  2099.           *scanline;
  2100.  
  2101.         /*
  2102.           Read standard image format.
  2103.         */
  2104.         scanline=(unsigned char *)
  2105.           malloc(iris_header.columns*sizeof(unsigned char));
  2106.         if (scanline == (unsigned char *) NULL)
  2107.           {
  2108.             Warning("Memory allocation error",image->filename);
  2109.             DestroyImages(image);
  2110.             return((Image *) NULL);
  2111.           }
  2112.         for (z=0; z < (int) iris_header.depth; z++)
  2113.         {
  2114.           p=iris_pixels+z;
  2115.           for (y=0; y < (int) iris_header.rows; y++)
  2116.           {
  2117.             (void) ReadData((char *) scanline,1,(int) iris_header.columns,
  2118.               image->file);
  2119.             for (x=0; x < (int) iris_header.columns; x++)
  2120.             {
  2121.               *p=scanline[x];
  2122.               p+=4;
  2123.             }
  2124.           }
  2125.         }
  2126.         (void) free((char *) scanline);
  2127.       }
  2128.     else
  2129.       {
  2130.         unsigned char
  2131.           *packets;
  2132.  
  2133.         unsigned int
  2134.           data_order;
  2135.  
  2136.         unsigned long
  2137.           offset,
  2138.           *offsets,
  2139.           *runlength;
  2140.  
  2141.         /*
  2142.           Read runlength-encoded image format.
  2143.         */
  2144.         offsets=(unsigned long *)
  2145.           malloc(iris_header.rows*iris_header.depth*sizeof(unsigned long));
  2146.         packets=(unsigned char *)
  2147.           malloc(((iris_header.columns << 1)+10)*sizeof(unsigned char));
  2148.         runlength=(unsigned long *)
  2149.           malloc(iris_header.rows*iris_header.depth*sizeof(unsigned long));
  2150.         if ((offsets == (unsigned long *) NULL) ||
  2151.             (packets == (unsigned char *) NULL) ||
  2152.             (runlength == (unsigned long *) NULL))
  2153.           {
  2154.             Warning("Memory allocation error",image->filename);
  2155.             DestroyImages(image);
  2156.             return((Image *) NULL);
  2157.           }
  2158.         (void) ReadData((char *) offsets,sizeof(unsigned long),
  2159.           (int) (iris_header.rows*iris_header.depth),image->file);
  2160.         (void) ReadData((char *) runlength,sizeof(unsigned long),
  2161.           (int) (iris_header.rows*iris_header.depth),image->file);
  2162.         /*
  2163.           Check data order.
  2164.         */
  2165.         offset=0;
  2166.         data_order=0;
  2167.         for (y=0; ((y < (int) iris_header.rows) && !data_order); y++)
  2168.           for (z=0; ((z < (int) iris_header.depth) && !data_order); z++)
  2169.           {
  2170.             if (offsets[y+z*iris_header.rows] < offset)
  2171.               data_order=1;
  2172.             offset=offsets[y+z*iris_header.rows];
  2173.           }
  2174.         offset=512+
  2175.           ((iris_header.rows*iris_header.depth) << 1)*sizeof(unsigned long);
  2176.         if (data_order == 1)
  2177.           {
  2178.             for (z=0; z < (int) iris_header.depth; z++)
  2179.             {
  2180.               p=iris_pixels;
  2181.               for (y=0; y < (int) iris_header.rows; y++)
  2182.               {
  2183.                 if (offset != offsets[y+z*iris_header.rows])
  2184.                   {
  2185.                     offset=offsets[y+z*iris_header.rows];
  2186.                     (void) fseek(image->file,(int) offset,0);
  2187.                   }
  2188.                 (void) ReadData((char *) packets,1,
  2189.                   (int) runlength[y+z*iris_header.rows],image->file);
  2190.                 offset+=runlength[y+z*iris_header.rows];
  2191.                 IRISDecode(packets,p+z);
  2192.                 p+=(iris_header.columns*4);
  2193.               }
  2194.             }
  2195.           }
  2196.         else
  2197.           {
  2198.             p=iris_pixels;
  2199.             for (y=0; y < (int) iris_header.rows; y++)
  2200.             {
  2201.               for (z=0; z < (int) iris_header.depth; z++)
  2202.               {
  2203.                 if (offset != offsets[y+z*iris_header.rows])
  2204.                   {
  2205.                     offset=offsets[y+z*iris_header.rows];
  2206.                     (void) fseek(image->file,(int) offset,0);
  2207.                   }
  2208.                 (void) ReadData((char *) packets,1,
  2209.                   (int) runlength[y+z*iris_header.rows],image->file);
  2210.                 offset+=runlength[y+z*iris_header.rows];
  2211.                 IRISDecode(packets,p+z);
  2212.               }
  2213.               p+=(iris_header.columns*4);
  2214.             }
  2215.           }
  2216.         (void) free(runlength);
  2217.         (void) free(packets);
  2218.         (void) free(offsets);
  2219.       }
  2220.     /*
  2221.       Initialize image structure.
  2222.     */
  2223.     image->alpha=iris_header.depth == 4;
  2224.     image->columns=iris_header.columns;
  2225.     image->rows=iris_header.rows;
  2226.     image->packets=image->columns*image->rows;
  2227.     image->pixels=(RunlengthPacket *)
  2228.       malloc(image->packets*sizeof(RunlengthPacket));
  2229.     if (image->pixels == (RunlengthPacket *) NULL)
  2230.       {
  2231.         Warning("Memory allocation error",(char *) NULL);
  2232.         DestroyImages(image);
  2233.         return((Image *) NULL);
  2234.       }
  2235.     /*
  2236.       Convert IRIS raster image to runlength-encoded packets.
  2237.     */
  2238.     q=image->pixels;
  2239.     if (iris_header.depth >= 3)
  2240.       {
  2241.         /*
  2242.           Convert IRIS image to DirectClass runlength-encoded packets.
  2243.         */
  2244.         for (y=0; y < image->rows; y++)
  2245.         {
  2246.           p=iris_pixels+((image->rows-1)-y)*(image->columns*4);
  2247.           for (x=0; x < image->columns; x++)
  2248.           {
  2249.             q->red=(*p);
  2250.             q->green=(*(p+1));
  2251.             q->blue=(*(p+2));
  2252.             q->index=(*(p+3));
  2253.             q->length=0;
  2254.             p+=4;
  2255.             q++;
  2256.           }
  2257.         }
  2258.       }
  2259.     else
  2260.       {
  2261.         unsigned short
  2262.           index;
  2263.  
  2264.         /*
  2265.           Create grayscale map.
  2266.         */
  2267.         image->class=PseudoClass;
  2268.         image->colors=256;
  2269.         image->colormap=(ColorPacket *)
  2270.           malloc(image->colors*sizeof(ColorPacket));
  2271.         if (image->colormap == (ColorPacket *) NULL)
  2272.           {
  2273.             Warning("Unable to read image","Memory allocation failed");
  2274.             DestroyImage(image);
  2275.             return((Image *) NULL);
  2276.           }
  2277.         for (i=0; i < image->colors; i++)
  2278.         {
  2279.           image->colormap[i].red=(unsigned char) i;
  2280.           image->colormap[i].green=(unsigned char) i;
  2281.           image->colormap[i].blue=(unsigned char) i;
  2282.         }
  2283.         /*
  2284.           Convert IRIS image to PseudoClass runlength-encoded packets.
  2285.         */
  2286.         for (y=0; y < image->rows; y++)
  2287.         {
  2288.           p=iris_pixels+((image->rows-1)-y)*(image->columns*4);
  2289.           for (x=0; x < image->columns; x++)
  2290.           {
  2291.             index=(unsigned short) (*p);
  2292.             q->red=image->colormap[index].red;
  2293.             q->green=image->colormap[index].green;
  2294.             q->blue=image->colormap[index].blue;
  2295.             q->index=index;
  2296.             q->length=0;
  2297.             p+=4;
  2298.             q++;
  2299.           }
  2300.         }
  2301.       }
  2302.     (void) free((char *) iris_pixels);
  2303.     /*
  2304.       Proceed to next image.
  2305.     */
  2306.     iris_header.magic=MSBFirstReadShort(image->file);
  2307.     if (iris_header.magic == 0x01DA)
  2308.       {
  2309.         /*
  2310.           Allocate image structure.
  2311.         */
  2312.         image->next=AllocateImage(image_info);
  2313.         if (image->next == (Image *) NULL)
  2314.           {
  2315.             DestroyImages(image);
  2316.             return((Image *) NULL);
  2317.           }
  2318.         (void) strcpy(image->next->filename,image_info->filename);
  2319.         image->next->file=image->file;
  2320.         image->next->scene=image->scene+1;
  2321.         image->next->previous=image;
  2322.         image=image->next;
  2323.       }
  2324.   } while (iris_header.magic == 0x01DA);
  2325.   while (image->previous != (Image *) NULL)
  2326.     image=image->previous;
  2327.   CloseImage(image);
  2328.   return(image);
  2329. }
  2330.  
  2331. #ifdef HasJPEG
  2332. #undef FREAD
  2333. #undef FWRITE
  2334. #undef const
  2335. #include "jinclude.h"
  2336. Image
  2337.   *jpeg_image;
  2338.  
  2339. /*
  2340. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2341. %                                                                             %
  2342. %                                                                             %
  2343. %                                                                             %
  2344. %  R e a d J P E G I m a g e                                                  %
  2345. %                                                                             %
  2346. %                                                                             %
  2347. %                                                                             %
  2348. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2349. %
  2350. %  Function ReadJPEGImage reads a JPEG image file and returns it.  It allocates
  2351. %  the memory necessary for the new Image structure and returns a pointer to
  2352. %  the new image.
  2353. %
  2354. %  The format of the ReadJPEGImage routine is:
  2355. %
  2356. %      image=ReadJPEGImage(image_info)
  2357. %
  2358. %  A description of each parameter follows:
  2359. %
  2360. %    o image:  Function ReadJPEGImage returns a pointer to the image after
  2361. %      reading.  A null image is returned if there is a a memory shortage or
  2362. %      if the image cannot be read.
  2363. %
  2364. %    o filename:  Specifies the name of the jpeg image to read.
  2365. %
  2366. %
  2367. */
  2368.  
  2369. static void MIFFInitializeImage(jpeg_info)
  2370. decompress_info_ptr
  2371.   jpeg_info;
  2372. {
  2373.   /*
  2374.     Create JPEG image.
  2375.   */
  2376.   jpeg_image->columns=jpeg_info->image_width;
  2377.   jpeg_image->rows=jpeg_info->image_height;
  2378.   jpeg_image->packets=jpeg_image->columns*jpeg_image->rows;
  2379.   jpeg_image->pixels=(RunlengthPacket *)
  2380.     malloc(jpeg_image->packets*sizeof(RunlengthPacket));
  2381.   if (jpeg_image->pixels == (RunlengthPacket *) NULL)
  2382.     {
  2383.       Warning("Memory allocation error",(char *) NULL);
  2384.       exit(1);
  2385.     }
  2386.   jpeg_image->packet=jpeg_image->pixels;
  2387. }
  2388.  
  2389. static void MIFFComment(jpeg_info,length)
  2390. decompress_info_ptr
  2391.   jpeg_info;
  2392.  
  2393. long
  2394.   length;
  2395. {
  2396.   register char
  2397.     *p;
  2398.  
  2399.   if (jpeg_image->comments != (char *) NULL)
  2400.     jpeg_image->comments=(char *) realloc((char *) jpeg_image->comments,
  2401.       (unsigned int) (strlen(jpeg_image->comments)+length+1)*sizeof(char));
  2402.   else
  2403.     {
  2404.       jpeg_image->comments=(char *)
  2405.         malloc((unsigned int) (length+1)*sizeof(char));
  2406.       if (jpeg_image->comments != (char *) NULL)
  2407.         *jpeg_image->comments='\0';
  2408.     }
  2409.   if (jpeg_image->comments == (char *) NULL)
  2410.     {
  2411.       Warning("Memory allocation error",(char *) NULL);
  2412.       return;
  2413.     }
  2414.   p=jpeg_image->comments+strlen(jpeg_image->comments);
  2415.   for ( ; length > 0; length--)
  2416.     *p++=JGETC(jpeg_info);
  2417.   *p='\0';
  2418. }
  2419.  
  2420. static void MIFFOutputTermMethod(jpeg_info)
  2421. decompress_info_ptr
  2422.   jpeg_info;
  2423. {
  2424. }
  2425.  
  2426. static void MIFFWriteGRAY(jpeg_info,number_rows,pixel_data)
  2427. decompress_info_ptr
  2428.   jpeg_info;
  2429.  
  2430. int
  2431.   number_rows;
  2432.  
  2433. JSAMPIMAGE
  2434.   pixel_data;
  2435. {
  2436.   register int
  2437.     column,
  2438.     row;
  2439.  
  2440.   register JSAMPROW
  2441.     gray;
  2442.  
  2443.   register RunlengthPacket
  2444.     *q;
  2445.  
  2446.   /*
  2447.     Transfer grayscale JPEG pixel data to MIFF pixels.
  2448.   */
  2449.   q=jpeg_image->packet;
  2450.   for (row=0; row < number_rows; row++)
  2451.   {
  2452.     gray=pixel_data[0][row];
  2453.     for (column=jpeg_info->image_width; column > 0; column--)
  2454.     {
  2455.       q->red=GETJSAMPLE(*gray);
  2456.       q->green=GETJSAMPLE(*gray);
  2457.       q->blue=GETJSAMPLE(*gray);
  2458.       q->index=(unsigned short) GETJSAMPLE(*gray);
  2459.       q->length=0;
  2460.       q++;
  2461.       gray++;
  2462.     }
  2463.   }
  2464.   jpeg_image->packet=q;
  2465. }
  2466.  
  2467. static void MIFFWriteRGB(jpeg_info,number_rows,pixel_data)
  2468. decompress_info_ptr
  2469.   jpeg_info;
  2470.  
  2471. int
  2472.   number_rows;
  2473.  
  2474. JSAMPIMAGE
  2475.   pixel_data;
  2476. {
  2477.   register int
  2478.     column,
  2479.     row;
  2480.  
  2481.   register JSAMPROW
  2482.     blue,
  2483.     green,
  2484.     red;
  2485.  
  2486.   register RunlengthPacket
  2487.     *q;
  2488.  
  2489.   /*
  2490.     Transfer JPEG pixel data to MIFF pixels.
  2491.   */
  2492.   q=jpeg_image->packet;
  2493.   for (row=0; row < number_rows; row++)
  2494.   {
  2495.     red=pixel_data[0][row];
  2496.     green=pixel_data[1][row];
  2497.     blue=pixel_data[2][row];
  2498.     for (column=jpeg_info->image_width; column > 0; column--)
  2499.     {
  2500.       q->red=GETJSAMPLE(*red++);
  2501.       q->green=GETJSAMPLE(*green++);
  2502.       q->blue=GETJSAMPLE(*blue++);
  2503.       q->index=0;
  2504.       q->length=0;
  2505.       q++;
  2506.     }
  2507.   }
  2508.   jpeg_image->packet=q;
  2509. }
  2510.  
  2511. static void MIFFSelectMethod(jpeg_info)
  2512. decompress_info_ptr
  2513.   jpeg_info;
  2514. {
  2515.   jpeg_info->methods->put_pixel_rows=MIFFWriteRGB;
  2516.   jpeg_info->out_color_space=CS_RGB;
  2517.   if (jpeg_info->jpeg_color_space == CS_GRAYSCALE)
  2518.     {
  2519.       jpeg_info->out_color_space=CS_GRAYSCALE;
  2520.       jpeg_info->methods->put_pixel_rows=MIFFWriteGRAY;
  2521.     }
  2522.   jpeg_info->data_precision=8;
  2523. }
  2524.  
  2525. static Image *ReadJPEGImage(image_info)
  2526. ImageInfo
  2527.   *image_info;
  2528. {
  2529.   Image
  2530.     *image;
  2531.  
  2532.   struct Decompress_info_struct
  2533.     jpeg_info;
  2534.  
  2535.   struct Decompress_methods_struct
  2536.     jpeg_methods;
  2537.  
  2538.   struct External_methods_struct
  2539.     external_methods;
  2540.  
  2541.   /*
  2542.     Allocate jpeg_image structure.
  2543.   */
  2544.   image=AllocateImage(image_info);
  2545.   if (image == (Image *) NULL)
  2546.     return((Image *) NULL);
  2547.   /*
  2548.     Open image file.
  2549.   */
  2550.   OpenImage(image,"r");
  2551.   if (image->file == (FILE *) NULL)
  2552.     {
  2553.       Warning("Unable to open file",image->filename);
  2554.       DestroyImage(image);
  2555.       return((Image *) NULL);
  2556.     }
  2557.   /*
  2558.     Initialize the JPEG system-dependent methods.
  2559.   */
  2560.   jpeg_image=image;
  2561.   jpeg_info.input_file=image->file;
  2562.   jpeg_info.output_file=(FILE *) NULL;
  2563.   jpeg_info.methods=(&jpeg_methods);
  2564.   jpeg_info.emethods=(&external_methods);
  2565.   jselerror(&external_methods);
  2566.   jselmemmgr(&external_methods);
  2567.   jpeg_info.methods->output_init=MIFFInitializeImage;
  2568.   jpeg_info.methods->output_term=MIFFOutputTermMethod;
  2569.   jpeg_methods.d_ui_method_selection=MIFFSelectMethod;
  2570.   j_d_defaults(&jpeg_info,True);
  2571. #ifdef HUFF_LOOKAHEAD
  2572.   jpeg_info.methods->process_comment=MIFFComment;
  2573. #endif
  2574.   /*
  2575.     Read a JFIF JPEG file.
  2576.   */
  2577.   jselrjfif(&jpeg_info);
  2578.   jpeg_decompress(&jpeg_info);
  2579.   if (jpeg_info.jpeg_color_space == CS_GRAYSCALE)
  2580.     {
  2581.       register int
  2582.         i;
  2583.  
  2584.       /*
  2585.         Initialize grayscale colormap.
  2586.       */
  2587.       jpeg_image->class=PseudoClass;
  2588.       jpeg_image->colors=256;
  2589.       jpeg_image->colormap=(ColorPacket *)
  2590.         malloc(image->colors*sizeof(ColorPacket));
  2591.       if (jpeg_image->colormap == (ColorPacket *) NULL)
  2592.         {
  2593.           Warning("Unable to create image colormap","Memory allocation failed");
  2594.           DestroyImage(jpeg_image);
  2595.           return((Image *) NULL);
  2596.         }
  2597.       for (i=0; i < jpeg_image->colors; i++)
  2598.       {
  2599.         jpeg_image->colormap[i].red=(unsigned short) i;
  2600.         jpeg_image->colormap[i].green=(unsigned short) i;
  2601.         jpeg_image->colormap[i].blue=(unsigned short) i;
  2602.       }
  2603.     }
  2604.   CloseImage(jpeg_image);
  2605.   return(jpeg_image);
  2606. }
  2607. #else
  2608. static Image *ReadJPEGImage(image_info)
  2609. ImageInfo
  2610.   *image_info;
  2611. {
  2612.   Warning("JPEG library is not available",image_info->filename);
  2613.   return(ReadMIFFImage(image_info));
  2614. }
  2615. #endif
  2616.  
  2617. /*
  2618. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2619. %                                                                             %
  2620. %                                                                             %
  2621. %                                                                             %
  2622. %  R e a d M A P I m a g e                                                    %
  2623. %                                                                             %
  2624. %                                                                             %
  2625. %                                                                             %
  2626. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2627. %
  2628. %  Function ReadMAPImage reads an image of raw RGB colormap and colormap index
  2629. %  bytes and returns it.  It allocates the memory necessary for the new Image
  2630. %  structure and returns a pointer to the new image.
  2631. %
  2632. %  The format of the ReadMAPImage routine is:
  2633. %
  2634. %      image=ReadMAPImage(image_info)
  2635. %
  2636. %  A description of each parameter follows:
  2637. %
  2638. %    o image:  Function ReadMAPImage returns a pointer to the image after
  2639. %      reading.  A null image is returned if there is a a memory shortage or
  2640. %      if the image cannot be read.
  2641. %
  2642. %    o image_info: Specifies a pointer to an ImageInfo structure.
  2643. %
  2644. %
  2645. */
  2646. static Image *ReadMAPImage(image_info)
  2647. ImageInfo
  2648.   *image_info;
  2649. {
  2650.   Image
  2651.     *image;
  2652.  
  2653.   int
  2654.     colors;
  2655.  
  2656.   register int
  2657.     i;
  2658.  
  2659.   register unsigned char
  2660.     *p;
  2661.  
  2662.   unsigned char
  2663.     *colormap;
  2664.  
  2665.   unsigned int
  2666.     height,
  2667.     packet_size,
  2668.     status,
  2669.     width;
  2670.  
  2671.   /*
  2672.     Allocate image structure.
  2673.   */
  2674.   image=AllocateImage(image_info);
  2675.   if (image == (Image *) NULL)
  2676.     return((Image *) NULL);
  2677.   /*
  2678.     Open image file.
  2679.   */
  2680.   OpenImage(image,"r");
  2681.   if (image->file == (FILE *) NULL)
  2682.     {
  2683.       Warning("Unable to open file",image->filename);
  2684.       DestroyImage(image);
  2685.       return((Image *) NULL);
  2686.     }
  2687.   /*
  2688.     Determine width, height, and number of colors, e.g. 640x512+256.
  2689.   */
  2690.   width=512;
  2691.   height=512;
  2692.   colors=256;
  2693.   if (image_info->geometry != (char *) NULL)
  2694.     (void) XParseGeometry(image_info->geometry,&colors,&colors,&width,&height);
  2695.   /*
  2696.     Initialize image structure.
  2697.   */
  2698.   image->class=PseudoClass;
  2699.   image->compression=NoCompression;
  2700.   image->columns=width;
  2701.   image->rows=height;
  2702.   image->colors=colors;
  2703.   image->packets=image->columns*image->rows;
  2704.   packet_size=1;
  2705.   if (image->colors > 256)
  2706.     packet_size++;
  2707.   colormap=(unsigned char *) malloc(3*image->colors*sizeof(unsigned char));
  2708.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  2709.   image->packed_pixels=(unsigned char *)
  2710.     malloc(image->packets*packet_size*sizeof(unsigned char));
  2711.   if ((colormap == (unsigned char *) NULL) ||
  2712.       (image->colormap == (ColorPacket *) NULL) ||
  2713.       (image->packed_pixels == (unsigned char *) NULL))
  2714.     {
  2715.       Warning("Memory allocation error",(char *) NULL);
  2716.       DestroyImage(image);
  2717.       return((Image *) NULL);
  2718.     }
  2719.   /*
  2720.     Read image colormap.
  2721.   */
  2722.   (void) ReadData((char *) colormap,3,(int) image->colors,image->file);
  2723.   p=colormap;
  2724.   for (i=0; i < image->colors; i++)
  2725.   {
  2726.     image->colormap[i].red=(*p++);
  2727.     image->colormap[i].green=(*p++);
  2728.     image->colormap[i].blue=(*p++);
  2729.   }
  2730.   (void) free((char *) colormap);
  2731.   /*
  2732.     Convert raster image to runlength-encoded packets.
  2733.   */
  2734.   (void) ReadData((char *) image->packed_pixels,packet_size,
  2735.     (int) image->packets,image->file);
  2736.   status=RunlengthDecodeImage(image);
  2737.   if (status == False)
  2738.     {
  2739.       DestroyImages(image);
  2740.       return((Image *) NULL);
  2741.     }
  2742.   CloseImage(image);
  2743.   return(image);
  2744. }
  2745.  
  2746. /*
  2747. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2748. %                                                                             %
  2749. %                                                                             %
  2750. %                                                                             %
  2751. %   R e a d M I F F I m a g e                                                 %
  2752. %                                                                             %
  2753. %                                                                             %
  2754. %                                                                             %
  2755. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2756. %
  2757. %  Function ReadMIFFImage reads a MIFF image file and returns it.  It
  2758. %  allocates the memory necessary for the new Image structure and returns a
  2759. %  pointer to the new image.
  2760. %
  2761. %  The format of the ReadMIFFImage routine is:
  2762. %
  2763. %      image=ReadMIFFImage(filename)
  2764. %
  2765. %  A description of each parameter follows:
  2766. %
  2767. %    o image: Function ReadMIFFImage returns a pointer to the image after
  2768. %      reading.  A null image is returned if there is a a memory shortage or
  2769. %      if the image cannot be read.
  2770. %
  2771. %    o image_info: Specifies a pointer to an ImageInfo structure.
  2772. %
  2773. %
  2774. */
  2775. static Image *ReadMIFFImage(image_info)
  2776. ImageInfo
  2777.   *image_info;
  2778. {
  2779.   char
  2780.     keyword[MaxTextLength],
  2781.     value[MaxTextLength];
  2782.  
  2783.   Image
  2784.     *image;
  2785.  
  2786.   register int
  2787.     c,
  2788.     i;
  2789.  
  2790.   register unsigned char
  2791.     *p;
  2792.  
  2793.   unsigned int
  2794.     length,
  2795.     packet_size,
  2796.     status;
  2797.  
  2798.   unsigned long
  2799.     count,
  2800.     packets;
  2801.  
  2802.   /*
  2803.     Allocate image structure.
  2804.   */
  2805.   image=AllocateImage(image_info);
  2806.   if (image == (Image *) NULL)
  2807.     return((Image *) NULL);
  2808.   /*
  2809.     Open image file.
  2810.   */
  2811.   OpenImage(image,"r");
  2812.   if (image->file == (FILE *) NULL)
  2813.     {
  2814.       Warning("Unable to open file",image->filename);
  2815.       DestroyImage(image);
  2816.       return((Image *) NULL);
  2817.     }
  2818.   /*
  2819.     Decode image header;  header terminates one character beyond a ':'.
  2820.   */
  2821.   c=fgetc(image->file);
  2822.   if (c == EOF)
  2823.     {
  2824.       DestroyImage(image);
  2825.       return((Image *) NULL);
  2826.     }
  2827.   do
  2828.   {
  2829.     /*
  2830.       Decode image header;  header terminates one character beyond a ':'.
  2831.     */
  2832.     image->compression=NoCompression;
  2833.     while (isgraph(c) && (c != ':'))
  2834.     {
  2835.       register char
  2836.         *p;
  2837.  
  2838.       if (c == '{')
  2839.         {
  2840.           /*
  2841.             Read comment-- any text between { }.
  2842.           */
  2843.           if (image->comments != (char *) NULL)
  2844.             {
  2845.               length=strlen(image->comments);
  2846.               p=image->comments+length;
  2847.             }
  2848.           else
  2849.             {
  2850.               length=MaxTextLength;
  2851.               image->comments=(char *) malloc(length*sizeof(char));
  2852.               p=image->comments;
  2853.             }
  2854.           for ( ; image->comments != (char *) NULL; p++)
  2855.           {
  2856.             c=fgetc(image->file);
  2857.             if ((c == EOF) || (c == '}'))
  2858.               break;
  2859.             if ((p-image->comments+1) >= length)
  2860.               {
  2861.                 length<<=1;
  2862.                 image->comments=(char *)
  2863.                   realloc((char *) image->comments,length*sizeof(char));
  2864.                 if (image->comments == (char *) NULL)
  2865.                   break;
  2866.                 p=image->comments+strlen(image->comments);
  2867.               }
  2868.             *p=(unsigned char) c;
  2869.           }
  2870.           if (image->comments == (char *) NULL)
  2871.             {
  2872.               Warning("Unable to read image","Memory allocation failed");
  2873.               DestroyImages(image);
  2874.               return((Image *) NULL);
  2875.             }
  2876.           *p='\0';
  2877.           c=fgetc(image->file);
  2878.         }
  2879.       else
  2880.         if (isalnum(c))
  2881.           {
  2882.             /*
  2883.               Determine a keyword and its value.
  2884.             */
  2885.             p=keyword;
  2886.             do
  2887.             {
  2888.               if ((p-keyword) < (MaxTextLength-1))
  2889.                 *p++=(char) c;
  2890.               c=fgetc(image->file);
  2891.             } while (isalnum(c));
  2892.             *p='\0';
  2893.             while (isspace(c) || (c == '='))
  2894.               c=fgetc(image->file);
  2895.             p=value;
  2896.             while (!isspace(c))
  2897.             {
  2898.               if ((p-value) < (MaxTextLength-1))
  2899.                 *p++=(char) c;
  2900.               c=fgetc(image->file);
  2901.             }
  2902.             *p='\0';
  2903.             /*
  2904.               Assign a value to the specified keyword.
  2905.             */
  2906.             if (strcmp(keyword,"alpha") == 0)
  2907.               if ((strcmp(value,"True") == 0) || (strcmp(value,"true") == 0))
  2908.                 image->alpha=True;
  2909.               else
  2910.                 image->class=False;
  2911.             if (strcmp(keyword,"class") == 0)
  2912.               if (strcmp(value,"PseudoClass") == 0)
  2913.                 image->class=PseudoClass;
  2914.               else
  2915.                 if (strcmp(value,"DirectClass") == 0)
  2916.                   image->class=DirectClass;
  2917.                 else
  2918.                   image->class=UndefinedClass;
  2919.             if (strcmp(keyword,"colors") == 0)
  2920.               image->colors=(unsigned int) atoi(value);
  2921.             if (strcmp(keyword,"compression") == 0)
  2922.               if (strcmp(value,"QEncoded") == 0)
  2923.                 image->compression=QEncodedCompression;
  2924.               else
  2925.                 if (strcmp(value,"RunlengthEncoded") == 0)
  2926.                   image->compression=RunlengthEncodedCompression;
  2927.                 else
  2928.                   image->compression=UndefinedCompression;
  2929.             if (strcmp(keyword,"columns") == 0)
  2930.               image->columns=(unsigned int) atoi(value);
  2931.             if (strcmp(keyword,"id") == 0)
  2932.               if (strcmp(value,"ImageMagick") == 0)
  2933.                 image->id=ImageMagickId;
  2934.               else
  2935.                 image->id=UndefinedId;
  2936.             if (strcmp(keyword,"montage") == 0)
  2937.               {
  2938.                 image->montage=(char *) malloc(strlen(value)+1*sizeof(char));
  2939.                 if (image->montage == (char *) NULL)
  2940.                   {
  2941.                     Warning("Unable to read image","Memory allocation failed");
  2942.                     DestroyImages(image);
  2943.                     return((Image *) NULL);
  2944.                   }
  2945.                 (void) strcpy(image->montage,value);
  2946.               }
  2947.             if (strcmp(keyword,"packets") == 0)
  2948.               image->packets=(unsigned int) atoi(value);
  2949.             if (strcmp(keyword,"rows") == 0)
  2950.               image->rows=(unsigned int) atoi(value);
  2951.             if (strcmp(keyword,"scene") == 0)
  2952.               image->scene=(unsigned int) atoi(value);
  2953.             if (strcmp(keyword,"signature") == 0)
  2954.               {
  2955.                 image->signature=(char *)
  2956.                   malloc((strlen(value)+1)*sizeof(char));
  2957.                 if (image->signature == (char *) NULL)
  2958.                   {
  2959.                     Warning("Unable to read image","Memory allocation failed");
  2960.                     DestroyImages(image);
  2961.                     return((Image *) NULL);
  2962.                   }
  2963.                 (void) strcpy(image->signature,value);
  2964.               }
  2965.           }
  2966.         else
  2967.           c=fgetc(image->file);
  2968.       while (isspace(c))
  2969.         c=fgetc(image->file);
  2970.     }
  2971.     (void) fgetc(image->file);
  2972.     /*
  2973.       Verify that required image information is defined.
  2974.     */
  2975.     if ((image->id == UndefinedId) || (image->class == UndefinedClass) ||
  2976.         (image->compression == UndefinedCompression) || (image->columns == 0) ||
  2977.         (image->rows == 0))
  2978.       {
  2979.         Warning("Incorrect image header in file",image->filename);
  2980.         DestroyImages(image);
  2981.         return((Image *) NULL);
  2982.       }
  2983.     if ((image->columns*image->rows) > MaxImageSize)
  2984.       {
  2985.         Warning("Unable to read image","image size too large");
  2986.         DestroyImages(image);
  2987.         return((Image *) NULL);
  2988.       }
  2989.     if (image->montage != (char *) NULL)
  2990.       {
  2991.         register char
  2992.           *p;
  2993.  
  2994.         /*
  2995.           Image directory.
  2996.         */
  2997.         image->directory=(char *) malloc(MaxTextLength*sizeof(char));
  2998.         if (image->directory == (char *) NULL)
  2999.           {
  3000.             Warning("Unable to read image","Memory allocation failed");
  3001.             DestroyImages(image);
  3002.             return((Image *) NULL);
  3003.           }
  3004.         p=image->directory;
  3005.         do
  3006.         {
  3007.           if ((((int) strlen(image->directory)+1) % MaxTextLength) == 0)
  3008.             {
  3009.               /*
  3010.                 Allocate more memory for the image directory.
  3011.               */
  3012.               image->directory=(char *) realloc((char *) image->directory,
  3013.                 (strlen(image->directory)+MaxTextLength+1)*sizeof(char));
  3014.               if (image->directory == (char *) NULL)
  3015.                 {
  3016.                   Warning("Unable to read image","Memory allocation failed");
  3017.                   DestroyImages(image);
  3018.                   return((Image *) NULL);
  3019.                 }
  3020.               p=image->directory+strlen(image->directory);
  3021.             }
  3022.           c=fgetc(image->file);
  3023.           *p++=(unsigned char) c;
  3024.         } while (c != '\0');
  3025.       }
  3026.     if (image->class == PseudoClass)
  3027.       {
  3028.         unsigned int
  3029.           colors;
  3030.  
  3031.         /*
  3032.           PseudoClass image cannot have alpha data or be QEncoded.
  3033.         */
  3034.         if (image->alpha)
  3035.           {
  3036.             Warning("Unable to read image","alpha images must be DirectClass");
  3037.             DestroyImages(image);
  3038.             return((Image *) NULL);
  3039.           }
  3040.         if (image->compression == QEncodedCompression)
  3041.           {
  3042.             Warning("Unable to read image",
  3043.               "QEncoded images must be DirectClass");
  3044.             DestroyImages(image);
  3045.             return((Image *) NULL);
  3046.           }
  3047.         /*
  3048.           Create image colormap.
  3049.         */
  3050.         colors=image->colors;
  3051.         if (colors == 0)
  3052.           colors=256;
  3053.         image->colormap=(ColorPacket *) malloc(colors*sizeof(ColorPacket));
  3054.         if (image->colormap == (ColorPacket *) NULL)
  3055.           {
  3056.             Warning("Unable to read image","Memory allocation failed");
  3057.             DestroyImages(image);
  3058.             return((Image *) NULL);
  3059.           }
  3060.         if (image->colors == 0)
  3061.           for (i=0; i < colors; i++)
  3062.           {
  3063.             image->colormap[i].red=(unsigned char) i;
  3064.             image->colormap[i].green=(unsigned char) i;
  3065.             image->colormap[i].blue=(unsigned char) i;
  3066.             image->colors++;
  3067.           }
  3068.         else
  3069.           {
  3070.             unsigned char
  3071.               *colormap;
  3072.  
  3073.             /*
  3074.               Read image colormap from file.
  3075.             */
  3076.             colormap=(unsigned char *)
  3077.               malloc(3*image->colors*sizeof(unsigned char));
  3078.             if (colormap == (unsigned char *) NULL)
  3079.               {
  3080.                 Warning("Unable to read image","Memory allocation failed");
  3081.                 DestroyImages(image);
  3082.                 return((Image *) NULL);
  3083.               }
  3084.             (void) ReadData((char *) colormap,1,(int) (3*image->colors),
  3085.               image->file);
  3086.             p=colormap;
  3087.             for (i=0; i < image->colors; i++)
  3088.             {
  3089.               image->colormap[i].red=(*p++);
  3090.               image->colormap[i].green=(*p++);
  3091.               image->colormap[i].blue=(*p++);
  3092.             }
  3093.             (void) free((char *) colormap);
  3094.           }
  3095.       }
  3096.     /*
  3097.       Determine packed packet size.
  3098.     */
  3099.     if (image->class == PseudoClass)
  3100.       {
  3101.         image->packet_size=1;
  3102.         if (image->colors > 256)
  3103.           image->packet_size++;
  3104.       }
  3105.     else
  3106.       {
  3107.         image->packet_size=3;
  3108.         if (image->alpha)
  3109.           image->packet_size++;
  3110.       }
  3111.     if (image->compression == RunlengthEncodedCompression)
  3112.       image->packet_size++;
  3113.     packet_size=image->packet_size;
  3114.     if (image->compression == QEncodedCompression)
  3115.       packet_size=1;
  3116.     /*
  3117.       Allocate image pixels.
  3118.     */
  3119.     if (image->compression == NoCompression)
  3120.       image->packets=image->columns*image->rows;
  3121.     packets=image->packets;
  3122.     if (image->packets == 0)
  3123.       packets=image->columns*image->rows;
  3124.     image->packed_pixels=(unsigned char *)
  3125.       malloc((unsigned int) packets*packet_size*sizeof(unsigned char));
  3126.     if (image->packed_pixels == (unsigned char *) NULL)
  3127.       {
  3128.         Warning("Unable to read image","Memory allocation failed");
  3129.         DestroyImages(image);
  3130.         return((Image *) NULL);
  3131.       }
  3132.     /*
  3133.       Read image pixels from file.
  3134.     */
  3135.     if ((image->compression != RunlengthEncodedCompression) ||
  3136.         (image->packets != 0))
  3137.       (void) ReadData((char *) image->packed_pixels,1,
  3138.         (int) (packets*packet_size),image->file);
  3139.     else
  3140.       {
  3141.         /*
  3142.           Number of runlength packets is unspecified.
  3143.         */
  3144.         count=0;
  3145.         p=image->packed_pixels;
  3146.         do
  3147.         {
  3148.           (void) ReadData((char *) p,1,(int) packet_size,image->file);
  3149.           image->packets++;
  3150.           p+=(packet_size-1);
  3151.           count+=(*p+1);
  3152.           p++;
  3153.         }
  3154.         while (count < (image->columns*image->rows));
  3155.       }
  3156.     if (image->compression ==  QEncodedCompression)
  3157.       {
  3158.         unsigned char
  3159.           *compressed_pixels;
  3160.  
  3161.         /*
  3162.           Uncompress image pixels with Q encoding.
  3163.         */
  3164.         image->packets=image->columns*image->rows;
  3165.         compressed_pixels=image->packed_pixels;
  3166.         image->packed_pixels=(unsigned char *) malloc((unsigned int)
  3167.           image->packets*image->packet_size*sizeof(unsigned char));
  3168.         if (image->packed_pixels == (unsigned char *) NULL)
  3169.           {
  3170.             Warning("Unable to write image","Memory allocation failed");
  3171.             DestroyImage(image);
  3172.             return(False);
  3173.           }
  3174.         packets=QDecodeImage(compressed_pixels,image->packed_pixels,
  3175.           image->columns*(int) image->packet_size,image->rows);
  3176.         if (packets != (image->packets*image->packet_size))
  3177.           {
  3178.             Warning("Q encoding failed",image->filename);
  3179.             DestroyImages(image);
  3180.             return((Image *) NULL);
  3181.           }
  3182.         (void) free((char *) compressed_pixels);
  3183.       }
  3184.     /*
  3185.       Unpack the packed image pixels into runlength-encoded pixel packets.
  3186.     */
  3187.     status=RunlengthDecodeImage(image);
  3188.     if (status == False)
  3189.       {
  3190.         DestroyImages(image);
  3191.         return((Image *) NULL);
  3192.       }
  3193.     /*
  3194.       Proceed to next image.
  3195.     */
  3196.     do
  3197.     {
  3198.       c=fgetc(image->file);
  3199.     } while (!isgraph(c) && (c != EOF));
  3200.     if (c != EOF)
  3201.       {
  3202.         /*
  3203.           Allocate image structure.
  3204.         */
  3205.         image->next=AllocateImage(image_info);
  3206.         if (image->next == (Image *) NULL)
  3207.           {
  3208.             DestroyImages(image);
  3209.             return((Image *) NULL);
  3210.           }
  3211.         (void) strcpy(image->next->filename,image_info->filename);
  3212.         image->next->file=image->file;
  3213.         image->next->scene=image->scene+1;
  3214.         image->next->previous=image;
  3215.         image=image->next;
  3216.       }
  3217.   } while (c != EOF);
  3218.   while (image->previous != (Image *) NULL)
  3219.     image=image->previous;
  3220.   CloseImage(image);
  3221.   return(image);
  3222. }
  3223.  
  3224. /*
  3225. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3226. %                                                                             %
  3227. %                                                                             %
  3228. %                                                                             %
  3229. %  R e a d M T V I m a g e                                                    %
  3230. %                                                                             %
  3231. %                                                                             %
  3232. %                                                                             %
  3233. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3234. %
  3235. %  Function ReadMTVImage reads a MTV image file and returns it.  It allocates
  3236. %  the memory necessary for the new Image structure and returns a pointer to
  3237. %  the new image.
  3238. %
  3239. %  The format of the ReadMTVImage routine is:
  3240. %
  3241. %      image=ReadMTVImage(image_info)
  3242. %
  3243. %  A description of each parameter follows:
  3244. %
  3245. %    o image:  Function ReadMTVImage returns a pointer to the image after
  3246. %      reading.  A null image is returned if there is a a memory shortage or
  3247. %      if the image cannot be read.
  3248. %
  3249. %    o image_info: Specifies a pointer to an ImageInfo structure.
  3250. %
  3251. %
  3252. */
  3253. static Image *ReadMTVImage(image_info)
  3254. ImageInfo
  3255.   *image_info;
  3256. {
  3257.   Image
  3258.     *image;
  3259.  
  3260.   int
  3261.     count;
  3262.  
  3263.   register int
  3264.     i;
  3265.  
  3266.   register RunlengthPacket
  3267.     *q;
  3268.  
  3269.   register unsigned char
  3270.     *p;
  3271.  
  3272.   unsigned char
  3273.     *mtv_pixels;
  3274.  
  3275.   unsigned int
  3276.     columns,
  3277.     rows;
  3278.  
  3279.   /*
  3280.     Allocate image structure.
  3281.   */
  3282.   image=AllocateImage(image_info);
  3283.   if (image == (Image *) NULL)
  3284.     return((Image *) NULL);
  3285.   /*
  3286.     Open image file.
  3287.   */
  3288.   OpenImage(image,"r");
  3289.   if (image->file == (FILE *) NULL)
  3290.     {
  3291.       Warning("Unable to open file",image->filename);
  3292.       DestroyImage(image);
  3293.       return((Image *) NULL);
  3294.     }
  3295.   /*
  3296.     Read MTV image.
  3297.   */
  3298.   count=fscanf(image->file,"%u %u\n",&columns,&rows);
  3299.   if (count == 0)
  3300.     {
  3301.       Warning("Not a MTV image,",image->filename);
  3302.       DestroyImage(image);
  3303.       return((Image *) NULL);
  3304.     }
  3305.   do
  3306.   {
  3307.     /*
  3308.       Initialize image structure.
  3309.     */
  3310.     image->columns=columns;
  3311.     image->rows=rows;
  3312.     image->packets=image->columns*image->rows;
  3313.     mtv_pixels=(unsigned char *) malloc(3*image->packets*sizeof(unsigned char));
  3314.     image->pixels=(RunlengthPacket *)
  3315.       malloc(image->packets*sizeof(RunlengthPacket));
  3316.     if ((mtv_pixels == (unsigned char *) NULL) ||
  3317.         (image->pixels == (RunlengthPacket *) NULL))
  3318.       {
  3319.         Warning("Memory allocation error",(char *) NULL);
  3320.         DestroyImages(image);
  3321.         return((Image *) NULL);
  3322.       }
  3323.     /*
  3324.       Convert MTV raster image to runlength-encoded packets.
  3325.     */
  3326.     (void) ReadData((char *) mtv_pixels,3,(int) image->packets,image->file);
  3327.     p=mtv_pixels;
  3328.     q=image->pixels;
  3329.     for (i=0; i < image->packets; i++)
  3330.     {
  3331.       q->red=(*p++);
  3332.       q->green=(*p++);
  3333.       q->blue=(*p++);
  3334.       q->index=0;
  3335.       q->length=0;
  3336.       q++;
  3337.     }
  3338.     (void) free((char *) mtv_pixels);
  3339.     /*
  3340.       Proceed to next image.
  3341.     */
  3342.     count=fscanf(image->file,"%u %u\n",&columns,&rows);
  3343.     if (count > 0)
  3344.       {
  3345.         /*
  3346.           Allocate next image structure.
  3347.         */
  3348.         image->next=AllocateImage(image_info);
  3349.         if (image->next == (Image *) NULL)
  3350.           {
  3351.             DestroyImages(image);
  3352.             return((Image *) NULL);
  3353.           }
  3354.         (void) strcpy(image->next->filename,image_info->filename);
  3355.         image->next->file=image->file;
  3356.         image->next->scene=image->scene+1;
  3357.         image->next->previous=image;
  3358.         image=image->next;
  3359.       }
  3360.   } while (count > 0);
  3361.   while (image->previous != (Image *) NULL)
  3362.     image=image->previous;
  3363.   CloseImage(image);
  3364.   return(image);
  3365. }
  3366.  
  3367. /*
  3368. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3369. %                                                                             %
  3370. %                                                                             %
  3371. %                                                                             %
  3372. %  R e a d P C D I m a g e                                                    %
  3373. %                                                                             %
  3374. %                                                                             %
  3375. %                                                                             %
  3376. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3377. %
  3378. %  Function ReadPCDImage reads a Photo CD image file and returns it.  It
  3379. %  allocates the memory necessary for the new Image structure and returns a
  3380. %  pointer to the new image.
  3381. %
  3382. %  The format of the ReadPCDImage routine is:
  3383. %
  3384. %      image=ReadPCDImage(image_info)
  3385. %
  3386. %  A description of each parameter follows:
  3387. %
  3388. %    o image:  Function ReadPCDImage returns a pointer to the image after
  3389. %      reading.  A null image is returned if there is a a memory shortage or
  3390. %      if the image cannot be read.
  3391. %
  3392. %    o image_info: Specifies a pointer to an ImageInfo structure.
  3393. %
  3394. %
  3395. */
  3396. static Image *ReadPCDImage(image_info)
  3397. ImageInfo
  3398.   *image_info;
  3399. {
  3400.   char
  3401.     filename[MaxTextLength],
  3402.     options[MaxTextLength];
  3403.  
  3404.   Image
  3405.     *image,
  3406.     *next_image;
  3407.  
  3408.   /*
  3409.     Allocate image structure.
  3410.   */
  3411.   image=AllocateImage(image_info);
  3412.   if (image == (Image *) NULL)
  3413.     return((Image *) NULL);
  3414.   /*
  3415.     Open image file.
  3416.   */
  3417.   OpenImage(image,"r");
  3418.   if (image->file == (FILE *) NULL)
  3419.     {
  3420.       Warning("Unable to open file",image->filename);
  3421.       DestroyImage(image);
  3422.       return((Image *) NULL);
  3423.     }
  3424.   CloseImage(image);
  3425.   DestroyImage(image);
  3426.   (void) strcpy(options,"-3");
  3427.   if (image_info->geometry != (char *) NULL)
  3428.     {
  3429.       int
  3430.         x,
  3431.         y;
  3432.  
  3433.       register int
  3434.         i;
  3435.  
  3436.       unsigned int
  3437.         height,
  3438.         width;
  3439.  
  3440.       /*
  3441.         Determine width and height, e.g. 640x512.
  3442.       */
  3443.       width=512;
  3444.       height=768;
  3445.       (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  3446.       for (i=1; i < 5; i++)
  3447.       {
  3448.         width>>=1;
  3449.         height>>=1;
  3450.         if ((width < 128) && (height < 192))
  3451.           break;
  3452.       }
  3453.       (void) sprintf(options,"-%d",i);
  3454.     }
  3455.   /*
  3456.     Use hpcdtoppm to convert Photo CD image.
  3457.   */
  3458.   (void) strcpy(filename,image_info->filename);
  3459.   (void) sprintf(image_info->filename,"|hpcdtoppm -ppm %s %s",options,filename);
  3460.   image=ReadPNMImage(image_info);
  3461.   if (image == (Image *) NULL)
  3462.     {
  3463.       Warning("Photo CD translation failed",image_info->filename);
  3464.       return((Image *) NULL);
  3465.     }
  3466.   /*
  3467.     Assign proper filename.
  3468.   */
  3469.   do
  3470.   {
  3471.     (void) strcpy(image->filename,filename);
  3472.     next_image=image->next;
  3473.     if (next_image != (Image *) NULL)
  3474.       image=next_image;
  3475.   } while (next_image != (Image *) NULL);
  3476.   while (image->previous != (Image *) NULL)
  3477.     image=image->previous;
  3478.   return(image);
  3479. }
  3480.  
  3481. /*
  3482. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3483. %                                                                             %
  3484. %                                                                             %
  3485. %                                                                             %
  3486. %  R e a d P C X I m a g e                                                    %
  3487. %                                                                             %
  3488. %                                                                             %
  3489. %                                                                             %
  3490. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3491. %
  3492. %  Function ReadPCXImage reads a ZSoft IBM PC Paintbrush file and returns it.
  3493. %  It allocates the memory necessary for the new Image structure and returns
  3494. %  a pointer to the new image.
  3495. %
  3496. %  The format of the ReadPCXImage routine is:
  3497. %
  3498. %      image=ReadPCXImage(image_info)
  3499. %
  3500. %  A description of each parameter follows:
  3501. %
  3502. %    o image:  Function ReadPCXImage returns a pointer to the image after
  3503. %      reading.  A null image is returned if there is a a memory shortage or
  3504. %      if the image cannot be read.
  3505. %
  3506. %    o image_info: Specifies a pointer to an ImageInfo structure.
  3507. %
  3508. %
  3509. */
  3510. static Image *ReadPCXImage(image_info)
  3511. ImageInfo
  3512.   *image_info;
  3513. {
  3514.   typedef struct _PCXHeader
  3515.   {
  3516.     unsigned char
  3517.       identifier,
  3518.       version,
  3519.       encoding,
  3520.       bits_per_pixel;
  3521.  
  3522.     short int
  3523.       left,
  3524.       top,
  3525.       right,
  3526.       bottom,
  3527.       horizontal_resolution,
  3528.       vertical_resolution;
  3529.  
  3530.     unsigned char
  3531.       reserved,
  3532.       planes;
  3533.  
  3534.     short int
  3535.       bytes_per_line,
  3536.       palette_info;
  3537.  
  3538.     unsigned char
  3539.       colormap_signature;
  3540.   } PCXHeader;
  3541.  
  3542.   PCXHeader
  3543.     pcx_header;
  3544.  
  3545.   Image
  3546.     *image;
  3547.  
  3548.   int
  3549.     count,
  3550.     packets;
  3551.  
  3552.   register int
  3553.     i,
  3554.     x,
  3555.     y;
  3556.  
  3557.   register RunlengthPacket
  3558.     *q;
  3559.  
  3560.   register unsigned char
  3561.     *p;
  3562.  
  3563.   unsigned char
  3564.     packet,
  3565.     *pcx_colormap,
  3566.     *pcx_pixels;
  3567.  
  3568.   unsigned int
  3569.     status;
  3570.  
  3571.   /*
  3572.     Allocate image structure.
  3573.   */
  3574.   image=AllocateImage(image_info);
  3575.   if (image == (Image *) NULL)
  3576.     return((Image *) NULL);
  3577.   /*
  3578.     Open image file.
  3579.   */
  3580.   OpenImage(image,"r");
  3581.   if (image->file == (FILE *) NULL)
  3582.     {
  3583.       Warning("Unable to open file",image->filename);
  3584.       DestroyImage(image);
  3585.       return((Image *) NULL);
  3586.     }
  3587.   /*
  3588.     Determine if this is a PCX file.
  3589.   */
  3590.   status=ReadData((char *) &pcx_header.identifier,1,1,image->file);
  3591.   do
  3592.   {
  3593.     /*
  3594.       Verify PCX identifier.
  3595.     */
  3596.     if ((status == False) || (pcx_header.identifier != 0x0a))
  3597.       {
  3598.         Warning("Not a PCX image file",(char *) NULL);
  3599.         DestroyImages(image);
  3600.         return((Image *) NULL);
  3601.       }
  3602.     (void) ReadData((char *) &pcx_header.version,1,1,image->file);
  3603.     (void) ReadData((char *) &pcx_header.encoding,1,1,image->file);
  3604.     (void) ReadData((char *) &pcx_header.bits_per_pixel,1,1,image->file);
  3605.     pcx_header.left=LSBFirstReadShort(image->file);
  3606.     pcx_header.top=LSBFirstReadShort(image->file);
  3607.     pcx_header.right=LSBFirstReadShort(image->file);
  3608.     pcx_header.bottom=LSBFirstReadShort(image->file);
  3609.     pcx_header.horizontal_resolution=LSBFirstReadShort(image->file);
  3610.     pcx_header.vertical_resolution=LSBFirstReadShort(image->file);
  3611.     /*
  3612.       Read PCX raster colormap.
  3613.     */
  3614.     image->columns=(pcx_header.right-pcx_header.left)+1;
  3615.     image->rows=(pcx_header.bottom-pcx_header.top)+1;
  3616.     image->class=PseudoClass;
  3617.     image->colors=16;
  3618.     image->colormap=(ColorPacket *) malloc(256*sizeof(ColorPacket));
  3619.     pcx_colormap=(unsigned char *) malloc(3*256*sizeof(unsigned char));
  3620.     if ((image->colormap == (ColorPacket *) NULL) ||
  3621.         (pcx_colormap == (unsigned char *) NULL))
  3622.       {
  3623.         Warning("Memory allocation error",(char *) NULL);
  3624.         DestroyImages(image);
  3625.         return((Image *) NULL);
  3626.       }
  3627.     (void) ReadData((char *) pcx_colormap,3,(int) image->colors,image->file);
  3628.     p=pcx_colormap;
  3629.     for (i=0; i < image->colors; i++)
  3630.     {
  3631.       image->colormap[i].red=(*p++);
  3632.       image->colormap[i].green=(*p++);
  3633.       image->colormap[i].blue=(*p++);
  3634.     }
  3635.     (void) ReadData((char *) &pcx_header.reserved,1,1,image->file);
  3636.     (void) ReadData((char *) &pcx_header.planes,1,1,image->file);
  3637.     pcx_header.bytes_per_line=LSBFirstReadShort(image->file);
  3638.     pcx_header.palette_info=LSBFirstReadShort(image->file);
  3639.     for (i=0; i < 58; i++)
  3640.       (void) fgetc(image->file);
  3641.     /*
  3642.       Read image data.
  3643.     */
  3644.     packets=image->rows*pcx_header.bytes_per_line*pcx_header.planes;
  3645.     pcx_pixels=(unsigned char *) malloc(packets*sizeof(unsigned char));
  3646.     if (pcx_pixels == (unsigned char *) NULL)
  3647.       {
  3648.         Warning("Memory allocation error",(char *) NULL);
  3649.         DestroyImages(image);
  3650.         return((Image *) NULL);
  3651.       }
  3652.     /*
  3653.       Uncompress image data.
  3654.     */
  3655.     p=pcx_pixels;
  3656.     while (packets > 0)
  3657.     {
  3658.       packet=fgetc(image->file);
  3659.       if ((packet & 0xc0) != 0xc0)
  3660.         {
  3661.           *p++=packet;
  3662.           packets--;
  3663.           continue;
  3664.         }
  3665.       count=packet & 0x3f;
  3666.       packet=fgetc(image->file);
  3667.       packets-=count;
  3668.       while (--count >= 0)
  3669.         *p++=packet;
  3670.     }
  3671.     image->colors=1 << (pcx_header.bits_per_pixel*pcx_header.planes);
  3672.     if (image->colors > 16)
  3673.       {
  3674.         /*
  3675.           256 color images have their color map at the end of the file.
  3676.         */
  3677.         (void) ReadData((char *) &pcx_header.colormap_signature,1,1,
  3678.           image->file);
  3679.         (void) ReadData((char *) pcx_colormap,3,(int) image->colors,
  3680.           image->file);
  3681.         p=pcx_colormap;
  3682.         for (i=0; i < image->colors; i++)
  3683.         {
  3684.           image->colormap[i].red=(*p++);
  3685.           image->colormap[i].green=(*p++);
  3686.           image->colormap[i].blue=(*p++);
  3687.         }
  3688.       }
  3689.     else
  3690.       if (image->colors == 2)
  3691.         if (Intensity(image->colormap[0]) == Intensity(image->colormap[1]))
  3692.           {
  3693.             /*
  3694.               Monochrome colormap.
  3695.             */
  3696.             image->colormap[0].red=MaxRGB;
  3697.             image->colormap[0].green=MaxRGB;
  3698.             image->colormap[0].blue=MaxRGB;
  3699.             image->colormap[1].red=0;
  3700.             image->colormap[1].green=0;
  3701.             image->colormap[1].blue=0;
  3702.           }
  3703.     (void) free((char *) pcx_colormap);
  3704.     /*
  3705.       Initialize image structure.
  3706.     */
  3707.     image->packets=image->columns*image->rows;
  3708.     image->pixels=(RunlengthPacket *)
  3709.       malloc(image->packets*sizeof(RunlengthPacket));
  3710.     if (image->pixels == (RunlengthPacket *) NULL)
  3711.       {
  3712.         Warning("Memory allocation error",(char *) NULL);
  3713.         DestroyImages(image);
  3714.         return((Image *) NULL);
  3715.       }
  3716.     /*
  3717.       Convert PCX raster image to runlength-encoded packets.
  3718.     */
  3719.     q=image->pixels;
  3720.     if (pcx_header.planes > 1)
  3721.       {
  3722.         register int
  3723.           bits,
  3724.           mask;
  3725.  
  3726.         /*
  3727.           Convert multi-plane format into runlength-encoded pixels.
  3728.         */
  3729.         for (i=0; i < image->packets; i++)
  3730.         {
  3731.           q->index=0;
  3732.           q->length=0;
  3733.           q++;
  3734.         }
  3735.         for (y=0; y < image->rows; y++)
  3736.         {
  3737.           p=pcx_pixels+(y*pcx_header.bytes_per_line*pcx_header.planes);
  3738.           for (i=0; i < (int) pcx_header.planes; i++)
  3739.           {
  3740.             q=image->pixels+y*image->columns;
  3741.             for (x=0; x < pcx_header.bytes_per_line; x++)
  3742.             {
  3743.               bits=(*p++);
  3744.               for (mask=0x80; mask != 0; mask>>=1)
  3745.               {
  3746.                 if (bits & mask)
  3747.                   q->index|=1 << i;
  3748.                 q++;
  3749.               }
  3750.             }
  3751.           }
  3752.         }
  3753.       }
  3754.     else
  3755.       for (y=0; y < image->rows; y++)
  3756.       {
  3757.         p=pcx_pixels+y*pcx_header.bytes_per_line;
  3758.         switch (pcx_header.bits_per_pixel)
  3759.         {
  3760.           case 1:
  3761.           {
  3762.             register int
  3763.               bit;
  3764.  
  3765.             for (x=0; x < (image->columns-7); x+=8)
  3766.             {
  3767.               for (bit=7; bit >= 0; bit--)
  3768.               {
  3769.                 q->index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
  3770.                 q->length=0;
  3771.                 q++;
  3772.               }
  3773.               p++;
  3774.             }
  3775.             if ((image->columns % 8) != 0)
  3776.               {
  3777.                 for (bit=7; bit >= (8-(image->columns % 8)); bit--)
  3778.                 {
  3779.                   q->index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
  3780.                   q->length=0;
  3781.                   q++;
  3782.                 }
  3783.                 p++;
  3784.               }
  3785.             break;
  3786.           }
  3787.           case 2:
  3788.           {
  3789.             for (x=0; x < (image->columns-3); x+=4)
  3790.             {
  3791.               q->index=(*p >> 6) & 0x3;
  3792.               q->length=0;
  3793.               q++;
  3794.               q->index=(*p >> 4) & 0x3;
  3795.               q->length=0;
  3796.               q++;
  3797.               q->index=(*p >> 2) & 0x3;
  3798.               q->length=0;
  3799.               q++;
  3800.               q->index=(*p) & 0x3;
  3801.               q->length=0;
  3802.               q++;
  3803.               p++;
  3804.             }
  3805.             if ((image->columns % 4) != 0)
  3806.               {
  3807.                 for (i=3; i >= (4-(image->columns % 4)); i--)
  3808.                 {
  3809.                   q->index=(*p >> (i*2)) & 0x03;
  3810.                   q->length=0;
  3811.                   q++;
  3812.                 }
  3813.                 p++;
  3814.               }
  3815.             break;
  3816.           }
  3817.           case 4:
  3818.           {
  3819.             for (x=0; x < (image->columns-1); x+=2)
  3820.             {
  3821.               q->index=(*p >> 4) & 0xf;
  3822.               q->length=0;
  3823.               q++;
  3824.               q->index=(*p) & 0xf;
  3825.               q->length=0;
  3826.               q++;
  3827.               p++;
  3828.             }
  3829.             if ((image->columns % 2) != 0)
  3830.               {
  3831.                 q->index=(*p >> 4) & 0xf;
  3832.                 q->length=0;
  3833.                 q++;
  3834.                 p++;
  3835.               }
  3836.             break;
  3837.           }
  3838.           case 8:
  3839.           {
  3840.             for (x=0; x < image->columns; x++)
  3841.             {
  3842.               q->index=(*p);
  3843.               q->length=0;
  3844.               q++;
  3845.               p++;
  3846.             }
  3847.             break;
  3848.           }
  3849.           default:
  3850.             break;
  3851.         }
  3852.       }
  3853.     (void) free((char *) pcx_pixels);
  3854.     SyncImage(image);
  3855.     /*
  3856.       Proceed to next image.
  3857.     */
  3858.     status=ReadData((char *) &pcx_header.identifier,1,1,image->file);
  3859.     if ((status == True) && (pcx_header.identifier == 0x0a))
  3860.       {
  3861.         /*
  3862.           Allocate image structure.
  3863.         */
  3864.         image->next=AllocateImage(image_info);
  3865.         if (image->next == (Image *) NULL)
  3866.           {
  3867.             DestroyImages(image);
  3868.             return((Image *) NULL);
  3869.           }
  3870.         (void) strcpy(image->next->filename,image_info->filename);
  3871.         image->next->file=image->file;
  3872.         image->next->scene=image->scene+1;
  3873.         image->next->previous=image;
  3874.         image=image->next;
  3875.       }
  3876.   } while ((status == True) && (pcx_header.identifier == 0x0a));
  3877.   while (image->previous != (Image *) NULL)
  3878.     image=image->previous;
  3879.   CloseImage(image);
  3880.   return(image);
  3881. }
  3882.  
  3883. /*
  3884. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3885. %                                                                             %
  3886. %                                                                             %
  3887. %                                                                             %
  3888. %  R e a d P I C T I m a g e                                                  %
  3889. %                                                                             %
  3890. %                                                                             %
  3891. %                                                                             %
  3892. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3893. %
  3894. %  Function ReadPICTImage reads an Apple Macintosh QuickDraw/PICT image file
  3895. %  and returns it.  It allocates the memory necessary for the new Image
  3896. %  structure and returns a pointer to the new image.
  3897. %
  3898. %  The format of the ReadPICTImage routine is:
  3899. %
  3900. %      image=ReadPICTImage(image_info)
  3901. %
  3902. %  A description of each parameter follows:
  3903. %
  3904. %    o image:  Function ReadPICTImage returns a pointer to the image after
  3905. %      reading.  A null image is returned if there is a a memory shortage or
  3906. %      if the image cannot be read.
  3907. %
  3908. %    o image_info: Specifies a pointer to an ImageInfo structure.
  3909. %
  3910. %
  3911. */
  3912. static Image *ReadPICTImage(image_info)
  3913. ImageInfo
  3914.   *image_info;
  3915. {
  3916.   char
  3917.     filename[MaxTextLength];
  3918.  
  3919.   Image
  3920.     *image,
  3921.     *next_image;
  3922.  
  3923.   /*
  3924.     Allocate image structure.
  3925.   */
  3926.   image=AllocateImage(image_info);
  3927.   if (image == (Image *) NULL)
  3928.     return((Image *) NULL);
  3929.   /*
  3930.     Open image file.
  3931.   */
  3932.   OpenImage(image,"r");
  3933.   if (image->file == (FILE *) NULL)
  3934.     {
  3935.       Warning("Unable to open file",image->filename);
  3936.       DestroyImage(image);
  3937.       return((Image *) NULL);
  3938.     }
  3939.   CloseImage(image);
  3940.   DestroyImage(image);
  3941.   /*
  3942.     Use picttoppm to convert Macintosh PICT image.
  3943.   */
  3944.   (void) strcpy(filename,image_info->filename);
  3945.   (void) sprintf(image_info->filename,"|picttoppm %s",filename);
  3946.   image=ReadPNMImage(image_info);
  3947.   if (image == (Image *) NULL)
  3948.     {
  3949.       Warning("PICT translation failed",image_info->filename);
  3950.       return((Image *) NULL);
  3951.     }
  3952.   /*
  3953.     Assign proper filename.
  3954.   */
  3955.   do
  3956.   {
  3957.     (void) strcpy(image->filename,filename);
  3958.     next_image=image->next;
  3959.     if (next_image != (Image *) NULL)
  3960.       image=next_image;
  3961.   } while (next_image != (Image *) NULL);
  3962.   while (image->previous != (Image *) NULL)
  3963.     image=image->previous;
  3964.   return(image);
  3965. }
  3966.  
  3967. /*
  3968. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3969. %                                                                             %
  3970. %                                                                             %
  3971. %                                                                             %
  3972. %  R e a d P N M I m a g e                                                    %
  3973. %                                                                             %
  3974. %                                                                             %
  3975. %                                                                             %
  3976. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3977. %
  3978. %  Function ReadPNMImage reads a Portable Anymap image file and returns it.
  3979. %  It allocates the memory necessary for the new Image structure and returns
  3980. %  a pointer to the new image.
  3981. %
  3982. %  The format of the ReadPNMImage routine is:
  3983. %
  3984. %      image=ReadPNMImage(image_info)
  3985. %
  3986. %  A description of each parameter follows:
  3987. %
  3988. %    o image:  Function ReadPNMImage returns a pointer to the image after
  3989. %      reading.  A null image is returned if there is a a memory shortage or
  3990. %      if the image cannot be read.
  3991. %
  3992. %    o image_info: Specifies a pointer to an ImageInfo structure.
  3993. %
  3994. %
  3995. */
  3996. static unsigned int GetInteger(image,base)
  3997. Image
  3998.   *image;
  3999.  
  4000. unsigned int
  4001.   base;
  4002. {
  4003.   int
  4004.     c;
  4005.  
  4006.   unsigned int
  4007.     value;
  4008.  
  4009.   /*
  4010.     Skip any leading whitespace.
  4011.   */
  4012.   do
  4013.   {
  4014.     c=fgetc(image->file);
  4015.     if (c == EOF)
  4016.       return(0);
  4017.     if (c == '#')
  4018.       {
  4019.         register char
  4020.           *p;
  4021.  
  4022.         unsigned int
  4023.           length;
  4024.  
  4025.         /*
  4026.           Read comment.
  4027.         */
  4028.         if (image->comments != (char *) NULL)
  4029.           {
  4030.             length=strlen(image->comments);
  4031.             p=image->comments+length;
  4032.           }
  4033.         else
  4034.           {
  4035.             length=MaxTextLength;
  4036.             image->comments=(char *) malloc(length*sizeof(char));
  4037.             p=image->comments;
  4038.           }
  4039.         for ( ; image->comments != (char *) NULL; p++)
  4040.         {
  4041.           if ((p-image->comments+2) >= length)
  4042.             {
  4043.               length<<=1;
  4044.               image->comments=(char *)
  4045.                 realloc((char *) image->comments,length*sizeof(char));
  4046.               if (image->comments == (char *) NULL)
  4047.                 break;
  4048.               p=image->comments+strlen(image->comments);
  4049.             }
  4050.           c=fgetc(image->file);
  4051.           if ((c == EOF) || (c == '\n'))
  4052.             break;
  4053.           *p=(unsigned char) c;
  4054.         }
  4055.         if (image->comments == (char *) NULL)
  4056.           {
  4057.             Warning("Memory allocation error",(char *) NULL);
  4058.             return(0);
  4059.           }
  4060.         *p++='\n';
  4061.         *p='\0';
  4062.       }
  4063.   } while (!isdigit(c));
  4064.   if (base == 2)
  4065.     return(c-'0');
  4066.   /*
  4067.     Evaluate number.
  4068.   */
  4069.   value=0;
  4070.   do
  4071.   {
  4072.     value*=10;
  4073.     value+=c-'0';
  4074.     c=fgetc(image->file);
  4075.     if (c == EOF)
  4076.       return(0);
  4077.   }
  4078.   while (isdigit(c));
  4079.   return(value);
  4080. }
  4081.  
  4082. static Image *ReadPNMImage(image_info)
  4083. ImageInfo
  4084.   *image_info;
  4085. {
  4086.   char
  4087.     format;
  4088.  
  4089.   Image
  4090.     *image;
  4091.  
  4092.   register int
  4093.     i;
  4094.  
  4095.   register RunlengthPacket
  4096.     *q;
  4097.  
  4098.   register unsigned char
  4099.     *p;
  4100.  
  4101.   unsigned char
  4102.     *pixels,
  4103.     *scale;
  4104.  
  4105.   unsigned int
  4106.     max_value,
  4107.     status;
  4108.  
  4109.   /*
  4110.     Allocate image structure.
  4111.   */
  4112.   image=AllocateImage(image_info);
  4113.   if (image == (Image *) NULL)
  4114.     return((Image *) NULL);
  4115.   /*
  4116.     Open image file.
  4117.   */
  4118.   OpenImage(image,"r");
  4119.   if (image->file == (FILE *) NULL)
  4120.     {
  4121.       Warning("Unable to open file",image->filename);
  4122.       DestroyImage(image);
  4123.       return((Image *) NULL);
  4124.     }
  4125.   /*
  4126.     Read PNM image.
  4127.   */
  4128.   status=ReadData((char *) &format,1,1,image->file);
  4129.   do
  4130.   {
  4131.     /*
  4132.       Verify PNM identifier.
  4133.     */
  4134.     if ((status == False) || (format != 'P'))
  4135.       {
  4136.         Warning("Not a PNM image file",(char *) NULL);
  4137.         DestroyImage(image);
  4138.         return((Image *) NULL);
  4139.       }
  4140.     /*
  4141.       Initialize image structure.
  4142.     */
  4143.     format=fgetc(image->file);
  4144.     image->columns=GetInteger(image,10);
  4145.     image->rows=GetInteger(image,10);
  4146.     image->packets=image->columns*image->rows;
  4147.     if (image->packets == 0)
  4148.       {
  4149.         Warning("Unable to read image","image dimensions are zero");
  4150.         return((Image *) NULL);
  4151.       }
  4152.     image->pixels=(RunlengthPacket *)
  4153.       malloc(image->packets*sizeof(RunlengthPacket));
  4154.     if (image->pixels == (RunlengthPacket *) NULL)
  4155.       {
  4156.         Warning("Memory allocation error",(char *) NULL);
  4157.         DestroyImages(image);
  4158.         return((Image *) NULL);
  4159.       }
  4160.     if ((format == '1') || (format == '4'))
  4161.       max_value=1;  /* bitmap */
  4162.     else
  4163.       max_value=GetInteger(image,10);
  4164.     scale=(unsigned char *) NULL;
  4165.     if (max_value != MaxRGB)
  4166.       {
  4167.         /*
  4168.           Compute pixel scaling table.
  4169.         */
  4170.         scale=(unsigned char *) malloc((max_value+1)*sizeof(unsigned char));
  4171.         if (scale == (unsigned char *) NULL)
  4172.           {
  4173.             Warning("Unable to read image","Memory allocation failed");
  4174.             DestroyImages(image);
  4175.             return((Image *) NULL);
  4176.           }
  4177.         for (i=0; i <= max_value; i++)
  4178.           scale[i]=(unsigned char) ((i*MaxRGB+(max_value >> 1))/max_value);
  4179.       }
  4180.     if ((format != '3') && (format != '6'))
  4181.       {
  4182.         /*
  4183.           Create gray scale colormap.
  4184.         */
  4185.         image->class=PseudoClass;
  4186.         image->colors=Min(max_value,MaxRGB)+1;
  4187.         image->colormap=(ColorPacket *)
  4188.           malloc(image->colors*sizeof(ColorPacket));
  4189.         if (image->colormap == (ColorPacket *) NULL)
  4190.           {
  4191.             Warning("Memory allocation error",(char *) NULL);
  4192.             DestroyImages(image);
  4193.             return((Image *) NULL);
  4194.           }
  4195.         for (i=0; i < image->colors; i++)
  4196.         {
  4197.           image->colormap[i].red=(MaxRGB*i)/(image->colors-1);
  4198.           image->colormap[i].green=(MaxRGB*i)/(image->colors-1);
  4199.           image->colormap[i].blue=(MaxRGB*i)/(image->colors-1);
  4200.         }
  4201.       }
  4202.     /*
  4203.       Convert PNM pixels to runlength-encoded MIFF packets.
  4204.     */
  4205.     q=image->pixels;
  4206.     switch (format)
  4207.     {
  4208.       case '1':
  4209.       {
  4210.         /*
  4211.           Convert PBM image to runlength-encoded packets.
  4212.         */
  4213.         for (i=0; i < image->packets; i++)
  4214.         {
  4215.           q->index=!GetInteger(image,2);
  4216.           q->length=0;
  4217.           q++;
  4218.         }
  4219.         SyncImage(image);
  4220.         break;
  4221.       }
  4222.       case '2':
  4223.       {
  4224.         /*
  4225.           Convert PGM image to runlength-encoded packets.
  4226.         */
  4227.         if (max_value == MaxRGB)
  4228.           for (i=0; i < image->packets; i++)
  4229.           {
  4230.             q->index=GetInteger(image,10);
  4231.             q->length=0;
  4232.             q++;
  4233.           }
  4234.         else
  4235.           for (i=0; i < image->packets; i++)
  4236.           {
  4237.             q->index=scale[GetInteger(image,10)];
  4238.             q->length=0;
  4239.             q++;
  4240.           }
  4241.         SyncImage(image);
  4242.         break;
  4243.       }
  4244.       case '3':
  4245.       {
  4246.         /*
  4247.           Convert PNM image to runlength-encoded packets.
  4248.         */
  4249.         if (max_value == MaxRGB)
  4250.           for (i=0; i < image->packets; i++)
  4251.           {
  4252.             q->red=GetInteger(image,10);
  4253.             q->green=GetInteger(image,10);
  4254.             q->blue=GetInteger(image,10);
  4255.             q->index=0;
  4256.             q->length=0;
  4257.             q++;
  4258.           }
  4259.         else
  4260.           for (i=0; i < image->packets; i++)
  4261.           {
  4262.             q->red=scale[GetInteger(image,10)];
  4263.             q->green=scale[GetInteger(image,10)];
  4264.             q->blue=scale[GetInteger(image,10)];
  4265.             q->index=0;
  4266.             q->length=0;
  4267.             q++;
  4268.           }
  4269.         break;
  4270.       }
  4271.       case '4':
  4272.       {
  4273.         unsigned char
  4274.           bit,
  4275.           byte;
  4276.  
  4277.         unsigned int
  4278.           x,
  4279.           y;
  4280.  
  4281.         /*
  4282.           Convert PBM raw image to runlength-encoded packets.
  4283.         */
  4284.         for (y=0; y < image->rows; y++)
  4285.         {
  4286.           bit=0;
  4287.           byte=0;
  4288.           for (x=0; x < image->columns; x++)
  4289.           {
  4290.             if (bit == 0)
  4291.               byte=fgetc(image->file);
  4292.             q->index=(byte & 0x80) ? 0 : 1;
  4293.             q->length=0;
  4294.             q++;
  4295.             bit++;
  4296.             if (bit == 8)
  4297.               bit=0;
  4298.             byte<<=1;
  4299.           }
  4300.         }
  4301.         SyncImage(image);
  4302.         break;
  4303.       }
  4304.       case '5':
  4305.       {
  4306.         /*
  4307.           Convert PGM raw image to runlength-encoded packets.
  4308.         */
  4309.         pixels=(unsigned char *)
  4310.           malloc(image->packets*sizeof(unsigned char));
  4311.         if (pixels == (unsigned char *) NULL)
  4312.           {
  4313.             Warning("Memory allocation error",(char *) NULL);
  4314.             DestroyImages(image);
  4315.             return((Image *) NULL);
  4316.           }
  4317.         status=ReadData((char *) pixels,1,(int) image->packets,image->file);
  4318.         if (status == False)
  4319.           {
  4320.             Warning("Insufficient image data in file",image->filename);
  4321.             DestroyImages(image);
  4322.             return((Image *) NULL);
  4323.           }
  4324.         /*
  4325.           Convert PNM raw image to runlength-encoded packets.
  4326.         */
  4327.         p=pixels;
  4328.         for (i=0; i < image->packets; i++)
  4329.         {
  4330.           q->index=(*p++);
  4331.           q->length=0;
  4332.           q++;
  4333.         }
  4334.         SyncImage(image);
  4335.         (void) free((char *) pixels);
  4336.         break;
  4337.       }
  4338.       case '6':
  4339.       {
  4340.         /*
  4341.           Convert PNM raster image to runlength-encoded packets.
  4342.         */
  4343.         pixels=(unsigned char *)
  4344.           malloc(image->packets*3*sizeof(unsigned char));
  4345.         if (pixels == (unsigned char *) NULL)
  4346.           {
  4347.             Warning("Memory allocation error",(char *) NULL);
  4348.             DestroyImages(image);
  4349.             return((Image *) NULL);
  4350.           }
  4351.         status=ReadData((char *) pixels,1,(int) image->packets*3,image->file);
  4352.         if (status == False)
  4353.           {
  4354.             Warning("Insufficient image data in file",image->filename);
  4355.             DestroyImages(image);
  4356.             return((Image *) NULL);
  4357.           }
  4358.         p=pixels;
  4359.         if (max_value == MaxRGB)
  4360.           for (i=0; i < image->packets; i++)
  4361.           {
  4362.             q->red=(*p++);
  4363.             q->green=(*p++);
  4364.             q->blue=(*p++);
  4365.             q->index=0;
  4366.             q->length=0;
  4367.             q++;
  4368.           }
  4369.         else
  4370.           for (i=0; i < image->packets; i++)
  4371.           {
  4372.             q->red=scale[*p++];
  4373.             q->green=scale[*p++];
  4374.             q->blue=scale[*p++];
  4375.             q->index=0;
  4376.             q->length=0;
  4377.             q++;
  4378.           }
  4379.         (void) free((char *) pixels);
  4380.         break;
  4381.       }
  4382.       default:
  4383.       {
  4384.         Warning("Not a PNM image file",(char *) NULL);
  4385.         DestroyImages(image);
  4386.         return((Image *) NULL);
  4387.       }
  4388.     }
  4389.     if (scale != (unsigned char *) NULL)
  4390.       (void) free((char *) scale);
  4391.     if (image->class == PseudoClass)
  4392.       CompressColormap(image);
  4393.     /*
  4394.       Proceed to next image.
  4395.     */
  4396.     if ((format == '1') || (format == '2') || (format == '3'))
  4397.       do
  4398.       {
  4399.         /*
  4400.           Skip to end of line.
  4401.         */
  4402.         status=ReadData(&format,1,1,image->file);
  4403.         if (status == False)
  4404.           break;
  4405.       } while (format != '\n');
  4406.     status=ReadData((char *) &format,1,1,image->file);
  4407.     if ((status == True) && (format == 'P'))
  4408.       {
  4409.         /*
  4410.           Allocate image structure.
  4411.         */
  4412.         image->next=AllocateImage(image_info);
  4413.         if (image->next == (Image *) NULL)
  4414.           {
  4415.             DestroyImages(image);
  4416.             return((Image *) NULL);
  4417.           }
  4418.         (void) strcpy(image->next->filename,image_info->filename);
  4419.         image->next->file=image->file;
  4420.         image->next->scene=image->scene+1;
  4421.         image->next->previous=image;
  4422.         image=image->next;
  4423.       }
  4424.   } while ((status == True) && (format == 'P'));
  4425.   while (image->previous != (Image *) NULL)
  4426.     image=image->previous;
  4427.   CloseImage(image);
  4428.   return(image);
  4429. }
  4430.  
  4431. /*
  4432. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4433. %                                                                             %
  4434. %                                                                             %
  4435. %                                                                             %
  4436. %  R e a d P S I m a g e                                                      %
  4437. %                                                                             %
  4438. %                                                                             %
  4439. %                                                                             %
  4440. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4441. %
  4442. %  Function ReadPSImage reads a Adobe Postscript image file and returns it.  It
  4443. %  allocates the memory necessary for the new Image structure and returns a
  4444. %  pointer to the new image.
  4445. %
  4446. %  The format of the ReadPSImage routine is:
  4447. %
  4448. %      image=ReadPSImage(image_info)
  4449. %
  4450. %  A description of each parameter follows:
  4451. %
  4452. %    o image:  Function ReadPSImage returns a pointer to the image after
  4453. %      reading.  A null image is returned if there is a a memory shortage or
  4454. %      if the image cannot be read.
  4455. %
  4456. %    o image_info: Specifies a pointer to an ImageInfo structure.
  4457. %
  4458. %
  4459. */
  4460. static Image *ReadPSImage(image_info)
  4461. ImageInfo
  4462.   *image_info;
  4463. {
  4464.   char
  4465.     command[MaxTextLength],
  4466.     clip_geometry[MaxTextLength],
  4467.     *device,
  4468.     filename[MaxTextLength],
  4469.     options[MaxTextLength];
  4470.  
  4471.   Image
  4472.     *image,
  4473.     *next_image;
  4474.  
  4475.   /*
  4476.     Allocate image structure.
  4477.   */
  4478.   image=AllocateImage(image_info);
  4479.   if (image == (Image *) NULL)
  4480.     return((Image *) NULL);
  4481.   /*
  4482.     Open image file.
  4483.   */
  4484.   OpenImage(image,"r");
  4485.   if (image->file == (FILE *) NULL)
  4486.     {
  4487.       Warning("Unable to open file",image->filename);
  4488.       DestroyImage(image);
  4489.       return((Image *) NULL);
  4490.     }
  4491.   /*
  4492.     Determine if Postscript specifies a bounding box.
  4493.   */
  4494.   *options='\0';
  4495.   *clip_geometry='\0';
  4496.   while (fgets(command,MaxTextLength,image->file) != (char *) NULL)
  4497.     if (strncmp("%%BoundingBox:",command,strlen("%%BoundingBox:")) == 0)
  4498.       {
  4499.         int
  4500.           count,
  4501.           lower_x,
  4502.           lower_y,
  4503.           upper_x,
  4504.           upper_y,
  4505.           x,
  4506.           y;
  4507.  
  4508.         unsigned int
  4509.           dx_resolution,
  4510.           dy_resolution,
  4511.           x_resolution,
  4512.           y_resolution;
  4513.  
  4514.         count=sscanf(command,"%%%%BoundingBox: %d %d %d %d",&lower_x,&lower_y,
  4515.           &upper_x,&upper_y);
  4516.         if (count != 4)
  4517.           break;
  4518.         /*
  4519.           Set clip geometry as specified by the bounding box.
  4520.         */
  4521.         (void) XParseGeometry(PSDensityGeometry,&x,&y,&dx_resolution,
  4522.           &dy_resolution);
  4523.         x_resolution=dx_resolution;
  4524.         y_resolution=dy_resolution;
  4525.         (void) XParseGeometry(image_info->density,&x,&y,&x_resolution,
  4526.           &y_resolution);
  4527.         (void) sprintf(clip_geometry,"%ux%u+%u-%u",
  4528.           ((upper_x-lower_x)*x_resolution)/dx_resolution,
  4529.           ((upper_y-lower_y)*y_resolution)/dy_resolution,
  4530.           (lower_x*x_resolution)/dx_resolution,
  4531.           (lower_y*y_resolution)/dy_resolution);
  4532.         if (image_info->page == (char *) NULL)
  4533.           (void) sprintf(options,"-g%ux%u",(upper_x*x_resolution)/dx_resolution,
  4534.             (upper_y*y_resolution)/dy_resolution);
  4535.         break;
  4536.       }
  4537.   CloseImage(image);
  4538.   DestroyImage(image);
  4539.   /*
  4540.     Determine if page geometry or density options are specified.
  4541.   */
  4542.   if (image_info->page != (char *) NULL)
  4543.     {
  4544.       (void) strcat(options," -g");
  4545.       (void) strcat(options,image_info->page);
  4546.     }
  4547.   if (image_info->density != (char *) NULL)
  4548.     {
  4549.       (void) strcat(options," -r");
  4550.       (void) strcat(options,image_info->density);
  4551.     }
  4552.   /*
  4553.     Use Ghostscript to convert Postscript image.
  4554.   */
  4555.   device="ppmraw";
  4556.   if (image_info->monochrome)
  4557.     device="pbmraw";
  4558.   (void) strcpy(filename,image_info->filename);
  4559.   (void) sprintf(image_info->filename,
  4560.     "|gs -q -dNOPAUSE -sDEVICE=%s -sOutputFile=- %s %s < /dev/null",
  4561.     device,options,filename);
  4562.   image=ReadPNMImage(image_info);
  4563.   if (image == (Image *) NULL)
  4564.     {
  4565.       Warning("Postscript translation failed",image_info->filename);
  4566.       return((Image *) NULL);
  4567.     }
  4568.   do
  4569.   {
  4570.     (void) strcpy(image->filename,filename);
  4571.     if (*clip_geometry != '\0')
  4572.       {
  4573.         /*
  4574.           Clip image as specified by the bounding box.
  4575.         */
  4576.         TransformImage(&image,clip_geometry,(char *) NULL);
  4577.         if (image->next != (Image *) NULL)
  4578.           image->next->previous=image;
  4579.       }
  4580.     next_image=image->next;
  4581.     if (next_image != (Image *) NULL)
  4582.       image=next_image;
  4583.   } while (next_image != (Image *) NULL);
  4584.   while (image->previous != (Image *) NULL)
  4585.     image=image->previous;
  4586.   return(image);
  4587. }
  4588.  
  4589. /*
  4590. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4591. %                                                                             %
  4592. %                                                                             %
  4593. %                                                                             %
  4594. %  R e a d R G B I m a g e                                                    %
  4595. %                                                                             %
  4596. %                                                                             %
  4597. %                                                                             %
  4598. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4599. %
  4600. %  Function ReadRGBImage reads an image of raw red, green, and blue bytes and
  4601. %  returns it.  It allocates the memory necessary for the new Image structure
  4602. %  and returns a pointer to the new image.
  4603. %
  4604. %  The format of the ReadRGBImage routine is:
  4605. %
  4606. %      image=ReadRGBImage(image_info)
  4607. %
  4608. %  A description of each parameter follows:
  4609. %
  4610. %    o image:  Function ReadRGBImage returns a pointer to the image after
  4611. %      reading.  A null image is returned if there is a a memory shortage or
  4612. %      if the image cannot be read.
  4613. %
  4614. %    o image_info: Specifies a pointer to an ImageInfo structure.
  4615. %
  4616. %
  4617. */
  4618. static Image *ReadRGBImage(image_info)
  4619. ImageInfo
  4620.   *image_info;
  4621. {
  4622.   Image
  4623.     *image;
  4624.  
  4625.   int
  4626.     x,
  4627.     y;
  4628.  
  4629.   register int
  4630.     i;
  4631.  
  4632.   register RunlengthPacket
  4633.     *q;
  4634.  
  4635.   register unsigned char
  4636.     *p;
  4637.  
  4638.   unsigned char
  4639.     *rgb_pixels;
  4640.  
  4641.   unsigned int
  4642.     height,
  4643.     width;
  4644.  
  4645.   /*
  4646.     Allocate image structure.
  4647.   */
  4648.   image=AllocateImage(image_info);
  4649.   if (image == (Image *) NULL)
  4650.     return((Image *) NULL);
  4651.   /*
  4652.     Open image file.
  4653.   */
  4654.   OpenImage(image,"r");
  4655.   if (image->file == (FILE *) NULL)
  4656.     {
  4657.       Warning("Unable to open file",image->filename);
  4658.       DestroyImage(image);
  4659.       return((Image *) NULL);
  4660.     }
  4661.   /*
  4662.     Determine width and height, e.g. 640x512.
  4663.   */
  4664.   width=512;
  4665.   height=512;
  4666.   if (image_info->geometry != (char *) NULL)
  4667.     (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  4668.   /*
  4669.     Initialize image structure.
  4670.   */
  4671.   image->columns=width;
  4672.   image->rows=height;
  4673.   image->packets=image->columns*image->rows;
  4674.   rgb_pixels=(unsigned char *) malloc(3*image->packets*sizeof(unsigned char));
  4675.   image->pixels=(RunlengthPacket *)
  4676.     malloc(image->packets*sizeof(RunlengthPacket));
  4677.   if ((rgb_pixels == (unsigned char *) NULL) ||
  4678.       (image->pixels == (RunlengthPacket *) NULL))
  4679.     {
  4680.       Warning("Memory allocation error",(char *) NULL);
  4681.       DestroyImage(image);
  4682.       return((Image *) NULL);
  4683.     }
  4684.   /*
  4685.     Convert raster image to runlength-encoded packets.
  4686.   */
  4687.   (void) ReadData((char *) rgb_pixels,3,(int) image->packets,image->file);
  4688.   p=rgb_pixels;
  4689.   switch (image_info->interlace)
  4690.   {
  4691.     case NoneInterlace:
  4692.     default:
  4693.     {
  4694.       /*
  4695.         No interlacing:  RGBRGBRGBRGBRGBRGB...
  4696.       */
  4697.       q=image->pixels;
  4698.       for (i=0; i < image->packets; i++)
  4699.       {
  4700.         q->red=(*p++);
  4701.         q->green=(*p++);
  4702.         q->blue=(*p++);
  4703.         q->index=0;
  4704.         q->length=0;
  4705.         q++;
  4706.       }
  4707.       break;
  4708.     }
  4709.     case LineInterlace:
  4710.     {
  4711.       /*
  4712.         Line interlacing:  RRR...GGG...BBB...RRR...GGG...BBB...
  4713.       */
  4714.       for (y=0; y < image->rows; y++)
  4715.       {
  4716.         q=image->pixels+y*image->columns;
  4717.         for (x=0; x < image->columns; x++)
  4718.         {
  4719.           q->red=(*p++);
  4720.           q->index=0;
  4721.           q->length=0;
  4722.           q++;
  4723.         }
  4724.         q=image->pixels+y*image->columns;
  4725.         for (x=0; x < image->columns; x++)
  4726.         {
  4727.           q->green=(*p++);
  4728.           q++;
  4729.         }
  4730.         q=image->pixels+y*image->columns;
  4731.         for (x=0; x < image->columns; x++)
  4732.         {
  4733.           q->blue=(*p++);
  4734.           q++;
  4735.         }
  4736.       }
  4737.       break;
  4738.     }
  4739.     case PlaneInterlace:
  4740.     {
  4741.       /*
  4742.         Plane interlacing:  RRRRRR...GGGGGG...BBBBBB...
  4743.       */
  4744.       q=image->pixels;
  4745.       for (i=0; i < image->packets; i++)
  4746.       {
  4747.         q->red=(*p++);
  4748.         q->index=0;
  4749.         q->length=0;
  4750.         q++;
  4751.       }
  4752.       q=image->pixels;
  4753.       for (i=0; i < image->packets; i++)
  4754.       {
  4755.         q->green=(*p++);
  4756.         q++;
  4757.       }
  4758.       q=image->pixels;
  4759.       for (i=0; i < image->packets; i++)
  4760.       {
  4761.         q->blue=(*p++);
  4762.         q++;
  4763.       }
  4764.       break;
  4765.     }
  4766.   }
  4767.   (void) free((char *) rgb_pixels);
  4768.   CloseImage(image);
  4769.   return(image);
  4770. }
  4771.  
  4772. /*
  4773. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4774. %                                                                             %
  4775. %                                                                             %
  4776. %                                                                             %
  4777. %  R e a d R L E I m a g e                                                    %
  4778. %                                                                             %
  4779. %                                                                             %
  4780. %                                                                             %
  4781. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4782. %
  4783. %  Function ReadRLEImage reads a run-length encoded Utah Raster Toolkit
  4784. %  image file and returns it.  It allocates the memory necessary for the new
  4785. %  Image structure and returns a pointer to the new image.
  4786. %
  4787. %  The format of the ReadRLEImage routine is:
  4788. %
  4789. %      image=ReadRLEImage(image_info)
  4790. %
  4791. %  A description of each parameter follows:
  4792. %
  4793. %    o image:  Function ReadRLEImage returns a pointer to the image after
  4794. %      reading.  A null image is returned if there is a a memory shortage or
  4795. %      if the image cannot be read.
  4796. %
  4797. %    o image_info: Specifies a pointer to an ImageInfo structure.
  4798. %
  4799. %
  4800. */
  4801. static Image *ReadRLEImage(image_info)
  4802. ImageInfo
  4803.   *image_info;
  4804. {
  4805. #define SkipLinesOp  0x01
  4806. #define SetColorOp  0x02
  4807. #define SkipPixelsOp  0x03
  4808. #define ByteDataOp  0x05
  4809. #define RunDataOp  0x06
  4810. #define EOFOp  0x07
  4811.  
  4812.   char
  4813.     magick[12];
  4814.  
  4815.   Image
  4816.     *image;
  4817.  
  4818.   int
  4819.     opcode,
  4820.     operand,
  4821.     status,
  4822.     x,
  4823.     y;
  4824.  
  4825.   register int
  4826.     i,
  4827.     j;
  4828.  
  4829.   register RunlengthPacket
  4830.     *q;
  4831.  
  4832.   register unsigned char
  4833.     *p;
  4834.  
  4835.   unsigned char
  4836.     background_color[256],
  4837.     *colormap,
  4838.     pixel,
  4839.     plane,
  4840.     *rle_pixels;
  4841.  
  4842.   unsigned int
  4843.     bits_per_pixel,
  4844.     flags,
  4845.     map_length,
  4846.     number_colormaps,
  4847.     number_planes;
  4848.  
  4849.   /*
  4850.     Allocate image structure.
  4851.   */
  4852.   image=AllocateImage(image_info);
  4853.   if (image == (Image *) NULL)
  4854.     return((Image *) NULL);
  4855.   /*
  4856.     Open image file.
  4857.   */
  4858.   OpenImage(image,"r");
  4859.   if (image->file == (FILE *) NULL)
  4860.     {
  4861.       Warning("Unable to open file",image->filename);
  4862.       DestroyImage(image);
  4863.       return((Image *) NULL);
  4864.     }
  4865.   /*
  4866.     Determine if this is a RLE file.
  4867.   */
  4868.   status=ReadData((char *) magick,1,2,image->file);
  4869.   if ((status == False) || (strncmp(magick,"\122\314",2) != 0))
  4870.     {
  4871.       Warning("Not a RLE image file",(char *) NULL);
  4872.       DestroyImage(image);
  4873.       return((Image *) NULL);
  4874.     }
  4875.   do
  4876.   {
  4877.     /*
  4878.       Read image header.
  4879.     */
  4880.     (void) LSBFirstReadShort(image->file);
  4881.     (void) LSBFirstReadShort(image->file);
  4882.     image->columns=LSBFirstReadShort(image->file);
  4883.     image->rows=LSBFirstReadShort(image->file);
  4884.     image->packets=image->columns*image->rows;
  4885.     flags=fgetc(image->file);
  4886.     image->alpha=flags & 0x04;
  4887.     number_planes=fgetc(image->file);
  4888.     bits_per_pixel=fgetc(image->file);
  4889.     number_colormaps=fgetc(image->file);
  4890.     map_length=1 << fgetc(image->file);
  4891.     if ((number_planes == 0) || (number_planes == 2) || (bits_per_pixel != 8) ||
  4892.         (image->columns == 0))
  4893.       {
  4894.         Warning("Unsupported RLE image file",(char *) NULL);
  4895.         DestroyImage(image);
  4896.         return((Image *) NULL);
  4897.       }
  4898.     if (flags & 0x02)
  4899.       {
  4900.         /*
  4901.           No background color-- initialize to black.
  4902.         */
  4903.         for (i=0; i < number_planes; i++)
  4904.           background_color[i]=(unsigned char) 0;
  4905.         (void) fgetc(image->file);
  4906.       }
  4907.     else
  4908.       {
  4909.         /*
  4910.           Initialize background color.
  4911.         */
  4912.         p=background_color;
  4913.         for (i=0; i < number_planes; i++)
  4914.           *p++=(unsigned char) fgetc(image->file);
  4915.       }
  4916.     if ((number_planes & 0x01) == 0)
  4917.       (void) fgetc(image->file);
  4918.     colormap=(unsigned char *) NULL;
  4919.     if (number_colormaps != 0)
  4920.       {
  4921.         /*
  4922.           Read image colormaps.
  4923.         */
  4924.         colormap=(unsigned char *)
  4925.           malloc(number_colormaps*map_length*sizeof(unsigned char));
  4926.         if (colormap == (unsigned char *) NULL)
  4927.           {
  4928.             Warning("Memory allocation error",(char *) NULL);
  4929.             DestroyImage(image);
  4930.             return((Image *) NULL);
  4931.           }
  4932.         p=colormap;
  4933.         for (i=0; i < number_colormaps; i++)
  4934.           for (j=0; j < map_length; j++)
  4935.             *p++=(unsigned char) (LSBFirstReadShort(image->file) >> 8);
  4936.       }
  4937.     if (flags & 0x08)
  4938.       {
  4939.         unsigned int
  4940.           length;
  4941.  
  4942.         /*
  4943.           Read image comment.
  4944.         */
  4945.         length=LSBFirstReadShort(image->file);
  4946.         image->comments=(char *) malloc((length+1)*sizeof(char));
  4947.         if (image->comments == (char *) NULL)
  4948.           {
  4949.             Warning("Memory allocation error",(char *) NULL);
  4950.             DestroyImage(image);
  4951.             return((Image *) NULL);
  4952.           }
  4953.         (void) ReadData((char *) image->comments,1,(int) length,image->file);
  4954.         image->comments[length]='\0';
  4955.         if ((length & 0x01) == 0)
  4956.           (void) fgetc(image->file);
  4957.       }
  4958.     /*
  4959.       Allocate RLE pixels.
  4960.     */
  4961.     if (image->alpha)
  4962.       number_planes++;
  4963.     rle_pixels=(unsigned char *)
  4964.       malloc(image->packets*number_planes*sizeof(unsigned char));
  4965.     if (rle_pixels == (unsigned char *) NULL)
  4966.       {
  4967.         Warning("Memory allocation error",(char *) NULL);
  4968.         DestroyImage(image);
  4969.         return((Image *) NULL);
  4970.       }
  4971.     if ((flags & 0x01) && ((~flags) & 0x02))
  4972.       {
  4973.         /*
  4974.           Set background color.
  4975.         */
  4976.         p=rle_pixels;
  4977.         for (i=0; i < image->packets; i++)
  4978.         {
  4979.           if (!image->alpha)
  4980.             for (j=0; j < number_planes; j++)
  4981.               *p++=background_color[j];
  4982.           else
  4983.             {
  4984.               for (j=0; j < (number_planes-1); j++)
  4985.                 *p++=background_color[j];
  4986.               *p++=0;  /* initialize alpha channel */
  4987.             }
  4988.         }
  4989.       }
  4990.     /*
  4991.       Read runlength-encoded image.
  4992.     */
  4993.     plane=0;
  4994.     x=0;
  4995.     y=0;
  4996.     (void) fgetc(image->file);
  4997.     opcode=fgetc(image->file);
  4998.     while (((opcode & 0x3f) != EOFOp) && (opcode != EOF))
  4999.     {
  5000.       switch (opcode & 0x3f)
  5001.       {
  5002.         case SkipLinesOp:
  5003.         {
  5004.           operand=fgetc(image->file);
  5005.           if (opcode & 0x40)
  5006.             operand=LSBFirstReadShort(image->file);
  5007.           x=0;
  5008.           y+=operand;
  5009.           break;
  5010.         }
  5011.         case SetColorOp:
  5012.         {
  5013.           operand=fgetc(image->file);
  5014.           plane=operand;
  5015.           if (plane == 255)
  5016.             plane=number_planes-1;
  5017.           x=0;
  5018.           break;
  5019.         }
  5020.         case SkipPixelsOp:
  5021.         {
  5022.           operand=fgetc(image->file);
  5023.           if (opcode & 0x40)
  5024.             operand=LSBFirstReadShort(image->file);
  5025.           x+=operand;
  5026.           break;
  5027.         }
  5028.         case ByteDataOp:
  5029.         {
  5030.           operand=fgetc(image->file);
  5031.           if (opcode & 0x40)
  5032.             operand=LSBFirstReadShort(image->file);
  5033.           p=rle_pixels+((image->rows-y-1)*image->columns*number_planes)+
  5034.             x*number_planes+plane;
  5035.           operand++;
  5036.           for (i=0; i < operand; i++)
  5037.           {
  5038.             pixel=fgetc(image->file);
  5039.             if ((y < image->rows) && ((x+i) < image->columns))
  5040.               *p=pixel;
  5041.             p+=number_planes;
  5042.           }
  5043.           if (operand & 0x01)
  5044.             (void) fgetc(image->file);
  5045.           x+=operand;
  5046.           break;
  5047.         }
  5048.         case RunDataOp:
  5049.         {
  5050.           operand=fgetc(image->file);
  5051.           if (opcode & 0x40)
  5052.             operand=LSBFirstReadShort(image->file);
  5053.           pixel=fgetc(image->file);
  5054.           (void) fgetc(image->file);
  5055.           operand++;
  5056.           p=rle_pixels+((image->rows-y-1)*image->columns*number_planes)+
  5057.             x*number_planes+plane;
  5058.           for (i=0; i < operand; i++)
  5059.           {
  5060.             if ((y < image->rows) && ((x+i) < image->columns))
  5061.               *p=pixel;
  5062.             p+=number_planes;
  5063.           }
  5064.           x+=operand;
  5065.           break;
  5066.         }
  5067.         default:
  5068.           break;
  5069.       }
  5070.       opcode=fgetc(image->file);
  5071.     }
  5072.     if (number_colormaps != 0)
  5073.       {
  5074.         unsigned int
  5075.           mask;
  5076.  
  5077.         /*
  5078.           Apply colormap transformation to image.
  5079.         */
  5080.         mask=(map_length-1);
  5081.         p=rle_pixels;
  5082.         if (number_colormaps == 1)
  5083.           for (i=0; i < image->packets; i++)
  5084.             *p++=(unsigned char) colormap[*p & mask];
  5085.         else
  5086.           if ((number_planes >= 3) && (number_colormaps >= 3))
  5087.             for (i=0; i < image->packets; i++)
  5088.               for (j=0; j < number_planes; j++)
  5089.                 *p++=(unsigned char) colormap[j*map_length+(*p & mask)];
  5090.       }
  5091.     /*
  5092.       Initialize image structure.
  5093.     */
  5094.     image->pixels=(RunlengthPacket *)
  5095.       malloc(image->packets*sizeof(RunlengthPacket));
  5096.     if (image->pixels == (RunlengthPacket *) NULL)
  5097.       {
  5098.         Warning("Memory allocation error",(char *) NULL);
  5099.         DestroyImage(image);
  5100.         return((Image *) NULL);
  5101.       }
  5102.     q=image->pixels;
  5103.     if (number_planes >= 3)
  5104.       {
  5105.         /*
  5106.           Convert raster image to DirectClass runlength-encoded packets.
  5107.         */
  5108.         p=rle_pixels;
  5109.         for (i=0; i < image->packets; i++)
  5110.         {
  5111.           q->red=(*p++);
  5112.           q->green=(*p++);
  5113.           q->blue=(*p++);
  5114.           q->index=(unsigned short) (image->alpha ? (*p++) : 0);
  5115.           q->length=0;
  5116.           q++;
  5117.         }
  5118.       }
  5119.     else
  5120.       {
  5121.         /*
  5122.           Create colormap.
  5123.         */
  5124.         image->class=PseudoClass;
  5125.         image->colors=256;
  5126.         image->colormap=(ColorPacket *)
  5127.           malloc(image->colors*sizeof(ColorPacket));
  5128.         if (image->colormap == (ColorPacket *) NULL)
  5129.           {
  5130.             Warning("Unable to read image","Memory allocation failed");
  5131.             DestroyImage(image);
  5132.             return((Image *) NULL);
  5133.           }
  5134.         p=colormap;
  5135.         if (number_colormaps == 1)
  5136.           for (i=0; i < image->colors; i++)
  5137.           {
  5138.             image->colormap[i].red=(unsigned char) i;
  5139.             image->colormap[i].green=(unsigned char) i;
  5140.             image->colormap[i].blue=(unsigned char) i;
  5141.           }
  5142.         else
  5143.           for (i=0; i < image->colors; i++)
  5144.           {
  5145.             image->colormap[i].red=(*p);
  5146.             image->colormap[i].green=(*(p+256));
  5147.             image->colormap[i].blue=(*(p+512));
  5148.             p++;
  5149.           }
  5150.         /*
  5151.           Convert raster image to PseudoClass runlength-encoded packets.
  5152.         */
  5153.         p=rle_pixels;
  5154.         for (i=0; i < image->packets; i++)
  5155.         {
  5156.           q->index=(unsigned short) (*p++);
  5157.           q->length=0;
  5158.           q++;
  5159.         }
  5160.         SyncImage(image);
  5161.       }
  5162.     if (number_colormaps != 0)
  5163.       (void) free((char *) colormap);
  5164.     (void) free((char *) rle_pixels);
  5165.     /*
  5166.       Proceed to next image.
  5167.     */
  5168.     (void) fgetc(image->file);
  5169.     status=ReadData((char *) magick,1,2,image->file);
  5170.     if ((status == True) && (strncmp(magick,"\122\314",2) == 0))
  5171.       {
  5172.         /*
  5173.           Allocate next image structure.
  5174.         */
  5175.         image->next=AllocateImage(image_info);
  5176.         if (image->next == (Image *) NULL)
  5177.           {
  5178.             DestroyImages(image);
  5179.             return((Image *) NULL);
  5180.           }
  5181.         (void) strcpy(image->next->filename,image_info->filename);
  5182.         image->next->file=image->file;
  5183.         image->next->scene=image->scene+1;
  5184.         image->next->previous=image;
  5185.         image=image->next;
  5186.       }
  5187.   } while ((status == True) && (strncmp(magick,"\122\314",2) == 0));
  5188.   while (image->previous != (Image *) NULL)
  5189.     image=image->previous;
  5190.   CloseImage(image);
  5191.   return(image);
  5192. }
  5193.  
  5194. /*
  5195. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5196. %                                                                             %
  5197. %                                                                             %
  5198. %                                                                             %
  5199. %  R e a d S U N I m a g e                                                    %
  5200. %                                                                             %
  5201. %                                                                             %
  5202. %                                                                             %
  5203. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5204. %
  5205. %  Function ReadSUNImage reads a SUN image file and returns it.  It allocates
  5206. %  the memory necessary for the new Image structure and returns a pointer to
  5207. %  the new image.
  5208. %
  5209. %  The format of the ReadSUNImage routine is:
  5210. %
  5211. %      image=ReadSUNImage(image_info)
  5212. %
  5213. %  A description of each parameter follows:
  5214. %
  5215. %    o image:  Function ReadSUNImage returns a pointer to the image after
  5216. %      reading.  A null image is returned if there is a a memory shortage or
  5217. %      if the image cannot be read.
  5218. %
  5219. %    o image_info: Specifies a pointer to an ImageInfo structure.
  5220. %
  5221. %
  5222. */
  5223. static Image *ReadSUNImage(image_info)
  5224. ImageInfo
  5225.   *image_info;
  5226. {
  5227. #define RMT_EQUAL_RGB  1
  5228. #define RMT_NONE  0
  5229. #define RMT_RAW  2
  5230. #define RT_STANDARD  1
  5231. #define RT_ENCODED  2
  5232. #define RT_FORMAT_RGB  3
  5233.  
  5234.   typedef struct _SUNHeader
  5235.   {
  5236.     unsigned long
  5237.       magic,
  5238.       width,
  5239.       height,
  5240.       depth,
  5241.       length,
  5242.       type,
  5243.       maptype,
  5244.       maplength;
  5245.   } SUNHeader;
  5246.  
  5247.   Image
  5248.     *image;
  5249.  
  5250.   register int
  5251.     bit,
  5252.     i,
  5253.     x,
  5254.     y;
  5255.  
  5256.   register RunlengthPacket
  5257.     *q;
  5258.  
  5259.   register unsigned char
  5260.     *p;
  5261.  
  5262.   SUNHeader
  5263.     sun_header;
  5264.  
  5265.   unsigned char
  5266.     *sun_data,
  5267.     *sun_pixels;
  5268.  
  5269.   unsigned int
  5270.     status;
  5271.  
  5272.   /*
  5273.     Allocate image structure.
  5274.   */
  5275.   image=AllocateImage(image_info);
  5276.   if (image == (Image *) NULL)
  5277.     return((Image *) NULL);
  5278.   /*
  5279.     Open image file.
  5280.   */
  5281.   OpenImage(image,"r");
  5282.   if (image->file == (FILE *) NULL)
  5283.     {
  5284.       Warning("Unable to open file",image->filename);
  5285.       DestroyImage(image);
  5286.       return((Image *) NULL);
  5287.     }
  5288.   /*
  5289.     Read SUN raster header.
  5290.   */
  5291.   sun_header.magic=MSBFirstReadLong(image->file);
  5292.   do
  5293.   {
  5294.     /*
  5295.       Verify SUN identifier.
  5296.     */
  5297.     if (sun_header.magic != 0x59a66a95)
  5298.       {
  5299.         Warning("Not a SUN raster,",image->filename);
  5300.         DestroyImages(image);
  5301.         return((Image *) NULL);
  5302.       }
  5303.     sun_header.width=MSBFirstReadLong(image->file);
  5304.     sun_header.height=MSBFirstReadLong(image->file);
  5305.     sun_header.depth=MSBFirstReadLong(image->file);
  5306.     sun_header.length=MSBFirstReadLong(image->file);
  5307.     sun_header.type=MSBFirstReadLong(image->file);
  5308.     sun_header.maptype=MSBFirstReadLong(image->file);
  5309.     sun_header.maplength=MSBFirstReadLong(image->file);
  5310.     switch (sun_header.maptype)
  5311.     {
  5312.       case RMT_NONE:
  5313.       {
  5314.         if (sun_header.depth < 24)
  5315.           {
  5316.             /*
  5317.               Create linear color ramp.
  5318.             */
  5319.             image->colors=1 << sun_header.depth;
  5320.             image->colormap=(ColorPacket *)
  5321.               malloc(image->colors*sizeof(ColorPacket));
  5322.             if (image->colormap == (ColorPacket *) NULL)
  5323.               {
  5324.                 Warning("Memory allocation error",(char *) NULL);
  5325.                 return((Image *) NULL);
  5326.               }
  5327.             for (i=0; i < image->colors; i++)
  5328.             {
  5329.               image->colormap[i].red=(MaxRGB*i)/(image->colors-1);
  5330.               image->colormap[i].green=(MaxRGB*i)/(image->colors-1);
  5331.               image->colormap[i].blue=(MaxRGB*i)/(image->colors-1);
  5332.             }
  5333.           }
  5334.         break;
  5335.       }
  5336.       case RMT_EQUAL_RGB:
  5337.       {
  5338.         unsigned char
  5339.           *sun_colormap;
  5340.  
  5341.         /*
  5342.           Read SUN raster colormap.
  5343.         */
  5344.         image->colors=sun_header.maplength/3;
  5345.         image->colormap=(ColorPacket *)
  5346.           malloc(image->colors*sizeof(ColorPacket));
  5347.         sun_colormap=(unsigned char *)
  5348.           malloc(image->colors*sizeof(unsigned char));
  5349.         if ((image->colormap == (ColorPacket *) NULL) ||
  5350.             (sun_colormap == (unsigned char *) NULL))
  5351.           {
  5352.             Warning("Memory allocation error",(char *) NULL);
  5353.             DestroyImages(image);
  5354.             return((Image *) NULL);
  5355.           }
  5356.         (void) ReadData((char *) sun_colormap,1,(int) image->colors,
  5357.           image->file);
  5358.         for (i=0; i < image->colors; i++)
  5359.           image->colormap[i].red=sun_colormap[i];
  5360.         (void) ReadData((char *) sun_colormap,1,(int) image->colors,
  5361.           image->file);
  5362.         for (i=0; i < image->colors; i++)
  5363.           image->colormap[i].green=sun_colormap[i];
  5364.         (void) ReadData((char *) sun_colormap,1,(int) image->colors,
  5365.           image->file);
  5366.         for (i=0; i < image->colors; i++)
  5367.           image->colormap[i].blue=sun_colormap[i];
  5368.         (void) free((char *) sun_colormap);
  5369.         break;
  5370.       }
  5371.       case RMT_RAW:
  5372.       {
  5373.         unsigned char
  5374.           *sun_colormap;
  5375.  
  5376.         /*
  5377.           Read SUN raster colormap.
  5378.         */
  5379.         sun_colormap=(unsigned char *)
  5380.           malloc(sun_header.maplength*sizeof(unsigned char));
  5381.         if (sun_colormap == (unsigned char *) NULL)
  5382.           {
  5383.             Warning("Memory allocation error",(char *) NULL);
  5384.             DestroyImages(image);
  5385.             return((Image *) NULL);
  5386.           }
  5387.         (void) ReadData((char *) sun_colormap,1,(int) sun_header.maplength,
  5388.           image->file);
  5389.         (void) free((char *) sun_colormap);
  5390.         break;
  5391.       }
  5392.       default:
  5393.       {
  5394.         Warning("Colormap type is not supported",image->filename);
  5395.         DestroyImages(image);
  5396.         return((Image *) NULL);
  5397.       }
  5398.     }
  5399.     sun_data=(unsigned char *) malloc(sun_header.length*sizeof(unsigned char));
  5400.     if (sun_data == (unsigned char *) NULL)
  5401.       {
  5402.         Warning("Memory allocation error",(char *) NULL);
  5403.         DestroyImages(image);
  5404.         return((Image *) NULL);
  5405.       }
  5406.     status=ReadData((char *) sun_data,1,(int) sun_header.length,image->file);
  5407.     if ((status == False) && (sun_header.type != RT_ENCODED))
  5408.       {
  5409.         Warning("Unable to read image data",image_info->filename);
  5410.         DestroyImages(image);
  5411.         return((Image *) NULL);
  5412.       }
  5413.     sun_pixels=sun_data;
  5414.     if (sun_header.type == RT_ENCODED)
  5415.       {
  5416.         unsigned int
  5417.           width,
  5418.           height;
  5419.  
  5420.         /*
  5421.           Read run-length encoded raster pixels.
  5422.         */
  5423.         width=sun_header.width*(((sun_header.depth-1) >> 3)+1);
  5424.         height=sun_header.height;
  5425.         sun_pixels=(unsigned char *) malloc(width*height*sizeof(unsigned char));
  5426.         if (sun_pixels == (unsigned char *) NULL)
  5427.           {
  5428.             Warning("Memory allocation error",(char *) NULL);
  5429.             DestroyImages(image);
  5430.             return((Image *) NULL);
  5431.           }
  5432.         (void) SUNDecodeImage(sun_data,sun_pixels,width,height);
  5433.         (void) free((char *) sun_data);
  5434.       }
  5435.     /*
  5436.       Initialize image structure.
  5437.     */
  5438.     image->alpha=(sun_header.depth == 32);
  5439.     image->class=(sun_header.depth < 24 ? PseudoClass : DirectClass);
  5440.     image->columns=sun_header.width;
  5441.     image->rows=sun_header.height;
  5442.     image->packets=image->columns*image->rows;
  5443.     image->pixels=(RunlengthPacket *)
  5444.       malloc(image->packets*sizeof(RunlengthPacket));
  5445.     if (image->pixels == (RunlengthPacket *) NULL)
  5446.       {
  5447.         Warning("Memory allocation error",(char *) NULL);
  5448.         DestroyImages(image);
  5449.         return((Image *) NULL);
  5450.       }
  5451.     /*
  5452.       Convert SUN raster image to runlength-encoded packets.
  5453.     */
  5454.     p=sun_pixels;
  5455.     q=image->pixels;
  5456.     if (sun_header.depth == 1)
  5457.       for (y=0; y < image->rows; y++)
  5458.       {
  5459.         /*
  5460.           Convert bitmap scanline to runlength-encoded color packets.
  5461.         */
  5462.         for (x=0; x < (image->columns >> 3); x++)
  5463.         {
  5464.           for (bit=7; bit >= 0; bit--)
  5465.           {
  5466.             q->index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
  5467.             q->length=0;
  5468.             q++;
  5469.           }
  5470.           p++;
  5471.         }
  5472.         if ((image->columns % 8) != 0)
  5473.           {
  5474.             for (bit=7; bit >= (8-(image->columns % 8)); bit--)
  5475.             {
  5476.               q->index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
  5477.               q->length=0;
  5478.               q++;
  5479.             }
  5480.             p++;
  5481.           }
  5482.         if ((((image->columns/8)+(image->columns % 8 ? 1 : 0)) % 2) != 0)
  5483.           p++;
  5484.       }
  5485.     else
  5486.       if (image->class == PseudoClass)
  5487.         for (y=0; y < image->rows; y++)
  5488.         {
  5489.           /*
  5490.             Convert PseudoColor scanline to runlength-encoded color packets.
  5491.           */
  5492.           for (x=0; x < image->columns; x++)
  5493.           {
  5494.             q->index=(*p++);
  5495.             q->length=0;
  5496.             q++;
  5497.           }
  5498.           if ((image->columns % 2) != 0)
  5499.             p++;
  5500.         }
  5501.       else
  5502.         for (y=0; y < image->rows; y++)
  5503.         {
  5504.           /*
  5505.             Convert DirectColor scanline to runlength-encoded color packets.
  5506.           */
  5507.           for (x=0; x < image->columns; x++)
  5508.           {
  5509.             q->index=(unsigned short) (image->alpha ? (*p++) : 0);
  5510.             if (sun_header.type == RT_STANDARD)
  5511.               {
  5512.                 q->blue=(*p++);
  5513.                 q->green=(*p++);
  5514.                 q->red=(*p++);
  5515.               }
  5516.             else
  5517.               {
  5518.                 q->red=(*p++);
  5519.                 q->green=(*p++);
  5520.                 q->blue=(*p++);
  5521.               }
  5522.             if (image->colors != 0)
  5523.               {
  5524.                 q->red=image->colormap[q->red].red;
  5525.                 q->green=image->colormap[q->green].green;
  5526.                 q->blue=image->colormap[q->blue].blue;
  5527.               }
  5528.             q->length=0;
  5529.             q++;
  5530.           }
  5531.           if (((image->columns % 2) != 0) && (image->alpha == False))
  5532.             p++;
  5533.         }
  5534.     (void) free((char *) sun_pixels);
  5535.     if (image->class == PseudoClass)
  5536.       {
  5537.         SyncImage(image);
  5538.         CompressColormap(image);
  5539.       }
  5540.     /*
  5541.       Proceed to next image.
  5542.     */
  5543.     sun_header.magic=MSBFirstReadLong(image->file);
  5544.     if (sun_header.magic == 0x59a66a95)
  5545.       {
  5546.         /*
  5547.           Allocate image structure.
  5548.         */
  5549.         image->next=AllocateImage(image_info);
  5550.         if (image->next == (Image *) NULL)
  5551.           {
  5552.             DestroyImages(image);
  5553.             return((Image *) NULL);
  5554.           }
  5555.         (void) strcpy(image->next->filename,image_info->filename);
  5556.         image->next->file=image->file;
  5557.         image->next->scene=image->scene+1;
  5558.         image->next->previous=image;
  5559.         image=image->next;
  5560.       }
  5561.   } while (sun_header.magic == 0x59a66a95);
  5562.   while (image->previous != (Image *) NULL)
  5563.     image=image->previous;
  5564.   CloseImage(image);
  5565.   return(image);
  5566. }
  5567.  
  5568. /*
  5569. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5570. %                                                                             %
  5571. %                                                                             %
  5572. %                                                                             %
  5573. %  R e a d T A R G A I m a g e                                                %
  5574. %                                                                             %
  5575. %                                                                             %
  5576. %                                                                             %
  5577. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5578. %
  5579. %  Function ReadTARGAImage reads a Truevision Targa image file and returns
  5580. %  it.  It allocates the memory necessary for the new Image structure and
  5581. %  returns a pointer to the new image.
  5582. %
  5583. %  The format of the ReadTARGAImage routine is:
  5584. %
  5585. %      image=ReadTARGAImage(image_info)
  5586. %
  5587. %  A description of each parameter follows:
  5588. %
  5589. %    o image:  Function ReadTARGAImage returns a pointer to the image after
  5590. %      reading.  A null image is returned if there is a a memory shortage or
  5591. %      if the image cannot be read.
  5592. %
  5593. %    o image_info: Specifies a pointer to an ImageInfo structure.
  5594. %
  5595. %
  5596. */
  5597. static Image *ReadTARGAImage(image_info)
  5598. ImageInfo
  5599.   *image_info;
  5600. {
  5601. #define TargaColormap 1
  5602. #define TargaRGB 2
  5603. #define TargaMonochrome 3
  5604. #define TargaRLEColormap  9
  5605. #define TargaRLERGB  10
  5606. #define TargaRLEMonochrome  11
  5607.  
  5608.   typedef struct _TargaHeader
  5609.   {
  5610.     unsigned char
  5611.       id_length,
  5612.       colormap_type,
  5613.       image_type;
  5614.  
  5615.     unsigned short
  5616.       colormap_index,
  5617.       colormap_length;
  5618.  
  5619.     unsigned char
  5620.       colormap_size;
  5621.  
  5622.     unsigned short
  5623.       x_origin,
  5624.       y_origin,
  5625.       width,
  5626.       height;
  5627.  
  5628.     unsigned char
  5629.       pixel_size,
  5630.       attributes;
  5631.   } TargaHeader;
  5632.  
  5633.   Image
  5634.     *image;
  5635.  
  5636.   register int
  5637.     i,
  5638.     x,
  5639.     y;
  5640.  
  5641.   register RunlengthPacket
  5642.     *q;
  5643.  
  5644.   TargaHeader
  5645.     targa_header;
  5646.  
  5647.   unsigned char
  5648.     blue,
  5649.     green,
  5650.     j,
  5651.     k,
  5652.     red,
  5653.     runlength;
  5654.  
  5655.   unsigned int
  5656.     base,
  5657.     flag,
  5658.     real,
  5659.     skip,
  5660.     status,
  5661.     true;
  5662.  
  5663.   unsigned short
  5664.     index;
  5665.  
  5666.   /*
  5667.     Allocate image structure.
  5668.   */
  5669.   image=AllocateImage(image_info);
  5670.   if (image == (Image *) NULL)
  5671.     return((Image *) NULL);
  5672.   /*
  5673.     Open image file.
  5674.   */
  5675.   OpenImage(image,"r");
  5676.   if (image->file == (FILE *) NULL)
  5677.     {
  5678.       Warning("Unable to open file",image->filename);
  5679.       DestroyImage(image);
  5680.       return((Image *) NULL);
  5681.     }
  5682.   /*
  5683.     Determine if this is a TARGA file.
  5684.   */
  5685.   status=ReadData((char *) &targa_header.id_length,1,1,image->file);
  5686.   do
  5687.   {
  5688.     /*
  5689.       Read TARGA header information.
  5690.     */
  5691.     targa_header.colormap_type=fgetc(image->file);
  5692.     targa_header.image_type=fgetc(image->file);
  5693.     if ((status == False) || (targa_header.image_type > 11))
  5694.       {
  5695.         Warning("Not a TARGA image file",(char *) NULL);
  5696.         DestroyImages(image);
  5697.         return((Image *) NULL);
  5698.       }
  5699.     targa_header.colormap_index=LSBFirstReadShort(image->file);
  5700.     targa_header.colormap_length=LSBFirstReadShort(image->file);
  5701.     targa_header.colormap_size=fgetc(image->file);
  5702.     targa_header.x_origin=LSBFirstReadShort(image->file);
  5703.     targa_header.y_origin=LSBFirstReadShort(image->file);
  5704.     targa_header.width=LSBFirstReadShort(image->file);
  5705.     targa_header.height=LSBFirstReadShort(image->file);
  5706.     targa_header.pixel_size=fgetc(image->file);
  5707.     targa_header.attributes=fgetc(image->file);
  5708.     /*
  5709.       Initialize image structure.
  5710.     */
  5711.     image->alpha=targa_header.pixel_size == 32;
  5712.     image->columns=targa_header.width;
  5713.     image->rows=targa_header.height;
  5714.     image->packets=image->columns*image->rows;
  5715.     image->pixels=(RunlengthPacket *)
  5716.       malloc(image->packets*sizeof(RunlengthPacket));
  5717.     if (image->pixels == (RunlengthPacket *) NULL)
  5718.       {
  5719.         Warning("Memory allocation error",(char *) NULL);
  5720.         DestroyImages(image);
  5721.         return((Image *) NULL);
  5722.       }
  5723.     if (targa_header.id_length != 0)
  5724.       {
  5725.         /*
  5726.           TARGA image comment.
  5727.         */
  5728.         image->comments=(char *)
  5729.           malloc((targa_header.id_length+1)*sizeof(char));
  5730.         if (image->comments == (char *) NULL)
  5731.           {
  5732.             Warning("Memory allocation error",(char *) NULL);
  5733.             DestroyImages(image);
  5734.             return((Image *) NULL);
  5735.           }
  5736.         (void) ReadData(image->comments,1,(int) targa_header.id_length,
  5737.           image->file);
  5738.         image->comments[targa_header.id_length]='\0';
  5739.       }
  5740.     if (targa_header.colormap_type != 0)
  5741.       {
  5742.         /*
  5743.           Read TARGA raster colormap.
  5744.         */
  5745.         image->class=PseudoClass;
  5746.         image->colors=targa_header.colormap_length;
  5747.         image->colormap=(ColorPacket *)
  5748.           malloc(image->colors*sizeof(ColorPacket));
  5749.         if (image->colormap == (ColorPacket *) NULL)
  5750.           {
  5751.             Warning("Memory allocation error",(char *) NULL);
  5752.             DestroyImages(image);
  5753.             return((Image *) NULL);
  5754.           }
  5755.         for (i=0; i < image->colors; i++)
  5756.         {
  5757.           switch (targa_header.colormap_size)
  5758.           {
  5759.             case 8:
  5760.             default:
  5761.             {
  5762.               /*
  5763.                 Gray scale.
  5764.               */
  5765.               red=fgetc(image->file);
  5766.               green=red;
  5767.               blue=red;
  5768.               break;
  5769.             }
  5770.             case 15:
  5771.             case 16:
  5772.             {
  5773.               /*
  5774.                 5 bits each of red green and blue.
  5775.               */
  5776.               j=fgetc(image->file);
  5777.               k=fgetc(image->file);
  5778.               red=(unsigned char) ((MaxRGB*((int) (k & 0x7c) >> 2))/31);
  5779.               green=(unsigned char)
  5780.                 ((MaxRGB*(((int) (k & 0x03) << 3)+((int) (j & 0xe0) >> 5)))/31);
  5781.               blue=(unsigned char) ((MaxRGB*((int) (j & 0x1f)))/31);
  5782.               break;
  5783.             }
  5784.             case 32:
  5785.             case 24:
  5786.             {
  5787.               /*
  5788.                 8 bits each of blue green and red.
  5789.               */
  5790.               blue=fgetc(image->file);
  5791.               green=fgetc(image->file);
  5792.               red=fgetc(image->file);
  5793.               break;
  5794.             }
  5795.           }
  5796.           image->colormap[i].red=red;
  5797.           image->colormap[i].green=green;
  5798.           image->colormap[i].blue=blue;
  5799.         }
  5800.       }
  5801.     /*
  5802.       Convert TARGA pixels to runlength-encoded packets.
  5803.     */
  5804.     base=0;
  5805.     flag=0;
  5806.     index=0;
  5807.     skip=False;
  5808.     real=0;
  5809.     runlength=0;
  5810.     true=0;
  5811.     for (y=0; y < image->rows; y++)
  5812.     {
  5813.       real=true;
  5814.       if (((unsigned char) (targa_header.attributes & 0x20) >> 5) == 0)
  5815.         real=image->rows-real-1;
  5816.       q=image->pixels+(real*image->columns);
  5817.       for (x=0; x < image->columns; x++)
  5818.       {
  5819.         if ((targa_header.image_type == TargaRLEColormap) ||
  5820.             (targa_header.image_type == TargaRLERGB) ||
  5821.             (targa_header.image_type == TargaRLEMonochrome))
  5822.           if (runlength != 0)
  5823.             {
  5824.               runlength--;
  5825.               skip=flag != 0;
  5826.             }
  5827.           else
  5828.             {
  5829.               status=ReadData((char *) &runlength,1,1,image->file);
  5830.               if (status == False)
  5831.                 {
  5832.                   Warning("Unable to read image data",image_info->filename);
  5833.                   DestroyImages(image);
  5834.                   return((Image *) NULL);
  5835.                 }
  5836.               flag=runlength & 0x80;
  5837.               if (flag != 0)
  5838.                 runlength-=128;
  5839.               skip=False;
  5840.             }
  5841.         if (!skip)
  5842.           switch (targa_header.pixel_size)
  5843.           {
  5844.             case 8:
  5845.             default:
  5846.             {
  5847.               /*
  5848.                 Gray scale.
  5849.               */
  5850.               index=fgetc(image->file);
  5851.               if (targa_header.colormap_type == 0)
  5852.                 {
  5853.                   red=(unsigned char) index;
  5854.                   green=(unsigned char) index;
  5855.                   blue=(unsigned char) index;
  5856.                 }
  5857.               else
  5858.                 {
  5859.                   red=image->colormap[index].red;
  5860.                   green=image->colormap[index].green;
  5861.                   blue=image->colormap[index].blue;
  5862.                 }
  5863.               break;
  5864.             }
  5865.             case 15:
  5866.             case 16:
  5867.             {
  5868.               /*
  5869.                 5 bits each of red green and blue.
  5870.               */
  5871.               j=fgetc(image->file);
  5872.               k=fgetc(image->file);
  5873.               red=(unsigned char) ((MaxRGB*((int) (k & 0x7c) >> 2))/31);
  5874.               green=(unsigned char)
  5875.                 ((MaxRGB*(((int) (k & 0x03) << 3)+((int) (j & 0xe0) >> 5)))/31);
  5876.               blue=(unsigned char) ((MaxRGB*((int) (j & 0x1f)))/31);
  5877.               break;
  5878.             }
  5879.             case 24:
  5880.             case 32:
  5881.             {
  5882.               /*
  5883.                 8 bits each of blue green and red.
  5884.               */
  5885.               blue=fgetc(image->file);
  5886.               green=fgetc(image->file);
  5887.               red=fgetc(image->file);
  5888.               if (targa_header.pixel_size == 32)
  5889.                 index=fgetc(image->file);
  5890.               break;
  5891.             }
  5892.           }
  5893.         if (status == False)
  5894.           {
  5895.             Warning("Unable to read image data",image_info->filename);
  5896.             DestroyImages(image);
  5897.             return((Image *) NULL);
  5898.           }
  5899.         q->red=red;
  5900.         q->green=green;
  5901.         q->blue=blue;
  5902.         q->index=index;
  5903.         q->length=0;
  5904.         q++;
  5905.       }
  5906.       if (((unsigned char) (targa_header.attributes & 0xc0) >> 6) == 4)
  5907.         true+=4;
  5908.       else
  5909.         if (((unsigned char) (targa_header.attributes & 0xc0) >> 6) == 2)
  5910.           true+=2;
  5911.         else
  5912.           true++;
  5913.       if (true >= image->rows)
  5914.         {
  5915.           base++;
  5916.           true=base;
  5917.         }
  5918.     }
  5919.     if ((targa_header.image_type == TargaMonochrome) ||
  5920.         (targa_header.image_type == TargaRLEMonochrome))
  5921.       {
  5922.         QuantizeImage(image,2,8,False,GRAYColorspace,True);
  5923.         SyncImage(image);
  5924.       }
  5925.     /*
  5926.       Proceed to next image.
  5927.     */
  5928.     status=ReadData((char *) &targa_header.id_length,1,1,image->file);
  5929.     if (status == True)
  5930.       {
  5931.         /*
  5932.           Allocate image structure.
  5933.         */
  5934.         image->next=AllocateImage(image_info);
  5935.         if (image->next == (Image *) NULL)
  5936.           {
  5937.             DestroyImages(image);
  5938.             return((Image *) NULL);
  5939.           }
  5940.         (void) strcpy(image->next->filename,image_info->filename);
  5941.         image->next->file=image->file;
  5942.         image->next->scene=image->scene+1;
  5943.         image->next->previous=image;
  5944.         image=image->next;
  5945.       }
  5946.   } while (status == True);
  5947.   while (image->previous != (Image *) NULL)
  5948.     image=image->previous;
  5949.   CloseImage(image);
  5950.   return(image);
  5951. }
  5952.  
  5953. /*
  5954. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5955. %                                                                             %
  5956. %                                                                             %
  5957. %                                                                             %
  5958. %  R e a d T E X T I m a g e                                                  %
  5959. %                                                                             %
  5960. %                                                                             %
  5961. %                                                                             %
  5962. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5963. %
  5964. %  Function ReadTEXTImage reads a text file and returns it as an image.  It
  5965. %  allocates the memory necessary for the new Image structure and returns a
  5966. %  pointer to the new image.
  5967. %
  5968. %  The format of the ReadTEXTImage routine is:
  5969. %
  5970. %      image=ReadTEXTImage(image_info)
  5971. %
  5972. %  A description of each parameter follows:
  5973. %
  5974. %    o image:  Function ReadTEXTImage returns a pointer to the image after
  5975. %      reading. A null image is returned if there is a a memory shortage or if
  5976. %      the image cannot be read.
  5977. %
  5978. %    o image_info: Specifies a pointer to an ImageInfo structure.
  5979. %
  5980. %
  5981. */
  5982. static Image *ReadTEXTImage(image_info)
  5983. ImageInfo
  5984.   *image_info;
  5985. {
  5986.   char
  5987.     *resource_value,
  5988.     *text_status,
  5989.     text[MaxTextLength];
  5990.  
  5991.   Display
  5992.     *display;
  5993.  
  5994.   Image
  5995.     *image;
  5996.  
  5997.   int
  5998.     status,
  5999.     offset,
  6000.     x,
  6001.     y;
  6002.  
  6003.   register int
  6004.     i;
  6005.  
  6006.   register RunlengthPacket
  6007.     *p;
  6008.  
  6009.   RunlengthPacket
  6010.     background_color;
  6011.  
  6012.   unsigned int
  6013.     height,
  6014.     width;
  6015.  
  6016.   XAnnotateInfo
  6017.     annotate_info;
  6018.  
  6019.   XFontStruct
  6020.     *font_info;
  6021.  
  6022.   XPixelInfo
  6023.     pixel_info;
  6024.  
  6025.   XResourceInfo
  6026.     resource_info;
  6027.  
  6028.   XrmDatabase
  6029.     resource_database,
  6030.     server_database;
  6031.  
  6032.   XStandardColormap
  6033.     *map_info;
  6034.  
  6035.   XVisualInfo
  6036.     *visual_info;
  6037.  
  6038.   /*
  6039.     Allocate image structure.
  6040.   */
  6041.   image=AllocateImage(image_info);
  6042.   if (image == (Image *) NULL)
  6043.     return((Image *) NULL);
  6044.   /*
  6045.     Open image file.
  6046.   */
  6047.   OpenImage(image,"r");
  6048.   if (image->file == (FILE *) NULL)
  6049.     {
  6050.       Warning("Unable to open file",image->filename);
  6051.       DestroyImage(image);
  6052.       return((Image *) NULL);
  6053.     }
  6054.   /*
  6055.     Open X server connection.
  6056.   */
  6057.   display=XOpenDisplay(image_info->server_name);
  6058.   if (display == (Display *) NULL)
  6059.     {
  6060.       Warning("Unable to connect to X server",
  6061.         XDisplayName(image_info->server_name));
  6062.       DestroyImage(image);
  6063.       return((Image *) NULL);
  6064.     }
  6065.   /*
  6066.     Set our forgiving error handler.
  6067.   */
  6068.   XSetErrorHandler(XError);
  6069.   /*
  6070.     Get user defaults from X resource database.
  6071.   */
  6072.   XrmInitialize();
  6073.   XGetDefault(display,client_name,"dummy");
  6074.   resource_database=XrmGetDatabase(display);
  6075.   resource_value=XResourceManagerString(display);
  6076.   if (resource_value == (char *) NULL)
  6077.     resource_value="";
  6078.   server_database=XrmGetStringDatabase(resource_value);
  6079.   XrmMergeDatabases(server_database,&resource_database);
  6080.   XGetResourceInfo(resource_database,client_name,&resource_info);
  6081.   resource_info.colormap=PrivateColormap;
  6082.   /*
  6083.     Allocate standard colormap.
  6084.   */
  6085.   XGetAnnotateInfo(&annotate_info);
  6086.   map_info=XAllocStandardColormap();
  6087.   if (map_info == (XStandardColormap *) NULL)
  6088.     Warning("Unable to create standard colormap","Memory allocation failed");
  6089.   else
  6090.     {
  6091.       /*
  6092.         Initialize visual info.
  6093.       */
  6094.       visual_info=XBestVisualInfo(display,map_info,&resource_info);
  6095.       if (visual_info == (XVisualInfo *) NULL)
  6096.         Warning("Unable to get visual",resource_info.visual_type);
  6097.       map_info->colormap=(Colormap) NULL;
  6098.       pixel_info.pixels=(unsigned long *) NULL;
  6099.       /*
  6100.         Initialize font info.
  6101.       */
  6102.       if (image_info->font != (char *) NULL)
  6103.         resource_info.font=image_info->font;
  6104.       font_info=XBestFont(display,&resource_info);
  6105.       if (font_info == (XFontStruct *) NULL)
  6106.         Warning("Unable to load font",resource_info.font);
  6107.       annotate_info.font_info=font_info;
  6108.       annotate_info.height=font_info->ascent+font_info->descent;
  6109.     }
  6110.   if ((map_info == (XStandardColormap *) NULL) ||
  6111.       (visual_info == (XVisualInfo *) NULL) ||
  6112.       (font_info == (XFontStruct *) NULL))
  6113.     {
  6114.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  6115.         font_info,&resource_info,(XWindowInfo *) NULL);
  6116.       DestroyImage(image);
  6117.       return((Image *) NULL);
  6118.     }
  6119.   /*
  6120.     Initialize Standard Colormap.
  6121.   */
  6122.   XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen),
  6123.     map_info);
  6124.   XGetPixelInfo(display,visual_info,map_info,&resource_info,(Image *) NULL,
  6125.     &pixel_info);
  6126.   pixel_info.annotate_context=XDefaultGC(display,visual_info->screen);
  6127.   pixel_info.annotate_index=1;
  6128.   background_color.red=pixel_info.background_color.red >> 8;
  6129.   background_color.green=pixel_info.background_color.red >> 8;
  6130.   background_color.blue=pixel_info.background_color.red >> 8;
  6131.   background_color.index=0;
  6132.   background_color.length=0;
  6133.   /*
  6134.     Initialize Image structure.
  6135.   */
  6136.   (void) XParseGeometry(TextPageGeometry,&x,&y,&width,&height);
  6137.   (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  6138.   image->columns=width;
  6139.   image->rows=height;
  6140.   image->packets=image->columns*image->rows;
  6141.   image->pixels=(RunlengthPacket *)
  6142.     malloc(image->packets*sizeof(RunlengthPacket));
  6143.   image->class=PseudoClass;
  6144.   image->colors=2;
  6145.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  6146.   if ((image->pixels == (RunlengthPacket *) NULL) ||
  6147.       (image->colormap == (ColorPacket *) NULL))
  6148.     {
  6149.       Warning("Unable to allocate image","Memory allocation error");
  6150.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  6151.         font_info,&resource_info,(XWindowInfo *) NULL);
  6152.       DestroyImage(image);
  6153.       return((Image *) NULL);
  6154.     }
  6155.   /*
  6156.     Initialize colormap.
  6157.   */
  6158.   image->colormap[0].red=pixel_info.background_color.red >> 8;
  6159.   image->colormap[0].green=pixel_info.background_color.green >> 8;
  6160.   image->colormap[0].blue=pixel_info.background_color.blue >> 8;
  6161.   image->colormap[1].red=pixel_info.foreground_color.red >> 8;
  6162.   image->colormap[1].green=pixel_info.foreground_color.green >> 8;
  6163.   image->colormap[1].blue=pixel_info.foreground_color.blue >> 8;
  6164.   /*
  6165.     Initialize text image to background color.
  6166.   */
  6167.   p=image->pixels;
  6168.   for (i=0; i < image->packets; i++)
  6169.     *p++=background_color;
  6170.   /*
  6171.     Annotate the text image.
  6172.   */
  6173.   annotate_info.text=(char *) malloc(MaxTextLength*sizeof(char));
  6174.   if (annotate_info.text == (char *) NULL)
  6175.     {
  6176.       Warning("Unable to read image","Memory allocation failed");
  6177.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  6178.         font_info,&resource_info,(XWindowInfo *) NULL);
  6179.       DestroyImage(image);
  6180.       return((Image *) NULL);
  6181.     }
  6182.   text[MaxTextLength-1]='\0';
  6183.   text_status=fgets(text,MaxTextLength,image->file);
  6184.   if ((int) strlen(text) > 0)
  6185.     text[strlen(text)-1]='\0';
  6186.   offset=0;
  6187.   while (text_status != (char *) NULL)
  6188.   {
  6189.     *annotate_info.text='\0';
  6190.     if (*text != '\0')
  6191.       {
  6192.         /*
  6193.           Compute width of text.
  6194.         */
  6195.         (void) strcpy(annotate_info.text,text);
  6196.         annotate_info.width=
  6197.           XTextWidth(font_info,annotate_info.text,strlen(annotate_info.text));
  6198.         if ((annotate_info.width+4) >= image->columns)
  6199.           {
  6200.             /*
  6201.               Reduce text until width is within bounds.
  6202.             */
  6203.             i=strlen(annotate_info.text);
  6204.             for (; (annotate_info.width+(x << 1)) >= image->columns; i--)
  6205.               annotate_info.width=
  6206.                 XTextWidth(font_info,annotate_info.text,(unsigned int) i);
  6207.             annotate_info.text[i]='\0';
  6208.             while ((i > 0) && !isspace(annotate_info.text[i]))
  6209.               i--;
  6210.             if (i > 0)
  6211.               annotate_info.text[i]='\0';
  6212.             annotate_info.width=XTextWidth(font_info,annotate_info.text,
  6213.               strlen(annotate_info.text));
  6214.           }
  6215.         /*
  6216.           Annotate image with text.
  6217.         */
  6218.         (void) sprintf(annotate_info.geometry,"%ux%u%+d%+d",
  6219.           annotate_info.width,annotate_info.height,x,y+offset);
  6220.         status=XAnnotateImage(display,&pixel_info,&annotate_info,False,image);
  6221.         if (status == 0)
  6222.           {
  6223.             Warning("Unable to annotate image","Memory allocation error");
  6224.             break;
  6225.           }
  6226.       }
  6227.     /*
  6228.       Get next string.
  6229.     */
  6230.     if (strlen(text) != strlen(annotate_info.text))
  6231.       (void) strcpy(text,text+strlen(annotate_info.text)+1);
  6232.     else
  6233.       {
  6234.         text_status=fgets(text,MaxTextLength,image->file);
  6235.         if ((int) strlen(text) > 0)
  6236.           text[strlen(text)-1]='\0';
  6237.       }
  6238.     offset+=annotate_info.height;
  6239.     if ((text_status != (char *) NULL) &&
  6240.         (((y << 1)+offset+annotate_info.height) >= image->rows))
  6241.       {
  6242.         /*
  6243.           Page is full-- allocate next image structure.
  6244.         */
  6245.         image->orphan=True;
  6246.         image->next=CopyImage(image,image->columns,image->rows,False);
  6247.         image->orphan=False;
  6248.         if (image->next == (Image *) NULL)
  6249.           {
  6250.             Warning("Unable to annotate image","Memory allocation error");
  6251.             break;
  6252.           }
  6253.         (void) strcpy(image->next->filename,image_info->filename);
  6254.         image->next->file=image->file;
  6255.         image->next->scene=image->scene+1;
  6256.         image->next->previous=image;
  6257.         image=image->next;
  6258.         /*
  6259.           Initialize text image to background color.
  6260.         */
  6261.         p=image->pixels;
  6262.         for (i=0; i < image->packets; i++)
  6263.           *p++=background_color;
  6264.         offset=0;
  6265.       }
  6266.   }
  6267.   /*
  6268.     Force class to PseudoClass.
  6269.   */
  6270.   while (image->previous != (Image *) NULL)
  6271.   {
  6272.     image->class=PseudoClass;
  6273.     image=image->previous;
  6274.   }
  6275.   image->class=PseudoClass;
  6276.   CloseImage(image);
  6277.   /*
  6278.     Free resources.
  6279.   */
  6280.   (void) free((char *) annotate_info.text);
  6281.   XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  6282.     font_info,&resource_info,(XWindowInfo *) NULL);
  6283.   return(image);
  6284. }
  6285.  
  6286. #ifdef HasTIFF
  6287. #include "tiff.h"
  6288. #include "tiffio.h"
  6289.  
  6290. /*
  6291. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6292. %                                                                             %
  6293. %                                                                             %
  6294. %                                                                             %
  6295. %  R e a d T I F F I m a g e                                                  %
  6296. %                                                                             %
  6297. %                                                                             %
  6298. %                                                                             %
  6299. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6300. %
  6301. %  Function ReadTIFFImage reads a Tagged image file and returns it.  It
  6302. %  allocates the memory necessary for the new Image structure and returns a
  6303. %  pointer to the new image.
  6304. %
  6305. %  The format of the ReadTIFFImage routine is:
  6306. %
  6307. %      image=ReadTIFFImage(image_info)
  6308. %
  6309. %  A description of each parameter follows:
  6310. %
  6311. %    o image:  Function ReadTIFFImage returns a pointer to the image after
  6312. %      reading.  A null image is returned if there is a a memory shortage or
  6313. %      if the image cannot be read.
  6314. %
  6315. %    o image_info: Specifies a pointer to an ImageInfo structure.
  6316. %
  6317. %
  6318. */
  6319. static Image *ReadTIFFImage(image_info)
  6320. ImageInfo
  6321.   *image_info;
  6322. {
  6323.   char
  6324.     *comment;
  6325.  
  6326.   Image
  6327.     *image;
  6328.  
  6329.   int
  6330.     range;
  6331.  
  6332.   register int
  6333.     i,
  6334.     quantum,
  6335.     x,
  6336.     y;
  6337.  
  6338.   register RunlengthPacket
  6339.     *q;
  6340.  
  6341.   TIFF
  6342.     *tiff;
  6343.  
  6344.   unsigned int
  6345.     status;
  6346.  
  6347.   unsigned long
  6348.     height,
  6349.     width;
  6350.  
  6351.   unsigned short
  6352.     bits_per_sample,
  6353.     max_sample_value,
  6354.     min_sample_value,
  6355.     photometric,
  6356.     samples_per_pixel;
  6357.  
  6358.   /*
  6359.     Allocate image structure.
  6360.   */
  6361.   image=AllocateImage(image_info);
  6362.   if (image == (Image *) NULL)
  6363.     return((Image *) NULL);
  6364.   /*
  6365.     Open TIFF image tiff.
  6366.   */
  6367.   tiff=TIFFOpen(image->filename,"r");
  6368.   if (tiff == (TIFF *) NULL)
  6369.     {
  6370.       Warning("Unable to open tiff image",image->filename);
  6371.       DestroyImage(image);
  6372.       return((Image *) NULL);
  6373.     }
  6374.   do
  6375.   {
  6376.     if (image_info->verbose)
  6377.       TIFFPrintDirectory(tiff,stderr,False);
  6378.     /*
  6379.       Allocate memory for the image and pixel buffer.
  6380.     */
  6381.     TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH,&width);
  6382.     TIFFGetField(tiff,TIFFTAG_IMAGELENGTH,&height);
  6383.     for (quantum=1; quantum <= 16; quantum<<=1)
  6384.     {
  6385.       image->columns=width/quantum;
  6386.       image->rows=height/quantum;
  6387.       image->packets=image->columns*image->rows;
  6388.       image->pixels=(RunlengthPacket *)
  6389.         malloc(image->packets*sizeof(RunlengthPacket));
  6390.       if ((image->pixels != (RunlengthPacket *) NULL))
  6391.         break;
  6392.     }
  6393.     if (image->pixels == (RunlengthPacket *) NULL)
  6394.       {
  6395.         Warning("Unable to allocate memory",(char *) NULL);
  6396.         DestroyImages(image);
  6397.         TIFFClose(tiff);
  6398.         return((Image *) NULL);
  6399.       }
  6400.     TIFFGetFieldDefaulted(tiff,TIFFTAG_BITSPERSAMPLE,&bits_per_sample);
  6401.     TIFFGetFieldDefaulted(tiff,TIFFTAG_MINSAMPLEVALUE,&min_sample_value);
  6402.     TIFFGetFieldDefaulted(tiff,TIFFTAG_MAXSAMPLEVALUE,&max_sample_value);
  6403.     TIFFGetFieldDefaulted(tiff,TIFFTAG_PHOTOMETRIC,&photometric);
  6404.     TIFFGetFieldDefaulted(tiff,TIFFTAG_SAMPLESPERPIXEL,&samples_per_pixel);
  6405.     comment=(char *) NULL;
  6406.     TIFFGetField(tiff,TIFFTAG_IMAGEDESCRIPTION,&comment);
  6407.     if (comment != (char *) NULL)
  6408.       if ((int) strlen(comment) > 4)
  6409.         {
  6410.           image->comments=(char *)
  6411.             malloc((unsigned int) (strlen(comment)+1)*sizeof(char));
  6412.           if (image->comments == (char *) NULL)
  6413.             {
  6414.               Warning("Unable to allocate memory",(char *) NULL);
  6415.               DestroyImages(image);
  6416.               TIFFClose(tiff);
  6417.               return((Image *) NULL);
  6418.             }
  6419.           (void) strcpy(image->comments,comment);
  6420.         }
  6421.     range=max_sample_value-min_sample_value;
  6422.     if ((bits_per_sample > 8) || (samples_per_pixel > 1) || TIFFIsTiled(tiff))
  6423.       {
  6424.         register unsigned long
  6425.           *p,
  6426.           *pixels;
  6427.  
  6428.         /*
  6429.           Convert TIFF image to DirectClass MIFF image.
  6430.         */
  6431.         image->alpha=samples_per_pixel > 3;
  6432.         pixels=(unsigned long *) malloc(image->packets*sizeof(unsigned long));
  6433.         if (pixels == (unsigned long *) NULL)
  6434.           {
  6435.             Warning("Unable to allocate memory",(char *) NULL);
  6436.             DestroyImages(image);
  6437.             TIFFClose(tiff);
  6438.             return((Image *) NULL);
  6439.           }
  6440.         if (quantum > 1)
  6441.           Warning("Not enough memory","cropping required");
  6442.         status=TIFFReadRGBAImage(tiff,image->columns,image->rows,pixels,0);
  6443.         if (status == False)
  6444.           {
  6445.             Warning("Unable to read TIFF image",(char *) NULL);
  6446.             (void) free((char *) pixels);
  6447.             DestroyImages(image);
  6448.             TIFFClose(tiff);
  6449.             return((Image *) NULL);
  6450.           }
  6451.         /*
  6452.           Convert image to DirectClass runlength-encoded packets.
  6453.         */
  6454.         q=image->pixels;
  6455.         for (y=image->rows-1; y >= 0; y--)
  6456.         {
  6457.           p=pixels+y*image->columns;
  6458.           for (x=0; x < image->columns; x++)
  6459.           {
  6460.             q->red=TIFFGetR(*p);
  6461.             q->green=TIFFGetG(*p);
  6462.             q->blue=TIFFGetB(*p);
  6463.             q->index=(unsigned short) (image->alpha ? TIFFGetA(*p) : 0);
  6464.             q->length=0;
  6465.             p++;
  6466.             q++;
  6467.           }
  6468.         }
  6469.         (void) free((char *) pixels);
  6470.         if (samples_per_pixel == 1)
  6471.           QuantizeImage(image,(unsigned int) range,8,False,RGBColorspace,True);
  6472.       }
  6473.     else
  6474.       {
  6475.         unsigned char
  6476.           *p,
  6477.           *r,
  6478.           *quantum_scanline,
  6479.           *scanline;
  6480.  
  6481.         /*
  6482.           Convert TIFF image to PseudoClass MIFF image.
  6483.         */
  6484.         image->class=PseudoClass;
  6485.         image->colors=range+1;
  6486.         image->colormap=(ColorPacket *)
  6487.           malloc(image->colors*sizeof(ColorPacket));
  6488.         quantum_scanline=(unsigned char *) malloc(width*sizeof(unsigned char));
  6489.         scanline=(unsigned char *) malloc(TIFFScanlineSize(tiff));
  6490.         if ((image->colormap == (ColorPacket *) NULL) ||
  6491.             (quantum_scanline == (unsigned char *) NULL) ||
  6492.             (scanline == (unsigned char *) NULL))
  6493.           {
  6494.             Warning("Unable to allocate memory",(char *) NULL);
  6495.             DestroyImages(image);
  6496.             TIFFClose(tiff);
  6497.             return((Image *) NULL);
  6498.           }
  6499.         /*
  6500.           Create colormap.
  6501.         */
  6502.         switch (photometric)
  6503.         {
  6504.           case PHOTOMETRIC_MINISBLACK:
  6505.           {
  6506.             for (i=0; i < image->colors; i++)
  6507.             {
  6508.               image->colormap[i].red=(MaxRGB*i)/range;
  6509.               image->colormap[i].green=(MaxRGB*i)/range;
  6510.               image->colormap[i].blue=(MaxRGB*i)/range;
  6511.             }
  6512.             break;
  6513.           }
  6514.           case PHOTOMETRIC_MINISWHITE:
  6515.           {
  6516.             for (i=0; i < image->colors; i++)
  6517.             {
  6518.               image->colormap[i].red=((range-i)*MaxRGB)/range;
  6519.               image->colormap[i].green=((range-i)*MaxRGB)/range;
  6520.               image->colormap[i].blue=((range-i)*MaxRGB)/range;
  6521.             }
  6522.             break;
  6523.           }
  6524.           case PHOTOMETRIC_PALETTE:
  6525.           {
  6526.             unsigned short
  6527.               *blue_colormap,
  6528.               *green_colormap,
  6529.               *red_colormap;
  6530.  
  6531.             TIFFGetField(tiff,TIFFTAG_COLORMAP,&red_colormap,&green_colormap,
  6532.               &blue_colormap);
  6533.             for (i=0; i < image->colors; i++)
  6534.             {
  6535.               image->colormap[i].red=((int) red_colormap[i]*MaxRGB)/65535;
  6536.               image->colormap[i].green=((int) green_colormap[i]*MaxRGB)/65535;
  6537.               image->colormap[i].blue=((int) blue_colormap[i]*MaxRGB)/65535;
  6538.             }
  6539.             break;
  6540.           }
  6541.           default:
  6542.             break;
  6543.         }
  6544.         /*
  6545.           Convert image to PseudoClass runlength-encoded packets.
  6546.         */
  6547.         if (quantum > 1)
  6548.           Warning("Not enough memory","subsampling required");
  6549.         q=image->pixels;
  6550.         for (y=0; y < image->rows; y++)
  6551.         {
  6552.           for (i=0; i < quantum; i++)
  6553.             TIFFReadScanline(tiff,scanline,y*quantum+i,0);
  6554.           p=scanline;
  6555.           r=quantum_scanline;
  6556.           switch (photometric)
  6557.           {
  6558.             case PHOTOMETRIC_MINISBLACK:
  6559.             case PHOTOMETRIC_MINISWHITE:
  6560.             {
  6561.               switch (bits_per_sample)
  6562.               {
  6563.                 case 1:
  6564.                 {
  6565.                   register int
  6566.                     bit;
  6567.  
  6568.                   for (x=0; x < (width-7); x+=8)
  6569.                   {
  6570.                     for (bit=7; bit >= 0; bit--)
  6571.                       *r++=((*p) & (0x01 << bit) ? 0x01 : 0x00);
  6572.                     p++;
  6573.                   }
  6574.                   if ((width % 8) != 0)
  6575.                     {
  6576.                       for (bit=7; bit >= (8-(width % 8)); bit--)
  6577.                         *r++=((*p) & (0x01 << bit) ? 0x00 : 0x01);
  6578.                       p++;
  6579.                     }
  6580.                   break;
  6581.                 }
  6582.                 case 2:
  6583.                 {
  6584.                   for (x=0; x < (width-3); x+=4)
  6585.                   {
  6586.                     *r++=(*p >> 6) & 0x3;
  6587.                     *r++=(*p >> 4) & 0x3;
  6588.                     *r++=(*p >> 2) & 0x3;
  6589.                     *r++=(*p) & 0x3;
  6590.                     p++;
  6591.                   }
  6592.                   if ((width % 4) != 0)
  6593.                     {
  6594.                       for (i=3; i >= (4-(width % 4)); i--)
  6595.                         *r++=(*p >> (i*2)) & 0x03;
  6596.                       p++;
  6597.                     }
  6598.                   break;
  6599.                 }
  6600.                 case 4:
  6601.                 {
  6602.                   for (x=0; x < (width-1); x+=2)
  6603.                   {
  6604.                     *r++=(*p >> 4) & 0xf;
  6605.                     *r++=(*p) & 0xf;
  6606.                     p++;
  6607.                   }
  6608.                   if ((width % 2) != 0)
  6609.                     {
  6610.                       *r++=(*p >> 4) & 0xf;
  6611.                       p++;
  6612.                     }
  6613.                   break;
  6614.                 }
  6615.                 case 8:
  6616.                 {
  6617.                   for (x=0; x < width; x++)
  6618.                   {
  6619.                     *r++=(*p);
  6620.                     p++;
  6621.                   }
  6622.                   break;
  6623.                 }
  6624.                 default:
  6625.                   break;
  6626.               }
  6627.               break;
  6628.             }
  6629.             case PHOTOMETRIC_PALETTE:
  6630.             {
  6631.               for (x=0; x < width; x++)
  6632.               {
  6633.                 *r++=(*p);
  6634.                 p++;
  6635.               }
  6636.               break;
  6637.             }
  6638.             default:
  6639.               break;
  6640.           }
  6641.           /*
  6642.             Subsample quantum scanline.
  6643.           */
  6644.           r=quantum_scanline;
  6645.           for (x=0; x < image->columns; x++)
  6646.           {
  6647.             q->index=(*r);
  6648.             q->length=0;
  6649.             q++;
  6650.             r+=quantum;
  6651.           }
  6652.         }
  6653.         (void) free((char *) quantum_scanline);
  6654.         (void) free((char *) scanline);
  6655.       }
  6656.     if (image->class == PseudoClass)
  6657.       {
  6658.         SyncImage(image);
  6659.         CompressColormap(image);
  6660.       }
  6661.     /*
  6662.       Proceed to next image.
  6663.     */
  6664.     status=TIFFReadDirectory(tiff);
  6665.     if (status == True)
  6666.       {
  6667.         /*
  6668.           Allocate image structure.
  6669.         */
  6670.         image->next=AllocateImage(image_info);
  6671.         if (image->next == (Image *) NULL)
  6672.           {
  6673.             DestroyImages(image);
  6674.             return((Image *) NULL);
  6675.           }
  6676.         (void) strcpy(image->next->filename,image_info->filename);
  6677.         image->next->file=image->file;
  6678.         image->next->scene=image->scene+1;
  6679.         image->next->previous=image;
  6680.         image=image->next;
  6681.       }
  6682.   } while (status == True);
  6683.   TIFFClose(tiff);
  6684.   while (image->previous != (Image *) NULL)
  6685.     image=image->previous;
  6686.   return(image);
  6687. }
  6688. #else
  6689. static Image *ReadTIFFImage(image_info)
  6690. ImageInfo
  6691.   *image_info;
  6692. {
  6693.   Warning("TIFF library is not available",image_info->filename);
  6694.   return(ReadMIFFImage(image_info));
  6695. }
  6696. #endif
  6697.  
  6698. /*
  6699. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6700. %                                                                             %
  6701. %                                                                             %
  6702. %                                                                             %
  6703. %   R e a d V I C A R I m a g e                                               %
  6704. %                                                                             %
  6705. %                                                                             %
  6706. %                                                                             %
  6707. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6708. %
  6709. %  Function ReadVICARImage reads a VICAR image file and returns it.  It
  6710. %  allocates the memory necessary for the new Image structure and returns a
  6711. %  pointer to the new image.
  6712. %
  6713. %  The format of the ReadVICARImage routine is:
  6714. %
  6715. %      image=ReadVICARImage(image_info)
  6716. %
  6717. %  A description of each parameter follows:
  6718. %
  6719. %    o image: Function ReadVICARImage returns a pointer to the image after
  6720. %      reading.  A null image is returned if there is a a memory shortage or if
  6721. %      the image cannot be read.
  6722. %
  6723. %    o filename: Specifies the name of the image to read.
  6724. %
  6725. %
  6726. */
  6727. static Image *ReadVICARImage(image_info)
  6728. ImageInfo
  6729.   *image_info;
  6730. {
  6731.   char
  6732.     keyword[MaxTextLength],
  6733.     value[MaxTextLength];
  6734.  
  6735.   Image
  6736.     *image;
  6737.  
  6738.   long
  6739.     count;
  6740.  
  6741.   register int
  6742.     c,
  6743.     i;
  6744.  
  6745.   register RunlengthPacket
  6746.     *q;
  6747.  
  6748.   register unsigned char
  6749.     *p;
  6750.  
  6751.   unsigned char
  6752.     *vicar_pixels;
  6753.  
  6754.   unsigned int
  6755.     header_length,
  6756.     status,
  6757.     value_expected;
  6758.  
  6759.   /*
  6760.     Allocate image structure.
  6761.   */
  6762.   image=AllocateImage(image_info);
  6763.   if (image == (Image *) NULL)
  6764.     return((Image *) NULL);
  6765.   /*
  6766.     Open image file.
  6767.   */
  6768.   OpenImage(image,"r");
  6769.   if (image->file == (FILE *) NULL)
  6770.     {
  6771.       Warning("Unable to open file",image->filename);
  6772.       DestroyImage(image);
  6773.       return((Image *) NULL);
  6774.     }
  6775.   /*
  6776.     Decode image header.
  6777.   */
  6778.   c=fgetc(image->file);
  6779.   count=1;
  6780.   if (c == EOF)
  6781.     {
  6782.       DestroyImage(image);
  6783.       return((Image *) NULL);
  6784.     }
  6785.   header_length=0;
  6786.   while (isgraph(c) && ((image->columns*image->rows) == 0))
  6787.   {
  6788.     if (!isalnum(c))
  6789.       {
  6790.         c=fgetc(image->file);
  6791.         count++;
  6792.       }
  6793.     else
  6794.       {
  6795.         register char
  6796.           *p;
  6797.  
  6798.         /*
  6799.           Determine a keyword and its value.
  6800.         */
  6801.         p=keyword;
  6802.         do
  6803.         {
  6804.           if ((p-keyword) < (MaxTextLength-1))
  6805.             *p++=(char) c;
  6806.           c=fgetc(image->file);
  6807.           count++;
  6808.         } while (isalnum(c) || (c == '_'));
  6809.         *p='\0';
  6810.         value_expected=False;
  6811.         while (isspace(c) || (c == '='))
  6812.         {
  6813.           if (c == '=')
  6814.             value_expected=True;
  6815.           c=fgetc(image->file);
  6816.           count++;
  6817.         }
  6818.         if (value_expected == False)
  6819.           continue;
  6820.         p=value;
  6821.         while (isalnum(c))
  6822.         {
  6823.           if ((p-value) < (MaxTextLength-1))
  6824.             *p++=(char) c;
  6825.           c=fgetc(image->file);
  6826.           count++;
  6827.         }
  6828.         *p='\0';
  6829.         /*
  6830.           Assign a value to the specified keyword.
  6831.         */
  6832.         if (strcmp(keyword,"LABEL_RECORDS") == 0)
  6833.           header_length=(unsigned int) atoi(value);
  6834.         if (strcmp(keyword,"LBLSIZE") == 0)
  6835.           header_length=(unsigned int) atoi(value);
  6836.         if (strcmp(keyword,"RECORD_BYTES") == 0)
  6837.           image->columns=(unsigned int) atoi(value);
  6838.         if (strcmp(keyword,"NS") == 0)
  6839.           image->columns=(unsigned int) atoi(value);
  6840.         if (strcmp(keyword,"LINES") == 0)
  6841.           image->rows=(unsigned int) atoi(value);
  6842.         if (strcmp(keyword,"NL") == 0)
  6843.           image->rows=(unsigned int) atoi(value);
  6844.       }
  6845.     while (isspace(c))
  6846.     {
  6847.       c=fgetc(image->file);
  6848.       count++;
  6849.     }
  6850.   }
  6851.   /*
  6852.     Read the rest of the header.
  6853.   */
  6854.   while (count < header_length)
  6855.   {
  6856.     c=fgetc(image->file);
  6857.     count++;
  6858.   }
  6859.   /*
  6860.     Verify that required image information is defined.
  6861.   */
  6862.   if ((image->columns*image->rows) == 0)
  6863.     {
  6864.       Warning("Incorrect image header in file",image->filename);
  6865.       DestroyImage(image);
  6866.       return((Image *) NULL);
  6867.     }
  6868.   /*
  6869.     Create linear colormap.
  6870.   */
  6871.   image->class=PseudoClass;
  6872.   image->colors=256;
  6873.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  6874.   if (image->colormap == (ColorPacket *) NULL)
  6875.     {
  6876.       Warning("Memory allocation error",(char *) NULL);
  6877.       DestroyImage(image);
  6878.       return((Image *) NULL);
  6879.     }
  6880.   for (i=0; i < image->colors; i++)
  6881.   {
  6882.     image->colormap[i].red=(unsigned char) i;
  6883.     image->colormap[i].green=(unsigned char) i;
  6884.     image->colormap[i].blue=(unsigned char) i;
  6885.   }
  6886.   /*
  6887.     Initialize image structure.
  6888.   */
  6889.   image->packets=image->columns*image->rows;
  6890.   image->pixels=(RunlengthPacket *)
  6891.     malloc(image->packets*sizeof(RunlengthPacket));
  6892.   vicar_pixels=(unsigned char *) malloc(image->packets*sizeof(unsigned char));
  6893.   if ((image->pixels == (RunlengthPacket *) NULL) ||
  6894.       (vicar_pixels == (unsigned char *) NULL))
  6895.     {
  6896.       Warning("Memory allocation error",(char *) NULL);
  6897.       DestroyImage(image);
  6898.       return((Image *) NULL);
  6899.     }
  6900.   /*
  6901.     Convert VICAR pixels to runlength-encoded packets.
  6902.   */
  6903.   status=ReadData((char *) vicar_pixels,1,(int) image->packets,image->file);
  6904.   if (status == False)
  6905.     {
  6906.       Warning("Insufficient image data in file",image->filename);
  6907.       DestroyImage(image);
  6908.       return((Image *) NULL);
  6909.     }
  6910.   /*
  6911.     Convert VICAR pixels to runlength-encoded packets.
  6912.   */
  6913.   p=vicar_pixels;
  6914.   q=image->pixels;
  6915.   for (i=0; i < image->packets; i++)
  6916.   {
  6917.     q->red=(*p);
  6918.     q->green=(*p);
  6919.     q->blue=(*p);
  6920.     q->index=(unsigned short) *p;
  6921.     q->length=0;
  6922.     p++;
  6923.     q++;
  6924.   }
  6925.   (void) free((char *) vicar_pixels);
  6926.   CompressColormap(image);
  6927.   CloseImage(image);
  6928.   return(image);
  6929. }
  6930.  
  6931. /*
  6932. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6933. %                                                                             %
  6934. %                                                                             %
  6935. %                                                                             %
  6936. %   R e a d V I F F I m a g e                                                 %
  6937. %                                                                             %
  6938. %                                                                             %
  6939. %                                                                             %
  6940. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6941. %
  6942. %  Function ReadVIFFImage reads a Khoros Visualization image file and returns
  6943. %  it.  It allocates the memory necessary for the new Image structure and
  6944. %  returns a pointer to the new image.
  6945. %
  6946. %  The format of the ReadVIFFImage routine is:
  6947. %
  6948. %      image=ReadVIFFImage(image_info)
  6949. %
  6950. %  A description of each parameter follows:
  6951. %
  6952. %    o image: Function ReadVIFFImage returns a pointer to the image after
  6953. %      reading.  A null image is returned if there is a a memory shortage or if
  6954. %      the image cannot be read.
  6955. %
  6956. %    o filename: Specifies the name of the image to read.
  6957. %
  6958. %
  6959. */
  6960. static Image *ReadVIFFImage(image_info)
  6961. ImageInfo
  6962.   *image_info;
  6963. {
  6964. #define VFF_CM_genericRGB  15
  6965. #define VFF_CM_ntscRGB  1
  6966. #define VFF_CM_NONE  0
  6967. #define VFF_DEP_DECORDER  0x4
  6968. #define VFF_DEP_NSORDER  0x8
  6969. #define VFF_DES_RAW  0
  6970. #define VFF_LOC_IMPLICIT  1
  6971. #define VFF_MAPTYP_NONE  0
  6972. #define VFF_MAPTYP_1_BYTE  1
  6973. #define VFF_MS_NONE  0
  6974. #define VFF_MS_ONEPERBAND  1
  6975. #define VFF_MS_SHARED  3
  6976. #define VFF_TYP_BIT  0
  6977. #define VFF_TYP_1_BYTE  1
  6978. #define VFF_TYP_2_BYTE  2
  6979. #define VFF_TYP_4_BYTE  4
  6980.  
  6981.   typedef struct _ViffHeader
  6982.   {
  6983.     unsigned char
  6984.       identifier,
  6985.       file_type,
  6986.       release,
  6987.       version,
  6988.       machine_dependency,
  6989.       reserve[3];
  6990.  
  6991.     char
  6992.       comment[512];
  6993.  
  6994.     unsigned long
  6995.       rows,
  6996.       columns,
  6997.       subrows;
  6998.  
  6999.     long
  7000.       x_offset,
  7001.       y_offset;
  7002.  
  7003.     float
  7004.       x_pixel_size,
  7005.       y_pixel_size;
  7006.  
  7007.     unsigned long
  7008.       location_type,
  7009.       location_dimension,
  7010.       number_of_images,
  7011.       number_data_bands,
  7012.       data_storage_type,
  7013.       data_encode_scheme,
  7014.       map_scheme,
  7015.       map_storage_type,
  7016.       map_rows,
  7017.       map_columns,
  7018.       map_subrows,
  7019.       map_enable,
  7020.       maps_per_cycle,
  7021.       color_space_model;
  7022.   } ViffHeader;
  7023.  
  7024.   Image
  7025.     *image;
  7026.  
  7027.   int
  7028.     bytes_per_pixel;
  7029.  
  7030.   register int
  7031.     bit,
  7032.     i,
  7033.     x,
  7034.     y;
  7035.  
  7036.   register RunlengthPacket
  7037.     *q;
  7038.  
  7039.   register unsigned char
  7040.     *p;
  7041.  
  7042.   unsigned char
  7043.     buffer[7],
  7044.     *viff_pixels;
  7045.  
  7046.   unsigned int
  7047.     status;
  7048.  
  7049.   unsigned long
  7050.     packets;
  7051.  
  7052.   ViffHeader
  7053.     viff_header;
  7054.  
  7055.   /*
  7056.     Allocate image structure.
  7057.   */
  7058.   image=AllocateImage(image_info);
  7059.   if (image == (Image *) NULL)
  7060.     return((Image *) NULL);
  7061.   /*
  7062.     Open image file.
  7063.   */
  7064.   OpenImage(image,"r");
  7065.   if (image->file == (FILE *) NULL)
  7066.     {
  7067.       Warning("Unable to open file",image->filename);
  7068.       DestroyImage(image);
  7069.       return((Image *) NULL);
  7070.     }
  7071.   /*
  7072.     Read VIFF header (1024 bytes).
  7073.   */
  7074.   status=ReadData((char *) &viff_header.identifier,1,1,image->file);
  7075.   do
  7076.   {
  7077.     /*
  7078.       Verify VIFF identifier.
  7079.     */
  7080.     if ((status == False) || ((unsigned char) viff_header.identifier != 0xab))
  7081.       {
  7082.         Warning("Not a VIFF raster,",image->filename);
  7083.         DestroyImages(image);
  7084.         return((Image *) NULL);
  7085.       }
  7086.     /*
  7087.       Initialize VIFF image.
  7088.     */
  7089.     (void) ReadData((char *) buffer,1,7,image->file);
  7090.     viff_header.file_type=buffer[0];
  7091.     viff_header.release=buffer[1];
  7092.     viff_header.version=buffer[2];
  7093.     viff_header.machine_dependency=buffer[3];
  7094.     (void) ReadData((char *) viff_header.comment,1,512,image->file);
  7095.     viff_header.comment[511]='\0';
  7096.     if ((int) strlen(viff_header.comment) > 4)
  7097.       {
  7098.         image->comments=(char *)
  7099.           malloc((unsigned int) (strlen(viff_header.comment)+1)*sizeof(char));
  7100.         if (image->comments == (char *) NULL)
  7101.           {
  7102.             Warning("Memory allocation error",(char *) NULL);
  7103.             DestroyImages(image);
  7104.             return((Image *) NULL);
  7105.           }
  7106.         (void) strcpy(image->comments,viff_header.comment);
  7107.       }
  7108.     if ((viff_header.machine_dependency == VFF_DEP_DECORDER) ||
  7109.         (viff_header.machine_dependency == VFF_DEP_NSORDER))
  7110.       {
  7111.         viff_header.rows=LSBFirstReadLong(image->file);
  7112.         viff_header.columns=LSBFirstReadLong(image->file);
  7113.         viff_header.subrows=LSBFirstReadLong(image->file);
  7114.         viff_header.x_offset=LSBFirstReadLong(image->file);
  7115.         viff_header.y_offset=LSBFirstReadLong(image->file);
  7116.         viff_header.x_pixel_size=(float) LSBFirstReadLong(image->file);
  7117.         viff_header.y_pixel_size=(float) LSBFirstReadLong(image->file);
  7118.         viff_header.location_type=LSBFirstReadLong(image->file);
  7119.         viff_header.location_dimension=LSBFirstReadLong(image->file);
  7120.         viff_header.number_of_images=LSBFirstReadLong(image->file);
  7121.         viff_header.number_data_bands=LSBFirstReadLong(image->file);
  7122.         viff_header.data_storage_type=LSBFirstReadLong(image->file);
  7123.         viff_header.data_encode_scheme=LSBFirstReadLong(image->file);
  7124.         viff_header.map_scheme=LSBFirstReadLong(image->file);
  7125.         viff_header.map_storage_type=LSBFirstReadLong(image->file);
  7126.         viff_header.map_rows=LSBFirstReadLong(image->file);
  7127.         viff_header.map_columns=LSBFirstReadLong(image->file);
  7128.         viff_header.map_subrows=LSBFirstReadLong(image->file);
  7129.         viff_header.map_enable=LSBFirstReadLong(image->file);
  7130.         viff_header.maps_per_cycle=LSBFirstReadLong(image->file);
  7131.         viff_header.color_space_model=LSBFirstReadLong(image->file);
  7132.       }
  7133.     else
  7134.       {
  7135.         viff_header.rows=MSBFirstReadLong(image->file);
  7136.         viff_header.columns=MSBFirstReadLong(image->file);
  7137.         viff_header.subrows=MSBFirstReadLong(image->file);
  7138.         viff_header.x_offset=MSBFirstReadLong(image->file);
  7139.         viff_header.y_offset=MSBFirstReadLong(image->file);
  7140.         viff_header.x_pixel_size=(float) MSBFirstReadLong(image->file);
  7141.         viff_header.y_pixel_size=(float) MSBFirstReadLong(image->file);
  7142.         viff_header.location_type=MSBFirstReadLong(image->file);
  7143.         viff_header.location_dimension=MSBFirstReadLong(image->file);
  7144.         viff_header.number_of_images=MSBFirstReadLong(image->file);
  7145.         viff_header.number_data_bands=MSBFirstReadLong(image->file);
  7146.         viff_header.data_storage_type=MSBFirstReadLong(image->file);
  7147.         viff_header.data_encode_scheme=MSBFirstReadLong(image->file);
  7148.         viff_header.map_scheme=MSBFirstReadLong(image->file);
  7149.         viff_header.map_storage_type=MSBFirstReadLong(image->file);
  7150.         viff_header.map_rows=MSBFirstReadLong(image->file);
  7151.         viff_header.map_columns=MSBFirstReadLong(image->file);
  7152.         viff_header.map_subrows=MSBFirstReadLong(image->file);
  7153.         viff_header.map_enable=MSBFirstReadLong(image->file);
  7154.         viff_header.maps_per_cycle=MSBFirstReadLong(image->file);
  7155.         viff_header.color_space_model=MSBFirstReadLong(image->file);
  7156.       }
  7157.     for (i=0; i < 420; i++)
  7158.       (void) fgetc(image->file);
  7159.     /*
  7160.       Verify that we can read this VIFF image.
  7161.     */
  7162.     if ((viff_header.columns*viff_header.rows) == 0)
  7163.       {
  7164.         Warning("Image column or row size is not supported",image->filename);
  7165.         DestroyImages(image);
  7166.         return((Image *) NULL);
  7167.       }
  7168.     if ((viff_header.data_storage_type != VFF_TYP_BIT) &&
  7169.         (viff_header.data_storage_type != VFF_TYP_1_BYTE) &&
  7170.         (viff_header.data_storage_type != VFF_TYP_2_BYTE) &&
  7171.         (viff_header.data_storage_type != VFF_TYP_4_BYTE))
  7172.       {
  7173.         Warning("Data storage type is not supported",image->filename);
  7174.         DestroyImages(image);
  7175.         return((Image *) NULL);
  7176.       }
  7177.     if (viff_header.data_encode_scheme != VFF_DES_RAW)
  7178.       {
  7179.         Warning("Data encoding scheme is not supported",image->filename);
  7180.         DestroyImages(image);
  7181.         return((Image *) NULL);
  7182.       }
  7183.     if ((viff_header.map_storage_type != VFF_MAPTYP_NONE) &&
  7184.         (viff_header.map_storage_type != VFF_MAPTYP_1_BYTE))
  7185.       {
  7186.         Warning("Map storage type is not supported",image->filename);
  7187.         DestroyImages(image);
  7188.         return((Image *) NULL);
  7189.       }
  7190.     if ((viff_header.color_space_model != VFF_CM_NONE) &&
  7191.         (viff_header.color_space_model != VFF_CM_ntscRGB) &&
  7192.         (viff_header.color_space_model != VFF_CM_genericRGB))
  7193.       {
  7194.         Warning("Color space model is not supported",image->filename);
  7195.         DestroyImages(image);
  7196.         return((Image *) NULL);
  7197.       }
  7198.     if (viff_header.location_type != VFF_LOC_IMPLICIT)
  7199.       {
  7200.         Warning("Location type is not supported",image->filename);
  7201.         DestroyImages(image);
  7202.         return((Image *) NULL);
  7203.       }
  7204.     if (viff_header.number_of_images != 1)
  7205.       {
  7206.         Warning("Number of images is not supported",image->filename);
  7207.         DestroyImages(image);
  7208.         return((Image *) NULL);
  7209.       }
  7210.     switch (viff_header.map_scheme)
  7211.     {
  7212.       case VFF_MS_NONE:
  7213.       {
  7214.         if (viff_header.number_data_bands < 3)
  7215.           {
  7216.             /*
  7217.               Create linear color ramp.
  7218.             */
  7219.             if (viff_header.data_storage_type == VFF_TYP_BIT)
  7220.               image->colors=2;
  7221.             else
  7222.               image->colors=1 << (viff_header.number_data_bands*8);
  7223.             image->colormap=(ColorPacket *)
  7224.               malloc(image->colors*sizeof(ColorPacket));
  7225.             if (image->colormap == (ColorPacket *) NULL)
  7226.               {
  7227.                 Warning("Memory allocation error",(char *) NULL);
  7228.                 return((Image *) NULL);
  7229.               }
  7230.             for (i=0; i < image->colors; i++)
  7231.             {
  7232.               image->colormap[i].red=(MaxRGB*i)/(image->colors-1);
  7233.               image->colormap[i].green=(MaxRGB*i)/(image->colors-1);
  7234.               image->colormap[i].blue=(MaxRGB*i)/(image->colors-1);
  7235.             }
  7236.           }
  7237.         break;
  7238.       }
  7239.       case VFF_MS_ONEPERBAND:
  7240.       case VFF_MS_SHARED:
  7241.       {
  7242.         unsigned char
  7243.           *viff_colormap;
  7244.  
  7245.         /*
  7246.           Read VIFF raster colormap.
  7247.         */
  7248.         image->colors=viff_header.map_columns;
  7249.         image->colormap=(ColorPacket *)
  7250.           malloc(image->colors*sizeof(ColorPacket));
  7251.         viff_colormap=(unsigned char *)
  7252.           malloc(image->colors*sizeof(unsigned char));
  7253.         if ((image->colormap == (ColorPacket *) NULL) ||
  7254.             (viff_colormap == (unsigned char *) NULL))
  7255.           {
  7256.             Warning("Memory allocation error",(char *) NULL);
  7257.             DestroyImages(image);
  7258.             return((Image *) NULL);
  7259.           }
  7260.         (void) ReadData((char *) viff_colormap,1,(int) image->colors,
  7261.           image->file);
  7262.         for (i=0; i < image->colors; i++)
  7263.         {
  7264.           image->colormap[i].red=viff_colormap[i];
  7265.           image->colormap[i].green=viff_colormap[i];
  7266.           image->colormap[i].blue=viff_colormap[i];
  7267.         }
  7268.         if (viff_header.map_rows > 1)
  7269.           {
  7270.             (void) ReadData((char *) viff_colormap,1,(int) image->colors,
  7271.               image->file);
  7272.             for (i=0; i < image->colors; i++)
  7273.               image->colormap[i].green=viff_colormap[i];
  7274.           }
  7275.         if (viff_header.map_rows > 2)
  7276.           {
  7277.             (void) ReadData((char *) viff_colormap,1,(int) image->colors,
  7278.               image->file);
  7279.             for (i=0; i < image->colors; i++)
  7280.               image->colormap[i].blue=viff_colormap[i];
  7281.           }
  7282.         (void) free((char *) viff_colormap);
  7283.         break;
  7284.       }
  7285.       default:
  7286.       {
  7287.         Warning("Colormap type is not supported",image->filename);
  7288.         DestroyImages(image);
  7289.         return((Image *) NULL);
  7290.       }
  7291.     }
  7292.     /*
  7293.       Allocate VIFF pixels.
  7294.     */
  7295.     bytes_per_pixel=1;
  7296.     if (viff_header.data_storage_type == VFF_TYP_2_BYTE)
  7297.       bytes_per_pixel=2;
  7298.     if (viff_header.data_storage_type == VFF_TYP_4_BYTE)
  7299.       bytes_per_pixel=4;
  7300.     if (viff_header.data_storage_type == VFF_TYP_BIT)
  7301.       packets=((viff_header.columns+7) >> 3)*viff_header.rows;
  7302.     else
  7303.       packets=
  7304.         viff_header.columns*viff_header.rows*viff_header.number_data_bands;
  7305.     viff_pixels=(unsigned char *)
  7306.       malloc(bytes_per_pixel*packets*sizeof(unsigned char));
  7307.     if (viff_pixels == (unsigned char *) NULL)
  7308.       {
  7309.         Warning("Memory allocation error",(char *) NULL);
  7310.         DestroyImages(image);
  7311.         return((Image *) NULL);
  7312.       }
  7313.     (void) ReadData((char *) viff_pixels,bytes_per_pixel,(int) packets,
  7314.       image->file);
  7315.     if (viff_header.data_storage_type == VFF_TYP_2_BYTE)
  7316.       {
  7317.         register short int
  7318.           *p;
  7319.  
  7320.         register unsigned char
  7321.           *q;
  7322.  
  7323.         short int
  7324.           max_value,
  7325.           min_value,
  7326.           value;
  7327.  
  7328.         unsigned long
  7329.           scale_factor;
  7330.  
  7331.         /*
  7332.           Ensure the header byte-order is most-significant byte first.
  7333.         */
  7334.         if ((viff_header.machine_dependency == VFF_DEP_DECORDER) ||
  7335.             (viff_header.machine_dependency == VFF_DEP_NSORDER))
  7336.           MSBFirstOrderShort((char *) &viff_header,bytes_per_pixel*packets);
  7337.         /*
  7338.           Determine scale factor.
  7339.         */
  7340.         p=(short int *) viff_pixels;
  7341.         max_value=(*p);
  7342.         min_value=(*p);
  7343.         for (i=0; i < packets; i++)
  7344.         {
  7345.           if (*p > max_value)
  7346.             max_value=(*p);
  7347.           else
  7348.             if (*p < min_value)
  7349.               min_value=(*p);
  7350.           p++;
  7351.         }
  7352.         if ((min_value == 0) && (max_value == 0))
  7353.           scale_factor=0;
  7354.         else
  7355.           if (min_value == max_value)
  7356.             {
  7357.               scale_factor=UpShift(MaxRGB)/min_value;
  7358.               min_value=0;
  7359.             }
  7360.           else
  7361.             scale_factor=UpShift(MaxRGB)/(max_value-min_value);
  7362.         /*
  7363.           Scale integer pixels to [0..MaxRGB].
  7364.         */
  7365.         p=(short int *) viff_pixels;
  7366.         q=viff_pixels;
  7367.         for (i=0; i < packets; i++)
  7368.         {
  7369.           value=DownShift((*p-min_value)*scale_factor);
  7370.           if (value > MaxRGB)
  7371.             value=MaxRGB;
  7372.           else
  7373.             if (value < 0)
  7374.               value=0;
  7375.           *q=(unsigned char) value;
  7376.           p++;
  7377.           q++;
  7378.         }
  7379.       }
  7380.     if (viff_header.data_storage_type == VFF_TYP_4_BYTE)
  7381.       {
  7382.         int
  7383.           max_value,
  7384.           min_value,
  7385.           value;
  7386.  
  7387.         register int
  7388.           *p;
  7389.  
  7390.         register unsigned char
  7391.           *q;
  7392.  
  7393.         unsigned long
  7394.           scale_factor;
  7395.  
  7396.         /*
  7397.           Ensure the header byte-order is most-significant byte first.
  7398.         */
  7399.         if ((viff_header.machine_dependency == VFF_DEP_DECORDER) ||
  7400.             (viff_header.machine_dependency == VFF_DEP_NSORDER))
  7401.           MSBFirstOrderLong((char *) &viff_header,bytes_per_pixel*packets);
  7402.         /*
  7403.           Determine scale factor.
  7404.         */
  7405.         p=(int *) viff_pixels;
  7406.         max_value=(*p);
  7407.         min_value=(*p);
  7408.         for (i=0; i < packets; i++)
  7409.         {
  7410.           if (*p > max_value)
  7411.             max_value=(*p);
  7412.           else
  7413.             if (*p < min_value)
  7414.               min_value=(*p);
  7415.           p++;
  7416.         }
  7417.         if ((min_value == 0) && (max_value == 0))
  7418.           scale_factor=0;
  7419.         else
  7420.           if (min_value == max_value)
  7421.             {
  7422.               scale_factor=UpShift(MaxRGB)/min_value;
  7423.               min_value=0;
  7424.             }
  7425.           else
  7426.             scale_factor=UpShift(MaxRGB)/(max_value-min_value);
  7427.         /*
  7428.           Scale integer pixels to [0..MaxRGB].
  7429.         */
  7430.         p=(int *) viff_pixels;
  7431.         q=viff_pixels;
  7432.         for (i=0; i < packets; i++)
  7433.         {
  7434.           value=DownShift((*p-min_value)*scale_factor);
  7435.           if (value > MaxRGB)
  7436.             value=MaxRGB;
  7437.           else
  7438.             if (value < 0)
  7439.               value=0;
  7440.           *q=(unsigned char) value;
  7441.           p++;
  7442.           q++;
  7443.         }
  7444.       }
  7445.     /*
  7446.       Initialize image structure.
  7447.     */
  7448.     image->alpha=(viff_header.number_data_bands == 4);
  7449.     image->class=
  7450.       (viff_header.number_data_bands < 3 ? PseudoClass : DirectClass);
  7451.     image->columns=viff_header.rows;
  7452.     image->rows=viff_header.columns;
  7453.     image->packets=image->columns*image->rows;
  7454.     image->pixels=(RunlengthPacket *)
  7455.       malloc(image->packets*sizeof(RunlengthPacket));
  7456.     if (image->pixels == (RunlengthPacket *) NULL)
  7457.       {
  7458.         Warning("Memory allocation error",(char *) NULL);
  7459.         DestroyImages(image);
  7460.         return((Image *) NULL);
  7461.       }
  7462.     /*
  7463.       Convert VIFF raster image to runlength-encoded packets.
  7464.     */
  7465.     p=viff_pixels;
  7466.     q=image->pixels;
  7467.     if (viff_header.data_storage_type == VFF_TYP_BIT)
  7468.       {
  7469.         unsigned int
  7470.           polarity;
  7471.  
  7472.         /*
  7473.           Convert bitmap scanline to runlength-encoded color packets.
  7474.         */
  7475.         polarity=(viff_header.machine_dependency == VFF_DEP_DECORDER) ||
  7476.           (viff_header.machine_dependency == VFF_DEP_NSORDER);
  7477.         for (y=0; y < image->rows; y++)
  7478.         {
  7479.           /*
  7480.             Convert bitmap scanline to runlength-encoded color packets.
  7481.           */
  7482.           for (x=0; x < (image->columns >> 3); x++)
  7483.           {
  7484.             for (bit=0; bit < 8; bit++)
  7485.             {
  7486.               q->index=((*p) & (0x01 << bit) ? polarity : !polarity);
  7487.               q->length=0;
  7488.               q++;
  7489.             }
  7490.             p++;
  7491.           }
  7492.           if ((image->columns % 8) != 0)
  7493.             {
  7494.               for (bit=0; bit < (image->columns % 8); bit++)
  7495.               {
  7496.                 q->index=((*p) & (0x01 << bit) ? polarity : !polarity);
  7497.                 q->length=0;
  7498.                 q++;
  7499.               }
  7500.               p++;
  7501.             }
  7502.         }
  7503.       }
  7504.     else
  7505.       if (image->class == PseudoClass)
  7506.         for (y=0; y < image->rows; y++)
  7507.         {
  7508.           /*
  7509.             Convert PseudoColor scanline to runlength-encoded color packets.
  7510.           */
  7511.           for (x=0; x < image->columns; x++)
  7512.           {
  7513.             q->index=(*p++);
  7514.             q->length=0;
  7515.             q++;
  7516.           }
  7517.         }
  7518.       else
  7519.         {
  7520.           unsigned long
  7521.             offset;
  7522.  
  7523.           /*
  7524.             Convert DirectColor scanline to runlength-encoded color packets.
  7525.           */
  7526.           offset=image->columns*image->rows;
  7527.           for (y=0; y < image->rows; y++)
  7528.           {
  7529.             for (x=0; x < image->columns; x++)
  7530.             {
  7531.               q->red=(*p);
  7532.               q->green=(*(p+offset));
  7533.               q->blue=(*(p+offset*2));
  7534.               if (image->colors != 0)
  7535.                 {
  7536.                   q->red=image->colormap[q->red].red;
  7537.                   q->green=image->colormap[q->green].green;
  7538.                   q->blue=image->colormap[q->blue].blue;
  7539.                 }
  7540.               q->index=(unsigned short) (image->alpha ? (*(p+offset*3)) : 0);
  7541.               q->length=0;
  7542.               p++;
  7543.               q++;
  7544.             }
  7545.           }
  7546.         }
  7547.     (void) free((char *) viff_pixels);
  7548.     if (image->class == PseudoClass)
  7549.       {
  7550.         SyncImage(image);
  7551.         CompressColormap(image);
  7552.       }
  7553.     /*
  7554.       Proceed to next image.
  7555.     */
  7556.     status=ReadData((char *) &viff_header.identifier,1,1,image->file);
  7557.     if ((status == True) && (viff_header.identifier == 0xab))
  7558.       {
  7559.         /*
  7560.           Allocate image structure.
  7561.         */
  7562.         image->next=AllocateImage(image_info);
  7563.         if (image->next == (Image *) NULL)
  7564.           {
  7565.             DestroyImages(image);
  7566.             return((Image *) NULL);
  7567.           }
  7568.         (void) strcpy(image->next->filename,image_info->filename);
  7569.         image->next->file=image->file;
  7570.         image->next->scene=image->scene+1;
  7571.         image->next->previous=image;
  7572.         image=image->next;
  7573.       }
  7574.   } while ((status == True) && (viff_header.identifier == 0xab));
  7575.   while (image->previous != (Image *) NULL)
  7576.     image=image->previous;
  7577.   CloseImage(image);
  7578.   return(image);
  7579. }
  7580.  
  7581. /*
  7582. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7583. %                                                                             %
  7584. %                                                                             %
  7585. %                                                                             %
  7586. %   R e a d X I m a g e                                                       %
  7587. %                                                                             %
  7588. %                                                                             %
  7589. %                                                                             %
  7590. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7591. %
  7592. %  Procedure ReadXImage reads an image from an X window.
  7593. %
  7594. %  The format of the ReadXImage routine is:
  7595. %
  7596. %      image=ReadXImage(image_info,frame,borders,screen,descend)
  7597. %
  7598. %  A description of each parameter follows:
  7599. %
  7600. %    o image_info: Specifies a pointer to an ImageInfo structure.
  7601. %
  7602. %    o frame: Specifies whether to include the window manager frame with the
  7603. %      image.
  7604. %
  7605. %    o borders: Specifies whether borders pixels are to be saved with
  7606. %      the image.
  7607. %
  7608. %    o screen: Specifies whether the GetImage request used to obtain the image
  7609. %      should be done on the root window, rather than directly on the specified
  7610. %      window.
  7611. %
  7612. %    o descend: If this option is zero the colormap of the chosen window is
  7613. %      used to obtain the red, green, and blue values.  Otherwise the image
  7614. %      is obtained by descending the window hierarchy and reading each
  7615. %      subwindow and its colormap.
  7616. %
  7617. %
  7618. */
  7619. Image *ReadXImage(image_info,frame,borders,screen,descend)
  7620. ImageInfo
  7621.   *image_info;
  7622.  
  7623. unsigned int
  7624.   frame,
  7625.   borders,
  7626.   screen,
  7627.   descend;
  7628. {
  7629.   Colormap
  7630.     *colormaps;
  7631.  
  7632.   Display
  7633.     *display;
  7634.  
  7635.   Image
  7636.     *image;
  7637.  
  7638.   int
  7639.     number_colormaps,
  7640.     number_windows,
  7641.     status,
  7642.     x;
  7643.  
  7644.   RectangleInfo
  7645.     clip_info;
  7646.  
  7647.   Window
  7648.     client_window,
  7649.     *colormap_windows,
  7650.     root_window,
  7651.     target_window;
  7652.  
  7653.   XTextProperty
  7654.     window_name;
  7655.  
  7656.   /*
  7657.     Open X server connection.
  7658.   */
  7659.   display=XOpenDisplay(image_info->server_name);
  7660.   if (display == (Display *) NULL)
  7661.     {
  7662.       Warning("Unable to connect to X server",
  7663.         XDisplayName(image_info->server_name));
  7664.       return((Image *) NULL);
  7665.     }
  7666.   /*
  7667.     Set our forgiving error handler.
  7668.   */
  7669.   XSetErrorHandler(XError);
  7670.   /*
  7671.     Select target window.
  7672.   */
  7673.   clip_info.x=0;
  7674.   clip_info.y=0;
  7675.   clip_info.width=0;
  7676.   clip_info.height=0;
  7677.   root_window=XRootWindow(display,XDefaultScreen(display));
  7678.   target_window=(Window) NULL;
  7679.   if ((image_info->filename != (char *) NULL) &&
  7680.       (*image_info->filename != '\0'))
  7681.     if (Latin1Compare(image_info->filename,"root") == 0)
  7682.       target_window=root_window;
  7683.     else
  7684.       {
  7685.         /*
  7686.           Select window by ID or name.
  7687.         */
  7688.         if (isdigit(*image_info->filename))
  7689.           target_window=XWindowByID(display,root_window,
  7690.             (Window) strtol(image_info->filename,(char **) NULL,0));
  7691.         if (target_window == (Window) NULL)
  7692.           target_window=XWindowByName(display,root_window,image_info->filename);
  7693.         if (target_window == (Window) NULL)
  7694.           Warning("No window with specified id exists",image_info->filename);
  7695.       }
  7696.   /*
  7697.     If target window is not defined, interactively select one.
  7698.   */
  7699.   if (target_window == (Window) NULL)
  7700.     target_window=XSelectWindow(display,&clip_info);
  7701.   client_window=target_window;
  7702.   if (target_window != root_window)
  7703.     {
  7704.       unsigned int
  7705.         d;
  7706.  
  7707.       /*
  7708.         Get client window.
  7709.       */
  7710.       status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
  7711.       if (status != 0)
  7712.         {
  7713.           client_window=XClientWindow(display,target_window);
  7714.           if (!frame)
  7715.             target_window=client_window;
  7716.         }
  7717.     }
  7718.   if (screen)
  7719.     {
  7720.       int
  7721.         y;
  7722.  
  7723.       Window
  7724.         child;
  7725.  
  7726.       XWindowAttributes
  7727.         window_attributes;
  7728.  
  7729.       /*
  7730.         Obtain window image directly from screen.
  7731.       */
  7732.       status=XGetWindowAttributes(display,target_window,&window_attributes);
  7733.       if (status == False)
  7734.         {
  7735.           Warning("Unable to read X window attributes",image_info->filename);
  7736.           XCloseDisplay(display);
  7737.           return((Image *) NULL);
  7738.         }
  7739.       XTranslateCoordinates(display,target_window,root_window,0,0,&x,&y,&child);
  7740.       clip_info.x=x;
  7741.       clip_info.y=y;
  7742.       clip_info.width=window_attributes.width;
  7743.       clip_info.height=window_attributes.height;
  7744.       if (borders)
  7745.         {
  7746.           /*
  7747.             Include border in image.
  7748.           */
  7749.           clip_info.x-=window_attributes.border_width;
  7750.           clip_info.y-=window_attributes.border_width;
  7751.           clip_info.width+=window_attributes.border_width << 1;
  7752.           clip_info.height+=window_attributes.border_width << 1;
  7753.         }
  7754.       target_window=root_window;
  7755.     }
  7756.   /*
  7757.     If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend.
  7758.   */
  7759.   number_windows=0;
  7760.   status=XGetWMColormapWindows(display,target_window,&colormap_windows,
  7761.     &number_windows);
  7762.   if ((status == True) && (number_windows > 0))
  7763.     {
  7764.       descend=True;
  7765.       XFree ((char *) colormap_windows);
  7766.     }
  7767.   colormaps=XListInstalledColormaps(display,target_window,&number_colormaps);
  7768.   if (number_colormaps > 0)
  7769.     {
  7770.       if (number_colormaps > 1)
  7771.         descend=True;
  7772.       XFree((char *) colormaps);
  7773.     }
  7774.   /*
  7775.     Alert the user not to alter the screen.
  7776.   */
  7777.   XBell(display,0);
  7778.   /*
  7779.     Get image by window id.
  7780.   */
  7781.   XGrabServer(display);
  7782.   image=XGetWindowImage(display,target_window,borders,descend);
  7783.   XUngrabServer(display);
  7784.   (void) strcpy(image->filename,image_info->filename);
  7785.   if (image == (Image *) NULL)
  7786.     Warning("Unable to read X window image",image_info->filename);
  7787.   else
  7788.     {
  7789.       if ((clip_info.width != 0) && (clip_info.height != 0))
  7790.         {
  7791.           Image
  7792.             *clipped_image;
  7793.  
  7794.           /*
  7795.             Clip image as defined by the clipping rectangle.
  7796.           */
  7797.           clipped_image=ClipImage(image,&clip_info);
  7798.           if (clipped_image != (Image *) NULL)
  7799.             {
  7800.               DestroyImage(image);
  7801.               image=clipped_image;
  7802.             }
  7803.         }
  7804.       status=XGetWMName(display,target_window,&window_name);
  7805.       if (status == True)
  7806.         {
  7807.           if ((image_info->filename != (char *) NULL) &&
  7808.               (*image_info->filename == '\0'))
  7809.             {
  7810.               /*
  7811.                 Initialize image filename.
  7812.               */
  7813.               (void) strncpy(image->filename,(char *) window_name.value,
  7814.                 (int) window_name.nitems);
  7815.               image->filename[window_name.nitems]='\0';
  7816.             }
  7817.         }
  7818.     }
  7819.   /*
  7820.     Alert the user we're done.
  7821.   */
  7822.   XBell(display,0);
  7823.   XBell(display,0);
  7824.   XCloseDisplay(display);
  7825.   return(image);
  7826. }
  7827.  
  7828. /*
  7829. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7830. %                                                                             %
  7831. %                                                                             %
  7832. %                                                                             %
  7833. %  R e a d X B M I m a g e                                                    %
  7834. %                                                                             %
  7835. %                                                                             %
  7836. %                                                                             %
  7837. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7838. %
  7839. %  Function ReadXBMImage reads an X11 bitmap image file and returns it.  It
  7840. %  allocates the memory necessary for the new Image structure and returns a
  7841. %  pointer to the new image.
  7842. %
  7843. %  The format of the ReadXBMImage routine is:
  7844. %
  7845. %      image=ReadXBMImage(image_info)
  7846. %
  7847. %  A description of each parameter follows:
  7848. %
  7849. %    o image:  Function ReadXBMImage returns a pointer to the image after
  7850. %      reading.  A null image is returned if there is a a memory shortage or
  7851. %      if the image cannot be read.
  7852. %
  7853. %    o image_info: Specifies a pointer to an ImageInfo structure.
  7854. %
  7855. %
  7856. */
  7857. static Image *ReadXBMImage(image_info)
  7858. ImageInfo
  7859.   *image_info;
  7860. {
  7861.   char
  7862.     data[MaxTextLength];
  7863.  
  7864.   Image
  7865.     *image;
  7866.  
  7867.   register int
  7868.     x,
  7869.     y;
  7870.  
  7871.   register RunlengthPacket
  7872.     *q;
  7873.  
  7874.   register unsigned char
  7875.     bit;
  7876.  
  7877.   register unsigned short
  7878.     index;
  7879.  
  7880.   unsigned int
  7881.     byte;
  7882.  
  7883.   /*
  7884.     Allocate image structure.
  7885.   */
  7886.   image=AllocateImage(image_info);
  7887.   if (image == (Image *) NULL)
  7888.     return((Image *) NULL);
  7889.   /*
  7890.     Open image file.
  7891.   */
  7892.   OpenImage(image,"r");
  7893.   if (image->file == (FILE *) NULL)
  7894.     {
  7895.       Warning("Unable to open file",image->filename);
  7896.       DestroyImage(image);
  7897.       return((Image *) NULL);
  7898.     }
  7899.   /*
  7900.     Read X bitmap header.
  7901.   */
  7902.   while (fgets(data,MaxTextLength,image->file) != (char *) NULL)
  7903.     if (sscanf(data,"#define %*32s %u",&image->columns) == 1)
  7904.       break;
  7905.   while (fgets(data,MaxTextLength,image->file) != (char *) NULL)
  7906.     if (sscanf(data,"#define %*32s %u",&image->rows) == 1)
  7907.       break;
  7908.   if ((image->columns == 0) || (image->rows == 0))
  7909.     {
  7910.       Warning("XBM file is not in the correct format",image->filename);
  7911.       DestroyImage(image);
  7912.       return((Image *) NULL);
  7913.     }
  7914.   while (fgets(data,MaxTextLength,image->file) != (char *) NULL)
  7915.     if (sscanf(data,"%*[^#] char"))
  7916.       break;
  7917.   if (feof(image->file))
  7918.     {
  7919.       Warning("XBM file is not in the correct format",image->filename);
  7920.       DestroyImage(image);
  7921.       return((Image *) NULL);
  7922.     }
  7923.   /*
  7924.     Initialize image structure.
  7925.   */
  7926.   image->packets=image->columns*image->rows;
  7927.   image->pixels=(RunlengthPacket *)
  7928.     malloc(image->packets*sizeof(RunlengthPacket));
  7929.   if (image->pixels == (RunlengthPacket *) NULL)
  7930.     {
  7931.       Warning("Memory allocation error",(char *) NULL);
  7932.       DestroyImage(image);
  7933.       return((Image *) NULL);
  7934.     }
  7935.   /*
  7936.     Create colormap.
  7937.   */
  7938.   image->class=PseudoClass;
  7939.   image->colors=2;
  7940.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  7941.   if (image->colormap == (ColorPacket *) NULL)
  7942.     {
  7943.       Warning("Memory allocation error",(char *) NULL);
  7944.       DestroyImage(image);
  7945.       return((Image *) NULL);
  7946.     }
  7947.   image->colormap[0].red=0;
  7948.   image->colormap[0].green=0;
  7949.   image->colormap[0].blue=0;
  7950.   image->colormap[1].red=MaxRGB;
  7951.   image->colormap[1].green=MaxRGB;
  7952.   image->colormap[1].blue=MaxRGB;
  7953.   /*
  7954.     Convert X bitmap image to runlength-encoded packets.
  7955.   */
  7956.   q=image->pixels;
  7957.   for (y=0; y < image->rows; y++)
  7958.   {
  7959.     bit=0;
  7960.     for (x=0; x < image->columns; x++)
  7961.     {
  7962.       if (bit == 0)
  7963.         (void) fscanf(image->file,"%i,",&byte);
  7964.       index=(byte & 0x01) ? 0 : 1;
  7965.       q->red=image->colormap[index].red;
  7966.       q->green=image->colormap[index].green;
  7967.       q->blue=image->colormap[index].blue;
  7968.       q->index=index;
  7969.       q->length=0;
  7970.       q++;
  7971.       bit++;
  7972.       byte>>=1;
  7973.       if (bit == 8)
  7974.         bit=0;
  7975.     }
  7976.   }
  7977.   CloseImage(image);
  7978.   return(image);
  7979. }
  7980.  
  7981. /*
  7982. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7983. %                                                                             %
  7984. %                                                                             %
  7985. %                                                                             %
  7986. %  R e a d X C I m a g e                                                      %
  7987. %                                                                             %
  7988. %                                                                             %
  7989. %                                                                             %
  7990. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7991. %
  7992. %  Function ReadXCImage creates a constant image and initializes to the
  7993. %  X server color as specified by the filename.  It allocates the memory
  7994. %  necessary for the new Image structure and returns a pointer to the new
  7995. %  image.
  7996. %
  7997. %  The format of the ReadXCImage routine is:
  7998. %
  7999. %      image=ReadXCImage(image_info)
  8000. %
  8001. %  A description of each parameter follows:
  8002. %
  8003. %    o image:  Function ReadXCImage returns a pointer to the image after
  8004. %      creating it. A null image is returned if there is a a memory shortage
  8005. %      or if the image cannot be read.
  8006. %
  8007. %    o image_info: Specifies a pointer to an ImageInfo structure.
  8008. %
  8009. %
  8010. */
  8011. static Image *ReadXCImage(image_info)
  8012. ImageInfo
  8013.   *image_info;
  8014. {
  8015.   char
  8016.     *resource_value;
  8017.  
  8018.   Display
  8019.     *display;
  8020.  
  8021.   Image
  8022.     *image;
  8023.  
  8024.   int
  8025.     x,
  8026.     y;
  8027.  
  8028.   register int
  8029.     i;
  8030.  
  8031.   register RunlengthPacket
  8032.     *q;
  8033.  
  8034.   unsigned int
  8035.     height,
  8036.     width;
  8037.  
  8038.   XPixelInfo
  8039.     pixel_info;
  8040.  
  8041.   XResourceInfo
  8042.     resource_info;
  8043.  
  8044.   XrmDatabase
  8045.     resource_database,
  8046.     server_database;
  8047.  
  8048.   XStandardColormap
  8049.     *map_info;
  8050.  
  8051.   XVisualInfo
  8052.     *visual_info;
  8053.  
  8054.   /*
  8055.     Allocate image structure.
  8056.   */
  8057.   image=AllocateImage(image_info);
  8058.   if (image == (Image *) NULL)
  8059.     return((Image *) NULL);
  8060.   /*
  8061.     Open X server connection.
  8062.   */
  8063.   display=XOpenDisplay(image_info->server_name);
  8064.   if (display == (Display *) NULL)
  8065.     {
  8066.       Warning("Unable to connect to X server",
  8067.         XDisplayName(image_info->server_name));
  8068.       DestroyImage(image);
  8069.       return((Image *) NULL);
  8070.     }
  8071.   /*
  8072.     Set our forgiving error handler.
  8073.   */
  8074.   XSetErrorHandler(XError);
  8075.   /*
  8076.     Get user defaults from X resource database.
  8077.   */
  8078.   XrmInitialize();
  8079.   XGetDefault(display,client_name,"dummy");
  8080.   resource_database=XrmGetDatabase(display);
  8081.   resource_value=XResourceManagerString(display);
  8082.   if (resource_value == (char *) NULL)
  8083.     resource_value="";
  8084.   server_database=XrmGetStringDatabase(resource_value);
  8085.   XrmMergeDatabases(server_database,&resource_database);
  8086.   XGetResourceInfo(resource_database,client_name,&resource_info);
  8087.   /*
  8088.     Allocate standard colormap.
  8089.   */
  8090.   map_info=XAllocStandardColormap();
  8091.   if (map_info == (XStandardColormap *) NULL)
  8092.     Warning("Unable to create standard colormap","Memory allocation failed");
  8093.   else
  8094.     {
  8095.       /*
  8096.         Initialize visual info.
  8097.       */
  8098.       visual_info=XBestVisualInfo(display,map_info,&resource_info);
  8099.       if (visual_info == (XVisualInfo *) NULL)
  8100.         Warning("Unable to get visual",resource_info.visual_type);
  8101.       map_info->colormap=(Colormap) NULL;
  8102.       pixel_info.pixels=(unsigned long *) NULL;
  8103.     }
  8104.   if ((map_info == (XStandardColormap *) NULL) ||
  8105.       (visual_info == (XVisualInfo *) NULL))
  8106.     {
  8107.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8108.         (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8109.       DestroyImage(image);
  8110.       return((Image *) NULL);
  8111.     }
  8112.   /*
  8113.     Determine image color-- specified by the filename.
  8114.   */
  8115.   if (*image_info->filename != '\0')
  8116.     resource_info.background_color=image_info->filename;
  8117.   XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen),
  8118.     map_info);
  8119.   XGetPixelInfo(display,visual_info,map_info,&resource_info,(Image *) NULL,
  8120.     &pixel_info);
  8121.   pixel_info.annotate_context=XDefaultGC(display,visual_info->screen);
  8122.   /*
  8123.     Determine width and height, e.g. 640x512.
  8124.   */
  8125.   width=512;
  8126.   height=512;
  8127.   (void) strcpy(image->filename,image_info->filename);
  8128.   if (image_info->geometry != (char *) NULL)
  8129.     (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  8130.   /*
  8131.     Initialize Image structure.
  8132.   */
  8133.   image->columns=width;
  8134.   image->rows=height;
  8135.   image->packets=image->columns*image->rows;
  8136.   image->pixels=(RunlengthPacket *)
  8137.     malloc(image->packets*sizeof(RunlengthPacket));
  8138.   image->class=PseudoClass;
  8139.   image->colors=1;
  8140.   image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  8141.   if ((image->pixels == (RunlengthPacket *) NULL) ||
  8142.       (image->colormap == (ColorPacket *) NULL))
  8143.     {
  8144.       Warning("Unable to allocate image","Memory allocation error");
  8145.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8146.         (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8147.       DestroyImage(image);
  8148.       return((Image *) NULL);
  8149.     }
  8150.   /*
  8151.     Initialize colormap.
  8152.   */
  8153.   image->colormap[0].red=pixel_info.background_color.red >> 8;
  8154.   image->colormap[0].green=pixel_info.background_color.green >> 8;
  8155.   image->colormap[0].blue=pixel_info.background_color.blue >> 8;
  8156.   q=image->pixels;
  8157.   for (i=0; i < image->packets; i++)
  8158.   {
  8159.     q->index=0;
  8160.     q->length=0;
  8161.     q++;
  8162.   }
  8163.   SyncImage(image);
  8164.   /*
  8165.     Free resources.
  8166.   */
  8167.   XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8168.     (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8169.   return(image);
  8170. }
  8171.  
  8172. /*
  8173. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8174. %                                                                             %
  8175. %                                                                             %
  8176. %                                                                             %
  8177. %  R e a d X P M I m a g e                                                    %
  8178. %                                                                             %
  8179. %                                                                             %
  8180. %                                                                             %
  8181. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8182. %
  8183. %  Function ReadXBMImage reads an X11 pixmap image file and returns it.  It
  8184. %  allocates the memory necessary for the new Image structure and returns a
  8185. %  pointer to the new image.
  8186. %
  8187. %  The format of the ReadXPMImage routine is:
  8188. %
  8189. %      image=ReadXPMImage(image_info)
  8190. %
  8191. %  A description of each parameter follows:
  8192. %
  8193. %    o image:  Function ReadXPMImage returns a pointer to the image after
  8194. %      creating it. A null image is returned if there is a a memory shortage
  8195. %      or if the image cannot be read.
  8196. %
  8197. %    o image_info: Specifies a pointer to an ImageInfo structure.
  8198. %
  8199. %
  8200. */
  8201. #ifdef HasXPM
  8202. #include "xpm.h"
  8203. static Image *ReadXPMImage(image_info)
  8204. ImageInfo
  8205.   *image_info;
  8206. {
  8207.   char
  8208.     *resource_value,
  8209.     *xpm_buffer;
  8210.  
  8211.   Display
  8212.     *display;
  8213.  
  8214.   Image
  8215.     *image;
  8216.  
  8217.   int
  8218.     length,
  8219.     status,
  8220.     x,
  8221.     y;
  8222.  
  8223.   register char
  8224.     *q;
  8225.  
  8226.   register int
  8227.     i;
  8228.  
  8229.   register RunlengthPacket
  8230.     *p;
  8231.  
  8232.   register unsigned long
  8233.     pixel;
  8234.  
  8235.   XColor
  8236.     *colors;
  8237.  
  8238.   XImage
  8239.     *mask_image,
  8240.     *ximage;
  8241.  
  8242.   XpmAttributes
  8243.     xpm_attributes;
  8244.  
  8245.   XResourceInfo
  8246.     resource_info;
  8247.  
  8248.   XrmDatabase
  8249.     resource_database,
  8250.     server_database;
  8251.  
  8252.   XStandardColormap
  8253.     *map_info;
  8254.  
  8255.   XVisualInfo
  8256.     *visual_info;
  8257.  
  8258.   /*
  8259.     Allocate image structure.
  8260.   */
  8261.   image=AllocateImage(image_info);
  8262.   if (image == (Image *) NULL)
  8263.     return((Image *) NULL);
  8264.   /*
  8265.     Open image file.
  8266.   */
  8267.   OpenImage(image,"r");
  8268.   if (image->file == (FILE *) NULL)
  8269.     {
  8270.       Warning("Unable to open file",image->filename);
  8271.       DestroyImage(image);
  8272.       return((Image *) NULL);
  8273.     }
  8274.   /*
  8275.     Read XPM file.
  8276.   */
  8277.   length=MaxTextLength;
  8278.   xpm_buffer=(char *) malloc(length*sizeof(char));
  8279.   if (xpm_buffer != (char *) NULL)
  8280.     {
  8281.       q=xpm_buffer;
  8282.       while (fgets(q,MaxTextLength,image->file) != (char *) NULL)
  8283.       {
  8284.         q+=strlen(q);
  8285.         if ((q-xpm_buffer+MaxTextLength) > length)
  8286.           {
  8287.             length<<=1;
  8288.             xpm_buffer=(char *)
  8289.               realloc((char *) xpm_buffer,length*sizeof(char));
  8290.             if (xpm_buffer == (char *) NULL)
  8291.               break;
  8292.             q=xpm_buffer+strlen(xpm_buffer);
  8293.           }
  8294.       }
  8295.     }
  8296.   if (xpm_buffer == (char *) NULL)
  8297.     {
  8298.       Warning("Unable to read XPM image","Memory allocation failed");
  8299.       DestroyImage(image);
  8300.       return((Image *) NULL);
  8301.     }
  8302.   CloseImage(image);
  8303.   /*
  8304.     Open X server connection.
  8305.   */
  8306.   display=XOpenDisplay(image_info->server_name);
  8307.   if (display == (Display *) NULL)
  8308.     {
  8309.       Warning("Unable to connect to X server",
  8310.         XDisplayName(image_info->server_name));
  8311.       DestroyImage(image);
  8312.       return((Image *) NULL);
  8313.     }
  8314.   /*
  8315.     Set our forgiving error handler.
  8316.   */
  8317.   XSetErrorHandler(XError);
  8318.   /*
  8319.     Get user defaults from X resource database.
  8320.   */
  8321.   XrmInitialize();
  8322.   XGetDefault(display,client_name,"dummy");
  8323.   resource_database=XrmGetDatabase(display);
  8324.   resource_value=XResourceManagerString(display);
  8325.   if (resource_value == (char *) NULL)
  8326.     resource_value="";
  8327.   server_database=XrmGetStringDatabase(resource_value);
  8328.   XrmMergeDatabases(server_database,&resource_database);
  8329.   XGetResourceInfo(resource_database,client_name,&resource_info);
  8330.   /*
  8331.     Allocate standard colormap.
  8332.   */
  8333.   map_info=XAllocStandardColormap();
  8334.   if (map_info == (XStandardColormap *) NULL)
  8335.     Warning("Unable to create standard colormap","Memory allocation failed");
  8336.   else
  8337.     {
  8338.       /*
  8339.         Initialize visual info.
  8340.       */
  8341.       visual_info=XBestVisualInfo(display,map_info,&resource_info);
  8342.       if (visual_info == (XVisualInfo *) NULL)
  8343.         Warning("Unable to get visual",resource_info.visual_type);
  8344.       map_info->colormap=(Colormap) NULL;
  8345.     }
  8346.   if ((map_info == (XStandardColormap *) NULL) ||
  8347.       (visual_info == (XVisualInfo *) NULL))
  8348.     {
  8349.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8350.         (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8351.       DestroyImage(image);
  8352.       return((Image *) NULL);
  8353.     }
  8354.   /*
  8355.     Initialize X colormap.
  8356.   */
  8357.   map_info->colormap=XCreateColormap(display,
  8358.     XRootWindow(display,visual_info->screen),visual_info->visual,
  8359.     visual_info->class == DirectColor ? AllocAll : AllocNone);
  8360.   if (map_info->colormap == (Colormap) NULL)
  8361.     {
  8362.       Warning("Unable to create colormap",(char *) NULL);
  8363.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8364.         (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8365.       DestroyImage(image);
  8366.       return((Image *) NULL);
  8367.     }
  8368.   /*
  8369.     Initialize XPM attributes.
  8370.   */
  8371.   xpm_attributes.valuemask=XpmColorKey | XpmColormap | XpmDepth | XpmVisual;
  8372.   xpm_attributes.visual=visual_info->visual;
  8373.   xpm_attributes.colormap=map_info->colormap;
  8374.   xpm_attributes.depth=visual_info->depth;
  8375.   xpm_attributes.color_key=XPM_COLOR;
  8376.   if (IsGrayImage(image))
  8377.     if (image->colors > 16)
  8378.       xpm_attributes.color_key=XPM_GRAY;
  8379.     else
  8380.       if (image->colors == 2)
  8381.         xpm_attributes.color_key=XPM_MONO;
  8382.       else
  8383.         xpm_attributes.color_key=XPM_GRAY4;
  8384.   /*
  8385.     Read in a file in the XPM format into a X image structure.
  8386.   */
  8387.   status=XpmCreateImageFromBuffer(display,xpm_buffer,&ximage,&mask_image,
  8388.     &xpm_attributes);
  8389.   if (status != XpmSuccess)
  8390.     {
  8391.       Warning("Unable to read XPM image",(char *) NULL);
  8392.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8393.         (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8394.       DestroyImage(image);
  8395.       return((Image *) NULL);
  8396.     }
  8397.   XpmFreeAttributes(&xpm_attributes);
  8398.   /*
  8399.     Get the colormap colors.
  8400.   */
  8401.   colors=(XColor *) malloc(visual_info->colormap_size*sizeof(XColor));
  8402.   if (colors == (XColor *) NULL)
  8403.     {
  8404.       Warning("Unable to read X colormap",(char *) NULL);
  8405.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8406.         (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8407.       XDestroyImage(ximage);
  8408.       DestroyImage(image);
  8409.       return((Image *) NULL);
  8410.     }
  8411.   if ((visual_info->class != DirectColor) && (visual_info->class != TrueColor))
  8412.     for (i=0; i < visual_info->colormap_size; i++)
  8413.     {
  8414.       colors[i].pixel=i;
  8415.       colors[i].pad=0;
  8416.     }
  8417.   else
  8418.     {
  8419.       unsigned long
  8420.         blue,
  8421.         blue_bit,
  8422.         green,
  8423.         green_bit,
  8424.         red,
  8425.         red_bit;
  8426.  
  8427.       /*
  8428.         DirectColor or TrueColor visual.
  8429.       */
  8430.       red=0;
  8431.       green=0;
  8432.       blue=0;
  8433.       red_bit=visual_info->red_mask & (~(visual_info->red_mask)+1);
  8434.       green_bit=visual_info->green_mask & (~(visual_info->green_mask)+1);
  8435.       blue_bit=visual_info->blue_mask & (~(visual_info->blue_mask)+1);
  8436.       for (i=0; i < visual_info->colormap_size; i++)
  8437.       {
  8438.         colors[i].pixel=red | green | blue;
  8439.         colors[i].pad=0;
  8440.         red+=red_bit;
  8441.         if (red > visual_info->red_mask)
  8442.           red=0;
  8443.         green+=green_bit;
  8444.         if (green > visual_info->green_mask)
  8445.           green=0;
  8446.         blue+=blue_bit;
  8447.         if (blue > visual_info->blue_mask)
  8448.           blue=0;
  8449.       }
  8450.     }
  8451.   XQueryColors(display,map_info->colormap,colors,visual_info->colormap_size);
  8452.   /*
  8453.     Convert X image to MIFF format.
  8454.   */
  8455.   if ((visual_info->class != TrueColor) && (visual_info->class != DirectColor))
  8456.     image->class=PseudoClass;
  8457.   image->columns=ximage->width;
  8458.   image->rows=ximage->height;
  8459.   image->packets=image->columns*image->rows;
  8460.   image->pixels=(RunlengthPacket *)
  8461.     malloc(image->packets*sizeof(RunlengthPacket));
  8462.   if (image->pixels == (RunlengthPacket *) NULL)
  8463.     {
  8464.       (void) free((char *) colors);
  8465.       XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8466.         (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8467.       XDestroyImage(ximage);
  8468.       DestroyImage(image);
  8469.       return((Image *) NULL);
  8470.     }
  8471.   p=image->pixels;
  8472.   switch (image->class)
  8473.   {
  8474.     case DirectClass:
  8475.     {
  8476.       register unsigned long
  8477.         color,
  8478.         index;
  8479.  
  8480.       unsigned long
  8481.         blue_mask,
  8482.         blue_shift,
  8483.         green_mask,
  8484.         green_shift,
  8485.         red_mask,
  8486.         red_shift;
  8487.  
  8488.       /*
  8489.         Determine shift and mask for red, green, and blue.
  8490.       */
  8491.       red_mask=visual_info->red_mask;
  8492.       red_shift=0;
  8493.       while ((red_mask & 0x01) == 0)
  8494.       {
  8495.         red_mask>>=1;
  8496.         red_shift++;
  8497.       }
  8498.       green_mask=visual_info->green_mask;
  8499.       green_shift=0;
  8500.       while ((green_mask & 0x01) == 0)
  8501.       {
  8502.         green_mask>>=1;
  8503.         green_shift++;
  8504.       }
  8505.       blue_mask=visual_info->blue_mask;
  8506.       blue_shift=0;
  8507.       while ((blue_mask & 0x01) == 0)
  8508.       {
  8509.         blue_mask>>=1;
  8510.         blue_shift++;
  8511.       }
  8512.       /*
  8513.         Convert X image to DirectClass packets.
  8514.       */
  8515.       if ((visual_info->colormap_size > 0) &&
  8516.           (visual_info->class == DirectColor))
  8517.         for (y=0; y < image->rows; y++)
  8518.         {
  8519.           for (x=0; x < image->columns; x++)
  8520.           {
  8521.             pixel=XGetPixel(ximage,x,y);
  8522.             index=(pixel >> red_shift) & red_mask;
  8523.             p->red=(unsigned char) (colors[index].red >> 8);
  8524.             index=(pixel >> green_shift) & green_mask;
  8525.             p->green=(unsigned char) (colors[index].green >> 8);
  8526.             index=(pixel >> blue_shift) & blue_mask;
  8527.             p->blue=(unsigned char) (colors[index].blue >> 8);
  8528.             p->index=0;
  8529.             p->length=0;
  8530.             p++;
  8531.           }
  8532.         }
  8533.       else
  8534.         for (y=0; y < image->rows; y++)
  8535.           for (x=0; x < image->columns; x++)
  8536.           {
  8537.             pixel=XGetPixel(ximage,x,y);
  8538.             color=(pixel >> red_shift) & red_mask;
  8539.             p->red=(unsigned char)
  8540.               ((((unsigned long) color*65535)/red_mask) >> 8);
  8541.             color=(pixel >> green_shift) & green_mask;
  8542.             p->green=(unsigned char)
  8543.               ((((unsigned long) color*65535)/green_mask) >> 8);
  8544.             color=(pixel >> blue_shift) & blue_mask;
  8545.             p->blue=(unsigned char)
  8546.               ((((unsigned long) color*65535)/blue_mask) >> 8);
  8547.             p->index=0;
  8548.             p->length=0;
  8549.             p++;
  8550.           }
  8551.       break;
  8552.     }
  8553.     case PseudoClass:
  8554.     {
  8555.       /*
  8556.         Create colormap.
  8557.       */
  8558.       image->colors=visual_info->colormap_size;
  8559.       image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  8560.       if (image->colormap == (ColorPacket *) NULL)
  8561.         {
  8562.           (void) free((char *) colors);
  8563.           XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8564.             (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8565.           XDestroyImage(ximage);
  8566.           DestroyImage(image);
  8567.           return((Image *) NULL);
  8568.         }
  8569.       for (i=0; i < image->colors; i++)
  8570.       {
  8571.         image->colormap[colors[i].pixel].red=colors[i].red >> 8;
  8572.         image->colormap[colors[i].pixel].green=colors[i].green >> 8;
  8573.         image->colormap[colors[i].pixel].blue=colors[i].blue >> 8;
  8574.       }
  8575.       /*
  8576.         Convert X image to PseudoClass packets.
  8577.       */
  8578.       for (y=0; y < image->rows; y++)
  8579.         for (x=0; x < image->columns; x++)
  8580.         {
  8581.           pixel=XGetPixel(ximage,x,y);
  8582.           p->index=(unsigned short) pixel;
  8583.           p->length=0;
  8584.           p++;
  8585.         }
  8586.       SyncImage(image);
  8587.       break;
  8588.     }
  8589.   }
  8590.   if (image->class == PseudoClass)
  8591.     CompressColormap(image);
  8592.   /*
  8593.     Free resources.
  8594.   */
  8595.   (void) free((char *) colors);
  8596.   XDestroyImage(ximage);
  8597.   XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL,
  8598.     (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL);
  8599.   return(image);
  8600. }
  8601. #else
  8602. static Image *ReadXPMImage(image_info)
  8603. ImageInfo
  8604.   *image_info;
  8605. {
  8606.   Warning("XPM library is not available",image_info->filename);
  8607.   return(ReadMIFFImage(image_info));
  8608. }
  8609. #endif
  8610.  
  8611. /*
  8612. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8613. %                                                                             %
  8614. %                                                                             %
  8615. %                                                                             %
  8616. %  R e a d X W D I m a g e                                                    %
  8617. %                                                                             %
  8618. %                                                                             %
  8619. %                                                                             %
  8620. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8621. %
  8622. %  Function ReadXWDImage reads an X Window System window dump image file and
  8623. %  returns it.  It allocates the memory necessary for the new Image structure
  8624. %  and returns a pointer to the new image.
  8625. %
  8626. %  The format of the ReadXWDImage routine is:
  8627. %
  8628. %      image=ReadXWDImage(image_info)
  8629. %
  8630. %  A description of each parameter follows:
  8631. %
  8632. %    o image:  Function ReadXWDImage returns a pointer to the image after
  8633. %      reading.  A null image is returned if there is a a memory shortage or
  8634. %      if the image cannot be read.
  8635. %
  8636. %    o image_info: Specifies a pointer to an ImageInfo structure.
  8637. %
  8638. %
  8639. */
  8640. static Image *ReadXWDImage(image_info)
  8641. ImageInfo
  8642.   *image_info;
  8643. {
  8644.   char
  8645.     *window_name;
  8646.  
  8647.   Display
  8648.     display;
  8649.  
  8650.   Image
  8651.     *image;
  8652.  
  8653.   int
  8654.     status,
  8655.     x,
  8656.     y;
  8657.  
  8658.   register int
  8659.     i;
  8660.  
  8661.   register RunlengthPacket
  8662.     *q;
  8663.  
  8664.   register unsigned short
  8665.     index;
  8666.  
  8667.   register unsigned long
  8668.     pixel;
  8669.  
  8670.   unsigned long
  8671.     lsb_first,
  8672.     packets;
  8673.  
  8674.   ScreenFormat
  8675.     screen_format;
  8676.  
  8677.   XColor
  8678.     *colors;
  8679.  
  8680.   XImage
  8681.     *ximage;
  8682.  
  8683.   XWDFileHeader
  8684.     header;
  8685.  
  8686.   /*
  8687.     Allocate image structure.
  8688.   */
  8689.   image=AllocateImage(image_info);
  8690.   if (image == (Image *) NULL)
  8691.     return((Image *) NULL);
  8692.   /*
  8693.     Open image file.
  8694.   */
  8695.   OpenImage(image,"r");
  8696.   if (image->file == (FILE *) NULL)
  8697.     {
  8698.       Warning("Unable to open file",image->filename);
  8699.       DestroyImage(image);
  8700.       return((Image *) NULL);
  8701.     }
  8702.   /*
  8703.      Read in header information.
  8704.   */
  8705.   status=ReadData((char *) &header,sizeof(header),1,image->file);
  8706.   if (status == False)
  8707.     {
  8708.       Warning("Unable to read dump file header",image->filename);
  8709.       DestroyImage(image);
  8710.       return((Image *) NULL);
  8711.     }
  8712.   /*
  8713.     Ensure the header byte-order is most-significant byte first.
  8714.   */
  8715.   lsb_first=1;
  8716.   if (*(char *) &lsb_first)
  8717.     MSBFirstOrderLong((char *) &header,sizeof(header));
  8718.   /*
  8719.     Check to see if the dump file is in the proper format.
  8720.   */
  8721.   if (header.file_version != XWD_FILE_VERSION)
  8722.     {
  8723.       Warning("XWD file format version mismatch",image->filename);
  8724.       DestroyImage(image);
  8725.       return((Image *) NULL);
  8726.     }
  8727.   if (header.header_size < sizeof(header))
  8728.     {
  8729.       Warning("XWD header size is too small",image->filename);
  8730.       DestroyImage(image);
  8731.       return((Image *) NULL);
  8732.     }
  8733.   packets=(header.header_size-sizeof(header));
  8734.   window_name=(char *) malloc((unsigned int) packets*sizeof(char));
  8735.   if (window_name == (char *) NULL)
  8736.     {
  8737.       Warning("Unable to allocate memory",(char *) NULL);
  8738.       DestroyImage(image);
  8739.       return((Image *) NULL);
  8740.     }
  8741.   status=ReadData((char *) window_name,1,(int) packets,image->file);
  8742.   if (status == False)
  8743.     {
  8744.       Warning("Unable to read window name from dump file",image->filename);
  8745.       DestroyImage(image);
  8746.       return((Image *) NULL);
  8747.     }
  8748.   /*
  8749.     Initialize the X image.
  8750.   */
  8751.   display.byte_order=header.byte_order;
  8752.   display.bitmap_unit=header.bitmap_unit;
  8753.   display.bitmap_bit_order=header.bitmap_bit_order;
  8754.   display.pixmap_format=(&screen_format);
  8755.   display.nformats=1;
  8756.   screen_format.depth=header.pixmap_depth;
  8757.   screen_format.bits_per_pixel=(int) header.bits_per_pixel;
  8758.   ximage=XCreateImage(&display,(Visual *) NULL,
  8759.     (unsigned int) header.pixmap_depth,(int) header.pixmap_format,
  8760.     (int) header.xoffset,(char *) NULL,(unsigned int) header.pixmap_width,
  8761.     (unsigned int) header.pixmap_height,(int) header.bitmap_pad,
  8762.     (int) header.bytes_per_line);
  8763.   ximage->red_mask=header.red_mask;
  8764.   ximage->green_mask=header.green_mask;
  8765.   ximage->blue_mask=header.blue_mask;
  8766.   /*
  8767.     Read colormap.
  8768.   */
  8769.   colors=(XColor *) NULL;
  8770.   if (header.ncolors != 0)
  8771.     {
  8772.       colors=(XColor *) malloc((unsigned int) header.ncolors*sizeof(XColor));
  8773.       if (colors == (XColor *) NULL)
  8774.         {
  8775.           Warning("Unable to allocate memory",(char *) NULL);
  8776.           DestroyImage(image);
  8777.           return((Image *) NULL);
  8778.         }
  8779.       status=ReadData((char *) colors,sizeof(XColor),(int) header.ncolors,
  8780.         image->file);
  8781.       if (status == False)
  8782.         {
  8783.           Warning("Unable to read color map from dump file",image->filename);
  8784.           DestroyImage(image);
  8785.           return((Image *) NULL);
  8786.         }
  8787.       /*
  8788.         Ensure the header byte-order is most-significant byte first.
  8789.       */
  8790.       lsb_first=1;
  8791.       if (*(char *) &lsb_first)
  8792.         for (i=0; i < header.ncolors; i++)
  8793.         {
  8794.           MSBFirstOrderLong((char *) &colors[i].pixel,sizeof(unsigned long));
  8795.           MSBFirstOrderShort((char *) &colors[i].red,3*sizeof(unsigned short));
  8796.         }
  8797.     }
  8798.   /*
  8799.     Allocate the pixel buffer.
  8800.   */
  8801.   if (ximage->format == ZPixmap)
  8802.     packets=ximage->bytes_per_line*ximage->height;
  8803.   else
  8804.     packets=ximage->bytes_per_line*ximage->height*ximage->depth;
  8805.   ximage->data=(char *) malloc(packets*sizeof(unsigned char));
  8806.   if (ximage->data == (char *) NULL)
  8807.     {
  8808.       Warning("Unable to allocate memory",(char *) NULL);
  8809.       DestroyImage(image);
  8810.       return((Image *) NULL);
  8811.     }
  8812.   status=ReadData(ximage->data,1,(int) packets,image->file);
  8813.   if (status == False)
  8814.     {
  8815.       Warning("Unable to read dump pixmap",image->filename);
  8816.       DestroyImage(image);
  8817.       return((Image *) NULL);
  8818.     }
  8819.   /*
  8820.     Convert image to MIFF format.
  8821.   */
  8822.   image->columns=ximage->width;
  8823.   image->rows=ximage->height;
  8824.   /*
  8825.     Initial image comment.
  8826.   */
  8827.   if ((ximage->red_mask > 0) || (ximage->green_mask > 0) ||
  8828.       (ximage->blue_mask > 0))
  8829.     image->class=DirectClass;
  8830.   else
  8831.     image->class=PseudoClass;
  8832.   image->colors=header.ncolors;
  8833.   image->packets=image->columns*image->rows;
  8834.   image->pixels=(RunlengthPacket *)
  8835.     malloc(image->packets*sizeof(RunlengthPacket));
  8836.   if (image->pixels == (RunlengthPacket *) NULL)
  8837.     {
  8838.       Warning("Unable to allocate memory",(char *) NULL);
  8839.       DestroyImage(image);
  8840.       return((Image *) NULL);
  8841.     }
  8842.   q=image->pixels;
  8843.   switch (image->class)
  8844.   {
  8845.     case DirectClass:
  8846.     {
  8847.       register unsigned long
  8848.         color;
  8849.  
  8850.       unsigned long
  8851.         blue_mask,
  8852.         blue_shift,
  8853.         green_mask,
  8854.         green_shift,
  8855.         red_mask,
  8856.         red_shift;
  8857.  
  8858.       /*
  8859.         Determine shift and mask for red, green, and blue.
  8860.       */
  8861.       red_mask=ximage->red_mask;
  8862.       red_shift=0;
  8863.       while ((red_mask & 0x01) == 0)
  8864.       {
  8865.         red_mask>>=1;
  8866.         red_shift++;
  8867.       }
  8868.       green_mask=ximage->green_mask;
  8869.       green_shift=0;
  8870.       while ((green_mask & 0x01) == 0)
  8871.       {
  8872.         green_mask>>=1;
  8873.         green_shift++;
  8874.       }
  8875.       blue_mask=ximage->blue_mask;
  8876.       blue_shift=0;
  8877.       while ((blue_mask & 0x01) == 0)
  8878.       {
  8879.         blue_mask>>=1;
  8880.         blue_shift++;
  8881.       }
  8882.       /*
  8883.         Convert X image to DirectClass packets.
  8884.       */
  8885.       if (image->colors != 0)
  8886.         for (y=0; y < image->rows; y++)
  8887.         {
  8888.           for (x=0; x < image->columns; x++)
  8889.           {
  8890.             pixel=XGetPixel(ximage,x,y);
  8891.             index=(unsigned short) ((pixel >> red_shift) & red_mask);
  8892.             q->red=(unsigned char) (colors[index].red >> 8);
  8893.             index=(unsigned short) ((pixel >> green_shift) & green_mask);
  8894.             q->green=(unsigned char) (colors[index].green >> 8);
  8895.             index=(unsigned short) ((pixel >> blue_shift) & blue_mask);
  8896.             q->blue=(unsigned char) (colors[index].blue >> 8);
  8897.             q->index=0;
  8898.             q->length=0;
  8899.             q++;
  8900.           }
  8901.         }
  8902.       else
  8903.         for (y=0; y < image->rows; y++)
  8904.           for (x=0; x < image->columns; x++)
  8905.           {
  8906.             pixel=XGetPixel(ximage,x,y);
  8907.             color=(pixel >> red_shift) & red_mask;
  8908.             q->red=(unsigned char)
  8909.               ((((unsigned long) color*65535)/red_mask) >> 8);
  8910.             color=(pixel >> green_shift) & green_mask;
  8911.             q->green=(unsigned char)
  8912.               ((((unsigned long) color*65535)/green_mask) >> 8);
  8913.             color=(pixel >> blue_shift) & blue_mask;
  8914.             q->blue=(unsigned char)
  8915.               ((((unsigned long) color*65535)/blue_mask) >> 8);
  8916.             q->index=0;
  8917.             q->length=0;
  8918.             q++;
  8919.           }
  8920.       break;
  8921.     }
  8922.     case PseudoClass:
  8923.     {
  8924.       /*
  8925.         Convert X image to PseudoClass packets.
  8926.       */
  8927.       image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  8928.       if (image->colormap == (ColorPacket *) NULL)
  8929.         {
  8930.           Warning("Unable to allocate memory",(char *) NULL);
  8931.           DestroyImage(image);
  8932.           return((Image *) NULL);
  8933.         }
  8934.       for (i=0; i < image->colors; i++)
  8935.       {
  8936.         image->colormap[i].red=colors[i].red >> 8;
  8937.         image->colormap[i].green=colors[i].green >> 8;
  8938.         image->colormap[i].blue=colors[i].blue >> 8;
  8939.       }
  8940.       for (y=0; y < image->rows; y++)
  8941.         for (x=0; x < image->columns; x++)
  8942.         {
  8943.           pixel=XGetPixel(ximage,x,y);
  8944.           q->red=(unsigned char) (colors[pixel].red >> 8);
  8945.           q->green=(unsigned char) (colors[pixel].green >> 8);
  8946.           q->blue=(unsigned char) (colors[pixel].blue >> 8);
  8947.           q->index=(unsigned short) pixel;
  8948.           q->length=0;
  8949.           q++;
  8950.         }
  8951.       CompressColormap(image);
  8952.       break;
  8953.     }
  8954.   }
  8955.   /*
  8956.     Free image and colormap.
  8957.   */
  8958.   (void) free((char *) window_name);
  8959.   if (header.ncolors != 0)
  8960.     (void) free((char *) colors);
  8961.   XDestroyImage(ximage);
  8962.   CloseImage(image);
  8963.   return(image);
  8964. }
  8965.  
  8966. /*
  8967. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8968. %                                                                             %
  8969. %                                                                             %
  8970. %                                                                             %
  8971. %  R e a d Y U V I m a g e                                                    %
  8972. %                                                                             %
  8973. %                                                                             %
  8974. %                                                                             %
  8975. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  8976. %
  8977. %  Function ReadYUVImage reads an image with digital YUV (CCIR 601 1:1:1) bytes
  8978. %  and returns it.  It allocates the memory necessary for the new Image
  8979. %  structure and returns a pointer to the new image.  U and V, normally -0.5
  8980. %  through 0.5, are expected to be normalized to the range 0 through MaxRGB
  8981. %  fit withing a byte.
  8982. %
  8983. %  The format of the ReadYUVImage routine is:
  8984. %
  8985. %      image=ReadYUVImage(image_info)
  8986. %
  8987. %  A description of each parameter follows:
  8988. %
  8989. %    o image:  Function ReadYUVImage returns a pointer to the image after
  8990. %      reading.  A null image is returned if there is a a memory shortage or
  8991. %      if the image cannot be read.
  8992. %
  8993. %    o image_info: Specifies a pointer to an ImageInfo structure.
  8994. %
  8995. %
  8996. */
  8997. static Image *ReadYUVImage(image_info)
  8998. ImageInfo
  8999.   *image_info;
  9000. {
  9001.   Image
  9002.     *image;
  9003.  
  9004.   int
  9005.     x,
  9006.     y;
  9007.  
  9008.   register int
  9009.     i;
  9010.  
  9011.   register RunlengthPacket
  9012.     *q;
  9013.  
  9014.   register unsigned char
  9015.     *p;
  9016.  
  9017.   unsigned char
  9018.     *yuv_pixels;
  9019.  
  9020.   unsigned int
  9021.     height,
  9022.     width;
  9023.  
  9024.   /*
  9025.     Allocate image structure.
  9026.   */
  9027.   image=AllocateImage(image_info);
  9028.   if (image == (Image *) NULL)
  9029.     return((Image *) NULL);
  9030.   /*
  9031.     Open image file.
  9032.   */
  9033.   OpenImage(image,"r");
  9034.   if (image->file == (FILE *) NULL)
  9035.     {
  9036.       Warning("Unable to open file",image->filename);
  9037.       DestroyImage(image);
  9038.       return((Image *) NULL);
  9039.     }
  9040.   /*
  9041.     Determine width and height, e.g. 640x512.
  9042.   */
  9043.   width=512;
  9044.   height=512;
  9045.   if (image_info->geometry != (char *) NULL)
  9046.     (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  9047.   /*
  9048.     Initialize image structure.
  9049.   */
  9050.   image->columns=width;
  9051.   image->rows=height;
  9052.   image->packets=image->columns*image->rows;
  9053.   yuv_pixels=(unsigned char *) malloc(3*image->packets*sizeof(unsigned char));
  9054.   image->pixels=(RunlengthPacket *)
  9055.     malloc(image->packets*sizeof(RunlengthPacket));
  9056.   if ((yuv_pixels == (unsigned char *) NULL) ||
  9057.       (image->pixels == (RunlengthPacket *) NULL))
  9058.     {
  9059.       Warning("Memory allocation error",(char *) NULL);
  9060.       DestroyImage(image);
  9061.       return((Image *) NULL);
  9062.     }
  9063.   /*
  9064.     Convert raster image to runlength-encoded packets.
  9065.   */
  9066.   (void) ReadData((char *) yuv_pixels,3,(int) image->packets,image->file);
  9067.   p=yuv_pixels;
  9068.   switch (image_info->interlace)
  9069.   {
  9070.     case NoneInterlace:
  9071.     default:
  9072.     {
  9073.       /*
  9074.         No interlacing:  YUVYUVYUVYUVYUVYUV...
  9075.       */
  9076.       q=image->pixels;
  9077.       for (i=0; i < image->packets; i++)
  9078.       {
  9079.         q->red=(*p++);
  9080.         q->green=(*p++);
  9081.         q->blue=(*p++);
  9082.         q->index=0;
  9083.         q->length=0;
  9084.         q++;
  9085.       }
  9086.       break;
  9087.     }
  9088.     case LineInterlace:
  9089.     {
  9090.       /*
  9091.         Line interlacing:  YYY...UUU...VVV...YYY...UUU...VVV...
  9092.       */
  9093.       for (y=0; y < image->rows; y++)
  9094.       {
  9095.         q=image->pixels+y*image->columns;
  9096.         for (x=0; x < image->columns; x++)
  9097.         {
  9098.           q->red=(*p++);
  9099.           q->index=0;
  9100.           q->length=0;
  9101.           q++;
  9102.         }
  9103.         q=image->pixels+y*image->columns;
  9104.         for (x=0; x < image->columns; x++)
  9105.         {
  9106.           q->green=(*p++);
  9107.           q++;
  9108.         }
  9109.         q=image->pixels+y*image->columns;
  9110.         for (x=0; x < image->columns; x++)
  9111.         {
  9112.           q->blue=(*p++);
  9113.           q++;
  9114.         }
  9115.       }
  9116.       break;
  9117.     }
  9118.     case PlaneInterlace:
  9119.     {
  9120.       /*
  9121.         Plane interlacing:  YYYYYY...UUUUUU...VVVVVV...
  9122.       */
  9123.       q=image->pixels;
  9124.       for (i=0; i < image->packets; i++)
  9125.       {
  9126.         q->red=(*p++);
  9127.         q->index=0;
  9128.         q->length=0;
  9129.         q++;
  9130.       }
  9131.       q=image->pixels;
  9132.       for (i=0; i < image->packets; i++)
  9133.       {
  9134.         q->green=(*p++);
  9135.         q++;
  9136.       }
  9137.       q=image->pixels;
  9138.       for (i=0; i < image->packets; i++)
  9139.       {
  9140.         q->blue=(*p++);
  9141.         q++;
  9142.       }
  9143.       break;
  9144.     }
  9145.   }
  9146.   (void) free((char *) yuv_pixels);
  9147.   TransformRGBImage(image,YCbCrColorspace);
  9148.   CloseImage(image);
  9149.   return(image);
  9150. }
  9151.  
  9152. /*
  9153. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9154. %                                                                             %
  9155. %                                                                             %
  9156. %                                                                             %
  9157. %  R e a d Y U V 3 I m a g e                                                  %
  9158. %                                                                             %
  9159. %                                                                             %
  9160. %                                                                             %
  9161. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9162. %
  9163. %  Function ReadYUV3Image reads an image with digital YUV (CCIR 601 2:1:1)
  9164. %  bytes and returns it.  It allocates the memory necessary for the new Image
  9165. %  structure and returns a pointer to the new image.  U and V, normally -0.5
  9166. %  through 0.5, are expected to be normalized to the range 0 through MaxRGB
  9167. %  fit withing a byte.
  9168. %
  9169. %  The format of the ReadYUV3Image routine is:
  9170. %
  9171. %      image=ReadYUV3Image(image_info)
  9172. %
  9173. %  A description of each parameter follows:
  9174. %
  9175. %    o image:  Function ReadYUV3Image returns a pointer to the image after
  9176. %      reading.  A null image is returned if there is a a memory shortage or
  9177. %      if the image cannot be read.
  9178. %
  9179. %    o image_info: Specifies a pointer to an ImageInfo structure.
  9180. %
  9181. %
  9182. */
  9183. static Image *ReadYUV3Image(image_info)
  9184. ImageInfo
  9185.   *image_info;
  9186. {
  9187.   char
  9188.     filename[MaxTextLength];
  9189.  
  9190.   Image
  9191.     *image,
  9192.     *scaled_image;
  9193.  
  9194.   int
  9195.     x,
  9196.     y;
  9197.  
  9198.   register int
  9199.     i;
  9200.  
  9201.   register RunlengthPacket
  9202.     *q;
  9203.  
  9204.   register unsigned char
  9205.     *p;
  9206.  
  9207.   unsigned char
  9208.     *uv_pixels,
  9209.     *y_pixels;
  9210.  
  9211.   unsigned int
  9212.     height,
  9213.     width;
  9214.  
  9215.   /*
  9216.     Allocate image structure.
  9217.   */
  9218.   scaled_image=AllocateImage(image_info);
  9219.   if (scaled_image == (Image *) NULL)
  9220.     return((Image *) NULL);
  9221.   /*
  9222.     Open image file.
  9223.   */
  9224.   (void) strcpy(filename,image_info->filename);
  9225.   (void) strcpy(scaled_image->filename,filename);
  9226.   if (strcmp(scaled_image->filename,"-") != 0)
  9227.     (void) strcat(scaled_image->filename,".Y");
  9228.   OpenImage(scaled_image,"r");
  9229.   if (scaled_image->file == (FILE *) NULL)
  9230.     {
  9231.       Warning("Unable to open file",scaled_image->filename);
  9232.       DestroyImage(scaled_image);
  9233.       return((Image *) NULL);
  9234.     }
  9235.   /*
  9236.     Determine width and height, e.g. 640x512.
  9237.   */
  9238.   width=512;
  9239.   height=512;
  9240.   if (image_info->geometry != (char *) NULL)
  9241.     (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  9242.   /*
  9243.     Read Y channel.
  9244.   */
  9245.   scaled_image->columns=width >> 1;
  9246.   scaled_image->rows=height >> 1;
  9247.   scaled_image->packets=scaled_image->columns*scaled_image->rows;
  9248.   uv_pixels=(unsigned char *)
  9249.     malloc(scaled_image->packets*sizeof(unsigned char));
  9250.   y_pixels=(unsigned char *)
  9251.     malloc(4*scaled_image->packets*sizeof(unsigned char));
  9252.   scaled_image->pixels=(RunlengthPacket *)
  9253.     malloc(scaled_image->packets*sizeof(RunlengthPacket));
  9254.   if ((uv_pixels == (unsigned char *) NULL) ||
  9255.       (y_pixels == (unsigned char *) NULL) ||
  9256.       (scaled_image->pixels == (RunlengthPacket *) NULL))
  9257.     {
  9258.       Warning("Memory allocation error",(char *) NULL);
  9259.       DestroyImage(scaled_image);
  9260.       return((Image *) NULL);
  9261.     }
  9262.   (void) ReadData((char *) y_pixels,4,(int) scaled_image->packets,
  9263.     scaled_image->file);
  9264.   CloseImage(scaled_image);
  9265.   /*
  9266.     Read U channel.
  9267.   */
  9268.   (void) strcpy(scaled_image->filename,filename);
  9269.   if (strcmp(scaled_image->filename,"-") != 0)
  9270.     (void) strcat(scaled_image->filename,".U");
  9271.   OpenImage(scaled_image,"r");
  9272.   if (scaled_image->file == (FILE *) NULL)
  9273.     {
  9274.       Warning("Unable to open file",scaled_image->filename);
  9275.       DestroyImage(scaled_image);
  9276.       return((Image *) NULL);
  9277.     }
  9278.   (void) ReadData((char *) uv_pixels,1,(int) scaled_image->packets,
  9279.     scaled_image->file);
  9280.   p=uv_pixels;
  9281.   q=scaled_image->pixels;
  9282.   for (i=0; i < scaled_image->packets; i++)
  9283.   {
  9284.     q->green=(*p);
  9285.     q->index=0;
  9286.     q->length=0;
  9287.     p++;
  9288.     q++;
  9289.   }
  9290.   CloseImage(scaled_image);
  9291.   /*
  9292.     Read V channel.
  9293.   */
  9294.   (void) strcpy(scaled_image->filename,filename);
  9295.   if (strcmp(scaled_image->filename,"-") != 0)
  9296.     (void) strcat(scaled_image->filename,".V");
  9297.   OpenImage(scaled_image,"r");
  9298.   if (scaled_image->file == (FILE *) NULL)
  9299.     {
  9300.       Warning("Unable to open file",scaled_image->filename);
  9301.       DestroyImage(scaled_image);
  9302.       return((Image *) NULL);
  9303.     }
  9304.   (void) ReadData((char *) uv_pixels,1,(int) scaled_image->packets,
  9305.     scaled_image->file);
  9306.   p=uv_pixels;
  9307.   q=scaled_image->pixels;
  9308.   for (i=0; i < scaled_image->packets; i++)
  9309.   {
  9310.     q->blue=(*p);
  9311.     p++;
  9312.     q++;
  9313.   }
  9314.   CloseImage(scaled_image);
  9315.   (void) free((char *) uv_pixels);
  9316.   /*
  9317.     Scale image.
  9318.   */
  9319.   scaled_image->orphan=True;
  9320.   image=
  9321.     ScaleImage(scaled_image,scaled_image->columns << 1,scaled_image->rows << 1);
  9322.   DestroyImage(scaled_image);
  9323.   if (image == (Image *) NULL)
  9324.     {
  9325.       Warning("Unable to read image","Memory allocation failed");
  9326.       return((Image *) NULL);
  9327.     }
  9328.   p=y_pixels;
  9329.   q=image->pixels;
  9330.   for (i=0; i < (image->columns*image->rows); i++)
  9331.   {
  9332.     q->red=(*p);
  9333.     p++;
  9334.     q++;
  9335.   }
  9336.   (void) free((char *) y_pixels);
  9337.   TransformRGBImage(image,YCbCrColorspace);
  9338.   (void) strcpy(image->filename,filename);
  9339.   return(image);
  9340. }
  9341.  
  9342. /*
  9343. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9344. %                                                                             %
  9345. %                                                                             %
  9346. %                                                                             %
  9347. %   R e a d I m a g e                                                         %
  9348. %                                                                             %
  9349. %                                                                             %
  9350. %                                                                             %
  9351. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9352. %
  9353. %  Function ReadImage reads an image and returns it.  It allocates
  9354. %  the memory necessary for the new Image structure and returns a pointer to
  9355. %  the new image.  By default, the image format is determined by its magic
  9356. %  number. To specify a particular image format, precede the filename with an
  9357. %  explicit image format name and a colon (i.e.  ps:image) or as the filename
  9358. %  suffix  (i.e. image.ps).
  9359. %
  9360. %  The format of the ReadImage routine is:
  9361. %
  9362. %      image=ReadImage(image_info)
  9363. %
  9364. %  A description of each parameter follows:
  9365. %
  9366. %    o image: Function ReadImage returns a pointer to the image after
  9367. %      reading.  A null image is returned if there is a a memory shortage or
  9368. %      if the image cannot be read.
  9369. %
  9370. %    o image_info: Specifies a pointer to an ImageInfo structure.
  9371. %
  9372. %
  9373. */
  9374. Image *ReadImage(image_info)
  9375. ImageInfo
  9376.   *image_info;
  9377. {
  9378.   char
  9379.     magic_number[12];
  9380.  
  9381.   Image
  9382.     *image;
  9383.  
  9384.   unsigned int
  9385.     temporary_file;
  9386.  
  9387.   temporary_file=False;
  9388.   SetImageMagick(image_info);
  9389.   if (!image_info->assert)
  9390.     {
  9391.       Image
  9392.         decode_image;
  9393.  
  9394.       /*
  9395.         Determine type from image magic number.
  9396.       */
  9397.       *magic_number='\0';
  9398.       (void) strcpy(decode_image.filename,image_info->filename);
  9399.       OpenImage(&decode_image,"r");
  9400.       if (decode_image.file != (FILE *) NULL)
  9401.         if ((decode_image.file == stdin) || decode_image.pipe)
  9402.           {
  9403.             char
  9404.               *directory;
  9405.  
  9406.             FILE
  9407.               *file;
  9408.  
  9409.             int
  9410.               c;
  9411.  
  9412.             /*
  9413.               Copy standard input or pipe to temporary file.
  9414.             */
  9415.             temporary_file=True;
  9416.             directory=(char *) getenv("TMPDIR");
  9417.             if (directory == (char *) NULL)
  9418.               directory="/tmp";
  9419.             (void) sprintf(image_info->filename,"%s/magickXXXXXX",directory);
  9420.             (void) mktemp(image_info->filename);
  9421.             file=fopen(image_info->filename,"w");
  9422.             if (file == (FILE *) NULL)
  9423.               {
  9424.                 Warning("Unable to write file",image_info->filename);
  9425.                 return((Image *) NULL);
  9426.               }
  9427.             c=fgetc(decode_image.file);
  9428.             while (c != EOF)
  9429.             {
  9430.               (void) putc(c,file);
  9431.               c=fgetc(decode_image.file);
  9432.             }
  9433.             (void) fclose(file);
  9434.             CloseImage(&decode_image);
  9435.             (void) strcpy(decode_image.filename,image_info->filename);
  9436.             OpenImage(&decode_image,"r");
  9437.           }
  9438.       if (decode_image.file != (FILE *) NULL)
  9439.         {
  9440.           /*
  9441.             Read magic number.
  9442.           */
  9443.           (void) ReadData(magic_number,sizeof(char),sizeof(magic_number),
  9444.             decode_image.file);
  9445.           CloseImage(&decode_image);
  9446.         }
  9447.       /*
  9448.         Determine the image format.
  9449.       */
  9450.       if (strncmp(magic_number,"BM",2) == 0)
  9451.         (void) strcpy(image_info->magick,"BMP");
  9452.       if (strncmp(magic_number,"GIF8",4) == 0)
  9453.         (void) strcpy(image_info->magick,"GIF");
  9454.       if (strncmp(magic_number,"\001\332",2) == 0)
  9455.         (void) strcpy(image_info->magick,"IRIS");
  9456.       if (strncmp(magic_number,"\377\330\377",3) == 0)
  9457.         (void) strcpy(image_info->magick,"JPEG");
  9458.       else
  9459.         if ((strcmp(image_info->magick,"JPEG") == 0) ||
  9460.             (strcmp(image_info->magick,"JPG") == 0))
  9461.           (void) strcpy(image_info->magick,"MIFF");
  9462.       if ((unsigned char) *magic_number == 0x0a)
  9463.         (void) strcpy(image_info->magick,"PCX");
  9464.       if ((*magic_number == 'P') && isdigit(magic_number[1]))
  9465.         (void) strcpy(image_info->magick,"PNM");
  9466.       if (strncmp(magic_number,"%!",2) == 0)
  9467.         (void) strcpy(image_info->magick,"PS");
  9468.       if (strncmp(magic_number,"\131\246\152\225",4) == 0)
  9469.         (void) strcpy(image_info->magick,"SUN");
  9470.       if ((strncmp(magic_number,"\115\115",2) == 0) ||
  9471.           (strncmp(magic_number,"\111\111",2) == 0))
  9472.         (void) strcpy(image_info->magick,"TIFF");
  9473.       if (strncmp(magic_number,"\122\314",2) == 0)
  9474.         (void) strcpy(image_info->magick,"RLE");
  9475.       if ((strncmp(magic_number,"LBLSIZE",7) == 0) ||
  9476.          (strncmp(magic_number,"NJPL1I",6) == 0))
  9477.         (void) strcpy(image_info->magick,"VICAR");
  9478.       if ((unsigned char) *magic_number == 0xab)
  9479.         (void) strcpy(image_info->magick,"VIFF");
  9480.       if (strncmp(magic_number,"#define",7) == 0)
  9481.         (void) strcpy(image_info->magick,"XBM");
  9482.       if ((magic_number[1] == 0x00) && (magic_number[2] == 0x00))
  9483.         if ((magic_number[5] == 0x00) && (magic_number[6] == 0x00))
  9484.           if ((magic_number[4] == 0x07) || (magic_number[7] == 0x07))
  9485.             (void) strcpy(image_info->magick,"XWD");
  9486.     }
  9487.   /*
  9488.     Call appropriate image reader based on image type.
  9489.   */
  9490.   switch (*image_info->magick)
  9491.   {
  9492.     case 'A':
  9493.     {
  9494.       if (strcmp(image_info->magick,"ALPHA") == 0)
  9495.         image=ReadALPHAImage(image_info);
  9496.       else
  9497.         image=ReadAVSImage(image_info);
  9498.       break;
  9499.     }
  9500.     case 'B':
  9501.     {
  9502.       image=ReadBMPImage(image_info);
  9503.       break;
  9504.     }
  9505.     case 'C':
  9506.     {
  9507.       image=ReadCMYKImage(image_info);
  9508.       break;
  9509.     }
  9510.     case 'E':
  9511.     {
  9512.       image=ReadPSImage(image_info);
  9513.       break;
  9514.     }
  9515.     case 'F':
  9516.     {
  9517.       if (strcmp(image_info->magick,"FAX") == 0)
  9518.         image=ReadFAXImage(image_info);
  9519.       else
  9520.         image=ReadFITSImage(image_info);
  9521.       break;
  9522.     }
  9523.     case 'G':
  9524.     {
  9525.       if (strcmp(image_info->magick,"GIF") == 0)
  9526.         image=ReadGIFImage(image_info);
  9527.       else
  9528.         if (strcmp(image_info->magick,"GIF87") == 0)
  9529.           image=ReadGIFImage(image_info);
  9530.         else
  9531.           if (strcmp(image_info->magick,"GRAY") == 0)
  9532.             image=ReadGRAYImage(image_info);
  9533.           else
  9534.             image=ReadFAXImage(image_info);
  9535.       break;
  9536.     }
  9537.     case 'H':
  9538.     {
  9539.       image=ReadHISTOGRAMImage(image_info);
  9540.       break;
  9541.     }
  9542.     case 'I':
  9543.     {
  9544.       image=ReadIRISImage(image_info);
  9545.       break;
  9546.     }
  9547.     case 'J':
  9548.     {
  9549.       image=ReadJPEGImage(image_info);
  9550.       break;
  9551.     }
  9552.     case 'M':
  9553.     {
  9554.       if (strcmp(image_info->magick,"MAP") == 0)
  9555.         image=ReadMAPImage(image_info);
  9556.       else
  9557.         if (strcmp(image_info->magick,"MIFF") == 0)
  9558.           image=ReadMIFFImage(image_info);
  9559.         else
  9560.           image=ReadMTVImage(image_info);
  9561.       break;
  9562.     }
  9563.     case 'P':
  9564.     {
  9565.       if (strcmp(image_info->magick,"PCD") == 0)
  9566.         image=ReadPCDImage(image_info);
  9567.       else
  9568.         if (strcmp(image_info->magick,"PCX") == 0)
  9569.           image=ReadPCXImage(image_info);
  9570.         else
  9571.           if (strcmp(image_info->magick,"PICT") == 0)
  9572.             image=ReadPICTImage(image_info);
  9573.           else
  9574.             if (strcmp(image_info->magick,"PM") == 0)
  9575.               image=ReadXPMImage(image_info);
  9576.             else
  9577.               if ((strcmp(image_info->magick,"PS") == 0) ||
  9578.                   (strcmp(image_info->magick,"PS2") == 0))
  9579.                 image=ReadPSImage(image_info);
  9580.               else
  9581.                 image=ReadPNMImage(image_info);
  9582.       break;
  9583.     }
  9584.     case 'R':
  9585.     {
  9586.       if (strcmp(image_info->magick,"RAS") == 0)
  9587.         image=ReadSUNImage(image_info);
  9588.       else
  9589.         if (strcmp(image_info->magick,"RGB") == 0)
  9590.           image=ReadRGBImage(image_info);
  9591.         else
  9592.           image=ReadRLEImage(image_info);
  9593.       break;
  9594.     }
  9595.     case 'S':
  9596.     {
  9597.       image=ReadSUNImage(image_info);
  9598.       break;
  9599.     }
  9600.     case 'T':
  9601.     {
  9602.       if (strcmp(image_info->magick,"TGA") == 0)
  9603.         image=ReadTARGAImage(image_info);
  9604.       else
  9605.         if ((strcmp(image_info->magick,"TIF") == 0) ||
  9606.             (strcmp(image_info->magick,"TIFF") == 0))
  9607.           image=ReadTIFFImage(image_info);
  9608.         else
  9609.           image=ReadTEXTImage(image_info);
  9610.       break;
  9611.     }
  9612.     case 'V':
  9613.     {
  9614.       if (strcmp(image_info->magick,"VICAR") == 0)
  9615.         image=ReadVICARImage(image_info);
  9616.       else
  9617.         image=ReadVIFFImage(image_info);
  9618.       break;
  9619.     }
  9620.     case 'X':
  9621.     {
  9622.       if (strcmp(image_info->magick,"X") == 0)
  9623.         image=ReadXImage(image_info,False,False,False,False);
  9624.       else
  9625.         if (strcmp(image_info->magick,"XC") == 0)
  9626.           image=ReadXCImage(image_info);
  9627.         else
  9628.           if (strcmp(image_info->magick,"XBM") == 0)
  9629.             image=ReadXBMImage(image_info);
  9630.           else
  9631.             if (strcmp(image_info->magick,"XPM") == 0)
  9632.               image=ReadXPMImage(image_info);
  9633.             else
  9634.               if (strcmp(image_info->magick,"XV") == 0)
  9635.                 image=ReadVIFFImage(image_info);
  9636.               else
  9637.                 image=ReadXWDImage(image_info);
  9638.       break;
  9639.     }
  9640.     case 'Y':
  9641.     {
  9642.       if (strcmp(image_info->magick,"YUV") == 0)
  9643.         image=ReadYUVImage(image_info);
  9644.       else
  9645.         image=ReadYUV3Image(image_info);
  9646.       break;
  9647.     }
  9648.     default:
  9649.       image=ReadMIFFImage(image_info);
  9650.   }
  9651.   if (temporary_file)
  9652.     (void) unlink(image_info->filename);
  9653.   if (image != (Image *) NULL)
  9654.     {
  9655.       if (image->status)
  9656.         {
  9657.           Warning("An error has occurred reading from file",image->filename);
  9658.           DestroyImages(image);
  9659.           return((Image *) NULL);
  9660.         }
  9661.       if (image->comments == (char *) NULL)
  9662.         CommentImage(image,"  Imported from %m image: %f");
  9663.     }
  9664.   return(image);
  9665. }
  9666.