v13i035: ImageMagick - Graphics display programs, Part19/21

cristy at dupont.com cristy at dupont.com
Fri May 24 13:20:39 AEST 1991


Submitted-by: cristy at dupont.com
Posting-number: Volume 13, Issue 35
Archive-name: imagemagic/part19

#!/bin/sh
# this is img.19 (part 19 of ImageMagick)
# do not concatenate these parts, unpack them in order with /bin/sh
# file ImageMagick/X.h continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 19; 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/X.h'
else
echo 'x - continuing file ImageMagick/X.h'
sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/X.h' &&
X
X  unsigned int
X    monochrome;
X
X  char
X    *name;
X
X  char
X    *title,
X    *visual_type;
} XResourceInfo;
X
typedef struct _XWindowInfo
{
X  Window
X    id;
X
X  int
X    screen,
X    depth;
X
X  XVisualInfo
X    *visual_info;
X
X  XStandardColormap
X    *map_info;
X
X  XPixelInfo
X    *pixel_info;
X
X  XFontStruct
X    *font_info;
X
X  GC
X    graphic_context;
X
X  Cursor
X    cursor,
X    busy_cursor;
X
X  char
X    *name,
X    *geometry,
X    *icon_geometry,
X    *clip_geometry;
X
X  unsigned long
X    flags;
X
X  int
X    x,
X    y;
X
X  unsigned int
X    width,
X    height,
X    min_width,
X    min_height,
X    width_inc,
X    height_inc,
X    border_width,
X    immutable;
X
X  XImage
X    *ximage;
X
X  Pixmap
X    *pixmaps;
X
X  XSetWindowAttributes
X    attributes;
} XWindowInfo;
X
/*
X  X utilities routines.
*/
extern char 
X  *XVisualClassName();
X
extern int
X  IsTrue();
X
extern Image 
X  *XReadImage();
X
extern int 
X  IsTrue(),
X  XReadColormap();
X
extern XStandardColormap 
X  *XMakeStandardColormap();
X
extern unsigned long 
X  XBestPixel();
X
extern XVisualInfo 
X  *XBestVisualInfo();
X
extern void 
X  Latin1Upper(),
X  XBestIconSize(),
X  XMakeImageLSBFirst(),
X  XMakeImageMSBFirst(),
X  XMakeWindow();
X
extern Window 
X  XClientWindow(),
X  XSelectWindow(),
X  XWindowByName(),
X  XWindowByProperty();
X
extern XFontStruct 
X  *XBestFont();
X
extern XImage 
X  *XMakeImage();
X
/*
X  Invoke pre-X11R4 ICCCM routines if PWinGravity is not defined.
*/
#ifndef PWinGravity
#define PRE_R4_ICCCM
#include "PreR4Icccm.h"
#else
#define XInductColormap(display,colormap)
#define XUninductColormap(display,colormap)
#endif
SHAR_EOF
echo 'File ImageMagick/X.h is complete' &&
chmod 0755 ImageMagick/X.h ||
echo 'restore of ImageMagick/X.h failed'
Wc_c="`wc -c < 'ImageMagick/X.h'`"
test 2573 -eq "$Wc_c" ||
	echo 'ImageMagick/X.h: original size 2573, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ImageMagick/animate.man ==============
if test -f 'ImageMagick/animate.man' -a X"$1" != X"-c"; then
	echo 'x - skipping ImageMagick/animate.man (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ImageMagick/animate.man (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/animate.man' &&
