home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume34 / imagemagick / part06 < prev    next >
Text File  |  1992-12-14  |  59KB  |  2,016 lines

  1. Newsgroups: comp.sources.misc
  2. From: cristy@eplrx7.es.duPont.com (John Cristy)
  3. Subject:  v34i034:  imagemagick - X11 image processing and display v2.2, Part06/26
  4. Message-ID: <1992Dec13.202704.9309@sparky.imd.sterling.com>
  5. X-Md4-Signature: 2bbfaa12365a0e18fdc8373af0d29a49
  6. Date: Sun, 13 Dec 1992 20:27:04 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 34
  11. Archive-name: imagemagick/part06
  12. Environment: UNIX, VMS, X11, SGI, DEC, Cray, Sun, Vax
  13.  
  14. #!/bin/sh
  15. # this is Part.06 (part 6 of a multipart archive)
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file ImageMagick/image.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" != 6; 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/image.c'
  33. else
  34. echo 'x - continuing file ImageMagick/image.c'
  35. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/image.c' &&
  36. X      "  token pop /compression exch def pop",
  37. X      "  class 0 gt { PseudoClassImage } { DirectClassImage } ifelse",
  38. X      "  grestore",
  39. X      "  showpage",
  40. X      "} bind def",
  41. X      "",
  42. X      "DisplayImage",
  43. X      NULL
  44. X    };
  45. X
  46. X  char
  47. X    **q;
  48. X
  49. X  int
  50. X    x,
  51. X    y;
  52. X
  53. X  register RunlengthPacket
  54. X    *p;
  55. X
  56. X  register int
  57. X    i,
  58. X    j;
  59. X
  60. X  unsigned int
  61. X    height,
  62. X    width;
  63. X
  64. X  /*
  65. X    Open output image file.
  66. X  */
  67. X  OpenImage(image,"w");
  68. X  if (image->file == (FILE *) NULL)
  69. X    {
  70. X      Warning("unable to open file",image->filename);
  71. X      return(False);
  72. X    }
  73. X  if (geometry != (char *) NULL)
  74. X    {
  75. X      /*
  76. X        User specified Postscript page position.
  77. X      */
  78. X      x=0;
  79. X      y=0;
  80. X      width=image->columns;
  81. X      height=image->rows;
  82. X      (void) XParseGeometry(geometry,&x,&y,&width,&height);
  83. X    }
  84. X  else
  85. X    {
  86. X      int
  87. X        delta_x,
  88. X        delta_y;
  89. X
  90. X      unsigned long
  91. X        scale_factor;
  92. X
  93. X      /*
  94. X        Scale image to size of Postscript page.
  95. X      */
  96. X      scale_factor=UpShift(PageWidth-(2*PageSideMargin))/image->columns;
  97. X      if (scale_factor > (UpShift(PageHeight-(2*PageTopMargin))/image->rows))
  98. X        scale_factor=UpShift(PageHeight-(2*PageTopMargin))/image->rows;
  99. X      width=DownShift(image->columns*scale_factor);
  100. X      height=DownShift(image->rows*scale_factor);
  101. X      /*
  102. X        Center image on Postscript page.
  103. X      */
  104. X      delta_x=PageWidth-(width+(2*PageSideMargin));
  105. X      delta_y=PageHeight-(height+(2*PageTopMargin));
  106. X      if (delta_x >= 0)
  107. X        x=delta_x/2+PageSideMargin;
  108. X      else
  109. X        x=PageSideMargin;
  110. X      if (delta_y >= 0)
  111. X        y=delta_y/2+PageTopMargin;
  112. X      else
  113. X        y=PageTopMargin;
  114. X    }
  115. X  /*
  116. X    Output encapsulated Postscript header.
  117. X  */
  118. X  (void) fprintf(image->file,"%%!PS-Adobe-3.0 EPSF-2.0\n");
  119. X  (void) fprintf(image->file,"%%%%Title: %s\n",image->filename);
  120. X  (void) fprintf(image->file,"%%%%Creator: ImageMagick\n");
  121. X  (void) fprintf(image->file,"%%%%BoundingBox: %d %d %d %d\n",x,y,x+(int) width,
  122. X    y+(int) height);
  123. X  (void) fprintf(image->file,"%%%%EndComments\n");
  124. X  /*
  125. X    Output encapsulated Postscript commands.
  126. X  */
  127. X  for (q=Postscript; *q; q++)
  128. X    (void) fprintf(image->file,"%s\n",*q);
  129. X  /*
  130. X    Output image data.
  131. X  */
  132. X  if (image->compression == RunlengthEncodedCompression)
  133. X    CompressImage(image);
  134. X  p=image->pixels;
  135. X  switch (image->class)
  136. X  {
  137. X    case DirectClass:
  138. X    {
  139. X      (void) fprintf(image->file,"%d %d\n%u %u\n%u %u\n%d\n%d\n",x,y,width,
  140. X        height,image->columns,image->rows,(image->class == PseudoClass),
  141. X        image->compression == NoCompression);
  142. X      switch (image->compression)
  143. X      {
  144. X        case RunlengthEncodedCompression:
  145. X        default:
  146. X        {
  147. X          /*
  148. X            Dump runlength-encoded DirectColor packets.
  149. X          */
  150. X          x=0;
  151. X          for (i=0; i < image->packets; i++)
  152. X          {
  153. X            x++;
  154. X            (void) fprintf(image->file,"%02x%02x%02x%02x",p->red,p->green,
  155. X              p->blue,p->length);
  156. X            if (x == 9)
  157. X              {
  158. X                x=0;
  159. X                (void) fprintf(image->file,"\n");
  160. X              }
  161. X            p++;
  162. X          }
  163. X          break;
  164. X        }
  165. X        case NoCompression:
  166. X        {
  167. X          /*
  168. X            Dump uncompressed DirectColor packets.
  169. X          */
  170. X          x=0;
  171. X          for (i=0; i < image->packets; i++)
  172. X          {
  173. X            for (j=0; j <= ((int) p->length); j++)
  174. X            {
  175. X              x++;
  176. X              (void) fprintf(image->file,"%02x%02x%02x",p->red,p->green,
  177. X                p->blue);
  178. X              if (x == 12)
  179. X                {
  180. X                  x=0;
  181. X                  (void) fprintf(image->file,"\n");
  182. X                }
  183. X            }
  184. X            p++;
  185. X          }
  186. X          break;
  187. X        }
  188. X      }
  189. X      break;
  190. X    }
  191. X    case PseudoClass:
  192. X    {
  193. X      (void) fprintf(image->file,"%d %d\n%u %u\n%u %u\n%d\n%d\n",x,y,width,
  194. X        height,image->columns,image->rows,(image->class == PseudoClass),
  195. X        image->compression == NoCompression);
  196. X      /*
  197. X        Dump number of colors and colormap.
  198. X      */
  199. X      (void) fprintf(image->file,"%u\n",image->colors);
  200. X      for (i=0; i < image->colors; i++)
  201. X        (void) fprintf(image->file,"%02x%02x%02x\n",image->colormap[i].red,
  202. X          image->colormap[i].green,image->colormap[i].blue);
  203. X      switch (image->compression)
  204. X      {
  205. X        case RunlengthEncodedCompression:
  206. X        default:
  207. X        {
  208. X          /*
  209. X            Dump runlength-encoded PseudoColor packets.
  210. X          */
  211. X          x=0;
  212. X          for (i=0; i < image->packets; i++)
  213. X          {
  214. X            x++;
  215. X            (void) fprintf(image->file,"%02x%02x",p->index,p->length);
  216. X            if (x == 18)
  217. X              {
  218. X                x=0;
  219. X                (void) fprintf(image->file,"\n");
  220. X              }
  221. X            p++;
  222. X          }
  223. X          break;
  224. X        }
  225. X        case NoCompression:
  226. X        {
  227. X          /*
  228. X            Dump uncompressed PseudoColor packets.
  229. X          */
  230. X          x=0;
  231. X          for (i=0; i < image->packets; i++)
  232. X          {
  233. X            for (j=0; j <= ((int) p->length); j++)
  234. X            {
  235. X              x++;
  236. X              (void) fprintf(image->file,"%02x",p->index);
  237. X              if (x == 36)
  238. X                {
  239. X                  x=0;
  240. X                  (void) fprintf(image->file,"\n");
  241. X                }
  242. X            }
  243. X            p++;
  244. X          }
  245. X        }
  246. X        break;
  247. X      }
  248. X    }
  249. X  }
  250. X  (void) fprintf(image->file,"\n\n");
  251. X  (void) fprintf(image->file,"%%%%Trailer\n");
  252. X  CloseImage(image);
  253. X  return(True);
  254. }
  255. X
  256. /*
  257. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  258. %                                                                             %
  259. %                                                                             %
  260. %                                                                             %
  261. %  R e a d D a t a                                                            %
  262. %                                                                             %
  263. %                                                                             %
  264. %                                                                             %
  265. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  266. %
  267. %  Function ReadData reads data from the image file and returns it.  If it
  268. %  cannot read the requested number of items, False is returned indicating
  269. %  an error.
  270. %
  271. %  The format of the ReadData routine is:
  272. %
  273. %      status=ReadData(data,size,number_items,file)
  274. %
  275. %  A description of each parameter follows:
  276. %
  277. %    o status:  Function ReadData returns True if all the data requested
  278. %      is obtained without error, otherwise False.
  279. %
  280. %    o data:  Specifies an area to place the information reuested from
  281. %      the file.
  282. %
  283. %    o size:  Specifies an integer representing the length of an
  284. %      individual item to be read from the file.
  285. %
  286. %    o number_items:  Specifies an integer representing the number of items
  287. %      to read from the file.
  288. %
  289. %    o file:  Specifies a file to read the data.
  290. %
  291. %
  292. */
  293. unsigned int ReadData(data,size,number_items,file)
  294. char
  295. X  *data;
  296. X
  297. int
  298. X  size,
  299. X  number_items;
  300. X
  301. FILE
  302. X  *file;
  303. {
  304. X  size*=number_items;
  305. X  while (size > 0)
  306. X  {
  307. X    number_items=fread(data,1,size,file);
  308. X    if (number_items <= 0)
  309. X      return(False);
  310. X    size-=number_items;
  311. X    data+=number_items;
  312. X  }
  313. X  return(True);
  314. }
  315. X
  316. /*
  317. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  318. %                                                                             %
  319. %                                                                             %
  320. %                                                                             %
  321. %  R e a d D a t a B l o c k                                                  %
  322. %                                                                             %
  323. %                                                                             %
  324. %                                                                             %
  325. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  326. %
  327. %  Function ReadDataBlock reads data from the image file and returns it.  The
  328. %  amount of data is determined by first reading a count byte.  If
  329. %  ReadDataBlock cannot read the requested number of items, `-1' is returned
  330. %  indicating an error.
  331. %
  332. %  The format of the ReadData routine is:
  333. %
  334. %      status=ReadData(data,file)
  335. %
  336. %  A description of each parameter follows:
  337. %
  338. %    o status:  Function ReadData returns the number of characters read
  339. %      unless the is an error, otherwise `-1'.
  340. %
  341. %    o data:  Specifies an area to place the information reuested from
  342. %      the file.
  343. %
  344. %    o file:  Specifies a file to read the data.
  345. %
  346. %
  347. */
  348. int ReadDataBlock(data,file)
  349. char
  350. X  *data;
  351. X
  352. FILE
  353. X  *file;
  354. {
  355. X  unsigned char
  356. X    count;
  357. X
  358. X  unsigned int
  359. X    status;
  360. X
  361. X  status=ReadData((char *) &count,1,1,file);
  362. X  if (status == False)
  363. X    return(-1);
  364. X  if (count == 0)
  365. X    return(0);
  366. X  status=ReadData(data,1,(int) count,file);
  367. X  if (status == False)
  368. X    return(-1);
  369. X  return(count);
  370. }
  371. X
  372. /*
  373. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  374. %                                                                             %
  375. %                                                                             %
  376. %                                                                             %
  377. %   R e a d I m a g e                                                         %
  378. %                                                                             %
  379. %                                                                             %
  380. %                                                                             %
  381. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  382. %
  383. %  Function ReadImage reads an image file and returns it.  It allocates the
  384. %  memory necessary for the new Image structure and returns a pointer to the
  385. %  new image.
  386. %
  387. %  The format of the ReadImage routine is:
  388. %
  389. %      image=ReadImage(filename)
  390. %
  391. %  A description of each parameter follows:
  392. %
  393. %    o image: Function ReadImage returns a pointer to the image after reading.
  394. %      A null image is returned if there is a a memory shortage or if the
  395. %      image cannot be read.
  396. %
  397. %    o filename: Specifies the name of the image to read.
  398. %
  399. %
  400. */
  401. Image *ReadImage(filename)
  402. char
  403. X  *filename;
  404. {
  405. #define MaxKeywordLength  2048
  406. X
  407. X  char
  408. X    keyword[MaxKeywordLength],
  409. X    value[MaxKeywordLength];
  410. X
  411. X  Image
  412. X    *image;
  413. X
  414. X  register int
  415. X    c,
  416. X    i;
  417. X
  418. X  register unsigned char
  419. X    *p;
  420. X
  421. X  unsigned int
  422. X    max_characters,
  423. X    packet_size,
  424. X    status;
  425. X
  426. X  unsigned long int
  427. X    count,
  428. X    packets;
  429. X
  430. X  /*
  431. X    Allocate image structure.
  432. X  */
  433. X  image=AllocateImage("MIFF");
  434. X  if (image == (Image *) NULL)
  435. X    return((Image *) NULL);
  436. X  /*
  437. X    Open image file.
  438. X  */
  439. X  (void) strcpy(image->filename,filename);
  440. X  OpenImage(image,"r");
  441. X  if (image->file == (FILE *) NULL)
  442. X    {
  443. X      Warning("unable to open file",image->filename);
  444. X      DestroyImage(image);
  445. X      return((Image *) NULL);
  446. X    }
  447. X  /*
  448. X    Decode image header;  header terminates one character beyond a ':'.
  449. X  */
  450. X  c=fgetc(image->file);
  451. X  if (c == EOF)
  452. X    {
  453. X      DestroyImage(image);
  454. X      return((Image *) NULL);
  455. X    }
  456. X  do
  457. X  {
  458. X    /*
  459. X      Decode image header;  header terminates one character beyond a ':'.
  460. X    */
  461. X    image->compression=NoCompression;
  462. X    while (isgraph(c) && (c != ':'))
  463. X    {
  464. X      register char
  465. X        *p;
  466. X
  467. X      if (c == '{')
  468. X        {
  469. X          /*
  470. X            Comment.
  471. X          */
  472. X          max_characters=2048;
  473. X          image->comments=(char *) malloc(max_characters*sizeof(char));
  474. X          if (image->comments == (char *) NULL)
  475. X            {
  476. X              Warning("unable to read image","memory allocation failed");
  477. X              DestroyImages(image);
  478. X              return((Image *) NULL);
  479. X            }
  480. X          p=image->comments;
  481. X          *p='\0';
  482. X          c=fgetc(image->file);
  483. X          while ((isgraph(c) || isspace(c)) && (c != '}'))
  484. X          {
  485. X            if (p >= (image->comments+max_characters-1))
  486. X              {
  487. X                /*
  488. X                  Allocate more memory for the comment.
  489. X                */
  490. X                max_characters<<=1;
  491. X                image->comments=(char *)
  492. X                  realloc((char *) image->comments,max_characters);
  493. X                if (image->comments == (char *) NULL)
  494. X                  {
  495. X                    Warning("unable to read image","memory allocation failed");
  496. X                    DestroyImages(image);
  497. X                    return((Image *) NULL);
  498. X                  }
  499. X                p=image->comments+strlen(image->comments);
  500. X              }
  501. X            *p++=(unsigned char) c;
  502. X            c=fgetc(image->file);
  503. X          }
  504. X          *p='\0';
  505. X          c=fgetc(image->file);
  506. X        }
  507. X      else
  508. X        if (isalnum(c))
  509. X          {
  510. X            /*
  511. X              Determine a keyword and its value.
  512. X            */
  513. X            p=keyword;
  514. X            do
  515. X            {
  516. X              if ((p-keyword) < (MaxKeywordLength-1))
  517. X                *p++=(char) c;
  518. X              c=fgetc(image->file);
  519. X            } while (isalnum(c));
  520. X            *p='\0';
  521. X            while (isspace(c) || (c == '='))
  522. X              c=fgetc(image->file);
  523. X            p=value;
  524. X            while (!isspace(c))
  525. X            {
  526. X              if ((p-value) < (MaxKeywordLength-1))
  527. X                *p++=(char) c;
  528. X              c=fgetc(image->file);
  529. X            }
  530. X            *p='\0';
  531. X            /*
  532. X              Assign a value to the specified keyword.
  533. X            */
  534. X            if (strcmp(keyword,"alpha") == 0)
  535. X              if ((strcmp(value,"True") == 0) || (strcmp(value,"true") == 0))
  536. X                image->alpha=True;
  537. X              else
  538. X                image->class=False;
  539. X            if (strcmp(keyword,"class") == 0)
  540. X              if (strcmp(value,"PseudoClass") == 0)
  541. X                image->class=PseudoClass;
  542. X              else
  543. X                if (strcmp(value,"DirectClass") == 0)
  544. X                  image->class=DirectClass;
  545. X                else
  546. X                  image->class=UndefinedClass;
  547. X            if (strcmp(keyword,"colors") == 0)
  548. X              image->colors=(unsigned int) atoi(value);
  549. X            if (strcmp(keyword,"compression") == 0)
  550. X              if (strcmp(value,"QEncoded") == 0)
  551. X                image->compression=QEncodedCompression;
  552. X              else
  553. X                if (strcmp(value,"RunlengthEncoded") == 0)
  554. X                  image->compression=RunlengthEncodedCompression;
  555. X                else
  556. X                  image->compression=UndefinedCompression;
  557. X            if (strcmp(keyword,"columns") == 0)
  558. X              image->columns=(unsigned int) atoi(value);
  559. X            if (strcmp(keyword,"id") == 0)
  560. X              if (strcmp(value,"ImageMagick") == 0)
  561. X                image->id=ImageMagickId;
  562. X              else
  563. X                image->id=UndefinedId;
  564. X            if (strcmp(keyword,"montage") == 0)
  565. X              {
  566. X                image->montage=(char *) malloc(strlen(value)+1*sizeof(char));
  567. X                if (image->montage == (char *) NULL)
  568. X                  {
  569. X                    Warning("unable to read image","memory allocation failed");
  570. X                    DestroyImages(image);
  571. X                    return((Image *) NULL);
  572. X                  }
  573. X                (void) strcpy(image->montage,value);
  574. X              }
  575. X            if (strcmp(keyword,"packets") == 0)
  576. X              image->packets=(unsigned int) atoi(value);
  577. X            if (strcmp(keyword,"rows") == 0)
  578. X              image->rows=(unsigned int) atoi(value);
  579. X            if (strcmp(keyword,"scene") == 0)
  580. X              image->scene=(unsigned int) atoi(value);
  581. X            if (strcmp(keyword,"signature") == 0)
  582. X              {
  583. X                image->signature=(char *)
  584. X                  malloc((strlen(value)+1)*sizeof(char));
  585. X                if (image->signature == (char *) NULL)
  586. X                  {
  587. X                    Warning("unable to read image","memory allocation failed");
  588. X                    DestroyImages(image);
  589. X                    return((Image *) NULL);
  590. X                  }
  591. X                (void) strcpy(image->signature,value);
  592. X              }
  593. X          }
  594. X        else
  595. X          c=fgetc(image->file);
  596. X      while (isspace(c))
  597. X        c=fgetc(image->file);
  598. X    }
  599. X    (void) fgetc(image->file);
  600. X    /*
  601. X      Verify that required image information is defined.
  602. X    */
  603. X    if ((image->id == UndefinedId) || (image->class == UndefinedClass) ||
  604. X        (image->compression == UndefinedCompression) || (image->columns == 0) ||
  605. X        (image->rows == 0))
  606. X      {
  607. X        Warning("incorrect image header in file",image->filename);
  608. X        DestroyImages(image);
  609. X        return((Image *) NULL);
  610. X      }
  611. X    if ((image->columns*image->rows) > MaxImageSize)
  612. X      {
  613. X        Warning("unable to read image","image size too large");
  614. X        DestroyImages(image);
  615. X        return((Image *) NULL);
  616. X      }
  617. X    if (image->montage != (char *) NULL)
  618. X      {
  619. X        register char
  620. X          *p;
  621. X
  622. X        /*
  623. X          Tiling directory.
  624. X        */
  625. X        max_characters=2048;
  626. X        image->directory=(char *) malloc(max_characters*sizeof(char));
  627. X        if (image->directory == (char *) NULL)
  628. X          {
  629. X            Warning("unable to read image","memory allocation failed");
  630. X            DestroyImages(image);
  631. X            return((Image *) NULL);
  632. X          }
  633. X        p=image->directory;
  634. X        do
  635. X        {
  636. X          if (p >= (image->directory+max_characters-1))
  637. X            {
  638. X              /*
  639. X                Allocate more memory for the comment.
  640. X              */
  641. X              max_characters<<=1;
  642. X              image->directory=(char *)
  643. X                realloc((char *) image->directory,max_characters);
  644. X              if (image->directory == (char *) NULL)
  645. X                {
  646. X                  Warning("unable to read image","memory allocation failed");
  647. X                  DestroyImages(image);
  648. X                  return((Image *) NULL);
  649. X                }
  650. X              p=image->comments+strlen(image->comments);
  651. X            }
  652. X          c=fgetc(image->file);
  653. X          *p++=(unsigned char) c;
  654. X        } while (c != '\0');
  655. X      }
  656. X    if (image->class == PseudoClass)
  657. X      {
  658. X        unsigned int
  659. X          colors;
  660. X
  661. X        /*
  662. X          PseudoClass image cannot have alpha data or be QEncoded.
  663. X        */
  664. X        if (image->alpha)
  665. X          {
  666. X            Warning("unable to read image","alpha images must be DirectClass");
  667. X            DestroyImages(image);
  668. X            return((Image *) NULL);
  669. X          }
  670. X        if (image->compression == QEncodedCompression)
  671. X          {
  672. X            Warning("unable to read image",
  673. X              "QEncoded images must be DirectClass");
  674. X            DestroyImages(image);
  675. X            return((Image *) NULL);
  676. X          }
  677. X        /*
  678. X          Create image colormap.
  679. X        */
  680. X        colors=image->colors;
  681. X        if (colors == 0)
  682. X          colors=256;
  683. X        image->colormap=(ColorPacket *) malloc(colors*sizeof(ColorPacket));
  684. X        if (image->colormap == (ColorPacket *) NULL)
  685. X          {
  686. X            Warning("unable to read image","memory allocation failed");
  687. X            DestroyImages(image);
  688. X            return((Image *) NULL);
  689. X          }
  690. X        if (image->colors == 0)
  691. X          for (i=0; i < colors; i++)
  692. X          {
  693. X            image->colormap[i].red=(unsigned char) i;
  694. X            image->colormap[i].green=(unsigned char) i;
  695. X            image->colormap[i].blue=(unsigned char) i;
  696. X            image->colors++;
  697. X          }
  698. X        else
  699. X          {
  700. X            unsigned char
  701. X              *colormap;
  702. X
  703. X            /*
  704. X              Read image colormap from file.
  705. X            */
  706. X            colormap=(unsigned char *)
  707. X              malloc(3*image->colors*sizeof(unsigned char));
  708. X            if (colormap == (unsigned char *) NULL)
  709. X              {
  710. X                Warning("unable to read image","memory allocation failed");
  711. X                DestroyImages(image);
  712. X                return((Image *) NULL);
  713. X              }
  714. X            (void) ReadData((char *) colormap,1,(int) (3*image->colors),
  715. X              image->file);
  716. X            p=colormap;
  717. X            for (i=0; i < image->colors; i++)
  718. X            {
  719. X              image->colormap[i].red=(*p++);
  720. X              image->colormap[i].green=(*p++);
  721. X              image->colormap[i].blue=(*p++);
  722. X            }
  723. X            (void) free((char *) colormap);
  724. X          }
  725. X      }
  726. X    /*
  727. X      Determine packed packet size.
  728. X    */
  729. X    if (image->class == PseudoClass)
  730. X      {
  731. X        image->packet_size=1;
  732. X        if (image->colors > 256)
  733. X          image->packet_size++;
  734. X      }
  735. X    else
  736. X      {
  737. X        image->packet_size=3;
  738. X        if (image->alpha)
  739. X          image->packet_size++;
  740. X      }
  741. X    if (image->compression == RunlengthEncodedCompression)
  742. X      image->packet_size++;
  743. X    packet_size=image->packet_size;
  744. X    if (image->compression == QEncodedCompression)
  745. X      packet_size=1;
  746. X    /*
  747. X      Allocate image pixels.
  748. X    */
  749. X    if (image->compression == NoCompression)
  750. X      image->packets=image->columns*image->rows;
  751. X    packets=image->packets;
  752. X    if (image->packets == 0)
  753. X      packets=image->columns*image->rows;
  754. X    image->packed_pixels=(unsigned char *)
  755. X      malloc((unsigned int) packets*packet_size*sizeof(unsigned char));
  756. X    if (image->packed_pixels == (unsigned char *) NULL)
  757. X      {
  758. X        Warning("unable to read image","memory allocation failed");
  759. X        DestroyImages(image);
  760. X        return((Image *) NULL);
  761. X      }
  762. X    /*
  763. X      Read image pixels from file.
  764. X    */
  765. X    if ((image->compression != RunlengthEncodedCompression) ||
  766. X        (image->packets != 0))
  767. X      (void) ReadData((char *) image->packed_pixels,1,
  768. X        (int) (packets*packet_size),image->file);
  769. X    else
  770. X      {
  771. X        /*
  772. X          Number of runlength packets is unspecified.
  773. X        */
  774. X        count=0;
  775. X        p=image->packed_pixels;
  776. X        do
  777. X        {
  778. X          (void) ReadData((char *) p,1,(int) packet_size,image->file);
  779. X          image->packets++;
  780. X          p+=(packet_size-1);
  781. X          count+=(*p+1);
  782. X          p++;
  783. X        }
  784. X        while (count < (image->columns*image->rows));
  785. X      }
  786. X    if (image->compression ==  QEncodedCompression)
  787. X      {
  788. X        unsigned char
  789. X          *compressed_pixels;
  790. X
  791. X        /*
  792. X          Uncompress image pixels with Q encoding.
  793. X        */
  794. X        image->packets=image->columns*image->rows;
  795. X        compressed_pixels=image->packed_pixels;
  796. X        image->packed_pixels=(unsigned char *) malloc((unsigned int)
  797. X          image->packets*image->packet_size*sizeof(unsigned char));
  798. X        if (image->packed_pixels == (unsigned char *) NULL)
  799. X          {
  800. X            Warning("unable to write image","memory allocation failed");
  801. X            DestroyImage(image);
  802. X            return(False);
  803. X          }
  804. X        packets=QDecodeImage(compressed_pixels,image->packed_pixels,
  805. X          image->columns*(int) image->packet_size,image->rows);
  806. X        if (packets != (image->packets*image->packet_size))
  807. X          {
  808. X            Warning("Q encoding failed",image->filename);
  809. X            DestroyImages(image);
  810. X            return((Image *) NULL);
  811. X          }
  812. X        (void) free((char *) compressed_pixels);
  813. X      }
  814. X    /*
  815. X      Unpack the packed image pixels into runlength-encoded pixel packets.
  816. X    */
  817. X    status=UnpackImage(image);
  818. X    if (status == False)
  819. X      {
  820. X        DestroyImages(image);
  821. X        return((Image *) NULL);
  822. X      }
  823. X    /*
  824. X      Proceed to next image.
  825. X    */
  826. X    do
  827. X    {
  828. X      c=fgetc(image->file);
  829. X    } while (!isgraph(c) && (c != EOF));
  830. X    if (c != EOF)
  831. X      {
  832. X        /*
  833. X          Allocate image structure.
  834. X        */
  835. X        image->next=AllocateImage("MIFF");
  836. X        if (image->next == (Image *) NULL)
  837. X          {
  838. X            DestroyImages(image);
  839. X            return((Image *) NULL);
  840. X          }
  841. X        image->next->file=image->file;
  842. X        (void) sprintf(image->next->filename,"%s.%u\0",filename,image->scene+1);
  843. X        image->next->scene=image->scene+1;
  844. X        image->next->last=image;
  845. X        image=image->next;
  846. X      }
  847. X  } while (c != EOF);
  848. X  while (image->last != (Image *) NULL)
  849. X    image=image->last;
  850. X  CloseImage(image);
  851. X  return(image);
  852. }
  853. X
  854. /*
  855. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  856. %                                                                             %
  857. %                                                                             %
  858. %                                                                             %
  859. %   R e d u c e I m a g e                                                     %
  860. %                                                                             %
  861. %                                                                             %
  862. %                                                                             %
  863. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  864. %
  865. %  Function ReduceImage creates a new image that is a integral size less than
  866. %  an existing one.  It allocates the memory necessary for the new Image
  867. %  structure and returns a pointer to the new image.
  868. %
  869. %  ReduceImage scans the reference image to create a reduced image by computing
  870. %  the weighted average of a 4x4 cell centered at each reference pixel.  The
  871. %  target pixel requires two columns and two rows of the reference pixels.
  872. %  Therefore the reduced image columns and rows become:
  873. %
  874. %    number_columns/2
  875. %    number_rows/2
  876. %
  877. %  Weights assume that the importance of neighboring pixels is inversely
  878. %  proportional to the square of their distance from the target pixel.
  879. %
  880. %  The scan only processes pixels that have a full set of neighbors.  Pixels
  881. %  in the top, bottom, left, and right pairs of rows and columns are omitted
  882. %  from the scan.
  883. %
  884. %  The format of the ReduceImage routine is:
  885. %
  886. %      reduced_image=ReduceImage(image)
  887. %
  888. %  A description of each parameter follows:
  889. %
  890. %    o reduced_image: Function ReduceImage returns a pointer to the image
  891. %      after reducing.  A null image is returned if there is a a memory
  892. %      shortage or if the image size is less than IconSize*2.
  893. %
  894. %    o image: The address of a structure of type Image.
  895. %
  896. %
  897. */
  898. Image *ReduceImage(image)
  899. Image
  900. X  *image;
  901. {
  902. #define Rsum(weight) \
  903. X  total_red+=weight*(s->red); \
  904. X  total_green+=weight*(s->green); \
  905. X  total_blue+=weight*(s->blue); \
  906. X  total_alpha+=weight*(s->index); \
  907. X  s++;
  908. X
  909. X  ColorPacket
  910. X    *scanline;
  911. X
  912. X  Image
  913. X    *reduced_image;
  914. X
  915. X  register ColorPacket
  916. X    *s,
  917. X    *s0,
  918. X    *s1,
  919. X    *s2,
  920. X    *s3;
  921. X
  922. X  register RunlengthPacket
  923. X    *p,
  924. X    *q;
  925. X
  926. X  register unsigned int
  927. X    x;
  928. X
  929. X  unsigned int
  930. X    y;
  931. X
  932. X  unsigned long
  933. X    total_alpha,
  934. X    total_blue,
  935. X    total_green,
  936. X    total_red;
  937. X
  938. X  if ((image->columns < 4) || (image->rows < 4))
  939. X    {
  940. X      Warning("unable to reduce image","image size must exceed 3x3");
  941. X      return((Image *) NULL);
  942. X    }
  943. X  /*
  944. X    Initialize reduced image attributes.
  945. X  */
  946. X  reduced_image=CopyImage(image,image->columns >> 1,image->rows >> 1,False);
  947. X  if (reduced_image == (Image *) NULL)
  948. X    {
  949. X      Warning("unable to reduce image","memory allocation failed");
  950. X      return((Image *) NULL);
  951. X    }
  952. X  reduced_image->class=DirectClass;
  953. X  /*
  954. X    Allocate image buffer and scanline buffer for 4 rows of the image.
  955. X  */
  956. X  scanline=(ColorPacket *) malloc(4*image->columns*sizeof(ColorPacket));
  957. X  if (scanline == (ColorPacket *) NULL)
  958. X    {
  959. X      Warning("unable to reduce image","memory allocation failed");
  960. X      DestroyImage(reduced_image);
  961. X      return((Image *) NULL);
  962. X    }
  963. X  /*
  964. X    Preload the first 2 rows of the image.
  965. X  */
  966. X  p=image->pixels;
  967. X  image->runlength=p->length+1;
  968. X  s=scanline;
  969. X  for (x=0; x < (2*image->columns); x++)
  970. X  {
  971. X    if (image->runlength > 0)
  972. X      image->runlength--;
  973. X    else
  974. X      {
  975. X        p++;
  976. X        image->runlength=p->length;
  977. X      }
  978. X    s->red=p->red;
  979. X    s->green=p->green;
  980. X    s->blue=p->blue;
  981. X    s->index=p->index;
  982. X    s++;
  983. X  }
  984. X  /*
  985. X    Reduce each row.
  986. X  */
  987. X  p=image->pixels;
  988. X  image->runlength=p->length+1;
  989. X  q=reduced_image->pixels;
  990. X  for (y=0; y < (image->rows-1); y+=2)
  991. X  {
  992. X    /*
  993. X      Initialize sliding window pointers.
  994. X    */
  995. X    s0=scanline+image->columns*((y+0) % 4);
  996. X    s1=scanline+image->columns*((y+1) % 4);
  997. X    s2=scanline+image->columns*((y+2) % 4);
  998. X    s3=scanline+image->columns*((y+3) % 4);
  999. X    /*
  1000. X      Read another scan line.
  1001. X    */
  1002. X    s=s2;
  1003. X    for (x=0; x < image->columns; x++)
  1004. X    {
  1005. X      if (image->runlength > 0)
  1006. X        image->runlength--;
  1007. X      else
  1008. X        {
  1009. X          p++;
  1010. X          image->runlength=p->length;
  1011. X        }
  1012. X      s->red=p->red;
  1013. X      s->green=p->green;
  1014. X      s->blue=p->blue;
  1015. X      s->index=p->index;
  1016. X      s++;
  1017. X    }
  1018. X    /*
  1019. X      Read another scan line.
  1020. X    */
  1021. X    s=s3;
  1022. X    for (x=0; x < image->columns; x++)
  1023. X    {
  1024. X      if (image->runlength > 0)
  1025. X        image->runlength--;
  1026. X      else
  1027. X        {
  1028. X          p++;
  1029. X          image->runlength=p->length;
  1030. X        }
  1031. X      s->red=p->red;
  1032. X      s->green=p->green;
  1033. X      s->blue=p->blue;
  1034. X      s->index=p->index;
  1035. X      s++;
  1036. X    }
  1037. X    for (x=0; x < (image->columns-1); x+=2)
  1038. X    {
  1039. X      /*
  1040. X        Compute weighted average of target pixel color components.
  1041. X
  1042. X        These particular coefficients total to 128.  Use 128/2-1 or 63 to
  1043. X        insure correct round off.
  1044. X      */
  1045. X      total_red=0;
  1046. X      total_green=0;
  1047. X      total_blue=0;
  1048. X      total_alpha=0;
  1049. X      s=s0;
  1050. X      Rsum(3); Rsum(7);  Rsum(7);  Rsum(3);
  1051. X      s=s1;
  1052. X      Rsum(7); Rsum(15); Rsum(15); Rsum(7);
  1053. X      s=s2;
  1054. X      Rsum(7); Rsum(15); Rsum(15); Rsum(7);
  1055. X      s=s3;
  1056. X      Rsum(3); Rsum(7);  Rsum(7);  Rsum(3);
  1057. X      s0+=2;
  1058. X      s1+=2;
  1059. X      s2+=2;
  1060. X      s3+=2;
  1061. X      q->red=(unsigned char) ((total_red+63) >> 7);
  1062. X      q->green=(unsigned char) ((total_green+63) >> 7);
  1063. X      q->blue=(unsigned char) ((total_blue+63) >> 7);
  1064. X      q->index=(unsigned char) ((total_alpha+63) >> 7);
  1065. X      q->length=0;
  1066. X      q++;
  1067. X    }
  1068. X  }
  1069. X  (void) free((char *) scanline);
  1070. X  return(reduced_image);
  1071. }
  1072. X
  1073. /*
  1074. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1075. %                                                                             %
  1076. %                                                                             %
  1077. %                                                                             %
  1078. %   R e f l e c t I m a g e                                                   %
  1079. %                                                                             %
  1080. %                                                                             %
  1081. %                                                                             %
  1082. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1083. %
  1084. %  Function ReflectImage creates a new image that refelects each scanline of an
  1085. %  existing one.  It allocates the memory necessary for the new Image structure
  1086. %  and returns a pointer to the new image.
  1087. %
  1088. %  The format of the ReflectImage routine is:
  1089. %
  1090. %      reflected_image=ReflectImage(image)
  1091. %
  1092. %  A description of each parameter follows:
  1093. %
  1094. %    o reflected_image: Function ReflectImage returns a pointer to the image
  1095. %      after reflecting.  A null image is returned if there is a memory
  1096. %      shortage.
  1097. %
  1098. %    o image: The address of a structure of type Image.
  1099. %
  1100. %
  1101. */
  1102. Image *ReflectImage(image)
  1103. Image
  1104. X  *image;
  1105. {
  1106. X  ColorPacket
  1107. X    *scanline;
  1108. X
  1109. X  Image
  1110. X    *reflected_image;
  1111. X
  1112. X  register ColorPacket
  1113. X    *s;
  1114. X
  1115. X  register RunlengthPacket
  1116. X    *p,
  1117. X    *q;
  1118. X
  1119. X  register unsigned int
  1120. X    x,
  1121. X    y;
  1122. X
  1123. X  /*
  1124. X    Initialize reflected image attributes.
  1125. X  */
  1126. X  reflected_image=CopyImage(image,image->columns,image->rows,False);
  1127. X  if (reflected_image == (Image *) NULL)
  1128. X    {
  1129. X      Warning("unable to reflect image","memory allocation failed");
  1130. X      return((Image *) NULL);
  1131. X    }
  1132. X  /*
  1133. X    Allocate scan line buffer and column offset buffers.
  1134. X  */
  1135. X  scanline=(ColorPacket *) malloc(image->columns*sizeof(ColorPacket));
  1136. X  if (scanline == (ColorPacket *) NULL)
  1137. X    {
  1138. X      Warning("unable to reflect image","memory allocation failed");
  1139. X      DestroyImage(reflected_image);
  1140. X      return((Image *) NULL);
  1141. X    }
  1142. X  /*
  1143. X    Reflect each row.
  1144. X  */
  1145. X  p=image->pixels;
  1146. X  image->runlength=p->length+1;
  1147. X  q=reflected_image->pixels;
  1148. X  for (y=0; y < reflected_image->rows; y++)
  1149. X  {
  1150. X    /*
  1151. X      Read a scan line.
  1152. X    */
  1153. X    s=scanline;
  1154. X    for (x=0; x < image->columns; x++)
  1155. X    {
  1156. X      if (image->runlength > 0)
  1157. X        image->runlength--;
  1158. X      else
  1159. X        {
  1160. X          p++;
  1161. X          image->runlength=p->length;
  1162. X        }
  1163. X      s->red=p->red;
  1164. X      s->green=p->green;
  1165. X      s->blue=p->blue;
  1166. X      s->index=p->index;
  1167. X      s++;
  1168. X    }
  1169. X    /*
  1170. X      Reflect each column.
  1171. X    */
  1172. X    s=scanline+image->columns;
  1173. X    for (x=0; x < reflected_image->columns; x++)
  1174. X    {
  1175. X      s--;
  1176. X      q->red=s->red;
  1177. X      q->green=s->green;
  1178. X      q->blue=s->blue;
  1179. X      q->index=s->index;
  1180. X      q->length=0;
  1181. X      q++;
  1182. X    }
  1183. X  }
  1184. X  (void) free((char *) scanline);
  1185. X  return(reflected_image);
  1186. }
  1187. X
  1188. /*
  1189. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1190. %                                                                             %
  1191. %                                                                             %
  1192. %     R G B T r a n s f o r m I m a g e                                       %
  1193. %                                                                             %
  1194. %                                                                             %
  1195. %                                                                             %
  1196. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1197. %
  1198. %  Procedure RGBTransformImage converts the reference image from RGB to
  1199. %  an alternate colorspace.
  1200. %
  1201. %  The format of the RGBTransformImage routine is:
  1202. %
  1203. %      RGBTransformImage(image,colorspace)
  1204. %
  1205. %  A description of each parameter follows:
  1206. %
  1207. %    o image: The address of a structure of type Image;  returned from
  1208. %      ReadImage.
  1209. %
  1210. %    o colorspace: An unsigned integer value that indicates which colorspace
  1211. %      to transform the image.
  1212. %
  1213. %
  1214. */
  1215. void RGBTransformImage(image,colorspace)
  1216. Image
  1217. X  *image;
  1218. X
  1219. unsigned int
  1220. X  colorspace;
  1221. {
  1222. #define X 0
  1223. #define Y (MaxRGB+1)
  1224. #define Z (MaxRGB+1)*2
  1225. X
  1226. X  long int
  1227. X    tx,
  1228. X    ty,
  1229. X    tz,
  1230. X    *x,
  1231. X    *y,
  1232. X    *z;
  1233. X
  1234. X  register int
  1235. X    blue,
  1236. X    green,
  1237. X    i,
  1238. X    red;
  1239. X
  1240. X  register RunlengthPacket
  1241. X    *p;
  1242. X
  1243. X  register unsigned char
  1244. X    *range_limit;
  1245. X
  1246. X  unsigned char
  1247. X    *range_table;
  1248. X
  1249. X  if (colorspace == RGBColorspace)
  1250. X    return;
  1251. X  /*
  1252. X    Allocate the tables.
  1253. X  */
  1254. X  x=(long int *) malloc(3*(MaxRGB+1)*sizeof(long int));
  1255. X  y=(long int *) malloc(3*(MaxRGB+1)*sizeof(long int));
  1256. X  z=(long int *) malloc(3*(MaxRGB+1)*sizeof(long int));
  1257. X  range_table=(unsigned char *) malloc(3*(MaxRGB+1)*sizeof(unsigned char));
  1258. X  if ((x == (long int *) NULL) || (y == (long int *) NULL) ||
  1259. X      (z == (long int *) NULL) || (range_table == (unsigned char *) NULL))
  1260. X    {
  1261. X      Warning("unable to transform color space","memory allocation failed");
  1262. X      return;
  1263. X    }
  1264. X  /*
  1265. X    Pre-compute conversion tables.
  1266. X  */
  1267. X  for (i=0; i <= MaxRGB; i++)
  1268. X  {
  1269. X    range_table[i]=0;
  1270. X    range_table[i+(MaxRGB+1)]=(unsigned char) i;
  1271. X    range_table[i+(MaxRGB+1)*2]=MaxRGB;
  1272. X  }
  1273. X  range_limit=range_table+(MaxRGB+1);
  1274. X  tx=0;
  1275. X  ty=0;
  1276. X  tz=0;
  1277. X  switch (colorspace)
  1278. X  {
  1279. X    case GRAYColorspace:
  1280. X    {
  1281. X      /*
  1282. X        Initialize GRAY tables:
  1283. X
  1284. X          G = 0.29900*R+0.58700*G+0.11400*B
  1285. X      */
  1286. X      for (i=0; i <= MaxRGB; i++)
  1287. X      {
  1288. X        x[i+X]=UpShifted(0.29900)*i;
  1289. X        y[i+X]=UpShifted(0.58700)*i;
  1290. X        z[i+X]=UpShifted(0.11400)*i;
  1291. X        x[i+Y]=UpShifted(0.29900)*i;
  1292. X        y[i+Y]=UpShifted(0.58700)*i;
  1293. X        z[i+Y]=UpShifted(0.11400)*i;
  1294. X        x[i+Z]=UpShifted(0.29900)*i;
  1295. X        y[i+Z]=UpShifted(0.58700)*i;
  1296. X        z[i+Z]=UpShifted(0.11400)*i;
  1297. X      }
  1298. X      break;
  1299. X    }
  1300. X    case YIQColorspace:
  1301. X    {
  1302. X      /*
  1303. X        Initialize YIQ tables:
  1304. X
  1305. X          Y = 0.29900*R+0.58700*G+0.11400*B
  1306. X          I = 0.59600*R-0.27400*G-0.32200*B
  1307. X          Q = 0.21100*R-0.52300*G+0.31200*B
  1308. X      */
  1309. X      for (i=0; i <= MaxRGB; i++)
  1310. X      {
  1311. X        x[i+X]=UpShifted(0.29900)*i;
  1312. X        y[i+X]=UpShifted(0.58700)*i;
  1313. X        z[i+X]=UpShifted(0.11400)*i;
  1314. X        x[i+Y]=UpShifted(0.59600)*i;
  1315. X        y[i+Y]=(-UpShifted(0.27400))*i;
  1316. X        z[i+Y]=(-UpShifted(0.32200))*i;
  1317. X        x[i+Z]=UpShifted(0.21100)*i;
  1318. X        y[i+Z]=(-UpShifted(0.52300))*i;
  1319. X        z[i+Z]=UpShifted(0.31200)*i;
  1320. X      }
  1321. X      break;
  1322. X    }
  1323. X    case YUVColorspace:
  1324. X    default:
  1325. X    {
  1326. X      /*
  1327. X        Initialize YUV tables:
  1328. X
  1329. X          Y =  0.29900*R+0.58700*G+0.11400*B
  1330. X          U = -0.16874*R-0.33126*G+0.50000*B
  1331. X          V =  0.50000*R-0.41869*G-0.08131*B
  1332. X
  1333. X        U and V, normally -0.5 through 0.5, are normalized to the range 0
  1334. X        through MaxRGB.
  1335. X      */
  1336. X      ty=UpShifted((MaxRGB+1)/2);
  1337. X      tz=UpShifted((MaxRGB+1)/2);
  1338. X      for (i=0; i <= MaxRGB; i++)
  1339. X      {
  1340. X        x[i+X]=UpShifted(0.29900)*i;
  1341. X        y[i+X]=UpShifted(0.58700)*i;
  1342. X        z[i+X]=UpShifted(0.11400)*i;
  1343. X        x[i+Y]=(-UpShifted(0.16874))*i;
  1344. X        y[i+Y]=(-UpShifted(0.33126))*i;
  1345. X        z[i+Y]=UpShifted(0.50000)*i;
  1346. X        x[i+Z]=UpShifted(0.50000)*i;
  1347. X        y[i+Z]=(-UpShifted(0.41869))*i;
  1348. X        z[i+Z]=(-UpShifted(0.08131))*i;
  1349. X      }
  1350. X      break;
  1351. X    }
  1352. X    case XYZColorspace:
  1353. X    {
  1354. X      /*
  1355. X        Initialize XYZ tables:
  1356. X
  1357. X          X = 0.49000*R+0.31000*G+0.20000*B
  1358. X          Y = 0.17700*R+0.81300*G+0.01100*B
  1359. X          Z = 0.00000*R+0.01000*G+0.99000*B
  1360. X      */
  1361. X      for (i=0; i <= MaxRGB; i++)
  1362. X      {
  1363. X        x[i+X]=UpShifted(0.49000)*i;
  1364. X        y[i+X]=UpShifted(0.31000)*i;
  1365. X        z[i+X]=UpShifted(0.20000)*i;
  1366. X        x[i+Y]=UpShifted(0.17700)*i;
  1367. X        y[i+Y]=UpShifted(0.81300)*i;
  1368. X        z[i+Y]=UpShifted(0.01100)*i;
  1369. X        x[i+Z]=0;
  1370. X        y[i+Z]=UpShifted(0.01000)*i;
  1371. X        z[i+Z]=UpShifted(0.99000)*i;
  1372. X      }
  1373. X      break;
  1374. X    }
  1375. X  }
  1376. X  /*
  1377. X    Convert from RGB.
  1378. X  */
  1379. X  switch (image->class)
  1380. X  {
  1381. X    case DirectClass:
  1382. X    {
  1383. X      /*
  1384. X        Convert DirectClass image.
  1385. X      */
  1386. X      p=image->pixels;
  1387. X      for (i=0; i < image->packets; i++)
  1388. X      {
  1389. X        red=p->red;
  1390. X        green=p->green;
  1391. X        blue=p->blue;
  1392. X        p->red=range_limit[DownShift(x[red+X]+y[green+X]+z[blue+X]+tx)];
  1393. X        p->green=range_limit[DownShift(x[red+Y]+y[green+Y]+z[blue+Y]+ty)];
  1394. X        p->blue=range_limit[DownShift(x[red+Z]+y[green+Z]+z[blue+Z]+tz)];
  1395. X        p++;
  1396. X      }
  1397. X      break;
  1398. X    }
  1399. X    case PseudoClass:
  1400. X    {
  1401. X      register unsigned short
  1402. X        index;
  1403. X
  1404. X      /*
  1405. X        Convert PseudoClass image.
  1406. X      */
  1407. X      for (i=0; i < image->colors; i++)
  1408. X      {
  1409. X        red=image->colormap[i].red;
  1410. X        green=image->colormap[i].green;
  1411. X        blue=image->colormap[i].blue;
  1412. X        image->colormap[i].red=
  1413. X          range_limit[DownShift(x[red+X]+y[green+X]+z[blue+X]+tx)];
  1414. X        image->colormap[i].green=
  1415. X          range_limit[DownShift(x[red+Y]+y[green+Y]+z[blue+Y]+ty)];
  1416. X        image->colormap[i].blue=
  1417. X          range_limit[DownShift(x[red+Z]+y[green+Z]+z[blue+Z]+tz)];
  1418. X      }
  1419. X      p=image->pixels;
  1420. X      for (i=0; i < image->packets; i++)
  1421. X      {
  1422. X        index=p->index;
  1423. X        p->red=image->colormap[index].red;
  1424. X        p->green=image->colormap[index].green;
  1425. X        p->blue=image->colormap[index].blue;
  1426. X        p++;
  1427. X      }
  1428. X      break;
  1429. X    }
  1430. X  }
  1431. X  /*
  1432. X    Free allocated memory.
  1433. X  */
  1434. X  (void) free((char *) range_table);
  1435. X  (void) free((char *) z);
  1436. X  (void) free((char *) y);
  1437. X  (void) free((char *) x);
  1438. }
  1439. X
  1440. /*
  1441. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1442. %                                                                             %
  1443. %                                                                             %
  1444. %                                                                             %
  1445. %   S c a l e I m a g e                                                       %
  1446. %                                                                             %
  1447. %                                                                             %
  1448. %                                                                             %
  1449. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1450. %
  1451. %  Function ScaleImage creates a new image that is a scaled size of an
  1452. %  existing one using pixel replication.  It allocates the memory necessary
  1453. %  for the new Image structure and returns a pointer to the new image.
  1454. %
  1455. %  The format of the ScaleImage routine is:
  1456. %
  1457. %      scaled_image=ScaleImage(image,columns,rows)
  1458. %
  1459. %  A description of each parameter follows:
  1460. %
  1461. %    o scaled_image: Function ScaleImage returns a pointer to the image after
  1462. %      scaling.  A null image is returned if there is a memory shortage.
  1463. %
  1464. %    o image: The address of a structure of type Image.
  1465. %
  1466. %    o columns: An integer that specifies the number of columns in the scaled
  1467. %      image.
  1468. %
  1469. %    o rows: An integer that specifies the number of rows in the scaled
  1470. %      image.
  1471. %
  1472. %
  1473. */
  1474. Image *ScaleImage(image,columns,rows)
  1475. Image
  1476. X  *image;
  1477. X
  1478. unsigned int
  1479. X  columns,
  1480. X  rows;
  1481. {
  1482. X  ColorPacket
  1483. X    *scanline;
  1484. X
  1485. X  Image
  1486. X    *scaled_image;
  1487. X
  1488. X  register ColorPacket
  1489. X    *s;
  1490. X
  1491. X  register RunlengthPacket
  1492. X    *p,
  1493. X    *q;
  1494. X
  1495. X  register unsigned int
  1496. X    x;
  1497. X
  1498. X  unsigned int
  1499. X    *x_offset,
  1500. X    y,
  1501. X    *y_offset;
  1502. X
  1503. X  unsigned long
  1504. X    scale_factor;
  1505. X
  1506. X  if ((columns == 0) || (rows == 0))
  1507. X    {
  1508. X      Warning("unable to scale image","image dimensions are zero");
  1509. X      return((Image *) NULL);
  1510. X    }
  1511. X  if ((columns > MaxImageSize) || (rows > MaxImageSize))
  1512. X    {
  1513. X      Warning("unable to scale image","image too large");
  1514. X      return((Image *) NULL);
  1515. X    }
  1516. X  /*
  1517. X    Initialize scaled image attributes.
  1518. X  */
  1519. X  scaled_image=CopyImage(image,columns,rows,False);
  1520. X  if (scaled_image == (Image *) NULL)
  1521. X    {
  1522. X      Warning("unable to scale image","memory allocation failed");
  1523. X      return((Image *) NULL);
  1524. X    }
  1525. X  /*
  1526. X    Allocate scan line buffer and column offset buffers.
  1527. X  */
  1528. X  scanline=(ColorPacket *) malloc(image->columns*sizeof(ColorPacket));
  1529. X  x_offset=(unsigned int *) malloc(scaled_image->columns*sizeof(unsigned int));
  1530. X  y_offset=(unsigned int *) malloc(scaled_image->rows*sizeof(unsigned int));
  1531. X  if ((scanline == (ColorPacket *) NULL) ||
  1532. X      (x_offset == (unsigned int *) NULL) ||
  1533. X      (y_offset == (unsigned int *) NULL))
  1534. X    {
  1535. X      Warning("unable to scale image","memory allocation failed");
  1536. X      DestroyImage(scaled_image);
  1537. X      return((Image *) NULL);
  1538. X    }
  1539. X  /*
  1540. X    Initialize column pixel offsets.
  1541. X  */
  1542. X  scale_factor=UpShift(image->columns-1)/scaled_image->columns;
  1543. X  columns=0;
  1544. X  for (x=0; x < scaled_image->columns; x++)
  1545. X  {
  1546. X    x_offset[x]=DownShift((x+1)*scale_factor)-columns;
  1547. X    columns+=x_offset[x];
  1548. X  }
  1549. X  /*
  1550. X    Initialize row pixel offsets.
  1551. X  */
  1552. X  scale_factor=UpShift(image->rows-1)/scaled_image->rows;
  1553. X  rows=0;
  1554. X  for (y=0; y < scaled_image->rows; y++)
  1555. X  {
  1556. X    y_offset[y]=DownShift((y+1)*scale_factor)-rows;
  1557. X    rows+=y_offset[y];
  1558. X  }
  1559. X  /*
  1560. X    Preload first scanline.
  1561. X  */
  1562. X  p=image->pixels;
  1563. X  image->runlength=p->length+1;
  1564. X  s=scanline;
  1565. X  for (x=0; x < image->columns; x++)
  1566. X  {
  1567. X    if (image->runlength > 0)
  1568. X      image->runlength--;
  1569. X    else
  1570. X      {
  1571. X        p++;
  1572. X        image->runlength=p->length;
  1573. X      }
  1574. X    s->red=p->red;
  1575. X    s->green=p->green;
  1576. X    s->blue=p->blue;
  1577. X    s->index=p->index;
  1578. X    s++;
  1579. X  }
  1580. X  /*
  1581. X    Scale each row.
  1582. X  */
  1583. X  q=scaled_image->pixels;
  1584. X  for (y=0; y < scaled_image->rows; y++)
  1585. X  {
  1586. X    /*
  1587. X      Scale each column.
  1588. X    */
  1589. X    s=scanline;
  1590. X    for (x=0; x < scaled_image->columns; x++)
  1591. X    {
  1592. X      q->red=s->red;
  1593. X      q->green=s->green;
  1594. X      q->blue=s->blue;
  1595. X      q->index=s->index;
  1596. X      q->length=0;
  1597. X      q++;
  1598. X      s+=x_offset[x];
  1599. X    }
  1600. X    if (y_offset[y] > 0)
  1601. X      {
  1602. X        /*
  1603. X          Skip a scan line.
  1604. X        */
  1605. X        for (x=0; x < (image->columns*(y_offset[y]-1)); x++)
  1606. X          if (image->runlength > 0)
  1607. X            image->runlength--;
  1608. X          else
  1609. X            {
  1610. X              p++;
  1611. X              image->runlength=p->length;
  1612. X            }
  1613. X        /*
  1614. X          Read a scan line.
  1615. X        */
  1616. X        s=scanline;
  1617. X        for (x=0; x < image->columns; x++)
  1618. X        {
  1619. X          if (image->runlength > 0)
  1620. X            image->runlength--;
  1621. X          else
  1622. X            {
  1623. X              p++;
  1624. X              image->runlength=p->length;
  1625. X            }
  1626. X          s->red=p->red;
  1627. X          s->green=p->green;
  1628. X          s->blue=p->blue;
  1629. X          s->index=p->index;
  1630. X          s++;
  1631. X        }
  1632. X      }
  1633. X  }
  1634. X  (void) free((char *) scanline);
  1635. X  (void) free((char *) x_offset);
  1636. X  (void) free((char *) y_offset);
  1637. X  return(scaled_image);
  1638. }
  1639. X
  1640. /*
  1641. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1642. %                                                                             %
  1643. %                                                                             %
  1644. %                                                                             %
  1645. %   S o r t C o l o r m a p B y I n t e n t s i t y                           %
  1646. %                                                                             %
  1647. %                                                                             %
  1648. %                                                                             %
  1649. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1650. %
  1651. %  Function SortColormapByIntensity sorts the colormap of a PseudoClass image
  1652. %  by decreasing color intensity.
  1653. %
  1654. %  The format of the SortColormapByIntensity routine is:
  1655. %
  1656. %      SortColormapByIntensity(image)
  1657. %
  1658. %  A description of each parameter follows:
  1659. %
  1660. %    o image: A pointer to a Image structure.
  1661. %
  1662. %
  1663. */
  1664. static int IntensityCompare(x,y)
  1665. const void
  1666. X  *x,
  1667. X  *y;
  1668. {
  1669. X  ColorPacket
  1670. X    *color_1,
  1671. X    *color_2;
  1672. X
  1673. X  color_1=(ColorPacket *) x;
  1674. X  color_2=(ColorPacket *) y;
  1675. X  return((int) Intensity(*color_2)-(int) Intensity(*color_1));
  1676. }
  1677. X
  1678. void SortColormapByIntensity(image)
  1679. Image
  1680. X  *image;
  1681. {
  1682. X  register int
  1683. X    i;
  1684. X
  1685. X  register RunlengthPacket
  1686. X    *p;
  1687. X
  1688. X  register unsigned short
  1689. X    index;
  1690. X
  1691. X  unsigned short
  1692. X    *pixels;
  1693. X
  1694. X  if (image->class != PseudoClass)
  1695. X    return;
  1696. X  /*
  1697. X    Allocate memory for pixel indexes.
  1698. X  */
  1699. X  pixels=(unsigned short *) malloc(image->colors*sizeof(unsigned short));
  1700. X  if (pixels == (unsigned short *) NULL)
  1701. X    {
  1702. X      Warning("unable to sort colormap","memory allocation failed");
  1703. X      return;
  1704. X    }
  1705. X  /*
  1706. X    Assign index values to colormap entries.
  1707. X  */
  1708. X  for (i=0; i < image->colors; i++)
  1709. X    image->colormap[i].index=(unsigned short) i;
  1710. X  /*
  1711. X    Sort image colormap by decreasing color popularity.
  1712. X  */
  1713. X  (void) qsort((void *) image->colormap,(int) image->colors,sizeof(ColorPacket),
  1714. X    IntensityCompare);
  1715. X  /*
  1716. X    Update image colormap indexes to sorted colormap order.
  1717. X  */
  1718. X  for (i=0; i < image->colors; i++)
  1719. X    pixels[image->colormap[i].index]=(unsigned short) i;
  1720. X  p=image->pixels;
  1721. X  for (i=0; i < image->packets; i++)
  1722. X  {
  1723. X    index=pixels[p->index];
  1724. X    p->red=image->colormap[index].red;
  1725. X    p->green=image->colormap[index].green;
  1726. X    p->blue=image->colormap[index].blue;
  1727. X    p->index=index;
  1728. X    p++;
  1729. X  }
  1730. X  (void) free((char *) pixels);
  1731. }
  1732. X
  1733. /*
  1734. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1735. %                                                                             %
  1736. %                                                                             %
  1737. %                                                                             %
  1738. %   S t e r e o I m a g e                                                     %
  1739. %                                                                             %
  1740. %                                                                             %
  1741. %                                                                             %
  1742. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1743. %
  1744. %  Function StereoImage combines two images and produces a single image that
  1745. %  is the composite of a left and right image of a stereo pair.  The left
  1746. %  image is converted to grayscale and written to the red channel of the
  1747. %  stereo image.  The right image is converted to grayscale and written to the
  1748. %  blue channel of the stereo image.  View the composite image with red-blue
  1749. %  glasses to create a stereo effect.
  1750. %
  1751. %  The format of the StereoImage routine is:
  1752. %
  1753. %      stereo_image=StereoImage(left_image,right_image)
  1754. %
  1755. %  A description of each parameter follows:
  1756. %
  1757. %    o stereo_image: Function StereoImage returns a pointer to the stereo
  1758. %      image.  A null image is returned if there is a memory shortage.
  1759. %
  1760. %    o left_image: The address of a structure of type Image.
  1761. %
  1762. %    o right_image: The address of a structure of type Image.
  1763. %
  1764. %
  1765. */
  1766. Image *StereoImage(left_image,right_image)
  1767. Image
  1768. X  *left_image,
  1769. X  *right_image;
  1770. {
  1771. X  Image
  1772. X    *stereo_image;
  1773. X
  1774. X  register int
  1775. X    i;
  1776. X
  1777. X  register RunlengthPacket
  1778. X    *p,
  1779. X    *q,
  1780. X    *r;
  1781. X
  1782. X  if ((left_image->columns != right_image->columns) ||
  1783. X      (left_image->rows != right_image->rows))
  1784. X    {
  1785. X      Warning("unable to create stereo image",
  1786. X        "left and right image sizes differ");
  1787. X      return((Image *) NULL);
  1788. X    }
  1789. X  /*
  1790. X    Initialize stereo image attributes.
  1791. X  */
  1792. X  stereo_image=CopyImage(left_image,left_image->columns,left_image->rows,False);
  1793. X  if (stereo_image == (Image *) NULL)
  1794. X    {
  1795. X      Warning("unable to create stereo image","memory allocation failed");
  1796. X      return((Image *) NULL);
  1797. X    }
  1798. X  stereo_image->class=DirectClass;
  1799. X  /*
  1800. X    Copy left image to red channel and right image to blue channel.
  1801. X  */
  1802. X  QuantizeImage(left_image,256,8,False,GRAYColorspace,True);
  1803. X  p=left_image->pixels;
  1804. X  left_image->runlength=p->length+1;
  1805. X  QuantizeImage(right_image,256,8,False,GRAYColorspace,True);
  1806. X  q=right_image->pixels;
  1807. X  right_image->runlength=q->length+1;
  1808. X  r=stereo_image->pixels;
  1809. X  for (i=0; i < (stereo_image->columns*stereo_image->rows); i++)
  1810. X  {
  1811. X    if (left_image->runlength > 0)
  1812. X      left_image->runlength--;
  1813. X    else
  1814. X      {
  1815. X        p++;
  1816. X        left_image->runlength=p->length;
  1817. X      }
  1818. X    if (right_image->runlength > 0)
  1819. X      right_image->runlength--;
  1820. X    else
  1821. X      {
  1822. X        q++;
  1823. X        right_image->runlength=q->length;
  1824. X      }
  1825. X    r->red=(unsigned int) (p->red*12) >> 4;
  1826. X    r->green=0;
  1827. X    r->blue=q->blue;
  1828. X    r->index=0;
  1829. X    r->length=0;
  1830. X    r++;
  1831. X  }
  1832. X  return(stereo_image);
  1833. }
  1834. X
  1835. X
  1836. /*
  1837. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1838. %                                                                             %
  1839. %                                                                             %
  1840. %                                                                             %
  1841. %   T r a n s f o r m I m a g e                                               %
  1842. %                                                                             %
  1843. %                                                                             %
  1844. %                                                                             %
  1845. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1846. %
  1847. %  Function TransformImage creates a new image that is a transformed size of
  1848. %  of existing one as specified by the clip, image and scale geometries.  It
  1849. %  allocates the memory necessary for the new Image structure and returns a
  1850. %  pointer to the new image.
  1851. %
  1852. %  If a clip geometry is specified a subregion of the image is obtained.
  1853. %  If the specified image size, as defined by the image and scale geometries,
  1854. %  is smaller than the actual image size, the image is first reduced to an
  1855. %  integral of the specified image size with an antialias digital filter.  The
  1856. %  image is then scaled to the exact specified image size with pixel
  1857. %  replication.  If the specified image size is greater than the actual image
  1858. %  size, the image is first enlarged to an integral of the specified image
  1859. %  size with bilinear interpolation.  The image is then scaled to the exact
  1860. %  specified image size with pixel replication.
  1861. %
  1862. %  The format of the TransformImage routine is:
  1863. %
  1864. %      TransformImage(image,clip_geometry,image_geometry,scale_geometry)
  1865. %
  1866. %  A description of each parameter follows:
  1867. %
  1868. %    o image: The address of an address of a structure of type Image.  The
  1869. %      transformed image is returned as this parameter.
  1870. %
  1871. %    o clip_geometry: Specifies a pointer to a clip geometry string.
  1872. %      This geometry defined a subregion of the image.
  1873. %
  1874. %    o image_geometry: Specifies a pointer to a image geometry string.
  1875. %      The specified width and height of this geometry string are absolute.
  1876. %
  1877. %    o scale_geometry: Specifies a pointer to a scale geometry string.
  1878. %      The specified width and height of this geometry string are relative.
  1879. %
  1880. %
  1881. */
  1882. void TransformImage(image,clip_geometry,image_geometry,scale_geometry)
  1883. Image
  1884. X  **image;
  1885. X
  1886. char
  1887. X  *clip_geometry,
  1888. X  *image_geometry,
  1889. X  *scale_geometry;
  1890. {
  1891. X  Image
  1892. X    *transformed_image;
  1893. X
  1894. X  int
  1895. X    flags,
  1896. X    x,
  1897. X    y;
  1898. X
  1899. X  unsigned int
  1900. X    height,
  1901. X    width;
  1902. X
  1903. X  transformed_image=(*image);
  1904. X  if (clip_geometry != (char *) NULL)
  1905. X    {
  1906. X      Image
  1907. X        *clipped_image;
  1908. X
  1909. X      /*
  1910. X        Clip transformed_image to a user specified size.
  1911. X      */
  1912. X      x=0;
  1913. X      y=0;
  1914. X      flags=XParseGeometry(clip_geometry,&x,&y,&width,&height);
  1915. X      if ((flags & WidthValue) == 0)
  1916. X        width=(unsigned int) ((int) transformed_image->columns-x);
  1917. X      if ((flags & HeightValue) == 0)
  1918. X        height=(unsigned int) ((int) transformed_image->rows-y);
  1919. X      if ((flags & XNegative) != 0)
  1920. X        x+=transformed_image->columns-width;
  1921. X      if ((flags & YNegative) != 0)
  1922. X        y+=transformed_image->rows-height;
  1923. X      clipped_image=ClipImage(transformed_image,x,y,width,height);
  1924. X      if (clipped_image != (Image *) NULL)
  1925. X        {
  1926. X          DestroyImage(transformed_image);
  1927. X          transformed_image=clipped_image;
  1928. X        }
  1929. X    }
  1930. X  /*
  1931. X    Scale image to a user specified size.
  1932. X  */
  1933. X  width=transformed_image->columns;
  1934. X  height=transformed_image->rows;
  1935. X  if (scale_geometry != (char *) NULL)
  1936. X    {
  1937. X      float
  1938. X        scale_height,
  1939. X        scale_width;
  1940. X
  1941. X      scale_width=0.0;
  1942. X      scale_height=0.0;
  1943. X      (void) sscanf(scale_geometry,"%fx%f",&scale_width,&scale_height);
  1944. X      if (scale_height == 0.0)
  1945. X        scale_height=scale_width;
  1946. X      width=(unsigned int) (width*scale_width);
  1947. X      height=(unsigned int) (height*scale_height);
  1948. X    }
  1949. X  if (image_geometry != (char *) NULL)
  1950. X    (void) XParseGeometry(image_geometry,&x,&y,&width,&height);
  1951. X  while ((transformed_image->columns >= (width << 1)) &&
  1952. X         (transformed_image->rows >= (height << 1)))
  1953. X  {
  1954. X    Image
  1955. X      *reduced_image;
  1956. X
  1957. X    /*
  1958. X      Reduce image with a antialias digital filter.
  1959. X     */
  1960. X    reduced_image=ReduceImage(transformed_image);
  1961. X    if (reduced_image == (Image *) NULL)
  1962. X      break;
  1963. X    DestroyImage(transformed_image);
  1964. X    transformed_image=reduced_image;
  1965. X  }
  1966. X  while ((transformed_image->columns <= (width >> 1)) &&
  1967. X         (transformed_image->rows <= (height >> 1)))
  1968. X  {
  1969. X    Image
  1970. X      *zoomed_image;
  1971. X
  1972. X    /*
  1973. X      Zoom transformed_image with bilinear interpolation.
  1974. X    */
  1975. X    zoomed_image=ZoomImage(transformed_image);
  1976. X    if (zoomed_image == (Image *) NULL)
  1977. X      break;
  1978. X    DestroyImage(transformed_image);
  1979. X    transformed_image=zoomed_image;
  1980. X  }
  1981. X  if ((transformed_image->columns != width) ||
  1982. X      (transformed_image->rows != height))
  1983. X    {
  1984. X      Image
  1985. X        *scaled_image;
  1986. X
  1987. X      /*
  1988. X        Scale image with pixel replication.
  1989. X      */
  1990. X      scaled_image=ScaleImage(transformed_image,width,height);
  1991. X      if (scaled_image != (Image *) NULL)
  1992. X        {
  1993. X          DestroyImage(transformed_image);
  1994. X          transformed_image=scaled_image;
  1995. X        }
  1996. X    }
  1997. X  *image=transformed_image;
  1998. }
  1999. X
  2000. /*
  2001. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2002. %                                                                             %
  2003. %                                                                             %
  2004. %     T r a n s f o r m R G B I m a g e                                       %
  2005. %                                                                             %
  2006. %                                                                             %
  2007. %                                                                             %
  2008. SHAR_EOF
  2009. true || echo 'restore of ImageMagick/image.c failed'
  2010. fi
  2011. echo 'End of  part 6'
  2012. echo 'File ImageMagick/image.c is continued in part 7'
  2013. echo 7 > _shar_seq_.tmp
  2014. exit 0
  2015. exit 0 # Just in case...
  2016.