Xref: utzoo alt.sex.pictures.d:3611 alt.sources:3704 Path: utzoo!utgpu!cs.utexas.edu!wuarchive!psuvax1!rutgers!uwvax!persoft!gorgon!dag From: dag@gorgon.uucp (Daniel A. Glasser) Newsgroups: alt.sex.pictures.d,alt.sources Subject: yagcsp (Yet Another GIF Contact Sheet Program) Summary: Awful, but it seems to work Keywords: GIF proofsheet C code PBMplus Message-ID: <1991May06.033638.3758@gorgon.uucp> Date: 6 May 91 03:36:38 GMT References: <1991May4.172224.1064@eddie.mit.edu> Sender: dag@gorgon.uucp (Daniel A. Glasser) Followup-To: alt.sex.pictures.d Organization: Perseus Reductions (Medusa Division) Lines: 393 #!/bin/sh # This is a shell script. It's not important, really, but if you strip # off everything that comes before these shell comments and feed the # result to sh (not csh) you should get the file csheet.c. Note # that this is a hand-made shell archive and it will not protect you # against overwriting a file by the same name. Use at your own risk. # echo Extracting csheet.c cat >csheet.c < where is a space separated list of the files (including paths if not in the current directory) to be included in the contact sheet. These files are expected to have the extension ".gif", and if they don't, .gif is _not_ appended. A recent version of the PBMplus utility package (or at least part of said package) must be accessable through the user's search path (PATH) for system() to do its stuff. The program looks in the environment for four symbols, SHEETWORK (defaults to /tmp) The directory the work gets done in. It is a good idea to set this environment variable to something other than /tmp, just in case someone else is trying to run this program at the same time you are. There should be several megabytes free in the file system containing this directory. SHEETDEST (defaults to .) The directory in which the resulting .gif file will be placed. SHEETNAME (defaults to sheet) The first part of the name of the contact sheet file. It will have a two-digit sequence number appended to it, followed by ".gif". SHEETHEIGHT (defaults to 768) This specifies the maximum height of the contact sheet (in scan lines). You can override the default default values at compile time by defining DEFWORK, DEFDEST, DEFPREFIX, and DEFHEIGHT, respectively. bugs: If the files names are not in wildcard expansion order in the argument list to the program, the labels on the images might be wrong. I'm sure there are many more, I've not seen them yet. todo: The program should take switches to override both the defaults and the environment. Someone who cares should add this. It's rather difficult to interrupt this program... Appropriate signals should be caught and the return status from 'system()' should be examined so the program can tell when a child has been interrupted rather than just failed. Some cleanup of the work directory should be done. There is no need to use the basename of the .gif file as part of the temporary file names. A unique prefix should be generated for each instance of this program along with the sequence number of the file in the command line, thereby eliminating a bunch of problems with wild-card expansion order and conflicts between concurrent executions of this program. */ #include #ifndef DEFWORK #define DEFWORK "/tmp" #endif #ifndef DEFDEST #define DEFDEST "." #endif #ifndef DEFPREFIX #define DEFPREFIX "sheet" #endif #ifndef DEFHEIGHT #define DEFHEIGHT 768 #endif char command[257]; int atoi(); char *strchr(); char *strrchr(); char *getenv(); int strlen(); char *workdir; char *destdir; char *prefix; int maxheight; void panic(str) char *str; { fprintf("Panic on command\n%s\nPlease clean up %s yourself.\n", str, workdir); exit(1); } int basename(dest, src, len) char *dest; char *src; int len; { char *x; int l; while (x = strchr(src, '/')) src = x + 1; if ((x = strrchr(src, '.')) == NULL) { x = src + strlen(src); } for (l=0; l < len; ++l) { if ((src == x) || (*src == '\0')) break; *dest++ = *src++; } *dest = '\0'; return l; } int getval(str, fld) char *str; int fld; { --fld; while(fld) { while ((*str != ' ') && (*str != '\t')) { if (*str == '\0') return 0; ++str; } while ((*str == ' ') || (*str == '\t')) ++str; --fld; } if (*str == '\0') return 0; else return atoi(str); } void linedone(row, page) int row; int page; { printf("Compiling row %d of contact sheet %d\n", row, page); sprintf(command, "pnmcat -white -lr %s/*.s* | ppmquant 256 > %s/row%d.ppm", workdir, workdir, row * 2 - 1); printf("%s\n", command); if (system(command)) panic(command); sprintf(command, "pnmcat -white -lr %s/fname? > %s/row%d.ppm", workdir, workdir, row * 2); printf("%s\n", command); if (system(command)) panic(command); sprintf(command, "rm -f %s/*.s* %s/fname?", workdir, workdir); printf("%s\n", command); if (system(command)) panic(command); } void pagedone(row, page) int row; int page; { char result[128]; FILE *fp; int height; printf("Assembling contact sheet %d\n", page); sprintf(command, "pnmcat -white -tb %s/row?.ppm > %s/page%02d.ppm", workdir, workdir, page); printf("%s\n", command); if (system(command)) panic(command); sprintf(command, "rm -f %s/row?.ppm", workdir); printf("%s\n", command); if (system(command)) panic(command); sprintf(command, "pnmfile %s/page%02d.ppm > %s/size", workdir, page, workdir); printf("%s\n", command); if (system(command)) panic(command); sprintf(command, "%s/size", workdir); if ((fp = fopen(command, "r")) == NULL) { perror(command); fprintf(stderr, "Fatal error, you'll have to clean %s up\n", workdir); exit(1); } fgets(result, 128, fp); fclose(fp); printf("rm %s\n", command); unlink(command); height = getval(result, 6); if (height == 0) height = maxheight + 1; printf("Page height is %d\n", height); if (height > maxheight) { printf("Scaling down to %d scans.\n", maxheight); sprintf(command, "pnmscale -ysize %d < %s/page%02d.ppm | ppmquant 256 | ppmtogif > %s/%s%02d.gif", maxheight, workdir, page, destdir, prefix, page); } else { sprintf(command, "ppmquant 256 < %s/page%02d.ppm | ppmtogif > %s/%s%02d.gif", workdir, page, destdir, prefix, page); } printf("%s\n", command); if (system(command)) panic(command); sprintf(command, "rm -f %s/page%02d.ppm", workdir, page); printf("%s\n", command); if (system(command)) panic(command); printf("++++ file %s/%s%02d.gif is complete!\n", destdir, prefix, page); } main(argc, argv) int argc; char **argv; { char base[32]; char workfile[64]; char *tmp; int curfile; int curpage; int currow; int i; if (argc <= 1) { fprintf(stderr, "useage: %s list-of-gif-files\n", argv[0]); exit(1); } if ((workdir = getenv("SHEETWORK")) == NULL) workdir = DEFWORK; if ((destdir = getenv("SHEETDEST")) == NULL) destdir = DEFDEST; if ((prefix = getenv("SHEETNAME")) == NULL) prefix = DEFPREFIX; if (tmp = getenv("SHEETHEIGHT")) { if ((maxheight = atoi(tmp)) <= 0) maxheight = DEFHEIGHT; } else maxheight = DEFHEIGHT; curfile = 0; currow = 0; curpage = 0; for (i=1; i %s", argv[i], workfile); printf("%s\n", command); if (system(command) != 0) { printf("Error processing %s, skipping...", argv[i]); unlink(workfile); continue; } sprintf(command, "pbmtext %s.gif | pnmscale -xsize 102 -ysize 20 > %s/fname%d", base, workdir, curfile); if (system(command)) panic(command); ++curfile; if (curfile >= 5) { currow++; curfile = 0; linedone(currow, curpage); if (currow == 4) { pagedone(currow, curpage); ++curpage; currow = 0; } /* end of page done */ } /* end of row done */ } /* end of for () */ if (currow != 0 || curfile != 0) { currow++; if (curfile != 0) linedone(currow, curpage); pagedone(currow, curpage); ++curpage; } printf("All done, %d pages produced from %d image files.\n", curpage, argc - 1); exit(0); } EndOfTerribleCProgram echo done extracting csheet.c exit 0 -- Daniel A. Glasser One of those things that goes dag%gorgon@persoft.com "BUMP! (ouch!)" in the night.