home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume30 / icontact / part01 < prev    next >
Encoding:
Text File  |  1992-06-20  |  52.7 KB  |  1,705 lines

  1. Newsgroups: comp.sources.misc
  2. From: cs62a12@wind.ucsd.edu (Mark Hanson)
  3. Subject:  v30i077:  icontact - perl script to create contact sheets of images, v1.2, Part01/01
  4. Message-ID: <1992Jun21.041357.3409@sparky.imd.sterling.com>
  5. X-Md4-Signature: aba4191ef8cc40c7bf11344cb8f5f274
  6. Date: Sun, 21 Jun 1992 04:13:57 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: cs62a12@wind.ucsd.edu (Mark Hanson)
  10. Posting-number: Volume 30, Issue 77
  11. Archive-name: icontact/part01
  12. Environment: UNIX, perl, pbmplus
  13.  
  14. icontact-1.2 (14jun92)
  15.  
  16. This is the third release of icontact.  The only new features are the
  17. -k and -K options.  I have also cleaned up the code and the man page
  18. a bit.
  19.  
  20. I would appreciate hearing from you if you find icontact useful or have
  21. suggestions on how to make it better.  I only have access to a
  22. SPARCstation running SunOS 4.1.2, so icontact has only been tested in
  23. this environment.  If icontact fails in your environment, let me know
  24. so I can fix it.
  25.  
  26. Send all e-mail regarding icontact to cs62a12@wind.ucsd.edu.
  27.  
  28. Here is the DESCRIPTION section from the man page:
  29.  
  30.   icontact is a perl script that takes a bunch of image files and creates
  31.   contact sheets.  icontact determines the file format by the file name
  32.   extension of the input files and then uses internal tables to look up
  33.   the commands it needs to convert the images to the ppm format.  Once in
  34.   the ppm format, icontact uses various pbmplus commands to create the
  35.   contact sheets.  icontact is particularly useful if you have lots of
  36.   image files in all sorts of different formats and you want to create an
  37.   index of all of them without converting them all to a common format
  38.   first.
  39.  
  40.   icontact is highly configurable.  It can probably do anything you would
  41.   ever want this type of program to do - and more.  If you think of
  42.   additional features that would be useful for a program of this type to
  43.   do, tell me and I'll see what I can do.
  44.  
  45.   Besides perl, icontact requires the pbmplus package by Jef Poskanzer.
  46.   The Independent JPEG Group's package (cjpeg, djpeg) is also necessary
  47.   if you are going to be processing any JPEG files.  It should not be
  48.   difficult to add filters from other packages as long as there is a way
  49.   to go to and from the ppm format with them.
  50.  
  51. THANKS TO
  52. - Roger Hayes (roger.hayes@eng.sun.com)
  53.     for sending me an implementation of the -W option.
  54. - Larry W. Virden (lwv26@cas.org) 
  55.     for suggesting the -O option and the feature that allows you to take an
  56.     old contact sheet and add new images to it.
  57.  
  58. I hope you find icontact useful,
  59. mark
  60.  
  61. ---
  62. #! /bin/sh
  63. # This is a shell archive.  Remove anything before this line, then unpack
  64. # it by saving it into a file and typing "sh file".  To overwrite existing
  65. # files, type "sh file -c".  You can also feed this as standard input via
  66. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  67. # will see the following message at the end:
  68. #        "End of shell archive."
  69. # Contents:  README icontact.1 icontact
  70. # Wrapped by mark@eggman on Sun Jun 14 20:30:31 1992
  71. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  72. if test -f 'README' -a "${1}" != "-c" ; then 
  73.   echo shar: Will not clobber existing file \"'README'\"
  74. else
  75. echo shar: Extracting \"'README'\" \(2061 characters\)
  76. sed "s/^X//" >'README' <<'END_OF_FILE'
  77. Xicontact-1.2 (14jun92)
  78. X
  79. XThis is the third release of icontact.  The only new features are the
  80. X-k and -K options.  I have also cleaned up the code and the man page
  81. Xa bit.
  82. X
  83. XI would appreciate hearing from you if you find icontact useful or have
  84. Xsuggestions on how to make it better.  I only have access to a
  85. XSPARCstation running SunOS 4.1.2, so icontact has only been tested in
  86. Xthis environment.  If icontact fails in your environment, let me know
  87. Xso I can fix it.
  88. X
  89. XSend all e-mail regarding icontact to cs62a12@wind.ucsd.edu.
  90. X
  91. XHere is the DESCRIPTION section from the man page:
  92. X
  93. X  icontact is a perl script that takes a bunch of image files and creates
  94. X  contact sheets.  icontact determines the file format by the file name
  95. X  extension of the input files and then uses internal tables to look up
  96. X  the commands it needs to convert the images to the ppm format.  Once in
  97. X  the ppm format, icontact uses various pbmplus commands to create the
  98. X  contact sheets.  icontact is particularly useful if you have lots of
  99. X  image files in all sorts of different formats and you want to create an
  100. X  index of all of them without converting them all to a common format
  101. X  first.
  102. X
  103. X  icontact is highly configurable.  It can probably do anything you would
  104. X  ever want this type of program to do - and more.  If you think of
  105. X  additional features that would be useful for a program of this type to
  106. X  do, tell me and I'll see what I can do.
  107. X
  108. X  Besides perl, icontact requires the pbmplus package by Jef Poskanzer.
  109. X  The Independent JPEG Group's package (cjpeg, djpeg) is also necessary
  110. X  if you are going to be processing any JPEG files.  It should not be
  111. X  difficult to add filters from other packages as long as there is a way
  112. X  to go to and from the ppm format with them.
  113. X
  114. XTHANKS TO
  115. X- Roger Hayes (roger.hayes@eng.sun.com)
  116. X    for sending me an implementation of the -W option.
  117. X- Larry W. Virden (lwv26@cas.org) 
  118. X    for suggesting the -O option and the feature that allows you to take an
  119. X    old contact sheet and add new images to it.
  120. X
  121. XI hope you find icontact useful,
  122. Xmark
  123. END_OF_FILE
  124. if test 2061 -ne `wc -c <'README'`; then
  125.     echo shar: \"'README'\" unpacked with wrong size!
  126. fi
  127. # end of 'README'
  128. fi
  129. if test -f 'icontact.1' -a "${1}" != "-c" ; then 
  130.   echo shar: Will not clobber existing file \"'icontact.1'\"
  131. else
  132. echo shar: Extracting \"'icontact.1'\" \(17155 characters\)
  133. sed "s/^X//" >'icontact.1' <<'END_OF_FILE'
  134. X.nh
  135. X.TH ICONTACT 1 "icontact\-1.2 (14jun92)"
  136. X.SH NAME
  137. Xicontact \- create contact sheets from images of different formats
  138. X.SH SYNOPSIS
  139. X\fBicontact\fP [ \fIoptions\fP ] [ { \fIimage file\fP | \fIparameter
  140. Xfile\fP } ... ]
  141. X.SH DESCRIPTION
  142. X.PP
  143. X\fIicontact\fP is a \fIperl\fP script that takes a bunch of image files
  144. Xand creates contact sheets.  \fIicontact\fP determines the file format
  145. Xby the file name extension of the input files and then uses internal
  146. Xtables to look up the commands it needs to convert the images to the
  147. Xppm format.  Once in the ppm format, \fIicontact\fP uses various
  148. X\fIpbmplus\fP commands to create the contact sheets.  \fIicontact\fP is
  149. Xparticularly useful if you have lots of image files in all sorts of
  150. Xdifferent formats and you want to create an index of all of them
  151. Xwithout converting them all to a common format first.
  152. X.PP
  153. X\fIicontact\fP is highly configurable.  It can probably do anything you
  154. Xwould ever want this type of program to do \(em and more.  If you think
  155. Xof additional features that would be useful for a program of this type
  156. Xto do, tell me and I'll see what I can do.
  157. X.PP
  158. XBesides \fIperl\fP, \fIicontact\fP requires the \fIpbmplus\fP package
  159. Xby Jef Poskanzer.  The Independent JPEG Group's package (\fIcjpeg\fP,
  160. X\fIdjpeg\fP) is also necessary if you are going to be processing any
  161. XJPEG files.  It should not be difficult to add filters from other
  162. Xpackages as long as there is a way to go to and from the ppm format
  163. Xwith them.
  164. X.SH OPTIONS
  165. X.PP
  166. XSwitches that do not take arguments may be combined into a single
  167. Xswitch with other switches: \fB\-abBlv\fP.  Switches that take
  168. Xarguments must be followed by their arguments with a space in between:
  169. X\fB\-c\ 10\ \-r\ 5\fP.  The fancy way combine all these switches is:
  170. X\fB\-abBlvc\ 10\ \-r\ 5\fP.  That is, you can combine the switches
  171. Xtogether in any way you like so long as the switches that take an
  172. Xargument are followed by said argument with a space in between.  If you
  173. Xdon't want to get fancy, just specify each switch by itself:
  174. X\fB\-a\ \-b\ \-B\ \-c\ 10\ \-l\ \-r\ 5\ \-v\fP.
  175. X.\"
  176. X.PP
  177. XIn all cases in which a switch does not take an argument,
  178. X\fB\-switch\fP will turn the switch on, and \fB+switch\fP will turn the
  179. Xswitch off.  For example, \fB\-l\fP will turn labels on, and \fB+l\fP
  180. Xwill turn labels off.  This can be useful if you have a particular set
  181. Xof switches set in a configuration file and you want to temporarily
  182. Xdisable a switch to make a sheet without changing the configuration
  183. Xfile.  If a set of switches are combined into a single switch that
  184. Xleads with either a \fB+\fP or a \fB\-\fP, the \fB+\fP or \fB\-\fP
  185. Xaffects all the switches in that set of switches.  If a switch that
  186. Xtakes an argument is specified with a leading \fB+\fP, it is assumed
  187. Xthat you meant \fB\-\fP.
  188. X.\"
  189. X.PP
  190. XAn argument of \fB\-\-\fP terminates the options list and signals the
  191. Xbeginning of the file list.
  192. X.\"
  193. X.PP
  194. XSwitches can be specified in two places: the command line and a
  195. Xconfiguration file.  The command line switches are the most potent \(em
  196. Xthey override everything.  The switches in a configuration file are the
  197. Xnext most potent \(em they are only overridden by the command line
  198. Xswitches.  The internal defaults of \fIicontact\fP are overridden by
  199. Xboth the command line and configuration file.
  200. X.\"
  201. X.IP \fB\(+-a\fP
  202. XMake the output sheets fit into the size specified with the \fB\-x\fP
  203. Xand \fB\-y\fP switches.  Setting the \fB\-x\fP and \fB\-y\fP switches
  204. Xto the size of your screen will yield contact sheets which are no
  205. Xlarger than your screen.  The \fB\-r\fP and \fB\-c\fP switches will be
  206. Xignored if the \fB\-a\fP switch is present because the number of rows
  207. Xand columns is figured out dynamically and will probably change from
  208. Xsheet to sheet unless the \fB\-i\fP switch is specified or all the
  209. Xsource images are of the same size to begin with.
  210. X.\"
  211. X.IP \fB\(+-B\fP
  212. XAdd a border to each image in the contact sheet.  This will make each
  213. Ximage in the contact sheets 6 pixels larger in both width and height.
  214. XIf the background is white, the border will be white\-black\-white.  If
  215. Xit is black, it will be black\-white\-black.  The background color may
  216. Xbe selected with the \fB\-W\fP switch.
  217. X.\"
  218. X.IP \fB\(+-b\fP
  219. XUse the \fIbasename(1)\fP of the file name instead of the whole path
  220. Xname to the file in labels.  This switch will be ignored if the
  221. X\fB\-l\fP switch is not specified.
  222. X.\"
  223. X.IP "\fB\-c\fP \fIn\fP"
  224. XMake the contact sheets with \fIn\fP columns of images.  This switch is
  225. Xignored if the \fB\-a\fP switch is specified.  The default value is 7.
  226. X.\"
  227. X.IP "\fB\-d\fP \fIdir\fP"
  228. XPut the contact sheets in \fIdir\fP when completed.  The default value
  229. Xis ``.''.
  230. X.\"
  231. X.IP "\fB\-F\fP \fIfile\fP"
  232. X\fIfile\fP will be used with \fIpbmtext\fP as a font for labels.  Each
  233. Ximage's height will be increased by the height of the characters in the
  234. Xfont.  This switch will be ignored if the \fB\-l\fP switch is not
  235. Xspecified.  By default, \fIpbmtext\fP's internal font is used.
  236. X.\"
  237. X.IP "\fB\-f\fP \fIformat\fP"
  238. XEncode the finished contact sheets in \fIformat\fP.  The default value
  239. Xis ``.ppm.Z''.
  240. X.\"
  241. X.IP \fB\(+-g\fP
  242. XGenerate a parameter file for each contact sheet produced.  This
  243. Xparameter file will be named \fIprefix###.format.suffix\fP, where
  244. X\fIprefix\fP is the contact sheet name, \fI###\fP is the number of the
  245. Xcontact sheet, \fIformat\fP is the file format of the contact sheet,
  246. Xand \fIsuffix\fP is the parameter file suffix specified with the
  247. X\fB\-P\fP option.  When \fIicontact\fP sees one of these files on the
  248. Xcommand line, it looks in the parameter file for the names and
  249. Xlocations of images inside the sheet specified by removing the
  250. X\fIsuffix\fP from the parameter file name.  These images will be cut
  251. Xout and put in the new output sheets instead of being fully processed
  252. Xagain.  For best results when using parameter files on the command
  253. Xline, select no quantization and a lossless file format both when the
  254. Xsheet is first created and also when its parameter file is used on the
  255. Xcommand line.  This will prevent information loss if this operation is
  256. Xperformed multiple times.
  257. X.\"
  258. X.IP "\fB\-h\fP \fIn\fP"
  259. XMake each image in the contact sheets a maximum of \fIn\fP pixels
  260. Xhigh.  The aspect ratio of the images will not be changed.  This switch
  261. Xwill be ignored if the \fB\-X\fP switch is also specified.  The default
  262. Xvalue is 100.
  263. X.\"
  264. X.IP \fB\-help\fP
  265. XThis is a special case which will print out a help message explaining
  266. X\fIicontact\fP's options.  Any other unrecognized switch will do the
  267. Xsame.
  268. X.\"
  269. X.IP \fB\(+-i\fP
  270. XMake all of the images the same size.  The size of the images is
  271. Xdetermined by the dimensions specified with the \fB\-w\fP and \fB\-h\fP
  272. Xswitches.  Use of this switch can create contact sheets with lots of
  273. Xblank space between images.  This switch cannot be used with the
  274. X\fB\-X\fP or \fB\-Y\fP switches.
  275. X.\"
  276. X.IP "\fB\-K\fP \fIfile\fP"
  277. XUse \fIfile\fP as the configuration file.  The default configuration
  278. Xfile name is ``~/.icrc''.  Putting this option in the configuration
  279. Xfile will have no effect since once you're in it, it's too late to
  280. Xswitch to another one.
  281. X.\"
  282. X.IP \fB\(+-k\fP
  283. XDon't reference the configuration file.  Putting this option in the
  284. Xconfiguration file will have no effect since once you're in the
  285. Xconfiguration file, it's too late to back out.
  286. X.\"
  287. X.IP \fB\(+-l\fP
  288. XAttach a label containing the image's file name below each image.  This
  289. Xname may be truncated if the label is wider than the image.  The
  290. Xbehavior of this switch can be changed with the \fB\-b\fP and \fB\-F\fP
  291. Xswitches.
  292. X.\"
  293. X.IP "\fB\-n\fP \fIfile\fP"
  294. XTake the file names from \fIfile\fP and add them to the ones specified
  295. Xon the command line, if any.  The file names in \fIfile\fP must be one
  296. Xper line.  These file names will be processed after the file names
  297. Xspecified on the command line.
  298. X.\"
  299. X.IP \fB\(+-O\fP
  300. XFind the number for the first sheet by looking in the destination
  301. Xdirectory for sheets with the same prefix and format that we are going
  302. Xto create.  Take the highest numbered one, increment, and this is the
  303. Xnew starting number for the new sheets.  If there are no files with the
  304. Xsame prefix and format in the destination directory, the new sheets
  305. Xwill start with 001.  This switch cannot be used with the \fB\-o\fP
  306. Xswitch.
  307. X.\"
  308. X.IP "\fB\-o\fP \fIn\fP"
  309. XThe output sheet numbering will begin with \fIn\fP and increase from
  310. Xthere.  This switch cannot be used with the \fB\-O\fP switch.  The
  311. Xdefault value is 001.
  312. X.\"
  313. X.IP "\fB\-P\fP \fIsuffix\fP"
  314. X\fIsuffix\fP will be used as the extension of the contact sheet
  315. Xparameter files if the \fB\-g\fP switch is specified.  See the
  316. X\fB\-g\fP switch description for more details.  The default value is
  317. X``.icp''.
  318. X.\"
  319. X.IP "\fB\-p\fP \fIprefix\fP"
  320. XName the contact sheets \fIprefix###.format\fP, where \fI###\fP is the
  321. Xnumber of the contact sheet and \fIformat\fP is the format of the
  322. Xcontact sheet.  The default value is ``ic\-''.
  323. X.\"
  324. X.IP "\fB\-q\fP \fIn\fP"
  325. XQuantize the contact sheets down to \fIn\fP colors.  A value of 0 will
  326. Xturn off quantization.  The default value is 0.
  327. X.\"
  328. X.IP "\fB\-r\fP \fIn\fP"
  329. XMake the contact sheets with \fIn\fP rows of images.  This switch is
  330. Xignored if the \fB\-a\fP switch is specified.  The default value is 7.
  331. X.\"
  332. X.IP \fB\(+-S\fP
  333. XSort the file names taken from the command line (and, optionally, from
  334. Xthe file specified with the \fB\-n\fP switch) into alphabetical order
  335. Xbefore making the sheet.
  336. X.\"
  337. X.IP \fB\(+-s\fP
  338. XDon't output anything except warnings and fatal errors.
  339. X.\"
  340. X.IP "\fB\-t\fP \fItempdir\fP"
  341. XUse \fItempdir\fP to hold \fIicontact\fP's intermediate files.
  342. X\fIicontact\fP tries to minimize the amount of temporary space it
  343. Xneeds, but it's disk space requirements can be large depending upon the
  344. Xparticular operation it is performing.  If you have a tiny /tmp
  345. Xdirectory, you'll want to use this option to aim \fIicontact\fP at a
  346. Xlarger chunk of disk.  The default value is ``/tmp''.
  347. X.\"
  348. X.IP \fB\(+-u\fP
  349. XDelete duplicate entries in the list of image file names.  The first
  350. Xfile with any particular name will make it through, but following files
  351. Xwith the same name will be deleted from the file name list.  The
  352. Xdefault it to allow duplicate file names.
  353. X.\"
  354. X.IP \fB\(+-v\fP
  355. XCause all sorts of possibly interesting output to be printed to the
  356. Xscreen.  The output includes the current parameters of \fIicontact\fP
  357. Xand all the shell commands it is running.  If you're having difficulty
  358. Xgetting \fIicontact\fP to do what you want it to do, try using this
  359. Xswitch to see what \fIicontact\fP is doing behind your back.
  360. X.\"
  361. X.IP "\fB\-W\fP \fIn\fP"
  362. XMake the background white instead of black, which is the default.  If
  363. Xyou are printing your contact sheets on a laser printer, this will save
  364. Xyour toner cartridge.
  365. X.\"
  366. X.IP "\fB\-w\fP \fIn\fP"
  367. XMake each image in the contact sheets a maximum of \fIn\fP pixels
  368. Xwide.  The aspect ratio of the images will not be changed.  This switch
  369. Xwill be ignored if the \fB\-Y\fP switch is also specified.  The default
  370. Xvalue is 100.
  371. X.\"
  372. X.IP \fB\(+-X\fP
  373. XThis switch will make all the images the same width.  Their heights
  374. Xwill be whatever they are when the image comes out of \fIpnmscale\fP.
  375. XThe aspect ratios of the images will not be changed.  Wide images will
  376. Xbe short and tall images will be tall.  This switch cannot be used with
  377. Xthe \fB\-i\fP or \fB\-Y\fP switches.
  378. X.\"
  379. X.IP "\fB\-x\fP \fIn\fP"
  380. XWhen used with the \fB\-a\fP switch, \fIn\fP specifies the width of the
  381. Xoutput sheets in pixels.  This switch will be ignored unless the
  382. X\fB\-a\fP switch is specified.  The default value is 1152.
  383. X.\"
  384. X.IP \fB\(+-Y\fP
  385. XThis switch will make all the images the same height.  Their widths
  386. Xwill be whatever they are when the image comes out of \fIpnmscale\fP.
  387. XWide images will be wide and tall images will be skinny.  The aspect
  388. Xratios of the images will not be changed.  This switch cannot be used
  389. Xwith the \fB\-i\fP or \fB\-X\fP switches.
  390. X.\"
  391. X.IP "\fB\-y\fP \fIn\fP"
  392. XWhen used with the \fB\-a\fP switch, \fIn\fP specifies the height of
  393. Xthe output sheets in pixels.  This switch will be ignored unless the
  394. X\fB\-a\fP switch is specified.  The default value is 900.
  395. X.\"
  396. X.SH ENVIRONMENT
  397. X.IP "\fBTMPDIR, TEMPDIR\fP"
  398. XThese environment variables can be used to set the location of
  399. X\fIicontact\fP's temporary directory.  If both \fBTMPDIR\fP and
  400. X\fBTEMPDIR\fP are set, a warning will be printed and the value of
  401. X\fBTMPDIR\fP will be used.  If only one of them is set, that one will
  402. Xbe used.  This value will be overridden if the \fB\-t\fP switch is used
  403. Xon the command line or in the configuration file.
  404. X.\"
  405. X.SH FILES
  406. X.IP "configuration file"
  407. XThe name of the default configuration file is \fB.icrc\fP in your home
  408. Xdirectory.  The proper syntax of this file is as follows:  Comments
  409. Xbegin with a \fB#\fP and terminate with a newline.  Lines may be
  410. Xblank.  Configuration lines begin with one of the following keywords:
  411. X\fBencode\fP, \fBdecode\fP, \fBswitches\fP, or \fBquantize\fP.  Lines
  412. Xbeginning with \fBencode\fP are used to define commands \fIicontact\fP
  413. Xwill use to encode files into a specific format.  Lines beginning with
  414. X\fBdecode\fP are used to define commands \fIicontact\fP will use to
  415. Xdecode files of a specific format.  Lines beginning with \fBquantize\fP
  416. Xare used to define the quantization value of sheets created in a
  417. Xspecific format.  The format of lines beginning with \fBencode\fP,
  418. X\fBdecode\fP or \fBquantize\fP is this:
  419. X.sp
  420. X.ce
  421. X<\fIkeyword\fP>\ <\fIformat\fP>\ <\fIvalue\fP>
  422. X.sp
  423. X<\fIformat\fP> may not contain whitespace, but <\fIvalue\fP> may.  If
  424. X<\fIkeyword\fP> is \fBquantize\fP, then <\fIvalue\fP> must be a non
  425. Xnegative integer.  The format of lines beginning with \fBswitches\fP is
  426. Xthis:
  427. X.sp
  428. X.ce
  429. X\fBswitches\fP\ <\fIcommand\ line\ switches\fP>
  430. X.sp
  431. X<\fIcommand\ line\ switches\fP> may be any set of switches that you can
  432. Xspecify on the command line and may contain whitespace.
  433. X.sp
  434. X.nf
  435. X.in +0.5i
  436. X.ft CW
  437. X# sample icontact configuration file
  438. X
  439. Xswitches    -g      # parameter file generation
  440. Xswitches    -B      # borders
  441. Xswitches    -l      # add labels
  442. Xswitches    -b      # basename(1) the labels
  443. Xswitches    -S      # sort all the filenames
  444. Xswitches    -v      # verbose
  445. Xswitches    -W      # white background
  446. Xswitches    -a      # automatic sizing
  447. Xswitches    -x 640  # screen width
  448. Xswitches    -y 480  # screen height
  449. X# OR:
  450. X# switches    -gBlBSvWax 640 -y 480     # everything
  451. X
  452. Xencode      jpg     cjpeg -o
  453. Xdecode      jpg     djpeg
  454. X
  455. Xencode      ppm     
  456. Xdecode      ppm     
  457. X
  458. Xquantize    gif     256
  459. Xquantize    jpg     0
  460. X.ft R
  461. X.in -0.5i
  462. X.sp
  463. X.fi
  464. X.\"
  465. X.IP "contact sheet parameter files"
  466. XThese files are lists of file names (one per line) followed by the
  467. Ximage's \fIx\fP and \fIy\fP offsets into the contact sheet and then the
  468. Ximage's height and width.  They are created by using the \fB\-g\fP
  469. Xoption.  These files allow blank lines and comments beginning with
  470. X\fB#\fP and terminating with a newline.
  471. X.\"
  472. X.IP \fBTMPDIR/icb\-$$\fP
  473. Xa temporary file for storing the border if the \fB\-i\fP and \fB\-B\fP
  474. Xswitches are specified
  475. X.\"
  476. X.IP \fBTMPDIR/ici#\-$$\fP
  477. Xtemporary files for storing images before they are made into rows
  478. X.\"
  479. X.IP \fBTMPDIR/icp#\-$$\fP
  480. Xtemporary files for holding expanded sheets while \fIicontact\fP cuts
  481. Ximages out of them
  482. X.\"
  483. X.IP \fBTMPDIR/icr#\-$$\fP
  484. Xtemporary files for storing rows before they are made into sheets
  485. X.\"
  486. X.IP \fBTMPDIR/ict\-$$\fP
  487. Xa temporary file for storing labels and borders
  488. X.\"
  489. X.SH "SEE ALSO"
  490. X\fIbasename(1)\fP, \fIperl(1)\fP, \fIpbm(5)\fP, \fIpgm(5)\fP,
  491. X\fIppm(5)\fP, \fIcjpeg(1)\fP, \fIdjpeg(1)\fP
  492. X.\"
  493. X.SH DIAGNOSTICS
  494. XThe diagnostic messages are intended to be self explanatory.
  495. X.\"
  496. X.SH BUGS
  497. X.PP
  498. XIf a file name has ``.''s in it that do not come before a valid file
  499. Xformat extension, the file will be skipped because \fIicontact\fP will
  500. Xnot be able to find decode commands in it's internal tables.
  501. X.PP
  502. X\fIicontact\fP allows you to specify stupid output formats like
  503. X``.gif.Z''.
  504. X.PP
  505. XWhen in automatic sheet sizing mode (\fB\-a\fP), if a processed image
  506. Xis larger than the dimensions of a sheet, this image will appear in a
  507. Xsheet all by itself, and the sheet will be larger than you specified
  508. Xwith \fB\-x\fP and \fB\-y\fP.
  509. X.PP
  510. X\fIicontact\fP will most likely fail if it is used on filenames that
  511. Xcontain whitespace.
  512. X.PP
  513. XWhen images are cut out of previously made contact sheets by specifying
  514. Xa parameter file on the command line, they are not rescaled.  So, even
  515. Xthough you may have specified \fB\-w 100 \-h 100\fP this time, the
  516. Ximages cut from the previously made contact sheet will be the same size
  517. Xthey were when that sheet was made.  This shouldn't be a problem for
  518. Xyou if you choose an image size early and stick with it.
  519. X.\"
  520. X.SH AUTHOR
  521. XMark Hanson
  522. X.br
  523. X8693 Via Mallorca #15
  524. X.br
  525. XLa Jolla, CA 92037\-2575
  526. X.br
  527. Xcs62a12@wind.ucsd.edu
  528. X.sp
  529. XBug reports, patches, suggestions, questions, and money are all
  530. Xwelcome.
  531. X.sp
  532. X\fIicontact\fP is:
  533. X.br
  534. XCopyright (C) 1992 Mark B. Hanson
  535. X.br
  536. XPermission to use, copy, modify, and distribute this software and its
  537. Xdocumentation for any purpose and without fee is hereby granted,
  538. Xprovided that both the above copyright notice and this permission
  539. Xnotice appear in all copies and in supporting documentation.  This
  540. Xsoftware is provided "as is" without express or implied warranty.
  541. END_OF_FILE
  542. if test 17155 -ne `wc -c <'icontact.1'`; then
  543.     echo shar: \"'icontact.1'\" unpacked with wrong size!
  544. fi
  545. # end of 'icontact.1'
  546. fi
  547. if test -f 'icontact' -a "${1}" != "-c" ; then 
  548.   echo shar: Will not clobber existing file \"'icontact'\"
  549. else
  550. echo shar: Extracting \"'icontact'\" \(28926 characters\)
  551. sed "s/^X//" >'icontact' <<'END_OF_FILE'
  552. X#!/usr/local/bin/perl
  553. X
  554. X# Copyright (C) 1992 Mark B. Hanson
  555. X# Permission to use, copy, modify, and distribute this software and its
  556. X# documentation for any purpose and without fee is hereby granted, provided
  557. X# that both the above copyright notice and this permission notice appear in all
  558. X# copies and in supporting documentation.  This software is provided "as is"
  559. X# without express or implied warranty.
  560. X
  561. X$program = 'icontact';
  562. X$version = '1.2 (14jun92)';
  563. X$copyright = 'Copyright (C) 1992';
  564. X$author = 'Mark B. Hanson (cs62a12@wind.ucsd.edu)';
  565. X
  566. X
  567. X#
  568. X# default values for parameters that correspond to command line switches
  569. X#
  570. X# Leave these alone if you want them to match the man page.
  571. X# Use a configuration file to customize icontact to your liking.
  572. X#
  573. X
  574. X$AutoOff = 0;       # boolean,  0 = sheet numbers start with 0
  575. X            #           1 = start with next highest number in dest. dir.
  576. X$Auto = 0;          # boolean,  0 = use $Columns and $Rows
  577. X            #           1 = dynamically sized to $Xdim, $Ydim
  578. X$Base = 0;          # boolean,  0 = display whole filename in labels 
  579. X            #           1 = display basename of filenames in labels 
  580. X$Borders = 0;       # boolean,  0 = no spiffy borders around each image
  581. X            #           1 = spiffy borders around each image
  582. X$Ignore = 0;        # boolean,  0 = use configuration file
  583. X            #           1 = don't use configuration file
  584. X$Ident = 0;         # boolean,  0 = don't pad images, just scale them
  585. X            #           1 = pad each image to be the same size
  586. X$Labels = 0;        # boolean,  0 = no labels
  587. X            #           1 = labels
  588. X$Param = 0;         # boolean,  0 = no parameter files for sheets
  589. X            #           1 = generate parameter files for sheets
  590. X$Silent = 0;        # boolean,  0 = normal output
  591. X            #           1 = no output except warnings and errors
  592. X$Sort = 0;          # boolean,  0 = don't sort filenames
  593. X            #           1 = sort filenames
  594. X$Uniq = 0;          # boolean,  0 = leave duplicates in file list
  595. X            #           1 = remove duplicates from file list
  596. X$Verbose = 0;       # boolean,  0 = normal output
  597. X            #           1 = show execution
  598. X$White = 0;         # boolean,  0 = black background
  599. X            #           1 = white background
  600. X$Xsame = 0;         # boolean,  0 = don't make all the images the same width
  601. X            #           1 = make all the images the same width
  602. X$Ysame = 0;         # boolean,  0 = don't make all the images the same height
  603. X            #           1 = make all the images the same height
  604. X
  605. X$Columns = 7;       # n > 0,    number of columns in sheets (!auto mode)
  606. X$Rows = 7;          # n > 0,    number of rows in sheets (!auto mode)
  607. X
  608. X$Xdim = 1152;       # n > 0,    width of max sheet size (auto mode)
  609. X$Ydim = 900;        # n > 0,    height of max sheet size (auto mode)
  610. X
  611. X$Width = 100;       # n > 0,    max width of each image
  612. X$Height = 100;      # n > 0,    max height of each image
  613. X
  614. X$Config = '';       # string,   name of an alternate configuration file
  615. X
  616. X$Dir =  '.';        # string,   directory to put finished sheets in
  617. X
  618. X$Prefix = 'ic-';    # string,   prefix for filename of sheets
  619. X
  620. X$Offset = 1;        # n > 0,    start at n when numbering the sheets
  621. X
  622. X$Tempdir = '/tmp';  # string,   directory to use for temporary files
  623. X
  624. X$Font = '';         # string,   name of a file to use as a font with pbmtext
  625. X
  626. X$Format = '.ppm.Z'; # string,   the format in which sheets are to be encoded
  627. X
  628. X$Namefile = '';     # string,   name of a file from which to get more filenames
  629. X
  630. X$Suffix = '.icp';   # string,   suffix of parameter files
  631. X
  632. X$Quant = 0;         # n >= 0,   number of colors to be left in sheets
  633. X            #           a value of 0 means no quantization
  634. X
  635. X
  636. X#
  637. X# The tables below are filled with common examples that I typed in to save
  638. X# you some time and to give you a feel for how icontact decides how to
  639. X# {en,de}code files.  Don't worry if your particular set of favorite programs
  640. X# and file name extensions is not listed here.  Like it says in the man
  641. X# page: `icontact is highly configurable.'  Use a configuration file to make
  642. X# icontact use any set of programs and filename extensions you want.
  643. X#
  644. X
  645. X#
  646. X# associative array to go from file suffix -> ppm.
  647. X#
  648. X
  649. X%decode = (
  650. X    'Z',        'trap \'exit 130\' 2; zcat',
  651. X    'atk',      'atktopbm',
  652. X    'brush',    'brushtopbm',
  653. X    'cmuwm',    'cmuwmtopbm',
  654. X    'fits',     'fitstopgm',
  655. X    'fs',       'fstopgm',
  656. X    'g3',       'g3topbm',
  657. X    'gem',      'gemtopbm',
  658. X    'gif',      'giftoppm',
  659. X    'gould',    'gouldtoppm',
  660. X    'hips',     'hipstopgm',
  661. X    'icon',     'icontopbm',
  662. X    'ilbm',     'ilbmtoppm',
  663. X    'jpg',      'djpeg',
  664. X    'lispm',    'lispmtopgm',
  665. X    'macp',     'macptopbm',
  666. X    'mgr',      'mgrtopbm',
  667. X    'mtv',      'mtvtoppm',
  668. X    'pbm',      '',
  669. X    'pcx',      'pcxtoppm',
  670. X    'pgm',      '',
  671. X    'pi1',      'pi1toppm',
  672. X    'pi3',      'pi3toppm',
  673. X    'pict',     'picttoppm',
  674. X    'pj',       'pjtoppm',
  675. X    'ppm',      '',
  676. X    'qrt',      'qrttoppm',
  677. X    'rast',     'rasttopnm',
  678. X    'spc',      'spctoppm',
  679. X    'spu',      'sputoppm',
  680. X    'tga',      'tgatoppm',
  681. X    'tiff',     'tifftopnm',
  682. X    'xbm',      'xbmtopbm',
  683. X    'xim',      'ximtoppm',
  684. X    'xpm',      'xpmtoppm',
  685. X    'xwd',      'xwdtopnm',
  686. X    'ybm',      'ybmtopbm',
  687. X    'yuv',      'yuvtoppm',
  688. X);
  689. X
  690. X
  691. X#
  692. X# associative array to go from ppm -> file suffix.
  693. X#
  694. X
  695. X%encode = (
  696. X    '10x',      'ppmtopgm | pgmtopbm | pbmto10x',
  697. X    'Z',        '(compress -v -f; exit 0)',
  698. X    'ascii',    'ppmtopgm | pgmtopbm | pbmtoascii',
  699. X    'atk',      'ppmtopgm | pgmtopbm | pbmtoatk',
  700. X    'bbnbg',    'ppmtopgm | pgmtopbm | pbmtobbnbg',
  701. X    'cmuwm',    'ppmtopgm | pgmtopbm | pbmtocmuwm',
  702. X    'epson',    'ppmtopgm | pgmtopbm | pbmtoepson',
  703. X    'fits',     'ppmtopgm | pgmtofits',
  704. X    'fs',       'ppmtopgm | pgmtofs',
  705. X    'g3',       'ppmtopgm | pgmtopbm | pbmtog3',
  706. X    'gem',      'ppmtopgm | pgmtopbm | pbmtogem',
  707. X    'gif',      'ppmtogif',
  708. X    'go',       'ppmtopgm | pgmtopbm | pbmtogo',
  709. X    'icon',     'ppmtopgm | pgmtopbm | pbmtoicon',
  710. X    'icr',      'ppmtoicr',
  711. X    'ilbm',     'ppmtoilbm',
  712. X    'jpg',      'cjpeg -o',
  713. X    'lispm',    'ppmtopgm | pgmtolispm',
  714. X    'lj',       'ppmtopgm | pgmtopbm | pbmtolj',
  715. X    'macp',     'ppmtopgm | pgmtopbm | pbmtomacp',
  716. X    'mgr',      'ppmtopgm | pgmtopbm | pbmtomgr',
  717. X    'pbm',      'ppmtopgm | pgmtopbm',
  718. X    'pcx',      'ppmtopcx',
  719. X    'pgm',      'ppmtopgm',
  720. X    'pi1',      'ppmtopi1',
  721. X    'pi3',      'ppmtopgm | pgmtopbm | pbmtopi3',
  722. X    'pict',     'ppmtopict',
  723. X    'pj',       'ppmtopj',
  724. X    'plot',     'ppmtopgm | pgmtopbm | pbmtoplot',
  725. X    'ppm',      '',
  726. X    'ps',       'pnmtops',
  727. X    'ptx',      'ppmtopgm | pgmtopbm | pbmtoptx',
  728. X    'puzz',     'ppmtopuzz',
  729. X    'rast',     'pnmtorast',
  730. X    'sixel',    'ppmtosixel',
  731. X    'tga',      'ppmtotga',
  732. X    'tiff',     'pnmtotiff',
  733. X    'uil',      'ppmtouil',
  734. X    'x10bm',    'ppmtopgm | pgmtopbm | pbmtox10bm',
  735. X    'xbm',      'ppmtopgm | pgmtopbm | pbmtoxbm',
  736. X    'xpm',      'ppmtoxpm',
  737. X    'xwd',      'pnmtoxwd',
  738. X    'ybm',      'ppmtopgm | pgmtopbm | pbmtoybm',
  739. X    'yuv',      'ppmtoyuv',
  740. X    'zinc',     'ppmtopgm | pgmtopbm | pbmtozinc',
  741. X);
  742. X
  743. X
  744. X#
  745. X# default quantization values based upon output file suffix.
  746. X# if a format's default quant value is the default for the -q switch
  747. X# ($Quant), don't bother listing it.
  748. X#
  749. X
  750. X%defquant = (
  751. X    'gif',      256,
  752. X);
  753. X
  754. X
  755. X#
  756. X# mapping from command line switches to internal variable names
  757. X#
  758. X
  759. X%optvar = (
  760. X    'a', 'Auto',    'B', 'Borders', 'b', 'Base',    'c', 'Columns',
  761. X    'd', 'Dir',     'F', 'Font',    'f', 'Format',  'g', 'Param',
  762. X    'h', 'Height',  'i', 'Ident',   'K', 'Config',  'k', 'Ignore',
  763. X    'l', 'Labels',  'n', 'Namefile','O', 'AutoOff', 'o', 'Offset',
  764. X    'P', 'Suffix',  'p', 'Prefix',  'q', 'Quant',   'r', 'Rows',
  765. X    'S', 'Sort',    's', 'Silent',  't', 'Tempdir', 'u', 'Uniq',
  766. X    'v', 'Verbose', 'W', 'White',   'w', 'Width',   'X', 'Xsame',
  767. X    'x', 'Xdim',    'Y', 'Ysame',   'y', 'Ydim',
  768. X);
  769. X
  770. X
  771. X# ---------------------------- end of definitions -----------------------------
  772. X
  773. X
  774. X#
  775. X# keep track of the default settings for the usage message
  776. X#
  777. X
  778. Xfor (values(%optvar)) {
  779. X    $d{$_} = eval "\$$_";
  780. X}
  781. X
  782. X
  783. X#
  784. X# tell the public who's responsible for this mess...
  785. X#
  786. X
  787. X&info("$program-$version $copyright $author") if $Verbose;
  788. X
  789. X
  790. X#
  791. X# assign $Tempdir
  792. X#
  793. X
  794. Xif ($ENV{'TMPDIR'} && $ENV{'TEMPDIR'}) {
  795. X    &warning("both TMPDIR and TEMPDIR are set.  Using TMPDIR.");
  796. X    $Tempdir = $ENV{'TMPDIR'};
  797. X} else {
  798. X    # if neither environment variable is set, set it to itself
  799. X    $Tempdir = $ENV{'TMPDIR'} || $ENV{'TEMPDIR'} || $Tempdir;
  800. X}
  801. X
  802. X
  803. X#
  804. X# evaluate arguments before processing the configuration file
  805. X# to get the -k and -K options
  806. X#
  807. X
  808. X&evalargs(@ARGV);
  809. X
  810. X
  811. X#
  812. X# process the configuration file
  813. X#
  814. X
  815. Xunless ($Ignore) {
  816. X    local($home) = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($<))[7];
  817. X    local($cfile) = $Config || ($home && "$home/.icrc");
  818. X
  819. X    if ($cfile) {
  820. X    if (-f $cfile) {
  821. X        if (-e _) {
  822. X        if (open(CONFIG, "<$cfile")) {
  823. X            local($v, $f, $c, $line, @switches);
  824. X            for ($line = 1; $_ = <CONFIG>; $line++) {
  825. X            next if /^\s*#/ || /^\s*$/;
  826. X            s/#.*$//;
  827. X            if (($f, $v) = /^\s*quantize\s+(\S+)\s+(\d+)\s*$/) {
  828. X                $f =~ s/^\.//;
  829. X                $defquant{$f} = $v;
  830. X            } elsif (($f, $c) = /^\s*encode\s+(\S+)\s+(.*)\s*$/) {
  831. X                $f =~ s/^\.//;
  832. X                $encode{$f} = $c;
  833. X            } elsif (($f, $c) = /^\s*decode\s+(\S+)\s+(.*)\s*$/) {
  834. X                $f =~ s/^\.//;
  835. X                $decode{$f} = $c;
  836. X            } elsif (/^\s*switches\s+(.+)\s*$/) {
  837. X                @switches = split(/\s+/, $1);
  838. X                while (@switches = &evalargs(@switches)) {
  839. X                &warning('Ignoring `', shift @switches,
  840. X                    "' on line $line of $cfile");
  841. X                }
  842. X            } else {
  843. X                &warning("can't understand line $line of `$cfile'");
  844. X            }
  845. X            }
  846. X            close CONFIG;
  847. X        } else {
  848. X            &warning("can't open `$cfile': $!!");
  849. X        }
  850. X        }
  851. X    } else {
  852. X        &warning("`$cfile' is not a file!  Configuration file not used.");
  853. X    }
  854. X    } else {
  855. X    &warning("can't find your home directory!",
  856. X        'Configuration file not found.');
  857. X    }
  858. X}
  859. X
  860. X
  861. X#
  862. X# evaluate arguments after processing the configuration file
  863. X# (yeah, this is sort of ugly.)
  864. X#
  865. X
  866. X@ARGV = &evalargs(@ARGV);
  867. X
  868. X
  869. X#
  870. X# sanity checks (fatal)
  871. X#
  872. X
  873. X&fatal("no files specified!") unless @ARGV;
  874. X
  875. Xforeach $switch ('c', 'h', 'r', 'w', 'x', 'y') {
  876. X    $num = eval "\$$optvar{$switch}";
  877. X    if ($num !~ /^\d+$/ || $num < 1) {
  878. X    &fatal("-$switch argument must be a positive integer!");
  879. X    }
  880. X}
  881. X
  882. Xforeach $switch ('o', 'q') {
  883. X    $num = eval "\$$optvar{$switch}";
  884. X    if ($num !~ /^\d+$/ || $num < 0) {
  885. X    &fatal("-$switch argument must be non-negative integer!");
  886. X    }
  887. X}
  888. X
  889. Xforeach ($Tempdir, $Dir) {
  890. X    $_ = '/' unless $_;
  891. X    &fatal("directory `$_' does not exist!") unless -e $_;
  892. X    &fatal("`$_' is not a directory!") unless -d _;
  893. X    &fatal("read permission denied on `$_'!") unless -r _;
  894. X    &fatal("write permission denied on `$_'!") unless -w _;
  895. X}
  896. X
  897. X&fatal("font file `$Font' does not exist!") unless -e $Font;
  898. X&fatal("name file `$Namefile' does not exist!") unless -e $Namefile;
  899. X
  900. X&fatal('-i and -X switches can\'t be used together.') if ($Ident && $Xsame);
  901. X&fatal('-i and -Y switches can\'t be used together.') if ($Ident && $Ysame);
  902. X&fatal('-X and -Y switches can\'t be used together.') if ($Xsame && $Ysame);
  903. X
  904. X&fatal('-O and -o switches can\'t be used together.')
  905. X    if ($opt{'o'} && $AutoOff);
  906. X
  907. X
  908. X#
  909. X# sanity checks (warnings)
  910. X#
  911. X
  912. Xif ($Auto) {
  913. X    &warning('image width is larger than sheet width \
  914. X(your sheets will be one image wide)!') if ($Width > $Xdim);
  915. X    &warning('image height is larger than sheet height \
  916. X(your sheets will be one image high)!') if ($Height > $Ydim);
  917. X    &warning('-r and -a specified!  Ignoring -r.') if $opt{'r'};
  918. X    &warning('-c and -a specified!  Ignoring -c.') if $opt{'c'};
  919. X} else {
  920. X    &warning('-x specified without -a!  Ignoring -x.') if $opt{'x'};
  921. X    &warning('-y specified without -a!  Ignoring -y.') if $opt{'y'};
  922. X}
  923. X
  924. X&warning('-X and -h specified!  Ignoring -h.') if ($Xsame && $opt{'h'});
  925. X&warning('-Y and -w specified!  Ignoring -w.') if ($Ysame && $opt{'w'});
  926. X
  927. Xif ($Verbose && $Silent) {
  928. X    &warning('-v and -s cancel each other out!');
  929. X    $Silent = $Verbose = 0;
  930. X}
  931. X
  932. Xunless ($Labels) {
  933. X    &warning('-F specified without -l!  Ignoring -F.') if ($Font);
  934. X    &warning('-b specified without -l!  Ignoring -b.') if ($Base);
  935. X}
  936. X
  937. X
  938. X#
  939. X# process output format
  940. X#
  941. X
  942. X$Format =~ s/^\.//;
  943. X
  944. X@suffs = split(/\./, $Format);
  945. X
  946. Xif (@badext = grep(!defined($encode{$_}), @suffs)) {
  947. X    &fatal(sprintf('unknown extension%s (%s) in output format!',
  948. X    ((@badext > 1) ? 's' : ''), &cslist(@badext)));
  949. X}
  950. X
  951. X@encodecmd = grep($_, @encode{@suffs});
  952. X
  953. X$Quant = $defquant{$Format} if (!$opt{'q'} && $defquant{$Format});
  954. X
  955. Xunshift(@encodecmd, "ppmquant -fs $Quant") if $Quant;
  956. X
  957. X$encodecmd = @encodecmd ? ('| ' . join(' | ', @encodecmd) . ' ') : '';
  958. X
  959. X
  960. X#
  961. X# get filenames from named file
  962. X#
  963. X
  964. X@filelist = ();
  965. X
  966. Xif ($Namefile) {
  967. X    open(NAMEFILE, "<$Namefile") ||
  968. X        &fatal("unable to open `$Namefile' to read filenames: $!!");
  969. X    chop(@filelist = <NAMEFILE>);
  970. X    close(NAMEFILE);
  971. X}
  972. X
  973. Xunshift(@filelist, @ARGV);
  974. X
  975. X&fatal("no files specified!") unless @filelist;
  976. X
  977. Xif ($Xsame) {
  978. X    $pnmscale = "pnmscale -xsize $Width";
  979. X} elsif ($Ysame) {
  980. X    $pnmscale = "pnmscale -ysize $Height";
  981. X} else {
  982. X    $pnmscale = "pnmscale -xysize $Width $Height";
  983. X}
  984. X
  985. X
  986. X#
  987. X# start up the signal handler.
  988. X#
  989. X
  990. X$SIG{'HUP'} = $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = 'catcher';
  991. X
  992. X
  993. X#
  994. X# look for and process parameter files
  995. X#
  996. X
  997. X$Suffix =~ s/^\.//;
  998. X
  999. X@newlist = ();
  1000. X$pcount = 1;
  1001. X
  1002. Xforeach $file (@filelist) {
  1003. X    if ($file !~ /\.$Suffix$/) {
  1004. X    push(@newlist, $file);
  1005. X    next;
  1006. X    }
  1007. X
  1008. X    unless (open(PARAM, "<$file")) {
  1009. X    &skip("can't open `$file' for reading: $!!");
  1010. X    next;
  1011. X    }
  1012. X    
  1013. X    local($fn, @xywh, $line);
  1014. X    for ($line = 1; $_ = <PARAM>; $line++) {
  1015. X    next if /^\s*#/ || /^\s*$/;
  1016. X    s/#.*$//;
  1017. X    if (($fn, @xywh) = /^\s*(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/) {
  1018. X        push(@newlist, $fn);
  1019. X        $esheetname{$fn} = "$Tempdir/icp$pcount-$$";
  1020. X        $parameters{$fn} = "@xywh";
  1021. X        ($sheetname{$fn} = $file) =~ s/\.$Suffix$//;
  1022. X    } else {
  1023. X        &warning("can't understand line $line of `$file'!");
  1024. X    }
  1025. X    }
  1026. X    close(PARAM);
  1027. X    $pcount++;
  1028. X}
  1029. X@filelist = @newlist;
  1030. X
  1031. X
  1032. X#
  1033. X# uniq filenames
  1034. X#
  1035. X
  1036. Xif ($Uniq) {
  1037. X    local(%seen) = @newlist = ();
  1038. X    foreach (@filelist) {
  1039. X    if ($seen{$_}++) {
  1040. X        &info("removing duplicate `$_' from file list");
  1041. X        $esheetname{$_} = '';       # use the one that's not shrunk already.
  1042. X    } else {
  1043. X        push(@newlist, $_);
  1044. X    }
  1045. X    }
  1046. X    @filelist = @newlist;
  1047. X}
  1048. X
  1049. X
  1050. X#
  1051. X# take the basename's once and for all.
  1052. X#
  1053. X
  1054. Xforeach (@filelist, values(%sheetname)) {
  1055. X    $basename{$_} = (/([^\/]*)$/ ? $1 : $_);
  1056. X}
  1057. X
  1058. X
  1059. X#
  1060. X# sort filenames
  1061. X#
  1062. X
  1063. X@filelist = ($Base ? sort by_basename @filelist : sort @filelist) if ($Sort);
  1064. X
  1065. X
  1066. X#
  1067. X# figure out how big each character is in the specified font
  1068. X#
  1069. X
  1070. Xif ($Labels) {
  1071. X    $pbmtext = 'pbmtext' . ($Font ? " -font '$Font'" : '');
  1072. X    open(TEXT, "$pbmtext 'M' | pnmfile |") || 
  1073. X    &fatal("can't open `$pbmtext' to determine font size for labels: $!!");
  1074. X
  1075. X    (<TEXT> =~ /\s+(\d+)\s+by\s+(\d+)\s+/) ||
  1076. X    &fatal("can't understand `$pbmtext 'M' | pnmfile |' output!");
  1077. X
  1078. X    close(TEXT);
  1079. X
  1080. X    $cwidth = int($1 / 3);
  1081. X    $cheight = $2;
  1082. X
  1083. X    $invert = $White ? '' : ' | pnminvert';
  1084. X}
  1085. X
  1086. X
  1087. X#
  1088. X# determine the offset to be used for the first sheet.
  1089. X#
  1090. X
  1091. Xif ($opt{'o'}) {
  1092. X    $scount = $Offset;
  1093. X} elsif ($AutoOff) {
  1094. X    opendir(DESTDIR, $Dir) ||
  1095. X    &fatal("can't open destination directory to find offset: $!!");
  1096. X
  1097. X    local($last) =
  1098. X    reverse sort grep(/^$Prefix([0-9]{3,})\.$Format$/, readdir(DESTDIR));
  1099. X
  1100. X    closedir(DESTDIR);
  1101. X
  1102. X    if ($last) {
  1103. X    $last =~ /^$Prefix([0-9]{3,})\.$Format$/;
  1104. X    $scount = $1 + 1;
  1105. X    } else {
  1106. X    $scount = 1;
  1107. X    }
  1108. X} else {
  1109. X    $scount = 1;
  1110. X}
  1111. X
  1112. X
  1113. X#
  1114. X# a few initializations...
  1115. X#
  1116. X
  1117. X$background = $White ? 'white' : 'black';
  1118. X
  1119. X@stripes = $White ? ('white', 'black', 'white') : ('black', 'white', 'black');
  1120. X
  1121. X$temp = "$Tempdir/ict-$$";
  1122. X
  1123. X$icount = $rcount = 1;
  1124. X
  1125. X$iqwidth = $iqheight = $rqheight = 0;
  1126. X
  1127. X@ipqueue = @fpqueue = @rpqueue = ();
  1128. X
  1129. X@tfie = ();
  1130. X
  1131. X
  1132. X#
  1133. X# create one border file for all the images if $Ident && $Borders
  1134. X#
  1135. X
  1136. Xif ($Borders && $Ident) {
  1137. X    $border = "$Tempdir/icb-$$";
  1138. X
  1139. X    local($count) = 2;
  1140. X
  1141. X    $command = sprintf('pbmmake -%s %d %d > %s',
  1142. X    shift @stripes, ($Width + $count), ($Height + $count), $border);
  1143. X
  1144. X    &shell($command) || &fatal('unable to create border file!');
  1145. X
  1146. X    foreach $color (@stripes) {
  1147. X    $count += 2;
  1148. X
  1149. X    $command = sprintf('pbmmake -%s %d %d | pnmpaste %s 1 1 > %s',
  1150. X        $color, ($Width + $count), ($Height + $count), $border, $temp);
  1151. X
  1152. X    &shell($command) || &fatal('unable to add a layer to border file!');
  1153. X
  1154. X    &mv($temp, $border) || &fatal("unable to move `$temp' to `$border'!");
  1155. X    }
  1156. X}
  1157. X
  1158. X
  1159. X#
  1160. X# process each file
  1161. X#
  1162. X
  1163. XIMAGE: while ($file = shift @filelist) {
  1164. X    $image = "$Tempdir/ici$icount-$$";
  1165. X
  1166. X    if ($sheetname{$file}) {    # file is to be cut from sheet
  1167. X    unless (grep(/^$esheetname{$file}$/, @tfie)) {
  1168. X        &toppm($sheetname{$file}, $esheetname{$file}, 0) || next IMAGE;
  1169. X    }
  1170. X    &cut($file, $image) || next IMAGE;
  1171. X    &rm($esheetname{$file}) unless
  1172. X        grep(/^$esheetname{$file}$/, @esheetname{@filelist});
  1173. X    } else {    # file is an image file
  1174. X    unless (-e $file) {
  1175. X        &skip("`$file' does not exist!");
  1176. X        next IMAGE;
  1177. X    }
  1178. X    unless (-f _) {
  1179. X        &skip("`$file' is not a file!");
  1180. X        next IMAGE;
  1181. X    }
  1182. X    &toppm($file, $image, 1) || next IMAGE;
  1183. X    }
  1184. X
  1185. X    $label = ($Base ? $basename{$file} : $file);
  1186. X
  1187. X    if ($Auto || $Labels || $Borders || $Param || $Ident) {
  1188. X    unless (open(SIZE, "pnmfile $image |")) {
  1189. X        &skip("can't open `pnmfile $image |' for reading: $!!");
  1190. X        &rm($image);
  1191. X        next IMAGE;
  1192. X    }
  1193. X    unless ((($iwidth, $iheight) =
  1194. X        (<SIZE> =~ /\s+(\d+)\s+by\s+(\d+)\s+/))) {
  1195. X        &skip("can't understand `pnmfile $image |' output!");
  1196. X        &rm($image);
  1197. X        close(SIZE);
  1198. X        next IMAGE;
  1199. X    }
  1200. X    close(SIZE);
  1201. X
  1202. X    ($zxoff, $zyoff, $ziwidth, $ziheight) = (0, 0, $iwidth, $iheight)
  1203. X        if ($Param);
  1204. X    }
  1205. X
  1206. X    if ($Ident) {
  1207. X    $xpad = int(($Width - $iwidth) / 2);
  1208. X    $ypad = int(($Height - $iheight) / 2);
  1209. X
  1210. X    $command = sprintf('pbmmake -%s %d %d | pnmpaste %s %d %d > %s',
  1211. X        $background, $Width, $Height, $image, $xpad, $ypad, $temp);
  1212. X
  1213. X    unless (&shell($command)) {
  1214. X        &skip("unable to pad `$file' to ${Width}x$Height!");
  1215. X        &rm($image, $temp);
  1216. X        next IMAGE;
  1217. X    }
  1218. X
  1219. X    unless (&mv($temp, $image)) {
  1220. X        &rm($image, $temp);
  1221. X        next IMAGE;
  1222. X    }
  1223. X
  1224. X    $iwidth = $Width;
  1225. X    $iheight = $Height;
  1226. X
  1227. X    if ($Param) {
  1228. X        $zxoff += $xpad;
  1229. X        $zyoff += $ypad;
  1230. X    }
  1231. X
  1232. X    }
  1233. X
  1234. X    if ($Borders) {
  1235. X    if ($Ident) {
  1236. X        $iwidth += 6;
  1237. X        $iheight += 6;
  1238. X
  1239. X        unless (&shell("pnmpaste $image 3 3 $border > $temp")) {
  1240. X        &skip("unable to add a border to `$file'!");
  1241. X        &rm($image, $temp);
  1242. X        next IMAGE;
  1243. X        }
  1244. X        unless (&mv($temp, $image)) {
  1245. X        &rm($image, $temp);
  1246. X        next IMAGE;
  1247. X        }
  1248. X    } else {
  1249. X        foreach $color (@stripes) {
  1250. X        $iwidth += 2;
  1251. X        $iheight += 2;
  1252. X
  1253. X        $command = sprintf('pbmmake -%s %d %d | pnmpaste %s 1 1 > %s',
  1254. X            $color, $iwidth, $iheight, $image, $temp);
  1255. X
  1256. X        unless (&shell($command)) {
  1257. X            &skip("unable to add a layer of border on `$file'!");
  1258. X            &rm($image, $temp);
  1259. X            next IMAGE;
  1260. X        }
  1261. X        unless (&mv($temp, $image)) {
  1262. X            &rm($image, $temp);
  1263. X            next IMAGE;
  1264. X        }
  1265. X        }
  1266. X    }
  1267. X
  1268. X    if ($Param) {
  1269. X        $zxoff += 3;
  1270. X        $zyoff += 3;
  1271. X    }
  1272. X    }
  1273. X
  1274. X    if ($Labels) {
  1275. X    $slots = int($iwidth / $cwidth);
  1276. X
  1277. X    if ($slots - length($label) > 1) {
  1278. X        $command = sprintf('%s \'%s\'%s | pnmcat -%s -tb %s - > %s',
  1279. X        $pbmtext, $label, $invert, $background, $image, $temp);
  1280. X    } else {
  1281. X        $command = sprintf(
  1282. X        '%s \'%s\'%s | pnmcut %d 0 %d %d | pnmcat -%s -tb %s - > %s',
  1283. X        $pbmtext, substr($label, 0, $slots), $invert, $cwidth,
  1284. X        ($cwidth * $slots), $cheight, $background, $image, $temp);
  1285. X    }
  1286. X
  1287. X    unless (&shell($command)) {
  1288. X        &skip("unable to attach label to `$file'!");
  1289. X        &rm($image, $temp);
  1290. X        next IMAGE;
  1291. X    }
  1292. X    unless (&mv($temp, $image)) {
  1293. X        &rm($image, $temp);
  1294. X        next IMAGE;
  1295. X    }
  1296. X    $iheight += $cheight;
  1297. X    }
  1298. X
  1299. X    if ($Auto) {
  1300. X    if ($iqwidth + $iwidth > $Xdim) {
  1301. X        if (@iqueue) {
  1302. X        &image2row;
  1303. X        $rcount++;
  1304. X        $wrheight = $iqheight;
  1305. X        &pushimage;
  1306. X        ($iqwidth, $iqheight) = ($iwidth, $iheight);
  1307. X        } else {
  1308. X        &pushimage;
  1309. X        &image2row;
  1310. X        $rcount++;
  1311. X        $wrheight = $iheight;
  1312. X        $iqwidth = $iqheight = 0;
  1313. X        }
  1314. X        if ($rqheight + $wrheight > $Ydim) {
  1315. X        if (@rqueue) {
  1316. X            &row2sheet;
  1317. X            &pushrow;
  1318. X            $rqheight = $wrheight;
  1319. X        } else {
  1320. X            &pushrow;
  1321. X            &row2sheet;
  1322. X            $rqheight = 0;
  1323. X        }
  1324. X        } else {
  1325. X        &pushrow;
  1326. X        $rqheight += $wrheight;
  1327. X        }
  1328. X    } else {
  1329. X        &pushimage;
  1330. X        $iqwidth += $iwidth;
  1331. X        $iqheight = $iheight if ($iheight > $iqheight);
  1332. X    }
  1333. X    } else {
  1334. X    &pushimage;
  1335. X    if (($icount % $Columns) == 0) {
  1336. X        &image2row;
  1337. X        &pushrow;
  1338. X        &row2sheet if (($rcount % $Rows) == 0);
  1339. X        $rcount++;
  1340. X    }
  1341. X    }
  1342. X
  1343. X    $icount++;
  1344. X}
  1345. X
  1346. Xif (@iqueue) {
  1347. X    &image2row;
  1348. X    &row2sheet if ($Auto && $rqheight + $iqheight > $Ydim);
  1349. X    &pushrow;
  1350. X}
  1351. X&row2sheet if @rqueue;
  1352. X
  1353. X&cleanup;
  1354. X
  1355. Xexit(0);        
  1356. X
  1357. X&catcher('HEY, THIS CAN\'T HAPPEN');    # just to get rid of the warning...
  1358. X
  1359. X
  1360. X# --------------------------- end of main program -----------------------------
  1361. X
  1362. X
  1363. Xsub by_basename {
  1364. X    $basename{$a} cmp $basename{$b};
  1365. X}
  1366. X
  1367. X
  1368. Xsub by_number {
  1369. X    $a <=> $b;
  1370. X}
  1371. X
  1372. X
  1373. Xsub catcher {
  1374. X    &cleanup;
  1375. X    &fatal("caught a SIG@_ -- shutting down!");
  1376. X}
  1377. X
  1378. X
  1379. Xsub cleanup {
  1380. X    foreach (@tfie) { &warning("can't unlink `$_': $!!") unless unlink; }
  1381. X}
  1382. X
  1383. X
  1384. Xsub cslist {
  1385. X    local($") = ", ";
  1386. X    "@_";
  1387. X}
  1388. X
  1389. X
  1390. Xsub cut {
  1391. X    local($input, $output) = @_;
  1392. X
  1393. X    &info("cutting `$input'");
  1394. X    if (!&shell("pnmcut $parameters{$input} $esheetname{$input} > $output")) {
  1395. X    &skip("can't cut from $esheetname{$input}");
  1396. X    &rm($output);
  1397. X    return 0;
  1398. X    }
  1399. X    return 1;
  1400. X}
  1401. X
  1402. X
  1403. Xsub evalargs {
  1404. X    local(@args) = @_;
  1405. X
  1406. X    while ($_ = $args[0], ($_ && /^[-+]/)) {
  1407. X    shift @args;
  1408. X    last if /^--$/;
  1409. X
  1410. X    if (/^[-+]help$/) {                                 # `h' special case
  1411. X        &usage;
  1412. X    } elsif (/^[-+]([cdFfhKnoPpqrtwxy])$/) {            # argument
  1413. X        if (@args) {
  1414. X        eval "\$opt{'$1'} = 1; \$$optvar{$1} = shift \@args";
  1415. X        } else {
  1416. X        &fatal("no argument given for -$1 switch!");
  1417. X        }
  1418. X    } elsif (/^([-+])([aBbgiklOSsuvWXY])(.*)$/) {       # no argument
  1419. X        $val = ($1 eq '-');
  1420. X        $backon = length($3) ? "; unshift(\@args, '$1$3')" : '';
  1421. X        eval "\$$optvar{$2} = $val$backon";
  1422. X    } else {                                            # unknown
  1423. X        warn "$program: FATAL ERROR: unknown option: `$_'!\n";
  1424. X        &usage;
  1425. X    }
  1426. X    }
  1427. X    @args;
  1428. X}
  1429. X
  1430. X
  1431. Xsub fatal {
  1432. X    die "$program: FATAL ERROR: ", @_, "\n";
  1433. X}
  1434. X
  1435. X
  1436. Xsub image2row {
  1437. X    &info("assembling row $rcount");
  1438. X    $row = "$Tempdir/icr$rcount-$$";
  1439. X    unless (&shell("pnmcat -$background -lr -jbottom @iqueue > $row")) {
  1440. X    &skip("can't assemble row $rcount!");
  1441. X    &rm($row);
  1442. X    }
  1443. X    if ($Param) {
  1444. X    push(@fpqueue, @ipqueue);
  1445. X    @ipqueue = ();
  1446. X    }
  1447. X    &rm(@iqueue);
  1448. X    @iqueue = ();
  1449. X}
  1450. X
  1451. X
  1452. Xsub info {
  1453. X    warn "$program: ", @_, "\n" unless $Silent;
  1454. X}
  1455. X
  1456. X
  1457. Xsub mv {
  1458. X    local($src, $dest) = @_;
  1459. X
  1460. X    unless (rename($src, $dest)) {
  1461. X    &skip("unable to rename `$src' to `$dest': $!!");
  1462. X    return 0;
  1463. X    }
  1464. X
  1465. X    &tfdelete($src);
  1466. X    &tfadd($dest);
  1467. X    1;
  1468. X}
  1469. X
  1470. X
  1471. Xsub on {
  1472. X    local($num) = @_;
  1473. X
  1474. X    $num ? 'on' : 'off';
  1475. X}
  1476. X
  1477. X
  1478. Xsub pushimage {
  1479. X    push(@iqueue, $image);
  1480. X    if ($Param) {
  1481. X    push(@ipqueue, pack("a255I7", $label, $rcount, $iwidth, $iheight,
  1482. X                $zxoff, $zyoff, $ziwidth, $ziheight));
  1483. X    }
  1484. X}
  1485. X
  1486. X
  1487. Xsub pushrow {
  1488. X    push(@rqueue, $row);
  1489. X    if ($Param) {
  1490. X    push(@rpqueue, @fpqueue);
  1491. X    @fpqueue = ();
  1492. X    }
  1493. X}
  1494. X
  1495. X
  1496. Xsub rm {
  1497. X    foreach $file (@_) {
  1498. X    &tfdelete($file);
  1499. X    &warning("can't unlink `$file': $!!") unless unlink($file);
  1500. X    }
  1501. X}
  1502. X
  1503. X
  1504. Xsub row2sheet {
  1505. X    local($sheet) = sprintf("%s/%s%03d.%s", $Dir, $Prefix, $scount, $Format);
  1506. X    &info("assembling `$sheet'");
  1507. X    unless (&shell("pnmcat -$background -tb @rqueue $encodecmd> $sheet")) {
  1508. X    &skip("can't assemble sheet $scount!");
  1509. X    &rm($sheet);
  1510. X    }
  1511. X    &tfdelete($sheet);  # save the sheets!
  1512. X
  1513. X    if ($Param) {
  1514. X    local($pfile) = "$sheet.$Suffix";
  1515. X    &info("creating `$pfile'");
  1516. X    if (open(PARAM, ">$pfile")) {
  1517. X        local(%height, %width, $r, $h, $w, $n, $zx, $zy, $zw, $zh);
  1518. X
  1519. X        foreach (@rpqueue) {
  1520. X        ($n, $r, $w, $h, $zx, $zy, $zw, $zh) = unpack("A255I7", $_);
  1521. X        $width{$r} = $width{$r} ? ($width{$r} + $w) : $w;
  1522. X        $height{$r} = $h if (!$height{$r} || $h > $height{$r});
  1523. X        }
  1524. X
  1525. X        local($xoff);
  1526. X        local($yoff) = 0;
  1527. X        local($pastr) = -1;
  1528. X        local($widest) = reverse sort by_number values(%width);
  1529. X
  1530. X        foreach (@rpqueue) {
  1531. X        ($n, $r, $w, $h, $zx, $zy, $zw, $zh) = unpack("A255I7", $_);
  1532. X        if ($r != $pastr) {
  1533. X            $pastr = $r;
  1534. X            $xoff = 0;
  1535. X            $yoff += $height{$r};
  1536. X        }
  1537. X        printf(PARAM "%-40s %5d %5d %5d %5d\n", $n,
  1538. X            int(($widest - $width{$r}) / 2) + $xoff + $zx,
  1539. X            $yoff - $h + $zy,
  1540. X            $zw, $zh);
  1541. X        $xoff += $w;
  1542. X        }
  1543. X
  1544. X        @rpqueue = ();
  1545. X        close(PARAM);
  1546. X    } else {
  1547. X        &warning("can't open $pfile: $!!\n");
  1548. X    }
  1549. X    }
  1550. X    $scount++;
  1551. X    &rm(@rqueue);
  1552. X    @rqueue = ();
  1553. X}
  1554. X
  1555. X
  1556. Xsub shell {
  1557. X    local($command) = @_;
  1558. X
  1559. X    &tfadd($1) if ($command =~ /\s+>\s+(\S+)$/);
  1560. X
  1561. X    if ($Verbose) {
  1562. X    &info($command);
  1563. X    } else {
  1564. X    $command = "($command) 2> /dev/null";
  1565. X    }
  1566. X
  1567. X    system $command;
  1568. X
  1569. X    if ($? & 255) {
  1570. X    &warning("`$command' was killed by signal: ", ($? & 127), '.', 
  1571. X        ($? & 128) ? "core dumped." : '');
  1572. X    return 0;
  1573. X    } elsif ($status = ($? >> 8)) {
  1574. X    if ($status & 128) {
  1575. X        &cleanup;
  1576. X        &fatal("`$command' was terminated abnormally by signal: ",
  1577. X        ($status & 127));
  1578. X    } else {
  1579. X        &warning("`$command' terminated with exit status: $status");
  1580. X        return 0;
  1581. X    }
  1582. X    }
  1583. X    1;
  1584. X}
  1585. X
  1586. X
  1587. Xsub skip {
  1588. X    &warning(@_, "  Skipping.");
  1589. X}
  1590. X
  1591. X
  1592. Xsub tfadd {
  1593. X    local($file) = @_;
  1594. X    push(@tfie, $file) unless grep(/^$file$/, @tfie);
  1595. X}
  1596. X
  1597. X
  1598. Xsub tfdelete {
  1599. X    local($file) = @_;
  1600. X    @tfie = grep(!/^$file$/, @tfie);
  1601. X}
  1602. X
  1603. X
  1604. Xsub toppm {
  1605. X    local($input, $output, $shrink) = @_;
  1606. X
  1607. X    local(@suffs) = split(/\./, $basename{$input});
  1608. X    shift @suffs;
  1609. X
  1610. X    unless (@suffs) {
  1611. X    &skip("no extension on `$input'!");
  1612. X    return 0;
  1613. X    }
  1614. X
  1615. X    if (@badext = grep(!defined($decode{$_}), @suffs)) {
  1616. X    &skip(sprintf('unknown extension%s (%s) on `%s\'!',
  1617. X        ((@badext > 1) ? 's' : ''), &cslist(@badext), $input));
  1618. X    return 0;
  1619. X    }
  1620. X
  1621. X    local(@decodecmd) = grep($_, reverse @decode{@suffs});
  1622. X
  1623. X    local($init) = (@decodecmd && ($decodecmd[0] =~ tr/|/|/) == 0) ?
  1624. X    (shift @decodecmd) . " '$input'" :
  1625. X    "cat '$input'";
  1626. X
  1627. X    local($decodecmd);
  1628. X    if ($shrink) {
  1629. X    $decodecmd = join(' | ', ($init, @decodecmd, "$pnmscale > $output"));
  1630. X    &info("shrinking `$input'");
  1631. X    } else {
  1632. X    $decodecmd = join(' | ', ($init, @decodecmd)) . " > $output";
  1633. X    &info("expanding `$input'");
  1634. X    }
  1635. X
  1636. X    unless (&shell($decodecmd)) {
  1637. X    &skip("can't decode `$input'!");
  1638. X    &rm($output);
  1639. X    return 0;
  1640. X    }
  1641. X    1;
  1642. X}
  1643. X
  1644. X
  1645. Xsub usage {
  1646. X    die "usage: $program [options] [{image file | parameter file} ...]
  1647. X[options] consists of:
  1648. X-a, +a\t automatically size sheets to the size of the screen.  default = ",
  1649. X    &on($d{'Auto'}), "
  1650. X-B, +B\t put borders around each image.  default = ", &on($d{'Borders'}), "
  1651. X-b, +b\t take the basename of the filenames.  default = ", &on($d{'Base'}), "
  1652. X-c #\t number of columns of images in each sheet.  default = $d{'Columns'}
  1653. X-d dir\t put sheets in `dir'.  default = `$d{'Dir'}'
  1654. X-f str\t `str' is the file format of the sheets.  default = `$d{'Format'}'
  1655. X-F file\t font file for labels.  default = `",
  1656. X    ($d{'Font'} || 'pbmtext\'s internal font'), "'
  1657. X-g, +g\t generate parameter files for sheets.  default = ", &on($d{'Param'}), "
  1658. X-h #\t height of each small image in pixels.  default = $d{'Height'}
  1659. X-i, +i\t make images the same size.  default = ", &on($d{'Ident'}), "
  1660. X-K file\t use `file' as the configuration file.  default = `",
  1661. X    ($d{'Config'} || '~/.icrc'), "'
  1662. X-k, +k\t don't reference the configuration file.  default = ",
  1663. X    &on($d{'Ignore'}), "
  1664. X-l, +l\t put labels under the images.  default = ", &on($d{'Labels'}), "
  1665. X-n file\t get filenames from `file'.  default = none
  1666. X-O, +O\t find the number for the first sheet automatically.  default = ",
  1667. X    &on($d{'AutoOff'}), "
  1668. X-o #\t start at this number when naming sheets.  default = $d{'Offset'}
  1669. X-P suff\t suffix of parameter files.  default = `$d{'Suffix'}'
  1670. X-p name\t name of the sheets. default = `$d{'Prefix'}'
  1671. X-q #\t number of colors in each sheet.  default = $d{'Quant'}
  1672. X-r #\t number of rows of images in each sheet.  default = $d{'Rows'}
  1673. X-S, +S\t sort all the filenames.  default = ", &on($d{'Sort'}), "
  1674. X-s, +s\t be silent.  default = ", &on($d{'Silent'}), "
  1675. X-t dir\t use `dir' to hold temporary files.  default = `$d{'Tempdir'}'
  1676. X-u, +u\t remove duplicate file names from file list.  default = ",
  1677. X    &on($d{'Uniq'}), "
  1678. X-v, +v\t be verbose.  default = ", &on($d{'Verbose'}), "
  1679. X-W, +W\t use a ", (!$d{'White'} ? "white" : "black"),
  1680. X    " background for the contact sheets.  default = ",
  1681. X    ($d{'White'} ? "white" : "black"), "
  1682. X-w #\t width of each small image in pixels.  default = $d{'Width'}
  1683. X-X, +X\t make images the same width.  default = ", &on($d{'Ysame'}), "
  1684. X-x #\t screen width in pixels.  default = $d{'Xdim'}
  1685. X-Y, +Y\t make images the same height.  default = ", &on($d{'Ysame'}), "
  1686. X-y #\t screen height in pixels.  default = $d{'Ydim'}
  1687. X";
  1688. X}
  1689. X
  1690. X
  1691. Xsub warning {
  1692. X    warn "$program: WARNING: ", @_, "\n";
  1693. X}
  1694. END_OF_FILE
  1695. if test 28926 -ne `wc -c <'icontact'`; then
  1696.     echo shar: \"'icontact'\" unpacked with wrong size!
  1697. fi
  1698. chmod +x 'icontact'
  1699. # end of 'icontact'
  1700. fi
  1701. echo shar: End of shell archive.
  1702. exit 0
  1703.  
  1704. exit 0 # Just in case...
  1705.