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

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i069:  imagemagic - X11 image processing and display, Part13/38
  4. Message-ID: <1993Jul14.175607.1448@sparky.sterling.com>
  5. X-Md4-Signature: 7f2ecd5556ec38034145ac51621b734d
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 17:56:07 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 69
  13. Archive-name: imagemagic/part13
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.13 (part 13 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/shear.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 13; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping ImageMagick/shear.c'
  36. else
  37. echo 'x - continuing file ImageMagick/shear.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/shear.c' &&
  39. X    corners[i].y+=(image->rows-3)/2.0;
  40. X  }
  41. X  x_min=corners[0].x;
  42. X  y_min=corners[0].y;
  43. X  x_max=corners[0].x;
  44. X  y_max=corners[0].y;
  45. X  for (i=1; i < 4; i++)
  46. X  {
  47. X    if (x_min > corners[i].x)
  48. X      x_min=corners[i].x;
  49. X    if (y_min > corners[i].y)
  50. X      y_min=corners[i].y;
  51. X    if (x_max < corners[i].x)
  52. X      x_max=corners[i].x;
  53. X    if (y_max < corners[i].y)
  54. X      y_max=corners[i].y;
  55. X  }
  56. X  x_min=floor((double) x_min);
  57. X  x_max=ceil((double) x_max);
  58. X  y_min=floor((double) y_min);
  59. X  y_max=ceil((double) y_max);
  60. X  if (!clip)
  61. X    {
  62. X      /*
  63. X        Do not clip sheared image.
  64. X      */
  65. X      clip_info.width=(unsigned int) (x_max-x_min);
  66. X      clip_info.height=(unsigned int) (y_max-y_min);
  67. X    }
  68. X  clip_info.x=(int) x_min+((int) (x_max-x_min)-clip_info.width)/2;
  69. X  clip_info.y=(int) y_min+((int) (y_max-y_min)-clip_info.height)/2;
  70. X  /*
  71. X    Clip image and return.
  72. X  */
  73. X  clipped_image=ClipImage(image,&clip_info);
  74. X  return(clipped_image);
  75. }
  76. X
  77. /*
  78. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  79. %                                                                             %
  80. %                                                                             %
  81. %                                                                             %
  82. %   I n t e g r a l R o t a t e I m a g e                                     %
  83. %                                                                             %
  84. %                                                                             %
  85. %                                                                             %
  86. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  87. %
  88. %  Function IntegralRotateImage rotates the image an integral of 90 degrees.
  89. %  It allocates the memory necessary for the new Image structure and returns
  90. %  a pointer to the rotated image.
  91. %
  92. %  The format of the IntegralRotateImage routine is:
  93. %
  94. %      rotated_image=IntegralRotateImage(image,rotations)
  95. %
  96. %  A description of each parameter follows.
  97. %
  98. %    o rotated_image: Function IntegralRotateImage returns a pointer to the
  99. %      rotated image.  A null image is returned if there is a a memory shortage.
  100. %
  101. %    o image: The address of a structure of type Image.
  102. %
  103. %    o rotations: Specifies the number of 90 degree rotations.
  104. %
  105. %
  106. */
  107. static Image *IntegralRotateImage(image,rotations)
  108. Image
  109. X  *image;
  110. X
  111. unsigned int
  112. X  rotations;
  113. {
  114. X  Image
  115. X    *rotated_image;
  116. X
  117. X  register RunlengthPacket
  118. X    *p,
  119. X    *q;
  120. X
  121. X  register int
  122. X    x,
  123. X    y;
  124. X
  125. X  /*
  126. X    Initialize rotated image attributes.
  127. X  */
  128. X  rotations%=4;
  129. X  if ((rotations == 1) || (rotations == 3))
  130. X    rotated_image=CopyImage(image,image->rows,image->columns,False);
  131. X  else
  132. X    rotated_image=CopyImage(image,image->columns,image->rows,False);
  133. X  if (rotated_image == (Image *) NULL)
  134. X    {
  135. X      Warning("unable to rotate image","memory allocation failed");
  136. X      return((Image *) NULL);
  137. X    }
  138. X  /*
  139. X    Expand runlength packets into a rectangular array of pixels.
  140. X  */
  141. X  p=image->pixels;
  142. X  image->runlength=p->length+1;
  143. X  switch (rotations)
  144. X  {
  145. X    case 0:
  146. X    {
  147. X      /*
  148. X        Rotate 0 degrees.
  149. X      */
  150. X      q=rotated_image->pixels;
  151. X      for (y=0; y < image->rows; y++)
  152. X      {
  153. X        for (x=0; x < image->columns; x++)
  154. X        {
  155. X          if (image->runlength != 0)
  156. X            image->runlength--;
  157. X          else
  158. X            {
  159. X              p++;
  160. X              image->runlength=p->length;
  161. X            }
  162. X          *q=(*p);
  163. X          q->length=0;
  164. X          q++;
  165. X        }
  166. X      }
  167. X      break;
  168. X    }
  169. X    case 1:
  170. X    {
  171. X      /*
  172. X        Rotate 90 degrees.
  173. X      */
  174. X      for (x=0; x < rotated_image->columns; x++)
  175. X      {
  176. X        q=rotated_image->pixels+(rotated_image->columns-x)-1;
  177. X        for (y=0; y < rotated_image->rows; y++)
  178. X        {
  179. X          if (image->runlength != 0)
  180. X            image->runlength--;
  181. X          else
  182. X            {
  183. X              p++;
  184. X              image->runlength=p->length;
  185. X            }
  186. X          *q=(*p);
  187. X          q->length=0;
  188. X          q+=rotated_image->columns;
  189. X        }
  190. X      }
  191. X      break;
  192. X    }
  193. X    case 2:
  194. X    {
  195. X      /*
  196. X        Rotate 180 degrees.
  197. X      */
  198. X      q=rotated_image->pixels+(rotated_image->columns*rotated_image->rows)-1;
  199. X      for (y=image->rows-1; y >= 0; y--)
  200. X      {
  201. X        for (x=0; x < image->columns; x++)
  202. X        {
  203. X          if (image->runlength != 0)
  204. X            image->runlength--;
  205. X          else
  206. X            {
  207. X              p++;
  208. X              image->runlength=p->length;
  209. X            }
  210. X          *q=(*p);
  211. X          q->length=0;
  212. X          q--;
  213. X        }
  214. X      }
  215. X      break;
  216. X    }
  217. X    case 3:
  218. X    {
  219. X      /*
  220. X        Rotate 270 degrees.
  221. X      */
  222. X      for (x=rotated_image->columns-1; x >= 0; x--)
  223. X      {
  224. X        q=rotated_image->pixels+(rotated_image->columns*rotated_image->rows)-
  225. X          x-1;
  226. X        for (y=0; y < rotated_image->rows; y++)
  227. X        {
  228. X          if (image->runlength != 0)
  229. X            image->runlength--;
  230. X          else
  231. X            {
  232. X              p++;
  233. X              image->runlength=p->length;
  234. X            }
  235. X          *q=(*p);
  236. X          q->length=0;
  237. X          q-=rotated_image->columns;
  238. X        }
  239. X      }
  240. X      break;
  241. X    }
  242. X  }
  243. X  return(rotated_image);
  244. }
  245. X
  246. /*
  247. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  248. %                                                                             %
  249. %                                                                             %
  250. %                                                                             %
  251. %   X S h e a r I m a g e                                                     %
  252. %                                                                             %
  253. %                                                                             %
  254. %                                                                             %
  255. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  256. %
  257. %  Procedure XShearImage shears the image in the X direction with a shear angle
  258. %  of 'degrees'.  Positive angles shear counter-clockwise (right-hand rule),
  259. %  and negative angles shear clockwise.  Angles are measured relative to a
  260. %  vertical Y-axis.  X shears will widen an image creating 'empty' triangles
  261. %  on the left and right sides of the source image.
  262. %
  263. %  The format of the XShearImage routine is:
  264. %
  265. %      XShearImage(image,degrees,width,height,x_offset,y_offset,background,
  266. %        range_limit)
  267. %
  268. %  A description of each parameter follows.
  269. %
  270. %    o image: The address of a structure of type Image.
  271. %
  272. %    o degrees: A double representing the shearing angle along the X axis.
  273. %
  274. %    o width, height, x_offset, y_offset: Defines a region of the image
  275. %      to shear.
  276. %
  277. %    o background: Specifies a ColorPacket used to fill empty triangles
  278. %      left over from shearing.
  279. %
  280. %
  281. */
  282. static void XShearImage(image,degrees,width,height,x_offset,y_offset,background,
  283. X  range_limit)
  284. Image
  285. X  *image;
  286. X
  287. double
  288. X  degrees;
  289. X
  290. unsigned int
  291. X  width,
  292. X  height;
  293. X
  294. int
  295. X  x_offset,
  296. X  y_offset;
  297. X
  298. ColorPacket
  299. X  background;
  300. X
  301. register unsigned char
  302. X  *range_limit;
  303. {
  304. X  double
  305. X    displacement;
  306. X
  307. X  enum {LEFT,RIGHT}
  308. X    direction;
  309. X
  310. X  int
  311. X    step,
  312. X    y;
  313. X
  314. X  long
  315. X    fractional_step;
  316. X
  317. X  register RunlengthPacket
  318. X    *p,
  319. X    *q;
  320. X
  321. X  register int
  322. X    blue,
  323. X    green,
  324. X    i,
  325. X    red;
  326. X
  327. X  RunlengthPacket
  328. X    last_pixel;
  329. X
  330. X  y_offset--;
  331. X  for (y=0; y < height; y++)
  332. X  {
  333. X    y_offset++;
  334. X    displacement=degrees*(((double) y)-(height-1)/2.0);
  335. X    if (displacement == 0.0)
  336. X      continue;
  337. X    if (displacement > 0.0)
  338. X      direction=RIGHT;
  339. X    else
  340. X      {
  341. X        displacement*=(-1.0);
  342. X        direction=LEFT;
  343. X      }
  344. X    step=(int) floor(displacement);
  345. X    fractional_step=UpShifted(displacement-(double) step);
  346. X    if (fractional_step == 0)
  347. X      {
  348. X        /*
  349. X          No fractional displacement-- just copy.
  350. X        */
  351. X        switch (direction)
  352. X        {
  353. X          case LEFT:
  354. X          {
  355. X            /*
  356. X              Transfer pixels left-to-right.
  357. X            */
  358. X            p=image->pixels+image->columns*y_offset+x_offset;
  359. X            q=p-step;
  360. X            for (i=0; i < width; i++)
  361. X            {
  362. X              *q=(*p);
  363. X              q++;
  364. X              p++;
  365. X            }
  366. X            /*
  367. X              Set old row to background color.
  368. X            */
  369. X            for (i=0; i < step; i++)
  370. X            {
  371. X              q->red=background.red;
  372. X              q->green=background.green;
  373. X              q->blue=background.blue;
  374. X              q++;
  375. X            }
  376. X            break;
  377. X          }
  378. X          case RIGHT:
  379. X          {
  380. X            /*
  381. X              Transfer pixels right-to-left.
  382. X            */
  383. X            p=image->pixels+image->columns*y_offset+x_offset+width;
  384. X            q=p+step;
  385. X            for (i=0; i < width; i++)
  386. X            {
  387. X              p--;
  388. X              q--;
  389. X              *q=(*p);
  390. X            }
  391. X            /*
  392. X              Set old row to background color.
  393. X            */
  394. X            for (i=0; i < step; i++)
  395. X            {
  396. X              q--;
  397. X              q->red=background.red;
  398. X              q->green=background.green;
  399. X              q->blue=background.blue;
  400. X            }
  401. X            break;
  402. X          }
  403. X        }
  404. X        continue;
  405. X      }
  406. X    /*
  407. X      Fractional displacement.
  408. X    */
  409. X    step++;
  410. X    last_pixel.red=background.red;
  411. X    last_pixel.green=background.green;
  412. X    last_pixel.blue=background.blue;
  413. X    switch (direction)
  414. X    {
  415. X      case LEFT:
  416. X      {
  417. X        /*
  418. X          Transfer pixels left-to-right.
  419. X        */
  420. X        p=image->pixels+image->columns*y_offset+x_offset;
  421. X        q=p-step;
  422. X        for (i=0; i < width; i++)
  423. X        {
  424. X          red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+p->red*
  425. X            fractional_step);
  426. X          green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  427. X            p->green*fractional_step);
  428. X          blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+p->blue*
  429. X            fractional_step);
  430. X          last_pixel=(*p);
  431. X          p++;
  432. X          q->red=range_limit[red];
  433. X          q->green=range_limit[green];
  434. X          q->blue=range_limit[blue];
  435. X          q++;
  436. X        }
  437. X        /*
  438. X          Set old row to background color.
  439. X        */
  440. X        red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+
  441. X          background.red*fractional_step);
  442. X        green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  443. X          background.green*fractional_step);
  444. X        blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+
  445. X          background.blue*fractional_step);
  446. X        q->red=range_limit[red];
  447. X        q->green=range_limit[green];
  448. X        q->blue=range_limit[blue];
  449. X        q++;
  450. X        for (i=0; i < step-1; i++)
  451. X        {
  452. X          q->red=background.red;
  453. X          q->green=background.green;
  454. X          q->blue=background.blue;
  455. X          q++;
  456. X        }
  457. X        break;
  458. X      }
  459. X      case RIGHT:
  460. X      {
  461. X        /*
  462. X          Transfer pixels right-to-left.
  463. X        */
  464. X        p=image->pixels+image->columns*y_offset+x_offset+width;
  465. X        q=p+step;
  466. X        for (i=0; i < width; i++)
  467. X        {
  468. X          p--;
  469. X          red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+p->red*
  470. X            fractional_step);
  471. X          green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  472. X            p->green*fractional_step);
  473. X          blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+p->blue*
  474. X            fractional_step);
  475. X          last_pixel=(*p);
  476. X          q--;
  477. X          q->red=range_limit[red];
  478. X          q->green=range_limit[green];
  479. X          q->blue=range_limit[blue];
  480. X        }
  481. X        /*
  482. X          Set old row to background color.
  483. X        */
  484. X        red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+
  485. X          background.red*fractional_step);
  486. X        green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  487. X          background.green*fractional_step);
  488. X        blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+
  489. X          background.blue*fractional_step);
  490. X        q--;
  491. X        q->red=range_limit[red];
  492. X        q->green=range_limit[green];
  493. X        q->blue=range_limit[blue];
  494. X        for (i=0; i < step-1; i++)
  495. X        {
  496. X          q--;
  497. X          q->red=background.red;
  498. X          q->green=background.green;
  499. X          q->blue=background.blue;
  500. X        }
  501. X        break;
  502. X      }
  503. X    }
  504. X  }
  505. }
  506. X
  507. /*
  508. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  509. %                                                                             %
  510. %                                                                             %
  511. %                                                                             %
  512. %   Y S h e a r I m a g e                                                     %
  513. %                                                                             %
  514. %                                                                             %
  515. %                                                                             %
  516. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  517. %
  518. %  Procedure YShearImage shears the image in the Y direction with a shear
  519. %  angle of 'degrees'.  Positive angles shear counter-clockwise (right-hand
  520. %  rule), and negative angles shear clockwise.  Angles are measured relative
  521. %  to a horizontal X-axis.  Y shears will increase the height of an image
  522. %  creating 'empty' triangles on the top and bottom of the source image.
  523. %
  524. %  The format of the YShearImage routine is:
  525. %
  526. %      YShearImage(image,degrees,width,height,x_offset,y_offset,background,
  527. %        range_limit)
  528. %
  529. %  A description of each parameter follows.
  530. %
  531. %    o image: The address of a structure of type Image.
  532. %
  533. %    o degrees: A double representing the shearing angle along the Y axis.
  534. %
  535. %    o width, height, x_offset, y_offset: Defines a region of the image
  536. %      to shear.
  537. %
  538. %    o background: Specifies a ColorPacket used to fill empty triangles
  539. %      left over from shearing.
  540. %
  541. %
  542. */
  543. static void YShearImage(image,degrees,width,height,x_offset,y_offset,background,
  544. X  range_limit)
  545. Image
  546. X  *image;
  547. X
  548. double
  549. X  degrees;
  550. X
  551. unsigned int
  552. X  width,
  553. X  height;
  554. X
  555. int
  556. X  x_offset,
  557. X  y_offset;
  558. X
  559. ColorPacket
  560. X  background;
  561. X
  562. register unsigned char
  563. X  *range_limit;
  564. {
  565. X  double
  566. X    displacement;
  567. X
  568. X  enum {UP,DOWN}
  569. X    direction;
  570. X
  571. X  int
  572. X    step,
  573. X    y;
  574. X
  575. X  long
  576. X    fractional_step;
  577. X
  578. X  register RunlengthPacket
  579. X    *p,
  580. X    *q;
  581. X
  582. X  register int
  583. X    blue,
  584. X    green,
  585. X    i,
  586. X    red;
  587. X
  588. X  RunlengthPacket
  589. X    last_pixel;
  590. X
  591. X  x_offset--;
  592. X  for (y=0; y < width; y++)
  593. X  {
  594. X    x_offset++;
  595. X    displacement=degrees*(((double) y)-(width-1)/2.0);
  596. X    if (displacement == 0.0)
  597. X      continue;
  598. X    if (displacement > 0.0)
  599. X      direction=DOWN;
  600. X    else
  601. X      {
  602. X        displacement*=(-1.0);
  603. X        direction=UP;
  604. X      }
  605. X    step=(int) floor(displacement);
  606. X    fractional_step=UpShifted(displacement-(double) step);
  607. X    if (fractional_step == 0)
  608. X      {
  609. X        /*
  610. X          No fractional displacement-- just copy the pixels.
  611. X        */
  612. X        switch (direction)
  613. X        {
  614. X          case UP:
  615. X          {
  616. X            /*
  617. X              Transfer pixels top-to-bottom.
  618. X            */
  619. X            p=image->pixels+image->columns*y_offset+x_offset;
  620. X            q=p-step*image->columns;
  621. X            for (i=0; i < height; i++)
  622. X            {
  623. X              *q=(*p);
  624. X              q+=image->columns;
  625. X              p+=image->columns;
  626. X            }
  627. X            /*
  628. X              Set old column to background color.
  629. X            */
  630. X            for (i=0; i < step; i++)
  631. X            {
  632. X              q->red=background.red;
  633. X              q->green=background.green;
  634. X              q->blue=background.blue;
  635. X              q+=image->columns;
  636. X            }
  637. X            break;
  638. X          }
  639. X          case DOWN:
  640. X          {
  641. X            /*
  642. X              Transfer pixels bottom-to-top.
  643. X            */
  644. X            p=image->pixels+image->columns*(y_offset+height)+x_offset;
  645. X            q=p+step*image->columns;
  646. X            for (i=0; i < height; i++)
  647. X            {
  648. X              q-=image->columns;
  649. X              p-=image->columns;
  650. X              *q=(*p);
  651. X            }
  652. X            /*
  653. X              Set old column to background color.
  654. X            */
  655. X            for (i=0; i < step; i++)
  656. X            {
  657. X              q-=image->columns;
  658. X              q->red=background.red;
  659. X              q->green=background.green;
  660. X              q->blue=background.blue;
  661. X            }
  662. X            break;
  663. X          }
  664. X        }
  665. X        continue;
  666. X      }
  667. X    /*
  668. X      Fractional displacment.
  669. X    */
  670. X    step++;
  671. X    last_pixel.red=background.red;
  672. X    last_pixel.green=background.green;
  673. X    last_pixel.blue=background.blue;
  674. X    switch (direction)
  675. X    {
  676. X      case UP:
  677. X      {
  678. X        /*
  679. X          Transfer pixels top-to-bottom.
  680. X        */
  681. X        p=image->pixels+image->columns*y_offset+x_offset;
  682. X        q=p-step*image->columns;
  683. X        for (i=0; i < height; i++)
  684. X        {
  685. X          red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+p->red*
  686. X            fractional_step);
  687. X          green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  688. X            p->green*fractional_step);
  689. X          blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+p->blue*
  690. X            fractional_step);
  691. X          last_pixel=(*p);
  692. X          p+=image->columns;
  693. X          q->red=range_limit[red];
  694. X          q->green=range_limit[green];
  695. X          q->blue=range_limit[blue];
  696. X          q+=image->columns;
  697. X        }
  698. X        /*
  699. X          Set old column to background color.
  700. X        */
  701. X        red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+
  702. X          background.red*fractional_step);
  703. X        green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  704. X          background.green*fractional_step);
  705. X        blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+
  706. X          background.blue*fractional_step);
  707. X        q->red=range_limit[red];
  708. X        q->green=range_limit[green];
  709. X        q->blue=range_limit[blue];
  710. X        q+=image->columns;
  711. X        for (i=0; i < step-1; i++)
  712. X        {
  713. X          q->red=background.red;
  714. X          q->green=background.green;
  715. X          q->blue=background.blue;
  716. X          q+=image->columns;
  717. X        }
  718. X        break;
  719. X      }
  720. X      case DOWN:
  721. X      {
  722. X        /*
  723. X          Transfer pixels bottom-to-top.
  724. X        */
  725. X        p=image->pixels+image->columns*(y_offset+height)+x_offset;
  726. X        q=p+step*image->columns;
  727. X        for (i=0; i < height; i++)
  728. X        {
  729. X          p-=image->columns;
  730. X          red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+p->red*
  731. X            fractional_step);
  732. X          green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  733. X            p->green*fractional_step);
  734. X          blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+p->blue*
  735. X            fractional_step);
  736. X          last_pixel=(*p);
  737. X          q-=image->columns;
  738. X          q->red=range_limit[red];
  739. X          q->green=range_limit[green];
  740. X          q->blue=range_limit[blue];
  741. X        }
  742. X        /*
  743. X          Set old column to background color.
  744. X        */
  745. X        red=DownShift(last_pixel.red*(UpShift(1)-fractional_step)+
  746. X          background.red*fractional_step);
  747. X        green=DownShift(last_pixel.green*(UpShift(1)-fractional_step)+
  748. X          background.green*fractional_step);
  749. X        blue=DownShift(last_pixel.blue*(UpShift(1)-fractional_step)+
  750. X          background.blue*fractional_step);
  751. X        q-=image->columns;
  752. X        q->red=range_limit[red];
  753. X        q->green=range_limit[green];
  754. X        q->blue=range_limit[blue];
  755. X        for (i=0; i < step-1; i++)
  756. X        {
  757. X          q-=image->columns;
  758. X          q->red=background.red;
  759. X          q->green=background.green;
  760. X          q->blue=background.blue;
  761. X        }
  762. X        break;
  763. X      }
  764. X    }
  765. X  }
  766. }
  767. X
  768. /*
  769. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  770. %                                                                             %
  771. %                                                                             %
  772. %                                                                             %
  773. %   R o t a t e I m a g e                                                     %
  774. %                                                                             %
  775. %                                                                             %
  776. %                                                                             %
  777. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  778. %
  779. %  Function RotateImage creates a new image that is a rotated copy of an
  780. %  existing one.  Positive angles rotate counter-clockwise (right-hand rule),
  781. %  while negative angles rotate clockwise.  Rotated images are usually larger
  782. %  than the originals and have 'empty' triangular corners.  X axis.  Empty
  783. %  triangles left over from shearing the image are filled with the color
  784. %  defined by the pixel at location (0,0).  RotateImage allocates the memory
  785. %  necessary for the new Image structure and returns a pointer to the new
  786. %  image.
  787. %
  788. %  Function RotateImage is based on the paper "A Fast Algorithm for General
  789. %  Raster Rotatation" by Alan W. Paeth.  RotateImage is adapted from a similiar
  790. %  routine based on the Paeth paper written by Michael Halle of the Spatial
  791. %  Imaging Group, MIT Media Lab.
  792. %
  793. %  The format of the RotateImage routine is:
  794. %
  795. %      RotateImage(image,degrees,clip)
  796. %
  797. %  A description of each parameter follows.
  798. %
  799. %    o status: Function RotateImage returns a pointer to the image after
  800. %      rotating.  A null image is returned if there is a memory shortage.
  801. %
  802. %    o image: The address of a structure of type Image;  returned from
  803. %      ReadImage.
  804. %
  805. %    o degrees: Specifies the number of degrees to rotate the image.
  806. %
  807. %    o clip: A value other than zero clips the corners of the rotated
  808. %      image and retains the original image size.
  809. %
  810. %
  811. */
  812. Image *RotateImage(image,degrees,clip)
  813. Image
  814. X  *image;
  815. X
  816. double
  817. X  degrees;
  818. X
  819. unsigned int
  820. X  clip;
  821. {
  822. X  ColorPacket
  823. X    background;
  824. X
  825. X  double
  826. X    x_shear,
  827. X    y_shear;
  828. X
  829. X  Image
  830. X    *clipped_image,
  831. X    *integral_image,
  832. X    *rotated_image;
  833. X
  834. X  int
  835. X    x_offset,
  836. X    y_offset;
  837. X
  838. X  RectangleInfo
  839. X    border_info;
  840. X
  841. X  register int
  842. X    i;
  843. X
  844. X  unsigned char
  845. X    *range_limit,
  846. X    *range_table;
  847. X
  848. X  unsigned int
  849. X    height,
  850. X    rotations,
  851. X    width,
  852. X    y_width;
  853. X
  854. X  /*
  855. X    Adjust rotation angle.
  856. X  */
  857. X  while (degrees < -45.0)
  858. X    degrees+=360.0;
  859. X  rotations=0;
  860. X  while (degrees > 45.0)
  861. X  {
  862. X    degrees-=90.0;
  863. X    rotations++;
  864. X  }
  865. X  rotations%=4;
  866. X  /*
  867. X    Calculate shear equations.
  868. X  */
  869. X  x_shear=(-tan(DegreesToRadians(degrees)/2.0));
  870. X  y_shear=sin(DegreesToRadians(degrees));
  871. X  integral_image=IntegralRotateImage(image,rotations);
  872. X  if ((x_shear == 0.0) || (y_shear == 0.0))
  873. X    return(integral_image);
  874. X  /*
  875. X    Initialize range table.
  876. X  */
  877. X  range_table=(unsigned char *) malloc(3*(MaxRGB+1)*sizeof(unsigned char));
  878. X  if (range_table == (unsigned char *) NULL)
  879. X    {
  880. X      DestroyImage(integral_image);
  881. X      Warning("unable to rotate image","memory allocation failed");
  882. X      return((Image *) NULL);
  883. X    }
  884. X  for (i=0; i <= MaxRGB; i++)
  885. X  {
  886. X    range_table[i]=0;
  887. X    range_table[i+(MaxRGB+1)]=(unsigned char) i;
  888. X    range_table[i+(MaxRGB+1)*2]=MaxRGB;
  889. X  }
  890. X  range_limit=range_table+(MaxRGB+1);
  891. X  /*
  892. X    Compute image size.
  893. X  */
  894. X  width=image->columns;
  895. X  height=image->rows;
  896. X  if ((rotations == 1) || (rotations == 3))
  897. X    {
  898. X      width=image->rows;
  899. X      height=image->columns;
  900. X    }
  901. X  y_width=width+(int) ceil(fabs(x_shear)*(double) (height-1));
  902. X  x_offset=(width+2*(int) ceil(fabs(x_shear)*(double) (height-1))-width)/2;
  903. X  y_offset=(height+(int) ceil(fabs(y_shear)*(double) (y_width-1))-height)/2;
  904. X  /*
  905. X    Surround image with border of background color.
  906. X  */
  907. X  background.red=image->pixels[0].red;
  908. X  background.green=image->pixels[0].green;
  909. X  background.blue=image->pixels[0].blue;
  910. X  border_info.width=integral_image->columns+2*x_offset;
  911. X  border_info.height=integral_image->rows+2*(y_offset+1);
  912. X  border_info.x=x_offset;
  913. X  border_info.y=y_offset+1;
  914. X  rotated_image=BorderImage(integral_image,&border_info,&background,
  915. X    &background);
  916. X  DestroyImage(integral_image);
  917. X  if (rotated_image == (Image *) NULL)
  918. X    {
  919. X      Warning("unable to rotate image","memory allocation failed");
  920. X      return((Image *) NULL);
  921. X    }
  922. X  rotated_image->class=DirectClass;
  923. X  /*
  924. X    Perform a fractional rotation.  First, shear the image rows.
  925. X  */
  926. X  XShearImage(rotated_image,x_shear,width,height,x_offset,
  927. X    (int) (rotated_image->rows-height-2)/2+1,background,range_limit);
  928. X  /*
  929. X    Shear the image columns.
  930. X  */
  931. X  YShearImage(rotated_image,y_shear,y_width,height,
  932. X    (int) (rotated_image->columns-y_width)/2,y_offset+1,background,range_limit);
  933. X  /*
  934. X    Shear the image rows again.
  935. X  */
  936. X  XShearImage(rotated_image,x_shear,y_width,rotated_image->rows-2,
  937. X    (int) (rotated_image->columns-y_width)/2,1,background,range_limit);
  938. X  (void) free((char *) range_table);
  939. X  clipped_image=ClipShearImage(rotated_image,x_shear,y_shear,width,height,clip);
  940. X  DestroyImage(rotated_image);
  941. X  return(clipped_image);
  942. }
  943. X
  944. /*
  945. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  946. %                                                                             %
  947. %                                                                             %
  948. %                                                                             %
  949. %   S h e a r I m a g e                                                       %
  950. %                                                                             %
  951. %                                                                             %
  952. %                                                                             %
  953. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  954. %
  955. %  Function ShearImage creates a new image that is a sheared copy of an
  956. %  existing one.  Shearing slides one edge of an image along the X or Y
  957. %  axis, creating a parallelogram.  An X direction shear slides an edge
  958. %  along the X axis, while a Y direction shear slides an edge along the Y
  959. %  axis.  The amount of the shear is controlled by a shear angle.  For X
  960. %  direction shears, x_shear is measured relative to the Y axis, and
  961. %  similarly, for Y direction shears y_shear is measured relative to the
  962. %  X axis.  Empty triangles left over from shearing the image are filled
  963. %  with the color defined by the pixel at location (0,0).  ShearImage
  964. %  allocates the memory necessary for the new Image structure and returns
  965. %  a pointer to the new image.
  966. %
  967. %  Function ShearImage is based on the paper "A Fast Algorithm for General
  968. %  Raster Rotatation" by Alan W. Paeth.  
  969. %
  970. %  The format of the ShearImage routine is:
  971. %
  972. %      ShearImage(image,x_shear,y_shear,clip)
  973. %
  974. %  A description of each parameter follows.
  975. %
  976. %    o status: Function ShearImage returns a pointer to the image after
  977. %      rotating.  A null image is returned if there is a memory shortage.
  978. %
  979. %    o image: The address of a structure of type Image;  returned from
  980. %      ReadImage.
  981. %
  982. %    o x_shear, y_shear: Specifies the number of degrees to shear the image.
  983. %
  984. %    o clip: A value other than zero clips the corners of the rotated
  985. %      image and retains the original image size.
  986. %
  987. %
  988. */
  989. Image *ShearImage(image,x_shear,y_shear,clip)
  990. Image
  991. X  *image;
  992. X
  993. double
  994. X  x_shear,
  995. X  y_shear;
  996. X
  997. unsigned int
  998. X  clip;
  999. {
  1000. X  ColorPacket
  1001. X    background;
  1002. X
  1003. X  Image
  1004. X    *clipped_image,
  1005. X    *sheared_image;
  1006. X
  1007. X  int
  1008. X    x_offset,
  1009. X    y_offset;
  1010. X
  1011. X  RectangleInfo
  1012. X    border_info;
  1013. X
  1014. X  register int
  1015. X    i;
  1016. X
  1017. X  unsigned char
  1018. X    *range_limit,
  1019. X    *range_table;
  1020. X
  1021. X  unsigned int
  1022. X    y_width;
  1023. X
  1024. X  /*
  1025. X    Adjust rotation angle.
  1026. X  */
  1027. X  while (x_shear < -45.0)
  1028. X    x_shear+=360.0;
  1029. X  while (x_shear > 45.0)
  1030. X    x_shear-=90.0;
  1031. X  while (y_shear < -45.0)
  1032. X    y_shear+=360.0;
  1033. X  while (y_shear > 45.0)
  1034. X    y_shear-=90.0;
  1035. X  x_shear=tan(DegreesToRadians(x_shear)/2.0);
  1036. X  y_shear=(-sin(DegreesToRadians(y_shear)));
  1037. X  /*
  1038. X    Initialize range table.
  1039. X  */
  1040. X  range_table=(unsigned char *) malloc(3*(MaxRGB+1)*sizeof(unsigned char));
  1041. X  if (range_table == (unsigned char *) NULL)
  1042. X    {
  1043. X      Warning("unable to rotate image","memory allocation failed");
  1044. X      return((Image *) NULL);
  1045. X    }
  1046. X  for (i=0; i <= MaxRGB; i++)
  1047. X  {
  1048. X    range_table[i]=0;
  1049. X    range_table[i+(MaxRGB+1)]=(unsigned char) i;
  1050. X    range_table[i+(MaxRGB+1)*2]=MaxRGB;
  1051. X  }
  1052. X  range_limit=range_table+(MaxRGB+1);
  1053. X  /*
  1054. X    Compute image size.
  1055. X  */
  1056. X  y_width=image->columns+(int) ceil(fabs(x_shear)*(double) (image->rows-1));
  1057. X  x_offset=(image->columns+2*
  1058. X    (int) ceil(fabs(x_shear)*(double) (image->rows-1))-image->columns)/2;
  1059. X  y_offset=(image->rows+
  1060. X    (int) ceil(fabs(y_shear)*(double) (y_width-1))-image->rows)/2;
  1061. X  /*
  1062. X    Surround image with border of background color.
  1063. X  */
  1064. X  background.red=image->pixels[0].red;
  1065. X  background.green=image->pixels[0].green;
  1066. X  background.blue=image->pixels[0].blue;
  1067. X  border_info.width=image->columns+2*x_offset;
  1068. X  border_info.height=image->columns+2*(y_offset+1);
  1069. X  border_info.x=x_offset;
  1070. X  border_info.y=y_offset+1;
  1071. X  sheared_image=BorderImage(image,&border_info,&background,&background);
  1072. X  if (sheared_image == (Image *) NULL)
  1073. X    {
  1074. X      Warning("unable to rotate image","memory allocation failed");
  1075. X      return((Image *) NULL);
  1076. X    }
  1077. X  sheared_image->class=DirectClass;
  1078. X  /*
  1079. X    Shear the image rows.
  1080. X  */
  1081. X  if (x_shear != 0.0)
  1082. X    XShearImage(sheared_image,x_shear,image->columns,image->rows,x_offset,
  1083. X      (int) (sheared_image->rows-image->rows)/2+1,background,range_limit);
  1084. X  /*
  1085. X    Shear the image columns.
  1086. X  */
  1087. X  if (y_shear != 0.0)
  1088. X    YShearImage(sheared_image,y_shear,y_width,image->rows,(int)
  1089. X      (sheared_image->columns-y_width)/2,y_offset+1,background,range_limit);
  1090. X  (void) free((char *) range_table);
  1091. X  clipped_image=ClipShearImage(sheared_image,x_shear,y_shear,image->columns,
  1092. X    image->rows,clip);
  1093. X  DestroyImage(sheared_image);
  1094. X  return(clipped_image);
  1095. }
  1096. SHAR_EOF
  1097. echo 'File ImageMagick/shear.c is complete' &&
  1098. chmod 0644 ImageMagick/shear.c ||
  1099. echo 'restore of ImageMagick/shear.c failed'
  1100. Wc_c="`wc -c < 'ImageMagick/shear.c'`"
  1101. test 35828 -eq "$Wc_c" ||
  1102.     echo 'ImageMagick/shear.c: original size 35828, current size' "$Wc_c"
  1103. rm -f _shar_wnt_.tmp
  1104. fi
  1105. # ============= ImageMagick/decode.c ==============
  1106. if test -f 'ImageMagick/decode.c' -a X"$1" != X"-c"; then
  1107.     echo 'x - skipping ImageMagick/decode.c (File already exists)'
  1108.     rm -f _shar_wnt_.tmp
  1109. else
  1110. > _shar_wnt_.tmp
  1111. echo 'x - extracting ImageMagick/decode.c (Text)'
  1112. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/decode.c' &&
  1113. /*
  1114. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1115. %                                                                             %
  1116. %                                                                             %
  1117. %                                                                             %
  1118. %                   DDDD   EEEEE   CCCC   OOO   DDDD   EEEEE                  %
  1119. %                   D   D  E      C      O   O  D   D  E                      %
  1120. %                   D   D  EEE    C      O   O  D   D  EEE                    %
  1121. %                   D   D  E      C      O   O  D   D  E                      %
  1122. %                   DDDD   EEEEE   CCCC   OOO   DDDD   EEEEE                  %
  1123. %                                                                             %
  1124. %                                                                             %
  1125. %                    Utility Routines to Read Image Formats                   %
  1126. %                                                                             %
  1127. %                                                                             %
  1128. %                                                                             %
  1129. %                             Software Design                                 %
  1130. %                               John Cristy                                   %
  1131. %                              January 1992                                   %
  1132. %                                                                             %
  1133. %                                                                             %
  1134. %  Copyright 1993 E. I. du Pont de Nemours & Company                          %
  1135. %                                                                             %
  1136. %  Permission to use, copy, modify, distribute, and sell this software and    %
  1137. %  its documentation for any purpose is hereby granted without fee,           %
  1138. %  provided that the above Copyright notice appear in all copies and that     %
  1139. %  both that Copyright notice and this permission notice appear in            %
  1140. %  supporting documentation, and that the name of E. I. du Pont de Nemours    %
  1141. %  & Company not be used in advertising or publicity pertaining to            %
  1142. %  distribution of the software without specific, written prior               %
  1143. %  permission.  E. I. du Pont de Nemours & Company makes no representations   %
  1144. %  about the suitability of this software for any purpose.  It is provided    %
  1145. %  "as is" without express or implied warranty.                               %
  1146. %                                                                             %
  1147. %  E. I. du Pont de Nemours & Company disclaims all warranties with regard    %
  1148. %  to this software, including all implied warranties of merchantability      %
  1149. %  and fitness, in no event shall E. I. du Pont de Nemours & Company be       %
  1150. %  liable for any special, indirect or consequential damages or any           %
  1151. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  1152. %  in an action of contract, negligence or other tortious action, arising     %
  1153. %  out of or in connection with the use or performance of this software.      %
  1154. %                                                                             %
  1155. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1156. %
  1157. %  Functions in this library convert to and from `alien' image formats to the
  1158. %  MIFF image format.
  1159. %
  1160. %
  1161. */
  1162. X
  1163. /*
  1164. X  Include declarations.
  1165. */
  1166. #include "display.h"
  1167. #include "image.h"
  1168. #include "compress.h"
  1169. #include "utility.h"
  1170. #include "X.h"
  1171. #include "XWDFile.h"
  1172. X
  1173. /*
  1174. X  Forward declarations.
  1175. */
  1176. static Image
  1177. X  *ReadMIFFImage _Declare((ImageInfo *));
  1178. X
  1179. /*
  1180. X  External declarations.
  1181. */
  1182. extern char
  1183. X  *client_name;
  1184. X
  1185. /*
  1186. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1187. %                                                                             %
  1188. %                                                                             %
  1189. %                                                                             %
  1190. %  R e a d A L P H A I m a g e                                                %
  1191. %                                                                             %
  1192. %                                                                             %
  1193. %                                                                             %
  1194. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1195. %
  1196. %  Function ReadALPHAImage reads an image of raw alpha bytes and returns it.
  1197. %  It allocates the memory necessary for the new Image structure and returns a
  1198. %  pointer to the new image.
  1199. %
  1200. %  The format of the ReadALPHAImage routine is:
  1201. %
  1202. %      image=ReadALPHAImage(image_info)
  1203. %
  1204. %  A description of each parameter follows:
  1205. %
  1206. %    o image:  Function ReadALPHAImage returns a pointer to the image after
  1207. %      reading.  A null image is returned if there is a a memory shortage or
  1208. %      if the image cannot be read.
  1209. %
  1210. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1211. %
  1212. %
  1213. */
  1214. static Image *ReadALPHAImage(image_info)
  1215. ImageInfo
  1216. X  *image_info;
  1217. {
  1218. X  Image
  1219. X    *image;
  1220. X
  1221. X  int
  1222. X    x,
  1223. X    y;
  1224. X
  1225. X  register int
  1226. X    i;
  1227. X
  1228. X  register RunlengthPacket
  1229. X    *q;
  1230. X
  1231. X  register unsigned char
  1232. X    index,
  1233. X    *p;
  1234. X
  1235. X  unsigned char
  1236. X    *alpha_pixels;
  1237. X
  1238. X  unsigned int
  1239. X    height,
  1240. X    width;
  1241. X
  1242. X  /*
  1243. X    Allocate image structure.
  1244. X  */
  1245. X  image=AllocateImage("ALPHA");
  1246. X  if (image == (Image *) NULL)
  1247. X    return((Image *) NULL);
  1248. X  /*
  1249. X    Open image file.
  1250. X  */
  1251. X  (void) strcpy(image->filename,image_info->filename);
  1252. X  OpenImage(image,"r");
  1253. X  if (image->file == (FILE *) NULL)
  1254. X    {
  1255. X      Warning("unable to open file",image->filename);
  1256. X      DestroyImage(image);
  1257. X      return((Image *) NULL);
  1258. X    }
  1259. X  /*
  1260. X    Create image.
  1261. X  */
  1262. X  image->alpha=True;
  1263. X  width=512;
  1264. X  height=512;
  1265. X  if (image_info->geometry != (char *) NULL)
  1266. X    (void) XParseGeometry(image_info->geometry,&x,&y,&width,&height);
  1267. X  image->columns=width;
  1268. X  image->rows=height;
  1269. X  image->packets=image->columns*image->rows;
  1270. X  alpha_pixels=(unsigned char *)
  1271. X    malloc((unsigned int) image->packets*sizeof(unsigned char));
  1272. X  image->pixels=(RunlengthPacket *)
  1273. X    malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  1274. X  if ((alpha_pixels == (unsigned char *) NULL) ||
  1275. X      (image->pixels == (RunlengthPacket *) NULL))
  1276. X    {
  1277. X      Warning("memory allocation error",(char *) NULL);
  1278. X      DestroyImage(image);
  1279. X      return((Image *) NULL);
  1280. X    }
  1281. X  /*
  1282. X    Convert raster image to runlength-encoded packets.
  1283. X  */
  1284. X  (void) ReadData((char *) alpha_pixels,1,(int) (image->columns*image->rows),
  1285. X    image->file);
  1286. X  p=alpha_pixels;
  1287. X  q=image->pixels;
  1288. X  for (i=0; i < (image->columns*image->rows); i++)
  1289. X  {
  1290. X    index=(*p++);
  1291. X    q->red=0;
  1292. X    q->green=0;
  1293. X    q->blue=0;
  1294. X    q->index=(unsigned short) index;
  1295. X    q->length=0;
  1296. X    q++;
  1297. X  }
  1298. X  (void) free((char *) alpha_pixels);
  1299. X  CloseImage(image);
  1300. X  return(image);
  1301. }
  1302. X
  1303. /*
  1304. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1305. %                                                                             %
  1306. %                                                                             %
  1307. %                                                                             %
  1308. %  R e a d A V S I m a g e                                                    %
  1309. %                                                                             %
  1310. %                                                                             %
  1311. %                                                                             %
  1312. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1313. %
  1314. %  Function ReadAVSImage reads a AVS X image file and returns it.  It
  1315. %  allocates the memory necessary for the new Image structure and returns a
  1316. %  pointer to the new image.
  1317. %
  1318. %  The format of the ReadAVSImage routine is:
  1319. %
  1320. %      image=ReadAVSImage(image_info)
  1321. %
  1322. %  A description of each parameter follows:
  1323. %
  1324. %    o image:  Function ReadAVSImage returns a pointer to the image after
  1325. %      reading. A null image is returned if there is a a memory shortage or if
  1326. %      the image cannot be read.
  1327. %
  1328. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1329. %
  1330. %
  1331. */
  1332. static Image *ReadAVSImage(image_info)
  1333. ImageInfo
  1334. X  *image_info;
  1335. {
  1336. X  typedef struct _AVSHeader
  1337. X  {
  1338. X    int
  1339. X      width,
  1340. X      height;
  1341. X  } AVSHeader;
  1342. X
  1343. X  AVSHeader
  1344. X    avs_header;
  1345. X
  1346. X  Image
  1347. X    *image;
  1348. X
  1349. X  register int
  1350. X    i;
  1351. X
  1352. X  register unsigned char
  1353. X    *p;
  1354. X
  1355. X  register RunlengthPacket
  1356. X    *q;
  1357. X
  1358. X  unsigned char
  1359. X    *avs_pixels;
  1360. X
  1361. X  unsigned int
  1362. X    status;
  1363. X
  1364. X  /*
  1365. X    Allocate image structure.
  1366. X  */
  1367. X  image=AllocateImage("AVS");
  1368. X  if (image == (Image *) NULL)
  1369. X    return((Image *) NULL);
  1370. X  /*
  1371. X    Open image file.
  1372. X  */
  1373. X  (void) strcpy(image->filename,image_info->filename);
  1374. X  OpenImage(image,"r");
  1375. X  if (image->file == (FILE *) NULL)
  1376. X    {
  1377. X      Warning("unable to open file",image->filename);
  1378. X      DestroyImage(image);
  1379. X      return((Image *) NULL);
  1380. X    }
  1381. X  /*
  1382. X    Read AVS image.
  1383. X  */
  1384. X  status=ReadData((char *) &avs_header,1,sizeof(AVSHeader),image->file);
  1385. X  if (status == False)
  1386. X    {
  1387. X      Warning("not a AVS image file",(char *) NULL);
  1388. X      DestroyImage(image);
  1389. X      return((Image *) NULL);
  1390. X    }
  1391. X  do
  1392. X  {
  1393. X    avs_pixels=(unsigned char *)
  1394. X      malloc(4*avs_header.width*avs_header.height*sizeof(unsigned char));
  1395. X    if (avs_pixels == (unsigned char *) NULL)
  1396. X      {
  1397. X        Warning("memory allocation error",(char *) NULL);
  1398. X        DestroyImages(image);
  1399. X        return((Image *) NULL);
  1400. X      }
  1401. X    (void) ReadData((char *) avs_pixels,1,avs_header.width*avs_header.height*4,
  1402. X      image->file);
  1403. X    /*
  1404. X      Create image.
  1405. X    */
  1406. X    image->alpha=True;
  1407. X    image->columns=avs_header.width;
  1408. X    image->rows=avs_header.height;
  1409. X    image->packets=image->columns*image->rows;
  1410. X    image->pixels=(RunlengthPacket *)
  1411. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  1412. X    image->comments=(char *)
  1413. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  1414. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  1415. X        (image->comments == (char *) NULL))
  1416. X      {
  1417. X        Warning("memory allocation error",(char *) NULL);
  1418. X        DestroyImages(image);
  1419. X        return((Image *) NULL);
  1420. X      }
  1421. X    (void) sprintf(image->comments,"\n  Imported from AVS raster image:  %s\n",
  1422. X      image->filename);
  1423. X    /*
  1424. X      Convert AVS raster image to runlength-encoded packets.
  1425. X    */
  1426. X    p=avs_pixels;
  1427. X    q=image->pixels;
  1428. X    for (i=0; i < (image->columns*image->rows); i++)
  1429. X    {
  1430. X      q->index=(unsigned char) (*p++);
  1431. X      q->red=(*p++);
  1432. X      q->green=(*p++);
  1433. X      q->blue=(*p++);
  1434. X      q->length=0;
  1435. X      q++;
  1436. X    }
  1437. X    (void) free((char *) avs_pixels);
  1438. X    status=ReadData((char *) &avs_header,1,sizeof(AVSHeader),image->file);
  1439. X    if (status == True)
  1440. X      {
  1441. X        /*
  1442. X          Allocate image structure.
  1443. X        */
  1444. X        image->next=AllocateImage("AVS");
  1445. X        if (image->next == (Image *) NULL)
  1446. X          {
  1447. X            DestroyImages(image);
  1448. X            return((Image *) NULL);
  1449. X          }
  1450. X        image->next->file=image->file;
  1451. X        (void) sprintf(image->next->filename,"%s.%u",image_info->filename,
  1452. X          image->scene+1);
  1453. X        image->next->scene=image->scene+1;
  1454. X        image->next->previous=image;
  1455. X        image=image->next;
  1456. X      }
  1457. X  } while (status == True);
  1458. X  while (image->previous != (Image *) NULL)
  1459. X    image=image->previous;
  1460. X  CloseImage(image);
  1461. X  return(image);
  1462. }
  1463. X
  1464. /*
  1465. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1466. %                                                                             %
  1467. %                                                                             %
  1468. %                                                                             %
  1469. %  R e a d B M P I m a g e                                                    %
  1470. %                                                                             %
  1471. %                                                                             %
  1472. %                                                                             %
  1473. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1474. %
  1475. %  Function ReadBMPImage reads a Microsoft Windows bitmap image file and
  1476. %  returns it.  It allocates the memory necessary for the new Image structure
  1477. %  and returns a pointer to the new image.
  1478. %
  1479. %  The format of the ReadBMPImage routine is:
  1480. %
  1481. %      image=ReadBMPImage(image_info)
  1482. %
  1483. %  A description of each parameter follows:
  1484. %
  1485. %    o image:  Function ReadBMPImage returns a pointer to the image after
  1486. %      reading.  A null image is returned if there is a a memory shortage or
  1487. %      if the image cannot be read.
  1488. %
  1489. %    o image_info: Specifies a pointer to an ImageInfo structure.
  1490. %
  1491. %
  1492. */
  1493. static Image *ReadBMPImage(image_info)
  1494. ImageInfo
  1495. X  *image_info;
  1496. {
  1497. X  typedef struct _BMPHeader
  1498. X  {
  1499. X    unsigned long
  1500. X      file_size;
  1501. X
  1502. X    unsigned short
  1503. X      reserved[2];
  1504. X
  1505. X    unsigned long
  1506. X      offset_bits,
  1507. X      size,
  1508. X      width,
  1509. X      height;
  1510. X
  1511. X    unsigned short
  1512. X      planes,
  1513. X      bit_count;
  1514. X
  1515. X    unsigned long
  1516. X      compression,
  1517. X      image_size,
  1518. X      x_pixels,
  1519. X      y_pixels,
  1520. X      number_colors,
  1521. X      colors_important;
  1522. X  } BMPHeader;
  1523. X
  1524. X  BMPHeader
  1525. X    bmp_header;
  1526. X
  1527. X  Image
  1528. X    *image;
  1529. X
  1530. X  register int
  1531. X    bit,
  1532. X    i,
  1533. X    x,
  1534. X    y;
  1535. X
  1536. X  register RunlengthPacket
  1537. X    *q;
  1538. X
  1539. X  register unsigned char
  1540. X    *p;
  1541. X
  1542. X  unsigned char
  1543. X    *bmp_data,
  1544. X    *bmp_pixels,
  1545. X    magick[12];
  1546. X
  1547. X  unsigned int
  1548. X    bytes_per_line,
  1549. X    status;
  1550. X
  1551. X  /*
  1552. X    Allocate image structure.
  1553. X  */
  1554. X  image=AllocateImage("BMP");
  1555. X  if (image == (Image *) NULL)
  1556. X    return((Image *) NULL);
  1557. X  /*
  1558. X    Open image file.
  1559. X  */
  1560. X  (void) strcpy(image->filename,image_info->filename);
  1561. X  OpenImage(image,"r");
  1562. X  if (image->file == (FILE *) NULL)
  1563. X    {
  1564. X      Warning("unable to open file",image->filename);
  1565. X      DestroyImage(image);
  1566. X      return((Image *) NULL);
  1567. X    }
  1568. X  /*
  1569. X    Determine if this is a BMP file.
  1570. X  */
  1571. X  status=ReadData((char *) magick,1,2,image->file);
  1572. X  do
  1573. X  {
  1574. X    /*
  1575. X      Verify BMP identifier.
  1576. X    */
  1577. X    if ((status == False) || (strncmp((char *) magick,"BM",2) != 0))
  1578. X      {
  1579. X        Warning("not a BMP image file",(char *) NULL);
  1580. X        DestroyImages(image);
  1581. X        return((Image *) NULL);
  1582. X      }
  1583. X    bmp_header.file_size=LSBFirstReadLong(image->file);
  1584. X    bmp_header.reserved[0]=LSBFirstReadShort(image->file);
  1585. X    bmp_header.reserved[1]=LSBFirstReadShort(image->file);
  1586. X    bmp_header.offset_bits=LSBFirstReadLong(image->file);
  1587. X    bmp_header.size=LSBFirstReadLong(image->file);
  1588. X    bmp_header.width=LSBFirstReadLong(image->file);
  1589. X    bmp_header.height=LSBFirstReadLong(image->file);
  1590. X    bmp_header.planes=LSBFirstReadShort(image->file);
  1591. X    bmp_header.bit_count=LSBFirstReadShort(image->file);
  1592. X    bmp_header.compression=LSBFirstReadLong(image->file);
  1593. X    bmp_header.image_size=LSBFirstReadLong(image->file);
  1594. X    bmp_header.x_pixels=LSBFirstReadLong(image->file);
  1595. X    bmp_header.y_pixels=LSBFirstReadLong(image->file);
  1596. X    bmp_header.number_colors=LSBFirstReadLong(image->file);
  1597. X    bmp_header.colors_important=LSBFirstReadLong(image->file);
  1598. X    for (i=0; i < ((int) bmp_header.size-40); i++)
  1599. X      (void) fgetc(image->file);
  1600. X    if (bmp_header.bit_count < 24)
  1601. X      {
  1602. X        unsigned char
  1603. X          *bmp_colormap;
  1604. X
  1605. X        /*
  1606. X          Read BMP raster colormap.
  1607. X        */
  1608. X        image->class=PseudoClass;
  1609. X        image->colors=bmp_header.number_colors;
  1610. X        if (image->colors == 0)
  1611. X          image->colors=1 << bmp_header.bit_count;
  1612. X        image->colormap=(ColorPacket *)
  1613. X          malloc(image->colors*sizeof(ColorPacket));
  1614. X        bmp_colormap=(unsigned char *)
  1615. X          malloc(4*image->colors*sizeof(unsigned char));
  1616. X        if ((image->colormap == (ColorPacket *) NULL) ||
  1617. X            (bmp_colormap == (unsigned char *) NULL))
  1618. X          {
  1619. X            Warning("memory allocation error",(char *) NULL);
  1620. X            DestroyImages(image);
  1621. X            return((Image *) NULL);
  1622. X          }
  1623. X        (void) ReadData((char *) bmp_colormap,4,(int) image->colors,
  1624. X          image->file);
  1625. X        p=bmp_colormap;
  1626. X        for (i=0; i < image->colors; i++)
  1627. X        {
  1628. X          image->colormap[i].blue=(*p++);
  1629. X          image->colormap[i].green=(*p++);
  1630. X          image->colormap[i].red=(*p++);
  1631. X          p++;
  1632. X        }
  1633. X        (void) free((char *) bmp_colormap);
  1634. X      }
  1635. X    /*
  1636. X      Read image data.
  1637. X    */
  1638. X    if (bmp_header.image_size == 0)
  1639. X      bmp_header.image_size=
  1640. X        ((bmp_header.width*bmp_header.bit_count+31)/32)*4*bmp_header.height;
  1641. X    bmp_data=(unsigned char *)
  1642. X      malloc(bmp_header.image_size*sizeof(unsigned char));
  1643. X    if (bmp_data == (unsigned char *) NULL)
  1644. X      {
  1645. X        Warning("memory allocation error",(char *) NULL);
  1646. X        DestroyImages(image);
  1647. X        return((Image *) NULL);
  1648. X      }
  1649. X    status=ReadData((char *) bmp_data,1,(int) bmp_header.image_size,
  1650. X      image->file);
  1651. X    if (status == False)
  1652. X      {
  1653. X        Warning("unable to read image data",image_info->filename);
  1654. X        DestroyImages(image);
  1655. X        return((Image *) NULL);
  1656. X      }
  1657. X    bmp_pixels=bmp_data;
  1658. X    if (bmp_header.compression != 0)
  1659. X      {
  1660. X        /*
  1661. X          Convert run-length encoded raster pixels.
  1662. X        */
  1663. X        bmp_pixels=(unsigned char *)
  1664. X          malloc(bmp_header.image_size*sizeof(unsigned char));
  1665. X        if (bmp_pixels == (unsigned char *) NULL)
  1666. X          {
  1667. X            Warning("memory allocation error",(char *) NULL);
  1668. X            DestroyImages(image);
  1669. X            return((Image *) NULL);
  1670. X          }
  1671. X        (void) BMPDecodeImage(bmp_data,bmp_pixels,
  1672. X          (unsigned int) bmp_header.width,(unsigned int) bmp_header.height);
  1673. X        (void) free((char *) bmp_data);
  1674. X      }
  1675. X    /*
  1676. X      Create image.
  1677. X    */
  1678. X    image->columns=bmp_header.width;
  1679. X    image->rows=bmp_header.height;
  1680. X    image->packets=image->columns*image->rows;
  1681. X    image->pixels=(RunlengthPacket *)
  1682. X      malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  1683. X    image->comments=(char *)
  1684. X      malloc((strlen(image->filename)+2048)*sizeof(char));
  1685. X    (void) sprintf(image->comments,
  1686. X      "\n  Imported from BMP raster image:  %s\n",image->filename);
  1687. X    if ((image->pixels == (RunlengthPacket *) NULL) ||
  1688. X        (image->comments == (char *) NULL))
  1689. X      {
  1690. X        Warning("memory allocation error",(char *) NULL);
  1691. X        DestroyImages(image);
  1692. X        return((Image *) NULL);
  1693. X      }
  1694. X    /*
  1695. X      Convert BMP raster image to runlength-encoded packets.
  1696. SHAR_EOF
  1697. true || echo 'restore of ImageMagick/decode.c failed'
  1698. fi
  1699. echo 'End of ImageMagick part 13'
  1700. echo 'File ImageMagick/decode.c is continued in part 14'
  1701. echo 14 > _shar_seq_.tmp
  1702. exit 0
  1703.  
  1704. exit 0 # Just in case...
  1705. -- 
  1706.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1707. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1708.  "It's intuitively obvious to the |
  1709.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1710.