home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / sources / misc / 4189 < prev    next >
Encoding:
Text File  |  1992-12-14  |  57.5 KB  |  2,078 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: cristy@eplrx7.es.duPont.com (John Cristy)
  4. Subject:  v34i049:  imagemagick - X11 image processing and display v2.2, Part21/26
  5. Message-ID: <1992Dec15.035748.22863@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: ed06e1550203d0f677953f2d588ea2de
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. References: <csm-v34i028=imagemagick.141926@sparky.IMD.Sterling.COM>
  11. Date: Tue, 15 Dec 1992 03:57:48 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 2063
  14.  
  15. Submitted-by: cristy@eplrx7.es.duPont.com (John Cristy)
  16. Posting-number: Volume 34, Issue 49
  17. Archive-name: imagemagick/part21
  18. Environment: UNIX, VMS, X11, SGI, DEC, Cray, Sun, Vax
  19.  
  20. #!/bin/sh
  21. # this is Part.21 (part 21 of a multipart archive)
  22. # do not concatenate these parts, unpack them in order with /bin/sh
  23. # file ImageMagick/alien.c continued
  24. #
  25. if test ! -r _shar_seq_.tmp; then
  26.     echo 'Please unpack part 1 first!'
  27.     exit 1
  28. fi
  29. (read Scheck
  30.  if test "$Scheck" != 21; then
  31.     echo Please unpack part "$Scheck" next!
  32.     exit 1
  33.  else
  34.     exit 0
  35.  fi
  36. ) < _shar_seq_.tmp || exit 1
  37. if test ! -f _shar_wnt_.tmp; then
  38.     echo 'x - still skipping ImageMagick/alien.c'
  39. else
  40. echo 'x - continuing file ImageMagick/alien.c'
  41. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/alien.c' &&
  42. X      DestroyImage(image);
  43. X      return((Image *) NULL);
  44. X    }
  45. X  /*
  46. X    Create linear colormap.
  47. X  */
  48. X  image->class=PseudoClass;
  49. X  image->colors=256;
  50. X  image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  51. X  if (image->colormap == (ColorPacket *) NULL)
  52. X    {
  53. X      Warning("memory allocation error",(char *) NULL);
  54. X      DestroyImage(image);
  55. X      return((Image *) NULL);
  56. X    }
  57. X  for (i=0; i < image->colors; i++)
  58. X  {
  59. X    image->colormap[i].red=(unsigned char) i;
  60. X    image->colormap[i].green=(unsigned char) i;
  61. X    image->colormap[i].blue=(unsigned char) i;
  62. X  }
  63. X  /*
  64. X    Create image.
  65. X  */
  66. X  width=512;
  67. X  height=512;
  68. X  if (alien_info->geometry != (char *) NULL)
  69. X    (void) XParseGeometry(alien_info->geometry,&x,&y,&width,&height);
  70. X  image->columns=width;
  71. X  image->rows=height;
  72. X  image->packets=image->columns*image->rows;
  73. X  gray_pixels=(unsigned char *)
  74. X    malloc((unsigned int) image->packets*sizeof(unsigned char));
  75. X  image->pixels=(RunlengthPacket *)
  76. X    malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  77. X  if ((gray_pixels == (unsigned char *) NULL) ||
  78. X      (image->pixels == (RunlengthPacket *) NULL))
  79. X    {
  80. X      Warning("memory allocation error",(char *) NULL);
  81. X      DestroyImage(image);
  82. X      return((Image *) NULL);
  83. X    }
  84. X  /*
  85. X    Convert raster image to runlength-encoded packets.
  86. X  */
  87. X  (void) ReadData((char *) gray_pixels,1,(int) (image->columns*image->rows),
  88. X    image->file);
  89. X  p=gray_pixels;
  90. X  q=image->pixels;
  91. X  for (i=0; i < (image->columns*image->rows); i++)
  92. X  {
  93. X    index=(*p++);
  94. X    q->red=index;
  95. X    q->green=index;
  96. X    q->blue=index;
  97. X    q->index=(unsigned short) index;
  98. X    q->length=0;
  99. X    q++;
  100. X  }
  101. X  (void) free((char *) gray_pixels);
  102. X  CompressColormap(image);
  103. X  CloseImage(image);
  104. X  return(image);
  105. }
  106. X
  107. #ifdef AlienJPEG
  108. #undef FREAD
  109. #undef FWRITE
  110. #undef const
  111. #include "jinclude.h"
  112. static Image
  113. X  *jpeg_image;
  114. X
  115. /*
  116. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  117. %                                                                             %
  118. %                                                                             %
  119. %                                                                             %
  120. %  R e a d J P E G I m a g e                                                  %
  121. %                                                                             %
  122. %                                                                             %
  123. %                                                                             %
  124. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  125. %
  126. %  Function ReadJPEGImage reads an image file and returns it.  It allocates
  127. %  the memory necessary for the new Image structure and returns a pointer to
  128. %  the new image.
  129. %
  130. %  The format of the ReadJPEGImage routine is:
  131. %
  132. %      image=ReadJPEGImage(alien_info)
  133. %
  134. %  A description of each parameter follows:
  135. %
  136. %    o image:  Function ReadJPEGImage returns a pointer to the image after
  137. %      reading.  A null image is returned if there is a a memory shortage or
  138. %      if the image cannot be read.
  139. %
  140. %    o filename:  Specifies the name of the jpeg_image to read.
  141. %
  142. %
  143. */
  144. X
  145. static void MIFFInitializeImage(jpeg_info)
  146. decompress_info_ptr
  147. X  jpeg_info;
  148. {
  149. X  /*
  150. X    Create jpeg_image.
  151. X  */
  152. X  jpeg_image->columns=jpeg_info->image_width;
  153. X  jpeg_image->rows=jpeg_info->image_height;
  154. X  jpeg_image->packets=jpeg_image->columns*jpeg_image->rows;
  155. X  jpeg_image->pixels=(RunlengthPacket *)
  156. X    malloc(jpeg_image->packets*sizeof(RunlengthPacket));
  157. X  jpeg_image->comments=(char *)
  158. X    malloc((strlen(jpeg_image->filename)+2048)*sizeof(char));
  159. X  if ((jpeg_image->pixels == (RunlengthPacket *) NULL) ||
  160. X      (jpeg_image->comments == (char *) NULL))
  161. X    {
  162. X      Warning("memory allocation error",(char *) NULL);
  163. X      exit(1);
  164. X    }
  165. X  (void) sprintf(jpeg_image->comments,
  166. X    "\n  Imported from JFIF JPEG image:  %s\n",jpeg_image->filename);
  167. X  jpeg_image->packet=jpeg_image->pixels;
  168. }
  169. X
  170. static void MIFFOutputTermMethod(jpeg_info)
  171. decompress_info_ptr
  172. X  jpeg_info;
  173. {
  174. }
  175. X
  176. static void MIFFWriteGRAY(jpeg_info,number_rows,pixel_data)
  177. decompress_info_ptr
  178. X  jpeg_info;
  179. X
  180. int
  181. X  number_rows;
  182. X
  183. JSAMPIMAGE
  184. X  pixel_data;
  185. {
  186. X  register int
  187. X    column,
  188. X    row;
  189. X
  190. X  register JSAMPROW
  191. X    gray;
  192. X
  193. X  register RunlengthPacket
  194. X    *p;
  195. X
  196. X  /*
  197. X    Transfer grayscale JPEG pixel data to MIFF pixels.
  198. X  */
  199. X  p=jpeg_image->packet;
  200. X  for (row=0; row < number_rows; row++)
  201. X  {
  202. X    gray=pixel_data[0][row];
  203. X    for (column=jpeg_info->image_width; column > 0; column--)
  204. X    {
  205. X      p->red=GETJSAMPLE(*gray);
  206. X      p->green=GETJSAMPLE(*gray);
  207. X      p->blue=GETJSAMPLE(*gray);
  208. X      p->index=(unsigned short) GETJSAMPLE(*gray);
  209. X      p->length=0;
  210. X      p++;
  211. X      gray++;
  212. X    }
  213. X  }
  214. X  jpeg_image->packet=p;
  215. }
  216. X
  217. static void MIFFWriteRGB(jpeg_info,number_rows,pixel_data)
  218. decompress_info_ptr
  219. X  jpeg_info;
  220. X
  221. int
  222. X  number_rows;
  223. X
  224. JSAMPIMAGE
  225. X  pixel_data;
  226. {
  227. X  register int
  228. X    column,
  229. X    row;
  230. X
  231. X  register JSAMPROW
  232. X    blue,
  233. X    green,
  234. X    red;
  235. X
  236. X  register RunlengthPacket
  237. X    *p;
  238. X
  239. X  /*
  240. X    Transfer JPEG pixel data to MIFF pixels.
  241. X  */
  242. X  p=jpeg_image->packet;
  243. X  for (row=0; row < number_rows; row++)
  244. X  {
  245. X    red=pixel_data[0][row];
  246. X    green=pixel_data[1][row];
  247. X    blue=pixel_data[2][row];
  248. X    for (column=jpeg_info->image_width; column > 0; column--)
  249. X    {
  250. X      p->red=GETJSAMPLE(*red++);
  251. X      p->green=GETJSAMPLE(*green++);
  252. X      p->blue=GETJSAMPLE(*blue++);
  253. X      p->index=0;
  254. X      p->length=0;
  255. X      p++;
  256. X    }
  257. X  }
  258. X  jpeg_image->packet=p;
  259. }
  260. X
  261. static void MIFFSelectMethod(jpeg_info)
  262. decompress_info_ptr
  263. X  jpeg_info;
  264. {
  265. X  jpeg_info->methods->put_pixel_rows=MIFFWriteRGB;
  266. X  jpeg_info->out_color_space=CS_RGB;
  267. X  if (jpeg_info->jpeg_color_space == CS_GRAYSCALE)
  268. X    {
  269. X      jpeg_info->out_color_space=CS_GRAYSCALE;
  270. X      jpeg_info->methods->put_pixel_rows=MIFFWriteGRAY;
  271. X    }
  272. X  jpeg_info->data_precision=8;
  273. }
  274. X
  275. static Image *ReadJPEGImage(alien_info)
  276. AlienInfo
  277. X  *alien_info;
  278. {
  279. X  struct Decompress_info_struct
  280. X    jpeg_info;
  281. X
  282. X  struct Decompress_methods_struct
  283. X    jpeg_methods;
  284. X
  285. X  struct External_methods_struct
  286. X    external_methods;
  287. X
  288. X  /*
  289. X    Allocate jpeg_image structure.
  290. X  */
  291. X  jpeg_image=AllocateImage("JPEG");
  292. X  if (jpeg_image == (Image *) NULL)
  293. X    return((Image *) NULL);
  294. X  /*
  295. X    Open image file.
  296. X  */
  297. X  (void) strcpy(jpeg_image->filename,alien_info->filename);
  298. X  OpenImage(jpeg_image,"r");
  299. X  if (jpeg_image->file == (FILE *) NULL)
  300. X    {
  301. X      Warning("unable to open file",jpeg_image->filename);
  302. X      DestroyImage(jpeg_image);
  303. X      return((Image *) NULL);
  304. X    }
  305. X  /*
  306. X    Initialize the JPEG system-dependent methods.
  307. X  */
  308. X  jpeg_info.methods=(&jpeg_methods);
  309. X  jpeg_info.emethods=(&external_methods);
  310. X  jselerror(&external_methods);
  311. X  jselmemmgr(&external_methods);
  312. X  jpeg_info.methods->output_init=MIFFInitializeImage;
  313. X  jpeg_info.methods->output_term=MIFFOutputTermMethod;
  314. X  jpeg_methods.d_ui_method_selection=MIFFSelectMethod;
  315. X  j_d_defaults(&jpeg_info,True);
  316. X  /*
  317. X    Read a JFIF JPEG file.
  318. X  */
  319. X  jpeg_info.input_file=jpeg_image->file;
  320. X  jpeg_info.output_file=(FILE *) NULL;
  321. X  jselrjfif(&jpeg_info);
  322. X  jpeg_decompress(&jpeg_info);
  323. X  if (jpeg_info.jpeg_color_space == CS_GRAYSCALE)
  324. X    {
  325. X      register int
  326. X        i;
  327. X
  328. X      /*
  329. X        Initialize grayscale colormap.
  330. X      */
  331. X      jpeg_image->class=PseudoClass;
  332. X      jpeg_image->colors=256;
  333. X      jpeg_image->colormap=(ColorPacket *)
  334. X        malloc(jpeg_image->colors*sizeof(ColorPacket));
  335. X      if (jpeg_image->colormap == (ColorPacket *) NULL)
  336. X        {
  337. X          Warning("unable to create image colormap","memory allocation failed");
  338. X          DestroyImage(jpeg_image);
  339. X          return((Image *) NULL);
  340. X        }
  341. X      for (i=0; i < jpeg_image->colors; i++)
  342. X      {
  343. X        jpeg_image->colormap[i].red=(unsigned short) i;
  344. X        jpeg_image->colormap[i].green=(unsigned short) i;
  345. X        jpeg_image->colormap[i].blue=(unsigned short) i;
  346. X      }
  347. X    }
  348. X  CloseImage(jpeg_image);
  349. X  return(jpeg_image);
  350. }
  351. #else
  352. static Image *ReadJPEGImage(alien_info)
  353. AlienInfo
  354. X  *alien_info;
  355. {
  356. X  Warning("JPEG library is not available",alien_info->filename);
  357. X  return(ReadImage(alien_info->filename));
  358. }
  359. #endif
  360. X
  361. /*
  362. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  363. %                                                                             %
  364. %                                                                             %
  365. %                                                                             %
  366. %  R e a d M T V I m a g e                                                    %
  367. %                                                                             %
  368. %                                                                             %
  369. %                                                                             %
  370. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  371. %
  372. %  Function ReadMTVImage reads an image file and returns it.  It allocates
  373. %  the memory necessary for the new Image structure and returns a pointer to
  374. %  the new image.
  375. %
  376. %  The format of the ReadMTVImage routine is:
  377. %
  378. %      image=ReadMTVImage(alien_info)
  379. %
  380. %  A description of each parameter follows:
  381. %
  382. %    o image:  Function ReadMTVImage returns a pointer to the image after
  383. %      reading.  A null image is returned if there is a a memory shortage or
  384. %      if the image cannot be read.
  385. %
  386. %    o alien_info: Specifies a pointer to an AlienInfo structure.
  387. %
  388. %
  389. */
  390. static Image *ReadMTVImage(alien_info)
  391. AlienInfo
  392. X  *alien_info;
  393. {
  394. X  Image
  395. X    *image;
  396. X
  397. X  int
  398. X    count;
  399. X
  400. X  register int
  401. X    i;
  402. X
  403. X  register RunlengthPacket
  404. X    *q;
  405. X
  406. X  register unsigned char
  407. X    *p;
  408. X
  409. X  unsigned char
  410. X    *mtv_pixels;
  411. X
  412. X  unsigned int
  413. X    columns,
  414. X    rows;
  415. X
  416. X  /*
  417. X    Allocate image structure.
  418. X  */
  419. X  image=AllocateImage("MTV");
  420. X  if (image == (Image *) NULL)
  421. X    return((Image *) NULL);
  422. X  /*
  423. X    Open image file.
  424. X  */
  425. X  (void) strcpy(image->filename,alien_info->filename);
  426. X  OpenImage(image,"r");
  427. X  if (image->file == (FILE *) NULL)
  428. X    {
  429. X      Warning("unable to open file",image->filename);
  430. X      DestroyImage(image);
  431. X      return((Image *) NULL);
  432. X    }
  433. X  /*
  434. X    Read MTV image.
  435. X  */
  436. X  count=fscanf(image->file,"%u %u\n",&columns,&rows);
  437. X  if (count == 0)
  438. X    {
  439. X      Warning("not a MTV image,",image->filename);
  440. X      DestroyImage(image);
  441. X      return((Image *) NULL);
  442. X    }
  443. X  do
  444. X  {
  445. X    /*
  446. X      Allocate image pixels.
  447. X    */
  448. X    mtv_pixels=(unsigned char *) malloc(3*columns*rows*sizeof(unsigned char));
  449. X    if (mtv_pixels == (unsigned char *) NULL)
  450. X      {
  451. X        Warning("memory allocation error",(char *) NULL);
  452. X        DestroyImages(image);
  453. X        return((Image *) NULL);
  454. X      }
  455. X    /*
  456. X      Read image pixels.
  457. X    */
  458. X    (void) ReadData((char *) mtv_pixels,1,(int) (columns*rows*3),image->file);
  459. X    /*
  460. X      Create image.
  461. X    */
  462. X    image->columns=columns;
  463. X    image->rows=rows;
  464. X    image->packets=image->columns*image->rows;
  465. X    image->pixels=(RunlengthPacket *)
  466. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  467. X    image->comments=(char *)
  468. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  469. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  470. X        (image->comments == (char *) NULL))
  471. X      {
  472. X        Warning("memory allocation error",(char *) NULL);
  473. X        DestroyImages(image);
  474. X        return((Image *) NULL);
  475. X      }
  476. X    (void) sprintf(image->comments,"\n  Imported from MTV raster image:  %s\n",
  477. X      image->filename);
  478. X    /*
  479. X      Convert MTV raster image to runlength-encoded packets.
  480. X    */
  481. X    p=mtv_pixels;
  482. X    q=image->pixels;
  483. X    for (i=0; i < image->columns*image->rows; i++)
  484. X    {
  485. X      q->red=(*p++);
  486. X      q->green=(*p++);
  487. X      q->blue=(*p++);
  488. X      q->index=0;
  489. X      q->length=0;
  490. X      q++;
  491. X    }
  492. X    (void) free((char *) mtv_pixels);
  493. X    /*
  494. X      Proceed to next image.
  495. X    */
  496. X    count=fscanf(image->file,"%u %u\n",&columns,&rows);
  497. X    if (count > 0)
  498. X      {
  499. X        /*
  500. X          Allocate next image structure.
  501. X        */
  502. X        image->next=AllocateImage("MTV");
  503. X        if (image->next == (Image *) NULL)
  504. X          {
  505. X            DestroyImages(image);
  506. X            return((Image *) NULL);
  507. X          }
  508. X        image->next->file=image->file;
  509. X        (void) sprintf(image->next->filename,"%s.%u\0",alien_info->filename,
  510. X          image->scene+1);
  511. X        image->next->scene=image->scene+1;
  512. X        image->next->last=image;
  513. X        image=image->next;
  514. X      }
  515. X  } while (count > 0);
  516. X  while (image->last != (Image *) NULL)
  517. X    image=image->last;
  518. X  CloseImage(image);
  519. X  return(image);
  520. }
  521. X
  522. /*
  523. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  524. %                                                                             %
  525. %                                                                             %
  526. %                                                                             %
  527. %  R e a d P N M I m a g e                                                    %
  528. %                                                                             %
  529. %                                                                             %
  530. %                                                                             %
  531. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  532. %
  533. %  Function ReadPNMImage reads an image file and returns it.  It allocates
  534. %  the memory necessary for the new Image structure and returns a pointer to
  535. %  the new image.
  536. %
  537. %  The format of the ReadPNMImage routine is:
  538. %
  539. %      image=ReadPNMImage(alien_info)
  540. %
  541. %  A description of each parameter follows:
  542. %
  543. %    o image:  Function ReadPNMImage returns a pointer to the image after
  544. %      reading.  A null image is returned if there is a a memory shortage or
  545. %      if the image cannot be read.
  546. %
  547. %    o alien_info: Specifies a pointer to an AlienInfo structure.
  548. %
  549. %
  550. */
  551. X
  552. static unsigned int GetInteger(file)
  553. FILE
  554. X  *file;
  555. {
  556. X  char
  557. X    c;
  558. X
  559. X  int
  560. X    status;
  561. X
  562. X  unsigned int
  563. X    value;
  564. X
  565. X  /*
  566. X    Skip any leading whitespace.
  567. X  */
  568. X  do
  569. X  {
  570. X    status=ReadData(&c,1,1,file);
  571. X    if (status == False)
  572. X      return(0);
  573. X    if (c == '#')
  574. X      do
  575. X      {
  576. X        /*
  577. X          Skip any comments.
  578. X        */
  579. X        status=ReadData(&c,1,1,file);
  580. X        if (status == False)
  581. X          return(0);
  582. X      } while (c != '\n');
  583. X  } while (!isdigit(c));
  584. X  /*
  585. X    Evaluate number.
  586. X  */
  587. X  value=0;
  588. X  do
  589. X  {
  590. X    value*=10;
  591. X    value+=c-'0';
  592. X    status=ReadData(&c,1,1,file);
  593. X    if (status == False)
  594. X      return(0);
  595. X  }
  596. X  while (isdigit(c));
  597. X  return(value);
  598. }
  599. X
  600. static Image *ReadPNMImage(alien_info)
  601. AlienInfo
  602. X  *alien_info;
  603. {
  604. X  char
  605. X    format;
  606. X
  607. X  Image
  608. X    *image;
  609. X
  610. X  register int
  611. X    i;
  612. X
  613. X  register RunlengthPacket
  614. X    *q;
  615. X
  616. X  register unsigned char
  617. X    *p;
  618. X
  619. X  register unsigned short int
  620. X    index;
  621. X
  622. X  unsigned char
  623. X    *pixels,
  624. X    *scale;
  625. X
  626. X  unsigned int
  627. X    max_value,
  628. X    status;
  629. X
  630. X  /*
  631. X    Allocate image structure.
  632. X  */
  633. X  image=AllocateImage("PNM");
  634. X  if (image == (Image *) NULL)
  635. X    return((Image *) NULL);
  636. X  /*
  637. X    Open image file.
  638. X  */
  639. X  (void) strcpy(image->filename,alien_info->filename);
  640. X  OpenImage(image,"r");
  641. X  if (image->file == (FILE *) NULL)
  642. X    {
  643. X      Warning("unable to open file",image->filename);
  644. X      DestroyImage(image);
  645. X      return((Image *) NULL);
  646. X    }
  647. X  /*
  648. X    Read PNM image.
  649. X  */
  650. X  status=ReadData((char *) &format,1,1,image->file);
  651. X  if ((status == False) || (format != 'P'))
  652. X    {
  653. X      Warning("not a PNM image file",(char *) NULL);
  654. X      DestroyImage(image);
  655. X      return((Image *) NULL);
  656. X    }
  657. X  do
  658. X  {
  659. X    /*
  660. X      Create image.
  661. X    */
  662. X    status=ReadData((char *) &format,1,1,image->file);
  663. X    image->columns=GetInteger(image->file);
  664. X    image->rows=GetInteger(image->file);
  665. X    if ((image->columns*image->rows) == 0)
  666. X      {
  667. X        Warning("unable to read image","image dimensions are zero");
  668. X        return((Image *) NULL);
  669. X      }
  670. X    image->packets=image->columns*image->rows;
  671. X    image->pixels=(RunlengthPacket *)
  672. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  673. X    image->comments=(char *)
  674. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  675. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  676. X        (image->comments == (char *) NULL))
  677. X      {
  678. X        Warning("memory allocation error",(char *) NULL);
  679. X        DestroyImages(image);
  680. X        return((Image *) NULL);
  681. X      }
  682. X    (void) sprintf(image->comments,"\n  Imported from PNM raster image:  %s\n",
  683. X      image->filename);
  684. X    if ((format == '1') || (format == '4'))
  685. X      max_value=1;  /* bitmap */
  686. X    else
  687. X      max_value=GetInteger(image->file);
  688. X    scale=(unsigned char *) NULL;
  689. X    if (max_value > MaxRGB)
  690. X      {
  691. X        /*
  692. X          Compute pixel scaling table.
  693. X        */
  694. X        scale=(unsigned char *) malloc((max_value+1)*sizeof(unsigned char));
  695. X        if (scale == (unsigned char *) NULL)
  696. X          {
  697. X            Warning("unable to read image","memory allocation failed");
  698. X            DestroyImages(image);
  699. X            return((Image *) NULL);
  700. X          }
  701. X        for (i=0; i <= max_value; i++)
  702. X          scale[i]=(unsigned char) ((i*MaxRGB+(max_value >> 1))/max_value);
  703. X      }
  704. X    if ((format != '3') && (format != '6'))
  705. X      {
  706. X        /*
  707. X          Create gray scale colormap.
  708. X        */
  709. X        image->class=PseudoClass;
  710. X        image->colors=Min(max_value,MaxRGB)+1;
  711. X        image->colormap=(ColorPacket *)
  712. X          malloc(image->colors*sizeof(ColorPacket));
  713. X        if (image->colormap == (ColorPacket *) NULL)
  714. X          {
  715. X            Warning("memory allocation error",(char *) NULL);
  716. X            DestroyImages(image);
  717. X            return((Image *) NULL);
  718. X          }
  719. X        for (i=0; i < image->colors; i++)
  720. X        {
  721. X          image->colormap[i].red=(MaxRGB*i)/(image->colors-1);
  722. X          image->colormap[i].green=(MaxRGB*i)/(image->colors-1);
  723. X          image->colormap[i].blue=(MaxRGB*i)/(image->colors-1);
  724. X        }
  725. X      }
  726. X    /*
  727. X      Convert PNM pixels to runlength-encoded MIFF packets.
  728. X    */
  729. X    q=image->pixels;
  730. X    switch (format)
  731. X    {
  732. X      case '1':
  733. X      {
  734. X        /*
  735. X          Convert PBM image to runlength-encoded packets.
  736. X        */
  737. X        for (i=0; i < image->packets; i++)
  738. X        {
  739. X          index=GetInteger(image->file);
  740. X          if (index > 1)
  741. X            index=1;
  742. X          q->red=image->colormap[index].red;
  743. X          q->green=image->colormap[index].green;
  744. X          q->blue=image->colormap[index].blue;
  745. X          q->index=index;
  746. X          q->length=0;
  747. X          q++;
  748. X        }
  749. X        break;
  750. X      }
  751. X      case '2':
  752. X      {
  753. X        /*
  754. X          Convert PGM image to runlength-encoded packets.
  755. X        */
  756. X        if (max_value <= MaxRGB)
  757. X          for (i=0; i < image->packets; i++)
  758. X          {
  759. X            index=GetInteger(image->file);
  760. X            q->red=image->colormap[index].red;
  761. X            q->green=image->colormap[index].green;
  762. X            q->blue=image->colormap[index].blue;
  763. X            q->index=index;
  764. X            q->length=0;
  765. X            q++;
  766. X          }
  767. X        else
  768. X          for (i=0; i < image->packets; i++)
  769. X          {
  770. X            index=scale[GetInteger(image->file)];
  771. X            q->red=image->colormap[index].red;
  772. X            q->green=image->colormap[index].green;
  773. X            q->blue=image->colormap[index].blue;
  774. X            q->index=index;
  775. X            q->index=0;
  776. X            q->length=0;
  777. X            q++;
  778. X          }
  779. X        break;
  780. X      }
  781. X      case '3':
  782. X      {
  783. X        /*
  784. X          Convert PNM image to runlength-encoded packets.
  785. X        */
  786. X        if (max_value <= MaxRGB)
  787. X          for (i=0; i < image->packets; i++)
  788. X          {
  789. X            q->red=GetInteger(image->file);
  790. X            q->green=GetInteger(image->file);
  791. X            q->blue=GetInteger(image->file);
  792. X            q->index=0;
  793. X            q->length=0;
  794. X            q++;
  795. X          }
  796. X        else
  797. X          for (i=0; i < image->packets; i++)
  798. X          {
  799. X            q->red=scale[GetInteger(image->file)];
  800. X            q->green=scale[GetInteger(image->file)];
  801. X            q->blue=scale[GetInteger(image->file)];
  802. X            q->index=0;
  803. X            q->length=0;
  804. X            q++;
  805. X          }
  806. X        break;
  807. X      }
  808. X      case '4':
  809. X      {
  810. X        unsigned char
  811. X          bit,
  812. X          byte;
  813. X
  814. X        unsigned int
  815. X          x,
  816. X          y;
  817. X
  818. X        /*
  819. X          Convert PBM raw image to runlength-encoded packets.
  820. X        */
  821. X        for (y=0; y < image->rows; y++)
  822. X        {
  823. X          bit=0;
  824. X          for (x=0; x < image->columns; x++)
  825. X          {
  826. X            if (bit == 0)
  827. X              (void) ReadData((char *) &byte,1,1,image->file);
  828. X            q->index=(byte & 0x80) ? 0 : 1;
  829. X            byte<<=1;
  830. X            q->red=image->colormap[q->index].red;
  831. X            q->green=image->colormap[q->index].green;
  832. X            q->blue=image->colormap[q->index].blue;
  833. X            q->length=0;
  834. X            q++;
  835. X            bit++;
  836. X            if (bit == 8)
  837. X              bit=0;
  838. X          }
  839. X        }
  840. X        break;
  841. X      }
  842. X      case '5':
  843. X      {
  844. X        /*
  845. X          Convert PGM raw image to runlength-encoded packets.
  846. X        */
  847. X        pixels=(unsigned char *)
  848. X          malloc((unsigned int) image->packets*sizeof(unsigned char));
  849. X        if (pixels == (unsigned char *) NULL)
  850. X          {
  851. X            Warning("memory allocation error",(char *) NULL);
  852. X            DestroyImages(image);
  853. X            return((Image *) NULL);
  854. X          }
  855. X        status=ReadData((char *) pixels,1,(int) image->packets,image->file);
  856. X        if (status == False)
  857. X          {
  858. X            Warning("insufficient image data in file",image->filename);
  859. X            DestroyImages(image);
  860. X            return((Image *) NULL);
  861. X          }
  862. X        /*
  863. X          Convert PNM raw image to runlength-encoded packets.
  864. X        */
  865. X        p=pixels;
  866. X        if (max_value <= MaxRGB)
  867. X          for (i=0; i < image->packets; i++)
  868. X          {
  869. X            index=(*p++);
  870. X            q->red=image->colormap[index].red;
  871. X            q->green=image->colormap[index].green;
  872. X            q->blue=image->colormap[index].blue;
  873. X            q->index=index;
  874. X            q->length=0;
  875. X            q++;
  876. X          }
  877. X        else
  878. X          for (i=0; i < image->packets; i++)
  879. X          {
  880. X            index=scale[*p++];
  881. X            q->red=image->colormap[index].red;
  882. X            q->green=image->colormap[index].green;
  883. X            q->blue=image->colormap[index].blue;
  884. X            q->index=index;
  885. X            q->index=0;
  886. X            q->length=0;
  887. X            q++;
  888. X          }
  889. X        break;
  890. X      }
  891. X      case '6':
  892. X      {
  893. X        /*
  894. X          Convert PNM raster image to runlength-encoded packets.
  895. X        */
  896. X        pixels=(unsigned char *)
  897. X          malloc((unsigned int) image->packets*3*sizeof(unsigned char));
  898. X        if (pixels == (unsigned char *) NULL)
  899. X          {
  900. X            Warning("memory allocation error",(char *) NULL);
  901. X            DestroyImages(image);
  902. X            return((Image *) NULL);
  903. X          }
  904. X        status=ReadData((char *) pixels,1,(int) image->packets*3,image->file);
  905. X        if (status == False)
  906. X          {
  907. X            Warning("insufficient image data in file",image->filename);
  908. X            DestroyImages(image);
  909. X            return((Image *) NULL);
  910. X          }
  911. X        p=pixels;
  912. X        if (max_value <= MaxRGB)
  913. X          for (i=0; i < image->packets; i++)
  914. X          {
  915. X            q->red=(*p++);
  916. X            q->green=(*p++);
  917. X            q->blue=(*p++);
  918. X            q->index=0;
  919. X            q->length=0;
  920. X            q++;
  921. X          }
  922. X        else
  923. X          for (i=0; i < image->packets; i++)
  924. X          {
  925. X            q->red=scale[*p++];
  926. X            q->green=scale[*p++];
  927. X            q->blue=scale[*p++];
  928. X            q->index=0;
  929. X            q->length=0;
  930. X            q++;
  931. X          }
  932. X        break;
  933. X      }
  934. X      default:
  935. X      {
  936. X        Warning("not a PNM image file",(char *) NULL);
  937. X        DestroyImages(image);
  938. X        return((Image *) NULL);
  939. X      }
  940. X    }
  941. X    if (scale != (unsigned char *) NULL)
  942. X      (void) free((char *) scale);
  943. X    if (image->class == PseudoClass)
  944. X      CompressColormap(image);
  945. X    /*
  946. X      Proceed to next image.
  947. X    */
  948. X    status=ReadData((char *) &format,1,1,image->file);
  949. X    if ((status == True) && (format == 'P'))
  950. X      {
  951. X        /*
  952. X          Allocate image structure.
  953. X        */
  954. X        image->next=AllocateImage("PNM");
  955. X        if (image->next == (Image *) NULL)
  956. X          {
  957. X            DestroyImages(image);
  958. X            return((Image *) NULL);
  959. X          }
  960. X        image->next->file=image->file;
  961. X        (void) sprintf(image->next->filename,"%s.%u\0",alien_info->filename,
  962. X          image->scene+1);
  963. X        image->next->scene=image->scene+1;
  964. X        image->next->last=image;
  965. X        image=image->next;
  966. X      }
  967. X  } while ((status == True) && (format == 'P'));
  968. X  while (image->last != (Image *) NULL)
  969. X    image=image->last;
  970. X  CloseImage(image);
  971. X  return(image);
  972. }
  973. X
  974. /*
  975. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  976. %                                                                             %
  977. %                                                                             %
  978. %                                                                             %
  979. %  R e a d P S I m a g e                                                      %
  980. %                                                                             %
  981. %                                                                             %
  982. %                                                                             %
  983. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  984. %
  985. %  Function ReadPSImage reads a Postscript image file and returns it.  It
  986. %  allocates the memory necessary for the new Image structure and returns a
  987. %  pointer to the new image.
  988. %
  989. %  The format of the ReadPSImage routine is:
  990. %
  991. %      image=ReadPSImage(alien_info)
  992. %
  993. %  A description of each parameter follows:
  994. %
  995. %    o image:  Function ReadPSImage returns a pointer to the image after
  996. %      reading.  A null image is returned if there is a a memory shortage or
  997. %      if the image cannot be read.
  998. %
  999. %    o alien_info: Specifies a pointer to an AlienInfo structure.
  1000. %
  1001. %    o density: Specifies a pointer to a image density string;  horizonal
  1002. %      and vertical dots per inch.
  1003. %
  1004. %
  1005. */
  1006. static Image *ReadPSImage(alien_info)
  1007. AlienInfo
  1008. X  *alien_info;
  1009. {
  1010. #define XResolution  72
  1011. #define YResolution  72
  1012. X
  1013. X  char
  1014. X    command[2048],
  1015. X    clip_geometry[2048],
  1016. X    *directory,
  1017. X    filename[2048],
  1018. X    options[2048];
  1019. X
  1020. X  Image
  1021. X    *image,
  1022. X    *next_image;
  1023. X
  1024. X  unsigned int
  1025. X    status;
  1026. X
  1027. X  /*
  1028. X    Allocate image structure.
  1029. X  */
  1030. X  image=AllocateImage("PS");
  1031. X  if (image == (Image *) NULL)
  1032. X    return((Image *) NULL);
  1033. X  /*
  1034. X    Open image file.
  1035. X  */
  1036. X  (void) strcpy(image->filename,alien_info->filename);
  1037. X  OpenImage(image,"r");
  1038. X  if (image->file == (FILE *) NULL)
  1039. X    {
  1040. X      Warning("unable to open file",image->filename);
  1041. X      DestroyImage(image);
  1042. X      return((Image *) NULL);
  1043. X    }
  1044. X  /*
  1045. X    Determine if Postscript specifies a bounding box.
  1046. X  */
  1047. X  *clip_geometry='\0';
  1048. X  while (fgets(command,sizeof(command)-1,image->file) != (char *) NULL)
  1049. X    if (strncmp("%%BoundingBox:",command,strlen("%%BoundingBox:")) == 0)
  1050. X      {
  1051. X        int
  1052. X          count,
  1053. X          lower_x,
  1054. X          lower_y,
  1055. X          upper_x,
  1056. X          upper_y,
  1057. X          x,
  1058. X          y;
  1059. X
  1060. X        unsigned int
  1061. X          x_resolution,
  1062. X          y_resolution;
  1063. X
  1064. X        count=sscanf(command,"%%%%BoundingBox: %d %d %d %d",&lower_x,&lower_y,
  1065. X          &upper_x,&upper_y);
  1066. X        if (count != 4)
  1067. X          break;
  1068. X        /*
  1069. X          Set clip geometry as specified by the bounding box.
  1070. X        */
  1071. X        x_resolution=XResolution;
  1072. X        y_resolution=YResolution;
  1073. X        if (alien_info->density != (char *) NULL)
  1074. X          {
  1075. X            int
  1076. X              flags;
  1077. X
  1078. X            /*
  1079. X              User specified density.
  1080. X            */
  1081. X            flags=XParseGeometry(alien_info->density,&x,&y,&x_resolution,
  1082. X              &y_resolution);
  1083. X            if ((flags & WidthValue) == 0)
  1084. X              x_resolution=XResolution;
  1085. X            if ((flags & HeightValue) == 0)
  1086. X              y_resolution=x_resolution;
  1087. X          }
  1088. X        (void) sprintf(clip_geometry,"%ux%u+%u-%u\0",
  1089. X          ((upper_x-lower_x)*x_resolution+(XResolution >> 1))/XResolution,
  1090. X          ((upper_y-lower_y)*y_resolution+(YResolution >> 1))/YResolution,
  1091. X          (lower_x*x_resolution+(XResolution >> 1))/XResolution,
  1092. X          ((lower_y*y_resolution+(YResolution >> 1))/YResolution));
  1093. X        break;
  1094. X      }
  1095. X  CloseImage(image);
  1096. X  /*
  1097. X    Rendered Postscript goes to temporary PNM file.
  1098. X  */
  1099. X  directory=(char *) getenv("TMPDIR");
  1100. X  if (directory == (char *) NULL)
  1101. X    directory="/tmp";
  1102. X  (void) sprintf(filename,"%s/magickXXXXXX",directory);
  1103. X  (void) mktemp(filename);
  1104. X  /*
  1105. X    Determine if geometry or density options are specified.
  1106. X  */
  1107. X  *options='\0';
  1108. X  if (alien_info->geometry != (char *) NULL)
  1109. X    {
  1110. X      (void) strcat(options," -g");
  1111. X      (void) strcat(options,alien_info->geometry);
  1112. X    }
  1113. X  if (alien_info->density != (char *) NULL)
  1114. X    {
  1115. X      (void) strcat(options," -r");
  1116. X      (void) strcat(options,alien_info->density);
  1117. X    }
  1118. X  /*
  1119. X    Use Ghostscript to convert Postscript image.
  1120. X  */
  1121. X  (void) sprintf(command,"gs -q -sDEVICE=ppmraw -sOutputFile=%s %s %s",
  1122. X    filename,options,alien_info->filename);
  1123. X  (void) strcat(command," < /dev/null > /dev/null");
  1124. X  status=system(command);
  1125. X  if (status != 0)
  1126. X    {
  1127. X      Warning("unable to execute ghostscript (gs)",alien_info->filename);
  1128. X      return((Image *) NULL);
  1129. X    }
  1130. X  (void) strcpy(alien_info->filename,filename);
  1131. X  (void) strcpy(filename,image->filename);
  1132. X  DestroyImage(image);
  1133. X  image=ReadPNMImage(alien_info);
  1134. X  (void) unlink(alien_info->filename);
  1135. X  if (image == (Image *) NULL)
  1136. X    {
  1137. X      Warning("Postscript translation failed",alien_info->filename);
  1138. X      return((Image *) NULL);
  1139. X    }
  1140. X  do
  1141. X  {
  1142. X    if (image->last == (Image *) NULL)
  1143. X      (void) strcpy(image->filename,filename);
  1144. X    else
  1145. X      (void) sprintf(image->filename,"%s.%u\0",filename,image->scene);
  1146. X    (void) strcpy(image->magick,"PS");
  1147. X    if (*clip_geometry != '\0')
  1148. X      {
  1149. X        /*
  1150. X          Clip image as specified by the bounding box.
  1151. X        */
  1152. X        TransformImage(&image,clip_geometry,(char *) NULL,(char *) NULL);
  1153. X        if (image->next != (Image *) NULL)
  1154. X          image->next->last=image;
  1155. X      }
  1156. X    next_image=image->next;
  1157. X    if (next_image != (Image *) NULL)
  1158. X      image=next_image;
  1159. X  } while (next_image != (Image *) NULL);
  1160. X  while (image->last != (Image *) NULL)
  1161. X    image=image->last;
  1162. X  return(image);
  1163. }
  1164. X
  1165. /*
  1166. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1167. %                                                                             %
  1168. %                                                                             %
  1169. %                                                                             %
  1170. %  R e a d R G B I m a g e                                                    %
  1171. %                                                                             %
  1172. %                                                                             %
  1173. %                                                                             %
  1174. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1175. %
  1176. %  Function ReadRGBImage reads an image file and returns it.  It allocates the
  1177. %  memory necessary for the new Image structure and returns a pointer to the
  1178. %  new image.
  1179. %
  1180. %  The format of the ReadRGBImage routine is:
  1181. %
  1182. %      image=ReadRGBImage(alien_info)
  1183. %
  1184. %  A description of each parameter follows:
  1185. %
  1186. %    o image:  Function ReadRGBImage returns a pointer to the image after
  1187. %      reading.  A null image is returned if there is a a memory shortage or
  1188. %      if the image cannot be read.
  1189. %
  1190. %    o alien_info: Specifies a pointer to an AlienInfo structure.
  1191. %
  1192. %
  1193. */
  1194. static Image *ReadRGBImage(alien_info)
  1195. AlienInfo
  1196. X  *alien_info;
  1197. {
  1198. X  Image
  1199. X    *image;
  1200. X
  1201. X  int
  1202. X    x,
  1203. X    y;
  1204. X
  1205. X  register int
  1206. X    i;
  1207. X
  1208. X  register RunlengthPacket
  1209. X    *q;
  1210. X
  1211. X  register unsigned char
  1212. X    *p;
  1213. X
  1214. X  unsigned char
  1215. X    *rgb_pixels;
  1216. X
  1217. X  unsigned int
  1218. X    height,
  1219. X    width;
  1220. X
  1221. X  /*
  1222. X    Allocate image structure.
  1223. X  */
  1224. X  image=AllocateImage("RGB");
  1225. X  if (image == (Image *) NULL)
  1226. X    return((Image *) NULL);
  1227. X  /*
  1228. X    Open image file.
  1229. X  */
  1230. X  (void) strcpy(image->filename,alien_info->filename);
  1231. X  OpenImage(image,"r");
  1232. X  if (image->file == (FILE *) NULL)
  1233. X    {
  1234. X      Warning("unable to open file",image->filename);
  1235. X      DestroyImage(image);
  1236. X      return((Image *) NULL);
  1237. X    }
  1238. X  /*
  1239. X    Create image.
  1240. X  */
  1241. X  width=512;
  1242. X  height=512;
  1243. X  if (alien_info->geometry != (char *) NULL)
  1244. X    (void) XParseGeometry(alien_info->geometry,&x,&y,&width,&height);
  1245. X  image->columns=width;
  1246. X  image->rows=height;
  1247. X  image->packets=image->columns*image->rows;
  1248. X  rgb_pixels=(unsigned char *)
  1249. X    malloc((unsigned int) image->packets*3*sizeof(unsigned char));
  1250. X  image->pixels=(RunlengthPacket *)
  1251. X    malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  1252. X  if ((rgb_pixels == (unsigned char *) NULL) ||
  1253. X      (image->pixels == (RunlengthPacket *) NULL))
  1254. X    {
  1255. X      Warning("memory allocation error",(char *) NULL);
  1256. X      DestroyImage(image);
  1257. X      return((Image *) NULL);
  1258. X    }
  1259. X  /*
  1260. X    Convert raster image to runlength-encoded packets.
  1261. X  */
  1262. X  (void) ReadData((char *) rgb_pixels,3,(int) (image->columns*image->rows),
  1263. X    image->file);
  1264. X  p=rgb_pixels;
  1265. X  q=image->pixels;
  1266. X  for (i=0; i < (image->columns*image->rows); i++)
  1267. X  {
  1268. X    q->red=(*p++);
  1269. X    q->green=(*p++);
  1270. X    q->blue=(*p++);
  1271. X    q->index=0;
  1272. X    q->length=0;
  1273. X    q++;
  1274. X  }
  1275. X  (void) free((char *) rgb_pixels);
  1276. X  CloseImage(image);
  1277. X  return(image);
  1278. }
  1279. X
  1280. /*
  1281. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1282. %                                                                             %
  1283. %                                                                             %
  1284. %                                                                             %
  1285. %  R e a d R L E I m a g e                                                    %
  1286. %                                                                             %
  1287. %                                                                             %
  1288. %                                                                             %
  1289. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1290. %
  1291. %  Function ReadRLEImage reads a run-length encoded Utah Raster Toolkit
  1292. %  image file and returns it.  It allocates the memory necessary for the new
  1293. %  Image structure and returns a pointer to the new image.
  1294. %
  1295. %  The format of the ReadRLEImage routine is:
  1296. %
  1297. %      image=ReadRLEImage(alien_info)
  1298. %
  1299. %  A description of each parameter follows:
  1300. %
  1301. %    o image:  Function ReadRLEImage returns a pointer to the image after
  1302. %      reading.  A null image is returned if there is a a memory shortage or
  1303. %      if the image cannot be read.
  1304. %
  1305. %    o alien_info: Specifies a pointer to an AlienInfo structure.
  1306. %
  1307. %
  1308. */
  1309. static Image *ReadRLEImage(alien_info)
  1310. AlienInfo
  1311. X  *alien_info;
  1312. {
  1313. #define SkipLinesOp  0x01
  1314. #define SetColorOp  0x02
  1315. #define SkipPixelsOp  0x03
  1316. #define ByteDataOp  0x05
  1317. #define RunDataOp  0x06
  1318. #define EOFOp  0x07
  1319. X
  1320. X  char
  1321. X    magick[12];
  1322. X
  1323. X  Image
  1324. X    *image;
  1325. X
  1326. X  int
  1327. X    opcode,
  1328. X    operand,
  1329. X    status,
  1330. X    x,
  1331. X    y;
  1332. X
  1333. X  register int
  1334. X    i,
  1335. X    j;
  1336. X
  1337. X  register RunlengthPacket
  1338. X    *q;
  1339. X
  1340. X  register unsigned char
  1341. X    *p;
  1342. X
  1343. X  unsigned char
  1344. X    background_color[256],
  1345. X    *colormap,
  1346. X    header[2048],
  1347. X    integer[2],
  1348. X    pixel,
  1349. X    plane,
  1350. X    *rle_pixels;
  1351. X
  1352. X  unsigned int
  1353. X    bits_per_pixel,
  1354. X    flags,
  1355. X    map_length,
  1356. X    number_colormaps,
  1357. X    number_planes;
  1358. X
  1359. X  /*
  1360. X    Allocate image structure.
  1361. X  */
  1362. X  image=AllocateImage("RLE");
  1363. X  if (image == (Image *) NULL)
  1364. X    return((Image *) NULL);
  1365. X  /*
  1366. X    Open image file.
  1367. X  */
  1368. X  (void) strcpy(image->filename,alien_info->filename);
  1369. X  OpenImage(image,"r");
  1370. X  if (image->file == (FILE *) NULL)
  1371. X    {
  1372. X      Warning("unable to open file",image->filename);
  1373. X      DestroyImage(image);
  1374. X      return((Image *) NULL);
  1375. X    }
  1376. X  /*
  1377. X    Determine if this is a RLE file.
  1378. X  */
  1379. X  status=ReadData((char *) magick,1,2,image->file);
  1380. X  if ((status == False) || (strncmp(magick,"\122\314",2) != 0))
  1381. X    {
  1382. X      Warning("not a RLE image file",(char *) NULL);
  1383. X      DestroyImage(image);
  1384. X      return((Image *) NULL);
  1385. X    }
  1386. X  do
  1387. X  {
  1388. X    /*
  1389. X      Read image header.
  1390. X    */
  1391. X    status=ReadData((char *) header,1,13,image->file);
  1392. X    if (status == False)
  1393. X      {
  1394. X        Warning("unable to read RLE image header",(char *) NULL);
  1395. X        DestroyImage(image);
  1396. X        return((Image *) NULL);
  1397. X      }
  1398. X    image->columns=header[4]+(header[5] << 8);
  1399. X    image->rows=header[6]+(header[7] << 8);
  1400. X    image->packets=image->columns*image->rows;
  1401. X    flags=header[8];
  1402. X    image->alpha=flags & 0x04;
  1403. X    number_planes=header[9];
  1404. X    bits_per_pixel=header[10];
  1405. X    number_colormaps=header[11];
  1406. X    map_length=1 << header[12];
  1407. X    if ((number_planes == 0) || (number_planes == 2) || (bits_per_pixel != 8) ||
  1408. X        ((image->columns*image->rows) == 0))
  1409. X      {
  1410. X        Warning("unsupported RLE image file",(char *) NULL);
  1411. X        DestroyImage(image);
  1412. X        return((Image *) NULL);
  1413. X      }
  1414. X    if (flags & 0x02)
  1415. X      {
  1416. X        /*
  1417. X          No background color-- initialize to black.
  1418. X        */
  1419. X        for (i=0; i < number_planes; i++)
  1420. X          background_color[i]=(unsigned char) 0;
  1421. X        (void) fgetc(image->file);
  1422. X      }
  1423. X    else
  1424. X      {
  1425. X        /*
  1426. X          Initialize background color.
  1427. X        */
  1428. X        p=background_color;
  1429. X        for (i=0; i < number_planes; i++)
  1430. X          *p++=(unsigned char) fgetc(image->file);
  1431. X        if ((number_planes % 2) == 0)
  1432. X          (void) fgetc(image->file);
  1433. X      }
  1434. X    if (number_colormaps > 0)
  1435. X      {
  1436. X        /*
  1437. X          Read image colormaps.
  1438. X        */
  1439. X        colormap=(unsigned char *)
  1440. X          malloc(number_colormaps*map_length*sizeof(unsigned char));
  1441. X        if (colormap == (unsigned char *) NULL)
  1442. X          {
  1443. X            Warning("memory allocation error",(char *) NULL);
  1444. X            DestroyImage(image);
  1445. X            return((Image *) NULL);
  1446. X          }
  1447. X        p=colormap;
  1448. X        for (i=0; i < number_colormaps; i++)
  1449. X          for (j=0; j < map_length; j++)
  1450. X          {
  1451. X            (void) fgetc(image->file);
  1452. X            *p++=(unsigned char) fgetc(image->file);
  1453. X          }
  1454. X      }
  1455. X    /*
  1456. X      Allocate image comment.
  1457. X    */
  1458. X    image->comments=(char *)
  1459. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  1460. X    if (image->comments == (char *) NULL)
  1461. X      {
  1462. X        Warning("memory allocation error",(char *) NULL);
  1463. X        DestroyImage(image);
  1464. X        return((Image *) NULL);
  1465. X      }
  1466. X    (void) sprintf(image->comments,"\n  Imported from Utah raster image:  %s\n",
  1467. X      image->filename);
  1468. X    if (flags & 0x08)
  1469. X      {
  1470. X        unsigned int
  1471. X          comment_length;
  1472. X
  1473. X        /*
  1474. X          Read image comment.
  1475. X        */
  1476. X        (void) ReadData((char *) integer,1,2,image->file);
  1477. X        comment_length=integer[0]+(integer[1] << 8);
  1478. X        image->comments=(char *) realloc((char *) image->comments,
  1479. X          (unsigned int) (strlen(image->comments)+comment_length+2048));
  1480. X        if (image->comments == (char *) NULL)
  1481. X          {
  1482. X            Warning("memory allocation error",(char *) NULL);
  1483. X            DestroyImage(image);
  1484. X            return((Image *) NULL);
  1485. X          }
  1486. X        (void) strcat(image->comments,"\n  ");
  1487. X        status=ReadData((char *) image->comments+strlen(image->comments),1,
  1488. X          (int) comment_length+(comment_length % 2 ? 0 : 1),image->file);
  1489. X        if (status == False)
  1490. X          {
  1491. X            Warning("unable to read RLE comment",(char *) NULL);
  1492. X            DestroyImage(image);
  1493. X            return((Image *) NULL);
  1494. X          }
  1495. X        (void) strcat(image->comments,"\n");
  1496. X      }
  1497. X    /*
  1498. X      Allocate RLE pixels.
  1499. X    */
  1500. X    if (image->alpha)
  1501. X      number_planes++;
  1502. X    rle_pixels=(unsigned char *)
  1503. X      malloc((unsigned int) image->packets*number_planes*sizeof(unsigned char));
  1504. X    if (rle_pixels == (unsigned char *) NULL)
  1505. X      {
  1506. X        Warning("memory allocation error",(char *) NULL);
  1507. X        DestroyImage(image);
  1508. X        return((Image *) NULL);
  1509. X      }
  1510. X    if ((flags & 0x01) && ((~flags) & 0x02))
  1511. X      {
  1512. X        /*
  1513. X          Set background color.
  1514. X        */
  1515. X        p=rle_pixels;
  1516. X        for (i=0; i < image->packets; i++)
  1517. X        {
  1518. X          if (!image->alpha)
  1519. X            for (j=0; j < number_planes; j++)
  1520. X              *p++=background_color[j];
  1521. X          else
  1522. X            {
  1523. X              for (j=0; j < (number_planes-1); j++)
  1524. X                *p++=background_color[j];
  1525. X              *p++=0;  /* initialize alpha channel */
  1526. X            }
  1527. X        }
  1528. X      }
  1529. X    /*
  1530. X      Read runlength-encoded image.
  1531. X    */
  1532. X    plane=0;
  1533. X    x=0;
  1534. X    y=0;
  1535. X    (void) fgetc(image->file);
  1536. X    opcode=fgetc(image->file);
  1537. X    while (((opcode & 0x3f) != EOFOp) && (opcode != EOF))
  1538. X    {
  1539. X      switch (opcode & 0x3f)
  1540. X      {
  1541. X        case SkipLinesOp:
  1542. X        {
  1543. X          operand=fgetc(image->file);
  1544. X          if (opcode & 0x40)
  1545. X            {
  1546. X              (void) ReadData((char *) integer,1,2,image->file);
  1547. X              operand=integer[0]+(integer[1] << 8);
  1548. X            }
  1549. X          x=0;
  1550. X          y+=operand;
  1551. X          break;
  1552. X        }
  1553. X        case SetColorOp:
  1554. X        {
  1555. X          operand=fgetc(image->file);
  1556. X          plane=operand;
  1557. X          if (plane == 255)
  1558. X            plane=number_planes-1;
  1559. X          x=0;
  1560. X          break;
  1561. X        }
  1562. X        case SkipPixelsOp:
  1563. X        {
  1564. X          operand=fgetc(image->file);
  1565. X          if (opcode & 0x40)
  1566. X            {
  1567. X              (void) ReadData((char *) integer,1,2,image->file);
  1568. X              operand=integer[0]+(integer[1] << 8);
  1569. X            }
  1570. X          x+=operand;
  1571. X          break;
  1572. X        }
  1573. X        case ByteDataOp:
  1574. X        {
  1575. X          operand=fgetc(image->file);
  1576. X          if (opcode & 0x40)
  1577. X            {
  1578. X              (void) ReadData((char *) integer,1,2,image->file);
  1579. X              operand=integer[0]+(integer[1] << 8);
  1580. X            }
  1581. X          p=rle_pixels+((image->rows-y-1)*image->columns*number_planes)+
  1582. X            x*number_planes+plane;
  1583. X          operand++;
  1584. X          for (i=0; i < operand; i++)
  1585. X          {
  1586. X            pixel=fgetc(image->file);
  1587. X            if ((y < image->rows) && ((x+i) < image->columns))
  1588. X              *p=pixel;
  1589. X            p+=number_planes;
  1590. X          }
  1591. X          if (operand & 0x01)
  1592. X            (void) fgetc(image->file);
  1593. X          x+=operand;
  1594. X          break;
  1595. X        }
  1596. X        case RunDataOp:
  1597. X        {
  1598. X          operand=fgetc(image->file);
  1599. X          if (opcode & 0x40)
  1600. X            {
  1601. X              (void) ReadData((char *) integer,1,2,image->file);
  1602. X              operand=integer[0]+(integer[1] << 8);
  1603. X            }
  1604. X          pixel=fgetc(image->file);
  1605. X          (void) fgetc(image->file);
  1606. X          operand++;
  1607. X          p=rle_pixels+((image->rows-y-1)*image->columns*number_planes)+
  1608. X            x*number_planes+plane;
  1609. X          for (i=0; i < operand; i++)
  1610. X          {
  1611. X            if ((y < image->rows) && ((x+i) < image->columns))
  1612. X              *p=pixel;
  1613. X            p+=number_planes;
  1614. X          }
  1615. X          x+=operand;
  1616. X          break;
  1617. X        }
  1618. X        default:
  1619. X        {
  1620. X          Warning("Unrecognized RLE opcode",image->filename);
  1621. X          DestroyImage(image);
  1622. X          return((Image *) NULL);
  1623. X        }
  1624. X      }
  1625. X      opcode=fgetc(image->file);
  1626. X    }
  1627. X    if (number_colormaps > 0)
  1628. X      {
  1629. X        unsigned char
  1630. X          pixel;
  1631. X
  1632. X        unsigned int
  1633. X          mask;
  1634. X
  1635. X        /*
  1636. X          Apply colormap transformation to image.
  1637. X        */
  1638. X        mask=(map_length-1);
  1639. X        p=rle_pixels;
  1640. X        for (i=0; i < image->packets; i++)
  1641. X          for (j=0; j < number_planes; j++)
  1642. X          {
  1643. X            pixel=colormap[j*map_length+(*p & mask)];
  1644. X            *p++=pixel;
  1645. X          }
  1646. X        (void) free((char *) colormap);
  1647. X      }
  1648. X    /*
  1649. X      Create image.
  1650. X    */
  1651. X    image->pixels=(RunlengthPacket *)
  1652. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  1653. X    if (image->pixels == (RunlengthPacket *) NULL)
  1654. X      {
  1655. X        Warning("memory allocation error",(char *) NULL);
  1656. X        DestroyImage(image);
  1657. X        return((Image *) NULL);
  1658. X      }
  1659. X    p=rle_pixels;
  1660. X    q=image->pixels;
  1661. X    if (number_planes >= 3)
  1662. X      {
  1663. X        /*
  1664. X          Convert raster image to DirectClass runlength-encoded packets.
  1665. X        */
  1666. X        for (i=0; i < (image->columns*image->rows); i++)
  1667. X        {
  1668. X          q->red=(*p++);
  1669. X          q->green=(*p++);
  1670. X          q->blue=(*p++);
  1671. X          q->index=(unsigned short) (image->alpha ? (*p++) : 0);
  1672. X          q->length=0;
  1673. X          q++;
  1674. X        }
  1675. X      }
  1676. X    else
  1677. X      {
  1678. X        unsigned short
  1679. X          index;
  1680. X
  1681. X        /*
  1682. X          Create grayscale map.
  1683. X        */
  1684. X        image->class=PseudoClass;
  1685. X        image->colors=256;
  1686. X        image->colormap=(ColorPacket *)
  1687. X          malloc(image->colors*sizeof(ColorPacket));
  1688. X        if (image->colormap == (ColorPacket *) NULL)
  1689. X          {
  1690. X            Warning("unable to read image","memory allocation failed");
  1691. X            DestroyImage(image);
  1692. X            return((Image *) NULL);
  1693. X          }
  1694. X        for (i=0; i < image->colors; i++)
  1695. X        {
  1696. X          image->colormap[i].red=(unsigned char) i;
  1697. X          image->colormap[i].green=(unsigned char) i;
  1698. X          image->colormap[i].blue=(unsigned char) i;
  1699. X        }
  1700. X        /*
  1701. X          Convert raster image to PseudoClass runlength-encoded packets.
  1702. X        */
  1703. X        for (i=0; i < (image->columns*image->rows); i++)
  1704. X        {
  1705. X          index=(unsigned short) (*p++);
  1706. X          q->red=image->colormap[index].red;
  1707. X          q->green=image->colormap[index].green;
  1708. X          q->blue=image->colormap[index].blue;
  1709. X          q->index=index;
  1710. X          q->length=0;
  1711. X          q++;
  1712. X        }
  1713. X      }
  1714. X    (void) free((char *) rle_pixels);
  1715. X    /*
  1716. X      Proceed to next image.
  1717. X    */
  1718. X    (void) fgetc(image->file);
  1719. X    status=ReadData((char *) magick,1,2,image->file);
  1720. X    if ((status == True) && (strncmp(magick,"\122\314",2) == 0))
  1721. X      {
  1722. X        /*
  1723. X          Allocate next image structure.
  1724. X        */
  1725. X        image->next=AllocateImage("RLE");
  1726. X        if (image->next == (Image *) NULL)
  1727. X          {
  1728. X            DestroyImages(image);
  1729. X            return((Image *) NULL);
  1730. X          }
  1731. X        image->next->file=image->file;
  1732. X        (void) sprintf(image->next->filename,"%s.%u\0",alien_info->filename,
  1733. X          image->scene+1);
  1734. X        image->next->scene=image->scene+1;
  1735. X        image->next->last=image;
  1736. X        image=image->next;
  1737. X      }
  1738. X  } while ((status == True) && (strncmp(magick,"\122\314",2) == 0));
  1739. X  while (image->last != (Image *) NULL)
  1740. X    image=image->last;
  1741. X  CloseImage(image);
  1742. X  return(image);
  1743. }
  1744. X
  1745. /*
  1746. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1747. %                                                                             %
  1748. %                                                                             %
  1749. %                                                                             %
  1750. %  R e a d S U N I m a g e                                                    %
  1751. %                                                                             %
  1752. %                                                                             %
  1753. %                                                                             %
  1754. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1755. %
  1756. %  Function ReadSUNImage reads an image file and returns it.  It allocates
  1757. %  the memory necessary for the new Image structure and returns a pointer to
  1758. %  the new image.
  1759. %
  1760. %  The format of the ReadSUNImage routine is:
  1761. %
  1762. %      image=ReadSUNImage(alien_info)
  1763. %
  1764. %  A description of each parameter follows:
  1765. %
  1766. %    o image:  Function ReadSUNImage returns a pointer to the image after
  1767. %      reading.  A null image is returned if there is a a memory shortage or
  1768. %      if the image cannot be read.
  1769. %
  1770. %    o alien_info: Specifies a pointer to an AlienInfo structure.
  1771. %
  1772. %
  1773. */
  1774. static Image *ReadSUNImage(alien_info)
  1775. AlienInfo
  1776. X  *alien_info;
  1777. {
  1778. #define RMT_EQUAL_RGB  1
  1779. #define RMT_NONE  0
  1780. #define RMT_RAW  2
  1781. #define RT_STANDARD  1
  1782. #define RT_ENCODED  2
  1783. #define RT_FORMAT_RGB  3
  1784. X
  1785. X  typedef struct _Rasterfile
  1786. X  {
  1787. X    int
  1788. X      magic,
  1789. X      width,
  1790. X      height,
  1791. X      depth,
  1792. X      length,
  1793. X      type,
  1794. X      maptype,
  1795. X      maplength;
  1796. X  } Rasterfile;
  1797. X
  1798. X  Image
  1799. X    *image;
  1800. X
  1801. X  Rasterfile
  1802. X    sun_header;
  1803. X
  1804. X  register int
  1805. X    bit,
  1806. X    i,
  1807. X    x,
  1808. X    y;
  1809. X
  1810. X  register RunlengthPacket
  1811. X    *q;
  1812. X
  1813. X  register unsigned char
  1814. X    *p;
  1815. X
  1816. X  unsigned char
  1817. X    *sun_data,
  1818. X    *sun_pixels;
  1819. X
  1820. X  unsigned long
  1821. X    lsb_first;
  1822. X
  1823. X  unsigned short
  1824. X    index;
  1825. X
  1826. X  unsigned int
  1827. X    status;
  1828. X
  1829. X  /*
  1830. X    Allocate image structure.
  1831. X  */
  1832. X  image=AllocateImage("SUN");
  1833. X  if (image == (Image *) NULL)
  1834. X    return((Image *) NULL);
  1835. X  /*
  1836. X    Open image file.
  1837. X  */
  1838. X  (void) strcpy(image->filename,alien_info->filename);
  1839. X  OpenImage(image,"r");
  1840. X  if (image->file == (FILE *) NULL)
  1841. X    {
  1842. X      Warning("unable to open file",image->filename);
  1843. X      DestroyImage(image);
  1844. X      return((Image *) NULL);
  1845. X    }
  1846. X  /*
  1847. X    Read raster image.
  1848. X  */
  1849. X  status=ReadData((char *) &sun_header,1,sizeof(Rasterfile),image->file);
  1850. X  if (status == False)
  1851. X    {
  1852. X      Warning("not a SUN image file",(char *) NULL);
  1853. X      DestroyImage(image);
  1854. X      return((Image *) NULL);
  1855. X    }
  1856. X  do
  1857. X  {
  1858. X    /*
  1859. X      Ensure the header byte-order is most-significant byte first.
  1860. X    */
  1861. X    lsb_first=1;
  1862. X    if (*(char *) &lsb_first)
  1863. X      MSBFirstOrderLong((char *) &sun_header,sizeof(sun_header));
  1864. X    if (sun_header.magic != 0x59a66a95)
  1865. X      {
  1866. X        Warning("not a SUN raster,",image->filename);
  1867. X        DestroyImages(image);
  1868. X        return((Image *) NULL);
  1869. X      }
  1870. X    switch (sun_header.maptype)
  1871. X    {
  1872. X      case RMT_NONE:
  1873. X      {
  1874. X        if (sun_header.depth < 24)
  1875. X          {
  1876. X            /*
  1877. X              Create linear color ramp.
  1878. X            */
  1879. X            image->colors=1 << sun_header.depth;
  1880. X            image->colormap=(ColorPacket *)
  1881. X              malloc(image->colors*sizeof(ColorPacket));
  1882. X            if (image->colormap == (ColorPacket *) NULL)
  1883. X              {
  1884. X                Warning("memory allocation error",(char *) NULL);
  1885. X                return((Image *) NULL);
  1886. X              }
  1887. X            for (i=0; i < image->colors; i++)
  1888. X            {
  1889. X              image->colormap[i].red=(255*i)/(image->colors-1);
  1890. X              image->colormap[i].green=(255*i)/(image->colors-1);
  1891. X              image->colormap[i].blue=(255*i)/(image->colors-1);
  1892. X            }
  1893. X          }
  1894. X        break;
  1895. X      }
  1896. X      case RMT_EQUAL_RGB:
  1897. X      {
  1898. X        unsigned char
  1899. X          *sun_colormap;
  1900. X
  1901. X        /*
  1902. X          Read Sun raster colormap.
  1903. X        */
  1904. X        image->colors=sun_header.maplength/3;
  1905. X        image->colormap=(ColorPacket *)
  1906. X          malloc(image->colors*sizeof(ColorPacket));
  1907. X        sun_colormap=(unsigned char *)
  1908. X          malloc(image->colors*sizeof(unsigned char));
  1909. X        if ((image->colormap == (ColorPacket *) NULL) ||
  1910. X            (sun_colormap == (unsigned char *) NULL))
  1911. X          {
  1912. X            Warning("memory allocation error",(char *) NULL);
  1913. X            DestroyImages(image);
  1914. X            return((Image *) NULL);
  1915. X          }
  1916. X        (void) ReadData((char *) sun_colormap,1,(int) image->colors,
  1917. X          image->file);
  1918. X        for (i=0; i < image->colors; i++)
  1919. X          image->colormap[i].red=sun_colormap[i];
  1920. X        (void) ReadData((char *) sun_colormap,1,(int) image->colors,
  1921. X          image->file);
  1922. X        for (i=0; i < image->colors; i++)
  1923. X          image->colormap[i].green=sun_colormap[i];
  1924. X        (void) ReadData((char *) sun_colormap,1,(int) image->colors,
  1925. X          image->file);
  1926. X        for (i=0; i < image->colors; i++)
  1927. X          image->colormap[i].blue=sun_colormap[i];
  1928. X        (void) free((char *) sun_colormap);
  1929. X        break;
  1930. X      }
  1931. X      case RMT_RAW:
  1932. X      {
  1933. X        unsigned char
  1934. X          *sun_colormap;
  1935. X
  1936. X        /*
  1937. X          Read Sun raster colormap.
  1938. X        */
  1939. X        sun_colormap=(unsigned char *)
  1940. X          malloc(sun_header.maplength*sizeof(unsigned char));
  1941. X        if (sun_colormap == (unsigned char *) NULL)
  1942. X          {
  1943. X            Warning("memory allocation error",(char *) NULL);
  1944. X            DestroyImages(image);
  1945. X            return((Image *) NULL);
  1946. X          }
  1947. X        (void) ReadData((char *) sun_colormap,1,sun_header.maplength,
  1948. X          image->file);
  1949. X        (void) free((char *) sun_colormap);
  1950. X        break;
  1951. X      }
  1952. X      default:
  1953. X      {
  1954. X        Warning("colormap type is not supported",image->filename);
  1955. X        DestroyImages(image);
  1956. X        return((Image *) NULL);
  1957. X      }
  1958. X    }
  1959. X    sun_data=(unsigned char *) malloc(sun_header.length*sizeof(unsigned char));
  1960. X    if (sun_data == (unsigned char *) NULL)
  1961. X      {
  1962. X        Warning("memory allocation error",(char *) NULL);
  1963. X        DestroyImages(image);
  1964. X        return((Image *) NULL);
  1965. X      }
  1966. X    (void) ReadData((char *) sun_data,1,sun_header.length,image->file);
  1967. X    sun_pixels=sun_data;
  1968. X    if (sun_header.type == RT_ENCODED)
  1969. X      {
  1970. X        register int
  1971. X          count,
  1972. X          number_pixels;
  1973. X
  1974. X        register unsigned char
  1975. X          byte,
  1976. X          *q;
  1977. X
  1978. X        /*
  1979. X          Read run-length encoded raster pixels.
  1980. X        */
  1981. X        number_pixels=(sun_header.width+(sun_header.width % 2))*
  1982. X          sun_header.height*(((sun_header.depth-1) >> 3)+1);
  1983. X        sun_pixels=(unsigned char *)
  1984. X          malloc(number_pixels*sizeof(unsigned char));
  1985. X        if (sun_pixels == (unsigned char *) NULL)
  1986. X          {
  1987. X            Warning("memory allocation error",(char *) NULL);
  1988. X            DestroyImages(image);
  1989. X            return((Image *) NULL);
  1990. X          }
  1991. X        p=sun_data;
  1992. X        q=sun_pixels;
  1993. X        while ((q-sun_pixels) <= number_pixels)
  1994. X        {
  1995. X          byte=(*p++);
  1996. X          if (byte != 128)
  1997. X            *q++=byte;
  1998. X          else
  1999. X            {
  2000. X              /*
  2001. X                Runlength-encoded packet: <count><byte>
  2002. X              */
  2003. X              count=(*p++);
  2004. X              if (count > 0)
  2005. X                byte=(*p++);
  2006. X              while (count >= 0)
  2007. X              {
  2008. X                *q++=byte;
  2009. X                count--;
  2010. X              }
  2011. X           }
  2012. X        }
  2013. X      (void) free((char *) sun_data);
  2014. X    }
  2015. X    /*
  2016. X      Create image.
  2017. X    */
  2018. X    image->alpha=(sun_header.depth == 32);
  2019. X    image->class=(sun_header.depth < 24 ? PseudoClass : DirectClass);
  2020. X    image->columns=sun_header.width;
  2021. X    image->rows=sun_header.height;
  2022. X    image->packets=image->columns*image->rows;
  2023. X    image->pixels=(RunlengthPacket *)
  2024. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  2025. X    image->comments=(char *)
  2026. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  2027. X    (void) sprintf(image->comments,
  2028. X      "\n  Imported from Sun raster image:  %s\n\0",image->filename);
  2029. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  2030. X        (image->comments == (char *) NULL))
  2031. X      {
  2032. X        Warning("memory allocation error",(char *) NULL);
  2033. X        DestroyImages(image);
  2034. X        return((Image *) NULL);
  2035. X      }
  2036. X    /*
  2037. X      Convert Sun raster image to runlength-encoded packets.
  2038. X    */
  2039. X    p=sun_pixels;
  2040. X    q=image->pixels;
  2041. X    if (sun_header.depth == 1)
  2042. X      for (y=0; y < image->rows; y++)
  2043. X      {
  2044. X        /*
  2045. X          Convert bitmap scanline to runlength-encoded color packets.
  2046. X        */
  2047. X        for (x=0; x < (image->columns >> 3); x++)
  2048. X        {
  2049. X          for (bit=7; bit >= 0; bit--)
  2050. X          {
  2051. X            index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
  2052. X            q->red=image->colormap[index].red;
  2053. X            q->green=image->colormap[index].green;
  2054. X            q->blue=image->colormap[index].blue;
  2055. X            q->index=index;
  2056. X            q->length=0;
  2057. X            q++;
  2058. X          }
  2059. X          p++;
  2060. X        }
  2061. X        if ((image->columns % 8) != 0)
  2062. X          {
  2063. X            for (bit=7; bit >= (8-(image->columns % 8)); bit--)
  2064. X            {
  2065. X              index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
  2066. X              q->red=image->colormap[index].red;
  2067. X              q->green=image->colormap[index].green;
  2068. X              q->blue=image->colormap[index].blue;
  2069. X              q->index=index;
  2070. SHAR_EOF
  2071. true || echo 'restore of ImageMagick/alien.c failed'
  2072. fi
  2073. echo 'End of  part 21'
  2074. echo 'File ImageMagick/alien.c is continued in part 22'
  2075. echo 22 > _shar_seq_.tmp
  2076. exit 0
  2077. exit 0 # Just in case...
  2078.