.ad l
.nh
.TH ANIMATE 1 "1 January 1991" "X Version 11"
.SH NAME
animate - display a sequence of images on any workstation running X
.SH SYNOPSIS
.B "animate" [ \fIoptions\fP ...] \fIfile\fP
[ [ \fIoptions\fP ...] \fIfile\fP ...]
.SH DESCRIPTION
\fIAnimate\fP displays a sequence of images in the MIFF format on
any workstation display running an X server.  \fIAnimate\fP first
determines the hardware capabilities of the workstation.  If the number
of unique colors in an image is less than or equal to the number the
workstation can support, the image is displayed in an X window.
Otherwise the number of colors in the image is first reduced to match
the color resolution of the workstation before it is displayed.
.PP
This means that a continuous-tone 24 bits/pixel image can display on a
8 bit pseudo-color device or monochrome device.  In most instances the
reduced color image closely resembles the original.  Alternatively, a
monochrome or pseudo-color image can display on a continuous-tone 24
bits/pixels device.
.PP
To prevent colormap flashing, the use of a Standard Colormap or static
visual is recommended.  Refer to the \fB-map\fP and \fB-visual\fP in
\fBOPTIONS\fP.
.SH EXAMPLES
To animate a cockatoo image sequence while using the Standard Colormap
"best", use:
.PP
X     xstdcmap -best
X     animate -map best cockatoo.*
.PP
.PP
To scale each image of a cockatoo sequence to exactly 640 pixels in
width and 480 pixels in height and position the window at location
(200,200), use:
.PP
X     animate -geometry 640x480\+200\+200 cockatoo.*
.PP
To animate an image of a cockatoo without a border centered on a
backdrop, use:
.PP
X     animate -backdrop -borderwidth 0 cockatoo.*
.SH OPTIONS
.TP 5
.B "-backdrop"
display the image centered on a backdrop.
X
This backdrop covers the entire workstation screen and is useful for
hiding other X window activity while viewing the image.   The color of
the backdrop is specified as the background color.  Refer to \fBX
RESOURCES\fP for details.
.TP 5
.B "-clip \fI<width>x<height>{\+-}<x offset>{\+-}<y offset>\fP"
preferred size and location of the clipped image.  See \fBX(1)\fP for details 
about the geometry specification.
X
Use clipping to apply image processing options, or display, only a
particular area of an image.  
.TP 5
.B "-colors \fIvalue\fP"
preferred number of colors in the image.  
X
The actual number of colors in the image may be less than your request,
but never more.  Note, this is a color reduction option.  Images with
less unique colors than specified with this option will remain unchanged.
Refer to \fBCOLOR REDUCTION ALGORITHM\fP for more details.
X
Note, options \fB-dither\fP and \fB-treedepth\fP affect the color reduction
algorithm.
.TP 5
.B "-delay \fImilliseconds\fP"
display the next image after pausing.
X
This option is useful for regulating the display of the sequence of
images.  \fImilliseconds\fP milliseconds must expire before the display of 
the next image.  The default is to display each image without delay.
.TP 5
.B "-display \fIhost:display[.screen]\fP"
specifies the X server to contact; see \fBX(1)\fP.
.TP 5
.B "-dither"
apply Floyd/Steinberg error diffusion to the image.  
X
The basic strategy of dithering is to trade intensity resolution for 
spatial resolution by averaging the intensities of several neighboring 
pixels.  Images which suffer from severe contouring when reducing colors 
can be improved with this option.
X
The \fB-colors\fP, \fB-gray\fP, or \fB-monochrome\fP option is required 
for this option to take effect.
.TP 5
.B "-gamma \fIvalue\fP"
level of gamma correction.  
X
The same color image displayed on two different workstations may look
different due to differences in the display monitor.  Use gamma
correction to adjust for this color difference.  Reasonable values
extend from 0.8 to 2.3.  
.TP 5
.B "-geometry \fI<width>x<height>{\+-}<x offset>{\+-}<y offset>\fP"
preferred size and location of the image window.  See \fBX(1)\fP for details 
about the geometry specification.  By default, the window size is the image 
size and the location is choosen by you when it is mapped.
X
If the specified image size is smaller than the actual image size, the
image is first reduced to an integral of the specified image size with
an antialias digital filter.  The image is then scaled to the exact
specified image size with pixel replication.  If the specified image
size is greater than the actual image size, the image is first enlarged
to an integral of the specified image size with bilinear
interpolation.  The image is then scaled to the exact specified image
size with pixel replication.
X
When displaying an image on an X server, the x and y offset in the
geometry specification is relative to the root window.  When printing
an image, the x and y offset in the geometry specification is relative
to a Postscript page.  See \fB-print\fP for more details.
.TP 5
.B "-gray"
transform the image to gray scale colors.  
.TP 5
.B "-map \fItype\fP"
display image using this Standard Colormap type.
X
Choose from these Standard Colormap types:
X
X    default
X    best
X    red
X    green
X    blue
X    gray
X
The X server must support the Standard Colormap you choose, otherwise an 
error occurs.  See \fBxcmap(1)\fP for one way of creating Standard Colormaps.
.TP 5
.B "-monochrome"
transform the image to black and white.
X
Monochrome images can benefit from error diffusion.  Use \fB-dither\fP with
this option to diffuse the error.
.TP 5
.B "-reflect"
create a "mirror image" by reflecting the image scanlines.
.TP 5
.B "-rotate \fIdegrees\fP"
apply Paeth image rotation to the image.
.TP 5
.B "-scale \fI<width factor>x<height factor>\fP"
preferred size factors of the image.
X
This option behaves like \fB-geometry\fP except the width and height values
are relative instead of absolute.  The image size is multiplied by the
width and height factors to obtain the final image dimensions.  If only
one factor is specified, both the width and height factors assume the
value.
X
Factors may be fractional.  For example, a factor of 1.5 will increase the
image size by one and one-half.
.TP 5
.B "-treedepth \fIvalue\fP"
Normally, this integer value is zero or one.  A zero or one tells
\fIAnimate\fP to choose a optimal tree depth for the color reduction
algorithm.  
X
An optimal depth generally allows the best representation of the source
image with the fastest computational speed and the least amount of
memory.  However, the default depth is inappropriate for some images.
To assure the best representation, try values between 2 and 8 for this
parameter.  Refer to \fBCOLOR REDUCTION ALGORITHM\fP for more details.
X
The \fB-colors\fP, \fB-gray\fP, or \fB-monochrome\fP option is required
for this option to take effect.
.TP 5
.B "-visual \fItype\fP"
display image using this visual type.
X
Choose from these visual classes:
X
X    StaticGray
X    GrayScale
X    StaticColor
X    PseudoColor
X    TrueColor
X    DirectColor
X    default
X    \fIvisual id\fP
X
The X server must support the visual you choose, otherwise an error occurs.
If a visual is not specified, the visual class that can display the most 
simultaneous colors on the default screen is choosen.
.PP
In addition to those listed above, you can specify these standard X
resources as command line options:  -background, -bordercolor,
-borderwidth,  -font, -foreground, -iconGeometry, -iconic, -name, or -title.  
See \fBX RESOURCES\fP for details.
.PP
Any option you specify on the command line remains in effect until it is
explicitly changed by specifying the option again with a different effect.
For example, to animate two images, the first with 32 colors and the
second with only 16 colors, use:
.PP
X     animate -colors 32 cockatoo.1 -colors 16 cockatoo.2
.PP
Change \fI-\fP to \fI\+\fP in any option above to reverse its effect.
For example, specify \fB\+display\fP to apply image transformations
without viewing them on the X server.  Or, specify \fB\+dither\fP to not
apply error diffusion to an image.
.PP
Specify \fIfile\fP as \fI-\fP for standard input or output.  If \fIfile\fP 
has the extension \fB.Z\fP, the file is decoded with \fBuncompress\fP.  
.SH BUTTONS
.TP 5
.B "1"
Press and drag to select a command from a pop-up menu.  Choose from 
these commands:
X
X    Play
X    Step
X    Repeat
X    Auto Reverse
X    Forward
X    Reverse
X    Image Info
X    Quit
.SH KEYS
.TP 5
.B "0-9"
Press to change the level of delay.  Refer to \fB-delay\fP for more 
information.
.TP 5
.B "p"
Press to animate the sequence of images.
.TP 5
.B "s"
Press to display the next image in the sequence.
.TP 5
.B "."
Press to continually display the sequence of images.
.TP 5
.B "a"
Press to automatically reverse the sequence of images.
.TP 5
.B "f"
Press to animate in the forward direction.
.TP 5
.B "r"
Press to animate in the reverse direction.
.TP 5
.B "i"
Press to display information about the image.  Press any key or button
to erase the information.
X
This information is printed: image name;  image size; and the total
number of unique colors in the image.
.TP 5
.B "q"
Press to discard all images and exit program.
.SH "X RESOURCES"
\fIDisplay\fP options can appear on the command line or in your X
resource file.  Options on the command line supercede values specified
in your X resource file.  See \fBX(1)\fP for more information on X
resources.
X
All \fIdisplay\fP options have a corresponding X resource.  In addition,
the \fIdisplay\fP program uses the following X resources:
.TP 5
.B background (\fPclass\fB Background)
Specifies the preferred color to use for the image window background.  The
default is black.
.TP 5
.B borderColor (\fPclass\fB BorderColor)
Specifies the preferred color to use for the image window border.  The
default is white.
.TP 5
.B borderWidth (\fPclass\fB BorderWidth)
Specifies the width in pixels of the image window border.  The default is 2.
.TP 5
.B font (\fPclass\fB Font)
Specifies the name of the preferred font to use when displaying text in the
within the image window.  The default is 9x15, fixed, or 5x8 determined by
the image window size.
.TP 5
.B foreground (\fPclass\fB Foreground)
Specifies the preferred color to use for text within the image window.  The
default is white.
.TP 5
.B iconGeometry (\fPclass\fB IconGeometry)
Specifies the preferred size and position of the application when
iconified.  It is not necessarily obeyed by all window managers.
.TP 5
.B iconic (\fPclass\fB Iconic)
This resource indicates that you would prefer that the application's
windows initially not be visible as if the windows had be immediately
iconified by you.  Window managers may choose not to honor the
application's request.
.TP 5
.B name (\fPclass\fB Name)
This resource specifies the name under which resources for the
application should be found.  This resource is useful in shell aliases to
distinguish between invocations of an application, without resorting to
creating links to alter the executable file name.  The default is the
application name.
.TP 5
.B title (\fPclass\fB Title)
This resource specifies the title to be used for the image window.  This
information is sometimes used by a window manager to provide some sort
of header identifying the window.  The default is the image file name.
.SH "COLOR REDUCTION ALGORITHM"
.PP
This section describes how \fIDisplay\fP performs color reduction in an
image.  To fully understand this section, you should have a knowledge
of basic imaging techniques and the tree data structure and terminology.
.PP
For purposes of color allocation, an image is a set of \fIn\fP pixels,
where each pixel is a point in RGB space.  RGB space is a 3-dimensional
vector space, and each pixel, \fIp\d\s-3i\s0\u\fP,  is defined by an
ordered triple of red, green, and blue coordinates, (\fIr\d\s-3i\s0\u,
g\d\s-3i\s0\u, b\d\s-3i\s0\u\fP).
.PP
Each primary color component (red, green, or blue) represents an
intensity which varies linearly from 0 to a maximum value,
\fIc\d\s-3max\s0\u\fP, which corresponds to full saturation of that
color.  Color allocation is defined over a domain consisting of the
cube in RGB space with opposite vertices at (0,0,0) and
(\fIc\d\s-3max\s0\u,c\d\s-3max\s0\u,c\d\s-3max\s0\u\fP).  \fIDisplay\fP
requires \fIc\d\s-3max\s0\u = 255\fP.
.PP
The algorithm maps this domain onto a tree in which each node
represents a cube within that domain.  In the following discussion,
these cubes are defined by the coordinate of two opposite vertices: The
vertex nearest the origin in RGB space and the vertex farthest from the
origin.
.PP
The tree's root node represents the the entire domain, (0,0,0) through
(\fIc\d\s-3max\s0\u,c\d\s-3max\s0\u,c\d\s-3max\s0\u\fP).  Each lower level in
the tree is generated by subdividing one node's cube into eight smaller
cubes of equal size.  This corresponds to bisecting the parent cube
with planes passing through the midpoints of each edge.
.PP
The basic algorithm operates in three phases:  \fBClassification,
Reduction\fP, and \fBAssignment\fP.  \fBClassification\fP builds a
color description tree for the image.  \fBReduction\fP collapses the
tree until the number it represents, at most, is the number of colors
desired in the output image.  \fBAssignment\fP defines the output
image's color map and sets each pixel's color by reclassification in
the reduced tree.
.PP
\fBClassification\fP begins by initializing a color description tree of
sufficient depth to represent each possible input color in a leaf.
However, it is impractical to generate a fully-formed color description
tree in the classification phase for realistic values of
\fIc\d\s-3max\s0\u\fP.  If color components in the input image are
quantized to \fIk\fP-bit precision, so that \fIc\d\s-3max\s0\u =
2\u\s-3k\s0\d-1\fP, the tree would need \fIk\fP levels below the root
node to allow representing each possible input color in a leaf.  This
becomes prohibitive because the tree's total number of nodes is
.PP
X        \fI\s+6\(*S\u\s-9 k\d\di=1\s0 8k\fP\s0\u
.PP
A complete tree would require 19,173,961 nodes for \fIk = 8,
c\d\s-3max\s0\u = 255\fP.  Therefore, to avoid building a fully
populated tree, \fIDisplay\fP: (1) Initializes data structures for
nodes only as they are needed; (2) Chooses a maximum depth for the tree
as a function of the desired number of colors in the output image
(currently \fIlog\d\s-34\s0\u(colormap size)\+2\fP).  A tree of this
depth generally allows the best representation of the source image with
the fastest computational speed and the least amount of memory.
However, the default depth is inappropriate for some images.
Therefore, the caller can request a specific tree depth.
.PP
For each pixel in the input image, classification scans downward from
the root of the color description tree.  At each level of the tree, it
identifies the single node which represents a cube in RGB space
containing the pixel's color.  It updates the following data for each
such node:
.TP 5
.B n\d\s-31\s0\u:  
Number of pixels whose color is contained in the RGB cube which this
node represents;
.TP 5
.B n\d\s-32\s0\u:  
Number of pixels whose color is not represented in a node at lower
depth in the tree;  initially,  \fIn\d\s-32\s0\u = 0\fP for all nodes
except leaves of the tree.
.TP 5
.B S\d\s-3r\s0\u, S\d\s-3g\s0\u, S\d\s-3b\s0\u:
Sums of the red, green, and blue component values for all pixels not
classified at a lower depth.  The combination of these sums and
\fIn\d\s-32\s0\u\fP will ultimately characterize the mean color of a
set of pixels represented by this node.
.PP
\fBReduction\fP repeatedly prunes the tree until the number of nodes with
\fIn\d\s-32\s0\u  > 0\fP is less than or equal to the maximum number of colors
allowed in the output image.  On any given iteration over the tree, it
selects those nodes whose \fIn\d\s-31\s0\u\fP count is minimal for pruning and
merges their color statistics upward.  It uses a pruning threshold,
\fIn\d\s-3p\s0\u\fP, to govern node selection as follows:
.PP
X  n\d\s-3p\s0\u = 0
X  while number of nodes with (n\d\s-32\s0\u > 0) > required maximum number of colors
X      prune all nodes such that n\d\s-31\s0\u <= n\d\s-3p\s0\u
X      Set n\d\s-3p\s0\u  to minimum n\d\s-31\s0\u  in remaining nodes
.PP
When a node to be pruned has offspring, the pruning procedure invokes
itself recursively in order to prune the tree from the leaves upward.
The values of \fIn\d\s-32\s0\u  S\d\s-3r\s0\u, S\d\s-3g\s0\u,\fP  and
\fIS\d\s-3b\s0\u\fP in a node being pruned are always added to the
corresponding data in that node's parent.  This retains the pruned
node's color characteristics for later averaging.
.PP
For each node,  \fIn\d\s-32\s0\u\fP pixels exist for which that node
represents the smallest volume in RGB space containing those pixel's
colors.  When \fIn\d\s-32\s0\u  > 0\fP the node will uniquely define a
color in the output image.  At the beginning of reduction,
\fIn\d\s-32\s0\u = 0\fP  for all nodes except the leaves of the tree
which represent colors present in the input image.
.PP
The other pixel count, \fIn\d\s-31\s0\u\fP,  indicates the total
number of colors within the cubic volume which the node represents.
This includes \fIn\d\s-31\s0\u - n\d\s-32\s0\u\fP pixels whose colors
should be defined by nodes at a lower level in the tree.
.PP
\fBAssignment\fP generates the output image from the pruned tree.  The
output image consists of two parts:  (1)  A color map, which is an
array of color descriptions (RGB triples) for each color present in the
output image; (2)  A pixel array, which represents each pixel as an
index into the color map array.
.PP
First, the assignment phase makes one pass over the pruned color
description tree to establish the image's color map.  For each node
with \fIn\d\s-32\s0\u > 0\fP, it divides \fIS\d\s-3r\s0\u,
S\d\s-3g\s0\u\fP, and \fPS\d\s-3b\s0\u\fP by \fIn\d\s-32\s0\u\fP.  This
produces the mean color of all pixels that classify no lower than this
node.  Each of these colors becomes an entry in the color map.
.PP
Finally, the assignment phase reclassifies each pixel in the pruned
tree to identify the deepest node containing the pixel's color.  The
pixel's value in the pixel array becomes the index of this node's mean
color in the color map.
.SH "MEASURING COLOR REDUCTION ERROR"
.PP
Depending on the image, the color reduction error may be obvious or
invisible.  Images with high spatial frequencies (such as hair or
grass) will show error much less than pictures with large smoothly
shaded areas (such as faces).  This is because the high-frequency
contour edges introduced by the color reduction process are masked by
the high frequencies in the image.
.PP
To measure the difference between the original and color reduced images
(the total color reduction error), \fIDisplay\fP sums over all pixels
in an image the distance squared in RGB space between each original
pixel value and its color reduced value. \fIDisplay\fP prints several error 
measurements including the mean error per pixel, the normalized mean error,
and the normalized maximum error.
.PP
The normalized error measurement can be used to compare images.  In
general, the closer the mean error is to zero the more the quantized
image resembles the source image.  Ideally, the error should be
perceptually-based, since the human eye is the final judge of
quantization quality.
.PP
These errors are measured and printed when \fB-verbose\fP and \fB-colors\fI 
are specified on the command line:
.TP 5
.B mean error per pixel:  
is the mean error for any single pixel in the image.
.TP 5
.B normalized mean square error:  
is the normalized mean square quantization error for any single pixel in the
image.  
X
This distance measure is normalized to a range between 0 and 1.  It is
independent of the range of red, green, and blue values in the image.
.TP 5
.B normalized maximum square error:  
is the largest normalized square quantization error for any single
pixel in the image.
X
This distance measure is normalized to a range between 0 and 1.  It is
independent of the range of red, green, and blue values in the image.
.SH "MIFF FILE FORMAT"
.PP
The Machine Independent File Format is described in this section.
.PP
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 "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.  A detailed explanation of runlength-encoded and
Q-coder image compression follows this list.
.TP 5
.B "id=\fIImageMagick\fP"
is a required keyword and identifies this file as a MIFF image.  
.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 Q-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.
.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
X    compression=RunlengthEncoded  packets=27601
X    columns=1280  rows=1024
X    scene=1
X    ^L
X    :
.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.  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 
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 is encoded using the Q-coder compression algorithm.
Use the \fBpackets\fP keyword to specify the total number of Q-encoded
packets that comprise the image.  Refer to "Sofware implementations of
the Q-Coder", by Mitchell, J. L. and Pennebaker, W.B. (IBM Journal Res.
Development, Volume 32, Number 6, November 1988, pages 753 - 774) for
implementation specific details.
.PP
If \fBcompression\fP is \fIRunlengthEncoded\fP, each red, green, and
blue byte intensity 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.  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.  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 \fIQEncoded\fP, each colormap index is
encoded using the Q-coder compression algorithm.  Use the \fBpackets\fP
keyword to specify the total number of Q-encoded packets comprise the
image.  Refer to "Sofware implementations of the Q-Coder", by Mitchell,
J. L. and Pennebaker, W.B. (IBM Journal Res. Development, Volume 32,
Number 6, November 1988, pages 753 - 774) for implementation specific
details.
.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 FEATURES
Although \fIDisplay\fP will display an image on a server with an immutable
colormap, the image quality may suffer as compared to a server with a 
read/write colormap.
.PP
\fIDisplay\fP memory requirements is proportionate to the area of the image.
.PP
\fIDisplay\fP does not complain when it encounters a keyword in an image file
it does not understand.
.SH ENVIRONMENT
.TP 5
.B DISPLAY
To get the default host, display number, and screen.
.SH SEE ALSO
XX(1), xcmap(1), import(1), XtoPS(1), more(1), compress(1)
.SH COPYRIGHT
Copyright 1991 E. I. Dupont 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. Dupont de Nemours     
& Company not be used in advertising or publicity pertaining to            
distribution of the software without specific, written prior               
permission.  E. I. Dupont 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. Dupont 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. Dupont 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 ACKNOWLEDGEMENTS
The MIT X Consortium for making network transparent graphics a reality.
.PP
Michael Halle, Spatial Imaging Group at MIT, for the initial
implementation of Alan Paeth's image rotation algorithm.
.PP
David Pensak, E. I. Dupont de Nemours & Company, for providing a
computing environment that made this program possible.
.PP
Paul Raveling, USC Information Sciences Institute, for the original
idea of using space subdivision for the color reduction algorithm.
With Paul's permission, the \fBCOLOR REDUCTION ALGORITHM\fP section is
a adaptation from a document he wrote.
.SH AUTHORS
John Cristy, E.I. DuPont de Nemours & Company Incorporated
SHAR_EOF
chmod 0755 ImageMagick/animate.man ||
echo 'restore of ImageMagick/animate.man failed'
Wc_c="`wc -c < 'ImageMagick/animate.man'`"
test 29239 -eq "$Wc_c" ||
	echo 'ImageMagick/animate.man: original size 29239, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ImageMagick/Announce ==============
