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

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i087:  imagemagic - X11 image processing and display, Part31/38
  4. Message-ID: <1993Jul14.232146.23096@sparky.sterling.com>
  5. X-Md4-Signature: 89755b6e733ac1cb9e8c5e7af7978402
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 23:21:46 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 87
  13. Archive-name: imagemagic/part31
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.31 (part 31 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/quantize.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" != 31; 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/quantize.c'
  36. else
  37. echo 'x - continuing file ImageMagick/quantize.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/quantize.c' &&
  39. X      Classification(colormap_image);
  40. X      if (colorspace != RGBColorspace)
  41. X        TransformRGBImage(colormap_image,colorspace);
  42. X      optimal=True;
  43. X    }
  44. X  for (i=0; i < number_images; i++)
  45. X  {
  46. X    if (!dither)
  47. X      if (images[i]->packets == (images[i]->columns*images[i]->rows))
  48. X        CompressImage(images[i]);
  49. X    if (colorspace != RGBColorspace)
  50. X      RGBTransformImage(images[i],colorspace);
  51. X    if (colormap_image == (Image *) NULL)
  52. X      Classification(images[i]);
  53. X  }
  54. X  Reduction(number_colors);
  55. X  for (i=0; i < number_images; i++)
  56. X  {
  57. X    Assignment(images[i],dither,colorspace,optimal);
  58. X    if (colorspace != RGBColorspace)
  59. X      TransformRGBImage(images[i],colorspace);
  60. X  }
  61. X  /*
  62. X    Release color cube tree storage.
  63. X  */
  64. X  do
  65. X  {
  66. X    nodes=cube.node_queue->next;
  67. X    (void) free((char *) cube.node_queue);
  68. X    cube.node_queue=nodes;
  69. X  }
  70. X  while (cube.node_queue != (Nodes *) NULL);
  71. }
  72. SHAR_EOF
  73. echo 'File ImageMagick/quantize.c is complete' &&
  74. chmod 0644 ImageMagick/quantize.c ||
  75. echo 'restore of ImageMagick/quantize.c failed'
  76. Wc_c="`wc -c < 'ImageMagick/quantize.c'`"
  77. test 60193 -eq "$Wc_c" ||
  78.     echo 'ImageMagick/quantize.c: original size 60193, current size' "$Wc_c"
  79. rm -f _shar_wnt_.tmp
  80. fi
  81. # ============= ImageMagick/miff.man ==============
  82. if test -f 'ImageMagick/miff.man' -a X"$1" != X"-c"; then
  83.     echo 'x - skipping ImageMagick/miff.man (File already exists)'
  84.     rm -f _shar_wnt_.tmp
  85. else
  86. > _shar_wnt_.tmp
  87. echo 'x - extracting ImageMagick/miff.man (Text)'
  88. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/miff.man' &&
  89. .ad l
  90. .nh
  91. .TH MIFF 5 "10 October 1992" "ImageMagick"
  92. .SH NAME
  93. MIFF - ImageMagick's file format for raster images.
  94. .SH SYNOPSIS
  95. .B #include <image.h>
  96. .SH DESCRIPTION
  97. A MIFF image file consist of two sections.  The first section is
  98. composed of keywords describing the image in text form.  The next
  99. section is the binary image data.  The two sections are separated by a
  100. \fB:\fP character immediately followed by a \fInewline\fP.  Generally,
  101. the first section has a \fIform-feed\fP and \fInewline\fP proceeding
  102. the \fB:\fP character.   You can then list the image keywords with
  103. \fImore\fP, without printing the binary image that follows the \fB:\fP
  104. separator.
  105. .PP
  106. Each keyword must be separated by at least one space but can be
  107. separated with control characters such a \fIform-feed\fP or
  108. \fInewline\fP.
  109. .PP
  110. A list of valid keywords follows:
  111. .TP 5
  112. .B "alpha=\fITrue | False\fP"
  113. specifies whether a continuous-tone image also has alpha data.  Alpha data is
  114. generally useful for image compositing.
  115. X
  116. This keyword is optional.  If it is not specified, no alpha data is assumed.
  117. This keyword has no meaning for pseudo-color images.
  118. .TP 5
  119. .B "class=\fIDirectClass | PseudoClass\fP"
  120. identifies the type of binary image stored within the file.
  121. X
  122. This keyword is optional.  If it is not specified, a \fIDirectClass\fP
  123. image format is assumed.  An explanation of \fIDirectClass\fP and
  124. \fIPseudoClass\fP image data follows this list.
  125. .TP 5
  126. .B "colors=\fIvalue\fP"
  127. specifies the number of colors in the image, and for pseudo-color
  128. images the size of the colormap.
  129. X
  130. This keyword is optional.  However, if a colormap size is not
  131. specified, a linear colormap is assumed for pseudo-color images.
  132. .TP 5
  133. .B "columns=\fIvalue\fP"
  134. is a required keyword and specifies the number of columns, or width in
  135. pixels, of the image.
  136. .TP 5
  137. .B "compression=\fIQEncoded | RunlengthEncoded\fP"
  138. identifies how the image stored within the file is compressed.
  139. X
  140. This keyword is optional.  If it is not specified, the image is assumed
  141. to be uncompressed.  \fIQEncoded\fP has no meaning for pseudo-color
  142. images.  A detailed explanation of runlength-encoded and predictive
  143. arithmetic image compression follows this list.
  144. .TP 5
  145. .B "id=\fBImageMagick\fP"
  146. is a required keyword and identifies this file as a MIFF image.
  147. .TP 5
  148. .B "montage=\fI<width>x<height>{\+-}<x offset>{\+-}<y offset>\fP
  149. size and location of the individual tiles of a composite image.  See
  150. \fBX(1)\fP for details about the geometry specification.
  151. X
  152. Use this keyword when the image is a composite of a number of different
  153. tiles.  A tile consists of an image and optionally a border and a
  154. label.  \fI<width>\fP is the size in pixels of each individual tile in
  155. the horizonal direction and \fI<height>\fP is the size in the vertical
  156. direction.  Each tile must have an equal number of pixels in width and
  157. equal in height.  However, the width can differ from the height.  \fI<x
  158. offset>\fP is the offset in number of pixels from the vertical edge of
  159. the composite image where the first tile of a row begins and \fI<y
  160. offset>\fP is the offset from the horizonal edge where the first tile
  161. of a column begins.
  162. X
  163. If this keyword is specified, a directory of tile names must follow the
  164. image header.  The format of the directory is explained below.
  165. .TP 5
  166. .B "packets=\fIvalue\fP"
  167. specifies the number of compressed color packets in the image data
  168. section.
  169. X
  170. This keyword is optional, but recommended, for runlength-encoded image
  171. compression.  It is required for arithimetic encoded image compression.  A
  172. detailed explanation of image compression follows this list.
  173. .TP 5
  174. .B "rows=\fIvalue\fP"
  175. is a required keyword and specifies the number of rows, or height in pixels,
  176. of the image.
  177. .TP 5
  178. .B "scene=\fIvalue\fP"
  179. is an optional keyword and is a reference number for sequencing of
  180. images.
  181. X
  182. This keyword is typically useful for animating a sequence of images.
  183. .TP 5
  184. .B "signature=\fIvalue\fP"
  185. is an optional keyword and is a character string that uniquely identifies
  186. the image colormap.
  187. X
  188. A unique identifier for the colormap is useful for animating a sequence
  189. of \fIPseudoClass\fP images.  The default identifier is a digital
  190. signature computed from RSA's Data Security MD5 Digest Algorithm
  191. described in Internet draft [MD5], July 1992.  The colormap signature is
  192. usually computed for \fIPseudoClass\fP images.
  193. .PP
  194. Comments can be included in the keyword section.  Comments must begin with
  195. a \fB{\fP character and end with a \fI}\fP character.
  196. .PP
  197. An example keyword section follows:
  198. .PP
  199. X    {
  200. X      Rendered via Dore by Sandy Hause.
  201. X    }
  202. X    id=ImageMagick
  203. X    class=PseudoClass  colors=256  signature=d79e1c308aa5bbcdeea8ed63df412da9
  204. X    compression=RunlengthEncoded  packets=27601
  205. X    columns=1280  rows=1024
  206. X    scene=1  
  207. X    ^L
  208. X    :
  209. .PP
  210. If you specify \fBmontage\fP in the image header, follow the header
  211. with a directory of image tiles.  This directory consists of a name for
  212. each tile of the composite image separated by a NEWLINE character.  The
  213. list is terminated with a NULL character.
  214. .PP
  215. The binary image data that follows the keyword text is stored in one of
  216. two binary classes as specified by the \fBclass\fP keyword:
  217. \fIDirectClass\fP or \fIPseudoClass\fP.
  218. .PP
  219. Use the \fIDirectClass\fP class to store continuous-tone images.
  220. \fIDirectClass\fP requires that the image pixels immediately follow the
  221. keyword text and be stored as binary red, green, and blue intensity
  222. values (and optional alpha value).  Each color component is stored as
  223. one binary byte (8 bit) and ranges from 0 through 255.  The total
  224. number of pixels expected is equal to the number of pixel columns times
  225. the number of pixel rows as specified by the \fBcolumns\fP and
  226. \fBrows\fP keywords.
  227. .PP
  228. If the \fBcompression\fP keyword is not specified, a red, green, and blue byte
  229. (and optional alpha byte) in that order is expected for each pixel of the
  230. image.
  231. .PP
  232. If \fBcompression\fP is \fIQEncoded\fP, each red, green, and blue byte
  233. intensity value (and optional alpha value) is encoded using the predictive
  234. arithmetic compression algorithm.  Use the \fBpackets\fP keyword to specify
  235. the total number of arithimetic encoded packets that comprise the image.
  236. .PP
  237. If \fBcompression\fP is \fIRunlengthEncoded\fP, each red, green, and
  238. blue byte intensity value (and optional alpha value) is followed by a
  239. count byte. This value specifies the number of horizonally contiguous
  240. pixels in the image of that color.  The count (0-255) is one less than
  241. the actual number of contiguous pixels; thus a single packet can
  242. represent from 1 up to 256 identical pixels.  The total number of
  243. pixels specified by the individual count bytes must add up to the
  244. number of pixel columns times the number of pixel rows as specified by
  245. the \fBcolumns\fP and \fBrows\fP keywords.  Use \fBpackets\fP to
  246. specify the total number of runlength-encoded packets that comprise the
  247. image.
  248. .PP
  249. Use the \fIPseudoClass\fP class to store pseudo-color images.
  250. \fIPseudoClass\fP requires that the image colormap and pseudo-color
  251. pixels immediately follow the keyword text.  The colormap is stored as
  252. contiguous red, green, and blue intensity values.  Each color component
  253. is stored as one binary byte (8 bit) and ranges from 0 through 255. The
  254. number of intensity values expected is determined by the \fBcolors\fP
  255. keyword.  Note, an image colormap is restricted to at most 65535
  256. entries.  The binary pseudo-color image is stored as indexes into the
  257. colormap.  For colormaps of 256 colors or less, the indexes are stored
  258. as one binary byte (8 bit) and ranges from 0 through 255.  If the
  259. colormap size exceeds 256 entries, then each colormap index is two
  260. bytes each with the most-significant-byte first.  The total number of
  261. pixels expected is equal to the number of pixel columns times the
  262. number of pixel rows as specified by the \fBcolumns\fP and \fBrows\fP
  263. keywords.
  264. .PP
  265. If the \fBcompression\fP keyword is not specified, a colormap index is
  266. expected for each pixel of the image.
  267. .PP
  268. If \fBcompression\fP is \fIRunlengthEncoded\fP, each colormap index
  269. is followed by a count byte. This value  specifies the number of
  270. horizonally contiguous pixels in the image of that color.  The count
  271. (0-255) is one less than the actual number of contiguous pixels; thus a
  272. single packet can represent from 1 up to 256 identical pixels.  The
  273. total number of pixels specified by the individual count bytes must add
  274. up to the number of pixels expected in the image as specified by the
  275. \fBcolumns\fP and \fBrows\fP keywords.  Use \fBpackets\fP to specify the
  276. total number of runlength-encoded packets that comprise the image.
  277. .SH SEE ALSO
  278. .B
  279. display(1), animate(1), import(1), montage(1), mogrify(1), convert(1), more(1), compress(1)
  280. .SH COPYRIGHT
  281. Copyright 1993 E. I. du Pont de Nemours & Company
  282. .PP
  283. Permission to use, copy, modify, distribute, and sell this software and
  284. its documentation for any purpose is hereby granted without fee,
  285. provided that the above copyright notice appear in all copies and that
  286. both that copyright notice and this permission notice appear in
  287. supporting documentation, and that the name of E. I. du Pont de Nemours
  288. & Company not be used in advertising or publicity pertaining to
  289. distribution of the software without specific, written prior
  290. permission.  E. I. du Pont de Nemours & Company makes no representations
  291. about the suitability of this software for any purpose.  It is provided
  292. "as is" without express or implied warranty.
  293. .PP
  294. E. I. du Pont de Nemours & Company disclaims all warranties with regard
  295. to this software, including all implied warranties of merchantability
  296. and fitness, in no event shall E. I. du Pont de Nemours & Company be
  297. liable for any special, indirect or consequential damages or any
  298. damages whatsoever resulting from loss of use, data or profits, whether
  299. in an action of contract, negligence or other tortious action, arising
  300. out of or in connection with the use or performance of this software.
  301. .SH AUTHORS
  302. John Cristy, E.I. du Pont de Nemours & Company Incorporated
  303. SHAR_EOF
  304. chmod 0644 ImageMagick/miff.man ||
  305. echo 'restore of ImageMagick/miff.man failed'
  306. Wc_c="`wc -c < 'ImageMagick/miff.man'`"
  307. test 9952 -eq "$Wc_c" ||
  308.     echo 'ImageMagick/miff.man: original size 9952, current size' "$Wc_c"
  309. rm -f _shar_wnt_.tmp
  310. fi
  311. # ============= ImageMagick/montage.c ==============
  312. if test -f 'ImageMagick/montage.c' -a X"$1" != X"-c"; then
  313.     echo 'x - skipping ImageMagick/montage.c (File already exists)'
  314.     rm -f _shar_wnt_.tmp
  315. else
  316. > _shar_wnt_.tmp
  317. echo 'x - extracting ImageMagick/montage.c (Text)'
  318. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/montage.c' &&
  319. /*
  320. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  321. %                                                                             %
  322. %                                                                             %
  323. %                                                                             %
  324. %             M   M   OOO   N   N  TTTTT   AAA    GGGG  EEEEE                 %
  325. %             MM MM  O   O  NN  N    T    A   A  G      E                     %
  326. %             M M M  O   O  N N N    T    AAAAA  G  GG  EEE                   %
  327. %             M   M  O   O  N  NN    T    A   A  G   G  E                     %
  328. %             M   M   OOO   N   N    T    A   A   GGGG  EEEEE                 %
  329. %                                                                             %
  330. %                                                                             %
  331. %          Montage Machine Independent File Format Image via X11.             %
  332. %                                                                             %
  333. %                                                                             %
  334. %                                                                             %
  335. %                           Software Design                                   %
  336. %                             John Cristy                                     %
  337. %                              July 1992                                      %
  338. %                                                                             %
  339. %                                                                             %
  340. %  Copyright 1993 E. I. du Pont de Nemours & Company                          %
  341. %                                                                             %
  342. %  Permission to use, copy, modify, distribute, and sell this software and    %
  343. %  its documentation for any purpose is hereby granted without fee,           %
  344. %  provided that the above Copyright notice appear in all copies and that     %
  345. %  both that Copyright notice and this permission notice appear in            %
  346. %  supporting documentation, and that the name of E. I. du Pont de Nemours    %
  347. %  & Company not be used in advertising or publicity pertaining to            %
  348. %  distribution of the software without specific, written prior               %
  349. %  permission.  E. I. du Pont de Nemours & Company makes no representations   %
  350. %  about the suitability of this software for any purpose.  It is provided    %
  351. %  "as is" without express or implied warranty.                               %
  352. %                                                                             %
  353. %  E. I. du Pont de Nemours & Company disclaims all warranties with regard    %
  354. %  to this software, including all implied warranties of merchantability      %
  355. %  and fitness, in no event shall E. I. du Pont de Nemours & Company be       %
  356. %  liable for any special, indirect or consequential damages or any           %
  357. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  358. %  in an action of contract, negligence or other tortious action, arising     %
  359. %  out of or in connection with the use or performance of this software.      %
  360. %                                                                             %
  361. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  362. %
  363. %  Montage creates a composite image by combining several separate
  364. %  images.  The images are tiled on the composite image with the name of
  365. %  the image appearing just above the individual tile.
  366. %
  367. %  The composite image is constructed in the following manner.  First,
  368. %  each image specified on the command line, except for the last, is
  369. %  scaled to fit the maximum tile size.  The maximum tile size by default
  370. %  is 256x256.  It can be modified with the -geometry command line
  371. %  argument or X resource.  Note that the maximum tile size need not be a
  372. %  square.  The original aspect ratio of each image is maintainted unless
  373. %  +aspect_ratio is specfified.
  374. %
  375. %  Next the composite image is initialized with the color specified by the
  376. %  -background command line argument or X resource.  The width and height
  377. %  of the composite image is determined by the maximum tile size, the
  378. %  number of tiles per row, the tile border width and height, the image
  379. %  border width, and the label height.  The number of tiles per row specifies
  380. %  how many images are to appear in each row of the composite image.  The
  381. %  default is to have an equal number of images in each row and column of the
  382. %  composite.  This value can be specified with -tiles_per_row.  The tile
  383. %  border width and height, and the image border width defaults to the value
  384. %  of the X resource -borderwidth.  It can be changed with the -borderwidth or
  385. %  -geometry command line argument or X resource.  The label height is
  386. %  determined by the font you specify with the -font command line argument or
  387. %  X resource.  If you do not specify a font, a font is choosen that allows
  388. %  the name of the image to fit the maximum width of a tiled area.  The label
  389. %  colors is determined by the -background and -foreground command line
  390. %  argument or X resource.  Note, that if the background and foreground colors
  391. %  are the same, labels will not appear.
  392. %
  393. %  Finally, each image is set onto the composite image, surrounded by its
  394. %  border color, with its name centered just below it.  The individual images
  395. %  are centered within the width of the tiled area.  The final argument on the
  396. %  command line is the name assigned to the composite image.  The image is
  397. %  written in the MIFF format and may by viewed or printed with `display'.
  398. %
  399. %  The Montage program command syntax is:
  400. %
  401. %  Usage: montage [options ...] file [ [options ...] file ...] file
  402. %
  403. %  Where options include:
  404. %    -aspect_ratio         respect aspect ratio of the image
  405. %    -clip geometry        preferred size and location of the clipped image
  406. %    -colors value         preferred number of colors in the image
  407. %    -colorspace type      GRAY, RGB, XYZ, YCbCr, YIQ, or YUV
  408. %    -compose operator     composite operator
  409. %    -compress type        RunlengthEncoded or QEncoded
  410. %    -density geometry     vertical and horizonal density of the image
  411. %    -display server       query fonts from this X server
  412. %    -dither               apply Floyd/Steinberg error diffusion to image
  413. %    -frame                surround image with an ornamental border
  414. %    -gamma value          level of gamma correction
  415. %    -geometry geometry    preferred tile and border sizes
  416. %    -gravity direction    which direction to gravitate towards
  417. %    -interlace type       NONE, LINE, or PLANE
  418. %    -monochrome           transform image to black and white
  419. %    -page geometry        size and location of the Postscript page
  420. %    -quality value        JPEG quality setting
  421. %    -rotate degrees       apply Paeth rotation to the image
  422. %    -tiles_per_row value  number of image tiles per row
  423. %    -treedepth value      depth of the color classification tree
  424. %    -verbose              print detailed information about the image
  425. %
  426. %  In addition to those listed above, you can specify these standard X
  427. %  resources as command line options:  -background, -bordercolor -borderwidth,
  428. %  -font, -foreground, -highlight, or -title.
  429. %
  430. %  Change '-' to '+' in any option above to reverse its effect.  For
  431. %  example, specify +compress to store the image as uncompressed.
  432. %
  433. %  By default, the image format of `file' is determined by its magic
  434. %  number.  To specify a particular image format, precede the filename
  435. %  with an image format name and a colon (i.e. ps:image) or specify the
  436. %  image type as the filename suffix (i.e. image.ps).  Specify 'file' as
  437. %  '-' for standard input or output.
  438. %
  439. %
  440. */
  441. X
  442. /*
  443. X  Include declarations.
  444. */
  445. #include "display.h"
  446. #include "image.h"
  447. #include "X.h"
  448. #include "compress.h"
  449. X
  450. /*
  451. X  Global declarations.
  452. */
  453. char
  454. X  *client_name;
  455. X
  456. /*
  457. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  458. %                                                                             %
  459. %                                                                             %
  460. %                                                                             %
  461. %   E r r o r                                                                 %
  462. %                                                                             %
  463. %                                                                             %
  464. %                                                                             %
  465. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  466. %
  467. %  Function Error displays an error message and then terminates the program.
  468. %
  469. %  The format of the Error routine is:
  470. %
  471. %      Error(message,qualifier)
  472. %
  473. %  A description of each parameter follows:
  474. %
  475. %    o message: Specifies the message to display before terminating the
  476. %      program.
  477. %
  478. %    o qualifier: Specifies any qualifier to the message.
  479. %
  480. %
  481. */
  482. void Error(message,qualifier)
  483. char
  484. X  *message,
  485. X  *qualifier;
  486. {
  487. X  (void) fprintf(stderr,"%s: %s",client_name,message);
  488. X  if (qualifier != (char *) NULL)
  489. X    (void) fprintf(stderr," (%s)",qualifier);
  490. X  (void) fprintf(stderr,".\n");
  491. X  exit(1);
  492. }
  493. X
  494. /*
  495. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  496. %                                                                             %
  497. %                                                                             %
  498. %                                                                             %
  499. %   M o n t a g e I m a g e                                                   %
  500. %                                                                             %
  501. %                                                                             %
  502. %                                                                             %
  503. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  504. %
  505. %  Function MontageImage creates a composite image by combining several
  506. %  separate images.
  507. %
  508. %  The format of the MontageImage routine is:
  509. %
  510. %      MontageImage(display,resource_info,images,number_tiles,tiles_per_row,
  511. %        frame,compose)
  512. %
  513. %  A description of each parameter follows:
  514. %
  515. %    o display: Specifies a connection to an X server;  returned from
  516. %      XOpenDisplay.
  517. %
  518. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  519. %
  520. %    o image: Specifies a pointer to a Image structure; returned from
  521. %      ReadImage.
  522. %
  523. %    o number_tiles: Specifies the number of tiles to tile.
  524. %
  525. %    o tiles_per_row: Specifies the number of arguments.
  526. %
  527. %    o frame: An integer greater than zero will force an ornamental border
  528. %      around each tile.
  529. %
  530. %    o compose: Specifies an image composite operator.
  531. %
  532. %
  533. */
  534. static int LinearCompare(x,y)
  535. const void
  536. X  *x,
  537. X  *y;
  538. {
  539. X  Image
  540. X    **image_1,
  541. X    **image_2;
  542. X
  543. X  image_1=(Image **) x;
  544. X  image_2=(Image **) y;
  545. X  return((int) (*image_1)->scene-(int) (*image_2)->scene);
  546. }
  547. X
  548. static Image *MontageImage(display,resource_info,images,number_tiles,
  549. X  tiles_per_row,frame,compose)
  550. Display
  551. X  *display;
  552. X
  553. XXResourceInfo
  554. X  *resource_info;
  555. X
  556. Image
  557. X  **images;
  558. X
  559. unsigned int
  560. X  number_tiles,
  561. X  tiles_per_row,
  562. X  frame,
  563. X  compose;
  564. {
  565. #define HighlightWidth  5
  566. X
  567. X  ColorPacket
  568. X    border_color,
  569. X    highlight_color;
  570. X
  571. X  Image
  572. X    *image,
  573. X    *montage_image;
  574. X
  575. X  int
  576. X    x,
  577. X    x_offset,
  578. X    y,
  579. X    y_offset;
  580. X
  581. X  register char
  582. X    *q;
  583. X
  584. X  register int
  585. X    i;
  586. X
  587. X  register RunlengthPacket
  588. X    *p;
  589. X
  590. X  RectangleInfo
  591. X    tile_info;
  592. X
  593. X  unsigned int
  594. X    border_width,
  595. X    count,
  596. X    status,
  597. X    tile;
  598. X
  599. X  XAnnotateInfo
  600. X    annotate_info;
  601. X
  602. X  XColor
  603. X    background_color;
  604. X
  605. X  XWindowInfo
  606. X    image_window;
  607. X
  608. X  /*
  609. X    Determine tile sizes.
  610. X  */
  611. X  border_width=resource_info->border_width;
  612. X  if (frame)
  613. X    border_width+=2*HighlightWidth;
  614. X  tile_info.x=resource_info->border_width;
  615. X  tile_info.y=resource_info->border_width;
  616. X  if (resource_info->image_geometry != (char *) NULL)
  617. X    {
  618. X      XParseGeometry(resource_info->image_geometry,&tile_info.x,
  619. X        &tile_info.y,&tile_info.width,&tile_info.height);
  620. X      if (tile_info.x < 0)
  621. X        tile_info.x=0;
  622. X      if (tile_info.y < 0)
  623. X        tile_info.y=0;
  624. X    }
  625. X  tile_info.width=images[0]->columns;
  626. X  tile_info.height=images[0]->rows;
  627. X  for (tile=1; tile < number_tiles; tile++)
  628. X  {
  629. X    if (images[tile]->columns > tile_info.width)
  630. X      tile_info.width=images[tile]->columns;
  631. X    if (images[tile]->rows > tile_info.height)
  632. X      tile_info.height=images[tile]->rows;
  633. X  }
  634. X  if (tiles_per_row == 0)
  635. X    {
  636. X      /*
  637. X        Compute tiles per row.
  638. X      */
  639. X      tiles_per_row=1;
  640. X      while ((tiles_per_row*tiles_per_row) < number_tiles)
  641. X        tiles_per_row++;
  642. X    }
  643. X  /*
  644. X    Initialize tile colors.
  645. X  */
  646. X  background_color.red=0;
  647. X  background_color.green=0;
  648. X  background_color.blue=0;
  649. X  border_color.red=0;
  650. X  border_color.green=0;
  651. X  border_color.blue=0;
  652. X  highlight_color=border_color;
  653. X  XGetAnnotateInfo(&annotate_info);
  654. X  if (display)
  655. X    {
  656. X      char
  657. X        text[2048];
  658. X
  659. X      XFontStruct
  660. X        *font_info;
  661. X
  662. X      XPixelInfo
  663. X        pixel_info;
  664. X
  665. X      XStandardColormap
  666. X        map_info;
  667. X
  668. X      XVisualInfo
  669. X        *visual_info;
  670. X
  671. X      /*
  672. X        Initialize visual info.
  673. X      */
  674. X      visual_info=XBestVisualInfo(display,"default",(char *) NULL,
  675. X        (XStandardColormap *) NULL);
  676. X      if (visual_info == (XVisualInfo *) NULL)
  677. X         Error("unable to get visual",resource_info->visual_type);
  678. X      /*
  679. X        Initialize font info.
  680. X      */
  681. X      tile=0;
  682. X      for (i=1; i < number_tiles; i++)
  683. X        if ((int) strlen(images[i]->filename) >
  684. X            (int) strlen(images[tile]->filename))
  685. X          tile=i;
  686. X      (void) strcpy(text,images[tile]->filename);
  687. X      font_info=XBestFont(display,resource_info,text,tile_info.width);
  688. X      if (font_info == (XFontStruct *) NULL)
  689. X        Error("unable to load font",resource_info->font);
  690. X      annotate_info.text=(char *) malloc(2048*sizeof(char));
  691. X      if (annotate_info.text == (char *) NULL)
  692. X        Error("unable to montage images","memory allocation failed");
  693. X      annotate_info.font_info=font_info;
  694. X      annotate_info.height=font_info->ascent+font_info->descent;
  695. X      /*
  696. X        Determine background, border, and highlight colors.
  697. X      */
  698. X      map_info.colormap=XDefaultColormap(display,visual_info->screen);
  699. X      XGetPixelInfo(display,visual_info,&map_info,resource_info,(Image *) NULL,
  700. X        &pixel_info);
  701. X      background_color=pixel_info.background_color;
  702. X      border_color.red=pixel_info.border_color.red >> 8;
  703. X      border_color.green=pixel_info.border_color.green >> 8;
  704. X      border_color.blue=pixel_info.border_color.blue >> 8;
  705. X      highlight_color.red=pixel_info.highlight_color.red >> 8;
  706. X      highlight_color.green=pixel_info.highlight_color.green >> 8;
  707. X      highlight_color.blue=pixel_info.highlight_color.blue >> 8;
  708. X      /*
  709. X        Window superclass.
  710. X      */
  711. X      image_window.id=XRootWindow(display,visual_info->screen);
  712. X      image_window.screen=visual_info->screen;
  713. X      image_window.depth=visual_info->depth;
  714. X      image_window.visual_info=visual_info;
  715. X      image_window.pixel_info=(&pixel_info);
  716. X      image_window.font_info=font_info;
  717. X    }
  718. X  /*
  719. X    Allocate image structure.
  720. X  */
  721. X  montage_image=AllocateImage("MIFF");
  722. X  if (montage_image == (Image *) NULL)
  723. X    Error("memory allocation error",(char *) NULL);
  724. X  /*
  725. X    Initialize Image structure.
  726. X  */
  727. X  montage_image->comments=(char *) malloc(2048*sizeof(char));
  728. X  montage_image->columns=
  729. X    (tile_info.width+(tile_info.x+border_width)*2)*tiles_per_row;
  730. X  montage_image->rows=(tile_info.height+(tile_info.y+border_width)*2+
  731. X    (display ? annotate_info.height+4 : 0))*
  732. X    (number_tiles/tiles_per_row+((number_tiles % tiles_per_row) != 0))+
  733. X    ((tile_info.y+border_width) >> 1);
  734. X  if (resource_info->title != (char *) NULL)
  735. X    montage_image->rows+=((annotate_info.height+4) << 1)+
  736. X      (tile_info.y << 1);
  737. X  montage_image->montage=(char *) malloc(2048*sizeof(char));
  738. X  count=1;
  739. X  for (tile=0; tile < number_tiles; tile++)
  740. X    count+=strlen(images[tile]->filename)+1;
  741. X  montage_image->directory=(char *) malloc(count*sizeof(char));
  742. X  montage_image->packets=montage_image->columns*montage_image->rows;
  743. X  montage_image->pixels=(RunlengthPacket *)
  744. X    malloc((unsigned int) montage_image->packets*sizeof(RunlengthPacket));
  745. X  if ((montage_image->comments == (char *) NULL) ||
  746. X      (montage_image->montage == (char *) NULL) ||
  747. X      (montage_image->directory == (char *) NULL) ||
  748. X      (montage_image->pixels == (RunlengthPacket *) NULL))
  749. X    Error("memory allocation error",(char *) NULL);
  750. X  (void) sprintf(montage_image->comments,"\n  ImageMagick image montage.\n");
  751. X  /*
  752. X    Set montage geometry.
  753. X  */
  754. X  x_offset=0;
  755. X  y_offset=((tile_info.y+border_width) >> 1);
  756. X  if (resource_info->title != (char *) NULL)
  757. X    y_offset+=((annotate_info.height+4) << 1)+(tile_info.y << 1);
  758. X  *montage_image->directory='\0';
  759. X  (void) sprintf(montage_image->montage,"%dx%d%+d%+d",
  760. X    tile_info.width+(tile_info.x+border_width)*2,
  761. X    (tile_info.height+(tile_info.y+border_width)*2+annotate_info.height+4),
  762. X    x_offset,y_offset);
  763. X  /*
  764. X    Initialize montage image to background color.
  765. X  */
  766. X  p=montage_image->pixels;
  767. X  for (i=0; i < montage_image->packets; i++)
  768. X  {
  769. X    p->red=background_color.red >> 8;
  770. X    p->green=background_color.green >> 8;
  771. X    p->blue=background_color.blue >> 8;
  772. X    p->index=0;
  773. X    p->length=0;
  774. X    p++;
  775. X  }
  776. X  /*
  777. X    Sort images by increasing tile number.
  778. X  */
  779. X  (void) qsort((void *) images,number_tiles,sizeof(Image *),LinearCompare);
  780. X  if (display && (resource_info->title != (char *) NULL))
  781. X    {
  782. X      /*
  783. X        Copy title to the composite image.
  784. X      */
  785. X      (void) strcpy(annotate_info.text,resource_info->title);
  786. X      annotate_info.width=XTextWidth(image_window.font_info,annotate_info.text,
  787. X        strlen(annotate_info.text));
  788. X      if (((annotate_info.width+tile_info.x*2) << 1) >=
  789. X          montage_image->columns)
  790. X        {
  791. X          /*
  792. X            Label is too wide-- shorten.
  793. X          */
  794. X          q=annotate_info.text+strlen(annotate_info.text);
  795. X          do
  796. X          {
  797. X            *--q='\0';
  798. X            if ((int) strlen(annotate_info.text) > 2)
  799. X              (void) strcpy(q-2,"...");
  800. X            annotate_info.width=XTextWidth(image_window.font_info,
  801. X              annotate_info.text,strlen(annotate_info.text));
  802. X          } while (((annotate_info.width+tile_info.x*2) << 1) >=
  803. X                   montage_image->columns);
  804. X        }
  805. X      (void) sprintf(annotate_info.geometry,"%ux%u%+d%+d",
  806. X        annotate_info.width << 1,annotate_info.height << 1,tile_info.x+
  807. X        (int) (montage_image->columns >> 1)-(int) annotate_info.width,
  808. X        tile_info.y+4);
  809. X      (void) XAnnotateImage(display,&image_window,&annotate_info,True,
  810. X        montage_image);
  811. X    }
  812. X  /*
  813. X    Copy tile images to the composite image.
  814. X  */
  815. X  x_offset=tile_info.x;
  816. X  y_offset=tile_info.y;
  817. X  if (display)
  818. X    if (resource_info->title != (char *) NULL)
  819. X      y_offset+=((annotate_info.height+4) << 1)+(tile_info.y << 1);
  820. X  *montage_image->directory='\0';
  821. X  for (tile=0; tile < number_tiles; tile++)
  822. X  {
  823. X    /*
  824. X      Copy this tile to the composite image.
  825. X    */
  826. X    image=images[tile];
  827. X    (void) strcat(montage_image->directory,image->filename);
  828. X    (void) strcat(montage_image->directory,"\n");
  829. X    status=RunlengthDecodeImage(image);
  830. X    if (status == False)
  831. X      Error("unable to unpack image",(char *) NULL);
  832. X    if ((border_width != 0) && !frame)
  833. X      {
  834. X        ColorPacket
  835. X          black;
  836. X
  837. X        Image
  838. X          *bordered_image;
  839. X
  840. X        RectangleInfo
  841. X          border_info;
  842. X
  843. X        /*
  844. X          Put a border around the image.
  845. X        */
  846. X        border_info.width=image->columns+2*(border_width-1);
  847. X        border_info.height=image->rows+2*(border_width-1);
  848. X        border_info.x=border_width-1;
  849. X        border_info.y=border_width-1;
  850. X        bordered_image=
  851. X          BorderImage(image,&border_info,&border_color,&highlight_color);
  852. X        if (bordered_image != (Image *) NULL)
  853. X          {
  854. X            DestroyImage(image);
  855. X            image=bordered_image;
  856. X          }
  857. X        border_info.width=image->columns+2;
  858. X        border_info.height=image->rows+2;
  859. X        border_info.x=1;
  860. X        border_info.y=1;
  861. X        black.red=0;
  862. X        black.green=0;
  863. X        black.blue=0;
  864. X        bordered_image=BorderImage(image,&border_info,&black,&black);
  865. X        if (bordered_image != (Image *) NULL)
  866. X          {
  867. X            DestroyImage(image);
  868. X            image=bordered_image;
  869. X          }
  870. X      }
  871. X    /*
  872. X      Gravitate image as specified by the tile gravity.
  873. X    */
  874. X    switch (resource_info->gravity)
  875. X    {
  876. X      case NorthWestGravity:
  877. X      {
  878. X        x=0;
  879. X        y=0;
  880. X        break;
  881. X      }
  882. X      case NorthGravity:
  883. X      {
  884. X        x=((tile_info.width+2*border_width)-image->columns)/2;
  885. X        y=0;
  886. X        break;
  887. X      }
  888. X      case NorthEastGravity:
  889. X      {
  890. X        x=(tile_info.width+2*border_width)-image->columns;
  891. X        y=0;
  892. X        break;
  893. X      }
  894. X      case WestGravity:
  895. X      {
  896. X        x=0;
  897. X        y=((tile_info.height+2*border_width)-image->rows)/2;
  898. X        break;
  899. X      }
  900. X      case ForgetGravity:
  901. X      case StaticGravity:
  902. X      case CenterGravity:
  903. X      default:
  904. X      {
  905. X        x=((tile_info.width+2*border_width)-image->columns)/2;
  906. X        y=((tile_info.height+2*border_width)-image->rows)/2;
  907. X        break;
  908. X      }
  909. X      case EastGravity:
  910. X      {
  911. X        x=(tile_info.width+2*border_width)-image->columns;
  912. X        y=((tile_info.height+2*border_width)-image->rows)/2;
  913. X        break;
  914. X      }
  915. X      case SouthWestGravity:
  916. X      {
  917. X        x=0;
  918. X        y=(tile_info.height+2*border_width)-image->rows;
  919. X        break;
  920. X      }
  921. X      case SouthGravity:
  922. X      {
  923. X        x=((tile_info.width+2*border_width)-image->columns)/2;
  924. X        y=(tile_info.height+2*border_width)-image->rows;
  925. X        break;
  926. X      }
  927. X      case SouthEastGravity:
  928. X      {
  929. X        x=(tile_info.width+2*border_width)-image->columns;
  930. X        y=(tile_info.height+2*border_width)-image->rows;
  931. X        break;
  932. X      }
  933. X    }
  934. X    if (frame)
  935. X      {
  936. X        Image
  937. X          *framed_image;
  938. X
  939. X        RectangleInfo
  940. X          frame_info;
  941. X
  942. X        /*
  943. X          Put an ornamental border around this tile.
  944. X        */
  945. X        frame_info.width=tile_info.width+2*border_width;
  946. X        frame_info.height=tile_info.height+2*border_width+
  947. X          (annotate_info.height+4);
  948. X        frame_info.x=(x > 0 ? x : border_width);
  949. X        y-=(annotate_info.height+4);
  950. X        frame_info.y=(y > 0 ? y : border_width);
  951. X        framed_image=FrameImage(image,&frame_info,HighlightWidth,&border_color,
  952. X          &highlight_color);
  953. X        if (framed_image != (Image *) NULL)
  954. X          {
  955. X            DestroyImage(image);
  956. X            image=framed_image;
  957. X          }
  958. X        x=0;
  959. X        y=0;
  960. X      }
  961. X    /*
  962. X      Composite background image with tile image.
  963. X    */
  964. X    CompositeImage(montage_image,compose,image,x_offset+x,y_offset+y);
  965. X    if (display)
  966. X      {
  967. X        /*
  968. X          Copy tile label to the composite image.
  969. X        */
  970. X        (void) strcpy(annotate_info.text,image->label);
  971. X        annotate_info.width=XTextWidth(image_window.font_info,
  972. X          annotate_info.text,strlen(annotate_info.text));
  973. X        if (annotate_info.width >= (tile_info.width+2*border_width))
  974. X          {
  975. X            /*
  976. X              Label is too wide-- shorten.
  977. X            */
  978. X            q=annotate_info.text+strlen(annotate_info.text);
  979. X            do
  980. X            {
  981. X              *--q='\0';
  982. X              if ((int) strlen(annotate_info.text) > 2)
  983. X                (void) strcpy(q-2,"...");
  984. X              annotate_info.width=XTextWidth(image_window.font_info,
  985. X                annotate_info.text,strlen(annotate_info.text));
  986. X            } while (annotate_info.width >= (tile_info.width+2*border_width));
  987. X          }
  988. X        (void) sprintf(annotate_info.geometry,"%ux%u%+d%+d",
  989. X          annotate_info.width,annotate_info.height,x_offset+
  990. X          ((tile_info.width+2*border_width) >> 1)-(annotate_info.width >> 1),
  991. X          y_offset+y+tile_info.y+2+(frame ? tile_info.height+2*border_width-
  992. X          (annotate_info.height+2) : (int) image->rows));
  993. X        (void) XAnnotateImage(display,&image_window,&annotate_info,!frame,
  994. X          montage_image);
  995. X      }
  996. X    DestroyImage(image);
  997. X    if (((tile+1) % tiles_per_row) != 0)
  998. X      x_offset+=tile_info.width+(tile_info.x+border_width)*2;
  999. X    else
  1000. X      {
  1001. X        x_offset=tile_info.x;
  1002. X        y_offset+=tile_info.height+(tile_info.y+border_width)*2+
  1003. X          (annotate_info.height+4);
  1004. X      }
  1005. X  }
  1006. X  (void) free((char *) annotate_info.text);
  1007. X  if (display)
  1008. X    {
  1009. X      /*
  1010. X        Free X resources.
  1011. X      */
  1012. X      XFreeFont(display,image_window.font_info);
  1013. X      XFree((void *) image_window.visual_info);
  1014. X    }
  1015. X  return(montage_image);
  1016. }
  1017. X
  1018. /*
  1019. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1020. %                                                                             %
  1021. %                                                                             %
  1022. %                                                                             %
  1023. %   U s a g e                                                                 %
  1024. %                                                                             %
  1025. %                                                                             %
  1026. %                                                                             %
  1027. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1028. %
  1029. %  Function Usage displays the program command syntax.
  1030. %
  1031. %  The format of the Usage routine is:
  1032. %
  1033. %      Usage()
  1034. %
  1035. %
  1036. */
  1037. static void Usage()
  1038. {
  1039. X  char
  1040. X    **p;
  1041. X
  1042. X  static char
  1043. X    *options[]=
  1044. X    {
  1045. X      "-aspect_ratio         respect aspect ratio of the image",
  1046. X      "-clip geometry        preferred size and location of the clipped image",
  1047. X      "-colors value         preferred number of colors in the image",
  1048. X      "-colorspace type      GRAY, RGB, XYZ, YCbCr, YIQ, or YUV",
  1049. X      "-compose operator     composite operator",
  1050. X      "-compress type        RunlengthEncoded or QEncoded",
  1051. X      "-density geometry     vertical and horizonal density of the image",
  1052. X      "-display server       query font from this X server",
  1053. X      "-dither               apply Floyd/Steinberg error diffusion to image",
  1054. X      "-frame                surround image with an ornamental border",
  1055. X      "-gamma value          level of gamma correction",
  1056. X      "-geometry geometry    preferred tile and border sizes",
  1057. X      "-gravity direction    which direction to gravitate towards",
  1058. X      "-interlace type       NONE, LINE, or PLANE",
  1059. X      "-monochrome           transform image to black and white",
  1060. X      "-page geometry        size and location of the Postscript page",
  1061. X      "-quality value        JPEG quality setting",
  1062. X      "-rotate degrees       apply Paeth rotation to the image",
  1063. X      "-tiles_per_row value  number of image tiles per row",
  1064. X      "-treedepth value      depth of the color classification tree",
  1065. X      "-verbose              print detailed information about the image",
  1066. X      (char *) NULL
  1067. X    };
  1068. X  (void) fprintf(stderr,
  1069. X    "Usage: %s [-options ...] file [ [-options ...] file ...] file\n",
  1070. X    client_name);
  1071. X  (void) fprintf(stderr,"\nWhere options include: \n");
  1072. X  for (p=options; *p != (char *) NULL; p++)
  1073. X    (void) fprintf(stderr,"  %s\n",*p);
  1074. X  (void) fprintf(stderr,
  1075. X    "\nIn addition to those listed above, you can specify these standard X\n");
  1076. X  (void) fprintf(stderr,
  1077. X    "resources as command line options:  -background, -bordercolor,\n");
  1078. X  (void) fprintf(stderr,
  1079. X    "-borderwidth, -font, -foreground, -highlight, or -title\n");
  1080. X  (void) fprintf(stderr,
  1081. X    "\nChange '-' to '+' in any option above to reverse its effect.  For\n");
  1082. X  (void) fprintf(stderr,
  1083. X    "example, specify +aspect_ratio to ignore the aspect ratio of an image.\n");
  1084. X  (void) fprintf(stderr,
  1085. X    "\nBy default, the image format of `file' is determined by its magic\n");
  1086. X  (void) fprintf(stderr,
  1087. X    "number.  To specify a particular image format, precede the filename\n");
  1088. X  (void) fprintf(stderr,
  1089. X    "with an image format name and a colon (i.e. ps:image) or specify the\n");
  1090. X  (void) fprintf(stderr,
  1091. X    "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
  1092. X  (void) fprintf(stderr,"'-' for standard input or output.\n");
  1093. X  exit(1);
  1094. }
  1095. X
  1096. /*
  1097. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1098. %                                                                             %
  1099. %                                                                             %
  1100. %                                                                             %
  1101. %    M a i n                                                                  %
  1102. %                                                                             %
  1103. %                                                                             %
  1104. %                                                                             %
  1105. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1106. %
  1107. %
  1108. */
  1109. int main(argc,argv)
  1110. int
  1111. X  argc;
  1112. X
  1113. char
  1114. X  **argv;
  1115. {
  1116. X  char
  1117. X    *clip_geometry,
  1118. X    *density,
  1119. X    *option,
  1120. X    *page_geometry,
  1121. X    *server_name,
  1122. X    *write_filename;
  1123. X
  1124. X  Display
  1125. X    *display;
  1126. X
  1127. X  double
  1128. X    gamma;
  1129. X
  1130. X  Image
  1131. X    **images,
  1132. X    *montage_image;
  1133. X
  1134. X  ImageInfo
  1135. X    image_info;
  1136. X
  1137. X  int
  1138. X    degrees,
  1139. X    i,
  1140. X    x;
  1141. X
  1142. X  time_t
  1143. X    start_time;
  1144. X
  1145. X  unsigned int
  1146. X    aspect_ratio,
  1147. X    compose,
  1148. X    compression,
  1149. X    display_image,
  1150. X    frame,
  1151. X    image_number,
  1152. X    interlace,
  1153. X    quality,
  1154. X    maximum_images,
  1155. X    tiles_per_row,
  1156. X    verbose;
  1157. X
  1158. X  XrmDatabase
  1159. X    resource_database;
  1160. X
  1161. X  XResourceInfo
  1162. X    resource_info;
  1163. X
  1164. X  /*
  1165. X    Display usage profile if there are no command line arguments.
  1166. X  */
  1167. X  client_name=(*argv);
  1168. X  if (argc < 3)
  1169. X    Usage();
  1170. X  /*
  1171. X    Set defaults.
  1172. X  */
  1173. X  aspect_ratio=True;
  1174. X  clip_geometry=(char *) NULL;
  1175. X  compose=ReplaceCompositeOp;
  1176. X  compression=UndefinedCompression;
  1177. X  degrees=0;
  1178. X  density=(char *) NULL;
  1179. X  display=(Display *) NULL;
  1180. X  display_image=True;
  1181. X  frame=False;
  1182. X  gamma=0.0;
  1183. X  interlace=NoneInterlace;
  1184. X  page_geometry=(char *) NULL;
  1185. X  quality=75;
  1186. X  resource_database=(XrmDatabase) NULL;
  1187. X  resource_info.border_color=(char *) NULL;
  1188. X  resource_info.border_width=0;
  1189. X  resource_info.colorspace=RGBColorspace;
  1190. X  resource_info.dither=False;
  1191. X  resource_info.gravity=CenterGravity;
  1192. X  resource_info.image_geometry=(char *) NULL;
  1193. X  resource_info.monochrome=False;
  1194. X  resource_info.number_colors=0;
  1195. X  resource_info.server_name=(char *) NULL;
  1196. X  resource_info.title=(char *) NULL;
  1197. X  resource_info.tree_depth=0;
  1198. X  server_name=(char *) NULL;
  1199. X  start_time=0;
  1200. X  tiles_per_row=0;
  1201. X  verbose=False;
  1202. X  maximum_images=2048;
  1203. X  images=(Image **) malloc(maximum_images*sizeof(Image *));
  1204. X  if (images == (Image **) NULL)
  1205. X    Error("unable to montage images","memory allocation failed");
  1206. X  /*
  1207. X    Check for server name specified on the command line.
  1208. X  */
  1209. X  for (i=1; i < argc; i++)
  1210. X  {
  1211. X    /*
  1212. X      Check command line for server name.
  1213. X    */
  1214. X    option=argv[i];
  1215. X    if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  1216. X      if (strncmp("display",option+1,3) == 0)
  1217. X        {
  1218. X          /*
  1219. X            User specified server name.
  1220. X          */
  1221. X          display_image=(*option == '-');
  1222. X          if (display_image)
  1223. X            {
  1224. X              i++;
  1225. X              if (i == argc)
  1226. X                Error("missing server name on -display",(char *) NULL);
  1227. X              server_name=argv[i];
  1228. X            }
  1229. X          break;
  1230. X        }
  1231. X  }
  1232. X  if (display_image)
  1233. X    {
  1234. X      char
  1235. X        *resource_value;
  1236. X
  1237. X      XrmDatabase
  1238. X        server_database;
  1239. X
  1240. X      /*
  1241. X        Open X server connection.
  1242. X      */
  1243. X      display=XOpenDisplay(server_name);
  1244. X      if (display == (Display *) NULL)
  1245. X        Error("unable to connect to X server",XDisplayName(server_name));
  1246. X      /*
  1247. X        Set our forgiving error handler.
  1248. X      */
  1249. X      XSetErrorHandler(XError);
  1250. X      /*
  1251. X        Initialize resource database.
  1252. X      */
  1253. X      XrmInitialize();
  1254. X      resource_database=XrmGetDatabase(display);
  1255. X      resource_value=XResourceManagerString(display);
  1256. X      if (resource_value == (char *) NULL)
  1257. X        resource_value="";
  1258. X      server_database=XrmGetStringDatabase(resource_value);
  1259. X      XrmMergeDatabases(server_database,&resource_database);
  1260. X      /*
  1261. X        Get user defaults from X resource database.
  1262. X      */
  1263. X      XGetResourceInfo(resource_database,client_name,&resource_info);
  1264. X      resource_value=
  1265. X        XGetResource(resource_database,client_name,"aspect_ratio","True");
  1266. X      aspect_ratio=IsTrue(resource_value);
  1267. X      clip_geometry=XGetResource(resource_database,client_name,"clipGeometry",
  1268. X        (char *) NULL);
  1269. X      resource_value=XGetResource(resource_database,client_name,"compression",
  1270. X        "RunlengthEncoded");
  1271. X      if (Latin1Compare("qencoded",resource_value) == 0)
  1272. X        compression=QEncodedCompression;
  1273. X      else
  1274. X        compression=RunlengthEncodedCompression;
  1275. X      density=
  1276. X        XGetResource(resource_database,client_name,"density",(char *) NULL);
  1277. X      resource_value=XGetResource(resource_database,client_name,"gamma","0.0");
  1278. X      gamma=atof(resource_value);
  1279. X      resource_value=
  1280. X        XGetResource(resource_database,client_name,"interlace","none");
  1281. X      interlace=UndefinedInterlace;
  1282. X      if (Latin1Compare("none",resource_value) == 0)
  1283. X        interlace=NoneInterlace;
  1284. X      if (Latin1Compare("line",resource_value) == 0)
  1285. X        interlace=LineInterlace;
  1286. X      if (Latin1Compare("plane",resource_value) == 0)
  1287. X        interlace=PlaneInterlace;
  1288. X      if (interlace == UndefinedInterlace)
  1289. X        Warning("unrecognized interlace type",resource_value);
  1290. X      page_geometry=XGetResource(resource_database,client_name,"pageGeometry",
  1291. X        (char *) NULL);
  1292. X      resource_value=XGetResource(resource_database,client_name,"rotate","0");
  1293. X      degrees=atoi(resource_value);
  1294. X      resource_value=XGetResource(resource_database,client_name,"quality","75");
  1295. X      quality=atoi(resource_value);
  1296. X      resource_value=
  1297. X        XGetResource(resource_database,client_name,"tiles_per_row","0");
  1298. X      tiles_per_row=atoi(resource_value);
  1299. X      resource_value=
  1300. X        XGetResource(resource_database,client_name,"verbose","False");
  1301. X      verbose=IsTrue(resource_value);
  1302. X    }
  1303. X  /*
  1304. X    Composite image is the last item on the command line.
  1305. X  */
  1306. X  write_filename=argv[argc-1];
  1307. X  if (access(write_filename,0) == 0)
  1308. X    {
  1309. X      char
  1310. X        answer[2];
  1311. X
  1312. X      (void) fprintf(stderr,"Overwrite %s? ",write_filename);
  1313. X      (void) gets(answer);
  1314. X      if (!((*answer == 'y') || (*answer == 'Y')))
  1315. X        exit(1);
  1316. X    }
  1317. X  /*
  1318. X    Parse command line.
  1319. X  */
  1320. X  image_number=0;
  1321. X  for (i=1; i < (argc-1); i++)
  1322. X  {
  1323. X    option=argv[i];
  1324. X    if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  1325. X      switch (*(option+1))
  1326. X      {
  1327. X        case 'a':
  1328. X        {
  1329. X          aspect_ratio=(*option == '-');
  1330. X          break;
  1331. X        }
  1332. X        case 'b':
  1333. X        {
  1334. X          if (strncmp("background",option+1,5) == 0)
  1335. X            {
  1336. X              resource_info.background_color=(char *) NULL;
  1337. X              if (*option == '-')
  1338. X                {
  1339. X                  i++;
  1340. X                  if (i == argc)
  1341. X                    Error("missing color on -background",(char *) NULL);
  1342. X                  resource_info.background_color=argv[i];
  1343. X                }
  1344. X              break;
  1345. X            }
  1346. X          if (strncmp("bordercolor",option+1,7) == 0)
  1347. X            {
  1348. X              resource_info.border_color=(char *) NULL;
  1349. X              if (*option == '-')
  1350. X                {
  1351. X                  i++;
  1352. X                  if (i == argc)
  1353. X                    Error("missing color on -bordercolor",(char *) NULL);
  1354. X                  resource_info.border_color=argv[i];
  1355. X                }
  1356. X              break;
  1357. X            }
  1358. X          if (strncmp("borderwidth",option+1,7) == 0)
  1359. X            {
  1360. X              resource_info.border_width=0;
  1361. X              if (*option == '-')
  1362. X                {
  1363. X                  i++;
  1364. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1365. X                    Error("missing width on -borderwidth",(char *) NULL);
  1366. X                  resource_info.border_width=atoi(argv[i]);
  1367. X                }
  1368. X              break;
  1369. X            }
  1370. X          Error("unrecognized option",option);
  1371. X          break;
  1372. X        }
  1373. X        case 'c':
  1374. X        {
  1375. X          if (strncmp("clip",option+1,2) == 0)
  1376. X            {
  1377. X              clip_geometry=(char *) NULL;
  1378. X              if (*option == '-')
  1379. X                {
  1380. X                  i++;
  1381. X                  if (i == argc)
  1382. X                    Error("missing geometry on -clip",(char *) NULL);
  1383. X                  clip_geometry=argv[i];
  1384. X                }
  1385. X              break;
  1386. X            }
  1387. X          if (strncmp("colors",option+1,7) == 0)
  1388. X            {
  1389. X              resource_info.number_colors=0;
  1390. X              if (*option == '-')
  1391. X                {
  1392. X                  i++;
  1393. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1394. X                    Error("missing colors on -colors",(char *) NULL);
  1395. SHAR_EOF
  1396. true || echo 'restore of ImageMagick/montage.c failed'
  1397. fi
  1398. echo 'End of ImageMagick part 31'
  1399. echo 'File ImageMagick/montage.c is continued in part 32'
  1400. echo 32 > _shar_seq_.tmp
  1401. exit 0
  1402.  
  1403. exit 0 # Just in case...
  1404. -- 
  1405.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1406. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1407.  "It's intuitively obvious to the |
  1408.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1409.