home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-20 | 52.7 KB | 1,705 lines |
- Newsgroups: comp.sources.misc
- From: cs62a12@wind.ucsd.edu (Mark Hanson)
- Subject: v30i077: icontact - perl script to create contact sheets of images, v1.2, Part01/01
- Message-ID: <1992Jun21.041357.3409@sparky.imd.sterling.com>
- X-Md4-Signature: aba4191ef8cc40c7bf11344cb8f5f274
- Date: Sun, 21 Jun 1992 04:13:57 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: cs62a12@wind.ucsd.edu (Mark Hanson)
- Posting-number: Volume 30, Issue 77
- Archive-name: icontact/part01
- Environment: UNIX, perl, pbmplus
-
- icontact-1.2 (14jun92)
-
- This is the third release of icontact. The only new features are the
- -k and -K options. I have also cleaned up the code and the man page
- a bit.
-
- I would appreciate hearing from you if you find icontact useful or have
- suggestions on how to make it better. I only have access to a
- SPARCstation running SunOS 4.1.2, so icontact has only been tested in
- this environment. If icontact fails in your environment, let me know
- so I can fix it.
-
- Send all e-mail regarding icontact to cs62a12@wind.ucsd.edu.
-
- Here is the DESCRIPTION section from the man page:
-
- icontact is a perl script that takes a bunch of image files and creates
- contact sheets. icontact determines the file format by the file name
- extension of the input files and then uses internal tables to look up
- the commands it needs to convert the images to the ppm format. Once in
- the ppm format, icontact uses various pbmplus commands to create the
- contact sheets. icontact is particularly useful if you have lots of
- image files in all sorts of different formats and you want to create an
- index of all of them without converting them all to a common format
- first.
-
- icontact is highly configurable. It can probably do anything you would
- ever want this type of program to do - and more. If you think of
- additional features that would be useful for a program of this type to
- do, tell me and I'll see what I can do.
-
- Besides perl, icontact requires the pbmplus package by Jef Poskanzer.
- The Independent JPEG Group's package (cjpeg, djpeg) is also necessary
- if you are going to be processing any JPEG files. It should not be
- difficult to add filters from other packages as long as there is a way
- to go to and from the ppm format with them.
-
- THANKS TO
- - Roger Hayes (roger.hayes@eng.sun.com)
- for sending me an implementation of the -W option.
- - Larry W. Virden (lwv26@cas.org)
- for suggesting the -O option and the feature that allows you to take an
- old contact sheet and add new images to it.
-
- I hope you find icontact useful,
- mark
-
- ---
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README icontact.1 icontact
- # Wrapped by mark@eggman on Sun Jun 14 20:30:31 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2061 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- Xicontact-1.2 (14jun92)
- X
- XThis is the third release of icontact. The only new features are the
- X-k and -K options. I have also cleaned up the code and the man page
- Xa bit.
- X
- XI would appreciate hearing from you if you find icontact useful or have
- Xsuggestions on how to make it better. I only have access to a
- XSPARCstation running SunOS 4.1.2, so icontact has only been tested in
- Xthis environment. If icontact fails in your environment, let me know
- Xso I can fix it.
- X
- XSend all e-mail regarding icontact to cs62a12@wind.ucsd.edu.
- X
- XHere is the DESCRIPTION section from the man page:
- X
- X icontact is a perl script that takes a bunch of image files and creates
- X contact sheets. icontact determines the file format by the file name
- X extension of the input files and then uses internal tables to look up
- X the commands it needs to convert the images to the ppm format. Once in
- X the ppm format, icontact uses various pbmplus commands to create the
- X contact sheets. icontact is particularly useful if you have lots of
- X image files in all sorts of different formats and you want to create an
- X index of all of them without converting them all to a common format
- X first.
- X
- X icontact is highly configurable. It can probably do anything you would
- X ever want this type of program to do - and more. If you think of
- X additional features that would be useful for a program of this type to
- X do, tell me and I'll see what I can do.
- X
- X Besides perl, icontact requires the pbmplus package by Jef Poskanzer.
- X The Independent JPEG Group's package (cjpeg, djpeg) is also necessary
- X if you are going to be processing any JPEG files. It should not be
- X difficult to add filters from other packages as long as there is a way
- X to go to and from the ppm format with them.
- X
- XTHANKS TO
- X- Roger Hayes (roger.hayes@eng.sun.com)
- X for sending me an implementation of the -W option.
- X- Larry W. Virden (lwv26@cas.org)
- X for suggesting the -O option and the feature that allows you to take an
- X old contact sheet and add new images to it.
- X
- XI hope you find icontact useful,
- Xmark
- END_OF_FILE
- if test 2061 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'icontact.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'icontact.1'\"
- else
- echo shar: Extracting \"'icontact.1'\" \(17155 characters\)
- sed "s/^X//" >'icontact.1' <<'END_OF_FILE'
- X.nh
- X.TH ICONTACT 1 "icontact\-1.2 (14jun92)"
- X.SH NAME
- Xicontact \- create contact sheets from images of different formats
- X.SH SYNOPSIS
- X\fBicontact\fP [ \fIoptions\fP ] [ { \fIimage file\fP | \fIparameter
- Xfile\fP } ... ]
- X.SH DESCRIPTION
- X.PP
- X\fIicontact\fP is a \fIperl\fP script that takes a bunch of image files
- Xand creates contact sheets. \fIicontact\fP determines the file format
- Xby the file name extension of the input files and then uses internal
- Xtables to look up the commands it needs to convert the images to the
- Xppm format. Once in the ppm format, \fIicontact\fP uses various
- X\fIpbmplus\fP commands to create the contact sheets. \fIicontact\fP is
- Xparticularly useful if you have lots of image files in all sorts of
- Xdifferent formats and you want to create an index of all of them
- Xwithout converting them all to a common format first.
- X.PP
- X\fIicontact\fP is highly configurable. It can probably do anything you
- Xwould ever want this type of program to do \(em and more. If you think
- Xof additional features that would be useful for a program of this type
- Xto do, tell me and I'll see what I can do.
- X.PP
- XBesides \fIperl\fP, \fIicontact\fP requires the \fIpbmplus\fP package
- Xby Jef Poskanzer. The Independent JPEG Group's package (\fIcjpeg\fP,
- X\fIdjpeg\fP) is also necessary if you are going to be processing any
- XJPEG files. It should not be difficult to add filters from other
- Xpackages as long as there is a way to go to and from the ppm format
- Xwith them.
- X.SH OPTIONS
- X.PP
- XSwitches that do not take arguments may be combined into a single
- Xswitch with other switches: \fB\-abBlv\fP. Switches that take
- Xarguments must be followed by their arguments with a space in between:
- X\fB\-c\ 10\ \-r\ 5\fP. The fancy way combine all these switches is:
- X\fB\-abBlvc\ 10\ \-r\ 5\fP. That is, you can combine the switches
- Xtogether in any way you like so long as the switches that take an
- Xargument are followed by said argument with a space in between. If you
- Xdon't want to get fancy, just specify each switch by itself:
- X\fB\-a\ \-b\ \-B\ \-c\ 10\ \-l\ \-r\ 5\ \-v\fP.
- X.\"
- X.PP
- XIn all cases in which a switch does not take an argument,
- X\fB\-switch\fP will turn the switch on, and \fB+switch\fP will turn the
- Xswitch off. For example, \fB\-l\fP will turn labels on, and \fB+l\fP
- Xwill turn labels off. This can be useful if you have a particular set
- Xof switches set in a configuration file and you want to temporarily
- Xdisable a switch to make a sheet without changing the configuration
- Xfile. If a set of switches are combined into a single switch that
- Xleads with either a \fB+\fP or a \fB\-\fP, the \fB+\fP or \fB\-\fP
- Xaffects all the switches in that set of switches. If a switch that
- Xtakes an argument is specified with a leading \fB+\fP, it is assumed
- Xthat you meant \fB\-\fP.
- X.\"
- X.PP
- XAn argument of \fB\-\-\fP terminates the options list and signals the
- Xbeginning of the file list.
- X.\"
- X.PP
- XSwitches can be specified in two places: the command line and a
- Xconfiguration file. The command line switches are the most potent \(em
- Xthey override everything. The switches in a configuration file are the
- Xnext most potent \(em they are only overridden by the command line
- Xswitches. The internal defaults of \fIicontact\fP are overridden by
- Xboth the command line and configuration file.
- X.\"
- X.IP \fB\(+-a\fP
- XMake the output sheets fit into the size specified with the \fB\-x\fP
- Xand \fB\-y\fP switches. Setting the \fB\-x\fP and \fB\-y\fP switches
- Xto the size of your screen will yield contact sheets which are no
- Xlarger than your screen. The \fB\-r\fP and \fB\-c\fP switches will be
- Xignored if the \fB\-a\fP switch is present because the number of rows
- Xand columns is figured out dynamically and will probably change from
- Xsheet to sheet unless the \fB\-i\fP switch is specified or all the
- Xsource images are of the same size to begin with.
- X.\"
- X.IP \fB\(+-B\fP
- XAdd a border to each image in the contact sheet. This will make each
- Ximage in the contact sheets 6 pixels larger in both width and height.
- XIf the background is white, the border will be white\-black\-white. If
- Xit is black, it will be black\-white\-black. The background color may
- Xbe selected with the \fB\-W\fP switch.
- X.\"
- X.IP \fB\(+-b\fP
- XUse the \fIbasename(1)\fP of the file name instead of the whole path
- Xname to the file in labels. This switch will be ignored if the
- X\fB\-l\fP switch is not specified.
- X.\"
- X.IP "\fB\-c\fP \fIn\fP"
- XMake the contact sheets with \fIn\fP columns of images. This switch is
- Xignored if the \fB\-a\fP switch is specified. The default value is 7.
- X.\"
- X.IP "\fB\-d\fP \fIdir\fP"
- XPut the contact sheets in \fIdir\fP when completed. The default value
- Xis ``.''.
- X.\"
- X.IP "\fB\-F\fP \fIfile\fP"
- X\fIfile\fP will be used with \fIpbmtext\fP as a font for labels. Each
- Ximage's height will be increased by the height of the characters in the
- Xfont. This switch will be ignored if the \fB\-l\fP switch is not
- Xspecified. By default, \fIpbmtext\fP's internal font is used.
- X.\"
- X.IP "\fB\-f\fP \fIformat\fP"
- XEncode the finished contact sheets in \fIformat\fP. The default value
- Xis ``.ppm.Z''.
- X.\"
- X.IP \fB\(+-g\fP
- XGenerate a parameter file for each contact sheet produced. This
- Xparameter file will be named \fIprefix###.format.suffix\fP, where
- X\fIprefix\fP is the contact sheet name, \fI###\fP is the number of the
- Xcontact sheet, \fIformat\fP is the file format of the contact sheet,
- Xand \fIsuffix\fP is the parameter file suffix specified with the
- X\fB\-P\fP option. When \fIicontact\fP sees one of these files on the
- Xcommand line, it looks in the parameter file for the names and
- Xlocations of images inside the sheet specified by removing the
- X\fIsuffix\fP from the parameter file name. These images will be cut
- Xout and put in the new output sheets instead of being fully processed
- Xagain. For best results when using parameter files on the command
- Xline, select no quantization and a lossless file format both when the
- Xsheet is first created and also when its parameter file is used on the
- Xcommand line. This will prevent information loss if this operation is
- Xperformed multiple times.
- X.\"
- X.IP "\fB\-h\fP \fIn\fP"
- XMake each image in the contact sheets a maximum of \fIn\fP pixels
- Xhigh. The aspect ratio of the images will not be changed. This switch
- Xwill be ignored if the \fB\-X\fP switch is also specified. The default
- Xvalue is 100.
- X.\"
- X.IP \fB\-help\fP
- XThis is a special case which will print out a help message explaining
- X\fIicontact\fP's options. Any other unrecognized switch will do the
- Xsame.
- X.\"
- X.IP \fB\(+-i\fP
- XMake all of the images the same size. The size of the images is
- Xdetermined by the dimensions specified with the \fB\-w\fP and \fB\-h\fP
- Xswitches. Use of this switch can create contact sheets with lots of
- Xblank space between images. This switch cannot be used with the
- X\fB\-X\fP or \fB\-Y\fP switches.
- X.\"
- X.IP "\fB\-K\fP \fIfile\fP"
- XUse \fIfile\fP as the configuration file. The default configuration
- Xfile name is ``~/.icrc''. Putting this option in the configuration
- Xfile will have no effect since once you're in it, it's too late to
- Xswitch to another one.
- X.\"
- X.IP \fB\(+-k\fP
- XDon't reference the configuration file. Putting this option in the
- Xconfiguration file will have no effect since once you're in the
- Xconfiguration file, it's too late to back out.
- X.\"
- X.IP \fB\(+-l\fP
- XAttach a label containing the image's file name below each image. This
- Xname may be truncated if the label is wider than the image. The
- Xbehavior of this switch can be changed with the \fB\-b\fP and \fB\-F\fP
- Xswitches.
- X.\"
- X.IP "\fB\-n\fP \fIfile\fP"
- XTake the file names from \fIfile\fP and add them to the ones specified
- Xon the command line, if any. The file names in \fIfile\fP must be one
- Xper line. These file names will be processed after the file names
- Xspecified on the command line.
- X.\"
- X.IP \fB\(+-O\fP
- XFind the number for the first sheet by looking in the destination
- Xdirectory for sheets with the same prefix and format that we are going
- Xto create. Take the highest numbered one, increment, and this is the
- Xnew starting number for the new sheets. If there are no files with the
- Xsame prefix and format in the destination directory, the new sheets
- Xwill start with 001. This switch cannot be used with the \fB\-o\fP
- Xswitch.
- X.\"
- X.IP "\fB\-o\fP \fIn\fP"
- XThe output sheet numbering will begin with \fIn\fP and increase from
- Xthere. This switch cannot be used with the \fB\-O\fP switch. The
- Xdefault value is 001.
- X.\"
- X.IP "\fB\-P\fP \fIsuffix\fP"
- X\fIsuffix\fP will be used as the extension of the contact sheet
- Xparameter files if the \fB\-g\fP switch is specified. See the
- X\fB\-g\fP switch description for more details. The default value is
- X``.icp''.
- X.\"
- X.IP "\fB\-p\fP \fIprefix\fP"
- XName the contact sheets \fIprefix###.format\fP, where \fI###\fP is the
- Xnumber of the contact sheet and \fIformat\fP is the format of the
- Xcontact sheet. The default value is ``ic\-''.
- X.\"
- X.IP "\fB\-q\fP \fIn\fP"
- XQuantize the contact sheets down to \fIn\fP colors. A value of 0 will
- Xturn off quantization. The default value is 0.
- X.\"
- X.IP "\fB\-r\fP \fIn\fP"
- XMake the contact sheets with \fIn\fP rows of images. This switch is
- Xignored if the \fB\-a\fP switch is specified. The default value is 7.
- X.\"
- X.IP \fB\(+-S\fP
- XSort the file names taken from the command line (and, optionally, from
- Xthe file specified with the \fB\-n\fP switch) into alphabetical order
- Xbefore making the sheet.
- X.\"
- X.IP \fB\(+-s\fP
- XDon't output anything except warnings and fatal errors.
- X.\"
- X.IP "\fB\-t\fP \fItempdir\fP"
- XUse \fItempdir\fP to hold \fIicontact\fP's intermediate files.
- X\fIicontact\fP tries to minimize the amount of temporary space it
- Xneeds, but it's disk space requirements can be large depending upon the
- Xparticular operation it is performing. If you have a tiny /tmp
- Xdirectory, you'll want to use this option to aim \fIicontact\fP at a
- Xlarger chunk of disk. The default value is ``/tmp''.
- X.\"
- X.IP \fB\(+-u\fP
- XDelete duplicate entries in the list of image file names. The first
- Xfile with any particular name will make it through, but following files
- Xwith the same name will be deleted from the file name list. The
- Xdefault it to allow duplicate file names.
- X.\"
- X.IP \fB\(+-v\fP
- XCause all sorts of possibly interesting output to be printed to the
- Xscreen. The output includes the current parameters of \fIicontact\fP
- Xand all the shell commands it is running. If you're having difficulty
- Xgetting \fIicontact\fP to do what you want it to do, try using this
- Xswitch to see what \fIicontact\fP is doing behind your back.
- X.\"
- X.IP "\fB\-W\fP \fIn\fP"
- XMake the background white instead of black, which is the default. If
- Xyou are printing your contact sheets on a laser printer, this will save
- Xyour toner cartridge.
- X.\"
- X.IP "\fB\-w\fP \fIn\fP"
- XMake each image in the contact sheets a maximum of \fIn\fP pixels
- Xwide. The aspect ratio of the images will not be changed. This switch
- Xwill be ignored if the \fB\-Y\fP switch is also specified. The default
- Xvalue is 100.
- X.\"
- X.IP \fB\(+-X\fP
- XThis switch will make all the images the same width. Their heights
- Xwill be whatever they are when the image comes out of \fIpnmscale\fP.
- XThe aspect ratios of the images will not be changed. Wide images will
- Xbe short and tall images will be tall. This switch cannot be used with
- Xthe \fB\-i\fP or \fB\-Y\fP switches.
- X.\"
- X.IP "\fB\-x\fP \fIn\fP"
- XWhen used with the \fB\-a\fP switch, \fIn\fP specifies the width of the
- Xoutput sheets in pixels. This switch will be ignored unless the
- X\fB\-a\fP switch is specified. The default value is 1152.
- X.\"
- X.IP \fB\(+-Y\fP
- XThis switch will make all the images the same height. Their widths
- Xwill be whatever they are when the image comes out of \fIpnmscale\fP.
- XWide images will be wide and tall images will be skinny. The aspect
- Xratios of the images will not be changed. This switch cannot be used
- Xwith the \fB\-i\fP or \fB\-X\fP switches.
- X.\"
- X.IP "\fB\-y\fP \fIn\fP"
- XWhen used with the \fB\-a\fP switch, \fIn\fP specifies the height of
- Xthe output sheets in pixels. This switch will be ignored unless the
- X\fB\-a\fP switch is specified. The default value is 900.
- X.\"
- X.SH ENVIRONMENT
- X.IP "\fBTMPDIR, TEMPDIR\fP"
- XThese environment variables can be used to set the location of
- X\fIicontact\fP's temporary directory. If both \fBTMPDIR\fP and
- X\fBTEMPDIR\fP are set, a warning will be printed and the value of
- X\fBTMPDIR\fP will be used. If only one of them is set, that one will
- Xbe used. This value will be overridden if the \fB\-t\fP switch is used
- Xon the command line or in the configuration file.
- X.\"
- X.SH FILES
- X.IP "configuration file"
- XThe name of the default configuration file is \fB.icrc\fP in your home
- Xdirectory. The proper syntax of this file is as follows: Comments
- Xbegin with a \fB#\fP and terminate with a newline. Lines may be
- Xblank. Configuration lines begin with one of the following keywords:
- X\fBencode\fP, \fBdecode\fP, \fBswitches\fP, or \fBquantize\fP. Lines
- Xbeginning with \fBencode\fP are used to define commands \fIicontact\fP
- Xwill use to encode files into a specific format. Lines beginning with
- X\fBdecode\fP are used to define commands \fIicontact\fP will use to
- Xdecode files of a specific format. Lines beginning with \fBquantize\fP
- Xare used to define the quantization value of sheets created in a
- Xspecific format. The format of lines beginning with \fBencode\fP,
- X\fBdecode\fP or \fBquantize\fP is this:
- X.sp
- X.ce
- X<\fIkeyword\fP>\ <\fIformat\fP>\ <\fIvalue\fP>
- X.sp
- X<\fIformat\fP> may not contain whitespace, but <\fIvalue\fP> may. If
- X<\fIkeyword\fP> is \fBquantize\fP, then <\fIvalue\fP> must be a non
- Xnegative integer. The format of lines beginning with \fBswitches\fP is
- Xthis:
- X.sp
- X.ce
- X\fBswitches\fP\ <\fIcommand\ line\ switches\fP>
- X.sp
- X<\fIcommand\ line\ switches\fP> may be any set of switches that you can
- Xspecify on the command line and may contain whitespace.
- X.sp
- X.nf
- X.in +0.5i
- X.ft CW
- X# sample icontact configuration file
- X
- Xswitches -g # parameter file generation
- Xswitches -B # borders
- Xswitches -l # add labels
- Xswitches -b # basename(1) the labels
- Xswitches -S # sort all the filenames
- Xswitches -v # verbose
- Xswitches -W # white background
- Xswitches -a # automatic sizing
- Xswitches -x 640 # screen width
- Xswitches -y 480 # screen height
- X# OR:
- X# switches -gBlBSvWax 640 -y 480 # everything
- X
- Xencode jpg cjpeg -o
- Xdecode jpg djpeg
- X
- Xencode ppm
- Xdecode ppm
- X
- Xquantize gif 256
- Xquantize jpg 0
- X.ft R
- X.in -0.5i
- X.sp
- X.fi
- X.\"
- X.IP "contact sheet parameter files"
- XThese files are lists of file names (one per line) followed by the
- Ximage's \fIx\fP and \fIy\fP offsets into the contact sheet and then the
- Ximage's height and width. They are created by using the \fB\-g\fP
- Xoption. These files allow blank lines and comments beginning with
- X\fB#\fP and terminating with a newline.
- X.\"
- X.IP \fBTMPDIR/icb\-$$\fP
- Xa temporary file for storing the border if the \fB\-i\fP and \fB\-B\fP
- Xswitches are specified
- X.\"
- X.IP \fBTMPDIR/ici#\-$$\fP
- Xtemporary files for storing images before they are made into rows
- X.\"
- X.IP \fBTMPDIR/icp#\-$$\fP
- Xtemporary files for holding expanded sheets while \fIicontact\fP cuts
- Ximages out of them
- X.\"
- X.IP \fBTMPDIR/icr#\-$$\fP
- Xtemporary files for storing rows before they are made into sheets
- X.\"
- X.IP \fBTMPDIR/ict\-$$\fP
- Xa temporary file for storing labels and borders
- X.\"
- X.SH "SEE ALSO"
- X\fIbasename(1)\fP, \fIperl(1)\fP, \fIpbm(5)\fP, \fIpgm(5)\fP,
- X\fIppm(5)\fP, \fIcjpeg(1)\fP, \fIdjpeg(1)\fP
- X.\"
- X.SH DIAGNOSTICS
- XThe diagnostic messages are intended to be self explanatory.
- X.\"
- X.SH BUGS
- X.PP
- XIf a file name has ``.''s in it that do not come before a valid file
- Xformat extension, the file will be skipped because \fIicontact\fP will
- Xnot be able to find decode commands in it's internal tables.
- X.PP
- X\fIicontact\fP allows you to specify stupid output formats like
- X``.gif.Z''.
- X.PP
- XWhen in automatic sheet sizing mode (\fB\-a\fP), if a processed image
- Xis larger than the dimensions of a sheet, this image will appear in a
- Xsheet all by itself, and the sheet will be larger than you specified
- Xwith \fB\-x\fP and \fB\-y\fP.
- X.PP
- X\fIicontact\fP will most likely fail if it is used on filenames that
- Xcontain whitespace.
- X.PP
- XWhen images are cut out of previously made contact sheets by specifying
- Xa parameter file on the command line, they are not rescaled. So, even
- Xthough you may have specified \fB\-w 100 \-h 100\fP this time, the
- Ximages cut from the previously made contact sheet will be the same size
- Xthey were when that sheet was made. This shouldn't be a problem for
- Xyou if you choose an image size early and stick with it.
- X.\"
- X.SH AUTHOR
- XMark Hanson
- X.br
- X8693 Via Mallorca #15
- X.br
- XLa Jolla, CA 92037\-2575
- X.br
- Xcs62a12@wind.ucsd.edu
- X.sp
- XBug reports, patches, suggestions, questions, and money are all
- Xwelcome.
- X.sp
- X\fIicontact\fP is:
- X.br
- XCopyright (C) 1992 Mark B. Hanson
- X.br
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xprovided that both the above copyright notice and this permission
- Xnotice appear in all copies and in supporting documentation. This
- Xsoftware is provided "as is" without express or implied warranty.
- END_OF_FILE
- if test 17155 -ne `wc -c <'icontact.1'`; then
- echo shar: \"'icontact.1'\" unpacked with wrong size!
- fi
- # end of 'icontact.1'
- fi
- if test -f 'icontact' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'icontact'\"
- else
- echo shar: Extracting \"'icontact'\" \(28926 characters\)
- sed "s/^X//" >'icontact' <<'END_OF_FILE'
- X#!/usr/local/bin/perl
- X
- X# Copyright (C) 1992 Mark B. Hanson
- X# Permission to use, copy, modify, and distribute this software and its
- X# documentation for any purpose and without fee is hereby granted, provided
- X# that both the above copyright notice and this permission notice appear in all
- X# copies and in supporting documentation. This software is provided "as is"
- X# without express or implied warranty.
- X
- X$program = 'icontact';
- X$version = '1.2 (14jun92)';
- X$copyright = 'Copyright (C) 1992';
- X$author = 'Mark B. Hanson (cs62a12@wind.ucsd.edu)';
- X
- X
- X#
- X# default values for parameters that correspond to command line switches
- X#
- X# Leave these alone if you want them to match the man page.
- X# Use a configuration file to customize icontact to your liking.
- X#
- X
- X$AutoOff = 0; # boolean, 0 = sheet numbers start with 0
- X # 1 = start with next highest number in dest. dir.
- X$Auto = 0; # boolean, 0 = use $Columns and $Rows
- X # 1 = dynamically sized to $Xdim, $Ydim
- X$Base = 0; # boolean, 0 = display whole filename in labels
- X # 1 = display basename of filenames in labels
- X$Borders = 0; # boolean, 0 = no spiffy borders around each image
- X # 1 = spiffy borders around each image
- X$Ignore = 0; # boolean, 0 = use configuration file
- X # 1 = don't use configuration file
- X$Ident = 0; # boolean, 0 = don't pad images, just scale them
- X # 1 = pad each image to be the same size
- X$Labels = 0; # boolean, 0 = no labels
- X # 1 = labels
- X$Param = 0; # boolean, 0 = no parameter files for sheets
- X # 1 = generate parameter files for sheets
- X$Silent = 0; # boolean, 0 = normal output
- X # 1 = no output except warnings and errors
- X$Sort = 0; # boolean, 0 = don't sort filenames
- X # 1 = sort filenames
- X$Uniq = 0; # boolean, 0 = leave duplicates in file list
- X # 1 = remove duplicates from file list
- X$Verbose = 0; # boolean, 0 = normal output
- X # 1 = show execution
- X$White = 0; # boolean, 0 = black background
- X # 1 = white background
- X$Xsame = 0; # boolean, 0 = don't make all the images the same width
- X # 1 = make all the images the same width
- X$Ysame = 0; # boolean, 0 = don't make all the images the same height
- X # 1 = make all the images the same height
- X
- X$Columns = 7; # n > 0, number of columns in sheets (!auto mode)
- X$Rows = 7; # n > 0, number of rows in sheets (!auto mode)
- X
- X$Xdim = 1152; # n > 0, width of max sheet size (auto mode)
- X$Ydim = 900; # n > 0, height of max sheet size (auto mode)
- X
- X$Width = 100; # n > 0, max width of each image
- X$Height = 100; # n > 0, max height of each image
- X
- X$Config = ''; # string, name of an alternate configuration file
- X
- X$Dir = '.'; # string, directory to put finished sheets in
- X
- X$Prefix = 'ic-'; # string, prefix for filename of sheets
- X
- X$Offset = 1; # n > 0, start at n when numbering the sheets
- X
- X$Tempdir = '/tmp'; # string, directory to use for temporary files
- X
- X$Font = ''; # string, name of a file to use as a font with pbmtext
- X
- X$Format = '.ppm.Z'; # string, the format in which sheets are to be encoded
- X
- X$Namefile = ''; # string, name of a file from which to get more filenames
- X
- X$Suffix = '.icp'; # string, suffix of parameter files
- X
- X$Quant = 0; # n >= 0, number of colors to be left in sheets
- X # a value of 0 means no quantization
- X
- X
- X#
- X# The tables below are filled with common examples that I typed in to save
- X# you some time and to give you a feel for how icontact decides how to
- X# {en,de}code files. Don't worry if your particular set of favorite programs
- X# and file name extensions is not listed here. Like it says in the man
- X# page: `icontact is highly configurable.' Use a configuration file to make
- X# icontact use any set of programs and filename extensions you want.
- X#
- X
- X#
- X# associative array to go from file suffix -> ppm.
- X#
- X
- X%decode = (
- X 'Z', 'trap \'exit 130\' 2; zcat',
- X 'atk', 'atktopbm',
- X 'brush', 'brushtopbm',
- X 'cmuwm', 'cmuwmtopbm',
- X 'fits', 'fitstopgm',
- X 'fs', 'fstopgm',
- X 'g3', 'g3topbm',
- X 'gem', 'gemtopbm',
- X 'gif', 'giftoppm',
- X 'gould', 'gouldtoppm',
- X 'hips', 'hipstopgm',
- X 'icon', 'icontopbm',
- X 'ilbm', 'ilbmtoppm',
- X 'jpg', 'djpeg',
- X 'lispm', 'lispmtopgm',
- X 'macp', 'macptopbm',
- X 'mgr', 'mgrtopbm',
- X 'mtv', 'mtvtoppm',
- X 'pbm', '',
- X 'pcx', 'pcxtoppm',
- X 'pgm', '',
- X 'pi1', 'pi1toppm',
- X 'pi3', 'pi3toppm',
- X 'pict', 'picttoppm',
- X 'pj', 'pjtoppm',
- X 'ppm', '',
- X 'qrt', 'qrttoppm',
- X 'rast', 'rasttopnm',
- X 'spc', 'spctoppm',
- X 'spu', 'sputoppm',
- X 'tga', 'tgatoppm',
- X 'tiff', 'tifftopnm',
- X 'xbm', 'xbmtopbm',
- X 'xim', 'ximtoppm',
- X 'xpm', 'xpmtoppm',
- X 'xwd', 'xwdtopnm',
- X 'ybm', 'ybmtopbm',
- X 'yuv', 'yuvtoppm',
- X);
- X
- X
- X#
- X# associative array to go from ppm -> file suffix.
- X#
- X
- X%encode = (
- X '10x', 'ppmtopgm | pgmtopbm | pbmto10x',
- X 'Z', '(compress -v -f; exit 0)',
- X 'ascii', 'ppmtopgm | pgmtopbm | pbmtoascii',
- X 'atk', 'ppmtopgm | pgmtopbm | pbmtoatk',
- X 'bbnbg', 'ppmtopgm | pgmtopbm | pbmtobbnbg',
- X 'cmuwm', 'ppmtopgm | pgmtopbm | pbmtocmuwm',
- X 'epson', 'ppmtopgm | pgmtopbm | pbmtoepson',
- X 'fits', 'ppmtopgm | pgmtofits',
- X 'fs', 'ppmtopgm | pgmtofs',
- X 'g3', 'ppmtopgm | pgmtopbm | pbmtog3',
- X 'gem', 'ppmtopgm | pgmtopbm | pbmtogem',
- X 'gif', 'ppmtogif',
- X 'go', 'ppmtopgm | pgmtopbm | pbmtogo',
- X 'icon', 'ppmtopgm | pgmtopbm | pbmtoicon',
- X 'icr', 'ppmtoicr',
- X 'ilbm', 'ppmtoilbm',
- X 'jpg', 'cjpeg -o',
- X 'lispm', 'ppmtopgm | pgmtolispm',
- X 'lj', 'ppmtopgm | pgmtopbm | pbmtolj',
- X 'macp', 'ppmtopgm | pgmtopbm | pbmtomacp',
- X 'mgr', 'ppmtopgm | pgmtopbm | pbmtomgr',
- X 'pbm', 'ppmtopgm | pgmtopbm',
- X 'pcx', 'ppmtopcx',
- X 'pgm', 'ppmtopgm',
- X 'pi1', 'ppmtopi1',
- X 'pi3', 'ppmtopgm | pgmtopbm | pbmtopi3',
- X 'pict', 'ppmtopict',
- X 'pj', 'ppmtopj',
- X 'plot', 'ppmtopgm | pgmtopbm | pbmtoplot',
- X 'ppm', '',
- X 'ps', 'pnmtops',
- X 'ptx', 'ppmtopgm | pgmtopbm | pbmtoptx',
- X 'puzz', 'ppmtopuzz',
- X 'rast', 'pnmtorast',
- X 'sixel', 'ppmtosixel',
- X 'tga', 'ppmtotga',
- X 'tiff', 'pnmtotiff',
- X 'uil', 'ppmtouil',
- X 'x10bm', 'ppmtopgm | pgmtopbm | pbmtox10bm',
- X 'xbm', 'ppmtopgm | pgmtopbm | pbmtoxbm',
- X 'xpm', 'ppmtoxpm',
- X 'xwd', 'pnmtoxwd',
- X 'ybm', 'ppmtopgm | pgmtopbm | pbmtoybm',
- X 'yuv', 'ppmtoyuv',
- X 'zinc', 'ppmtopgm | pgmtopbm | pbmtozinc',
- X);
- X
- X
- X#
- X# default quantization values based upon output file suffix.
- X# if a format's default quant value is the default for the -q switch
- X# ($Quant), don't bother listing it.
- X#
- X
- X%defquant = (
- X 'gif', 256,
- X);
- X
- X
- X#
- X# mapping from command line switches to internal variable names
- X#
- X
- X%optvar = (
- X 'a', 'Auto', 'B', 'Borders', 'b', 'Base', 'c', 'Columns',
- X 'd', 'Dir', 'F', 'Font', 'f', 'Format', 'g', 'Param',
- X 'h', 'Height', 'i', 'Ident', 'K', 'Config', 'k', 'Ignore',
- X 'l', 'Labels', 'n', 'Namefile','O', 'AutoOff', 'o', 'Offset',
- X 'P', 'Suffix', 'p', 'Prefix', 'q', 'Quant', 'r', 'Rows',
- X 'S', 'Sort', 's', 'Silent', 't', 'Tempdir', 'u', 'Uniq',
- X 'v', 'Verbose', 'W', 'White', 'w', 'Width', 'X', 'Xsame',
- X 'x', 'Xdim', 'Y', 'Ysame', 'y', 'Ydim',
- X);
- X
- X
- X# ---------------------------- end of definitions -----------------------------
- X
- X
- X#
- X# keep track of the default settings for the usage message
- X#
- X
- Xfor (values(%optvar)) {
- X $d{$_} = eval "\$$_";
- X}
- X
- X
- X#
- X# tell the public who's responsible for this mess...
- X#
- X
- X&info("$program-$version $copyright $author") if $Verbose;
- X
- X
- X#
- X# assign $Tempdir
- X#
- X
- Xif ($ENV{'TMPDIR'} && $ENV{'TEMPDIR'}) {
- X &warning("both TMPDIR and TEMPDIR are set. Using TMPDIR.");
- X $Tempdir = $ENV{'TMPDIR'};
- X} else {
- X # if neither environment variable is set, set it to itself
- X $Tempdir = $ENV{'TMPDIR'} || $ENV{'TEMPDIR'} || $Tempdir;
- X}
- X
- X
- X#
- X# evaluate arguments before processing the configuration file
- X# to get the -k and -K options
- X#
- X
- X&evalargs(@ARGV);
- X
- X
- X#
- X# process the configuration file
- X#
- X
- Xunless ($Ignore) {
- X local($home) = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($<))[7];
- X local($cfile) = $Config || ($home && "$home/.icrc");
- X
- X if ($cfile) {
- X if (-f $cfile) {
- X if (-e _) {
- X if (open(CONFIG, "<$cfile")) {
- X local($v, $f, $c, $line, @switches);
- X for ($line = 1; $_ = <CONFIG>; $line++) {
- X next if /^\s*#/ || /^\s*$/;
- X s/#.*$//;
- X if (($f, $v) = /^\s*quantize\s+(\S+)\s+(\d+)\s*$/) {
- X $f =~ s/^\.//;
- X $defquant{$f} = $v;
- X } elsif (($f, $c) = /^\s*encode\s+(\S+)\s+(.*)\s*$/) {
- X $f =~ s/^\.//;
- X $encode{$f} = $c;
- X } elsif (($f, $c) = /^\s*decode\s+(\S+)\s+(.*)\s*$/) {
- X $f =~ s/^\.//;
- X $decode{$f} = $c;
- X } elsif (/^\s*switches\s+(.+)\s*$/) {
- X @switches = split(/\s+/, $1);
- X while (@switches = &evalargs(@switches)) {
- X &warning('Ignoring `', shift @switches,
- X "' on line $line of $cfile");
- X }
- X } else {
- X &warning("can't understand line $line of `$cfile'");
- X }
- X }
- X close CONFIG;
- X } else {
- X &warning("can't open `$cfile': $!!");
- X }
- X }
- X } else {
- X &warning("`$cfile' is not a file! Configuration file not used.");
- X }
- X } else {
- X &warning("can't find your home directory!",
- X 'Configuration file not found.');
- X }
- X}
- X
- X
- X#
- X# evaluate arguments after processing the configuration file
- X# (yeah, this is sort of ugly.)
- X#
- X
- X@ARGV = &evalargs(@ARGV);
- X
- X
- X#
- X# sanity checks (fatal)
- X#
- X
- X&fatal("no files specified!") unless @ARGV;
- X
- Xforeach $switch ('c', 'h', 'r', 'w', 'x', 'y') {
- X $num = eval "\$$optvar{$switch}";
- X if ($num !~ /^\d+$/ || $num < 1) {
- X &fatal("-$switch argument must be a positive integer!");
- X }
- X}
- X
- Xforeach $switch ('o', 'q') {
- X $num = eval "\$$optvar{$switch}";
- X if ($num !~ /^\d+$/ || $num < 0) {
- X &fatal("-$switch argument must be non-negative integer!");
- X }
- X}
- X
- Xforeach ($Tempdir, $Dir) {
- X $_ = '/' unless $_;
- X &fatal("directory `$_' does not exist!") unless -e $_;
- X &fatal("`$_' is not a directory!") unless -d _;
- X &fatal("read permission denied on `$_'!") unless -r _;
- X &fatal("write permission denied on `$_'!") unless -w _;
- X}
- X
- X&fatal("font file `$Font' does not exist!") unless -e $Font;
- X&fatal("name file `$Namefile' does not exist!") unless -e $Namefile;
- X
- X&fatal('-i and -X switches can\'t be used together.') if ($Ident && $Xsame);
- X&fatal('-i and -Y switches can\'t be used together.') if ($Ident && $Ysame);
- X&fatal('-X and -Y switches can\'t be used together.') if ($Xsame && $Ysame);
- X
- X&fatal('-O and -o switches can\'t be used together.')
- X if ($opt{'o'} && $AutoOff);
- X
- X
- X#
- X# sanity checks (warnings)
- X#
- X
- Xif ($Auto) {
- X &warning('image width is larger than sheet width \
- X(your sheets will be one image wide)!') if ($Width > $Xdim);
- X &warning('image height is larger than sheet height \
- X(your sheets will be one image high)!') if ($Height > $Ydim);
- X &warning('-r and -a specified! Ignoring -r.') if $opt{'r'};
- X &warning('-c and -a specified! Ignoring -c.') if $opt{'c'};
- X} else {
- X &warning('-x specified without -a! Ignoring -x.') if $opt{'x'};
- X &warning('-y specified without -a! Ignoring -y.') if $opt{'y'};
- X}
- X
- X&warning('-X and -h specified! Ignoring -h.') if ($Xsame && $opt{'h'});
- X&warning('-Y and -w specified! Ignoring -w.') if ($Ysame && $opt{'w'});
- X
- Xif ($Verbose && $Silent) {
- X &warning('-v and -s cancel each other out!');
- X $Silent = $Verbose = 0;
- X}
- X
- Xunless ($Labels) {
- X &warning('-F specified without -l! Ignoring -F.') if ($Font);
- X &warning('-b specified without -l! Ignoring -b.') if ($Base);
- X}
- X
- X
- X#
- X# process output format
- X#
- X
- X$Format =~ s/^\.//;
- X
- X@suffs = split(/\./, $Format);
- X
- Xif (@badext = grep(!defined($encode{$_}), @suffs)) {
- X &fatal(sprintf('unknown extension%s (%s) in output format!',
- X ((@badext > 1) ? 's' : ''), &cslist(@badext)));
- X}
- X
- X@encodecmd = grep($_, @encode{@suffs});
- X
- X$Quant = $defquant{$Format} if (!$opt{'q'} && $defquant{$Format});
- X
- Xunshift(@encodecmd, "ppmquant -fs $Quant") if $Quant;
- X
- X$encodecmd = @encodecmd ? ('| ' . join(' | ', @encodecmd) . ' ') : '';
- X
- X
- X#
- X# get filenames from named file
- X#
- X
- X@filelist = ();
- X
- Xif ($Namefile) {
- X open(NAMEFILE, "<$Namefile") ||
- X &fatal("unable to open `$Namefile' to read filenames: $!!");
- X chop(@filelist = <NAMEFILE>);
- X close(NAMEFILE);
- X}
- X
- Xunshift(@filelist, @ARGV);
- X
- X&fatal("no files specified!") unless @filelist;
- X
- Xif ($Xsame) {
- X $pnmscale = "pnmscale -xsize $Width";
- X} elsif ($Ysame) {
- X $pnmscale = "pnmscale -ysize $Height";
- X} else {
- X $pnmscale = "pnmscale -xysize $Width $Height";
- X}
- X
- X
- X#
- X# start up the signal handler.
- X#
- X
- X$SIG{'HUP'} = $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = 'catcher';
- X
- X
- X#
- X# look for and process parameter files
- X#
- X
- X$Suffix =~ s/^\.//;
- X
- X@newlist = ();
- X$pcount = 1;
- X
- Xforeach $file (@filelist) {
- X if ($file !~ /\.$Suffix$/) {
- X push(@newlist, $file);
- X next;
- X }
- X
- X unless (open(PARAM, "<$file")) {
- X &skip("can't open `$file' for reading: $!!");
- X next;
- X }
- X
- X local($fn, @xywh, $line);
- X for ($line = 1; $_ = <PARAM>; $line++) {
- X next if /^\s*#/ || /^\s*$/;
- X s/#.*$//;
- X if (($fn, @xywh) = /^\s*(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/) {
- X push(@newlist, $fn);
- X $esheetname{$fn} = "$Tempdir/icp$pcount-$$";
- X $parameters{$fn} = "@xywh";
- X ($sheetname{$fn} = $file) =~ s/\.$Suffix$//;
- X } else {
- X &warning("can't understand line $line of `$file'!");
- X }
- X }
- X close(PARAM);
- X $pcount++;
- X}
- X@filelist = @newlist;
- X
- X
- X#
- X# uniq filenames
- X#
- X
- Xif ($Uniq) {
- X local(%seen) = @newlist = ();
- X foreach (@filelist) {
- X if ($seen{$_}++) {
- X &info("removing duplicate `$_' from file list");
- X $esheetname{$_} = ''; # use the one that's not shrunk already.
- X } else {
- X push(@newlist, $_);
- X }
- X }
- X @filelist = @newlist;
- X}
- X
- X
- X#
- X# take the basename's once and for all.
- X#
- X
- Xforeach (@filelist, values(%sheetname)) {
- X $basename{$_} = (/([^\/]*)$/ ? $1 : $_);
- X}
- X
- X
- X#
- X# sort filenames
- X#
- X
- X@filelist = ($Base ? sort by_basename @filelist : sort @filelist) if ($Sort);
- X
- X
- X#
- X# figure out how big each character is in the specified font
- X#
- X
- Xif ($Labels) {
- X $pbmtext = 'pbmtext' . ($Font ? " -font '$Font'" : '');
- X open(TEXT, "$pbmtext 'M' | pnmfile |") ||
- X &fatal("can't open `$pbmtext' to determine font size for labels: $!!");
- X
- X (<TEXT> =~ /\s+(\d+)\s+by\s+(\d+)\s+/) ||
- X &fatal("can't understand `$pbmtext 'M' | pnmfile |' output!");
- X
- X close(TEXT);
- X
- X $cwidth = int($1 / 3);
- X $cheight = $2;
- X
- X $invert = $White ? '' : ' | pnminvert';
- X}
- X
- X
- X#
- X# determine the offset to be used for the first sheet.
- X#
- X
- Xif ($opt{'o'}) {
- X $scount = $Offset;
- X} elsif ($AutoOff) {
- X opendir(DESTDIR, $Dir) ||
- X &fatal("can't open destination directory to find offset: $!!");
- X
- X local($last) =
- X reverse sort grep(/^$Prefix([0-9]{3,})\.$Format$/, readdir(DESTDIR));
- X
- X closedir(DESTDIR);
- X
- X if ($last) {
- X $last =~ /^$Prefix([0-9]{3,})\.$Format$/;
- X $scount = $1 + 1;
- X } else {
- X $scount = 1;
- X }
- X} else {
- X $scount = 1;
- X}
- X
- X
- X#
- X# a few initializations...
- X#
- X
- X$background = $White ? 'white' : 'black';
- X
- X@stripes = $White ? ('white', 'black', 'white') : ('black', 'white', 'black');
- X
- X$temp = "$Tempdir/ict-$$";
- X
- X$icount = $rcount = 1;
- X
- X$iqwidth = $iqheight = $rqheight = 0;
- X
- X@ipqueue = @fpqueue = @rpqueue = ();
- X
- X@tfie = ();
- X
- X
- X#
- X# create one border file for all the images if $Ident && $Borders
- X#
- X
- Xif ($Borders && $Ident) {
- X $border = "$Tempdir/icb-$$";
- X
- X local($count) = 2;
- X
- X $command = sprintf('pbmmake -%s %d %d > %s',
- X shift @stripes, ($Width + $count), ($Height + $count), $border);
- X
- X &shell($command) || &fatal('unable to create border file!');
- X
- X foreach $color (@stripes) {
- X $count += 2;
- X
- X $command = sprintf('pbmmake -%s %d %d | pnmpaste %s 1 1 > %s',
- X $color, ($Width + $count), ($Height + $count), $border, $temp);
- X
- X &shell($command) || &fatal('unable to add a layer to border file!');
- X
- X &mv($temp, $border) || &fatal("unable to move `$temp' to `$border'!");
- X }
- X}
- X
- X
- X#
- X# process each file
- X#
- X
- XIMAGE: while ($file = shift @filelist) {
- X $image = "$Tempdir/ici$icount-$$";
- X
- X if ($sheetname{$file}) { # file is to be cut from sheet
- X unless (grep(/^$esheetname{$file}$/, @tfie)) {
- X &toppm($sheetname{$file}, $esheetname{$file}, 0) || next IMAGE;
- X }
- X &cut($file, $image) || next IMAGE;
- X &rm($esheetname{$file}) unless
- X grep(/^$esheetname{$file}$/, @esheetname{@filelist});
- X } else { # file is an image file
- X unless (-e $file) {
- X &skip("`$file' does not exist!");
- X next IMAGE;
- X }
- X unless (-f _) {
- X &skip("`$file' is not a file!");
- X next IMAGE;
- X }
- X &toppm($file, $image, 1) || next IMAGE;
- X }
- X
- X $label = ($Base ? $basename{$file} : $file);
- X
- X if ($Auto || $Labels || $Borders || $Param || $Ident) {
- X unless (open(SIZE, "pnmfile $image |")) {
- X &skip("can't open `pnmfile $image |' for reading: $!!");
- X &rm($image);
- X next IMAGE;
- X }
- X unless ((($iwidth, $iheight) =
- X (<SIZE> =~ /\s+(\d+)\s+by\s+(\d+)\s+/))) {
- X &skip("can't understand `pnmfile $image |' output!");
- X &rm($image);
- X close(SIZE);
- X next IMAGE;
- X }
- X close(SIZE);
- X
- X ($zxoff, $zyoff, $ziwidth, $ziheight) = (0, 0, $iwidth, $iheight)
- X if ($Param);
- X }
- X
- X if ($Ident) {
- X $xpad = int(($Width - $iwidth) / 2);
- X $ypad = int(($Height - $iheight) / 2);
- X
- X $command = sprintf('pbmmake -%s %d %d | pnmpaste %s %d %d > %s',
- X $background, $Width, $Height, $image, $xpad, $ypad, $temp);
- X
- X unless (&shell($command)) {
- X &skip("unable to pad `$file' to ${Width}x$Height!");
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X
- X unless (&mv($temp, $image)) {
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X
- X $iwidth = $Width;
- X $iheight = $Height;
- X
- X if ($Param) {
- X $zxoff += $xpad;
- X $zyoff += $ypad;
- X }
- X
- X }
- X
- X if ($Borders) {
- X if ($Ident) {
- X $iwidth += 6;
- X $iheight += 6;
- X
- X unless (&shell("pnmpaste $image 3 3 $border > $temp")) {
- X &skip("unable to add a border to `$file'!");
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X unless (&mv($temp, $image)) {
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X } else {
- X foreach $color (@stripes) {
- X $iwidth += 2;
- X $iheight += 2;
- X
- X $command = sprintf('pbmmake -%s %d %d | pnmpaste %s 1 1 > %s',
- X $color, $iwidth, $iheight, $image, $temp);
- X
- X unless (&shell($command)) {
- X &skip("unable to add a layer of border on `$file'!");
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X unless (&mv($temp, $image)) {
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X }
- X }
- X
- X if ($Param) {
- X $zxoff += 3;
- X $zyoff += 3;
- X }
- X }
- X
- X if ($Labels) {
- X $slots = int($iwidth / $cwidth);
- X
- X if ($slots - length($label) > 1) {
- X $command = sprintf('%s \'%s\'%s | pnmcat -%s -tb %s - > %s',
- X $pbmtext, $label, $invert, $background, $image, $temp);
- X } else {
- X $command = sprintf(
- X '%s \'%s\'%s | pnmcut %d 0 %d %d | pnmcat -%s -tb %s - > %s',
- X $pbmtext, substr($label, 0, $slots), $invert, $cwidth,
- X ($cwidth * $slots), $cheight, $background, $image, $temp);
- X }
- X
- X unless (&shell($command)) {
- X &skip("unable to attach label to `$file'!");
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X unless (&mv($temp, $image)) {
- X &rm($image, $temp);
- X next IMAGE;
- X }
- X $iheight += $cheight;
- X }
- X
- X if ($Auto) {
- X if ($iqwidth + $iwidth > $Xdim) {
- X if (@iqueue) {
- X &image2row;
- X $rcount++;
- X $wrheight = $iqheight;
- X &pushimage;
- X ($iqwidth, $iqheight) = ($iwidth, $iheight);
- X } else {
- X &pushimage;
- X &image2row;
- X $rcount++;
- X $wrheight = $iheight;
- X $iqwidth = $iqheight = 0;
- X }
- X if ($rqheight + $wrheight > $Ydim) {
- X if (@rqueue) {
- X &row2sheet;
- X &pushrow;
- X $rqheight = $wrheight;
- X } else {
- X &pushrow;
- X &row2sheet;
- X $rqheight = 0;
- X }
- X } else {
- X &pushrow;
- X $rqheight += $wrheight;
- X }
- X } else {
- X &pushimage;
- X $iqwidth += $iwidth;
- X $iqheight = $iheight if ($iheight > $iqheight);
- X }
- X } else {
- X &pushimage;
- X if (($icount % $Columns) == 0) {
- X &image2row;
- X &pushrow;
- X &row2sheet if (($rcount % $Rows) == 0);
- X $rcount++;
- X }
- X }
- X
- X $icount++;
- X}
- X
- Xif (@iqueue) {
- X &image2row;
- X &row2sheet if ($Auto && $rqheight + $iqheight > $Ydim);
- X &pushrow;
- X}
- X&row2sheet if @rqueue;
- X
- X&cleanup;
- X
- Xexit(0);
- X
- X&catcher('HEY, THIS CAN\'T HAPPEN'); # just to get rid of the warning...
- X
- X
- X# --------------------------- end of main program -----------------------------
- X
- X
- Xsub by_basename {
- X $basename{$a} cmp $basename{$b};
- X}
- X
- X
- Xsub by_number {
- X $a <=> $b;
- X}
- X
- X
- Xsub catcher {
- X &cleanup;
- X &fatal("caught a SIG@_ -- shutting down!");
- X}
- X
- X
- Xsub cleanup {
- X foreach (@tfie) { &warning("can't unlink `$_': $!!") unless unlink; }
- X}
- X
- X
- Xsub cslist {
- X local($") = ", ";
- X "@_";
- X}
- X
- X
- Xsub cut {
- X local($input, $output) = @_;
- X
- X &info("cutting `$input'");
- X if (!&shell("pnmcut $parameters{$input} $esheetname{$input} > $output")) {
- X &skip("can't cut from $esheetname{$input}");
- X &rm($output);
- X return 0;
- X }
- X return 1;
- X}
- X
- X
- Xsub evalargs {
- X local(@args) = @_;
- X
- X while ($_ = $args[0], ($_ && /^[-+]/)) {
- X shift @args;
- X last if /^--$/;
- X
- X if (/^[-+]help$/) { # `h' special case
- X &usage;
- X } elsif (/^[-+]([cdFfhKnoPpqrtwxy])$/) { # argument
- X if (@args) {
- X eval "\$opt{'$1'} = 1; \$$optvar{$1} = shift \@args";
- X } else {
- X &fatal("no argument given for -$1 switch!");
- X }
- X } elsif (/^([-+])([aBbgiklOSsuvWXY])(.*)$/) { # no argument
- X $val = ($1 eq '-');
- X $backon = length($3) ? "; unshift(\@args, '$1$3')" : '';
- X eval "\$$optvar{$2} = $val$backon";
- X } else { # unknown
- X warn "$program: FATAL ERROR: unknown option: `$_'!\n";
- X &usage;
- X }
- X }
- X @args;
- X}
- X
- X
- Xsub fatal {
- X die "$program: FATAL ERROR: ", @_, "\n";
- X}
- X
- X
- Xsub image2row {
- X &info("assembling row $rcount");
- X $row = "$Tempdir/icr$rcount-$$";
- X unless (&shell("pnmcat -$background -lr -jbottom @iqueue > $row")) {
- X &skip("can't assemble row $rcount!");
- X &rm($row);
- X }
- X if ($Param) {
- X push(@fpqueue, @ipqueue);
- X @ipqueue = ();
- X }
- X &rm(@iqueue);
- X @iqueue = ();
- X}
- X
- X
- Xsub info {
- X warn "$program: ", @_, "\n" unless $Silent;
- X}
- X
- X
- Xsub mv {
- X local($src, $dest) = @_;
- X
- X unless (rename($src, $dest)) {
- X &skip("unable to rename `$src' to `$dest': $!!");
- X return 0;
- X }
- X
- X &tfdelete($src);
- X &tfadd($dest);
- X 1;
- X}
- X
- X
- Xsub on {
- X local($num) = @_;
- X
- X $num ? 'on' : 'off';
- X}
- X
- X
- Xsub pushimage {
- X push(@iqueue, $image);
- X if ($Param) {
- X push(@ipqueue, pack("a255I7", $label, $rcount, $iwidth, $iheight,
- X $zxoff, $zyoff, $ziwidth, $ziheight));
- X }
- X}
- X
- X
- Xsub pushrow {
- X push(@rqueue, $row);
- X if ($Param) {
- X push(@rpqueue, @fpqueue);
- X @fpqueue = ();
- X }
- X}
- X
- X
- Xsub rm {
- X foreach $file (@_) {
- X &tfdelete($file);
- X &warning("can't unlink `$file': $!!") unless unlink($file);
- X }
- X}
- X
- X
- Xsub row2sheet {
- X local($sheet) = sprintf("%s/%s%03d.%s", $Dir, $Prefix, $scount, $Format);
- X &info("assembling `$sheet'");
- X unless (&shell("pnmcat -$background -tb @rqueue $encodecmd> $sheet")) {
- X &skip("can't assemble sheet $scount!");
- X &rm($sheet);
- X }
- X &tfdelete($sheet); # save the sheets!
- X
- X if ($Param) {
- X local($pfile) = "$sheet.$Suffix";
- X &info("creating `$pfile'");
- X if (open(PARAM, ">$pfile")) {
- X local(%height, %width, $r, $h, $w, $n, $zx, $zy, $zw, $zh);
- X
- X foreach (@rpqueue) {
- X ($n, $r, $w, $h, $zx, $zy, $zw, $zh) = unpack("A255I7", $_);
- X $width{$r} = $width{$r} ? ($width{$r} + $w) : $w;
- X $height{$r} = $h if (!$height{$r} || $h > $height{$r});
- X }
- X
- X local($xoff);
- X local($yoff) = 0;
- X local($pastr) = -1;
- X local($widest) = reverse sort by_number values(%width);
- X
- X foreach (@rpqueue) {
- X ($n, $r, $w, $h, $zx, $zy, $zw, $zh) = unpack("A255I7", $_);
- X if ($r != $pastr) {
- X $pastr = $r;
- X $xoff = 0;
- X $yoff += $height{$r};
- X }
- X printf(PARAM "%-40s %5d %5d %5d %5d\n", $n,
- X int(($widest - $width{$r}) / 2) + $xoff + $zx,
- X $yoff - $h + $zy,
- X $zw, $zh);
- X $xoff += $w;
- X }
- X
- X @rpqueue = ();
- X close(PARAM);
- X } else {
- X &warning("can't open $pfile: $!!\n");
- X }
- X }
- X $scount++;
- X &rm(@rqueue);
- X @rqueue = ();
- X}
- X
- X
- Xsub shell {
- X local($command) = @_;
- X
- X &tfadd($1) if ($command =~ /\s+>\s+(\S+)$/);
- X
- X if ($Verbose) {
- X &info($command);
- X } else {
- X $command = "($command) 2> /dev/null";
- X }
- X
- X system $command;
- X
- X if ($? & 255) {
- X &warning("`$command' was killed by signal: ", ($? & 127), '.',
- X ($? & 128) ? "core dumped." : '');
- X return 0;
- X } elsif ($status = ($? >> 8)) {
- X if ($status & 128) {
- X &cleanup;
- X &fatal("`$command' was terminated abnormally by signal: ",
- X ($status & 127));
- X } else {
- X &warning("`$command' terminated with exit status: $status");
- X return 0;
- X }
- X }
- X 1;
- X}
- X
- X
- Xsub skip {
- X &warning(@_, " Skipping.");
- X}
- X
- X
- Xsub tfadd {
- X local($file) = @_;
- X push(@tfie, $file) unless grep(/^$file$/, @tfie);
- X}
- X
- X
- Xsub tfdelete {
- X local($file) = @_;
- X @tfie = grep(!/^$file$/, @tfie);
- X}
- X
- X
- Xsub toppm {
- X local($input, $output, $shrink) = @_;
- X
- X local(@suffs) = split(/\./, $basename{$input});
- X shift @suffs;
- X
- X unless (@suffs) {
- X &skip("no extension on `$input'!");
- X return 0;
- X }
- X
- X if (@badext = grep(!defined($decode{$_}), @suffs)) {
- X &skip(sprintf('unknown extension%s (%s) on `%s\'!',
- X ((@badext > 1) ? 's' : ''), &cslist(@badext), $input));
- X return 0;
- X }
- X
- X local(@decodecmd) = grep($_, reverse @decode{@suffs});
- X
- X local($init) = (@decodecmd && ($decodecmd[0] =~ tr/|/|/) == 0) ?
- X (shift @decodecmd) . " '$input'" :
- X "cat '$input'";
- X
- X local($decodecmd);
- X if ($shrink) {
- X $decodecmd = join(' | ', ($init, @decodecmd, "$pnmscale > $output"));
- X &info("shrinking `$input'");
- X } else {
- X $decodecmd = join(' | ', ($init, @decodecmd)) . " > $output";
- X &info("expanding `$input'");
- X }
- X
- X unless (&shell($decodecmd)) {
- X &skip("can't decode `$input'!");
- X &rm($output);
- X return 0;
- X }
- X 1;
- X}
- X
- X
- Xsub usage {
- X die "usage: $program [options] [{image file | parameter file} ...]
- X[options] consists of:
- X-a, +a\t automatically size sheets to the size of the screen. default = ",
- X &on($d{'Auto'}), "
- X-B, +B\t put borders around each image. default = ", &on($d{'Borders'}), "
- X-b, +b\t take the basename of the filenames. default = ", &on($d{'Base'}), "
- X-c #\t number of columns of images in each sheet. default = $d{'Columns'}
- X-d dir\t put sheets in `dir'. default = `$d{'Dir'}'
- X-f str\t `str' is the file format of the sheets. default = `$d{'Format'}'
- X-F file\t font file for labels. default = `",
- X ($d{'Font'} || 'pbmtext\'s internal font'), "'
- X-g, +g\t generate parameter files for sheets. default = ", &on($d{'Param'}), "
- X-h #\t height of each small image in pixels. default = $d{'Height'}
- X-i, +i\t make images the same size. default = ", &on($d{'Ident'}), "
- X-K file\t use `file' as the configuration file. default = `",
- X ($d{'Config'} || '~/.icrc'), "'
- X-k, +k\t don't reference the configuration file. default = ",
- X &on($d{'Ignore'}), "
- X-l, +l\t put labels under the images. default = ", &on($d{'Labels'}), "
- X-n file\t get filenames from `file'. default = none
- X-O, +O\t find the number for the first sheet automatically. default = ",
- X &on($d{'AutoOff'}), "
- X-o #\t start at this number when naming sheets. default = $d{'Offset'}
- X-P suff\t suffix of parameter files. default = `$d{'Suffix'}'
- X-p name\t name of the sheets. default = `$d{'Prefix'}'
- X-q #\t number of colors in each sheet. default = $d{'Quant'}
- X-r #\t number of rows of images in each sheet. default = $d{'Rows'}
- X-S, +S\t sort all the filenames. default = ", &on($d{'Sort'}), "
- X-s, +s\t be silent. default = ", &on($d{'Silent'}), "
- X-t dir\t use `dir' to hold temporary files. default = `$d{'Tempdir'}'
- X-u, +u\t remove duplicate file names from file list. default = ",
- X &on($d{'Uniq'}), "
- X-v, +v\t be verbose. default = ", &on($d{'Verbose'}), "
- X-W, +W\t use a ", (!$d{'White'} ? "white" : "black"),
- X " background for the contact sheets. default = ",
- X ($d{'White'} ? "white" : "black"), "
- X-w #\t width of each small image in pixels. default = $d{'Width'}
- X-X, +X\t make images the same width. default = ", &on($d{'Ysame'}), "
- X-x #\t screen width in pixels. default = $d{'Xdim'}
- X-Y, +Y\t make images the same height. default = ", &on($d{'Ysame'}), "
- X-y #\t screen height in pixels. default = $d{'Ydim'}
- X";
- X}
- X
- X
- Xsub warning {
- X warn "$program: WARNING: ", @_, "\n";
- X}
- END_OF_FILE
- if test 28926 -ne `wc -c <'icontact'`; then
- echo shar: \"'icontact'\" unpacked with wrong size!
- fi
- chmod +x 'icontact'
- # end of 'icontact'
- fi
- echo shar: End of shell archive.
- exit 0
-
- exit 0 # Just in case...
-