home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume34 / imagemagick / part21 < prev    next >
Encoding:
Text File  |  1992-12-14  |  57.3 KB  |  2,072 lines

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