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

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i090:  imagemagic - X11 image processing and display, Part34/38
  4. Message-ID: <1993Jul14.232237.23439@sparky.sterling.com>
  5. X-Md4-Signature: e04331de8f6948c79caf9b45a170742e
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 23:22:37 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 90
  13. Archive-name: imagemagic/part34
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.34 (part 34 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" != 34; 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. X      return(False);
  40. X    }
  41. X  /*
  42. X    Open output image file.
  43. X  */
  44. X  OpenImage(image,"w");
  45. X  if (image->file == (FILE *) NULL)
  46. X    {
  47. X      Warning("unable to open file",image->filename);
  48. X      return(False);
  49. X    }
  50. X  /*
  51. X    Allocate alpha pixels.
  52. X  */
  53. X  alpha_pixels=(unsigned char *)
  54. X    malloc(image->columns*image->rows*sizeof(unsigned char));
  55. X  if (alpha_pixels == (unsigned char *) NULL)
  56. X    {
  57. X      Warning("unable to allocate memory",(char *) NULL);
  58. X      return(False);
  59. X    }
  60. X  p=image->pixels;
  61. X  q=alpha_pixels;
  62. X  for (i=0; i < image->packets; i++)
  63. X  {
  64. X    for (j=0; j <= ((int) p->length); j++)
  65. X      *q++=(unsigned char) p->index;
  66. X    p++;
  67. X  }
  68. X  (void) fwrite((char *) alpha_pixels,1,(int) (image->columns*image->rows),
  69. X    image->file);
  70. X  (void) free((char *) alpha_pixels);
  71. X  CloseImage(image);
  72. X  return(True);
  73. }
  74. X
  75. /*
  76. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  77. %                                                                             %
  78. %                                                                             %
  79. %                                                                             %
  80. %   W r i t e A V S I m a g e                                                 %
  81. %                                                                             %
  82. %                                                                             %
  83. %                                                                             %
  84. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  85. %
  86. %  Function WriteAVSImage writes an image to a file in AVS X image format.
  87. %
  88. %  The format of the WriteAVSImage routine is:
  89. %
  90. %      status=WriteAVSImage(image)
  91. %
  92. %  A description of each parameter follows.
  93. %
  94. %    o status: Function WriteAVSImage return True if the image is written.
  95. %      False is returned is there is a memory shortage or if the image file
  96. %      fails to write.
  97. %
  98. %    o image:  A pointer to a Image structure.
  99. %
  100. %
  101. */
  102. static unsigned int WriteAVSImage(image)
  103. Image
  104. X  *image;
  105. {
  106. X  typedef struct _AVSHeader
  107. X  {
  108. X    int
  109. X      width,
  110. X      height;
  111. X  } AVSHeader;
  112. X
  113. X  AVSHeader
  114. X    avs_header;
  115. X
  116. X  register int
  117. X    i,
  118. X    j;
  119. X
  120. X  register RunlengthPacket
  121. X    *p;
  122. X
  123. X  register unsigned char
  124. X    *q;
  125. X
  126. X  unsigned char
  127. X    *avs_pixels;
  128. X
  129. X  /*
  130. X    Open output image file.
  131. X  */
  132. X  OpenImage(image,"w");
  133. X  if (image->file == (FILE *) NULL)
  134. X    {
  135. X      Warning("unable to open file",image->filename);
  136. X      return(False);
  137. X    }
  138. X  /*
  139. X    Initialize raster file header.
  140. X  */
  141. X  avs_header.width=image->columns;
  142. X  avs_header.height=image->rows;
  143. X  avs_pixels=(unsigned char *)
  144. X    malloc(4*image->columns*image->rows*sizeof(unsigned char));
  145. X  if (avs_pixels == (unsigned char *) NULL)
  146. X    {
  147. X      Warning("unable to allocate memory",(char *) NULL);
  148. X      return(False);
  149. X    }
  150. X  (void) fwrite((char *) &avs_header,sizeof(AVSHeader),1,image->file);
  151. X  p=image->pixels;
  152. X  q=avs_pixels;
  153. X  for (i=0; i < image->packets; i++)
  154. X  {
  155. X    for (j=0; j <= (int) p->length; j++)
  156. X    {
  157. X      *q++=(unsigned char) (image->alpha ? p->index : 0);
  158. X      *q++=p->red;
  159. X      *q++=p->green;
  160. X      *q++=p->blue;
  161. X    }
  162. X    p++;
  163. X  }
  164. X  (void) fwrite((char *) avs_pixels,4,(int)(image->columns*image->rows),
  165. X    image->file);
  166. X  CloseImage(image);
  167. X  return(True);
  168. }
  169. X
  170. /*
  171. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  172. %                                                                             %
  173. %                                                                             %
  174. %                                                                             %
  175. %   W r i t e B M P I m a g e                                                 %
  176. %                                                                             %
  177. %                                                                             %
  178. %                                                                             %
  179. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  180. %
  181. %  Function WriteBMPImage writes an image in Microsoft Windows bitmap encoded
  182. %  image format.
  183. %
  184. %  The format of the WriteBMPImage routine is:
  185. %
  186. %      status=WriteBMPImage(image)
  187. %
  188. %  A description of each parameter follows.
  189. %
  190. %    o status: Function WriteBMPImage return True if the image is written.
  191. %      False is returned is there is a memory shortage or if the image file
  192. %      fails to write.
  193. %
  194. %    o image:  A pointer to a Image structure.
  195. %
  196. %
  197. */
  198. static unsigned int WriteBMPImage(image)
  199. Image
  200. X  *image;
  201. {
  202. X  typedef struct _BMPHeader
  203. X  {
  204. X    unsigned long
  205. X      file_size;
  206. X
  207. X    unsigned short
  208. X      reserved[2];
  209. X
  210. X    unsigned long
  211. X      offset_bits,
  212. X      size,
  213. X      width,
  214. X      height;
  215. X
  216. X    unsigned short
  217. X      planes,
  218. X      bit_count;
  219. X
  220. X    unsigned long
  221. X      compression,
  222. X      image_size,
  223. X      x_pixels,
  224. X      y_pixels,
  225. X      number_colors,
  226. X      colors_important;
  227. X  } BMPHeader;
  228. X
  229. X  BMPHeader
  230. X    bmp_header;
  231. X
  232. X  register int
  233. X    i,
  234. X    j,
  235. X    x,
  236. X    y;
  237. X
  238. X  register RunlengthPacket
  239. X    *p;
  240. X
  241. X  register unsigned char
  242. X    *q;
  243. X
  244. X  unsigned char
  245. X    *bmp_pixels;
  246. X
  247. X  unsigned int
  248. X    bytes_per_line;
  249. X
  250. X  /*
  251. X    Open output image file.
  252. X  */
  253. X  OpenImage(image,"w");
  254. X  if (image->file == (FILE *) NULL)
  255. X    {
  256. X      Warning("unable to open file",image->filename);
  257. X      return(False);
  258. X    }
  259. X  /*
  260. X    Initialize BMP raster file header.
  261. X  */
  262. X  bmp_header.file_size=14+40;
  263. X  bmp_header.offset_bits=14+40;
  264. X  if ((image->class == DirectClass) || (image->colors > 256))
  265. X    {
  266. X      /*
  267. X        Full color BMP raster.
  268. X      */
  269. X      bmp_header.bit_count=24;
  270. X      bmp_header.number_colors=0;
  271. X    }
  272. X  else
  273. X    {
  274. X      unsigned int
  275. X        grayscale;
  276. X
  277. X      /*
  278. X        Determine if image is grayscale.
  279. X      */
  280. X      grayscale=True;
  281. X      for (i=0; i < image->colors; i++)
  282. X        if ((image->colormap[i].red != image->colormap[i].green) ||
  283. X            (image->colormap[i].green != image->colormap[i].blue))
  284. X          {
  285. X            grayscale=False;
  286. X            break;
  287. X          }
  288. X      if ((image->colors > 2) || !grayscale)
  289. X        bmp_header.bit_count=8;
  290. X      else
  291. X        bmp_header.bit_count=1;
  292. X      bmp_header.file_size+=image->colors*4;
  293. X      bmp_header.offset_bits+=image->colors*4;
  294. X      bmp_header.number_colors=image->colors;
  295. X    }
  296. X  bmp_header.reserved[0]=0;
  297. X  bmp_header.reserved[1]=0;
  298. X  bmp_header.size=40;
  299. X  bmp_header.width=image->columns;
  300. X  bmp_header.height=image->rows;
  301. X  bmp_header.planes=1;
  302. X  bmp_header.compression=0;
  303. X  bytes_per_line=((image->columns*bmp_header.bit_count+31)/32)*4;
  304. X  bmp_header.image_size=bytes_per_line*image->rows;
  305. X  bmp_header.file_size+=bmp_header.image_size;
  306. X  bmp_header.x_pixels=75*39;
  307. X  bmp_header.y_pixels=75*39;
  308. X  bmp_header.colors_important=bmp_header.number_colors;
  309. X  /*
  310. X    Write BMP header.
  311. X  */
  312. X  (void) fwrite("BM",1,2,image->file);
  313. X  LSBFirstWriteLong(bmp_header.file_size,image->file);
  314. X  LSBFirstWriteShort(bmp_header.reserved[0],image->file);
  315. X  LSBFirstWriteShort(bmp_header.reserved[1],image->file);
  316. X  LSBFirstWriteLong(bmp_header.offset_bits,image->file);
  317. X  LSBFirstWriteLong(bmp_header.size,image->file);
  318. X  LSBFirstWriteLong(bmp_header.width,image->file);
  319. X  LSBFirstWriteLong(bmp_header.height,image->file);
  320. X  LSBFirstWriteShort(bmp_header.planes,image->file);
  321. X  LSBFirstWriteShort(bmp_header.bit_count,image->file);
  322. X  LSBFirstWriteLong(bmp_header.compression,image->file);
  323. X  LSBFirstWriteLong(bmp_header.image_size,image->file);
  324. X  LSBFirstWriteLong(bmp_header.x_pixels,image->file);
  325. X  LSBFirstWriteLong(bmp_header.y_pixels,image->file);
  326. X  LSBFirstWriteLong(bmp_header.number_colors,image->file);
  327. X  LSBFirstWriteLong(bmp_header.colors_important,image->file);
  328. X  if (image->class == PseudoClass)
  329. X    {
  330. X      unsigned char
  331. X        *bmp_colormap;
  332. X
  333. X      /*
  334. X        Dump colormap to file.
  335. X      */
  336. X      bmp_colormap=(unsigned char *)
  337. X        malloc(4*image->colors*sizeof(unsigned char));
  338. X      if (bmp_colormap == (unsigned char *) NULL)
  339. X        {
  340. X          Warning("unable to allocate memory",(char *) NULL);
  341. X          return(False);
  342. X        }
  343. X      q=bmp_colormap;
  344. X      for (i=0; i < image->colors; i++)
  345. X      {
  346. X        *q++=image->colormap[i].blue;
  347. X        *q++=image->colormap[i].green;
  348. X        *q++=image->colormap[i].red;
  349. X        q++;
  350. X      }
  351. X      (void) fwrite((char *) bmp_colormap,4,(int) image->colors,image->file);
  352. X      (void) free((char *) bmp_colormap);
  353. X    }
  354. X  /*
  355. X    Convert MIFF to BMP raster pixels.
  356. X  */
  357. X  bmp_pixels=(unsigned char *)
  358. X     malloc(bmp_header.image_size*sizeof(unsigned char));
  359. X  if (bmp_pixels == (unsigned char *) NULL)
  360. X    {
  361. X      Warning("unable to allocate memory",(char *) NULL);
  362. X      return(False);
  363. X    }
  364. X  p=image->pixels;
  365. X  x=0;
  366. X  y=image->rows-1;
  367. X  switch (bmp_header.bit_count)
  368. X  {
  369. X    case 1:
  370. X    {
  371. X      register unsigned char
  372. X        bit,
  373. X        byte,
  374. X        polarity;
  375. X
  376. X      /*
  377. X        Convert PseudoClass image to a BMP monochrome image.
  378. X      */
  379. X      polarity=(Intensity(image->colormap[0]) <
  380. X        Intensity(image->colormap[1]) ? 0 : 1);
  381. X      bit=0;
  382. X      byte=0;
  383. X      q=bmp_pixels+y*bytes_per_line;
  384. X      for (i=0; i < image->packets; i++)
  385. X      {
  386. X        for (j=0; j <= (int) p->length; j++)
  387. X        {
  388. X          byte<<=1;
  389. X          if (p->index == polarity)
  390. X            byte|=0x01;
  391. X          bit++;
  392. X          if (bit == 8)
  393. X            {
  394. X              *q++=byte;
  395. X              bit=0;
  396. X              byte=0;
  397. X            }
  398. X          x++;
  399. X          if (x == image->columns)
  400. X            {
  401. X              /*
  402. X                Advance to the next scanline.
  403. X              */
  404. X              if (bit != 0)
  405. X                *q++=byte << (8-bit);
  406. X              bit=0;
  407. X              byte=0;
  408. X              x=0;
  409. X              y--;
  410. X              q=bmp_pixels+y*bytes_per_line;
  411. X           }
  412. X        }
  413. X        p++;
  414. X      }
  415. X      break;
  416. X    }
  417. X    case 8:
  418. X    {
  419. X      /*
  420. X        Convert PseudoClass packet to BMP pixel.
  421. X      */
  422. X      q=bmp_pixels+y*bytes_per_line;
  423. X      for (i=0; i < image->packets; i++)
  424. X      {
  425. X        for (j=0; j <= (int) p->length; j++)
  426. X        {
  427. X          *q++=p->index;
  428. X          x++;
  429. X          if (x == image->columns)
  430. X            {
  431. X              x=0;
  432. X              y--;
  433. X              q=bmp_pixels+y*bytes_per_line;
  434. X            }
  435. X        }
  436. X        p++;
  437. X      }
  438. X      break;
  439. X    }
  440. X    case 24:
  441. X    {
  442. X      /*
  443. X        Convert DirectClass packet to BMP RGB pixel.
  444. X      */
  445. X      q=bmp_pixels+y*bytes_per_line;
  446. X      for (i=0; i < image->packets; i++)
  447. X      {
  448. X        for (j=0; j <= (int) p->length; j++)
  449. X        {
  450. X          *q++=p->blue;
  451. X          *q++=p->green;
  452. X          *q++=p->red;
  453. X          x++;
  454. X          if (x == image->columns)
  455. X            {
  456. X              x=0;
  457. X              y--;
  458. X              q=bmp_pixels+y*bytes_per_line;
  459. X            }
  460. X        }
  461. X        p++;
  462. X      }
  463. X      break;
  464. X    }
  465. X  }
  466. X  (void) fwrite((char *) bmp_pixels,1,(int) bmp_header.image_size,image->file);
  467. X  (void) free((char *) bmp_pixels);
  468. X  CloseImage(image);
  469. X  return(True);
  470. }
  471. X
  472. /*
  473. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  474. %                                                                             %
  475. %                                                                             %
  476. %                                                                             %
  477. %   W r i t e C M Y K I m a g e                                               %
  478. %                                                                             %
  479. %                                                                             %
  480. %                                                                             %
  481. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  482. %
  483. %  Function WriteCMYKImage writes an image to a file in cyan, magenta,
  484. %  yellow, and black rasterfile format.
  485. %
  486. %  The format of the WriteCMYKImage routine is:
  487. %
  488. %      status=WriteCMYKImage(image,interlace,undercolor_geometry)
  489. %
  490. %  A description of each parameter follows.
  491. %
  492. %    o status: Function WriteCMYKImage return True if the image is written.
  493. %      False is returned is there is a memory shortage or if the image file
  494. %      fails to write.
  495. %
  496. %    o image:  A pointer to a Image structure.
  497. %
  498. %    o interlace:  An unsigned integer that specifies the interlacing
  499. %      scheme.
  500. %
  501. %    o undercolor_geometry: Specifies a pointer to a undercolor geometry
  502. %      string.  The specified undercolor removal and black generation of this
  503. %      geometry string are relative.
  504. %
  505. %
  506. */
  507. static unsigned int WriteCMYKImage(image,interlace,undercolor_geometry)
  508. Image
  509. X  *image;
  510. X
  511. unsigned int
  512. X  interlace;
  513. X
  514. char
  515. X  *undercolor_geometry;
  516. {
  517. X  float
  518. X    black_generation,
  519. X    undercolor;
  520. X
  521. X  register int
  522. X    i,
  523. X    j;
  524. X
  525. X  register RunlengthPacket
  526. X    *p;
  527. X
  528. X  register unsigned char
  529. X    *q;
  530. X
  531. X  unsigned char
  532. X    black,
  533. X    cyan,
  534. X    magenta,
  535. X    *cmyk_pixels,
  536. X    yellow;
  537. X
  538. X  /*
  539. X    Open output image file.
  540. X  */
  541. X  OpenImage(image,"w");
  542. X  if (image->file == (FILE *) NULL)
  543. X    {
  544. X      Warning("unable to open file",image->filename);
  545. X      return(False);
  546. X    }
  547. X  /*
  548. X    Convert MIFF to CMYK raster pixels.
  549. X  */
  550. X  cmyk_pixels=(unsigned char *)
  551. X    malloc(4*image->columns*image->rows*sizeof(unsigned char));
  552. X  if (cmyk_pixels == (unsigned char *) NULL)
  553. X    {
  554. X      Warning("unable to allocate memory",(char *) NULL);
  555. X      return(False);
  556. X    }
  557. X  undercolor=1.0;
  558. X  black_generation=0.0;
  559. X  if (undercolor_geometry != (char *) NULL)
  560. X    {
  561. X      (void) sscanf(undercolor_geometry,"%fx%f",&undercolor,&black_generation);
  562. X      if (black_generation == 0.0)
  563. X        black_generation=undercolor;
  564. X    }
  565. X  q=cmyk_pixels;
  566. X  switch (interlace)
  567. X  {
  568. X    case NoneInterlace:
  569. X    default:
  570. X    {
  571. X      /*
  572. X        No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
  573. X      */
  574. X      p=image->pixels;
  575. X      for (i=0; i < image->packets; i++)
  576. X      {
  577. X        for (j=0; j <= ((int) p->length); j++)
  578. X        {
  579. X          cyan=MaxRGB-p->red;
  580. X          magenta=MaxRGB-p->green;
  581. X          yellow=MaxRGB-p->blue;
  582. X          black=cyan;
  583. X          if (magenta < black)
  584. X            black=magenta;
  585. X          if (yellow < black)
  586. X            black=yellow;
  587. X          *q++=cyan-undercolor*black;
  588. X          *q++=magenta-undercolor*black;
  589. X          *q++=yellow-undercolor*black;
  590. X          *q++=black_generation*black;
  591. X        }
  592. X        p++;
  593. X      }
  594. X      break;
  595. X    }
  596. X    case LineInterlace:
  597. X    {
  598. X      register int
  599. X        x,
  600. X        y;
  601. X
  602. X      /*
  603. X        Line interlacing:  CCC...MMM...YYY...CCC...MMM...YYY...
  604. X      */
  605. X      if (!UncompressImage(image))
  606. X        return(False);
  607. X      for (y=0; y < image->rows; y++)
  608. X      {
  609. X        p=image->pixels+(y*image->columns);
  610. X        for (x=0; x < image->columns; x++)
  611. X        {
  612. X          cyan=MaxRGB-p->red;
  613. X          magenta=MaxRGB-p->green;
  614. X          yellow=MaxRGB-p->blue;
  615. X          black=cyan;
  616. X          if (magenta < black)
  617. X            black=magenta;
  618. X          if (yellow < black)
  619. X            black=yellow;
  620. X          *q++=cyan-undercolor*black;
  621. X          p++;
  622. X        }
  623. X        p=image->pixels+(y*image->columns);
  624. X        for (x=0; x < image->columns; x++)
  625. X        {
  626. X          cyan=MaxRGB-p->red;
  627. X          magenta=MaxRGB-p->green;
  628. X          yellow=MaxRGB-p->blue;
  629. X          black=cyan;
  630. X          if (magenta < black)
  631. X            black=magenta;
  632. X          if (yellow < black)
  633. X            black=yellow;
  634. X          *q++=magenta-undercolor*black;
  635. X          p++;
  636. X        }
  637. X        p=image->pixels+(y*image->columns);
  638. X        for (x=0; x < image->columns; x++)
  639. X        {
  640. X          cyan=MaxRGB-p->red;
  641. X          magenta=MaxRGB-p->green;
  642. X          yellow=MaxRGB-p->blue;
  643. X          black=cyan;
  644. X          if (magenta < black)
  645. X            black=magenta;
  646. X          if (yellow < black)
  647. X            black=yellow;
  648. X          *q++=yellow-undercolor*black;
  649. X          p++;
  650. X        }
  651. X        p=image->pixels+(y*image->columns);
  652. X        for (x=0; x < image->columns; x++)
  653. X        {
  654. X          cyan=MaxRGB-p->red;
  655. X          magenta=MaxRGB-p->green;
  656. X          yellow=MaxRGB-p->blue;
  657. X          black=cyan;
  658. X          if (magenta < black)
  659. X            black=magenta;
  660. X          if (yellow < black)
  661. X            black=yellow;
  662. X          *q++=black_generation*black;
  663. X          p++;
  664. X        }
  665. X      }
  666. X      break;
  667. X    }
  668. X    case PlaneInterlace:
  669. X    {
  670. X      /*
  671. X        Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
  672. X      */
  673. X      p=image->pixels;
  674. X      for (i=0; i < image->packets; i++)
  675. X      {
  676. X        for (j=0; j <= ((int) p->length); j++)
  677. X        {
  678. X          cyan=MaxRGB-p->red;
  679. X          magenta=MaxRGB-p->green;
  680. X          yellow=MaxRGB-p->blue;
  681. X          black=cyan;
  682. X          if (magenta < black)
  683. X            black=magenta;
  684. X          if (yellow < black)
  685. X            black=yellow;
  686. X          *q++=cyan-undercolor*black;
  687. X        }
  688. X        p++;
  689. X      }
  690. X      p=image->pixels;
  691. X      for (i=0; i < image->packets; i++)
  692. X      {
  693. X        for (j=0; j <= ((int) p->length); j++)
  694. X        {
  695. X          cyan=MaxRGB-p->red;
  696. X          magenta=MaxRGB-p->green;
  697. X          yellow=MaxRGB-p->blue;
  698. X          black=cyan;
  699. X          if (magenta < black)
  700. X            black=magenta;
  701. X          if (yellow < black)
  702. X            black=yellow;
  703. X          *q++=magenta-undercolor*black;
  704. X        }
  705. X        p++;
  706. X      }
  707. X      p=image->pixels;
  708. X      for (i=0; i < image->packets; i++)
  709. X      {
  710. X        for (j=0; j <= ((int) p->length); j++)
  711. X        {
  712. X           cyan=MaxRGB-p->red;
  713. X           magenta=MaxRGB-p->green;
  714. X           yellow=MaxRGB-p->blue;
  715. X           black=cyan;
  716. X           if (magenta < black)
  717. X             black=magenta;
  718. X           if (yellow < black)
  719. X             black=yellow;
  720. X           *q++=yellow-undercolor*black;
  721. X        }
  722. X        p++;
  723. X      }
  724. X      p=image->pixels;
  725. X      for (i=0; i < image->packets; i++)
  726. X      {
  727. X        for (j=0; j <= ((int) p->length); j++)
  728. X        {
  729. X          cyan=MaxRGB-p->red;
  730. X          magenta=MaxRGB-p->green;
  731. X          yellow=MaxRGB-p->blue;
  732. X          black=cyan;
  733. X          if (magenta < black)
  734. X            black=magenta;
  735. X          if (yellow < black)
  736. X            black=yellow;
  737. X          *q++=black_generation*black;
  738. X        }
  739. X        p++;
  740. X      }
  741. X      break;
  742. X    }
  743. X  }
  744. X  (void) fwrite((char *) cmyk_pixels,4,(int) (image->columns*image->rows),
  745. X    image->file);
  746. X  (void) free((char *) cmyk_pixels);
  747. X  CloseImage(image);
  748. X  return(True);
  749. }
  750. X
  751. /*
  752. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  753. %                                                                             %
  754. %                                                                             %
  755. %                                                                             %
  756. %   W r i t e F A X I m a g e                                                 %
  757. %                                                                             %
  758. %                                                                             %
  759. %                                                                             %
  760. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  761. %
  762. %  Procedure WriteFAXImage writes an image to a file in 1 dimensional Huffman
  763. %  encoded format.
  764. %
  765. %  The format of the WriteFAXImage routine is:
  766. %
  767. %      status=WriteFAXImage(image)
  768. %
  769. %  A description of each parameter follows.
  770. %
  771. %    o status: Function WriteFAXImage return True if the image is written.
  772. %      False is returned is there is a memory shortage or if the image file
  773. %      fails to write.
  774. %
  775. %    o image:  A pointer to a Image structure.
  776. %
  777. %
  778. */
  779. static unsigned int WriteFAXImage(image)
  780. Image
  781. X  *image;
  782. {
  783. X  /*
  784. X    Open output image file.
  785. X  */
  786. X  OpenImage(image,"w");
  787. X  if (image->file == (FILE *) NULL)
  788. X    {
  789. X      Warning("unable to open file",image->filename);
  790. X      return(False);
  791. X    }
  792. X  /*
  793. X    Convert MIFF to monochrome.
  794. X  */
  795. X  QuantizeImage(image,2,8,False,GRAYColorspace,True);
  796. X  (void) HuffmanEncodeImage(image);
  797. X  CloseImage(image);
  798. X  return(True);
  799. }
  800. X
  801. /*
  802. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  803. %                                                                             %
  804. %                                                                             %
  805. %                                                                             %
  806. %   W r i t e G I F I m a g e                                                 %
  807. %                                                                             %
  808. %                                                                             %
  809. %                                                                             %
  810. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  811. %
  812. %  Function WriteGIFImage writes an image to a file in the Compuserve Graphics
  813. %  image format.
  814. %
  815. %  The format of the WriteGIFImage routine is:
  816. %
  817. %      status=WriteGIFImage(image)
  818. %
  819. %  A description of each parameter follows.
  820. %
  821. %    o status: Function WriteGIFImage return True if the image is written.
  822. %      False is returned is there is a memory shortage or if the image file
  823. %      fails to write.
  824. %
  825. %    o image:  A pointer to a Image structure.
  826. %
  827. %
  828. */
  829. static unsigned int WriteGIFImage(image)
  830. Image
  831. X  *image;
  832. {
  833. X  register int
  834. X    i;
  835. X
  836. X  unsigned char
  837. X    bits_per_pixel,
  838. X    buffer[3];
  839. X
  840. X  unsigned int
  841. X    status;
  842. X
  843. X  /*
  844. X    Open output image file.
  845. X  */
  846. X  OpenImage(image,"w");
  847. X  if (image->file == (FILE *) NULL)
  848. X    {
  849. X      Warning("unable to open file",image->filename);
  850. X      return(False);
  851. X    }
  852. X  /*
  853. X    GIF colormap must be 256 entries or less.
  854. X  */
  855. X  if ((image->class == DirectClass) || (image->colors > 256))
  856. X    QuantizeImage(image,256,8,False,RGBColorspace,True);
  857. X  for (bits_per_pixel=1; bits_per_pixel < 8; bits_per_pixel++)
  858. X    if ((1 << bits_per_pixel) >= image->colors)
  859. X      break;
  860. X  /*
  861. X    Write GIF header.
  862. X  */
  863. X  (void) fwrite("GIF87a",1,6,image->file);
  864. X  LSBFirstWriteShort(image->columns,image->file);
  865. X  LSBFirstWriteShort(image->rows,image->file);
  866. X  *buffer=0x80;  /* global colormap */
  867. X  *buffer|=(bits_per_pixel-1) << 4;  /* color resolution */
  868. X  *buffer|=(bits_per_pixel-1);   /* size of global colormap */
  869. X  (void) fputc((char) *buffer,image->file);
  870. X  LSBFirstWriteShort(0,image->file);
  871. X  /*
  872. X    Write colormap.
  873. X  */
  874. X  for (i=0; i < image->colors; i++)
  875. X  {
  876. X    (void) fputc((char) image->colormap[i].red,image->file);
  877. X    (void) fputc((char) image->colormap[i].green,image->file);
  878. X    (void) fputc((char) image->colormap[i].blue,image->file);
  879. X  }
  880. X  buffer[0]=0;
  881. X  buffer[1]=0;
  882. X  buffer[2]=0;
  883. X  for ( ; i < (int) (1 << bits_per_pixel); i++)
  884. X    (void) fwrite((char *) buffer,1,3,image->file);
  885. X  (void) fputc(',',image->file);  /* separator */
  886. X  /*
  887. X    Write the image header.
  888. X  */
  889. X  LSBFirstWriteShort(0,image->file);
  890. X  LSBFirstWriteShort(0,image->file);
  891. X  LSBFirstWriteShort(image->columns,image->file);
  892. X  LSBFirstWriteShort(image->rows,image->file);
  893. X  buffer[0]=0;  /* no interlace */
  894. X  (void) fputc((char) *buffer,image->file);
  895. X  buffer[0]=Max(bits_per_pixel,2);
  896. X  (void) fputc((char) *buffer,image->file);
  897. X  status=LZWEncodeImage(image,Max(bits_per_pixel,2)+1);
  898. X  if (status == False)
  899. X    {
  900. X      Warning("unable to write image","memory allocation failed");
  901. X      return(False);
  902. X    }
  903. X  buffer[0]=0;
  904. X  (void) fputc((char) *buffer,image->file);
  905. X  (void) fputc(';',image->file); /* terminator */
  906. X  CloseImage(image);
  907. X  return(True);
  908. }
  909. X
  910. /*
  911. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  912. %                                                                             %
  913. %                                                                             %
  914. %                                                                             %
  915. %   W r i t e G R A Y I m a g e                                               %
  916. %                                                                             %
  917. %                                                                             %
  918. %                                                                             %
  919. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  920. %
  921. %  Function WriteGRAYImage writes an image to a file as gray scale intensity
  922. %  values [0..255].
  923. %
  924. %  The format of the WriteGRAYImage routine is:
  925. %
  926. %      status=WriteGRAYImage(image)
  927. %
  928. %  A description of each parameter follows.
  929. %
  930. %    o status: Function WriteGRAYImage return True if the image is written.
  931. %      False is returned is there is a memory shortage or if the image file
  932. %      fails to write.
  933. %
  934. %    o image:  A pointer to a Image structure.
  935. %
  936. %
  937. */
  938. static unsigned int WriteGRAYImage(image)
  939. Image
  940. X  *image;
  941. {
  942. X  register int
  943. X    i,
  944. X    j;
  945. X
  946. X  register RunlengthPacket
  947. X    *p;
  948. X
  949. X  register unsigned char
  950. X    *q;
  951. X
  952. X  unsigned char
  953. X    *gray_pixels;
  954. X
  955. X  /*
  956. X    Open output image file.
  957. X  */
  958. X  OpenImage(image,"w");
  959. X  if (image->file == (FILE *) NULL)
  960. X    {
  961. X      Warning("unable to open file",image->filename);
  962. X      return(False);
  963. X    }
  964. X  /*
  965. X    Convert image to gray scale PseudoColor class.
  966. X  */
  967. X  gray_pixels=(unsigned char *)
  968. X    malloc(image->columns*image->rows*sizeof(unsigned char));
  969. X  if (gray_pixels == (unsigned char *) NULL)
  970. X    {
  971. X      Warning("unable to allocate memory",(char *) NULL);
  972. X      return(False);
  973. X    }
  974. X  p=image->pixels;
  975. X  q=gray_pixels;
  976. X  for (i=0; i < image->packets; i++)
  977. X  {
  978. X    for (j=0; j <= ((int) p->length); j++)
  979. X      *q++=Intensity(*p);
  980. X    p++;
  981. X  }
  982. X  (void) fwrite((char *) gray_pixels,1,(int) (image->columns*image->rows),
  983. X    image->file);
  984. X  (void) free((char *) gray_pixels);
  985. X  CloseImage(image);
  986. X  return(True);
  987. }
  988. X
  989. /*
  990. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  991. %                                                                             %
  992. %                                                                             %
  993. %                                                                             %
  994. %   W r i t e H I S T O G R A M I m a g e                                     %
  995. %                                                                             %
  996. %                                                                             %
  997. %                                                                             %
  998. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  999. %
  1000. %  Function WriteHISTOGRAMImage writes an image to a file in HISTOGRAM format.
  1001. %  A list of unique pixel values and the number of times each occurs in the
  1002. %  image is written to the file.
  1003. %
  1004. %  The format of the WriteHISTOGRAMImage routine is:
  1005. %
  1006. %      status=WriteHISTOGRAMImage(image)
  1007. %
  1008. %  A description of each parameter follows.
  1009. %
  1010. %    o status: Function WriteHISTOGRAMImage return True if the image is written.
  1011. %      False is returned is there is a memory shortage or if the image file
  1012. %      fails to write.
  1013. %
  1014. %    o image:  A pointer to a Image structure.
  1015. %
  1016. %
  1017. */
  1018. static unsigned int WriteHISTOGRAMImage(image)
  1019. Image
  1020. X  *image;
  1021. {
  1022. X  /*
  1023. X    Open output image file.
  1024. X  */
  1025. X  OpenImage(image,"w");
  1026. X  if (image->file == (FILE *) NULL)
  1027. X    {
  1028. X      Warning("unable to open file",image->filename);
  1029. X      return(False);
  1030. X    }
  1031. X  (void) NumberColors(image,image->file);
  1032. X  CloseImage(image);
  1033. X  return(True);
  1034. }
  1035. X
  1036. /*
  1037. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1038. %                                                                             %
  1039. %                                                                             %
  1040. %                                                                             %
  1041. %   W r i t e I R I S I m a g e                                               %
  1042. %                                                                             %
  1043. %                                                                             %
  1044. %                                                                             %
  1045. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1046. %
  1047. %  Function WriteIRISImage writes an image in SGI RGB encoded image format.
  1048. %
  1049. %  The format of the WriteIRISImage routine is:
  1050. %
  1051. %      status=WriteIRISImage(image)
  1052. %
  1053. %  A description of each parameter follows.
  1054. %
  1055. %    o status: Function WriteIRISImage return True if the image is written.
  1056. %      False is returned is there is a memory shortage or if the image file
  1057. %      fails to write.
  1058. %
  1059. %    o image:  A pointer to a Image structure.
  1060. %
  1061. %
  1062. */
  1063. X
  1064. static int IRISEncode(pixels,count,packets)
  1065. unsigned char
  1066. X  *pixels;
  1067. X
  1068. int
  1069. X  count;
  1070. X
  1071. unsigned char
  1072. X  *packets;
  1073. {
  1074. X  short
  1075. X    runlength;
  1076. X
  1077. X  unsigned char
  1078. X    *limit,
  1079. X    *mark,
  1080. X    *p,
  1081. X    *q;
  1082. X
  1083. X  p=pixels;
  1084. X  limit=p+count*4;
  1085. X  q=packets;
  1086. X  while (p < limit)
  1087. X  {
  1088. X    mark=p;
  1089. X    p+=8;
  1090. X    while ((p < limit) && ((*(p-8) != *(p-4)) || (*(p-4) != *p)))
  1091. X      p+=4;
  1092. X    p-=8;
  1093. X    count=(p-mark)/4;
  1094. X    while (count)
  1095. X    {
  1096. X      runlength=count > 126 ? 126 : count;
  1097. X      count-=runlength;
  1098. X      *q++=0x80 | runlength;
  1099. X      for ( ; runlength > 0; runlength--)
  1100. X      {
  1101. X        *q++=(*mark);
  1102. X        mark+=4;
  1103. X      }
  1104. X    }
  1105. X    mark=p;
  1106. X    p+=4;
  1107. X    while ((p < limit) && (*p == *mark))
  1108. X      p+=4;
  1109. X    count=(p-mark)/4;
  1110. X    while (count)
  1111. X    {
  1112. X      runlength=count > 126 ? 126 : count;
  1113. X      count-=runlength;
  1114. X      *q++=runlength;
  1115. X      *q++=(*mark);
  1116. X    }
  1117. X  }
  1118. X  *q++=0;
  1119. X  return(q-packets);
  1120. }
  1121. X
  1122. static unsigned int WriteIRISImage(image)
  1123. Image
  1124. X  *image;
  1125. {
  1126. X  typedef struct _IRISHeader
  1127. X  {
  1128. X    unsigned short
  1129. X      magic,
  1130. X      type,
  1131. X      dimension,
  1132. X      columns,
  1133. X      rows,
  1134. X      depth;
  1135. X
  1136. X    unsigned long
  1137. X      minimum_value,
  1138. X      maximum_value;
  1139. X
  1140. X    unsigned char
  1141. X      filler[492];
  1142. X  } IRISHeader;
  1143. X
  1144. X  IRISHeader
  1145. X    iris_header;
  1146. X
  1147. X  register int
  1148. X    i,
  1149. X    j,
  1150. X    x,
  1151. X    y,
  1152. X    z;
  1153. X
  1154. X  register RunlengthPacket
  1155. X    *p;
  1156. X
  1157. X  register unsigned char
  1158. X    *q;
  1159. X
  1160. X  unsigned char
  1161. X    *iris_pixels,
  1162. X    *packets;
  1163. X
  1164. X  /*
  1165. X    Open output image file.
  1166. X  */
  1167. X  OpenImage(image,"w");
  1168. X  if (image->file == (FILE *) NULL)
  1169. X    {
  1170. X      Warning("unable to open file",image->filename);
  1171. X      return(False);
  1172. X    }
  1173. X  /*
  1174. X    Initialize IRIS raster file header.
  1175. X  */
  1176. X  iris_header.magic=0x01DA;
  1177. X  if (image->compression == NoCompression)
  1178. X    iris_header.type=0;
  1179. X  else
  1180. X    iris_header.type=0x0100;
  1181. X  iris_header.type|=(1 & 0x00ff);  /* one byte per pixel */
  1182. X  iris_header.dimension=3;
  1183. X  iris_header.columns=image->columns;
  1184. X  iris_header.rows=image->rows;
  1185. X  iris_header.depth=image->alpha ? 4 : 3;
  1186. X  if ((image->class == PseudoClass) && (image->colors <= 256))
  1187. X    {
  1188. X      unsigned int
  1189. X        grayscale;
  1190. X
  1191. X      /*
  1192. X        Determine if image is grayscale.
  1193. X      */
  1194. X      grayscale=True;
  1195. X      for (i=0; i < image->colors; i++)
  1196. X        if ((image->colormap[i].red != image->colormap[i].green) ||
  1197. X            (image->colormap[i].green != image->colormap[i].blue))
  1198. X          {
  1199. X            grayscale=False;
  1200. X            break;
  1201. X          }
  1202. X      if (grayscale)
  1203. X        {
  1204. X          iris_header.dimension=2;
  1205. X          iris_header.depth=1;
  1206. X        }
  1207. X    }
  1208. X  iris_header.minimum_value=0;
  1209. X  iris_header.maximum_value=MaxRGB;
  1210. X  for (i=0; i < sizeof(iris_header.filler); i++)
  1211. X    iris_header.filler[i]=0;
  1212. X  /*
  1213. X    Write IRIS header.
  1214. X  */
  1215. X  MSBFirstWriteShort(iris_header.magic,image->file);
  1216. X  MSBFirstWriteShort(iris_header.type,image->file);
  1217. X  MSBFirstWriteShort(iris_header.dimension,image->file);
  1218. X  MSBFirstWriteShort(iris_header.columns,image->file);
  1219. X  MSBFirstWriteShort(iris_header.rows,image->file);
  1220. X  MSBFirstWriteShort(iris_header.depth,image->file);
  1221. X  MSBFirstWriteLong(iris_header.minimum_value,image->file);
  1222. X  MSBFirstWriteLong(iris_header.maximum_value,image->file);
  1223. X  (void) fwrite(iris_header.filler,1,sizeof(iris_header.filler),image->file);
  1224. X  /*
  1225. X    Allocate IRIS pixels.
  1226. X  */
  1227. X  iris_pixels=(unsigned char *)
  1228. X    malloc(4*image->columns*image->rows*sizeof(unsigned char));
  1229. X  if (iris_pixels == (unsigned char *) NULL)
  1230. X    {
  1231. X      Warning("memory allocation error",image->filename);
  1232. X      return(False);
  1233. X    }
  1234. X  /*
  1235. X    Convert runlength-encoded packets to uncompressed IRIS pixels.
  1236. X  */
  1237. X  x=0;
  1238. X  y=0;
  1239. X  p=image->pixels;
  1240. X  q=iris_pixels+(iris_header.rows-1)*(iris_header.columns*4);
  1241. X  for (i=0; i < image->packets; i++)
  1242. X  {
  1243. X    for (j=0; j <= ((int) p->length); j++)
  1244. X    {
  1245. X      *q++=p->red;
  1246. X      *q++=p->green;
  1247. X      *q++=p->blue;
  1248. X      *q++=(unsigned char) p->index;
  1249. X      x++;
  1250. X      if (x == image->columns)
  1251. X        {
  1252. X          y++;
  1253. X          q=iris_pixels+((iris_header.rows-1)-y)*(iris_header.columns*4);
  1254. X          x=0;
  1255. X        }
  1256. X    }
  1257. X    p++;
  1258. X  }
  1259. X  if (image->compression == NoCompression)
  1260. X    {
  1261. X      unsigned char
  1262. X        *scanline;
  1263. X
  1264. X      /*
  1265. X        Write uncompressed IRIS pixels.
  1266. X      */
  1267. X      scanline=(unsigned char *)
  1268. X        malloc(iris_header.columns*sizeof(unsigned char));
  1269. X      if (scanline == (unsigned char *) NULL)
  1270. X        {
  1271. X          Warning("memory allocation error",image->filename);
  1272. X          return(False);
  1273. X        }
  1274. X      for (z=0; z < (int) iris_header.depth; z++)
  1275. X      {
  1276. X        q=iris_pixels+z;
  1277. X        for (y=0; y < (int) iris_header.rows; y++)
  1278. X        {
  1279. X          for (x=0; x < (int) iris_header.columns; x++)
  1280. X          {
  1281. X            scanline[x]=(*q);
  1282. X            q+=4;
  1283. X          }
  1284. X          (void) fwrite(scanline,sizeof(unsigned char),iris_header.columns,
  1285. X            image->file);
  1286. X        }
  1287. X      }
  1288. X      (void) free(scanline);
  1289. X    }
  1290. X  else
  1291. X    {
  1292. X      unsigned long
  1293. X        length,
  1294. X        number_packets,
  1295. X        offset,
  1296. X        *offsets,
  1297. X        *runlength;
  1298. X
  1299. X      /*
  1300. X        Convert IRIS uncompressed pixels to runlength-encoded pixels.
  1301. X      */
  1302. X      offsets=(unsigned long *)
  1303. X        malloc(iris_header.rows*iris_header.depth*sizeof(unsigned long));
  1304. X      packets=(unsigned char *)
  1305. X        malloc(4*(2*iris_header.columns+10)*image->rows*sizeof(unsigned char));
  1306. X      runlength=(unsigned long *)
  1307. X        malloc(iris_header.rows*iris_header.depth*sizeof(unsigned long));
  1308. X      if ((offsets == (unsigned long *) NULL) ||
  1309. X          (packets == (unsigned char *) NULL) ||
  1310. X          (runlength == (unsigned long *) NULL))
  1311. X        {
  1312. X          Warning("memory allocation error",image->filename);
  1313. X          return(False);
  1314. X        }
  1315. X      offset=512+
  1316. X        2*(iris_header.rows*iris_header.depth)*sizeof(unsigned long);
  1317. X      number_packets=0;
  1318. X      q=iris_pixels;
  1319. X      for (y=0; y < (int) iris_header.rows; y++)
  1320. X      {
  1321. X        for (z=0; z < (int) iris_header.depth; z++)
  1322. X        {
  1323. X          length=
  1324. X            IRISEncode(q+z,(int) iris_header.columns,packets+number_packets);
  1325. X          number_packets+=length;
  1326. X          offsets[y+z*iris_header.rows]=offset;
  1327. X          runlength[y+z*iris_header.rows]=length;
  1328. X          offset+=length;
  1329. X        }
  1330. X        q+=(iris_header.columns*4);
  1331. X      }
  1332. X      /*
  1333. X        Write out line start and length tables and runlength-encoded pixels.
  1334. X      */
  1335. X      (void) fwrite(offsets,sizeof(unsigned long),
  1336. X        iris_header.rows*iris_header.depth,image->file);
  1337. X      (void) fwrite(runlength,sizeof(unsigned long),
  1338. X        iris_header.rows*iris_header.depth,image->file);
  1339. X      (void) fwrite(packets,sizeof(unsigned char),number_packets,image->file);
  1340. X      /*
  1341. X        Free memory.
  1342. X      */
  1343. X      (void) free(runlength);
  1344. X      (void) free(packets);
  1345. X      (void) free(offsets);
  1346. X    }
  1347. X  (void) free(iris_pixels);
  1348. X  CloseImage(image);
  1349. X  return(True);
  1350. }
  1351. X
  1352. #ifdef HasJPEG
  1353. #undef FREAD
  1354. #undef FWRITE
  1355. #undef const
  1356. #include "jinclude.h"
  1357. static Image
  1358. X  *jpeg_image;
  1359. /*
  1360. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1361. %                                                                             %
  1362. %                                                                             %
  1363. %                                                                             %
  1364. %  W r i t e J P E G I m a g e                                                %
  1365. %                                                                             %
  1366. %                                                                             %
  1367. %                                                                             %
  1368. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1369. %
  1370. %  Function WriteJPEGImage writes a JPEG image file and returns it.  It
  1371. %  allocates the memory necessary for the new Image structure and returns a
  1372. %  pointer to the new image.
  1373. %
  1374. %  The format of the WriteJPEGImage routine is:
  1375. %
  1376. %      status=WriteJPEGImage(image,quality)
  1377. %
  1378. %  A description of each parameter follows:
  1379. %
  1380. %    o status:  Function WriteJPEGImage return True if the image is written.
  1381. %      False is returned is there is of a memory shortage or if the image
  1382. %      file cannot be opened for writing.
  1383. %
  1384. %    o jpeg_image:  A pointer to a Image structure.
  1385. %
  1386. %    o quality:  Specifies quality setting.  Quality is 0 (worst) to 100 (best).
  1387. %
  1388. %
  1389. */
  1390. X
  1391. METHODDEF void JPEGInitializeImage(jpeg_info)
  1392. compress_info_ptr
  1393. X  jpeg_info;
  1394. {
  1395. X  /*
  1396. X    Initialize JPEG image.
  1397. X  */
  1398. X  jpeg_info->image_width=jpeg_image->columns;
  1399. X  jpeg_info->image_height=jpeg_image->rows;
  1400. X  jpeg_info->data_precision=8;
  1401. X  jpeg_info->input_components=3;
  1402. X  jpeg_info->in_color_space=CS_RGB;
  1403. X  if ((jpeg_image->class == PseudoClass) && (jpeg_image->colors <= 256))
  1404. X    {
  1405. X      register int
  1406. X        i;
  1407. X
  1408. X      unsigned int
  1409. X        grayscale;
  1410. X
  1411. X      /*
  1412. X        Determine if jpeg_image is grayscale.
  1413. X      */
  1414. X      grayscale=True;
  1415. X      for (i=0; i < jpeg_image->colors; i++)
  1416. X        if ((jpeg_image->colormap[i].red != jpeg_image->colormap[i].green) ||
  1417. X            (jpeg_image->colormap[i].green != jpeg_image->colormap[i].blue))
  1418. X          {
  1419. X            grayscale=False;
  1420. X            break;
  1421. X          }
  1422. X      if (grayscale)
  1423. X        {
  1424. X          jpeg_info->input_components=1;
  1425. X          jpeg_info->in_color_space=CS_GRAYSCALE;
  1426. X        }
  1427. X    }
  1428. X  jpeg_image->packet=jpeg_image->pixels;
  1429. X  jpeg_image->runlength=jpeg_image->packet->length+1;
  1430. }
  1431. X
  1432. static void JPEGInputTermMethod(jpeg_info)
  1433. compress_info_ptr
  1434. X  jpeg_info;
  1435. {
  1436. }
  1437. X
  1438. static void JPEGWriteGRAY(jpeg_info,pixel_data)
  1439. compress_info_ptr
  1440. X  jpeg_info;
  1441. X
  1442. JSAMPARRAY
  1443. X  pixel_data;
  1444. {
  1445. X  register int
  1446. X    column;
  1447. X
  1448. X  register JSAMPROW
  1449. X    gray;
  1450. X
  1451. X  register RunlengthPacket
  1452. X    *p;
  1453. X
  1454. X  /*
  1455. X    Convert run-length encoded grayscale MIFF packets to JPEG pixels.
  1456. X  */
  1457. X  gray=pixel_data[0];
  1458. X  p=jpeg_image->packet;
  1459. X  for (column=jpeg_info->image_width; column > 0; column--)
  1460. X  {
  1461. X    if (jpeg_image->runlength > 0)
  1462. X      jpeg_image->runlength--;
  1463. X    else
  1464. X      {
  1465. X        p++;
  1466. X        jpeg_image->runlength=p->length;
  1467. X      }
  1468. X    *gray++=(JSAMPLE) p->red;
  1469. X  }
  1470. X  jpeg_image->packet=p;
  1471. }
  1472. X
  1473. static void JPEGWriteRGB(jpeg_info,pixel_data)
  1474. compress_info_ptr
  1475. X  jpeg_info;
  1476. X
  1477. JSAMPARRAY
  1478. X  pixel_data;
  1479. {
  1480. X  register int
  1481. X    column;
  1482. X
  1483. X  register JSAMPROW
  1484. X    blue,
  1485. X    green,
  1486. X    red;
  1487. X
  1488. X  register RunlengthPacket
  1489. X    *p;
  1490. X
  1491. X  /*
  1492. X    Convert run-length encoded MIFF packets to JPEG pixels.
  1493. X  */
  1494. X  red=pixel_data[0];
  1495. X  green=pixel_data[1];
  1496. X  blue=pixel_data[2];
  1497. X  p=jpeg_image->packet;
  1498. X  for (column=jpeg_info->image_width; column > 0; column--)
  1499. X  {
  1500. X    if (jpeg_image->runlength > 0)
  1501. X      jpeg_image->runlength--;
  1502. X    else
  1503. X      {
  1504. X        p++;
  1505. X        jpeg_image->runlength=p->length;
  1506. X      }
  1507. X    *red++=(JSAMPLE) p->red;
  1508. X    *green++=(JSAMPLE) p->green;
  1509. X    *blue++=(JSAMPLE) p->blue;
  1510. X  }
  1511. X  jpeg_image->packet=p;
  1512. }
  1513. X
  1514. static void JPEGSelectMethod(jpeg_info)
  1515. compress_info_ptr
  1516. X  jpeg_info;
  1517. {
  1518. X  jpeg_info->methods->get_input_row=JPEGWriteRGB;
  1519. X  if (jpeg_info->in_color_space == CS_GRAYSCALE)
  1520. X    {
  1521. X      j_monochrome_default(jpeg_info);
  1522. X      jpeg_info->methods->get_input_row=JPEGWriteGRAY;
  1523. X    }
  1524. }
  1525. X
  1526. static unsigned int WriteJPEGImage(image,quality)
  1527. Image
  1528. X  *image;
  1529. X
  1530. unsigned int
  1531. X  quality;
  1532. {
  1533. X  struct Compress_info_struct
  1534. X    jpeg_info;
  1535. X
  1536. X  struct Compress_methods_struct
  1537. X    jpeg_methods;
  1538. X
  1539. X  struct External_methods_struct
  1540. X    external_methods;
  1541. X
  1542. X  /*
  1543. X    Open image file.
  1544. X  */
  1545. X  OpenImage(image,"w");
  1546. X  if (image->file == (FILE *) NULL)
  1547. X    {
  1548. X      Warning("unable to open file",image->filename);
  1549. X      return(False);
  1550. X    }
  1551. X  /*
  1552. X    Initialize the JPEG system-dependent methods.
  1553. X  */
  1554. X  jpeg_image=image;
  1555. X  jpeg_info.methods=(&jpeg_methods);
  1556. X  jpeg_info.emethods=(&external_methods);
  1557. X  jselerror(&external_methods);
  1558. X  jselmemmgr(&external_methods);
  1559. X  jpeg_info.methods->input_init=JPEGInitializeImage;
  1560. X  jpeg_info.methods->input_term=JPEGInputTermMethod;
  1561. X  jpeg_methods.c_ui_method_selection=JPEGSelectMethod;
  1562. X  j_c_defaults(&jpeg_info,quality,False);
  1563. X  jpeg_info.optimize_coding=True;
  1564. X  jpeg_info.restart_in_rows=1;
  1565. X  if ((image->class == PseudoClass) && (image->colors <= 256))
  1566. X    jpeg_info.smoothing_factor=25;
  1567. X  /*
  1568. X    Write a JFIF JPEG file.
  1569. X  */
  1570. X  jpeg_info.input_file=(FILE *) NULL;
  1571. X  jpeg_info.output_file=image->file;
  1572. X  jselwjfif(&jpeg_info);
  1573. X  jpeg_compress(&jpeg_info);
  1574. X  CloseImage(image);
  1575. X  return(True);
  1576. }
  1577. #else
  1578. static unsigned int WriteJPEGImage(image,quality)
  1579. Image
  1580. X  *image;
  1581. X
  1582. unsigned int
  1583. X  quality;
  1584. {
  1585. X  unsigned int
  1586. X    status;
  1587. X
  1588. X  Warning("JPEG library is not available",image->filename);
  1589. X  status=WriteMIFFImage(image);
  1590. X  return(status);
  1591. }
  1592. #endif
  1593. X
  1594. /*
  1595. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1596. %                                                                             %
  1597. %                                                                             %
  1598. %                                                                             %
  1599. %   W r i t e M I F F I m a g e                                               %
  1600. %                                                                             %
  1601. %                                                                             %
  1602. %                                                                             %
  1603. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1604. %
  1605. %  Function WriteMIFFImage writes an image to a file.
  1606. %
  1607. %  The format of the WriteMIFFImage routine is:
  1608. %
  1609. %      status=WriteMIFFImage(image)
  1610. %
  1611. %  A description of each parameter follows:
  1612. %
  1613. %    o status: Function WriteMIFFImage return True if the image is written.
  1614. %      False is returned if there is a memory shortage or if the image file
  1615. %      fails to write.
  1616. %
  1617. %    o image: A pointer to a Image structure.
  1618. %
  1619. %
  1620. */
  1621. static unsigned int WriteMIFFImage(image)
  1622. Image
  1623. X  *image;
  1624. {
  1625. X  register int
  1626. X    i;
  1627. X
  1628. X  unsigned long
  1629. X    packets;
  1630. X
  1631. X  if ((image->class != DirectClass) && (image->class != PseudoClass))
  1632. X    {
  1633. X      Warning("unable to write image","unknown image class");
  1634. X      return(False);
  1635. X    }
  1636. X  if ((image->compression != RunlengthEncodedCompression) &&
  1637. X      (image->compression != QEncodedCompression) &&
  1638. X      (image->compression != NoCompression))
  1639. X    {
  1640. X      Warning("unable to write image","unknown image compression");
  1641. X      return(False);
  1642. X    }
  1643. X  /*
  1644. X    Open output image file.
  1645. X  */
  1646. X  OpenImage(image,"w");
  1647. X  if (image->file == (FILE *) NULL)
  1648. X    {
  1649. X      Warning("unable to open file",image->filename);
  1650. X      return(False);
  1651. X    }
  1652. X  /*
  1653. X    Pack image pixels.
  1654. X  */
  1655. X  if ((image->class == PseudoClass) &&
  1656. X      (image->compression == QEncodedCompression))
  1657. X    image->class=DirectClass;
  1658. X  if (image->compression == RunlengthEncodedCompression)
  1659. X    CompressImage(image);
  1660. X  (void) RunlengthEncodeImage(image);
  1661. X  packets=image->packets;
  1662. X  if (image->compression != RunlengthEncodedCompression)
  1663. X    packets=image->columns*image->rows;
  1664. X  if (image->compression == QEncodedCompression)
  1665. X    {
  1666. X      unsigned char
  1667. X        *compressed_pixels;
  1668. X
  1669. X      /*
  1670. X        Compress image pixels with Q encoding.
  1671. X      */
  1672. X      compressed_pixels=(unsigned char *)
  1673. X        malloc((unsigned int) packets*image->packet_size*sizeof(unsigned char));
  1674. X      if (compressed_pixels == (unsigned char *) NULL)
  1675. X        {
  1676. X          Warning("unable to write image","memory allocation failed");
  1677. X          return(False);
  1678. X        }
  1679. X      packets=QEncodeImage(image->packed_pixels,compressed_pixels,
  1680. X        image->columns*(int) image->packet_size,image->rows);
  1681. X      (void) free((char *) image->packed_pixels);
  1682. X      image->packed_pixels=compressed_pixels;
  1683. X      image->packet_size=1;
  1684. X    }
  1685. X  if (image->class == PseudoClass)
  1686. X    ColormapSignature(image);
  1687. X  /*
  1688. X    Write header to file.
  1689. X  */
  1690. X  if (image->comments != (char *) NULL)
  1691. X    (void) fprintf(image->file,"{%s}\n",image->comments);
  1692. X  (void) fprintf(image->file,"id=ImageMagick\n");
  1693. X  if (image->class == PseudoClass)
  1694. X    (void) fprintf(image->file,"class=PseudoClass  colors=%u  signature=%s\n",
  1695. X      image->colors,image->signature);
  1696. X  else
  1697. X    if (image->alpha)
  1698. X      (void) fprintf(image->file,"class=DirectClass  alpha=True\n");
  1699. X    else
  1700. X      (void) fprintf(image->file,"class=DirectClass\n");
  1701. X  if (image->compression == RunlengthEncodedCompression)
  1702. X    (void) fprintf(image->file,"compression=RunlengthEncoded  packets=%lu\n",
  1703. X      packets);
  1704. X  else
  1705. X    if (image->compression == QEncodedCompression)
  1706. X      (void) fprintf(image->file,"compression=QEncoded  packets=%lu\n",packets);
  1707. X  (void) fprintf(image->file,"columns=%u  rows=%u\n",image->columns,
  1708. X    image->rows);
  1709. X  if (image->scene != 0)
  1710. X    (void) fprintf(image->file,"scene=%u\n",image->scene);
  1711. X  if (image->montage != (char *) NULL)
  1712. X    (void) fprintf(image->file,"montage=%s\n",image->montage);
  1713. X  (void) fprintf(image->file,"\f\n:\n");
  1714. X  if (image->montage != (char *) NULL)
  1715. X    {
  1716. X      /*
  1717. X        Write montage tile directory.
  1718. X      */
  1719. X      if (image->directory != (char *) NULL)
  1720. X        (void) fprintf(image->file,"%s",image->directory);
  1721. X      (void) fputc('\0',image->file);
  1722. X    }
  1723. X  if (image->class == PseudoClass)
  1724. X    {
  1725. X      register unsigned char
  1726. X        *q;
  1727. X
  1728. X      unsigned char
  1729. X        *colormap;
  1730. X
  1731. X      /*
  1732. X        Allocate colormap.
  1733. X      */
  1734. X      colormap=(unsigned char *) malloc(3*image->colors*sizeof(unsigned char));
  1735. X      if (colormap == (unsigned char *) NULL)
  1736. X        {
  1737. X          Warning("unable to write image","memory allocation failed");
  1738. X          return(False);
  1739. X        }
  1740. X      q=colormap;
  1741. X      for (i=0; i < image->colors; i++)
  1742. X      {
  1743. X        *q++=image->colormap[i].red;
  1744. X        *q++=image->colormap[i].green;
  1745. X        *q++=image->colormap[i].blue;
  1746. X      }
  1747. X      /*
  1748. X        Write colormap to file.
  1749. X      */
  1750. X      (void) fwrite((char *) colormap,3,(int) image->colors,image->file);
  1751. X      (void) free((char *) colormap);
  1752. X    }
  1753. X  /*
  1754. X    Write image pixels to file.
  1755. X  */
  1756. X  (void) fwrite((char *) image->packed_pixels,(int) image->packet_size,
  1757. X    (int) packets,image->file);
  1758. X  (void) free((char *) image->packed_pixels);
  1759. X  image->packed_pixels=(unsigned char *) NULL;
  1760. X  CloseImage(image);
  1761. X  return(True);
  1762. }
  1763. X
  1764. /*
  1765. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1766. %                                                                             %
  1767. %                                                                             %
  1768. %                                                                             %
  1769. %   W r i t e M T V I m a g e                                                 %
  1770. %                                                                             %
  1771. %                                                                             %
  1772. %                                                                             %
  1773. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1774. %
  1775. %  Function WriteMTVImage writes an image to a file in red, green, and blue
  1776. %  MTV rasterfile format.
  1777. %
  1778. %  The format of the WriteMTVImage routine is:
  1779. %
  1780. %      status=WriteMTVImage(image)
  1781. %
  1782. %  A description of each parameter follows.
  1783. %
  1784. %    o status: Function WriteMTVImage return True if the image is written.
  1785. %      False is returned is there is a memory shortage or if the image file
  1786. %      fails to write.
  1787. %
  1788. %    o image:  A pointer to a Image structure.
  1789. %
  1790. %
  1791. */
  1792. static unsigned int WriteMTVImage(image)
  1793. Image
  1794. X  *image;
  1795. {
  1796. X  register int
  1797. X    i,
  1798. X    j;
  1799. X
  1800. X  register RunlengthPacket
  1801. X    *p;
  1802. X
  1803. X  register unsigned char
  1804. X    *q;
  1805. X
  1806. X  unsigned char
  1807. X    *mtv_pixels;
  1808. X
  1809. X  /*
  1810. X    Open output image file.
  1811. X  */
  1812. X  OpenImage(image,"w");
  1813. X  if (image->file == (FILE *) NULL)
  1814. X    {
  1815. X      Warning("unable to open file",image->filename);
  1816. X      return(False);
  1817. X    }
  1818. X  /*
  1819. X    Convert MIFF to MTV raster pixels.
  1820. X  */
  1821. X  mtv_pixels=(unsigned char *)
  1822. X    malloc(3*image->columns*image->rows*sizeof(unsigned char));
  1823. X  if (mtv_pixels == (unsigned char *) NULL)
  1824. X    {
  1825. X      Warning("unable to allocate memory",(char *) NULL);
  1826. X      return(False);
  1827. X    }
  1828. X  p=image->pixels;
  1829. X  q=mtv_pixels;
  1830. X  for (i=0; i < image->packets; i++)
  1831. X  {
  1832. X    for (j=0; j <= ((int) p->length); j++)
  1833. X    {
  1834. X      *q++=p->red;
  1835. X      *q++=p->green;
  1836. X      *q++=p->blue;
  1837. X    }
  1838. X    p++;
  1839. X  }
  1840. X  (void) fprintf(image->file,"%u %u\n",image->columns,image->rows);
  1841. X  (void) fwrite((char *) mtv_pixels,3,(int) (image->columns*image->rows),
  1842. X    image->file);
  1843. X  (void) free((char *) mtv_pixels);
  1844. X  CloseImage(image);
  1845. X  return(True);
  1846. }
  1847. X
  1848. /*
  1849. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1850. %                                                                             %
  1851. %                                                                             %
  1852. %                                                                             %
  1853. %   W r i t e P C X I m a g e                                                 %
  1854. %                                                                             %
  1855. SHAR_EOF
  1856. true || echo 'restore of ImageMagick/encode.c failed'
  1857. fi
  1858. echo 'End of ImageMagick part 34'
  1859. echo 'File ImageMagick/encode.c is continued in part 35'
  1860. echo 35 > _shar_seq_.tmp
  1861. exit 0
  1862.  
  1863. exit 0 # Just in case...
  1864. -- 
  1865.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1866. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1867.  "It's intuitively obvious to the |
  1868.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1869.