if test -f 'ImageMagick/Announce' -a X"$1" != X"-c"; then
	echo 'x - skipping ImageMagick/Announce (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ImageMagick/Announce (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/Announce' &&
ImageMagick, an X11 image processing and display utility, is now available
on export.lcs.mit.edu as contrib/ImageMagick.tar.Z.  After any initial bug
reports are fixed, I will submit the utilities to comp.sources.x.
X
cristy at dupont.com
X
---
X
Display
X
X    Display is a machine architecture independent image processing and
X    display program.  It can display any image in the MIFF format on
X    any workstation display running an X server.  Display first
X    determines the hardware capabilities of the workstation.  If the
X    number of unique colors in the image is less than or equal to the
X    number the workstation can support, the image is displayed in an X
X    window.  Otherwise the number of colors in the image is first
X    reduced to match the color resolution of the workstation before it
X    is displayed.
X
X    This means that a continuous-tone 24 bits/pixel image can display
X    on a 8 bit pseudo-color device or monochrome device.  In most
X    instances the reduced color image closely resembles the original.
X    Alternatively, a monochrome or pseudo-color image can display on a
X    continuous-tone 24 bits/pixels device.
X
Import
X
X    Import is an X Window System window dumping utility.  Import allows
X    X users to store window images in a specially formatted dump file.
X    This file can then be read by the Display utility for redisplay,
X    printing, editing, formatting, archiving, image processing, etc.
X    The target window can be specified by id or name or be selected by
X    clicking the mouse in the desired window.  The keyboard bell is
X    rung once at the beginning of the dump and twice when the dump is
X    completed.
X
XXtoPS
X
X    XtoPS is an X Window System window dumping utility.  XtoPS reads an
X    image from any visible window on an X server and outputs it to
X    encapsulated Postscript file.  You can view this file with any
X    Postscript compatible viewer or printer.  The image is displayed in
X    color on viewers or printers that support color Postscript,
X    otherwise it is displayed as grayscale.  The target window can be
X    specified by id or name or be selected by clicking the mouse in the
X    desired window.  The keyboard bell is rung once at the beginning of
X    the dump and twice when the dump is completed.
X
Animate
X
X     Animate displays a sequence of images in the MIFF format on
X     any workstation display running an X server.  Animate first
X     determines the hardware capabilities of the workstation.  If
X     the number of unique colors in an image is less than or
X     equal to the number the workstation can support, the image
X     is displayed in an X window.  Otherwise the number of colors
X     in the image is first reduced to match the color resolution
X     of the workstation before it is displayed.
SHAR_EOF
chmod 0755 ImageMagick/Announce ||
echo 'restore of ImageMagick/Announce failed'
Wc_c="`wc -c < 'ImageMagick/Announce'`"
test 2779 -eq "$Wc_c" ||
	echo 'ImageMagick/Announce: original size 2779, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ImageMagick/X.c ==============
