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

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i092:  imagemagic - X11 image processing and display, Part36/38
  4. Message-ID: <1993Jul14.232311.23691@sparky.sterling.com>
  5. X-Md4-Signature: a47000f3424693bc98952abeea5cd89a
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 23:23:11 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 92
  13. Archive-name: imagemagic/part36
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.36 (part 36 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/encode.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" != 36; 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/encode.c'
  36. else
  37. echo 'x - continuing file ImageMagick/encode.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/encode.c' &&
  39. %                                                                             %
  40. %                                                                             %
  41. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  42. %
  43. %  Function WriteRGBImage writes an image to a file in red, green, and
  44. %  blue rasterfile format.
  45. %
  46. %  The format of the WriteRGBImage routine is:
  47. %
  48. %      status=WriteRGBImage(image,interlace)
  49. %
  50. %  A description of each parameter follows.
  51. %
  52. %    o status: Function WriteRGBImage return True if the image is written.
  53. %      False is returned is there is a memory shortage or if the image file
  54. %      fails to write.
  55. %
  56. %    o image:  A pointer to a Image structure.
  57. %
  58. %    o interlace:  An unsigned integer that specifies the interlacing
  59. %      scheme.
  60. %
  61. %
  62. */
  63. static unsigned int WriteRGBImage(image,interlace)
  64. Image
  65. X  *image;
  66. X
  67. unsigned int
  68. X  interlace;
  69. {
  70. X  register int
  71. X    i,
  72. X    j;
  73. X
  74. X  register RunlengthPacket
  75. X    *p;
  76. X
  77. X  register unsigned char
  78. X    *q;
  79. X
  80. X  unsigned char
  81. X    *rgb_pixels;
  82. X
  83. X  /*
  84. X    Open output image file.
  85. X  */
  86. X  OpenImage(image,"w");
  87. X  if (image->file == (FILE *) NULL)
  88. X    {
  89. X      Warning("unable to open file",image->filename);
  90. X      return(False);
  91. X    }
  92. X  /*
  93. X    Convert MIFF to RGB raster pixels.
  94. X  */
  95. X  rgb_pixels=(unsigned char *)
  96. X    malloc(3*image->columns*image->rows*sizeof(unsigned char));
  97. X  if (rgb_pixels == (unsigned char *) NULL)
  98. X    {
  99. X      Warning("unable to allocate memory",(char *) NULL);
  100. X      return(False);
  101. X    }
  102. X  q=rgb_pixels;
  103. X  switch (interlace)
  104. X  {
  105. X    case NoneInterlace:
  106. X    default:
  107. X    {
  108. X      /*
  109. X        No interlacing:  RGBRGBRGBRGBRGBRGB...
  110. X      */
  111. X      p=image->pixels;
  112. X      for (i=0; i < image->packets; i++)
  113. X      {
  114. X        for (j=0; j <= ((int) p->length); j++)
  115. X        {
  116. X          *q++=p->red;
  117. X          *q++=p->green;
  118. X          *q++=p->blue;
  119. X        }
  120. X        p++;
  121. X      }
  122. X      break;
  123. X    }
  124. X    case LineInterlace:
  125. X    {
  126. X      register int
  127. X        x,
  128. X        y;
  129. X
  130. X      /*
  131. X        Line interlacing:  RRR...GGG...BBB...RRR...GGG...BBB...
  132. X      */
  133. X      if (!UncompressImage(image))
  134. X        return(False);
  135. X      for (y=0; y < image->rows; y++)
  136. X      {
  137. X        p=image->pixels+(y*image->columns);
  138. X        for (x=0; x < image->columns; x++)
  139. X        {
  140. X          *q++=p->red;
  141. X          p++;
  142. X        }
  143. X        p=image->pixels+(y*image->columns);
  144. X        for (x=0; x < image->columns; x++)
  145. X        {
  146. X          *q++=p->green;
  147. X          p++;
  148. X        }
  149. X        p=image->pixels+(y*image->columns);
  150. X        for (x=0; x < image->columns; x++)
  151. X        {
  152. X          *q++=p->blue;
  153. X          p++;
  154. X        }
  155. X      }
  156. X      break;
  157. X    }
  158. X    case PlaneInterlace:
  159. X    {
  160. X      /*
  161. X        Plane interlacing:  RRRRRR...GGGGGG...BBBBBB...
  162. X      */
  163. X      p=image->pixels;
  164. X      for (i=0; i < image->packets; i++)
  165. X      {
  166. X        for (j=0; j <= ((int) p->length); j++)
  167. X          *q++=p->red;
  168. X        p++;
  169. X      }
  170. X      p=image->pixels;
  171. X      for (i=0; i < image->packets; i++)
  172. X      {
  173. X        for (j=0; j <= ((int) p->length); j++)
  174. X          *q++=p->green;
  175. X        p++;
  176. X      }
  177. X      p=image->pixels;
  178. X      for (i=0; i < image->packets; i++)
  179. X      {
  180. X        for (j=0; j <= ((int) p->length); j++)
  181. X          *q++=p->blue;
  182. X        p++;
  183. X      }
  184. X      break;
  185. X    }
  186. X  }
  187. X  (void) fwrite((char *) rgb_pixels,3,(int) (image->columns*image->rows),
  188. X    image->file);
  189. X  (void) free((char *) rgb_pixels);
  190. X  CloseImage(image);
  191. X  return(True);
  192. }
  193. X
  194. /*
  195. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  196. %                                                                             %
  197. %                                                                             %
  198. %                                                                             %
  199. %   W r i t e S U N I m a g e                                                 %
  200. %                                                                             %
  201. %                                                                             %
  202. %                                                                             %
  203. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  204. %
  205. %  Function WriteSUNImage writes an image in the SUN rasterfile format.
  206. %
  207. %  The format of the WriteSUNImage routine is:
  208. %
  209. %      status=WriteSUNImage(image)
  210. %
  211. %  A description of each parameter follows.
  212. %
  213. %    o status: Function WriteSUNImage return True if the image is written.
  214. %      False is returned is there is a memory shortage or if the image file
  215. %      fails to write.
  216. %
  217. %    o image:  A pointer to a Image structure.
  218. %
  219. %
  220. */
  221. static unsigned int WriteSUNImage(image)
  222. Image
  223. X  *image;
  224. {
  225. #define RMT_EQUAL_RGB  1
  226. #define RMT_NONE  0
  227. #define RMT_RAW  2
  228. #define RT_STANDARD  1
  229. #define RT_FORMAT_RGB  3
  230. X
  231. X  typedef struct _SUNHeader
  232. X  {
  233. X    unsigned long
  234. X      magic,
  235. X      width,
  236. X      height,
  237. X      depth,
  238. X      length,
  239. X      type,
  240. X      maptype,
  241. X      maplength;
  242. X  } SUNHeader;
  243. X
  244. X  register int
  245. X    i,
  246. X    j,
  247. X    x;
  248. X
  249. X  register RunlengthPacket
  250. X    *p;
  251. X
  252. X  register unsigned char
  253. X    *q;
  254. X
  255. X  SUNHeader
  256. X    sun_header;
  257. X
  258. X  unsigned char
  259. X    *sun_pixels;
  260. X
  261. X  unsigned int
  262. X    grayscale;
  263. X
  264. X  /*
  265. X    Open output image file.
  266. X  */
  267. X  OpenImage(image,"w");
  268. X  if (image->file == (FILE *) NULL)
  269. X    {
  270. X      Warning("unable to open file",image->filename);
  271. X      return(False);
  272. X    }
  273. X  /*
  274. X    Initialize SUN raster file header.
  275. X  */
  276. X  sun_header.magic=0x59a66a95;
  277. X  sun_header.width=image->columns;
  278. X  sun_header.height=image->rows;
  279. X  sun_header.type=(image->class == DirectClass ? RT_FORMAT_RGB : RT_STANDARD);
  280. X  sun_header.maptype=RMT_NONE;
  281. X  sun_header.maplength=0;
  282. X  grayscale=False;
  283. X  if ((image->class == DirectClass) || (image->colors > 256))
  284. X    {
  285. X      /*
  286. X        Full color SUN raster.
  287. X      */
  288. X      sun_header.depth=(image->alpha ? 32 : 24);
  289. X      sun_header.length=image->columns*image->rows*(image->alpha ? 4 : 3);
  290. X      sun_header.length+=image->columns % 2 ? image->rows : 0;
  291. X    }
  292. X  else
  293. X    {
  294. X      /*
  295. X        Determine if image is grayscale.
  296. X      */
  297. X      grayscale=True;
  298. X      for (i=0; i < image->colors; i++)
  299. X        if ((image->colormap[i].red != image->colormap[i].green) ||
  300. X            (image->colormap[i].green != image->colormap[i].blue))
  301. X          {
  302. X            grayscale=False;
  303. X            break;
  304. X          }
  305. X      if ((image->colors > 2) || !grayscale)
  306. X        {
  307. X          /*
  308. X            Colormapped SUN raster.
  309. X          */
  310. X          sun_header.depth=8;
  311. X          sun_header.length=image->columns*image->rows;
  312. X          sun_header.length+=image->columns % 2 ? image->rows : 0;
  313. X          sun_header.maptype=RMT_EQUAL_RGB;
  314. X          sun_header.maplength=image->colors*3;
  315. X        }
  316. X      else
  317. X        {
  318. X          /*
  319. X            Monochrome SUN raster.
  320. X          */
  321. X          sun_header.depth=1;
  322. X          sun_header.length=((image->columns+7) >> 3)*image->rows;
  323. X          sun_header.length+=((image->columns/8)+(image->columns % 8 ? 1 : 0)) %
  324. X            2 ? image->rows : 0;
  325. X        }
  326. X    }
  327. X  /*
  328. X    Write SUN header.
  329. X  */
  330. X  MSBFirstWriteLong(sun_header.magic,image->file);
  331. X  MSBFirstWriteLong(sun_header.width,image->file);
  332. X  MSBFirstWriteLong(sun_header.height,image->file);
  333. X  MSBFirstWriteLong(sun_header.depth,image->file);
  334. X  MSBFirstWriteLong(sun_header.length,image->file);
  335. X  MSBFirstWriteLong(sun_header.type,image->file);
  336. X  MSBFirstWriteLong(sun_header.maptype,image->file);
  337. X  MSBFirstWriteLong(sun_header.maplength,image->file);
  338. X  /*
  339. X    Convert MIFF to SUN raster pixels.
  340. X  */
  341. X  sun_pixels=(unsigned char *) malloc(sun_header.length*sizeof(unsigned char));
  342. X  if (sun_pixels == (unsigned char *) NULL)
  343. X    {
  344. X      Warning("unable to allocate memory",(char *) NULL);
  345. X      return(False);
  346. X    }
  347. X  p=image->pixels;
  348. X  q=sun_pixels;
  349. X  x=0;
  350. X  if ((image->class == DirectClass) || (image->colors > 256))
  351. X    {
  352. X      /*
  353. X        Convert DirectClass packet to SUN RGB pixel.
  354. X      */
  355. X      for (i=0; i < image->packets; i++)
  356. X      {
  357. X        for (j=0; j <= (int) p->length; j++)
  358. X        {
  359. X          if (image->alpha)
  360. X            *q++=(unsigned char) p->index;
  361. X          *q++=p->red;
  362. X          *q++=p->green;
  363. X          *q++=p->blue;
  364. X          x++;
  365. X          if (x == image->columns)
  366. X            {
  367. X              if ((image->columns % 2) != 0)
  368. X                q++;  /* pad scanline */
  369. X              x=0;
  370. X            }
  371. X        }
  372. X        p++;
  373. X      }
  374. X    }
  375. X  else
  376. X    if ((image->colors > 2) || !grayscale)
  377. X      {
  378. X        unsigned char
  379. X          *sun_colormap;
  380. X
  381. X        /*
  382. X          Dump colormap to file.
  383. X        */
  384. X        sun_colormap=(unsigned char *)
  385. X          malloc(sun_header.maplength*sizeof(unsigned char));
  386. X        if (sun_colormap == (unsigned char *) NULL)
  387. X          {
  388. X            Warning("unable to allocate memory",(char *) NULL);
  389. X            return(False);
  390. X          }
  391. X        q=sun_colormap;
  392. X        for (i=0; i < image->colors; i++)
  393. X          *q++=image->colormap[i].red;
  394. X        for (i=0; i < image->colors; i++)
  395. X          *q++=image->colormap[i].green;
  396. X        for (i=0; i < image->colors; i++)
  397. X          *q++=image->colormap[i].blue;
  398. X        (void) fwrite((char *) sun_colormap,1,(int) sun_header.maplength,
  399. X          image->file);
  400. X        (void) free((char *) sun_colormap);
  401. X        /*
  402. X          Convert PseudoClass packet to SUN colormapped pixel.
  403. X        */
  404. X        q=sun_pixels;
  405. X        for (i=0; i < image->packets; i++)
  406. X        {
  407. X          for (j=0; j <= (int) p->length; j++)
  408. X          {
  409. X            *q++=p->index;
  410. X            x++;
  411. X            if (x == image->columns)
  412. X              {
  413. X                if ((image->columns % 2) != 0)
  414. X                  q++;  /* pad scanline */
  415. X                x=0;
  416. X              }
  417. X          }
  418. X          p++;
  419. X        }
  420. X      }
  421. X    else
  422. X      {
  423. X        register unsigned char
  424. X          bit,
  425. X          byte,
  426. X          polarity;
  427. X
  428. X        /*
  429. X          Convert PseudoClass image to a SUN monochrome image.
  430. X        */
  431. X        polarity=(Intensity(image->colormap[0]) <
  432. X          Intensity(image->colormap[1]) ? 0 : 1);
  433. X        bit=0;
  434. X        byte=0;
  435. X        for (i=0; i < image->packets; i++)
  436. X        {
  437. X          for (j=0; j <= (int) p->length; j++)
  438. X          {
  439. X            byte<<=1;
  440. X            if (p->index == polarity)
  441. X              byte|=0x01;
  442. X            bit++;
  443. X            if (bit == 8)
  444. X              {
  445. X                *q++=byte;
  446. X                bit=0;
  447. X                byte=0;
  448. X              }
  449. X            x++;
  450. X            if (x == image->columns)
  451. X              {
  452. X                /*
  453. X                  Advance to the next scanline.
  454. X                */
  455. X                if (bit != 0)
  456. X                  *q++=byte << (8-bit);
  457. X                if ((((image->columns/8)+
  458. X                    (image->columns % 8 ? 1 : 0)) % 2) != 0)
  459. X                  q++;  /* pad scanline */
  460. X                bit=0;
  461. X                byte=0;
  462. X                x=0;
  463. X             }
  464. X          }
  465. X          p++;
  466. X        }
  467. X      }
  468. X  (void) fwrite((char *) sun_pixels,1,(int) sun_header.length,image->file);
  469. X  (void) free((char *) sun_pixels);
  470. X  CloseImage(image);
  471. X  return(True);
  472. }
  473. X
  474. /*
  475. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  476. %                                                                             %
  477. %                                                                             %
  478. %                                                                             %
  479. %   W r i t e T A R G A I m a g e                                             %
  480. %                                                                             %
  481. %                                                                             %
  482. %                                                                             %
  483. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  484. %
  485. %  Function WriteTARGAImage writes a image in the Truevision Targa rasterfile
  486. %  format.
  487. %
  488. %  The format of the WriteTARGAImage routine is:
  489. %
  490. %      status=WriteTARGAImage(image)
  491. %
  492. %  A description of each parameter follows.
  493. %
  494. %    o status: Function WriteTARGAImage return True if the image is written.
  495. %      False is returned is there is a memory shortage or if the image file
  496. %      fails to write.
  497. %
  498. %    o image:  A pointer to a Image structure.
  499. %
  500. %
  501. */
  502. static unsigned int WriteTARGAImage(image)
  503. Image
  504. X  *image;
  505. {
  506. #define TargaColormap 1
  507. #define TargaRGB 2
  508. #define TargaMonochrome 3
  509. #define TargaRLEColormap  9
  510. #define TargaRLERGB  10
  511. #define TargaRLEMonochrome  11
  512. X
  513. X  typedef struct _TargaHeader
  514. X  {
  515. X    unsigned char
  516. X      id_length,
  517. X      colormap_type,
  518. X      image_type;
  519. X
  520. X    unsigned short
  521. X      colormap_index,
  522. X      colormap_length;
  523. X
  524. X    unsigned char
  525. X      colormap_size;
  526. X
  527. X    unsigned short
  528. X      x_origin,
  529. X      y_origin,
  530. X      width,
  531. X      height;
  532. X
  533. X    unsigned char
  534. X      pixel_size,
  535. X      attributes;
  536. X  } TargaHeader;
  537. X
  538. X  int
  539. X    count,
  540. X    runlength;
  541. X
  542. X  register int
  543. X    i,
  544. X    j;
  545. X
  546. X  register RunlengthPacket
  547. X    *p;
  548. X
  549. X  register unsigned char
  550. X    *q,
  551. X    *r;
  552. X
  553. X  TargaHeader
  554. X    targa_header;
  555. X
  556. X  unsigned char
  557. X    *targa_pixels;
  558. X
  559. X  unsigned int
  560. X    grayscale;
  561. X
  562. X  /*
  563. X    Reflect image.
  564. X  */
  565. X  image=ReflectImage(image);
  566. X  if (image == (Image *) NULL)
  567. X    {
  568. X      Warning("unable to open file",image->filename);
  569. X      return(False);
  570. X    }
  571. X  if (image->compression == RunlengthEncodedCompression)
  572. X    CompressImage(image);
  573. X  /*
  574. X    Open output image file.
  575. X  */
  576. X  OpenImage(image,"w");
  577. X  if (image->file == (FILE *) NULL)
  578. X    {
  579. X      Warning("unable to open file",image->filename);
  580. X      return(False);
  581. X    }
  582. X  /*
  583. X    Initialize TARGA raster file header.
  584. X  */
  585. X  targa_header.id_length=0;
  586. X  if (image->comments != (char *) NULL)
  587. X    targa_header.id_length=strlen(image->comments);
  588. X  targa_header.colormap_type=0;
  589. X  targa_header.colormap_index=0;
  590. X  targa_header.colormap_length=0;
  591. X  targa_header.colormap_size=0;
  592. X  targa_header.x_origin=0;
  593. X  targa_header.y_origin=0;
  594. X  targa_header.width=image->columns;
  595. X  targa_header.height=image->rows;
  596. X  targa_header.pixel_size=8;
  597. X  targa_header.attributes=0;
  598. X  grayscale=False;
  599. X  if ((image->class == DirectClass) || (image->colors > 256))
  600. X    {
  601. X      /*
  602. X        Full color TARGA raster.
  603. X      */
  604. X      targa_header.image_type=TargaRGB;
  605. X      if (image->compression == RunlengthEncodedCompression)
  606. X        targa_header.image_type=TargaRLERGB;
  607. X      targa_header.pixel_size=image->alpha ? 32 : 24;
  608. X    }
  609. X  else
  610. X    {
  611. X      /*
  612. X        Determine if image is grayscale.
  613. X      */
  614. X      grayscale=True;
  615. X      for (i=0; i < image->colors; i++)
  616. X        if ((image->colormap[i].red != image->colormap[i].green) ||
  617. X            (image->colormap[i].green != image->colormap[i].blue))
  618. X          {
  619. X            grayscale=False;
  620. X            break;
  621. X          }
  622. X      if ((image->colors > 2) || !grayscale)
  623. X        {
  624. X          /*
  625. X            Colormapped TARGA raster.
  626. X          */
  627. X          targa_header.image_type=TargaColormap;
  628. X          if (image->compression == RunlengthEncodedCompression)
  629. X            targa_header.image_type=TargaRLEColormap;
  630. X          targa_header.colormap_type=1;
  631. X          targa_header.colormap_index=0;
  632. X          targa_header.colormap_length=image->colors;
  633. X          targa_header.colormap_size=24;
  634. X        }
  635. X      else
  636. X        {
  637. X          /*
  638. X            Monochrome TARGA raster.
  639. X          */
  640. X          targa_header.image_type=TargaMonochrome;
  641. X          if (image->compression == RunlengthEncodedCompression)
  642. X            targa_header.image_type=TargaRLEMonochrome;
  643. X        }
  644. X    }
  645. X  /*
  646. X    Write TARGA header.
  647. X  */
  648. X  (void) fputc((char) targa_header.id_length,image->file);
  649. X  (void) fputc((char) targa_header.colormap_type,image->file);
  650. X  (void) fputc((char) targa_header.image_type,image->file);
  651. X  LSBFirstWriteShort(targa_header.colormap_index,image->file);
  652. X  LSBFirstWriteShort(targa_header.colormap_length,image->file);
  653. X  (void) fputc((char) targa_header.colormap_size,image->file);
  654. X  LSBFirstWriteShort(targa_header.x_origin,image->file);
  655. X  LSBFirstWriteShort(targa_header.y_origin,image->file);
  656. X  LSBFirstWriteShort(targa_header.width,image->file);
  657. X  LSBFirstWriteShort(targa_header.height,image->file);
  658. X  (void) fputc((char) targa_header.pixel_size,image->file);
  659. X  (void) fputc((char) targa_header.attributes,image->file);
  660. X  if (image->comments != (char *) NULL)
  661. X    (void) fwrite((char *) image->comments,1,strlen(image->comments),
  662. X      image->file);
  663. X  /*
  664. X    Convert MIFF to TARGA raster pixels.
  665. X  */
  666. X  count=(unsigned int)
  667. X    (targa_header.pixel_size*targa_header.width*targa_header.height) >> 3;
  668. X  if (image->compression == RunlengthEncodedCompression)
  669. X    count+=(count/128)+1;
  670. X  targa_pixels=(unsigned char *) malloc(count*sizeof(unsigned char));
  671. X  if (targa_pixels == (unsigned char *) NULL)
  672. X    {
  673. X      Warning("unable to allocate memory",(char *) NULL);
  674. X      return(False);
  675. X    }
  676. X  p=image->pixels+(image->packets-1);
  677. X  q=targa_pixels;
  678. X  if ((image->class == DirectClass) || (image->colors > 256))
  679. X    {
  680. X      /*
  681. X        Convert DirectClass packet to TARGA RGB pixel.
  682. X      */
  683. X      if (image->compression != RunlengthEncodedCompression)
  684. X        for (i=0; i < image->packets; i++)
  685. X        {
  686. X          for (j=0; j <= (int) p->length; j++)
  687. X          {
  688. X            *q++=p->blue;
  689. X            *q++=p->green;
  690. X            *q++=p->red;
  691. X            if (image->alpha)
  692. X              *q++=p->index;
  693. X          }
  694. X          p--;
  695. X        }
  696. X      else
  697. X        for (i=0; i < image->packets; i++)
  698. X        {
  699. X          runlength=p->length+1;
  700. X          if (runlength > 128)
  701. X            {
  702. X              *q++=0xff;
  703. X              *q++=p->blue;
  704. X              *q++=p->green;
  705. X              *q++=p->red;
  706. X              if (image->alpha)
  707. X                *q++=p->index;
  708. X              runlength-=128;
  709. X            }
  710. X          r=q;
  711. X          *q++=0x80+(runlength-1);
  712. X          *q++=p->blue;
  713. X          *q++=p->green;
  714. X          *q++=p->red;
  715. X          if (image->alpha)
  716. X            *q++=p->index;
  717. X          if (runlength != 1)
  718. X            p--;
  719. X          else
  720. X            {
  721. X              for ( ; i < image->packets; i++)
  722. X              {
  723. X                p--;
  724. X                if ((p->length != 0) || (runlength == 128))
  725. X                  break;
  726. X                *q++=p->blue;
  727. X                *q++=p->green;
  728. X                *q++=p->red;
  729. X                if (image->alpha)
  730. X                  *q++=p->index;
  731. X                runlength++;
  732. X              }
  733. X              *r=runlength-1;
  734. X            }
  735. X        }
  736. X    }
  737. X  else
  738. X    if ((image->colors > 2) || !grayscale)
  739. X      {
  740. X        unsigned char
  741. X          *targa_colormap;
  742. X
  743. X        /*
  744. X          Dump colormap to file (blue, green, red byte order).
  745. X        */
  746. X        targa_colormap=(unsigned char *)
  747. X          malloc(3*targa_header.colormap_length*sizeof(unsigned char));
  748. X        if (targa_colormap == (unsigned char *) NULL)
  749. X          {
  750. X            Warning("unable to allocate memory",(char *) NULL);
  751. X            return(False);
  752. X          }
  753. X        q=targa_colormap;
  754. X        for (i=0; i < image->colors; i++)
  755. X        {
  756. X          *q++=image->colormap[i].blue;
  757. X          *q++=image->colormap[i].green;
  758. X          *q++=image->colormap[i].red;
  759. X        }
  760. X        (void) fwrite((char *) targa_colormap,1,
  761. X          (int) 3*targa_header.colormap_length,image->file);
  762. X        (void) free((char *) targa_colormap);
  763. X        /*
  764. X          Convert PseudoClass packet to TARGA colormapped pixel.
  765. X        */
  766. X        q=targa_pixels;
  767. X        if (image->compression != RunlengthEncodedCompression)
  768. X          for (i=0; i < image->packets; i++)
  769. X          {
  770. X            for (j=0; j <= (int) p->length; j++)
  771. X              *q++=p->index;
  772. X            p--;
  773. X          }
  774. X        else
  775. X          for (i=0; i < image->packets; i++)
  776. X          {
  777. X            runlength=p->length+1;
  778. X            if (runlength > 128)
  779. X              {
  780. X                *q++=0xff;
  781. X                *q++=p->index;
  782. X                runlength-=128;
  783. X              }
  784. X            r=q;
  785. X            *q++=0x80+(runlength-1);
  786. X            *q++=p->index;
  787. X            if (runlength != 1)
  788. X              p--;
  789. X            else
  790. X              {
  791. X                for ( ; i < image->packets; i++)
  792. X                {
  793. X                  p--;
  794. X                  if ((p->length != 0) || (runlength == 128))
  795. X                    break;
  796. X                  *q++=p->index;
  797. X                  runlength++;
  798. X                }
  799. X                *r=runlength-1;
  800. X              }
  801. X          }
  802. X      }
  803. X    else
  804. X      {
  805. X        register unsigned char
  806. X          polarity;
  807. X
  808. X        /*
  809. X          Convert PseudoClass image to a TARGA monochrome image.
  810. X        */
  811. X        polarity=(Intensity(image->colormap[0]) <
  812. X          Intensity(image->colormap[1]) ? 0 : 1);
  813. X        if (image->compression != RunlengthEncodedCompression)
  814. X          for (i=0; i < image->packets; i++)
  815. X          {
  816. X            for (j=0; j <= (int) p->length; j++)
  817. X              *q++=p->index == polarity ? 0 : MaxRGB;
  818. X            p--;
  819. X          }
  820. X        else
  821. X          for (i=0; i < image->packets; i++)
  822. X          {
  823. X            runlength=p->length+1;
  824. X            if (runlength > 128)
  825. X              {
  826. X                *q++=0xff;
  827. X                *q++=p->index == polarity ? 0 : MaxRGB;
  828. X                runlength-=128;
  829. X              }
  830. X            r=q;
  831. X            *q++=0x80+(runlength-1);
  832. X            *q++=p->index == polarity ? 0 : MaxRGB;
  833. X            if (runlength != 1)
  834. X              p--;
  835. X            else
  836. X              {
  837. X                for ( ; i < image->packets; i++)
  838. X                {
  839. X                  p--;
  840. X                  if ((p->length != 0) || (runlength == 128))
  841. X                    break;
  842. X                  *q++=p->index == polarity ? 0 : MaxRGB;
  843. X                  runlength++;
  844. X                }
  845. X                *r=runlength-1;
  846. X              }
  847. X          }
  848. X      }
  849. X  (void) fwrite((char *) targa_pixels,1,(int) (q-targa_pixels),image->file);
  850. X  (void) free((char *) targa_pixels);
  851. X  CloseImage(image);
  852. X  return(True);
  853. }
  854. X
  855. /*
  856. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  857. %                                                                             %
  858. %                                                                             %
  859. %                                                                             %
  860. %   W r i t e T E X T I m a g e                                               %
  861. %                                                                             %
  862. %                                                                             %
  863. %                                                                             %
  864. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  865. %
  866. %  Function WriteTEXTImage writes an image in the TEXT image forma.
  867. %
  868. %  The format of the WriteTEXTImage routine is:
  869. %
  870. %      status=WriteTEXTImage(image)
  871. %
  872. %  A description of each parameter follows.
  873. %
  874. %    o status: Function WriteTEXTImage return True if the image is written.
  875. %      False is returned is there is a memory shortage or if the image file
  876. %      fails to write.
  877. %
  878. %    o image:  A pointer to a Image structure.
  879. %
  880. %
  881. */
  882. static unsigned int WriteTEXTImage(image)
  883. Image
  884. X  *image;
  885. {
  886. X  unsigned int
  887. X    status;
  888. X
  889. X  Warning("Cannot write TEXT images",image->filename);
  890. X  status=WriteMIFFImage(image);
  891. X  return(status);
  892. }
  893. X
  894. #ifdef HasTIFF
  895. #include "tiff.h"
  896. #include "tiffio.h"
  897. /*
  898. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  899. %                                                                             %
  900. %                                                                             %
  901. %                                                                             %
  902. %   W r i t e T I F F I m a g e                                               %
  903. %                                                                             %
  904. %                                                                             %
  905. %                                                                             %
  906. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  907. %
  908. %  Function WriteTIFFImage writes an image in the Tagged image file format.
  909. %
  910. %  The format of the WriteTIFFImage routine is:
  911. %
  912. %      status=WriteTIFFImage(image,verbose)
  913. %
  914. %  A description of each parameter follows:
  915. %
  916. %    o status:  Function WriteTIFFImage return True if the image is written.
  917. %      False is returned is there is of a memory shortage or if the image
  918. %      file cannot be opened for writing.
  919. %
  920. %    o image:  A pointer to a Image structure.
  921. %
  922. %    o verbose:  A value greater than zero prints detailed information about
  923. %      the image.
  924. %
  925. %
  926. */
  927. static unsigned int WriteTIFFImage(image,verbose)
  928. Image
  929. X  *image;
  930. X
  931. unsigned int
  932. X  verbose;
  933. {
  934. X  register RunlengthPacket
  935. X    *p;
  936. X
  937. X  register int
  938. X    i,
  939. X    j,
  940. X    x,
  941. X    y;
  942. X
  943. X  register unsigned char
  944. X    *q;
  945. X
  946. X  TIFF
  947. X    *file;
  948. X
  949. X  unsigned char
  950. X    *scanline;
  951. X
  952. X  unsigned short
  953. X    photometric,
  954. X    rows_per_strip;
  955. X
  956. X  /*
  957. X    Open TIFF file.
  958. X  */
  959. X  file=TIFFOpen(image->filename,"w");
  960. X  if (file == (TIFF *) NULL)
  961. X    return(False);
  962. X  /*
  963. X    Initialize TIFF fields.
  964. X  */
  965. X  TIFFSetField(file,TIFFTAG_DOCUMENTNAME,image->filename);
  966. X  TIFFSetField(file,TIFFTAG_SOFTWARE,"ImageMagick");
  967. X  if (image->comments != (char *) NULL)
  968. X    TIFFSetField(file,TIFFTAG_IMAGEDESCRIPTION,image->comments);
  969. X  if ((image->class == DirectClass) || (image->colors > 256))
  970. X    {
  971. X      photometric=PHOTOMETRIC_RGB;
  972. X      TIFFSetField(file,TIFFTAG_BITSPERSAMPLE,8);
  973. X      TIFFSetField(file,TIFFTAG_SAMPLESPERPIXEL,(image->alpha ? 4 : 3));
  974. X    }
  975. X  else
  976. X    {
  977. X      /*
  978. X        Determine if image is gray scale.
  979. X      */
  980. X      photometric=PHOTOMETRIC_MINISBLACK;
  981. X      for (i=0; i < image->colors; i++)
  982. X        if ((image->colormap[i].red != image->colormap[i].green) ||
  983. X            (image->colormap[i].green != image->colormap[i].blue))
  984. X          {
  985. X            photometric=PHOTOMETRIC_PALETTE;
  986. X            break;
  987. X          }
  988. X      if ((image->colors == 2) && (photometric == PHOTOMETRIC_MINISBLACK))
  989. X        TIFFSetField(file,TIFFTAG_BITSPERSAMPLE,1);
  990. X      else
  991. X        TIFFSetField(file,TIFFTAG_BITSPERSAMPLE,8);
  992. X      TIFFSetField(file,TIFFTAG_SAMPLESPERPIXEL,1);
  993. X    }
  994. X  TIFFSetField(file,TIFFTAG_PHOTOMETRIC,photometric);
  995. X  TIFFSetField(file,TIFFTAG_IMAGELENGTH,image->rows);
  996. X  TIFFSetField(file,TIFFTAG_IMAGEWIDTH,image->columns);
  997. X  TIFFSetField(file,TIFFTAG_FILLORDER,FILLORDER_MSB2LSB);
  998. X  TIFFSetField(file,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT);
  999. X  TIFFSetField(file,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
  1000. X  TIFFSetField(file,TIFFTAG_COMPRESSION,COMPRESSION_LZW);
  1001. X  if (image->compression == NoCompression)
  1002. X    TIFFSetField(file,TIFFTAG_COMPRESSION,COMPRESSION_NONE);
  1003. X  rows_per_strip=8192/TIFFScanlineSize(file);
  1004. X  if (rows_per_strip == 0)
  1005. X    rows_per_strip=1;
  1006. X  TIFFSetField(file,TIFFTAG_ROWSPERSTRIP,rows_per_strip);
  1007. X  scanline=(unsigned char *) malloc(TIFFScanlineSize(file));
  1008. X  if (scanline == (unsigned char *) NULL)
  1009. X    {
  1010. X      Warning("memory allocation error",(char *) NULL);
  1011. X      return(False);
  1012. X    }
  1013. X  p=image->pixels;
  1014. X  q=scanline;
  1015. X  x=0;
  1016. X  y=0;
  1017. X  if (photometric == PHOTOMETRIC_RGB)
  1018. X    for (i=0; i < image->packets; i++)
  1019. X    {
  1020. X      for (j=0; j <= (int) p->length; j++)
  1021. X      {
  1022. X        /*
  1023. X          Convert DirectClass packets to contiguous RGB scanlines.
  1024. X        */
  1025. X        *q++=p->red;
  1026. X        *q++=p->green;
  1027. X        *q++=p->blue;
  1028. X        if (image->alpha)
  1029. X          *q++=(unsigned char) p->index;
  1030. X        x++;
  1031. X        if (x == image->columns)
  1032. X          {
  1033. X            if (TIFFWriteScanline(file,scanline,y,0) < 0)
  1034. X              break;
  1035. X            q=scanline;
  1036. X            x=0;
  1037. X            y++;
  1038. X          }
  1039. X      }
  1040. X      p++;
  1041. X    }
  1042. X  else
  1043. X    if (photometric == PHOTOMETRIC_PALETTE)
  1044. X      {
  1045. X        unsigned short
  1046. X          blue[256],
  1047. X          green[256],
  1048. X          red[256];
  1049. X
  1050. X        /*
  1051. X          Initialize TIFF colormap.
  1052. X        */
  1053. X        for (i=0; i < image->colors; i++)
  1054. X        {
  1055. X          red[i]=(unsigned short)
  1056. X            ((image->colormap[i].red*65535)/(unsigned int) MaxRGB);
  1057. X          green[i]=(unsigned short)
  1058. X            ((image->colormap[i].green*65535)/(unsigned int) MaxRGB);
  1059. X          blue[i]=(unsigned short)
  1060. X            ((image->colormap[i].blue*65535)/(unsigned int) MaxRGB);
  1061. X        }
  1062. X        TIFFSetField(file,TIFFTAG_COLORMAP,red,green,blue);
  1063. X        /*
  1064. X          Convert PseudoClass packets to contiguous colormap indexed scanlines.
  1065. X        */
  1066. X        for (i=0; i < image->packets; i++)
  1067. X        {
  1068. X          for (j=0; j <= (int) p->length; j++)
  1069. X          {
  1070. X            *q++=(unsigned char) p->index;
  1071. X            x++;
  1072. X            if (x == image->columns)
  1073. X              {
  1074. X                if (TIFFWriteScanline(file,scanline,y,0) < 0)
  1075. X                  break;
  1076. X                q=scanline;
  1077. X                x=0;
  1078. X                y++;
  1079. X              }
  1080. X          }
  1081. X          p++;
  1082. X        }
  1083. X      }
  1084. X    else
  1085. X      if (image->colors > 2)
  1086. X        for (i=0; i < image->packets; i++)
  1087. X        {
  1088. X          for (j=0; j <= (int) p->length; j++)
  1089. X          {
  1090. X            /*
  1091. X              Convert PseudoClass packets to contiguous grayscale scanlines.
  1092. X            */
  1093. X            *q++=(unsigned char) image->colormap[p->index].red;
  1094. X            x++;
  1095. X            if (x == image->columns)
  1096. X              {
  1097. X                if (TIFFWriteScanline(file,scanline,y,0) < 0)
  1098. X                  break;
  1099. X                q=scanline;
  1100. X                x=0;
  1101. X                y++;
  1102. X              }
  1103. X          }
  1104. X          p++;
  1105. X        }
  1106. X      else
  1107. X        {
  1108. X          register unsigned char
  1109. X            bit,
  1110. X            byte,
  1111. X            polarity;
  1112. X
  1113. X          /*
  1114. X            Convert PseudoClass packets to contiguous monochrome scanlines.
  1115. X          */
  1116. X          polarity=(Intensity(image->colormap[0]) >
  1117. X            Intensity(image->colormap[1]) ? 0 : 1);
  1118. X          bit=0;
  1119. X          byte=0;
  1120. X          x=0;
  1121. X          for (i=0; i < image->packets; i++)
  1122. X          {
  1123. X            for (j=0; j <= (int) p->length; j++)
  1124. X            {
  1125. X              byte<<=1;
  1126. X              if (p->index == polarity)
  1127. X                byte|=0x01;
  1128. X              bit++;
  1129. X              if (bit == 8)
  1130. X                {
  1131. X                  *q++=byte;
  1132. X                  bit=0;
  1133. X                  byte=0;
  1134. X                }
  1135. X              x++;
  1136. X              if (x == image->columns)
  1137. X                {
  1138. X                  /*
  1139. X                    Advance to the next scanline.
  1140. X                  */
  1141. X                  if (bit != 0)
  1142. X                    *q++=byte << (8-bit);
  1143. X                  if (TIFFWriteScanline(file,scanline,y,0) < 0)
  1144. X                    break;
  1145. X                  q=scanline;
  1146. X                  bit=0;
  1147. X                  byte=0;
  1148. X                  x=0;
  1149. X                  y++;
  1150. X               }
  1151. X            }
  1152. X            p++;
  1153. X          }
  1154. X        }
  1155. X  (void) free((char *) scanline);
  1156. X  (void) TIFFFlushData(file);
  1157. X  if (verbose == True)
  1158. X    TIFFPrintDirectory(file,stderr,False);
  1159. X  (void) TIFFClose(file);
  1160. X  return(True);
  1161. }
  1162. #else
  1163. static unsigned int WriteTIFFImage(image,verbose)
  1164. Image
  1165. X  *image;
  1166. X
  1167. unsigned int
  1168. X  verbose;
  1169. {
  1170. X  unsigned int
  1171. X    status;
  1172. X
  1173. X  Warning("TIFF library is not available",image->filename);
  1174. X  status=WriteMIFFImage(image);
  1175. X  return(status);
  1176. }
  1177. #endif
  1178. X
  1179. /*
  1180. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1181. %                                                                             %
  1182. %                                                                             %
  1183. %                                                                             %
  1184. %   W r i t e V I C A R I m a g e                                             %
  1185. %                                                                             %
  1186. %                                                                             %
  1187. %                                                                             %
  1188. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1189. %
  1190. %  Function WriteVICARImage writes an image in the VICAR rasterfile format.
  1191. %
  1192. %  The format of the WriteVICARImage routine is:
  1193. %
  1194. %      status=WriteVICARImage(image)
  1195. %
  1196. %  A description of each parameter follows.
  1197. %
  1198. %    o status: Function WriteVICARImage return True if the image is written.
  1199. %      False is returned is there is a memory shortage or if the image file
  1200. %      fails to write.
  1201. %
  1202. %    o image:  A pointer to a Image structure.
  1203. %
  1204. %
  1205. */
  1206. static unsigned int WriteVICARImage(image)
  1207. Image
  1208. X  *image;
  1209. {
  1210. X  unsigned int
  1211. X    status;
  1212. X
  1213. X  Warning("Cannot write VICAR images",image->filename);
  1214. X  status=WriteMIFFImage(image);
  1215. X  return(status);
  1216. }
  1217. X
  1218. /*
  1219. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1220. %                                                                             %
  1221. %                                                                             %
  1222. %                                                                             %
  1223. %   W r i t e V I F F I m a g e                                               %
  1224. %                                                                             %
  1225. %                                                                             %
  1226. %                                                                             %
  1227. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1228. %
  1229. %  Function WriteVIFFImage writes an image to a file in the VIFF image format.
  1230. %
  1231. %  The format of the WriteVIFFImage routine is:
  1232. %
  1233. %      status=WriteVIFFImage(image)
  1234. %
  1235. %  A description of each parameter follows.
  1236. %
  1237. %    o status: Function WriteVIFFImage return True if the image is written.
  1238. %      False is returned is there is a memory shortage or if the image file
  1239. %      fails to write.
  1240. %
  1241. %    o image:  A pointer to a Image structure.
  1242. %
  1243. %
  1244. */
  1245. static unsigned int WriteVIFFImage(image)
  1246. Image
  1247. X  *image;
  1248. {
  1249. #define VFF_CM_genericRGB  15
  1250. #define VFF_CM_NONE  0
  1251. #define VFF_DEP_IEEEORDER  0x2
  1252. #define VFF_DES_RAW  0
  1253. #define VFF_LOC_IMPLICIT  1
  1254. #define VFF_MAPTYP_NONE  0
  1255. #define VFF_MAPTYP_1_BYTE  1
  1256. #define VFF_MS_NONE  0
  1257. #define VFF_MS_ONEPERBAND  1
  1258. #define VFF_TYP_BIT  0
  1259. #define VFF_TYP_1_BYTE  1
  1260. X
  1261. X  typedef struct _ViffHeader
  1262. X  {
  1263. X    char
  1264. X      identifier,
  1265. X      file_type,
  1266. X      release,
  1267. X      version,
  1268. X      machine_dependency,
  1269. X      reserve[3],
  1270. X      comment[512];
  1271. X
  1272. X    unsigned long
  1273. X      rows,
  1274. X      columns,
  1275. X      subrows;
  1276. X
  1277. X    long
  1278. X      x_offset,
  1279. X      y_offset;
  1280. X
  1281. X    unsigned int
  1282. X      x_pixel_size,
  1283. X      y_pixel_size;
  1284. X
  1285. X    unsigned long
  1286. X      location_type,
  1287. X      location_dimension,
  1288. X      number_of_images,
  1289. X      number_data_bands,
  1290. X      data_storage_type,
  1291. X      data_encode_scheme,
  1292. X      map_scheme,
  1293. X      map_storage_type,
  1294. X      map_rows,
  1295. X      map_columns,
  1296. X      map_subrows,
  1297. X      map_enable,
  1298. X      maps_per_cycle,
  1299. X      color_space_model;
  1300. X  } ViffHeader;
  1301. X
  1302. X  register int
  1303. X    i,
  1304. X    j;
  1305. X
  1306. X  register RunlengthPacket
  1307. X    *p;
  1308. X
  1309. X  register unsigned char
  1310. X    *q;
  1311. X
  1312. X  unsigned char
  1313. X    buffer[8],
  1314. X    *viff_pixels;
  1315. X
  1316. X  unsigned int
  1317. X    grayscale;
  1318. X
  1319. X  unsigned long
  1320. X    packets;
  1321. X
  1322. X  ViffHeader
  1323. X    viff_header;
  1324. X
  1325. X  /*
  1326. X    Open output image file.
  1327. X  */
  1328. X  OpenImage(image,"w");
  1329. X  if (image->file == (FILE *) NULL)
  1330. X    {
  1331. X      Warning("unable to open file",image->filename);
  1332. X      return(False);
  1333. X    }
  1334. X  /*
  1335. X    Initialize VIFF image structure.
  1336. X  */
  1337. X  viff_header.identifier=(char) 0xab;
  1338. X  viff_header.file_type=1;
  1339. X  viff_header.release=1;
  1340. X  viff_header.version=3;
  1341. X  viff_header.machine_dependency=VFF_DEP_IEEEORDER;  /* IEEE byte ordering */
  1342. X  (void) strcpy(viff_header.comment,"Image created by ImageMagick");
  1343. X  viff_header.rows=image->columns;
  1344. X  viff_header.columns=image->rows;
  1345. X  viff_header.subrows=0;
  1346. X  viff_header.x_offset=(~0);
  1347. X  viff_header.y_offset=(~0);
  1348. X  viff_header.x_pixel_size=0;
  1349. X  viff_header.y_pixel_size=0;
  1350. X  viff_header.location_type=VFF_LOC_IMPLICIT;
  1351. X  viff_header.location_dimension=0;
  1352. X  viff_header.number_of_images=1;
  1353. X  viff_header.data_encode_scheme=VFF_DES_RAW;
  1354. X  viff_header.map_scheme=VFF_MS_NONE;
  1355. X  viff_header.map_storage_type=VFF_MAPTYP_NONE;
  1356. X  viff_header.map_rows=0;
  1357. X  viff_header.map_columns=0;
  1358. X  viff_header.map_subrows=0;
  1359. X  viff_header.map_enable=1;  /* no colormap */
  1360. X  viff_header.maps_per_cycle=0;
  1361. X  grayscale=False;
  1362. X  if ((image->class == DirectClass) || (image->colors > 256))
  1363. X    {
  1364. X      /*
  1365. X        Full color VIFF raster.
  1366. X      */
  1367. X      viff_header.number_data_bands=image->alpha ? 4 : 3;
  1368. X      viff_header.color_space_model=VFF_CM_genericRGB;
  1369. X      viff_header.data_storage_type=VFF_TYP_1_BYTE;
  1370. X      packets=image->columns*image->rows*viff_header.number_data_bands;
  1371. X    }
  1372. X  else
  1373. X    {
  1374. X      /*
  1375. X        Determine if image is grayscale.
  1376. X      */
  1377. X      grayscale=True;
  1378. X      for (i=0; i < image->colors; i++)
  1379. X        if ((image->colormap[i].red != image->colormap[i].green) ||
  1380. X            (image->colormap[i].green != image->colormap[i].blue))
  1381. X          {
  1382. X            grayscale=False;
  1383. X            break;
  1384. X          }
  1385. X      viff_header.number_data_bands=1;
  1386. X      viff_header.color_space_model=VFF_CM_NONE;
  1387. X      viff_header.data_storage_type=VFF_TYP_1_BYTE;
  1388. X      packets=image->columns*image->rows;
  1389. X      if (!grayscale)
  1390. X        {
  1391. X          /*
  1392. X            PsuedoColor VIFF raster.
  1393. X          */
  1394. X          viff_header.map_scheme=VFF_MS_ONEPERBAND;
  1395. X          viff_header.map_storage_type=VFF_MAPTYP_1_BYTE;
  1396. X          viff_header.map_rows=3;
  1397. X          viff_header.map_columns=image->colors;
  1398. X        }
  1399. X      else
  1400. X        if (image->colors <= 2)
  1401. X          {
  1402. X            /*
  1403. X              Monochrome VIFF raster.
  1404. X            */
  1405. X            viff_header.data_storage_type=VFF_TYP_BIT;
  1406. X            packets=((image->columns+7) >> 3)*image->rows;
  1407. X          }
  1408. X    }
  1409. X  /*
  1410. X    Write VIFF image header (pad to 1024 bytes).
  1411. X  */
  1412. X  buffer[0]=viff_header.identifier;
  1413. X  buffer[1]=viff_header.file_type;
  1414. X  buffer[2]=viff_header.release;
  1415. X  buffer[3]=viff_header.version;
  1416. X  buffer[4]=viff_header.machine_dependency;
  1417. X  buffer[5]=viff_header.reserve[0];
  1418. X  buffer[6]=viff_header.reserve[1];
  1419. X  buffer[7]=viff_header.reserve[2];
  1420. X  (void) fwrite((char *) buffer,1,8,image->file);
  1421. X  (void) fwrite((char *) viff_header.comment,1,512,image->file);
  1422. X  MSBFirstWriteLong(viff_header.rows,image->file);
  1423. X  MSBFirstWriteLong(viff_header.columns,image->file);
  1424. X  MSBFirstWriteLong(viff_header.subrows,image->file);
  1425. X  MSBFirstWriteLong((unsigned long) viff_header.x_offset,image->file);
  1426. X  MSBFirstWriteLong((unsigned long) viff_header.y_offset,image->file);
  1427. X  MSBFirstWriteLong((unsigned long) viff_header.x_pixel_size,image->file);
  1428. X  MSBFirstWriteLong((unsigned long) viff_header.y_pixel_size,image->file);
  1429. X  MSBFirstWriteLong(viff_header.location_type,image->file);
  1430. X  MSBFirstWriteLong(viff_header.location_dimension,image->file);
  1431. X  MSBFirstWriteLong(viff_header.number_of_images,image->file);
  1432. X  MSBFirstWriteLong(viff_header.number_data_bands,image->file);
  1433. X  MSBFirstWriteLong(viff_header.data_storage_type,image->file);
  1434. X  MSBFirstWriteLong(viff_header.data_encode_scheme,image->file);
  1435. X  MSBFirstWriteLong(viff_header.map_scheme,image->file);
  1436. X  MSBFirstWriteLong(viff_header.map_storage_type,image->file);
  1437. X  MSBFirstWriteLong(viff_header.map_rows,image->file);
  1438. X  MSBFirstWriteLong(viff_header.map_columns,image->file);
  1439. X  MSBFirstWriteLong(viff_header.map_subrows,image->file);
  1440. X  MSBFirstWriteLong(viff_header.map_enable,image->file);
  1441. X  MSBFirstWriteLong(viff_header.maps_per_cycle,image->file);
  1442. X  MSBFirstWriteLong(viff_header.color_space_model,image->file);
  1443. X  for (i=0; i < 420; i++)
  1444. X    (void) fputc('\0',image->file);
  1445. X  /*
  1446. X    Convert MIFF to VIFF raster pixels.
  1447. X  */
  1448. X  viff_pixels=(unsigned char *) malloc(packets*sizeof(unsigned char));
  1449. X  if (viff_pixels == (unsigned char *) NULL)
  1450. X    {
  1451. X      Warning("unable to allocate memory",(char *) NULL);
  1452. X      return(False);
  1453. X    }
  1454. X  p=image->pixels;
  1455. X  q=viff_pixels;
  1456. X  if ((image->class == DirectClass) || (image->colors > 256))
  1457. X    {
  1458. X      unsigned long
  1459. X        offset;
  1460. X
  1461. X      /*
  1462. X        Convert DirectClass packet to VIFF RGB pixel.
  1463. X      */
  1464. X      offset=image->columns*image->rows;
  1465. X      for (i=0; i < image->packets; i++)
  1466. X      {
  1467. X        for (j=0; j <= (int) p->length; j++)
  1468. X        {
  1469. X          *q=p->red;
  1470. X          *(q+offset)=p->green;
  1471. X          *(q+offset*2)=p->blue;
  1472. X          if (image->alpha)
  1473. X            *(q+offset*3)=(unsigned char) p->index;
  1474. X          q++;
  1475. X        }
  1476. X        p++;
  1477. X      }
  1478. X    }
  1479. X  else
  1480. X    if (image->colors <= 2)
  1481. X      {
  1482. X        register unsigned char
  1483. X          bit,
  1484. X          byte,
  1485. X          polarity;
  1486. X
  1487. X        register int
  1488. X          x;
  1489. X
  1490. X        /*
  1491. X          Convert PseudoClass image to a VIFF monochrome image.
  1492. X        */
  1493. X        polarity=(Intensity(image->colormap[0]) >
  1494. X          Intensity(image->colormap[1]) ? 0 : 1);
  1495. X        x=0;
  1496. X        bit=0;
  1497. X        byte=0;
  1498. X        for (i=0; i < image->packets; i++)
  1499. X        {
  1500. X          for (j=0; j <= (int) p->length; j++)
  1501. X          {
  1502. X            byte>>=1;
  1503. X            if (p->index == polarity)
  1504. X              byte|=0x80;
  1505. X            bit++;
  1506. X            if (bit == 8)
  1507. X              {
  1508. X                *q++=byte;
  1509. X                bit=0;
  1510. X                byte=0;
  1511. X              }
  1512. X            x++;
  1513. X            if (x == image->columns)
  1514. X              {
  1515. X                /*
  1516. X                  Advance to the next scanline.
  1517. X                */
  1518. X                if (bit != 0)
  1519. X                  *q++=byte >> (8-bit);
  1520. X                bit=0;
  1521. X                byte=0;
  1522. X                x=0;
  1523. X             }
  1524. X          }
  1525. X          p++;
  1526. X        }
  1527. X      }
  1528. X    else
  1529. X      if (grayscale)
  1530. X        {
  1531. X          /*
  1532. X            Convert PseudoClass packet to VIFF grayscale pixel.
  1533. X          */
  1534. X          for (i=0; i < image->packets; i++)
  1535. X          {
  1536. X            for (j=0; j <= (int) p->length; j++)
  1537. X              *q++=p->red;
  1538. X            p++;
  1539. X          }
  1540. X        }
  1541. X      else
  1542. X        {
  1543. X          unsigned char
  1544. X            *viff_colormap;
  1545. X
  1546. X          /*
  1547. X            Dump colormap to file.
  1548. X          */
  1549. X          viff_colormap=(unsigned char *)
  1550. X            malloc(image->colors*3*sizeof(unsigned char));
  1551. X          if (viff_colormap == (unsigned char *) NULL)
  1552. X            {
  1553. X              Warning("unable to allocate memory",(char *) NULL);
  1554. X              return(False);
  1555. X            }
  1556. X          q=viff_colormap;
  1557. X          for (i=0; i < image->colors; i++)
  1558. X            *q++=image->colormap[i].red;
  1559. X          for (i=0; i < image->colors; i++)
  1560. X            *q++=image->colormap[i].green;
  1561. X          for (i=0; i < image->colors; i++)
  1562. X            *q++=image->colormap[i].blue;
  1563. X          (void) fwrite((char *) viff_colormap,1,(int) image->colors*3,
  1564. X            image->file);
  1565. X          (void) free((char *) viff_colormap);
  1566. X          /*
  1567. X            Convert PseudoClass packet to VIFF colormapped pixels.
  1568. X          */
  1569. X          q=viff_pixels;
  1570. X          for (i=0; i < image->packets; i++)
  1571. X          {
  1572. X            for (j=0; j <= (int) p->length; j++)
  1573. X              *q++=p->index;
  1574. X            p++;
  1575. X          }
  1576. X        }
  1577. X  (void) fwrite((char *) viff_pixels,1,(int) packets,image->file);
  1578. X  (void) free((char *) viff_pixels);
  1579. X  CloseImage(image);
  1580. X  return(True);
  1581. }
  1582. X
  1583. /*
  1584. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1585. %                                                                             %
  1586. %                                                                             %
  1587. %                                                                             %
  1588. %   W r i t e X I m a g e                                                     %
  1589. %                                                                             %
  1590. %                                                                             %
  1591. %                                                                             %
  1592. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1593. %
  1594. %  Function WriteXImage writes an image to an X server.
  1595. %
  1596. %  The format of the WriteXImage routine is:
  1597. %
  1598. %      status=WriteXImage(image,server_name)
  1599. %
  1600. %  A description of each parameter follows.
  1601. %
  1602. %    o status: Function WriteXCImage return True if the image is written.
  1603. %      False is returned is there is a memory shortage or if the image file
  1604. %      fails to write.
  1605. %
  1606. %    o image:  A pointer to a Image structure.
  1607. %
  1608. %    o server_name:  A pointer to a character string representing the
  1609. %      X server to display the image.
  1610. %
  1611. %
  1612. */
  1613. static unsigned int WriteXImage(image,server_name)
  1614. Image
  1615. X  *image;
  1616. X
  1617. char
  1618. X  *server_name;
  1619. {
  1620. X  Atom
  1621. X    delete_property,
  1622. X    protocols_property;
  1623. X
  1624. X  char
  1625. X    *resource_value;
  1626. X
  1627. X  Display
  1628. X    *display;
  1629. X
  1630. X  register char
  1631. X    *p;
  1632. X
  1633. X  unsigned int
  1634. X    status;
  1635. X
  1636. X  XResourceInfo
  1637. X    resource_info;
  1638. X
  1639. X  XrmDatabase
  1640. X    resource_database,
  1641. X    server_database;
  1642. X
  1643. X  XEvent
  1644. X    event;
  1645. X
  1646. X  XPixelInfo
  1647. X    pixel_info;
  1648. X
  1649. X  XSetWindowAttributes
  1650. X    window_attributes;
  1651. X
  1652. X  XStandardColormap
  1653. X    *map_info;
  1654. X
  1655. X  XTextProperty
  1656. X    window_name;
  1657. X
  1658. X  XVisualInfo
  1659. X    *visual_info;
  1660. X
  1661. X  XWindowInfo
  1662. X    window_info;
  1663. X
  1664. X  /*
  1665. X    Open X server connection.
  1666. X  */
  1667. X  display=XOpenDisplay(server_name);
  1668. X  if (display == (Display *) NULL)
  1669. X    {
  1670. X      Warning("unable to connect to X server",XDisplayName(server_name))
  1671. X      return(False);
  1672. X    }
  1673. X  /*
  1674. X    Initialize resource database.
  1675. X  */
  1676. X  XrmInitialize();
  1677. X  resource_database=XrmGetDatabase(display);
  1678. X  resource_value=XResourceManagerString(display);
  1679. X  if (resource_value == (char *) NULL)
  1680. X    resource_value="";
  1681. X  server_database=XrmGetStringDatabase(resource_value);
  1682. X  XrmMergeDatabases(server_database,&resource_database);
  1683. X  XGetResourceInfo(resource_database,client_name,&resource_info);
  1684. X  /*
  1685. X    Allocate standard colormap.
  1686. X  */
  1687. X  map_info=XAllocStandardColormap();
  1688. X  if (map_info == (XStandardColormap *) NULL)
  1689. X    {
  1690. X      Warning("unable to create standard colormap","memory allocation failed");
  1691. X      XCloseDisplay(display);
  1692. X      return(False);
  1693. X    }
  1694. X  map_info->colormap=(Colormap) NULL;
  1695. X  pixel_info.pixels=(unsigned long *) NULL;
  1696. X  /*
  1697. X    Get the best visual this server supports.
  1698. X  */
  1699. X  visual_info=XBestVisualInfo(display,resource_info.visual_type,
  1700. X    resource_info.map_type,map_info);
  1701. X  if (visual_info == (XVisualInfo *) NULL)
  1702. X    {
  1703. X      Warning("unable to get visual",resource_info.visual_type);
  1704. X      XCloseDisplay(display);
  1705. X      return(False);
  1706. X    }
  1707. X  /*
  1708. X    Initialize Standard Colormap.
  1709. X  */
  1710. X  XMakeStandardColormap(display,visual_info,&resource_info,&pixel_info,
  1711. X    image,map_info);
  1712. X  /*
  1713. X    Create a window to display image.
  1714. X  */
  1715. X  window_attributes.colormap=map_info->colormap;
  1716. X  window_attributes.event_mask=ButtonPressMask | ExposureMask;
  1717. X  window_info.id=XCreateWindow(display,XRootWindow(display,visual_info->screen),
  1718. X    0,0,image->columns,image->rows,resource_info.border_width,
  1719. X    visual_info->depth,InputOutput,visual_info->visual,CWColormap | CWEventMask,
  1720. X    &window_attributes);
  1721. X  if (window_info.id == (Window) NULL)
  1722. X    {
  1723. X      Warning("unable to create X window",(char *) NULL);
  1724. X      XCloseDisplay(display);
  1725. X      return(False);
  1726. X    }
  1727. X  /*
  1728. X    Initialize window info structure.
  1729. X  */
  1730. X  window_info.depth=visual_info->depth;
  1731. X  window_info.screen=visual_info->screen;
  1732. X  window_info.visual_info=visual_info;
  1733. X  window_info.map_info=map_info;
  1734. X  window_info.pixel_info=(&pixel_info);
  1735. X  window_info.cursor=XCreateFontCursor(display,XC_arrow);
  1736. X  window_info.busy_cursor=XCreateFontCursor(display,XC_watch);
  1737. X  if ((window_info.cursor == (Cursor) NULL) ||
  1738. X      (window_info.busy_cursor == (Cursor) NULL))
  1739. X    {
  1740. X      Warning("unable to create cursor",(char *) NULL);
  1741. X      XCloseDisplay(display);
  1742. X      return(False);
  1743. X    }
  1744. X  p=image->filename+strlen(image->filename)-1;
  1745. X  while ((p > image->filename) && (*(p-1) != '/'))
  1746. X    p--;
  1747. X  window_info.name=p;
  1748. X  window_info.geometry=(char *) NULL;
  1749. X  window_info.clip_geometry=(char *) NULL;
  1750. X  window_info.x=0;
  1751. X  window_info.y=0;
  1752. X  window_info.width=image->columns;
  1753. X  window_info.height=image->rows;
  1754. X  window_info.graphic_context=XDefaultGC(display,visual_info->screen);
  1755. X  window_info.ximage=(XImage *) NULL;
  1756. X  window_info.pixmap=(Pixmap) NULL;
  1757. X  /*
  1758. X    Set window properties & protocols.
  1759. X  */
  1760. X  status=XStringListToTextProperty(&window_info.name,1,&window_name);
  1761. X  if (status == 0)
  1762. X    {
  1763. X      Warning("unable to create text property",window_info.name);
  1764. X      XCloseDisplay(display);
  1765. X      return(False);
  1766. X    }
  1767. X  XSetWMProperties(display,window_info.id,&window_name,(XTextProperty *) NULL,
  1768. X    (char **) NULL,0,(XSizeHints *) NULL,(XWMHints *) NULL,(XClassHint *) NULL);
  1769. X  protocols_property=XInternAtom(display,"WM_PROTOCOLS",False);
  1770. X  delete_property=XInternAtom(display,"WM_DELETE_WINDOW",False);
  1771. X  if ((protocols_property != (Atom) NULL) && (delete_property != (Atom) NULL))
  1772. X    XSetWMProtocols(display,window_info.id,&delete_property,1);
  1773. X  /*
  1774. X    Initialize X image.
  1775. X  */
  1776. X  status=XMakeImage(display,&resource_info,&window_info,image,image->columns,
  1777. X    image->rows);
  1778. X  if (status == False)
  1779. X    {
  1780. X      Warning("unable to create X image",(char *) NULL);
  1781. X      XCloseDisplay(display);
  1782. X      return(False);
  1783. X    }
  1784. X  /*
  1785. X    Display image and wait for button press to exit.
  1786. X  */
  1787. X  XMapWindow(display,window_info.id);
  1788. X  for ( ; ; )
  1789. X  {
  1790. X    XNextEvent(display,&event);
  1791. X    if (event.type == ButtonPress)
  1792. X      break;
  1793. X    if (event.type == ClientMessage)
  1794. X      if (event.xclient.message_type == protocols_property)
  1795. SHAR_EOF
  1796. true || echo 'restore of ImageMagick/encode.c failed'
  1797. fi
  1798. echo 'End of ImageMagick part 36'
  1799. echo 'File ImageMagick/encode.c is continued in part 37'
  1800. echo 37 > _shar_seq_.tmp
  1801. exit 0
  1802.  
  1803. exit 0 # Just in case...
  1804. -- 
  1805.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1806. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1807.  "It's intuitively obvious to the |
  1808.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1809.