home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-13 | 50.3 KB | 1,409 lines |
- Newsgroups: comp.sources.x
- From: cristy@eplrx7.es.duPont.com (Cristy)
- Subject: v20i087: imagemagic - X11 image processing and display, Part31/38
- Message-ID: <1993Jul14.232146.23096@sparky.sterling.com>
- X-Md4-Signature: 89755b6e733ac1cb9e8c5e7af7978402
- Sender: chris@sparky.sterling.com (Chris Olson)
- Organization: Sterling Software
- Date: Wed, 14 Jul 1993 23:21:46 GMT
- Approved: chris@sterling.com
-
- Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
- Posting-number: Volume 20, Issue 87
- Archive-name: imagemagic/part31
- Environment: X11
- Supersedes: imagemagic: Volume 13, Issue 17-37
-
- #!/bin/sh
- # this is magick.31 (part 31 of ImageMagick)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file ImageMagick/quantize.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 31; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping ImageMagick/quantize.c'
- else
- echo 'x - continuing file ImageMagick/quantize.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/quantize.c' &&
- X Classification(colormap_image);
- X if (colorspace != RGBColorspace)
- X TransformRGBImage(colormap_image,colorspace);
- X optimal=True;
- X }
- X for (i=0; i < number_images; i++)
- X {
- X if (!dither)
- X if (images[i]->packets == (images[i]->columns*images[i]->rows))
- X CompressImage(images[i]);
- X if (colorspace != RGBColorspace)
- X RGBTransformImage(images[i],colorspace);
- X if (colormap_image == (Image *) NULL)
- X Classification(images[i]);
- X }
- X Reduction(number_colors);
- X for (i=0; i < number_images; i++)
- X {
- X Assignment(images[i],dither,colorspace,optimal);
- X if (colorspace != RGBColorspace)
- X TransformRGBImage(images[i],colorspace);
- X }
- X /*
- X Release color cube tree storage.
- X */
- X do
- X {
- X nodes=cube.node_queue->next;
- X (void) free((char *) cube.node_queue);
- X cube.node_queue=nodes;
- X }
- X while (cube.node_queue != (Nodes *) NULL);
- }
- SHAR_EOF
- echo 'File ImageMagick/quantize.c is complete' &&
- chmod 0644 ImageMagick/quantize.c ||
- echo 'restore of ImageMagick/quantize.c failed'
- Wc_c="`wc -c < 'ImageMagick/quantize.c'`"
- test 60193 -eq "$Wc_c" ||
- echo 'ImageMagick/quantize.c: original size 60193, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ImageMagick/miff.man ==============
- if test -f 'ImageMagick/miff.man' -a X"$1" != X"-c"; then
- echo 'x - skipping ImageMagick/miff.man (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ImageMagick/miff.man (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/miff.man' &&
- .ad l
- .nh
- .TH MIFF 5 "10 October 1992" "ImageMagick"
- .SH NAME
- MIFF - ImageMagick's file format for raster images.
- .SH SYNOPSIS
- .B #include <image.h>
- .SH DESCRIPTION
- A MIFF image file consist of two sections. The first section is
- composed of keywords describing the image in text form. The next
- section is the binary image data. The two sections are separated by a
- \fB:\fP character immediately followed by a \fInewline\fP. Generally,
- the first section has a \fIform-feed\fP and \fInewline\fP proceeding
- the \fB:\fP character. You can then list the image keywords with
- \fImore\fP, without printing the binary image that follows the \fB:\fP
- separator.
- .PP
- Each keyword must be separated by at least one space but can be
- separated with control characters such a \fIform-feed\fP or
- \fInewline\fP.
- .PP
- A list of valid keywords follows:
- .TP 5
- .B "alpha=\fITrue | False\fP"
- specifies whether a continuous-tone image also has alpha data. Alpha data is
- generally useful for image compositing.
- X
- This keyword is optional. If it is not specified, no alpha data is assumed.
- This keyword has no meaning for pseudo-color images.
- .TP 5
- .B "class=\fIDirectClass | PseudoClass\fP"
- identifies the type of binary image stored within the file.
- X
- This keyword is optional. If it is not specified, a \fIDirectClass\fP
- image format is assumed. An explanation of \fIDirectClass\fP and
- \fIPseudoClass\fP image data follows this list.
- .TP 5
- .B "colors=\fIvalue\fP"
- specifies the number of colors in the image, and for pseudo-color
- images the size of the colormap.
- X
- This keyword is optional. However, if a colormap size is not
- specified, a linear colormap is assumed for pseudo-color images.
- .TP 5
- .B "columns=\fIvalue\fP"
- is a required keyword and specifies the number of columns, or width in
- pixels, of the image.
- .TP 5
- .B "compression=\fIQEncoded | RunlengthEncoded\fP"
- identifies how the image stored within the file is compressed.
- X
- This keyword is optional. If it is not specified, the image is assumed
- to be uncompressed. \fIQEncoded\fP has no meaning for pseudo-color
- images. A detailed explanation of runlength-encoded and predictive
- arithmetic image compression follows this list.
- .TP 5
- .B "id=\fBImageMagick\fP"
- is a required keyword and identifies this file as a MIFF image.
- .TP 5
- .B "montage=\fI<width>x<height>{\+-}<x offset>{\+-}<y offset>\fP
- size and location of the individual tiles of a composite image. See
- \fBX(1)\fP for details about the geometry specification.
- X
- Use this keyword when the image is a composite of a number of different
- tiles. A tile consists of an image and optionally a border and a
- label. \fI<width>\fP is the size in pixels of each individual tile in
- the horizonal direction and \fI<height>\fP is the size in the vertical
- direction. Each tile must have an equal number of pixels in width and
- equal in height. However, the width can differ from the height. \fI<x
- offset>\fP is the offset in number of pixels from the vertical edge of
- the composite image where the first tile of a row begins and \fI<y
- offset>\fP is the offset from the horizonal edge where the first tile
- of a column begins.
- X
- If this keyword is specified, a directory of tile names must follow the
- image header. The format of the directory is explained below.
- .TP 5
- .B "packets=\fIvalue\fP"
- specifies the number of compressed color packets in the image data
- section.
- X
- This keyword is optional, but recommended, for runlength-encoded image
- compression. It is required for arithimetic encoded image compression. A
- detailed explanation of image compression follows this list.
- .TP 5
- .B "rows=\fIvalue\fP"
- is a required keyword and specifies the number of rows, or height in pixels,
- of the image.
- .TP 5
- .B "scene=\fIvalue\fP"
- is an optional keyword and is a reference number for sequencing of
- images.
- X
- This keyword is typically useful for animating a sequence of images.
- .TP 5
- .B "signature=\fIvalue\fP"
- is an optional keyword and is a character string that uniquely identifies
- the image colormap.
- X
- A unique identifier for the colormap is useful for animating a sequence
- of \fIPseudoClass\fP images. The default identifier is a digital
- signature computed from RSA's Data Security MD5 Digest Algorithm
- described in Internet draft [MD5], July 1992. The colormap signature is
- usually computed for \fIPseudoClass\fP images.
- .PP
- Comments can be included in the keyword section. Comments must begin with
- a \fB{\fP character and end with a \fI}\fP character.
- .PP
- An example keyword section follows:
- .PP
- X {
- X Rendered via Dore by Sandy Hause.
- X }
- X id=ImageMagick
- X class=PseudoClass colors=256 signature=d79e1c308aa5bbcdeea8ed63df412da9
- X compression=RunlengthEncoded packets=27601
- X columns=1280 rows=1024
- X scene=1
- X ^L
- X :
- .PP
- If you specify \fBmontage\fP in the image header, follow the header
- with a directory of image tiles. This directory consists of a name for
- each tile of the composite image separated by a NEWLINE character. The
- list is terminated with a NULL character.
- .PP
- The binary image data that follows the keyword text is stored in one of
- two binary classes as specified by the \fBclass\fP keyword:
- \fIDirectClass\fP or \fIPseudoClass\fP.
- .PP
- Use the \fIDirectClass\fP class to store continuous-tone images.
- \fIDirectClass\fP requires that the image pixels immediately follow the
- keyword text and be stored as binary red, green, and blue intensity
- values (and optional alpha value). Each color component is stored as
- one binary byte (8 bit) and ranges from 0 through 255. The total
- number of pixels expected is equal to the number of pixel columns times
- the number of pixel rows as specified by the \fBcolumns\fP and
- \fBrows\fP keywords.
- .PP
- If the \fBcompression\fP keyword is not specified, a red, green, and blue byte
- (and optional alpha byte) in that order is expected for each pixel of the
- image.
- .PP
- If \fBcompression\fP is \fIQEncoded\fP, each red, green, and blue byte
- intensity value (and optional alpha value) is encoded using the predictive
- arithmetic compression algorithm. Use the \fBpackets\fP keyword to specify
- the total number of arithimetic encoded packets that comprise the image.
- .PP
- If \fBcompression\fP is \fIRunlengthEncoded\fP, each red, green, and
- blue byte intensity value (and optional alpha value) is followed by a
- count byte. This value specifies the number of horizonally contiguous
- pixels in the image of that color. The count (0-255) is one less than
- the actual number of contiguous pixels; thus a single packet can
- represent from 1 up to 256 identical pixels. The total number of
- pixels specified by the individual count bytes must add up to the
- number of pixel columns times the number of pixel rows as specified by
- the \fBcolumns\fP and \fBrows\fP keywords. Use \fBpackets\fP to
- specify the total number of runlength-encoded packets that comprise the
- image.
- .PP
- Use the \fIPseudoClass\fP class to store pseudo-color images.
- \fIPseudoClass\fP requires that the image colormap and pseudo-color
- pixels immediately follow the keyword text. The colormap is stored as
- contiguous red, green, and blue intensity values. Each color component
- is stored as one binary byte (8 bit) and ranges from 0 through 255. The
- number of intensity values expected is determined by the \fBcolors\fP
- keyword. Note, an image colormap is restricted to at most 65535
- entries. The binary pseudo-color image is stored as indexes into the
- colormap. For colormaps of 256 colors or less, the indexes are stored
- as one binary byte (8 bit) and ranges from 0 through 255. If the
- colormap size exceeds 256 entries, then each colormap index is two
- bytes each with the most-significant-byte first. The total number of
- pixels expected is equal to the number of pixel columns times the
- number of pixel rows as specified by the \fBcolumns\fP and \fBrows\fP
- keywords.
- .PP
- If the \fBcompression\fP keyword is not specified, a colormap index is
- expected for each pixel of the image.
- .PP
- If \fBcompression\fP is \fIRunlengthEncoded\fP, each colormap index
- is followed by a count byte. This value specifies the number of
- horizonally contiguous pixels in the image of that color. The count
- (0-255) is one less than the actual number of contiguous pixels; thus a
- single packet can represent from 1 up to 256 identical pixels. The
- total number of pixels specified by the individual count bytes must add
- up to the number of pixels expected in the image as specified by the
- \fBcolumns\fP and \fBrows\fP keywords. Use \fBpackets\fP to specify the
- total number of runlength-encoded packets that comprise the image.
- .SH SEE ALSO
- .B
- display(1), animate(1), import(1), montage(1), mogrify(1), convert(1), more(1), compress(1)
- .SH COPYRIGHT
- Copyright 1993 E. I. du Pont de Nemours & Company
- .PP
- Permission to use, copy, modify, distribute, and sell this software and
- its documentation for any purpose is hereby granted without fee,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of E. I. du Pont de Nemours
- & Company not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior
- permission. E. I. du Pont de Nemours & Company makes no representations
- about the suitability of this software for any purpose. It is provided
- "as is" without express or implied warranty.
- .PP
- E. I. du Pont de Nemours & Company disclaims all warranties with regard
- to this software, including all implied warranties of merchantability
- and fitness, in no event shall E. I. du Pont de Nemours & Company be
- liable for any special, indirect or consequential damages or any
- damages whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action, arising
- out of or in connection with the use or performance of this software.
- .SH AUTHORS
- John Cristy, E.I. du Pont de Nemours & Company Incorporated
- SHAR_EOF
- chmod 0644 ImageMagick/miff.man ||
- echo 'restore of ImageMagick/miff.man failed'
- Wc_c="`wc -c < 'ImageMagick/miff.man'`"
- test 9952 -eq "$Wc_c" ||
- echo 'ImageMagick/miff.man: original size 9952, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ImageMagick/montage.c ==============
- if test -f 'ImageMagick/montage.c' -a X"$1" != X"-c"; then
- echo 'x - skipping ImageMagick/montage.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ImageMagick/montage.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/montage.c' &&
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % M M OOO N N TTTTT AAA GGGG EEEEE %
- % MM MM O O NN N T A A G E %
- % M M M O O N N N T AAAAA G GG EEE %
- % M M O O N NN T A A G G E %
- % M M OOO N N T A A GGGG EEEEE %
- % %
- % %
- % Montage Machine Independent File Format Image via X11. %
- % %
- % %
- % %
- % Software Design %
- % John Cristy %
- % July 1992 %
- % %
- % %
- % Copyright 1993 E. I. du Pont de Nemours & Company %
- % %
- % Permission to use, copy, modify, distribute, and sell this software and %
- % its documentation for any purpose is hereby granted without fee, %
- % provided that the above Copyright notice appear in all copies and that %
- % both that Copyright notice and this permission notice appear in %
- % supporting documentation, and that the name of E. I. du Pont de Nemours %
- % & Company not be used in advertising or publicity pertaining to %
- % distribution of the software without specific, written prior %
- % permission. E. I. du Pont de Nemours & Company makes no representations %
- % about the suitability of this software for any purpose. It is provided %
- % "as is" without express or implied warranty. %
- % %
- % E. I. du Pont de Nemours & Company disclaims all warranties with regard %
- % to this software, including all implied warranties of merchantability %
- % and fitness, in no event shall E. I. du Pont de Nemours & Company be %
- % liable for any special, indirect or consequential damages or any %
- % damages whatsoever resulting from loss of use, data or profits, whether %
- % in an action of contract, negligence or other tortious action, arising %
- % out of or in connection with the use or performance of this software. %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Montage creates a composite image by combining several separate
- % images. The images are tiled on the composite image with the name of
- % the image appearing just above the individual tile.
- %
- % The composite image is constructed in the following manner. First,
- % each image specified on the command line, except for the last, is
- % scaled to fit the maximum tile size. The maximum tile size by default
- % is 256x256. It can be modified with the -geometry command line
- % argument or X resource. Note that the maximum tile size need not be a
- % square. The original aspect ratio of each image is maintainted unless
- % +aspect_ratio is specfified.
- %
- % Next the composite image is initialized with the color specified by the
- % -background command line argument or X resource. The width and height
- % of the composite image is determined by the maximum tile size, the
- % number of tiles per row, the tile border width and height, the image
- % border width, and the label height. The number of tiles per row specifies
- % how many images are to appear in each row of the composite image. The
- % default is to have an equal number of images in each row and column of the
- % composite. This value can be specified with -tiles_per_row. The tile
- % border width and height, and the image border width defaults to the value
- % of the X resource -borderwidth. It can be changed with the -borderwidth or
- % -geometry command line argument or X resource. The label height is
- % determined by the font you specify with the -font command line argument or
- % X resource. If you do not specify a font, a font is choosen that allows
- % the name of the image to fit the maximum width of a tiled area. The label
- % colors is determined by the -background and -foreground command line
- % argument or X resource. Note, that if the background and foreground colors
- % are the same, labels will not appear.
- %
- % Finally, each image is set onto the composite image, surrounded by its
- % border color, with its name centered just below it. The individual images
- % are centered within the width of the tiled area. The final argument on the
- % command line is the name assigned to the composite image. The image is
- % written in the MIFF format and may by viewed or printed with `display'.
- %
- % The Montage program command syntax is:
- %
- % Usage: montage [options ...] file [ [options ...] file ...] file
- %
- % Where options include:
- % -aspect_ratio respect aspect ratio of the image
- % -clip geometry preferred size and location of the clipped image
- % -colors value preferred number of colors in the image
- % -colorspace type GRAY, RGB, XYZ, YCbCr, YIQ, or YUV
- % -compose operator composite operator
- % -compress type RunlengthEncoded or QEncoded
- % -density geometry vertical and horizonal density of the image
- % -display server query fonts from this X server
- % -dither apply Floyd/Steinberg error diffusion to image
- % -frame surround image with an ornamental border
- % -gamma value level of gamma correction
- % -geometry geometry preferred tile and border sizes
- % -gravity direction which direction to gravitate towards
- % -interlace type NONE, LINE, or PLANE
- % -monochrome transform image to black and white
- % -page geometry size and location of the Postscript page
- % -quality value JPEG quality setting
- % -rotate degrees apply Paeth rotation to the image
- % -tiles_per_row value number of image tiles per row
- % -treedepth value depth of the color classification tree
- % -verbose print detailed information about the image
- %
- % In addition to those listed above, you can specify these standard X
- % resources as command line options: -background, -bordercolor -borderwidth,
- % -font, -foreground, -highlight, or -title.
- %
- % Change '-' to '+' in any option above to reverse its effect. For
- % example, specify +compress to store the image as uncompressed.
- %
- % By default, the image format of `file' is determined by its magic
- % number. To specify a particular image format, precede the filename
- % with an image format name and a colon (i.e. ps:image) or specify the
- % image type as the filename suffix (i.e. image.ps). Specify 'file' as
- % '-' for standard input or output.
- %
- %
- */
- X
- /*
- X Include declarations.
- */
- #include "display.h"
- #include "image.h"
- #include "X.h"
- #include "compress.h"
- X
- /*
- X Global declarations.
- */
- char
- X *client_name;
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % E r r o r %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function Error displays an error message and then terminates the program.
- %
- % The format of the Error routine is:
- %
- % Error(message,qualifier)
- %
- % A description of each parameter follows:
- %
- % o message: Specifies the message to display before terminating the
- % program.
- %
- % o qualifier: Specifies any qualifier to the message.
- %
- %
- */
- void Error(message,qualifier)
- char
- X *message,
- X *qualifier;
- {
- X (void) fprintf(stderr,"%s: %s",client_name,message);
- X if (qualifier != (char *) NULL)
- X (void) fprintf(stderr," (%s)",qualifier);
- X (void) fprintf(stderr,".\n");
- X exit(1);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % M o n t a g e I m a g e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function MontageImage creates a composite image by combining several
- % separate images.
- %
- % The format of the MontageImage routine is:
- %
- % MontageImage(display,resource_info,images,number_tiles,tiles_per_row,
- % frame,compose)
- %
- % A description of each parameter follows:
- %
- % o display: Specifies a connection to an X server; returned from
- % XOpenDisplay.
- %
- % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
- %
- % o image: Specifies a pointer to a Image structure; returned from
- % ReadImage.
- %
- % o number_tiles: Specifies the number of tiles to tile.
- %
- % o tiles_per_row: Specifies the number of arguments.
- %
- % o frame: An integer greater than zero will force an ornamental border
- % around each tile.
- %
- % o compose: Specifies an image composite operator.
- %
- %
- */
- static int LinearCompare(x,y)
- const void
- X *x,
- X *y;
- {
- X Image
- X **image_1,
- X **image_2;
- X
- X image_1=(Image **) x;
- X image_2=(Image **) y;
- X return((int) (*image_1)->scene-(int) (*image_2)->scene);
- }
- X
- static Image *MontageImage(display,resource_info,images,number_tiles,
- X tiles_per_row,frame,compose)
- Display
- X *display;
- X
- XXResourceInfo
- X *resource_info;
- X
- Image
- X **images;
- X
- unsigned int
- X number_tiles,
- X tiles_per_row,
- X frame,
- X compose;
- {
- #define HighlightWidth 5
- X
- X ColorPacket
- X border_color,
- X highlight_color;
- X
- X Image
- X *image,
- X *montage_image;
- X
- X int
- X x,
- X x_offset,
- X y,
- X y_offset;
- X
- X register char
- X *q;
- X
- X register int
- X i;
- X
- X register RunlengthPacket
- X *p;
- X
- X RectangleInfo
- X tile_info;
- X
- X unsigned int
- X border_width,
- X count,
- X status,
- X tile;
- X
- X XAnnotateInfo
- X annotate_info;
- X
- X XColor
- X background_color;
- X
- X XWindowInfo
- X image_window;
- X
- X /*
- X Determine tile sizes.
- X */
- X border_width=resource_info->border_width;
- X if (frame)
- X border_width+=2*HighlightWidth;
- X tile_info.x=resource_info->border_width;
- X tile_info.y=resource_info->border_width;
- X if (resource_info->image_geometry != (char *) NULL)
- X {
- X XParseGeometry(resource_info->image_geometry,&tile_info.x,
- X &tile_info.y,&tile_info.width,&tile_info.height);
- X if (tile_info.x < 0)
- X tile_info.x=0;
- X if (tile_info.y < 0)
- X tile_info.y=0;
- X }
- X tile_info.width=images[0]->columns;
- X tile_info.height=images[0]->rows;
- X for (tile=1; tile < number_tiles; tile++)
- X {
- X if (images[tile]->columns > tile_info.width)
- X tile_info.width=images[tile]->columns;
- X if (images[tile]->rows > tile_info.height)
- X tile_info.height=images[tile]->rows;
- X }
- X if (tiles_per_row == 0)
- X {
- X /*
- X Compute tiles per row.
- X */
- X tiles_per_row=1;
- X while ((tiles_per_row*tiles_per_row) < number_tiles)
- X tiles_per_row++;
- X }
- X /*
- X Initialize tile colors.
- X */
- X background_color.red=0;
- X background_color.green=0;
- X background_color.blue=0;
- X border_color.red=0;
- X border_color.green=0;
- X border_color.blue=0;
- X highlight_color=border_color;
- X XGetAnnotateInfo(&annotate_info);
- X if (display)
- X {
- X char
- X text[2048];
- X
- X XFontStruct
- X *font_info;
- X
- X XPixelInfo
- X pixel_info;
- X
- X XStandardColormap
- X map_info;
- X
- X XVisualInfo
- X *visual_info;
- X
- X /*
- X Initialize visual info.
- X */
- X visual_info=XBestVisualInfo(display,"default",(char *) NULL,
- X (XStandardColormap *) NULL);
- X if (visual_info == (XVisualInfo *) NULL)
- X Error("unable to get visual",resource_info->visual_type);
- X /*
- X Initialize font info.
- X */
- X tile=0;
- X for (i=1; i < number_tiles; i++)
- X if ((int) strlen(images[i]->filename) >
- X (int) strlen(images[tile]->filename))
- X tile=i;
- X (void) strcpy(text,images[tile]->filename);
- X font_info=XBestFont(display,resource_info,text,tile_info.width);
- X if (font_info == (XFontStruct *) NULL)
- X Error("unable to load font",resource_info->font);
- X annotate_info.text=(char *) malloc(2048*sizeof(char));
- X if (annotate_info.text == (char *) NULL)
- X Error("unable to montage images","memory allocation failed");
- X annotate_info.font_info=font_info;
- X annotate_info.height=font_info->ascent+font_info->descent;
- X /*
- X Determine background, border, and highlight colors.
- X */
- X map_info.colormap=XDefaultColormap(display,visual_info->screen);
- X XGetPixelInfo(display,visual_info,&map_info,resource_info,(Image *) NULL,
- X &pixel_info);
- X background_color=pixel_info.background_color;
- X border_color.red=pixel_info.border_color.red >> 8;
- X border_color.green=pixel_info.border_color.green >> 8;
- X border_color.blue=pixel_info.border_color.blue >> 8;
- X highlight_color.red=pixel_info.highlight_color.red >> 8;
- X highlight_color.green=pixel_info.highlight_color.green >> 8;
- X highlight_color.blue=pixel_info.highlight_color.blue >> 8;
- X /*
- X Window superclass.
- X */
- X image_window.id=XRootWindow(display,visual_info->screen);
- X image_window.screen=visual_info->screen;
- X image_window.depth=visual_info->depth;
- X image_window.visual_info=visual_info;
- X image_window.pixel_info=(&pixel_info);
- X image_window.font_info=font_info;
- X }
- X /*
- X Allocate image structure.
- X */
- X montage_image=AllocateImage("MIFF");
- X if (montage_image == (Image *) NULL)
- X Error("memory allocation error",(char *) NULL);
- X /*
- X Initialize Image structure.
- X */
- X montage_image->comments=(char *) malloc(2048*sizeof(char));
- X montage_image->columns=
- X (tile_info.width+(tile_info.x+border_width)*2)*tiles_per_row;
- X montage_image->rows=(tile_info.height+(tile_info.y+border_width)*2+
- X (display ? annotate_info.height+4 : 0))*
- X (number_tiles/tiles_per_row+((number_tiles % tiles_per_row) != 0))+
- X ((tile_info.y+border_width) >> 1);
- X if (resource_info->title != (char *) NULL)
- X montage_image->rows+=((annotate_info.height+4) << 1)+
- X (tile_info.y << 1);
- X montage_image->montage=(char *) malloc(2048*sizeof(char));
- X count=1;
- X for (tile=0; tile < number_tiles; tile++)
- X count+=strlen(images[tile]->filename)+1;
- X montage_image->directory=(char *) malloc(count*sizeof(char));
- X montage_image->packets=montage_image->columns*montage_image->rows;
- X montage_image->pixels=(RunlengthPacket *)
- X malloc((unsigned int) montage_image->packets*sizeof(RunlengthPacket));
- X if ((montage_image->comments == (char *) NULL) ||
- X (montage_image->montage == (char *) NULL) ||
- X (montage_image->directory == (char *) NULL) ||
- X (montage_image->pixels == (RunlengthPacket *) NULL))
- X Error("memory allocation error",(char *) NULL);
- X (void) sprintf(montage_image->comments,"\n ImageMagick image montage.\n");
- X /*
- X Set montage geometry.
- X */
- X x_offset=0;
- X y_offset=((tile_info.y+border_width) >> 1);
- X if (resource_info->title != (char *) NULL)
- X y_offset+=((annotate_info.height+4) << 1)+(tile_info.y << 1);
- X *montage_image->directory='\0';
- X (void) sprintf(montage_image->montage,"%dx%d%+d%+d",
- X tile_info.width+(tile_info.x+border_width)*2,
- X (tile_info.height+(tile_info.y+border_width)*2+annotate_info.height+4),
- X x_offset,y_offset);
- X /*
- X Initialize montage image to background color.
- X */
- X p=montage_image->pixels;
- X for (i=0; i < montage_image->packets; i++)
- X {
- X p->red=background_color.red >> 8;
- X p->green=background_color.green >> 8;
- X p->blue=background_color.blue >> 8;
- X p->index=0;
- X p->length=0;
- X p++;
- X }
- X /*
- X Sort images by increasing tile number.
- X */
- X (void) qsort((void *) images,number_tiles,sizeof(Image *),LinearCompare);
- X if (display && (resource_info->title != (char *) NULL))
- X {
- X /*
- X Copy title to the composite image.
- X */
- X (void) strcpy(annotate_info.text,resource_info->title);
- X annotate_info.width=XTextWidth(image_window.font_info,annotate_info.text,
- X strlen(annotate_info.text));
- X if (((annotate_info.width+tile_info.x*2) << 1) >=
- X montage_image->columns)
- X {
- X /*
- X Label is too wide-- shorten.
- X */
- X q=annotate_info.text+strlen(annotate_info.text);
- X do
- X {
- X *--q='\0';
- X if ((int) strlen(annotate_info.text) > 2)
- X (void) strcpy(q-2,"...");
- X annotate_info.width=XTextWidth(image_window.font_info,
- X annotate_info.text,strlen(annotate_info.text));
- X } while (((annotate_info.width+tile_info.x*2) << 1) >=
- X montage_image->columns);
- X }
- X (void) sprintf(annotate_info.geometry,"%ux%u%+d%+d",
- X annotate_info.width << 1,annotate_info.height << 1,tile_info.x+
- X (int) (montage_image->columns >> 1)-(int) annotate_info.width,
- X tile_info.y+4);
- X (void) XAnnotateImage(display,&image_window,&annotate_info,True,
- X montage_image);
- X }
- X /*
- X Copy tile images to the composite image.
- X */
- X x_offset=tile_info.x;
- X y_offset=tile_info.y;
- X if (display)
- X if (resource_info->title != (char *) NULL)
- X y_offset+=((annotate_info.height+4) << 1)+(tile_info.y << 1);
- X *montage_image->directory='\0';
- X for (tile=0; tile < number_tiles; tile++)
- X {
- X /*
- X Copy this tile to the composite image.
- X */
- X image=images[tile];
- X (void) strcat(montage_image->directory,image->filename);
- X (void) strcat(montage_image->directory,"\n");
- X status=RunlengthDecodeImage(image);
- X if (status == False)
- X Error("unable to unpack image",(char *) NULL);
- X if ((border_width != 0) && !frame)
- X {
- X ColorPacket
- X black;
- X
- X Image
- X *bordered_image;
- X
- X RectangleInfo
- X border_info;
- X
- X /*
- X Put a border around the image.
- X */
- X border_info.width=image->columns+2*(border_width-1);
- X border_info.height=image->rows+2*(border_width-1);
- X border_info.x=border_width-1;
- X border_info.y=border_width-1;
- X bordered_image=
- X BorderImage(image,&border_info,&border_color,&highlight_color);
- X if (bordered_image != (Image *) NULL)
- X {
- X DestroyImage(image);
- X image=bordered_image;
- X }
- X border_info.width=image->columns+2;
- X border_info.height=image->rows+2;
- X border_info.x=1;
- X border_info.y=1;
- X black.red=0;
- X black.green=0;
- X black.blue=0;
- X bordered_image=BorderImage(image,&border_info,&black,&black);
- X if (bordered_image != (Image *) NULL)
- X {
- X DestroyImage(image);
- X image=bordered_image;
- X }
- X }
- X /*
- X Gravitate image as specified by the tile gravity.
- X */
- X switch (resource_info->gravity)
- X {
- X case NorthWestGravity:
- X {
- X x=0;
- X y=0;
- X break;
- X }
- X case NorthGravity:
- X {
- X x=((tile_info.width+2*border_width)-image->columns)/2;
- X y=0;
- X break;
- X }
- X case NorthEastGravity:
- X {
- X x=(tile_info.width+2*border_width)-image->columns;
- X y=0;
- X break;
- X }
- X case WestGravity:
- X {
- X x=0;
- X y=((tile_info.height+2*border_width)-image->rows)/2;
- X break;
- X }
- X case ForgetGravity:
- X case StaticGravity:
- X case CenterGravity:
- X default:
- X {
- X x=((tile_info.width+2*border_width)-image->columns)/2;
- X y=((tile_info.height+2*border_width)-image->rows)/2;
- X break;
- X }
- X case EastGravity:
- X {
- X x=(tile_info.width+2*border_width)-image->columns;
- X y=((tile_info.height+2*border_width)-image->rows)/2;
- X break;
- X }
- X case SouthWestGravity:
- X {
- X x=0;
- X y=(tile_info.height+2*border_width)-image->rows;
- X break;
- X }
- X case SouthGravity:
- X {
- X x=((tile_info.width+2*border_width)-image->columns)/2;
- X y=(tile_info.height+2*border_width)-image->rows;
- X break;
- X }
- X case SouthEastGravity:
- X {
- X x=(tile_info.width+2*border_width)-image->columns;
- X y=(tile_info.height+2*border_width)-image->rows;
- X break;
- X }
- X }
- X if (frame)
- X {
- X Image
- X *framed_image;
- X
- X RectangleInfo
- X frame_info;
- X
- X /*
- X Put an ornamental border around this tile.
- X */
- X frame_info.width=tile_info.width+2*border_width;
- X frame_info.height=tile_info.height+2*border_width+
- X (annotate_info.height+4);
- X frame_info.x=(x > 0 ? x : border_width);
- X y-=(annotate_info.height+4);
- X frame_info.y=(y > 0 ? y : border_width);
- X framed_image=FrameImage(image,&frame_info,HighlightWidth,&border_color,
- X &highlight_color);
- X if (framed_image != (Image *) NULL)
- X {
- X DestroyImage(image);
- X image=framed_image;
- X }
- X x=0;
- X y=0;
- X }
- X /*
- X Composite background image with tile image.
- X */
- X CompositeImage(montage_image,compose,image,x_offset+x,y_offset+y);
- X if (display)
- X {
- X /*
- X Copy tile label to the composite image.
- X */
- X (void) strcpy(annotate_info.text,image->label);
- X annotate_info.width=XTextWidth(image_window.font_info,
- X annotate_info.text,strlen(annotate_info.text));
- X if (annotate_info.width >= (tile_info.width+2*border_width))
- X {
- X /*
- X Label is too wide-- shorten.
- X */
- X q=annotate_info.text+strlen(annotate_info.text);
- X do
- X {
- X *--q='\0';
- X if ((int) strlen(annotate_info.text) > 2)
- X (void) strcpy(q-2,"...");
- X annotate_info.width=XTextWidth(image_window.font_info,
- X annotate_info.text,strlen(annotate_info.text));
- X } while (annotate_info.width >= (tile_info.width+2*border_width));
- X }
- X (void) sprintf(annotate_info.geometry,"%ux%u%+d%+d",
- X annotate_info.width,annotate_info.height,x_offset+
- X ((tile_info.width+2*border_width) >> 1)-(annotate_info.width >> 1),
- X y_offset+y+tile_info.y+2+(frame ? tile_info.height+2*border_width-
- X (annotate_info.height+2) : (int) image->rows));
- X (void) XAnnotateImage(display,&image_window,&annotate_info,!frame,
- X montage_image);
- X }
- X DestroyImage(image);
- X if (((tile+1) % tiles_per_row) != 0)
- X x_offset+=tile_info.width+(tile_info.x+border_width)*2;
- X else
- X {
- X x_offset=tile_info.x;
- X y_offset+=tile_info.height+(tile_info.y+border_width)*2+
- X (annotate_info.height+4);
- X }
- X }
- X (void) free((char *) annotate_info.text);
- X if (display)
- X {
- X /*
- X Free X resources.
- X */
- X XFreeFont(display,image_window.font_info);
- X XFree((void *) image_window.visual_info);
- X }
- X return(montage_image);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % U s a g e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Function Usage displays the program command syntax.
- %
- % The format of the Usage routine is:
- %
- % Usage()
- %
- %
- */
- static void Usage()
- {
- X char
- X **p;
- X
- X static char
- X *options[]=
- X {
- X "-aspect_ratio respect aspect ratio of the image",
- X "-clip geometry preferred size and location of the clipped image",
- X "-colors value preferred number of colors in the image",
- X "-colorspace type GRAY, RGB, XYZ, YCbCr, YIQ, or YUV",
- X "-compose operator composite operator",
- X "-compress type RunlengthEncoded or QEncoded",
- X "-density geometry vertical and horizonal density of the image",
- X "-display server query font from this X server",
- X "-dither apply Floyd/Steinberg error diffusion to image",
- X "-frame surround image with an ornamental border",
- X "-gamma value level of gamma correction",
- X "-geometry geometry preferred tile and border sizes",
- X "-gravity direction which direction to gravitate towards",
- X "-interlace type NONE, LINE, or PLANE",
- X "-monochrome transform image to black and white",
- X "-page geometry size and location of the Postscript page",
- X "-quality value JPEG quality setting",
- X "-rotate degrees apply Paeth rotation to the image",
- X "-tiles_per_row value number of image tiles per row",
- X "-treedepth value depth of the color classification tree",
- X "-verbose print detailed information about the image",
- X (char *) NULL
- X };
- X (void) fprintf(stderr,
- X "Usage: %s [-options ...] file [ [-options ...] file ...] file\n",
- X client_name);
- X (void) fprintf(stderr,"\nWhere options include: \n");
- X for (p=options; *p != (char *) NULL; p++)
- X (void) fprintf(stderr," %s\n",*p);
- X (void) fprintf(stderr,
- X "\nIn addition to those listed above, you can specify these standard X\n");
- X (void) fprintf(stderr,
- X "resources as command line options: -background, -bordercolor,\n");
- X (void) fprintf(stderr,
- X "-borderwidth, -font, -foreground, -highlight, or -title\n");
- X (void) fprintf(stderr,
- X "\nChange '-' to '+' in any option above to reverse its effect. For\n");
- X (void) fprintf(stderr,
- X "example, specify +aspect_ratio to ignore the aspect ratio of an image.\n");
- X (void) fprintf(stderr,
- X "\nBy default, the image format of `file' is determined by its magic\n");
- X (void) fprintf(stderr,
- X "number. To specify a particular image format, precede the filename\n");
- X (void) fprintf(stderr,
- X "with an image format name and a colon (i.e. ps:image) or specify the\n");
- X (void) fprintf(stderr,
- X "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
- X (void) fprintf(stderr,"'-' for standard input or output.\n");
- X exit(1);
- }
- X
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % M a i n %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- int main(argc,argv)
- int
- X argc;
- X
- char
- X **argv;
- {
- X char
- X *clip_geometry,
- X *density,
- X *option,
- X *page_geometry,
- X *server_name,
- X *write_filename;
- X
- X Display
- X *display;
- X
- X double
- X gamma;
- X
- X Image
- X **images,
- X *montage_image;
- X
- X ImageInfo
- X image_info;
- X
- X int
- X degrees,
- X i,
- X x;
- X
- X time_t
- X start_time;
- X
- X unsigned int
- X aspect_ratio,
- X compose,
- X compression,
- X display_image,
- X frame,
- X image_number,
- X interlace,
- X quality,
- X maximum_images,
- X tiles_per_row,
- X verbose;
- X
- X XrmDatabase
- X resource_database;
- X
- X XResourceInfo
- X resource_info;
- X
- X /*
- X Display usage profile if there are no command line arguments.
- X */
- X client_name=(*argv);
- X if (argc < 3)
- X Usage();
- X /*
- X Set defaults.
- X */
- X aspect_ratio=True;
- X clip_geometry=(char *) NULL;
- X compose=ReplaceCompositeOp;
- X compression=UndefinedCompression;
- X degrees=0;
- X density=(char *) NULL;
- X display=(Display *) NULL;
- X display_image=True;
- X frame=False;
- X gamma=0.0;
- X interlace=NoneInterlace;
- X page_geometry=(char *) NULL;
- X quality=75;
- X resource_database=(XrmDatabase) NULL;
- X resource_info.border_color=(char *) NULL;
- X resource_info.border_width=0;
- X resource_info.colorspace=RGBColorspace;
- X resource_info.dither=False;
- X resource_info.gravity=CenterGravity;
- X resource_info.image_geometry=(char *) NULL;
- X resource_info.monochrome=False;
- X resource_info.number_colors=0;
- X resource_info.server_name=(char *) NULL;
- X resource_info.title=(char *) NULL;
- X resource_info.tree_depth=0;
- X server_name=(char *) NULL;
- X start_time=0;
- X tiles_per_row=0;
- X verbose=False;
- X maximum_images=2048;
- X images=(Image **) malloc(maximum_images*sizeof(Image *));
- X if (images == (Image **) NULL)
- X Error("unable to montage images","memory allocation failed");
- X /*
- X Check for server name specified on the command line.
- X */
- X for (i=1; i < argc; i++)
- X {
- X /*
- X Check command line for server name.
- X */
- X option=argv[i];
- X if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
- X if (strncmp("display",option+1,3) == 0)
- X {
- X /*
- X User specified server name.
- X */
- X display_image=(*option == '-');
- X if (display_image)
- X {
- X i++;
- X if (i == argc)
- X Error("missing server name on -display",(char *) NULL);
- X server_name=argv[i];
- X }
- X break;
- X }
- X }
- X if (display_image)
- X {
- X char
- X *resource_value;
- X
- X XrmDatabase
- X server_database;
- X
- X /*
- X Open X server connection.
- X */
- X display=XOpenDisplay(server_name);
- X if (display == (Display *) NULL)
- X Error("unable to connect to X server",XDisplayName(server_name));
- X /*
- X Set our forgiving error handler.
- X */
- X XSetErrorHandler(XError);
- X /*
- X Initialize resource database.
- X */
- X XrmInitialize();
- X resource_database=XrmGetDatabase(display);
- X resource_value=XResourceManagerString(display);
- X if (resource_value == (char *) NULL)
- X resource_value="";
- X server_database=XrmGetStringDatabase(resource_value);
- X XrmMergeDatabases(server_database,&resource_database);
- X /*
- X Get user defaults from X resource database.
- X */
- X XGetResourceInfo(resource_database,client_name,&resource_info);
- X resource_value=
- X XGetResource(resource_database,client_name,"aspect_ratio","True");
- X aspect_ratio=IsTrue(resource_value);
- X clip_geometry=XGetResource(resource_database,client_name,"clipGeometry",
- X (char *) NULL);
- X resource_value=XGetResource(resource_database,client_name,"compression",
- X "RunlengthEncoded");
- X if (Latin1Compare("qencoded",resource_value) == 0)
- X compression=QEncodedCompression;
- X else
- X compression=RunlengthEncodedCompression;
- X density=
- X XGetResource(resource_database,client_name,"density",(char *) NULL);
- X resource_value=XGetResource(resource_database,client_name,"gamma","0.0");
- X gamma=atof(resource_value);
- X resource_value=
- X XGetResource(resource_database,client_name,"interlace","none");
- X interlace=UndefinedInterlace;
- X if (Latin1Compare("none",resource_value) == 0)
- X interlace=NoneInterlace;
- X if (Latin1Compare("line",resource_value) == 0)
- X interlace=LineInterlace;
- X if (Latin1Compare("plane",resource_value) == 0)
- X interlace=PlaneInterlace;
- X if (interlace == UndefinedInterlace)
- X Warning("unrecognized interlace type",resource_value);
- X page_geometry=XGetResource(resource_database,client_name,"pageGeometry",
- X (char *) NULL);
- X resource_value=XGetResource(resource_database,client_name,"rotate","0");
- X degrees=atoi(resource_value);
- X resource_value=XGetResource(resource_database,client_name,"quality","75");
- X quality=atoi(resource_value);
- X resource_value=
- X XGetResource(resource_database,client_name,"tiles_per_row","0");
- X tiles_per_row=atoi(resource_value);
- X resource_value=
- X XGetResource(resource_database,client_name,"verbose","False");
- X verbose=IsTrue(resource_value);
- X }
- X /*
- X Composite image is the last item on the command line.
- X */
- X write_filename=argv[argc-1];
- X if (access(write_filename,0) == 0)
- X {
- X char
- X answer[2];
- X
- X (void) fprintf(stderr,"Overwrite %s? ",write_filename);
- X (void) gets(answer);
- X if (!((*answer == 'y') || (*answer == 'Y')))
- X exit(1);
- X }
- X /*
- X Parse command line.
- X */
- X image_number=0;
- X for (i=1; i < (argc-1); i++)
- X {
- X option=argv[i];
- X if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
- X switch (*(option+1))
- X {
- X case 'a':
- X {
- X aspect_ratio=(*option == '-');
- X break;
- X }
- X case 'b':
- X {
- X if (strncmp("background",option+1,5) == 0)
- X {
- X resource_info.background_color=(char *) NULL;
- X if (*option == '-')
- X {
- X i++;
- X if (i == argc)
- X Error("missing color on -background",(char *) NULL);
- X resource_info.background_color=argv[i];
- X }
- X break;
- X }
- X if (strncmp("bordercolor",option+1,7) == 0)
- X {
- X resource_info.border_color=(char *) NULL;
- X if (*option == '-')
- X {
- X i++;
- X if (i == argc)
- X Error("missing color on -bordercolor",(char *) NULL);
- X resource_info.border_color=argv[i];
- X }
- X break;
- X }
- X if (strncmp("borderwidth",option+1,7) == 0)
- X {
- X resource_info.border_width=0;
- X if (*option == '-')
- X {
- X i++;
- X if ((i == argc) || !sscanf(argv[i],"%d",&x))
- X Error("missing width on -borderwidth",(char *) NULL);
- X resource_info.border_width=atoi(argv[i]);
- X }
- X break;
- X }
- X Error("unrecognized option",option);
- X break;
- X }
- X case 'c':
- X {
- X if (strncmp("clip",option+1,2) == 0)
- X {
- X clip_geometry=(char *) NULL;
- X if (*option == '-')
- X {
- X i++;
- X if (i == argc)
- X Error("missing geometry on -clip",(char *) NULL);
- X clip_geometry=argv[i];
- X }
- X break;
- X }
- X if (strncmp("colors",option+1,7) == 0)
- X {
- X resource_info.number_colors=0;
- X if (*option == '-')
- X {
- X i++;
- X if ((i == argc) || !sscanf(argv[i],"%d",&x))
- X Error("missing colors on -colors",(char *) NULL);
- SHAR_EOF
- true || echo 'restore of ImageMagick/montage.c failed'
- fi
- echo 'End of ImageMagick part 31'
- echo 'File ImageMagick/montage.c is continued in part 32'
- echo 32 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
- --
- // chris@Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! | sources-x@sterling.com
- "It's intuitively obvious to the |
- most casual observer..." | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
-