if test -f 'ImageMagick/X.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ImageMagick/X.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ImageMagick/X.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/X.c' &&
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%                                  X   X                                      %
%                                   X X                                       %
%                                    X                                        %
%                                   X X                                       %
%                                  X   X                                      %
%                                                                             %
%                       X11 Utility Routines for Display.                     %
%                                                                             %
%                                                                             %
%                                                                             %
%                           Software Design                                   %
%                             John Cristy                                     %
%                            January  1991                                    %
%                                                                             %
%                                                                             %
%  Copyright 1991 E. I. Dupont 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. Dupont de Nemours     %
%  & Company not be used in advertising or publicity pertaining to            %
%  distribution of the software without specific, written prior               %
%  permission.  E. I. Dupont 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. Dupont 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. Dupont 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.      %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/
X
/*
X  Include declarations.
*/
#include "display.h"
#include "image.h"
#include "X.h"
/*
X  External declarations.
*/
extern void
X  Error();
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I s T r u e                                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function IsTrue returns True if the boolean is "true", "on", "yes" or "1".
%
%  The format of the IsTrue routine is:
%
%      option=IsTrue(boolean)
%
%  A description of each parameter follows:
%
%    o option:either True or False depending on the boolean parameter.
%
%    o boolean:Specifies a pointer to a character array.
%
%
*/
int IsTrue(boolean)
char
X  *boolean;
{
X  char
X    c,
X    *p;
X
X  if (boolean == (char *) NULL)
X    return(False);
X  for (p=boolean; *p != (char) NULL; p++)
X  {
X    /*
X      Convert to lower case.
X    */
X    c=(*p);
X    if (isascii(c) && isupper(c))
X      *p=tolower(c);
X  }
X  if (strcmp(boolean,"true") == 0)
X    return(True);
X  if (strcmp(boolean,"on") == 0)
X    return(True);
X  if (strcmp(boolean,"yes") == 0)
X    return(True);
X  if (strcmp(boolean,"1") == 0)
X    return(True);
X  return(False);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   L a t i n 1 U p p e r                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function Latin1Upper converts a string to upper-case Latin1.
%
%  The format of the Latin1Upper routine is:
%
%      Latin1Upper(string)
%
%  A description of each parameter follows:
%
%    o string: A pointer to the string to convert to upper-case Latin1.
%
%
*/
void Latin1Upper(string)
unsigned char
X  *string;
{
X  unsigned char
X    c;
X
X  c=(*string);
X  while (c != (char) NULL)
X  {
X    if ((c >= XK_a) && (c <= XK_z))
X      *string=c-(XK_a-XK_A);
X    else
X      if ((c >= XK_agrave) && (c <= XK_odiaeresis))
X        *string=c-(XK_agrave-XK_Agrave);
X      else
X        if ((c >= XK_oslash) && (c <= XK_thorn))
X          *string=c-(XK_oslash-XK_Ooblique);
X    string++;
X    c=(*string);
X  }
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X B e s t F o n t                                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function XBestFont returns the "best" font.  "Best" is defined as a font
%  specified in the X resource database or a font such that the text width
%  displayed with the font does not exceed the specified maximum width.
%
%  The format of the XBestFont routine is:
%
%      font=XBestFont(display,resource_info,text,maximum_width)
%
%  A description of each parameter follows:
%
%    o font: XBestFont returns a pointer to a XFontStruct structure.
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o text: Specifies the text whose width is compared to the maximum.
%
%    o maximum_width: Specifies the maximum width in pixels of the text.
%
%
*/
XXFontStruct *XBestFont(display,resource_info,text,maximum_width)
Display
X  *display;
X
XXResourceInfo
X  *resource_info;
X
char
X  *text;
X
unsigned int
X  maximum_width;
{
X  static char
X    *fonts[]=
X    {
X      "fixed",
X      "6x10",
X      "5x8",
X      (char *) NULL
X    };
X
X  char
X    *font_name,
X    **p;
X
X  XFontStruct
X    *font_info;
X
X  font_info=(XFontStruct *) NULL;
X  font_name=resource_info->font_name;
X  if (font_name != (char *) NULL)
X    {
X      /*
X        Load preferred font specified in the X resource database.
X      */
X      font_info=XLoadQueryFont(display,font_name);
X      if (font_info == (XFontStruct *) NULL)
X        Warning("unable to load font",font_name);
X    }
X  /*
X    Load a font that does not exceed the text width.
X  */
X  for (p=fonts; *p != (char *) NULL; p++)
X  {
X    if (font_info != (XFontStruct *) NULL)
X      {
X        if (XTextWidth(font_info,text,strlen(text)) < maximum_width)
X          break;
X        font_name=(*p);
X        XFreeFont(display,font_info);
X      }
X    font_info=XLoadQueryFont(display,*p);
X  }
X  if (font_info == (XFontStruct *) NULL)
X    font_info=XLoadQueryFont(display,"fixed");  /* backup font */
X  if (font_info == (XFontStruct *) NULL)
X    font_info=XLoadQueryFont(display,"variable");  /* backup font */
X  return(font_info);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X B e s t I c o n S i z e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function XBestIconSize returns the "best" icon size.  "Best" is defined as
%  an icon size that maintains the aspect ratio of the image.  If the window
%  manager has preferred icon sizes, one of the preferred sizes is used.
%
%  The format of the XBestIconSize routine is:
%
%      XBestIconSize(display,icon_window,image)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o image: Specifies a pointer to a Image structure;  returned from
%      ReadImage.
%
%
*/
void XBestIconSize(display,icon_window,image)
Display
X  *display;
X
XXWindowInfo
X  *icon_window;
X
Image
X  *image;
{
#define MaxIconSize  64
X
X  int
X    number_sizes;
X
X  unsigned long
X    icon_height,
X    icon_width,
X    scale_factor;
X
X  Window
X    root_window;
X
X  XIconSize
X    *icon_size,
X    *size_list;
X
X  /*
X    Determine if the window manager has specified preferred icon sizes.
X  */
X  icon_size=(XIconSize *) NULL;
X  number_sizes=0;
X  root_window=XRootWindow(display,icon_window->screen);
X  if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
X    if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
X      icon_size=size_list;
X  if (icon_size == (XIconSize *) NULL)
X    {
X      /*
X        Window manager does not restrict icon size.
X      */
X      icon_size=XAllocIconSize();
X      if (icon_size == (XIconSize *) NULL)
X        Error("unable to create icon","memory allocation failed");
X      icon_size->min_width=1;
X      icon_size->max_width=MaxIconSize;
X      icon_size->min_height=1;
X      icon_size->max_height=MaxIconSize;
X      icon_size->width_inc=1;
X      icon_size->height_inc=1;
X    }
X  /*
X    Look for an icon size that maintains the aspect ratio of image.
X  */
X  if (image->columns >= image->rows)
X    {
X      icon_width=icon_size->max_width;
X      icon_height=icon_size->min_height;
X      scale_factor=(image->rows << 14)/image->columns;
X      while (icon_height < icon_size->max_height)
X      {
X        if (icon_height >= ((icon_size->max_width*scale_factor+8191) >> 14))
X          break;
X        icon_height+=icon_size->height_inc;
X      }
X    }
X  else
X    {
X      icon_width=icon_size->min_width;
X      icon_height=icon_size->max_height;
X      scale_factor=(image->columns << 14)/image->rows;
X      while (icon_width < icon_size->max_width)
X      {
X        if (icon_width >= ((icon_size->max_height*scale_factor+8191) >> 14))
X          break;
X        icon_width+=icon_size->width_inc;
X      }
X    }
X  XFree((char *) icon_size);
X  icon_window->width=icon_width;
X  icon_window->height=icon_height;
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X B e s t P i x e l                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function XBestPixel returns a pixel from an array of pixels that is closest
%  to the requested color.
%
%  The format of the XBestPixel routine is:
%
%      pixel=XBestPixel(colors,number_colors,color)
%
%  A description of each parameter follows:
%
%    o pixel: XBestPixel returns the pixel value closest to the requested
%      color.
%
%    o colors: Specifies an array of XColor structures.
%
%    o number_colors: Specifies the number of XColor structures in the
%      color definition array.
%
%    o color: Specifies the desired RGB value to find in the colors array.
%
%
*/
unsigned long XBestPixel(colors,number_colors,color)
XXColor
X  *colors;
X
unsigned int
X  number_colors;
X
XXColor
X  color;
{
X  register int
X    blue_distance,
X    green_distance,
X    i,
X    red_distance;
X
X  register unsigned long
X    distance,
X    min_distance,
X    pixel;
X
X  /*
X    Find closest representation for the requested RGB color.
X  */
X  pixel=0;
X  min_distance=(~0);
X  for (i=0; i < number_colors; i++)
X  {
X    red_distance=(colors[i].red >> 8)-(color.red >> 8);
X    green_distance=(colors[i].green >> 8)-(color.green >> 8);
X    blue_distance=(colors[i].blue >> 8)-(color.blue >> 8);
X    distance=red_distance*red_distance+green_distance*green_distance+
X      blue_distance*blue_distance;
X    if (distance < min_distance)
X      {
X        min_distance=distance;
X        pixel=colors[i].pixel;
X      }
X  }
X  return(pixel);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X B e s t V i s u a l I n f o                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function XBestVisualInfo returns visual information for a visual that is
%  the "best" the server supports.  "Best" is defined as:
%
%    1. Restrict the visual list to those supported by the default screen.
%
%    2. If a visual type is specified, restrict the visual list to those of
%       that type.
%
%    3. If a map type is specified, choose the visual that matches the id
%       specified by the Standard Colormap.
%
%    4  From the list of visuals, choose one that can display the most
%       simultaneous colors.  If more than one visual can display the same
%       number of simultaneous colors, one is choosen based on a rank.
%
%  The format of the XBestVisualInfo routine is:
%
%      visual_info=XBestVisualInfo(display,visual_type,map_type,map_info)
%
%  A description of each parameter follows:
%
%    o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
%      structure.
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o visual_type: Specifies the desired visual type.
%
%    o map_type: Specifies the desired Standard Colormap type.
%
%    o map_info: If map_type is specified, this structure is initialized
%      with info from the Standard Colormap.
%
%
*/
XXVisualInfo *XBestVisualInfo(display,visual_type,map_type,map_info)
Display
X  *display;
X
char
X  *visual_type,
X  *map_type;
X
XXStandardColormap
X  **map_info;
{
#define XVisualColormapSize(visual_info) \
X  ((visual_info->class == TrueColor) || (visual_info->class == DirectColor) ? \
X    visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
X    visual_info->colormap_size)
X
X  int
X    number_visuals;
X
X  register int
X    i;
X
X  unsigned int
X    visual_mask;
X
X  XVisualInfo
X    *visual_info,
X    *visual_list,
X    visual_template;
X
X  /*
X    Restrict visual search by screen number.
X  */
X  visual_mask=VisualScreenMask;
X  visual_template.screen=XDefaultScreen(display);
X  if (visual_type != (char *) NULL)
X    {
X      register char
X        *p;
X
X      register int
X        c;
X
X      /*
X        Restrict visual search by class or visual id.
X      */
X      p=visual_type;
X      for ( ; *p != (char) NULL; p++)
X      {
X        /*
X          Convert to lower case.
X        */
X        c=(*p);
X        if (isascii(c) && isupper(c))
X          *p=tolower(c);
X      }
X      if (strcmp("staticgray",visual_type) == 0)
X        {
X          visual_mask|=VisualClassMask;
X          visual_template.class=StaticGray;
X        }
X      else
X        if (strcmp("grayscale",visual_type) == 0)
X          {
X            visual_mask|=VisualClassMask;
X            visual_template.class=GrayScale;
X          }
X        else
X          if (strcmp("staticcolor",visual_type) == 0)
X            {
X              visual_mask|=VisualClassMask;
X              visual_template.class=StaticColor;
X            }
X          else
X            if (strcmp("pseudocolor",visual_type) == 0)
X              {
X                visual_mask|=VisualClassMask;
X                visual_template.class=PseudoColor;
X              }
X            else
X              if (strcmp("truecolor",visual_type) == 0)
X                {
X                  visual_mask|=VisualClassMask;
X                  visual_template.class=TrueColor;
X                }
X              else
X                if (strcmp("directcolor",visual_type) == 0)
X                  {
X                    visual_mask|=VisualClassMask;
X                    visual_template.class=DirectColor;
X                  }
X                else
X                  if (strcmp("default",visual_type) == 0)
X                    {
X                      visual_mask|=VisualIDMask;
X                      visual_template.visualid=XVisualIDFromVisual(
X                        XDefaultVisual(display,XDefaultScreen(display)));
X                    }
X                  else
X                    if (isdigit(*visual_type))
X                      {
X                        visual_mask|=VisualIDMask;
X                        visual_template.visualid=
X                          strtol(visual_type,(char **) NULL,0);
X                      }
X                    else
X                      Error("invalid visual specifier",visual_type);
X    }
X  /*
X    Get all visuals that meet our criteria so far.
X  */
X  number_visuals=0;
X  visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
X    &number_visuals);
X  visual_mask=VisualScreenMask | VisualIDMask;
X  if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
X    {
X      /*
X        Failed to get visual;  try using the default visual.
X      */
X      Warning("unable to get visual",visual_type);
X      visual_template.visualid=
X        XVisualIDFromVisual(XDefaultVisual(display,XDefaultScreen(display)));
X      visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
X        &number_visuals);
X      if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
X        return((XVisualInfo *) NULL);
X      Warning("using default visual",XVisualClassName(visual_list));
X    }
X  if (map_type != (char *) NULL)
X    {
X      Atom
X        map_property;
X
X      int
X        j,
X        number_maps,
X        status;
X
X      unsigned char
X        map_name[256];
X
X      Window
X        root_window;
X
X      XStandardColormap
X        *map_list;
X
X      /*
X        Restrict visual search by Standard Colormap visual id.
X      */
X      (void) sprintf((char *) map_name,"RGB_%s_MAP",map_type);
X      Latin1Upper(map_name);
X      map_property=XInternAtom(display,(char *) map_name,True);
X      if (map_property == (Atom) NULL)
X        Error("unable to get Standard Colormap",map_type);
X      root_window=XRootWindow(display,XDefaultScreen(display));
X      status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
X        map_property);
X      if (status == 0)
X        Error("unable to get Standard Colormap",map_type);
X      /*
X        Search all Standard Colormaps and visuals for ids that match.
X      */
X      *map_info=XAllocStandardColormap();
X      if (*map_info == (XStandardColormap *) NULL)
X        Error("unable to create Standard Colormap","memory allocation failed");
X      **map_info=map_list[0];
#ifndef PRE_R4_ICCCM
X      visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
X      for (i=0; i < number_maps; i++)
X        for (j=0; j < number_visuals; j++)
X          if (map_list[i].visualid ==
X              XVisualIDFromVisual(visual_list[j].visual))
X            {
X              **map_info=map_list[i];
X              visual_template.visualid=
X                XVisualIDFromVisual(visual_list[j].visual);
X              break;
X            }
X      if ((*map_info)->visualid != visual_template.visualid)
X        Error("unable to match visual to Standard Colormap",map_type);
#endif
X      if ((*map_info)->colormap == (Colormap) NULL)
X        Error("Standard Colormap is not initialized",map_type);
X      XFree((char *) map_list);
X    }
X  else
X    {
X      static unsigned int
X        rank[]=
X          {
X            StaticGray,
X            GrayScale,
X            StaticColor,
X            DirectColor,
X            TrueColor,
X            PseudoColor
X          };
X
X      XVisualInfo
X        *p;
X
X      /*
X        Pick one visual that displays the most simultaneous colors.
X      */
X      visual_info=visual_list;
X      p=visual_list;
X      for (i=1; i < number_visuals; i++)
X      {
X        p++;
X        if (XVisualColormapSize(p) > XVisualColormapSize(visual_info))
X          visual_info=p;
X        else
X          if (XVisualColormapSize(p) == XVisualColormapSize(visual_info))
X            if (rank[p->class] > rank[visual_info->class])
X              visual_info=p;
X      }
X      visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
X    }
X  XFree((char *) visual_list);
X  /*
X    Retrieve only one visual by its screen & id number.
X  */
X  visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
X    &number_visuals);
X  if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
X    return((XVisualInfo *) NULL);
X  return(visual_info);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X C l i e n t W i n d o w                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function XClientWindow finds a window, at or below the specified window,
%  which has a WM_STATE property.  If such a window is found, it is returned,
%  otherwise the argument window is returned.
%
%  The format of the XClientWindow function is:
%
%      client_window=XClientWindow(display,target_window)
%
%  A description of each parameter follows:
%
%    o client_window:XClientWindow returns a window, at or below the specified
%      window, which has a WM_STATE property otherwise the argument
%      target_window is returned.
%
%    o display:Specifies a pointer to the Display structure;  returned from
%      XOpenDisplay.
%
%    o target_window:Specifies the window to find a WM_STATE property.
%
%
*/
Window XClientWindow(display,target_window)
Display
X  *display;
X
Window
X  target_window;
{
X  Atom
X    state,
X    type;
X
X  int
X    format;
X
X  unsigned char
X    *data;
X
X  unsigned long
X    after,
X    number_items;
X
X  Window
X    client_window;
X
X  state=XInternAtom(display,"WM_STATE",True);
X  if (state == (Atom) NULL)
X    return(target_window);
X  type=(Atom) NULL;
X  (void) XGetWindowProperty(display,target_window,state,0L,0L,False,
X    AnyPropertyType,&type,&format,&number_items,&after,&data);
X  if (type != (Atom) NULL)
X    return(target_window);
X  client_window=XWindowByProperty(display,target_window,state);
X  if (client_window == (Window) NULL)
X    return(target_window);
X  return(client_window);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X M a k e I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function XMakeImage creates an X11 image.  If the image size differs from
%  the X11 image size, the image is first resized.
%
%  The format of the XMakeImage routine is:
%
%      ximage=XMakeImage(display,resource_info,image_window,image,columns,
%        height)
%
%  A description of each parameter follows:
%
%    o ximage: Specifies a pointer to a XImage structure;  returned from
%      XMakeImage.
%
%    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_window: Specifies a pointer to a XWindowInfo structure.
%
%    o image: Specifies a pointer to a Image structure;  returned from
%      ReadImage.
%
%    o width: Specifies the width in pixels of the rectangular area to
%      display.
%
%    o height: Specifies the height in pixels of the rectangular area to
%      display.
%
%
*/
XXImage *XMakeImage(display,resource_info,image_window,image,width,height)
Display
X  *display;
X
XXResourceInfo
X  *resource_info;
X
XXWindowInfo
X  *image_window;
X
Image
X  *image;
X
unsigned int
X  width,
X  height;
{
X  Image
X    *transformed_image;
X
X  XImage
X    *ximage;
X
X  /*
X    Create X image.
X  */
X  ximage=XCreateImage(display,image_window->visual_info->visual,
X    (resource_info->monochrome ? 1 : image_window->depth),
X    (((image_window->depth == 1) || resource_info->monochrome) ? XYBitmap :
X    ZPixmap),0,(char *) NULL,width,height,XBitmapPad(display),0);
X  if (ximage == (XImage *) NULL)
X    return((XImage *) NULL);
X  /*
X    Allocate X image pixel data.
X  */
X  if (ximage->format == XYBitmap)
X    ximage->data=(char *) malloc((unsigned int)
X      ximage->bytes_per_line*ximage->height*ximage->depth);
X  else
X    ximage->data=(char *)
X      malloc((unsigned int) ximage->bytes_per_line*ximage->height);
X  if (ximage->data == (char *) NULL)
X    {
X      /*
X        Unable to allocate pixel data.
X      */
X      XDestroyImage(ximage);
X      return((XImage *) NULL);
X    }
X  if (image == (Image *) NULL)
X    return(ximage);
X  transformed_image=image;
X  if (image_window->clip_geometry)
X    {
X      Image
X        *clipped_image;
X
X      int
X        clip_x,
X        clip_y;
X
X      unsigned
X        clip_height,
X        clip_width;
X
X      /*
X        Clip image.
X      */
X      (void) XParseGeometry(image_window->clip_geometry,&clip_x,&clip_y,
X        &clip_width,&clip_height);
X      clipped_image=
X        ClipImage(transformed_image,clip_x,clip_y,clip_width,clip_height);
X      if (clipped_image == (Image *) NULL)
X        return((XImage *) NULL);
X      if (transformed_image != image)
X        DestroyImage(transformed_image);
X      transformed_image=clipped_image;
X    }
X  if ((ximage->width != transformed_image->columns) ||
X      (ximage->height != transformed_image->rows))
X    {
X      Image
X        *scaled_image;
X
X      /*
X        Scale image.
X      */
X      scaled_image=ScaleImage(transformed_image,(unsigned int) ximage->width,
X        (unsigned int) ximage->height);
X      if (scaled_image == (Image *) NULL)
X        return((XImage *) NULL);
X      if (transformed_image != image)
X        DestroyImage(transformed_image);
X      transformed_image=scaled_image;
X    }
X  /*
X    Convert runlength-encoded pixels to X image data.
X  */
X  if ((ximage->byte_order == LSBFirst) ||
X      ((ximage->format == XYBitmap) && (ximage->bitmap_bit_order == LSBFirst)))
X    XMakeImageLSBFirst(image_window->map_info,image_window->pixel_info,
X      transformed_image,ximage);
X  else
X    XMakeImageMSBFirst(image_window->map_info,image_window->pixel_info,
X      transformed_image,ximage);
X  if (transformed_image != image)
X    DestroyImage(transformed_image);
X  return(ximage);
}
X
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X M a k e I m a g e L S B F i r s t                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Function XMakeImageLSBFirst initializes the pixel data of an X11 Image.
%  The X image pixels are copied in least-significant bit and byte first
%  order.  The server's scanline pad is respected.  Rather than using one or
%  two general cases, many special cases are found here to help speed up the
%  image conversion.
%
%  The format of the XMakeImageLSBFirst routine is:
%
%      XMakeImageLSBFirst(map_info,pixel_info,image,ximage)
%
%  A description of each parameter follows:
%
%    o map_info: Specifies a pointer to a XStandardColormap structure.
%
%    o pixel_info: Specifies a pointer to a XPixelInfo structure.
%
%    o image: Specifies a pointer to a Image structure;  returned from
%      ReadImage.
%
%    o ximage: Specifies a pointer to a XImage structure;  returned from
%      XCreateImage.
%
%
*/
void XMakeImageLSBFirst(map_info,pixel_info,image,ximage)
XXStandardColormap
X  *map_info;
X
XXPixelInfo
X  *pixel_info;
X
Image
X  *image;
X
XXImage
X  *ximage;
{
X  register int
X    i,
X    j,
X    x;
X
X  register RunlengthPacket
X    *p;
X
X  register unsigned char
X    *q;
X
X  register unsigned long
X    pixel;
X
X  unsigned int
X    scanline_pad;
X
X  unsigned long
X    *pixels;
X
X  pixels=pixel_info->pixels;
X  p=image->pixels;
X  q=(unsigned char *) ximage->data;
X  x=0;
X  if (ximage->format == XYBitmap)
X    {
X      register unsigned char
X        bit,
X        byte;
X
X      register unsigned char
X        foreground_pixel;
X
X      /*
X        Convert image to big-endian bitmap.
X      */
X      foreground_pixel=(Intensity(image->colormap[0]) >
X        Intensity(image->colormap[1]) ? 0 : 1);
X      scanline_pad=ximage->bytes_per_line-(ximage->width >> 3);
X      bit=0;
X      byte=0;
X      for (i=0; i < image->packets; i++)
X      {
X        for (j=0; j <= p->length; j++)
X        {
X          byte>>=1;
X          if (p->index == foreground_pixel)
X            byte|=0x80;
X          bit++;
X          if (bit == 8)
X            {
X              *q++=byte;
X              bit=0;
X              byte=0;
X            }
X          x++;
X          if (x == ximage->width)
X            {
X              /*
X                Advance to the next scanline.
X              */
X              if (bit > 0)
X                *q=byte >> (8-bit);
X              q+=scanline_pad;
X              bit=0;
X              byte=0;
X              x=0;
X            }
X        }
X        p++;
X      }
X    }
X  else
X    {
X      /*
X        Convert image to little-endian color-mapped X image.
X      */
X      scanline_pad=ximage->bytes_per_line-
X        ((ximage->width*ximage->bits_per_pixel) >> 3);
X      if (pixels != (unsigned long *) NULL)
X        switch (ximage->bits_per_pixel)
X        {
X          case 2:
X          {
X            register unsigned int
X              nibble;
X
X            /*
X              Convert to 2 bit color-mapped X image.
X            */
X            nibble=0;
X            for (i=0; i < image->packets; i++)
X            {
X              pixel=pixels[p->index] & 0xf;
X              for (j=0; j <= p->length; j++)
X              {
X                switch (nibble)
X                {
X                  case 0:
X                  {
X                    *q=(unsigned char) pixel;
X                    nibble++;
X                    break;
X                  }
X                  case 1:
X                  {
X                    *q|=(unsigned char) (pixel << 2);
X                    nibble++;
X                    break;
X                  }
X                  case 2:
X                  {
X                    *q|=(unsigned char) (pixel << 4);
X                    nibble++;
X                    break;
X                  }
X                  case 3:
X                  {
X                    *q|=(unsigned char) (pixel << 6);
X                    q++;
X                    nibble=0;
X                    break;
X                  }
X                }
X                x++;
X                if (x == ximage->width)
X                  {
X                    x=0;
X                    nibble=0;
X                    q+=scanline_pad;
X                  }
X              }
X              p++;
X            }
X            break;
X          }
X          case 4:
X          {
X            register unsigned int
X              nibble;
X
X            /*
X              Convert to 4 bit color-mapped X image.
X            */
X            nibble=0;
X            for (i=0; i < image->packets; i++)
X            {
X              pixel=pixels[p->index] & 0xf;
X              for (j=0; j <= p->length; j++)
X              {
X                switch (nibble)
X                {
X                  case 0:
X                  {
X                    *q=(unsigned char) pixel;
X                    nibble++;
X                    break;
X                  }
X                  case 1:
X                  {
X                    *q|=(unsigned char) (pixel << 4);
X                    q++;
X                    nibble=0;
X                    break;
X                  }
X                }
X                x++;
X                if (x == ximage->width)
X                  {
X                    x=0;
X                    nibble=0;
X                    q+=scanline_pad;
X                  }
X              }
X              p++;
X            }
X            break;
X          }
X          case 6:
X          case 8:
X          {
X            /*
X              Convert to 8 bit color-mapped X image.
X            */
X            for (i=0; i < image->packets; i++)
X            {
X              pixel=pixels[p->index];
X              for (j=0; j <= p->length; j++)
X              {
X                *q++=(unsigned char) pixel;
X                x++;
X                if (x == ximage->width)
X                  {
X                    x=0;
X                    q+=scanline_pad;
X                  }
X              }
X              p++;
X            }
X            break;
X          }
X          default:
X          {
X            register int
X              k;
X
X            register unsigned int
X              bytes_per_pixel;
X
X            unsigned char
X              channel[sizeof(unsigned long)];
X
X            /*
X              Convert to multi-byte color-mapped X image.
X            */
X            bytes_per_pixel=ximage->bits_per_pixel >> 3;
X            for (i=0; i < image->packets; i++)
X            {
X              pixel=pixels[p->index];
X              for (k=0; k < bytes_per_pixel; k++)
X              {
X                channel[k]=(unsigned char) pixel;
SHAR_EOF
true || echo 'restore of ImageMagick/X.c failed'
fi
echo 'End of ImageMagick part 19'
echo 'File ImageMagick/X.c is continued in part 20'
echo 20 > _shar_seq_.tmp
exit 0
--
Dan Heller
O'Reilly && Associates       Z-Code Software    Comp-sources-x:
Senior Writer                President          comp-sources-x at uunet.uu.net
argv at ora.com                 argv at zipcode.com



More information about the Comp.sources.x mailing list