home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / imagemgc / part15 < prev    next >
Encoding:
Text File  |  1993-07-13  |  50.7 KB  |  1,781 lines

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i071:  imagemagic - X11 image processing and display, Part15/38
  4. Message-ID: <1993Jul14.175636.1590@sparky.sterling.com>
  5. X-Md4-Signature: 95be9b04ae1904e443773ec9f7130273
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 17:56:36 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 71
  13. Archive-name: imagemagic/part15
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.15 (part 15 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/decode.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 15; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping ImageMagick/decode.c'
  36. else
  37. echo 'x - continuing file ImageMagick/decode.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/decode.c' &&
  39. X              if (strcmp(value,"QEncoded") == 0)
  40. X                image->compression=QEncodedCompression;
  41. X              else
  42. X                if (strcmp(value,"RunlengthEncoded") == 0)
  43. X                  image->compression=RunlengthEncodedCompression;
  44. X                else
  45. X                  image->compression=UndefinedCompression;
  46. X            if (strcmp(keyword,"columns") == 0)
  47. X              image->columns=(unsigned int) atoi(value);
  48. X            if (strcmp(keyword,"id") == 0)
  49. X              if (strcmp(value,"ImageMagick") == 0)
  50. X                image->id=ImageMagickId;
  51. X              else
  52. X                image->id=UndefinedId;
  53. X            if (strcmp(keyword,"montage") == 0)
  54. X              {
  55. X                image->montage=(char *) malloc(strlen(value)+1*sizeof(char));
  56. X                if (image->montage == (char *) NULL)
  57. X                  {
  58. X                    Warning("unable to read image","memory allocation failed");
  59. X                    DestroyImages(image);
  60. X                    return((Image *) NULL);
  61. X                  }
  62. X                (void) strcpy(image->montage,value);
  63. X              }
  64. X            if (strcmp(keyword,"packets") == 0)
  65. X              image->packets=(unsigned int) atoi(value);
  66. X            if (strcmp(keyword,"rows") == 0)
  67. X              image->rows=(unsigned int) atoi(value);
  68. X            if (strcmp(keyword,"scene") == 0)
  69. X              image->scene=(unsigned int) atoi(value);
  70. X            if (strcmp(keyword,"signature") == 0)
  71. X              {
  72. X                image->signature=(char *)
  73. X                  malloc((strlen(value)+1)*sizeof(char));
  74. X                if (image->signature == (char *) NULL)
  75. X                  {
  76. X                    Warning("unable to read image","memory allocation failed");
  77. X                    DestroyImages(image);
  78. X                    return((Image *) NULL);
  79. X                  }
  80. X                (void) strcpy(image->signature,value);
  81. X              }
  82. X          }
  83. X        else
  84. X          c=fgetc(image->file);
  85. X      while (isspace(c))
  86. X        c=fgetc(image->file);
  87. X    }
  88. X    (void) fgetc(image->file);
  89. X    /*
  90. X      Verify that required image information is defined.
  91. X    */
  92. X    if ((image->id == UndefinedId) || (image->class == UndefinedClass) ||
  93. X        (image->compression == UndefinedCompression) || (image->columns == 0) ||
  94. X        (image->rows == 0))
  95. X      {
  96. X        Warning("incorrect image header in file",image->filename);
  97. X        DestroyImages(image);
  98. X        return((Image *) NULL);
  99. X      }
  100. X    if ((image->columns*image->rows) > MaxImageSize)
  101. X      {
  102. X        Warning("unable to read image","image size too large");
  103. X        DestroyImages(image);
  104. X        return((Image *) NULL);
  105. X      }
  106. X    if (image->montage != (char *) NULL)
  107. X      {
  108. X        register char
  109. X          *p;
  110. X
  111. X        /*
  112. X          Image directory.
  113. X        */
  114. X        max_characters=2048;
  115. X        image->directory=(char *) malloc(max_characters*sizeof(char));
  116. X        if (image->directory == (char *) NULL)
  117. X          {
  118. X            Warning("unable to read image","memory allocation failed");
  119. X            DestroyImages(image);
  120. X            return((Image *) NULL);
  121. X          }
  122. X        p=image->directory;
  123. X        do
  124. X        {
  125. X          if (p >= (image->directory+max_characters-1))
  126. X            {
  127. X              /*
  128. X                Allocate more memory for the image directory.
  129. X              */
  130. X              max_characters<<=1;
  131. X              image->directory=(char *)
  132. X                realloc((char *) image->directory,max_characters);
  133. X              if (image->directory == (char *) NULL)
  134. X                {
  135. X                  Warning("unable to read image","memory allocation failed");
  136. X                  DestroyImages(image);
  137. X                  return((Image *) NULL);
  138. X                }
  139. X              p=image->directory+strlen(image->directory);
  140. X            }
  141. X          c=fgetc(image->file);
  142. X          *p++=(unsigned char) c;
  143. X        } while (c != '\0');
  144. X      }
  145. X    if (image->class == PseudoClass)
  146. X      {
  147. X        unsigned int
  148. X          colors;
  149. X
  150. X        /*
  151. X          PseudoClass image cannot have alpha data or be QEncoded.
  152. X        */
  153. X        if (image->alpha)
  154. X          {
  155. X            Warning("unable to read image","alpha images must be DirectClass");
  156. X            DestroyImages(image);
  157. X            return((Image *) NULL);
  158. X          }
  159. X        if (image->compression == QEncodedCompression)
  160. X          {
  161. X            Warning("unable to read image",
  162. X              "QEncoded images must be DirectClass");
  163. X            DestroyImages(image);
  164. X            return((Image *) NULL);
  165. X          }
  166. X        /*
  167. X          Create image colormap.
  168. X        */
  169. X        colors=image->colors;
  170. X        if (colors == 0)
  171. X          colors=256;
  172. X        image->colormap=(ColorPacket *) malloc(colors*sizeof(ColorPacket));
  173. X        if (image->colormap == (ColorPacket *) NULL)
  174. X          {
  175. X            Warning("unable to read image","memory allocation failed");
  176. X            DestroyImages(image);
  177. X            return((Image *) NULL);
  178. X          }
  179. X        if (image->colors == 0)
  180. X          for (i=0; i < colors; i++)
  181. X          {
  182. X            image->colormap[i].red=(unsigned char) i;
  183. X            image->colormap[i].green=(unsigned char) i;
  184. X            image->colormap[i].blue=(unsigned char) i;
  185. X            image->colors++;
  186. X          }
  187. X        else
  188. X          {
  189. X            unsigned char
  190. X              *colormap;
  191. X
  192. X            /*
  193. X              Read image colormap from file.
  194. X            */
  195. X            colormap=(unsigned char *)
  196. X              malloc(3*image->colors*sizeof(unsigned char));
  197. X            if (colormap == (unsigned char *) NULL)
  198. X              {
  199. X                Warning("unable to read image","memory allocation failed");
  200. X                DestroyImages(image);
  201. X                return((Image *) NULL);
  202. X              }
  203. X            (void) ReadData((char *) colormap,1,(int) (3*image->colors),
  204. X              image->file);
  205. X            p=colormap;
  206. X            for (i=0; i < image->colors; i++)
  207. X            {
  208. X              image->colormap[i].red=(*p++);
  209. X              image->colormap[i].green=(*p++);
  210. X              image->colormap[i].blue=(*p++);
  211. X            }
  212. X            (void) free((char *) colormap);
  213. X          }
  214. X      }
  215. X    /*
  216. X      Determine packed packet size.
  217. X    */
  218. X    if (image->class == PseudoClass)
  219. X      {
  220. X        image->packet_size=1;
  221. X        if (image->colors > 256)
  222. X          image->packet_size++;
  223. X      }
  224. X    else
  225. X      {
  226. X        image->packet_size=3;
  227. X        if (image->alpha)
  228. X          image->packet_size++;
  229. X      }
  230. X    if (image->compression == RunlengthEncodedCompression)
  231. X      image->packet_size++;
  232. X    packet_size=image->packet_size;
  233. X    if (image->compression == QEncodedCompression)
  234. X      packet_size=1;
  235. X    /*
  236. X      Allocate image pixels.
  237. X    */
  238. X    if (image->compression == NoCompression)
  239. X      image->packets=image->columns*image->rows;
  240. X    packets=image->packets;
  241. X    if (image->packets == 0)
  242. X      packets=image->columns*image->rows;
  243. X    image->packed_pixels=(unsigned char *)
  244. X      malloc((unsigned int) packets*packet_size*sizeof(unsigned char));
  245. X    if (image->packed_pixels == (unsigned char *) NULL)
  246. X      {
  247. X        Warning("unable to read image","memory allocation failed");
  248. X        DestroyImages(image);
  249. X        return((Image *) NULL);
  250. X      }
  251. X    /*
  252. X      Read image pixels from file.
  253. X    */
  254. X    if ((image->compression != RunlengthEncodedCompression) ||
  255. X        (image->packets != 0))
  256. X      (void) ReadData((char *) image->packed_pixels,1,
  257. X        (int) (packets*packet_size),image->file);
  258. X    else
  259. X      {
  260. X        /*
  261. X          Number of runlength packets is unspecified.
  262. X        */
  263. X        count=0;
  264. X        p=image->packed_pixels;
  265. X        do
  266. X        {
  267. X          (void) ReadData((char *) p,1,(int) packet_size,image->file);
  268. X          image->packets++;
  269. X          p+=(packet_size-1);
  270. X          count+=(*p+1);
  271. X          p++;
  272. X        }
  273. X        while (count < (image->columns*image->rows));
  274. X      }
  275. X    if (image->compression ==  QEncodedCompression)
  276. X      {
  277. X        unsigned char
  278. X          *compressed_pixels;
  279. X
  280. X        /*
  281. X          Uncompress image pixels with Q encoding.
  282. X        */
  283. X        image->packets=image->columns*image->rows;
  284. X        compressed_pixels=image->packed_pixels;
  285. X        image->packed_pixels=(unsigned char *) malloc((unsigned int)
  286. X          image->packets*image->packet_size*sizeof(unsigned char));
  287. X        if (image->packed_pixels == (unsigned char *) NULL)
  288. X          {
  289. X            Warning("unable to write image","memory allocation failed");
  290. X            DestroyImage(image);
  291. X            return(False);
  292. X          }
  293. X        packets=QDecodeImage(compressed_pixels,image->packed_pixels,
  294. X          image->columns*(int) image->packet_size,image->rows);
  295. X        if (packets != (image->packets*image->packet_size))
  296. X          {
  297. X            Warning("Q encoding failed",image->filename);
  298. X            DestroyImages(image);
  299. X            return((Image *) NULL);
  300. X          }
  301. X        (void) free((char *) compressed_pixels);
  302. X      }
  303. X    /*
  304. X      Unpack the packed image pixels into runlength-encoded pixel packets.
  305. X    */
  306. X    status=RunlengthDecodeImage(image);
  307. X    if (status == False)
  308. X      {
  309. X        DestroyImages(image);
  310. X        return((Image *) NULL);
  311. X      }
  312. X    /*
  313. X      Proceed to next image.
  314. X    */
  315. X    do
  316. X    {
  317. X      c=fgetc(image->file);
  318. X    } while (!isgraph(c) && (c != EOF));
  319. X    if (c != EOF)
  320. X      {
  321. X        /*
  322. X          Allocate image structure.
  323. X        */
  324. X        image->next=AllocateImage("MIFF");
  325. X        if (image->next == (Image *) NULL)
  326. X          {
  327. X            DestroyImages(image);
  328. X            return((Image *) NULL);
  329. X          }
  330. X        image->next->file=image->file;
  331. X        (void) sprintf(image->next->filename,"%s.%u",image_info->filename,
  332. X          image->scene+1);
  333. X        image->next->scene=image->scene+1;
  334. X        image->next->previous=image;
  335. X        image=image->next;
  336. X      }
  337. X  } while (c != EOF);
  338. X  while (image->previous != (Image *) NULL)
  339. X    image=image->previous;
  340. X  CloseImage(image);
  341. X  return(image);
  342. }
  343. X
  344. /*
  345. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  346. %                                                                             %
  347. %                                                                             %
  348. %                                                                             %
  349. %  R e a d M T V I m a g e                                                    %
  350. %                                                                             %
  351. %                                                                             %
  352. %                                                                             %
  353. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  354. %
  355. %  Function ReadMTVImage reads a MTV image file and returns it.  It allocates
  356. %  the memory necessary for the new Image structure and returns a pointer to
  357. %  the new image.
  358. %
  359. %  The format of the ReadMTVImage routine is:
  360. %
  361. %      image=ReadMTVImage(image_info)
  362. %
  363. %  A description of each parameter follows:
  364. %
  365. %    o image:  Function ReadMTVImage returns a pointer to the image after
  366. %      reading.  A null image is returned if there is a a memory shortage or
  367. %      if the image cannot be read.
  368. %
  369. %    o image_info: Specifies a pointer to an ImageInfo structure.
  370. %
  371. %
  372. */
  373. static Image *ReadMTVImage(image_info)
  374. ImageInfo
  375. X  *image_info;
  376. {
  377. X  Image
  378. X    *image;
  379. X
  380. X  int
  381. X    count;
  382. X
  383. X  register int
  384. X    i;
  385. X
  386. X  register RunlengthPacket
  387. X    *q;
  388. X
  389. X  register unsigned char
  390. X    *p;
  391. X
  392. X  unsigned char
  393. X    *mtv_pixels;
  394. X
  395. X  unsigned int
  396. X    columns,
  397. X    rows;
  398. X
  399. X  /*
  400. X    Allocate image structure.
  401. X  */
  402. X  image=AllocateImage("MTV");
  403. X  if (image == (Image *) NULL)
  404. X    return((Image *) NULL);
  405. X  /*
  406. X    Open image file.
  407. X  */
  408. X  (void) strcpy(image->filename,image_info->filename);
  409. X  OpenImage(image,"r");
  410. X  if (image->file == (FILE *) NULL)
  411. X    {
  412. X      Warning("unable to open file",image->filename);
  413. X      DestroyImage(image);
  414. X      return((Image *) NULL);
  415. X    }
  416. X  /*
  417. X    Read MTV image.
  418. X  */
  419. X  count=fscanf(image->file,"%u %u\n",&columns,&rows);
  420. X  if (count == 0)
  421. X    {
  422. X      Warning("not a MTV image,",image->filename);
  423. X      DestroyImage(image);
  424. X      return((Image *) NULL);
  425. X    }
  426. X  do
  427. X  {
  428. X    /*
  429. X      Allocate image pixels.
  430. X    */
  431. X    mtv_pixels=(unsigned char *) malloc(3*columns*rows*sizeof(unsigned char));
  432. X    if (mtv_pixels == (unsigned char *) NULL)
  433. X      {
  434. X        Warning("memory allocation error",(char *) NULL);
  435. X        DestroyImages(image);
  436. X        return((Image *) NULL);
  437. X      }
  438. X    /*
  439. X      Read image pixels.
  440. X    */
  441. X    (void) ReadData((char *) mtv_pixels,1,(int) (columns*rows*3),image->file);
  442. X    /*
  443. X      Create image.
  444. X    */
  445. X    image->columns=columns;
  446. X    image->rows=rows;
  447. X    image->packets=image->columns*image->rows;
  448. X    image->pixels=(RunlengthPacket *)
  449. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  450. X    image->comments=(char *)
  451. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  452. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  453. X        (image->comments == (char *) NULL))
  454. X      {
  455. X        Warning("memory allocation error",(char *) NULL);
  456. X        DestroyImages(image);
  457. X        return((Image *) NULL);
  458. X      }
  459. X    (void) sprintf(image->comments,"\n  Imported from MTV raster image:  %s\n",
  460. X      image->filename);
  461. X    /*
  462. X      Convert MTV raster image to runlength-encoded packets.
  463. X    */
  464. X    p=mtv_pixels;
  465. X    q=image->pixels;
  466. X    for (i=0; i < (image->columns*image->rows); i++)
  467. X    {
  468. X      q->red=(*p++);
  469. X      q->green=(*p++);
  470. X      q->blue=(*p++);
  471. X      q->index=0;
  472. X      q->length=0;
  473. X      q++;
  474. X    }
  475. X    (void) free((char *) mtv_pixels);
  476. X    /*
  477. X      Proceed to next image.
  478. X    */
  479. X    count=fscanf(image->file,"%u %u\n",&columns,&rows);
  480. X    if (count > 0)
  481. X      {
  482. X        /*
  483. X          Allocate next image structure.
  484. X        */
  485. X        image->next=AllocateImage("MTV");
  486. X        if (image->next == (Image *) NULL)
  487. X          {
  488. X            DestroyImages(image);
  489. X            return((Image *) NULL);
  490. X          }
  491. X        image->next->file=image->file;
  492. X        (void) sprintf(image->next->filename,"%s.%u",image_info->filename,
  493. X          image->scene+1);
  494. X        image->next->scene=image->scene+1;
  495. X        image->next->previous=image;
  496. X        image=image->next;
  497. X      }
  498. X  } while (count > 0);
  499. X  while (image->previous != (Image *) NULL)
  500. X    image=image->previous;
  501. X  CloseImage(image);
  502. X  return(image);
  503. }
  504. X
  505. /*
  506. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  507. %                                                                             %
  508. %                                                                             %
  509. %                                                                             %
  510. %  R e a d P C X I m a g e                                                    %
  511. %                                                                             %
  512. %                                                                             %
  513. %                                                                             %
  514. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  515. %
  516. %  Function ReadPCXImage reads a ZSoft IBM PC Paintbrush file and returns it.
  517. %  It allocates the memory necessary for the new Image structure and returns
  518. %  a pointer to the new image.
  519. %
  520. %  The format of the ReadPCXImage routine is:
  521. %
  522. %      image=ReadPCXImage(image_info)
  523. %
  524. %  A description of each parameter follows:
  525. %
  526. %    o image:  Function ReadPCXImage returns a pointer to the image after
  527. %      reading.  A null image is returned if there is a a memory shortage or
  528. %      if the image cannot be read.
  529. %
  530. %    o image_info: Specifies a pointer to an ImageInfo structure.
  531. %
  532. %
  533. */
  534. static Image *ReadPCXImage(image_info)
  535. ImageInfo
  536. X  *image_info;
  537. {
  538. X  typedef struct _PCXHeader
  539. X  {
  540. X    unsigned char
  541. X      identifier,
  542. X      version,
  543. X      encoding,
  544. X      bits_per_pixel;
  545. X
  546. X    short int
  547. X      left,
  548. X      top,
  549. X      right,
  550. X      bottom,
  551. X      horizonal_resolution,
  552. X      vertical_resolution;
  553. X
  554. X    unsigned char
  555. X      reserved,
  556. X      planes;
  557. X
  558. X    short int
  559. X      bytes_per_line,
  560. X      palette_info;
  561. X
  562. X    unsigned char
  563. X      colormap_signature;
  564. X  } PCXHeader;
  565. X
  566. X  PCXHeader
  567. X    pcx_header;
  568. X
  569. X  Image
  570. X    *image;
  571. X
  572. X  int
  573. X    count,
  574. X    packets;
  575. X
  576. X  register int
  577. X    i,
  578. X    x,
  579. X    y;
  580. X
  581. X  register RunlengthPacket
  582. X    *q;
  583. X
  584. X  register unsigned char
  585. X    *p;
  586. X
  587. X  unsigned char
  588. X    packet,
  589. X    *pcx_colormap,
  590. X    *pcx_pixels;
  591. X
  592. X  unsigned int
  593. X    status;
  594. X
  595. X  /*
  596. X    Allocate image structure.
  597. X  */
  598. X  image=AllocateImage("PCX");
  599. X  if (image == (Image *) NULL)
  600. X    return((Image *) NULL);
  601. X  /*
  602. X    Open image file.
  603. X  */
  604. X  (void) strcpy(image->filename,image_info->filename);
  605. X  OpenImage(image,"r");
  606. X  if (image->file == (FILE *) NULL)
  607. X    {
  608. X      Warning("unable to open file",image->filename);
  609. X      DestroyImage(image);
  610. X      return((Image *) NULL);
  611. X    }
  612. X  /*
  613. X    Determine if this is a PCX file.
  614. X  */
  615. X  status=ReadData((char *) &pcx_header.identifier,1,1,image->file);
  616. X  do
  617. X  {
  618. X    /*
  619. X      Verify PCX identifier.
  620. X    */
  621. X    if ((status == False) || (pcx_header.identifier != 0x0a))
  622. X      {
  623. X        Warning("not a PCX image file",(char *) NULL);
  624. X        DestroyImages(image);
  625. X        return((Image *) NULL);
  626. X      }
  627. X    (void) ReadData((char *) &pcx_header.version,1,1,image->file);
  628. X    (void) ReadData((char *) &pcx_header.encoding,1,1,image->file);
  629. X    (void) ReadData((char *) &pcx_header.bits_per_pixel,1,1,image->file);
  630. X    pcx_header.left=LSBFirstReadShort(image->file);
  631. X    pcx_header.top=LSBFirstReadShort(image->file);
  632. X    pcx_header.right=LSBFirstReadShort(image->file);
  633. X    pcx_header.bottom=LSBFirstReadShort(image->file);
  634. X    pcx_header.horizonal_resolution=LSBFirstReadShort(image->file);
  635. X    pcx_header.vertical_resolution=LSBFirstReadShort(image->file);
  636. X    /*
  637. X      Read PCX raster colormap.
  638. X    */
  639. X    image->columns=(pcx_header.right-pcx_header.left)+1;
  640. X    image->rows=(pcx_header.bottom-pcx_header.top)+1;
  641. X    image->class=PseudoClass;
  642. X    image->colors=16;
  643. X    image->colormap=(ColorPacket *) malloc(256*sizeof(ColorPacket));
  644. X    pcx_colormap=(unsigned char *) malloc(3*256*sizeof(unsigned char));
  645. X    if ((image->colormap == (ColorPacket *) NULL) ||
  646. X        (pcx_colormap == (unsigned char *) NULL))
  647. X      {
  648. X        Warning("memory allocation error",(char *) NULL);
  649. X        DestroyImages(image);
  650. X        return((Image *) NULL);
  651. X      }
  652. X    (void) ReadData((char *) pcx_colormap,3,(int) image->colors,image->file);
  653. X    p=pcx_colormap;
  654. X    for (i=0; i < image->colors; i++)
  655. X    {
  656. X      image->colormap[i].red=(*p++);
  657. X      image->colormap[i].green=(*p++);
  658. X      image->colormap[i].blue=(*p++);
  659. X    }
  660. X    (void) ReadData((char *) &pcx_header.reserved,1,1,image->file);
  661. X    (void) ReadData((char *) &pcx_header.planes,1,1,image->file);
  662. X    pcx_header.bytes_per_line=LSBFirstReadShort(image->file);
  663. X    pcx_header.palette_info=LSBFirstReadShort(image->file);
  664. X    for (i=0; i < 58; i++)
  665. X      (void) fgetc(image->file);
  666. X    /*
  667. X      Read image data.
  668. X    */
  669. X    packets=image->rows*pcx_header.bytes_per_line*pcx_header.planes;
  670. X    pcx_pixels=(unsigned char *) malloc(packets*sizeof(unsigned char));
  671. X    if (pcx_pixels == (unsigned char *) NULL)
  672. X      {
  673. X        Warning("memory allocation error",(char *) NULL);
  674. X        DestroyImages(image);
  675. X        return((Image *) NULL);
  676. X      }
  677. X    /*
  678. X      Uncompress image data.
  679. X    */
  680. X    p=pcx_pixels;
  681. X    while (packets > 0)
  682. X    {
  683. X      packet=fgetc(image->file);
  684. X      if ((packet & 0xc0) != 0xc0)
  685. X        {
  686. X          *p++=packet;
  687. X          packets--;
  688. X          continue;
  689. X        }
  690. X      count=packet & 0x3f;
  691. X      packet=fgetc(image->file);
  692. X      packets-=count;
  693. X      while (--count >= 0)
  694. X        *p++=packet;
  695. X    }
  696. X    image->colors=1 << (pcx_header.bits_per_pixel*pcx_header.planes);
  697. X    if (image->colors > 16)
  698. X      {
  699. X        /*
  700. X          256 color images have their color map at the end of the file.
  701. X        */
  702. X        (void) ReadData((char *) &pcx_header.colormap_signature,1,1,
  703. X          image->file);
  704. X        (void) ReadData((char *) pcx_colormap,3,(int) image->colors,
  705. X          image->file);
  706. X        p=pcx_colormap;
  707. X        for (i=0; i < image->colors; i++)
  708. X        {
  709. X          image->colormap[i].red=(*p++);
  710. X          image->colormap[i].green=(*p++);
  711. X          image->colormap[i].blue=(*p++);
  712. X        }
  713. X      }
  714. X    else
  715. X      if (image->colors == 2)
  716. X        if (Intensity(image->colormap[0]) == Intensity(image->colormap[1]))
  717. X          {
  718. X            /*
  719. X              Monochrome colormap.
  720. X            */
  721. X            image->colormap[0].red=MaxRGB;
  722. X            image->colormap[0].green=MaxRGB;
  723. X            image->colormap[0].blue=MaxRGB;
  724. X            image->colormap[1].red=0;
  725. X            image->colormap[1].green=0;
  726. X            image->colormap[1].blue=0;
  727. X          }
  728. X    (void) free((char *) pcx_colormap);
  729. X    /*
  730. X      Create image.
  731. X    */
  732. X    image->packets=image->columns*image->rows;
  733. X    image->pixels=(RunlengthPacket *)
  734. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  735. X    image->comments=(char *)
  736. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  737. X    (void) sprintf(image->comments,
  738. X      "\n  Imported from PCX raster image:  %s\n",image->filename);
  739. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  740. X        (image->comments == (char *) NULL))
  741. X      {
  742. X        Warning("memory allocation error",(char *) NULL);
  743. X        DestroyImages(image);
  744. X        return((Image *) NULL);
  745. X      }
  746. X    /*
  747. X      Convert PCX raster image to runlength-encoded packets.
  748. X    */
  749. X    q=image->pixels;
  750. X    if (pcx_header.planes > 1)
  751. X      {
  752. X        register int
  753. X          bits,
  754. X          mask;
  755. X
  756. X        /*
  757. X          Convert multi-plane format into runlength-encoded pixels.
  758. X        */
  759. X        for (i=0; i < image->packets; i++)
  760. X        {
  761. X          q->index=0;
  762. X          q->length=0;
  763. X          q++;
  764. X        }
  765. X        for (y=0; y < image->rows; y++)
  766. X        {
  767. X          p=pcx_pixels+(y*pcx_header.bytes_per_line*pcx_header.planes);
  768. X          for (i=0; i < (int) pcx_header.planes; i++)
  769. X          {
  770. X            q=image->pixels+y*image->columns;
  771. X            for (x=0; x < pcx_header.bytes_per_line; x++)
  772. X            {
  773. X              bits=(*p++);
  774. X              for (mask=0x80; mask != 0; mask>>=1)
  775. X              {
  776. X                if (bits & mask)
  777. X                  q->index|=1 << i;
  778. X                q++;
  779. X              }
  780. X            }
  781. X          }
  782. X        }
  783. X      }
  784. X    else
  785. X      for (y=0; y < image->rows; y++)
  786. X      {
  787. X        p=pcx_pixels+y*pcx_header.bytes_per_line;
  788. X        switch (pcx_header.bits_per_pixel)
  789. X        {
  790. X          case 1:
  791. X          {
  792. X            register int
  793. X              bit;
  794. X
  795. X            for (x=0; x < (image->columns-7); x+=8)
  796. X            {
  797. X              for (bit=7; bit >= 0; bit--)
  798. X              {
  799. X                q->index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
  800. X                q->length=0;
  801. X                q++;
  802. X              }
  803. X              p++;
  804. X            }
  805. X            if ((image->columns % 8) != 0)
  806. X              {
  807. X                for (bit=7; bit >= (8-(image->columns % 8)); bit--)
  808. X                {
  809. X                  q->index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
  810. X                  q->length=0;
  811. X                  q++;
  812. X                }
  813. X                p++;
  814. X              }
  815. X            break;
  816. X          }
  817. X          case 2:
  818. X          {
  819. X            for (x=0; x < (image->columns-3); x+=4)
  820. X            {
  821. X              q->index=(*p >> 6) & 0x3;
  822. X              q->length=0;
  823. X              q++;
  824. X              q->index=(*p >> 4) & 0x3;
  825. X              q->length=0;
  826. X              q++;
  827. X              q->index=(*p >> 2) & 0x3;
  828. X              q->length=0;
  829. X              q++;
  830. X              q->index=(*p) & 0x3;
  831. X              q->length=0;
  832. X              q++;
  833. X              p++;
  834. X            }
  835. X            if ((image->columns % 4) != 0)
  836. X              {
  837. X                for (i=3; i >= (4-(image->columns % 4)); i--)
  838. X                {
  839. X                  q->index=(*p >> (i*2)) & 0x03;
  840. X                  q->length=0;
  841. X                  q++;
  842. X                }
  843. X                p++;
  844. X              }
  845. X            break;
  846. X          }
  847. X          case 4:
  848. X          {
  849. X            for (x=0; x < (image->columns-1); x+=2)
  850. X            {
  851. X              q->index=(*p >> 4) & 0xf;
  852. X              q->length=0;
  853. X              q++;
  854. X              q->index=(*p) & 0xf;
  855. X              q->length=0;
  856. X              q++;
  857. X              p++;
  858. X            }
  859. X            if ((image->columns % 2) != 0)
  860. X              {
  861. X                q->index=(*p >> 4) & 0xf;
  862. X                q->length=0;
  863. X                q++;
  864. X                p++;
  865. X              }
  866. X            break;
  867. X          }
  868. X          case 8:
  869. X          {
  870. X            for (x=0; x < image->columns; x++)
  871. X            {
  872. X              q->index=(*p);
  873. X              q->length=0;
  874. X              q++;
  875. X              p++;
  876. X            }
  877. X            break;
  878. X          }
  879. X          default:
  880. X            break;
  881. X        }
  882. X      }
  883. X    (void) free((char *) pcx_pixels);
  884. X    SyncImage(image);
  885. X    /*
  886. X      Proceed to next image.
  887. X    */
  888. X    status=ReadData((char *) &pcx_header.identifier,1,1,image->file);
  889. X    if ((status == True) && (pcx_header.identifier == 0x0a))
  890. X      {
  891. X        /*
  892. X          Allocate image structure.
  893. X        */
  894. X        image->next=AllocateImage("PCX");
  895. X        if (image->next == (Image *) NULL)
  896. X          {
  897. X            DestroyImages(image);
  898. X            return((Image *) NULL);
  899. X          }
  900. X        image->next->file=image->file;
  901. X        (void) sprintf(image->next->filename,"%s.%u",image_info->filename,
  902. X          image->scene+1);
  903. X        image->next->scene=image->scene+1;
  904. X        image->next->previous=image;
  905. X        image=image->next;
  906. X      }
  907. X  } while ((status == True) && (pcx_header.identifier == 0x0a));
  908. X  while (image->previous != (Image *) NULL)
  909. X    image=image->previous;
  910. X  CloseImage(image);
  911. X  return(image);
  912. }
  913. X
  914. /*
  915. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  916. %                                                                             %
  917. %                                                                             %
  918. %                                                                             %
  919. %  R e a d P I C T I m a g e                                                  %
  920. %                                                                             %
  921. %                                                                             %
  922. %                                                                             %
  923. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  924. %
  925. %  Function ReadPICTImage reads a Apple Macintosh QuickDraw/PICT image file
  926. %  and returns it.  It allocates the memory necessary for the new Image
  927. %  structure and returns a pointer to the new image.
  928. %
  929. %  The format of the ReadPICTImage routine is:
  930. %
  931. %      image=ReadPICTImage(image_info)
  932. %
  933. %  A description of each parameter follows:
  934. %
  935. %    o image:  Function ReadPICTImage returns a pointer to the image after
  936. %      reading.  A null image is returned if there is a a memory shortage or
  937. %      if the image cannot be read.
  938. %
  939. %    o image_info: Specifies a pointer to an ImageInfo structure.
  940. %
  941. %
  942. */
  943. static Image *ReadPICTImage(image_info)
  944. ImageInfo
  945. X  *image_info;
  946. {
  947. X  Image
  948. X    *image;
  949. X
  950. X  Warning("Cannot read PICT images",image_info->filename);
  951. X  image=ReadMIFFImage(image_info);
  952. X  return(image);
  953. }
  954. X
  955. /*
  956. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  957. %                                                                             %
  958. %                                                                             %
  959. %                                                                             %
  960. %  R e a d P N M I m a g e                                                    %
  961. %                                                                             %
  962. %                                                                             %
  963. %                                                                             %
  964. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  965. %
  966. %  Function ReadPNMImage reads a Portable Anymap image file and returns it.
  967. %  It allocates the memory necessary for the new Image structure and returns
  968. %  a pointer to the new image.
  969. %
  970. %  The format of the ReadPNMImage routine is:
  971. %
  972. %      image=ReadPNMImage(image_info)
  973. %
  974. %  A description of each parameter follows:
  975. %
  976. %    o image:  Function ReadPNMImage returns a pointer to the image after
  977. %      reading.  A null image is returned if there is a a memory shortage or
  978. %      if the image cannot be read.
  979. %
  980. %    o image_info: Specifies a pointer to an ImageInfo structure.
  981. %
  982. %
  983. */
  984. X
  985. static unsigned int GetInteger(file)
  986. FILE
  987. X  *file;
  988. {
  989. X  char
  990. X    c;
  991. X
  992. X  int
  993. X    status;
  994. X
  995. X  unsigned int
  996. X    value;
  997. X
  998. X  /*
  999. X    Skip any leading whitespace.
  1000. X  */
  1001. X  do
  1002. X  {
  1003. X    status=ReadData(&c,1,1,file);
  1004. X    if (status == False)
  1005. X      return(0);
  1006. X    if (c == '#')
  1007. X      do
  1008. X      {
  1009. X        /*
  1010. X          Skip any comments.
  1011. X        */
  1012. X        status=ReadData(&c,1,1,file);
  1013. X        if (status == False)
  1014. X          return(0);
  1015. X      } while (c != '\n');
  1016. X  } while (!isdigit(c));
  1017. X  /*
  1018. X    Evaluate number.
  1019. X  */
  1020. X  value=0;
  1021. X  do
  1022. X  {
  1023. X    value*=10;
  1024. X    value+=c-'0';
  1025. X    status=ReadData(&c,1,1,file);
  1026. X    if (status == False)
  1027. X      return(0);
  1028. X  }
  1029. X  while (isdigit(c));
  1030. X  return(value);
  1031. }
  1032. X
  1033. static Image *ReadPNMImage(image_info)
  1034. ImageInfo
  1035. X  *image_info;
  1036. {
  1037. X  char
  1038. X    format;
  1039. X
  1040. X  Image
  1041. X    *image;
  1042. X
  1043. X  register int
  1044. X    i;
  1045. X
  1046. X  register RunlengthPacket
  1047. X    *q;
  1048. X
  1049. X  register unsigned char
  1050. X    *p;
  1051. X
  1052. X  unsigned char
  1053. X    *pixels,
  1054. X    *scale;
  1055. X
  1056. X  unsigned int
  1057. X    max_value,
  1058. X    status;
  1059. X
  1060. X  /*
  1061. X    Allocate image structure.
  1062. X  */
  1063. X  image=AllocateImage("PNM");
  1064. X  if (image == (Image *) NULL)
  1065. X    return((Image *) NULL);
  1066. X  /*
  1067. X    Open image file.
  1068. X  */
  1069. X  (void) strcpy(image->filename,image_info->filename);
  1070. X  OpenImage(image,"r");
  1071. X  if (image->file == (FILE *) NULL)
  1072. X    {
  1073. X      Warning("unable to open file",image->filename);
  1074. X      DestroyImage(image);
  1075. X      return((Image *) NULL);
  1076. X    }
  1077. X  /*
  1078. X    Read PNM image.
  1079. X  */
  1080. X  status=ReadData((char *) &format,1,1,image->file);
  1081. X  do
  1082. X  {
  1083. X    /*
  1084. X      Verify PNM identifier.
  1085. X    */
  1086. X    if ((status == False) || (format != 'P'))
  1087. X      {
  1088. X        Warning("not a PNM image file",(char *) NULL);
  1089. X        DestroyImage(image);
  1090. X        return((Image *) NULL);
  1091. X      }
  1092. X    /*
  1093. X      Create image.
  1094. X    */
  1095. X    format=fgetc(image->file);
  1096. X    image->columns=GetInteger(image->file);
  1097. X    image->rows=GetInteger(image->file);
  1098. X    if ((image->columns*image->rows) == 0)
  1099. X      {
  1100. X        Warning("unable to read image","image dimensions are zero");
  1101. X        return((Image *) NULL);
  1102. X      }
  1103. X    image->packets=image->columns*image->rows;
  1104. X    image->pixels=(RunlengthPacket *)
  1105. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  1106. X    image->comments=(char *)
  1107. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  1108. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  1109. X        (image->comments == (char *) NULL))
  1110. X      {
  1111. X        Warning("memory allocation error",(char *) NULL);
  1112. X        DestroyImages(image);
  1113. X        return((Image *) NULL);
  1114. X      }
  1115. X    (void) sprintf(image->comments,"\n  Imported from PNM raster image:  %s\n",
  1116. X      image->filename);
  1117. X    if ((format == '1') || (format == '4'))
  1118. X      max_value=1;  /* bitmap */
  1119. X    else
  1120. X      max_value=GetInteger(image->file);
  1121. X    scale=(unsigned char *) NULL;
  1122. X    if (max_value != MaxRGB)
  1123. X      {
  1124. X        /*
  1125. X          Compute pixel scaling table.
  1126. X        */
  1127. X        scale=(unsigned char *) malloc((max_value+1)*sizeof(unsigned char));
  1128. X        if (scale == (unsigned char *) NULL)
  1129. X          {
  1130. X            Warning("unable to read image","memory allocation failed");
  1131. X            DestroyImages(image);
  1132. X            return((Image *) NULL);
  1133. X          }
  1134. X        for (i=0; i <= max_value; i++)
  1135. X          scale[i]=(unsigned char) ((i*MaxRGB+(max_value >> 1))/max_value);
  1136. X      }
  1137. X    if ((format != '3') && (format != '6'))
  1138. X      {
  1139. X        /*
  1140. X          Create gray scale colormap.
  1141. X        */
  1142. X        image->class=PseudoClass;
  1143. X        image->colors=Min(max_value,MaxRGB)+1;
  1144. X        image->colormap=(ColorPacket *)
  1145. X          malloc(image->colors*sizeof(ColorPacket));
  1146. X        if (image->colormap == (ColorPacket *) NULL)
  1147. X          {
  1148. X            Warning("memory allocation error",(char *) NULL);
  1149. X            DestroyImages(image);
  1150. X            return((Image *) NULL);
  1151. X          }
  1152. X        for (i=0; i < image->colors; i++)
  1153. X        {
  1154. X          image->colormap[i].red=(MaxRGB*i)/(image->colors-1);
  1155. X          image->colormap[i].green=(MaxRGB*i)/(image->colors-1);
  1156. X          image->colormap[i].blue=(MaxRGB*i)/(image->colors-1);
  1157. X        }
  1158. X      }
  1159. X    /*
  1160. X      Convert PNM pixels to runlength-encoded MIFF packets.
  1161. X    */
  1162. X    q=image->pixels;
  1163. X    switch (format)
  1164. X    {
  1165. X      case '1':
  1166. X      {
  1167. X        /*
  1168. X          Convert PBM image to runlength-encoded packets.
  1169. X        */
  1170. X        for (i=0; i < image->packets; i++)
  1171. X        {
  1172. X          q->index=GetInteger(image->file);
  1173. X          if (q->index > 1)
  1174. X            q->index=1;
  1175. X          q->length=0;
  1176. X          q++;
  1177. X        }
  1178. X        SyncImage(image);
  1179. X        break;
  1180. X      }
  1181. X      case '2':
  1182. X      {
  1183. X        /*
  1184. X          Convert PGM image to runlength-encoded packets.
  1185. X        */
  1186. X        if (max_value == MaxRGB)
  1187. X          for (i=0; i < image->packets; i++)
  1188. X          {
  1189. X            q->index=GetInteger(image->file);
  1190. X            q->length=0;
  1191. X            q++;
  1192. X          }
  1193. X        else
  1194. X          for (i=0; i < image->packets; i++)
  1195. X          {
  1196. X            q->index=scale[GetInteger(image->file)];
  1197. X            q->length=0;
  1198. X            q++;
  1199. X          }
  1200. X        SyncImage(image);
  1201. X        break;
  1202. X      }
  1203. X      case '3':
  1204. X      {
  1205. X        /*
  1206. X          Convert PNM image to runlength-encoded packets.
  1207. X        */
  1208. X        if (max_value == MaxRGB)
  1209. X          for (i=0; i < image->packets; i++)
  1210. X          {
  1211. X            q->red=GetInteger(image->file);
  1212. X            q->green=GetInteger(image->file);
  1213. X            q->blue=GetInteger(image->file);
  1214. X            q->index=0;
  1215. X            q->length=0;
  1216. X            q++;
  1217. X          }
  1218. X        else
  1219. X          for (i=0; i < image->packets; i++)
  1220. X          {
  1221. X            q->red=scale[GetInteger(image->file)];
  1222. X            q->green=scale[GetInteger(image->file)];
  1223. X            q->blue=scale[GetInteger(image->file)];
  1224. X            q->index=0;
  1225. X            q->length=0;
  1226. X            q++;
  1227. X          }
  1228. X        break;
  1229. X      }
  1230. X      case '4':
  1231. X      {
  1232. X        unsigned char
  1233. X          bit,
  1234. X          byte;
  1235. X
  1236. X        unsigned int
  1237. X          x,
  1238. X          y;
  1239. X
  1240. X        /*
  1241. X          Convert PBM raw image to runlength-encoded packets.
  1242. X        */
  1243. X        for (y=0; y < image->rows; y++)
  1244. X        {
  1245. X          bit=0;
  1246. X          byte=0;
  1247. X          for (x=0; x < image->columns; x++)
  1248. X          {
  1249. X            if (bit == 0)
  1250. X              byte=fgetc(image->file);
  1251. X            q->index=(byte & 0x80) ? 0 : 1;
  1252. X            q->length=0;
  1253. X            q++;
  1254. X            bit++;
  1255. X            if (bit == 8)
  1256. X              bit=0;
  1257. X            byte<<=1;
  1258. X          }
  1259. X        }
  1260. X        SyncImage(image);
  1261. X        break;
  1262. X      }
  1263. X      case '5':
  1264. X      {
  1265. X        /*
  1266. X          Convert PGM raw image to runlength-encoded packets.
  1267. X        */
  1268. X        pixels=(unsigned char *)
  1269. X          malloc((unsigned int) image->packets*sizeof(unsigned char));
  1270. X        if (pixels == (unsigned char *) NULL)
  1271. X          {
  1272. X            Warning("memory allocation error",(char *) NULL);
  1273. X            DestroyImages(image);
  1274. X            return((Image *) NULL);
  1275. X          }
  1276. X        status=ReadData((char *) pixels,1,(int) image->packets,image->file);
  1277. X        if (status == False)
  1278. X          {
  1279. X            Warning("insufficient image data in file",image->filename);
  1280. X            DestroyImages(image);
  1281. X            return((Image *) NULL);
  1282. X          }
  1283. X        /*
  1284. X          Convert PNM raw image to runlength-encoded packets.
  1285. X        */
  1286. X        p=pixels;
  1287. X        if (max_value == MaxRGB)
  1288. X          for (i=0; i < image->packets; i++)
  1289. X          {
  1290. X            q->index=(*p++);
  1291. X            q->length=0;
  1292. X            q++;
  1293. X          }
  1294. X        else
  1295. X          for (i=0; i < image->packets; i++)
  1296. X          {
  1297. X            q->index=scale[*p++];
  1298. X            q->length=0;
  1299. X            q++;
  1300. X          }
  1301. X        SyncImage(image);
  1302. X        break;
  1303. X      }
  1304. X      case '6':
  1305. X      {
  1306. X        /*
  1307. X          Convert PNM raster image to runlength-encoded packets.
  1308. X        */
  1309. X        pixels=(unsigned char *)
  1310. X          malloc((unsigned int) image->packets*3*sizeof(unsigned char));
  1311. X        if (pixels == (unsigned char *) NULL)
  1312. X          {
  1313. X            Warning("memory allocation error",(char *) NULL);
  1314. X            DestroyImages(image);
  1315. X            return((Image *) NULL);
  1316. X          }
  1317. X        status=ReadData((char *) pixels,1,(int) image->packets*3,image->file);
  1318. X        if (status == False)
  1319. X          {
  1320. X            Warning("insufficient image data in file",image->filename);
  1321. X            DestroyImages(image);
  1322. X            return((Image *) NULL);
  1323. X          }
  1324. X        p=pixels;
  1325. X        if (max_value == MaxRGB)
  1326. X          for (i=0; i < image->packets; i++)
  1327. X          {
  1328. X            q->red=(*p++);
  1329. X            q->green=(*p++);
  1330. X            q->blue=(*p++);
  1331. X            q->index=0;
  1332. X            q->length=0;
  1333. X            q++;
  1334. X          }
  1335. X        else
  1336. X          for (i=0; i < image->packets; i++)
  1337. X          {
  1338. X            q->red=scale[*p++];
  1339. X            q->green=scale[*p++];
  1340. X            q->blue=scale[*p++];
  1341. X            q->index=0;
  1342. X            q->length=0;
  1343. X            q++;
  1344. X          }
  1345. X        break;
  1346. X      }
  1347. X      default:
  1348. X      {
  1349. X        Warning("not a PNM image file",(char *) NULL);
  1350. X        DestroyImages(image);
  1351. X        return((Image *) NULL);
  1352. X      }
  1353. X    }
  1354. X    if (scale != (unsigned char *) NULL)
  1355. X      (void) free((char *) scale);
  1356. X    if (image->class == PseudoClass)
  1357. X      CompressColormap(image);
  1358. X    /*
  1359. X      Proceed to next image.
  1360. X    */
  1361. X    status=ReadData((char *) &format,1,1,image->file);
  1362. X    if ((status == True) && (format == 'P'))
  1363. X      {
  1364. X        /*
  1365. X          Allocate image structure.
  1366. X        */
  1367. X        image->next=AllocateImage("PNM");
  1368. X        if (image->next == (Image *) NULL)
  1369. X          {
  1370. X            DestroyImages(image);
  1371. X            return((Image *) NULL);
  1372. X          }
  1373. X        image->next->file=image->file;
  1374. X        (void) sprintf(image->next->filename,"%s.%u",image_info->filename,
  1375. X          image->scene+1);
  1376. X        image->next->scene=image->scene+1;
  1377. X        image->next->previous=image;
  1378. X        image=image->next;
  1379. X      }
  1380. X  } while ((status == True) && (format == 'P'));
  1381. X  while (image->previous != (Image *) NULL)
  1382. X    image=image->previous;
  1383. X  CloseImage(image);
  1384. X  return(image);
  1385. }
  1386. X
  1387. /*
  1388. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1389. %                                                                             %
  1390. %                                                                             %
  1391. %                                                                             %
  1392. %  R e a d P S I m a g e                                                      %
  1393. %                                                                             %
  1394. %                                                                             %
  1395. %                                                                             %
  1396. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1397. %
  1398. %  Function ReadPSImage reads a Adobe Postscript image file and returns it.  It
  1399. %  allocates the memory necessary for the new Image structure and returns a
  1400. %  pointer to the new image.
  1401. %
  1402. %  The format of the ReadPSImage routine is:
  1403. %
  1404. %      image=ReadPSImage(image_info)
  1405. %
  1406. %  A description of each parameter follows:
  1407. %
  1408. %    o image:  Function ReadPSImage returns a pointer to the image after
  1409. %      reading.  A null image is returned if there is a a memory shortage or
  1410. %      if the image cannot be read.
  1411. %
  1412. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1413. %
  1414. %    o density: Specifies a pointer to a image density string;  horizonal
  1415. %      and vertical dots per inch.
  1416. %
  1417. %
  1418. */
  1419. static Image *ReadPSImage(image_info)
  1420. ImageInfo
  1421. X  *image_info;
  1422. {
  1423. #define XResolution  72
  1424. #define YResolution  72
  1425. X
  1426. X  char
  1427. X    command[2048],
  1428. X    clip_geometry[2048],
  1429. X    *device,
  1430. X    *directory,
  1431. X    filename[2048],
  1432. X    options[2048];
  1433. X
  1434. X  Image
  1435. X    *image,
  1436. X    *next_image;
  1437. X
  1438. X  unsigned int
  1439. X    status;
  1440. X
  1441. X  /*
  1442. X    Allocate image structure.
  1443. X  */
  1444. X  image=AllocateImage("PS");
  1445. X  if (image == (Image *) NULL)
  1446. X    return((Image *) NULL);
  1447. X  /*
  1448. X    Open image file.
  1449. X  */
  1450. X  (void) strcpy(image->filename,image_info->filename);
  1451. X  OpenImage(image,"r");
  1452. X  if (image->file == (FILE *) NULL)
  1453. X    {
  1454. X      Warning("unable to open file",image->filename);
  1455. X      DestroyImage(image);
  1456. X      return((Image *) NULL);
  1457. X    }
  1458. X  /*
  1459. X    Determine if Postscript specifies a bounding box.
  1460. X  */
  1461. X  *clip_geometry='\0';
  1462. X  while (fgets(command,sizeof(command)-1,image->file) != (char *) NULL)
  1463. X    if (strncmp("%%BoundingBox:",command,strlen("%%BoundingBox:")) == 0)
  1464. X      {
  1465. X        int
  1466. X          count,
  1467. X          lower_x,
  1468. X          lower_y,
  1469. X          upper_x,
  1470. X          upper_y,
  1471. X          x,
  1472. X          y;
  1473. X
  1474. X        unsigned int
  1475. X          x_resolution,
  1476. X          y_resolution;
  1477. X
  1478. X        count=sscanf(command,"%%%%BoundingBox: %d %d %d %d",&lower_x,&lower_y,
  1479. X          &upper_x,&upper_y);
  1480. X        if (count != 4)
  1481. X          break;
  1482. X        /*
  1483. X          Set clip geometry as specified by the bounding box.
  1484. X        */
  1485. X        x_resolution=XResolution;
  1486. X        y_resolution=YResolution;
  1487. X        if (image_info->density != (char *) NULL)
  1488. X          {
  1489. X            int
  1490. X              flags;
  1491. X
  1492. X            /*
  1493. X              User specified density.
  1494. X            */
  1495. X            flags=XParseGeometry(image_info->density,&x,&y,&x_resolution,
  1496. X              &y_resolution);
  1497. X            if ((flags & WidthValue) == 0)
  1498. X              x_resolution=XResolution;
  1499. X            if ((flags & HeightValue) == 0)
  1500. X              y_resolution=x_resolution;
  1501. X          }
  1502. X        (void) sprintf(clip_geometry,"%ux%u+%u-%u",
  1503. X          ((upper_x-lower_x)*x_resolution+(XResolution >> 1))/XResolution,
  1504. X          ((upper_y-lower_y)*y_resolution+(YResolution >> 1))/YResolution,
  1505. X          (lower_x*x_resolution+(XResolution >> 1))/XResolution,
  1506. X          ((lower_y*y_resolution+(YResolution >> 1))/YResolution));
  1507. X        break;
  1508. X      }
  1509. X  CloseImage(image);
  1510. X  /*
  1511. X    Rendered Postscript goes to temporary PNM file.
  1512. X  */
  1513. X  directory=(char *) getenv("TMPDIR");
  1514. X  if (directory == (char *) NULL)
  1515. X    directory="/tmp";
  1516. X  (void) sprintf(filename,"%s/magickXXXXXX",directory);
  1517. X  (void) mktemp(filename);
  1518. X  device="ppmraw";
  1519. X  if (image_info->monochrome)
  1520. X    device="pbmraw";
  1521. X  /*
  1522. X    Determine if page geometry or density options are specified.
  1523. X  */
  1524. X  *options='\0';
  1525. X  if (image_info->page != (char *) NULL)
  1526. X    {
  1527. X      (void) strcat(options," -g");
  1528. X      (void) strcat(options,image_info->page);
  1529. X    }
  1530. X  if (image_info->density != (char *) NULL)
  1531. X    {
  1532. X      (void) strcat(options," -r");
  1533. X      (void) strcat(options,image_info->density);
  1534. X    }
  1535. X  /*
  1536. X    Use Ghostscript to convert Postscript image.
  1537. X  */
  1538. X  (void) sprintf(command,"gs -q -sDEVICE=%s -sOutputFile=%s %s %s",
  1539. X    device,filename,options,image_info->filename);
  1540. X  (void) strcat(command," < /dev/null > /dev/null");
  1541. X  status=system(command);
  1542. X  if (status != 0)
  1543. X    {
  1544. X      Warning("unable to execute ghostscript (gs)",image_info->filename);
  1545. X      return((Image *) NULL);
  1546. X    }
  1547. X  (void) strcpy(image_info->filename,filename);
  1548. X  (void) strcpy(filename,image->filename);
  1549. X  DestroyImage(image);
  1550. X  image=ReadPNMImage(image_info);
  1551. X  (void) unlink(image_info->filename);
  1552. X  if (image == (Image *) NULL)
  1553. X    {
  1554. X      Warning("Postscript translation failed",image_info->filename);
  1555. X      return((Image *) NULL);
  1556. X    }
  1557. X  do
  1558. X  {
  1559. X    if (image->previous == (Image *) NULL)
  1560. X      (void) strcpy(image->filename,filename);
  1561. X    else
  1562. X      (void) sprintf(image->filename,"%s.%u",filename,image->scene);
  1563. X    (void) strcpy(image->magick,"PS");
  1564. X    if (*clip_geometry != '\0')
  1565. X      {
  1566. X        /*
  1567. X          Clip image as specified by the bounding box.
  1568. X        */
  1569. X        TransformImage(&image,clip_geometry,(char *) NULL,(char *) NULL);
  1570. X        if (image->next != (Image *) NULL)
  1571. X          image->next->previous=image;
  1572. X      }
  1573. X    next_image=image->next;
  1574. X    if (next_image != (Image *) NULL)
  1575. X      image=next_image;
  1576. X  } while (next_image != (Image *) NULL);
  1577. X  while (image->previous != (Image *) NULL)
  1578. X    image=image->previous;
  1579. X  return(image);
  1580. }
  1581. X
  1582. /*
  1583. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1584. %                                                                             %
  1585. %                                                                             %
  1586. %                                                                             %
  1587. %  R e a d R G B I m a g e                                                    %
  1588. %                                                                             %
  1589. %                                                                             %
  1590. %                                                                             %
  1591. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1592. %
  1593. %  Function ReadRGBImage reads an image of raw red, green, and blue bytes and
  1594. %  returns it.  It allocates the memory necessary for the new Image structure
  1595. %  and returns a pointer to the new image.
  1596. %
  1597. %  The format of the ReadRGBImage routine is:
  1598. %
  1599. %      image=ReadRGBImage(image_info)
  1600. %
  1601. %  A description of each parameter follows:
  1602. %
  1603. %    o image:  Function ReadRGBImage returns a pointer to the image after
  1604. %      reading.  A null image is returned if there is a a memory shortage or
  1605. %      if the image cannot be read.
  1606. %
  1607. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1608. %
  1609. %
  1610. */
  1611. static Image *ReadRGBImage(image_info)
  1612. ImageInfo
  1613. X  *image_info;
  1614. {
  1615. X  Image
  1616. X    *image;
  1617. X
  1618. X  int
  1619. X    x,
  1620. X    y;
  1621. X
  1622. X  register int
  1623. X    i;
  1624. X
  1625. X  register RunlengthPacket
  1626. X    *q;
  1627. X
  1628. X  register unsigned char
  1629. X    *p;
  1630. X
  1631. X  unsigned char
  1632. X    *rgb_pixels;
  1633. X
  1634. X  unsigned int
  1635. X    height,
  1636. X    width;
  1637. X
  1638. X  /*
  1639. X    Allocate image structure.
  1640. X  */
  1641. X  image=AllocateImage("RGB");
  1642. X  if (image == (Image *) NULL)
  1643. X    return((Image *) NULL);
  1644. X  /*
  1645. X    Open image file.
  1646. X  */
  1647. X  (void) strcpy(image->filename,image_info->filename);
  1648. X  OpenImage(image,"r");
  1649. X  if (image->file == (FILE *) NULL)
  1650. X    {
  1651. X      Warning("unable to open file",image->filename);
  1652. X      DestroyImage(image);
  1653. X      return((Image *) NULL);
  1654. X    }
  1655. X  /*
  1656. X    Create image.
  1657. X  */
  1658. X  width=512;
  1659. X  height=512;
  1660. X  if (image_info->geometry != (char *) NULL)
  1661. X    (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  1662. X  image->columns=width;
  1663. X  image->rows=height;
  1664. X  image->packets=image->columns*image->rows;
  1665. X  rgb_pixels=(unsigned char *)
  1666. X    malloc((unsigned int) image->packets*3*sizeof(unsigned char));
  1667. X  image->pixels=(RunlengthPacket *)
  1668. X    malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  1669. X  if ((rgb_pixels == (unsigned char *) NULL) ||
  1670. X      (image->pixels == (RunlengthPacket *) NULL))
  1671. X    {
  1672. X      Warning("memory allocation error",(char *) NULL);
  1673. X      DestroyImage(image);
  1674. X      return((Image *) NULL);
  1675. X    }
  1676. X  /*
  1677. X    Convert raster image to runlength-encoded packets.
  1678. X  */
  1679. X  (void) ReadData((char *) rgb_pixels,3,(int) (image->columns*image->rows),
  1680. X    image->file);
  1681. X  p=rgb_pixels;
  1682. X  switch (image_info->interlace)
  1683. X  {
  1684. X    case NoneInterlace:
  1685. X    default:
  1686. X    {
  1687. X      /*
  1688. X        No interlacing:  RGBRGBRGBRGBRGBRGB...
  1689. X      */
  1690. X      q=image->pixels;
  1691. X      for (i=0; i < (image->columns*image->rows); i++)
  1692. X      {
  1693. X        q->red=(*p++);
  1694. X        q->green=(*p++);
  1695. X        q->blue=(*p++);
  1696. X        q->index=0;
  1697. X        q->length=0;
  1698. X        q++;
  1699. X      }
  1700. X      break;
  1701. X    }
  1702. X    case LineInterlace:
  1703. X    {
  1704. X      /*
  1705. X        Line interlacing:  RRR...GGG...BBB...RRR...GGG...BBB...
  1706. X      */
  1707. X      for (y=0; y < image->rows; y++)
  1708. X      {
  1709. X        q=image->pixels+y*image->columns;
  1710. X        for (x=0; x < image->columns; x++)
  1711. X        {
  1712. X          q->red=(*p++);
  1713. X          q->index=0;
  1714. X          q->length=0;
  1715. X          q++;
  1716. X        }
  1717. X        q=image->pixels+y*image->columns;
  1718. X        for (x=0; x < image->columns; x++)
  1719. X        {
  1720. X          q->green=(*p++);
  1721. X          q++;
  1722. X        }
  1723. X        q=image->pixels+y*image->columns;
  1724. X        for (x=0; x < image->columns; x++)
  1725. X        {
  1726. X          q->blue=(*p++);
  1727. X          q++;
  1728. X        }
  1729. X      }
  1730. X      break;
  1731. X    }
  1732. X    case PlaneInterlace:
  1733. X    {
  1734. X      /*
  1735. X        Plane interlacing:  RRRRRR...GGGGGG...BBBBBB...
  1736. X      */
  1737. X      q=image->pixels;
  1738. X      for (i=0; i < (image->columns*image->rows); i++)
  1739. X      {
  1740. X        q->red=(*p++);
  1741. X        q->index=0;
  1742. X        q->length=0;
  1743. X        q++;
  1744. X      }
  1745. X      q=image->pixels;
  1746. X      for (i=0; i < (image->columns*image->rows); i++)
  1747. X      {
  1748. X        q->green=(*p++);
  1749. X        q++;
  1750. X      }
  1751. X      q=image->pixels;
  1752. X      for (i=0; i < (image->columns*image->rows); i++)
  1753. X      {
  1754. X        q->blue=(*p++);
  1755. X        q++;
  1756. X      }
  1757. X      break;
  1758. X    }
  1759. X  }
  1760. X  (void) free((char *) rgb_pixels);
  1761. X  CloseImage(image);
  1762. X  return(image);
  1763. }
  1764. X
  1765. /*
  1766. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1767. SHAR_EOF
  1768. true || echo 'restore of ImageMagick/decode.c failed'
  1769. fi
  1770. echo 'End of ImageMagick part 15'
  1771. echo 'File ImageMagick/decode.c is continued in part 16'
  1772. echo 16 > _shar_seq_.tmp
  1773. exit 0
  1774.  
  1775. exit 0 # Just in case...
  1776. -- 
  1777.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1778. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1779.  "It's intuitively obvious to the |
  1780.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1781.