home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3953 < prev    next >
Text File  |  1991-09-01  |  13KB  |  484 lines

  1. Xref: wupost alt.sex.pictures.d:7004 alt.sources:3953 alt.binaries.pictures.d:712 alt.graphics.pixutils:1685
  2. Newsgroups: alt.sex.pictures.d,alt.sources,alt.binaries.pictures.d,alt.graphics.pixutils
  3. Path: wupost!zaphod.mps.ohio-state.edu!hobbes.physics.uiowa.edu!news.iastate.edu!pv7411.vincent.iastate.edu!edsall
  4. From: edsall@iastate.edu (David M Edsall)
  5. Subject: Improved contact sheet program
  6. Message-ID: <edsall.683774048@pv7411.vincent.iastate.edu>
  7. Summary: Will now check for existing contact sheets
  8. Keywords: C, pbmplus
  9. Sender: news@news.iastate.edu (USENET News System)
  10. Organization: Iowa State University, Ames IA
  11. Date: Mon, 2 Sep 1991 01:14:08 GMT
  12. Lines: 470
  13.  
  14.  
  15.  
  16.  
  17.    This is an improved version of the contact sheet program written in C that
  18. was posted by Daniel Glasser in May. The original would not check to see if
  19. existing contact sheets of the same basename existed and it also would include
  20. these contacts in the newly generated contacts. I like this program because it
  21. runs faster than any of the shell scripts previously posted. The improvements
  22. I have included are
  23.  
  24. 1) The user can set the initial page number of the set of contact sheets 
  25. generated by setting the environment variable STARTPAGE
  26.  
  27. 2) If STARTPAGE has not been set, the program will determine which contact
  28. sheets of the same basename exist and will count the number of these which
  29. exist. If we call that number "n", then the next page generated will have
  30. the suffix "n+1"
  31.  
  32. 3) When compiling the contact sheets, this program will not include the
  33. previously generated contact sheets of the same name. This was useful for
  34. me in that I roll my images off onto tape but I like to keep an archive of
  35. what I have on disk. This way I do not have to keep moving my previously
  36. generated contacts back and forth between my image directory and some 
  37. temporary directory while I compile the new contact sheets.
  38.  
  39.  
  40.    I have included the shell script that I use for my contacts which sets the
  41. environment variables that are important for me. Note for readers who have
  42. never seen this before: you must have the pbmplus package to run this and
  43. this program uses UNIX procedures to get environment variable settings from
  44. within the program. It is therefore OS dependent but it would probably not
  45. be that hard to replace the "getenv" functions within the program with 
  46. appropriate calls for your OS.
  47.  
  48.    - dave 
  49.  
  50.  
  51. #!/bin/sh
  52. # to extract, remove the header and type "sh filename"
  53. if `test ! -s ./csheet.c`
  54. then
  55. echo "writing ./csheet.c"
  56. cat > ./csheet.c << '\End\Of\Shar\'
  57. /* Csheet -- A program to make contact sheets out of .gif files.
  58.  
  59.     Version:    0.02
  60.     Original Author:    Daniel A. Glasser (dag%gorgon@persoft.com or
  61.                                dag@persoft.com)
  62.         Modified By:        David M. Edsall   (edsall@iastate.edu)
  63.     Date:            1 September 1991
  64.  
  65.     The author hereby places this program in the public domain.
  66.  
  67.     Anybody can do anything with this code, even clean it up and
  68.     call it h{er,is} own (though I'd appreciate some little credit
  69.     somewhere).  There is no warrenty expressed or implied in this
  70.     program.  The author assumes no liability for damage caused by
  71.     this program or by programmers who go berzerk after trying to
  72.     read this program.  You are on your own.
  73.  
  74.     The author admits that this program is awful.  Don't judge
  75.     his programming talent by the junk that's here.  I used to be
  76.     a competition programmer in college.  You learn to code fast
  77.     when maintainability and style don't matter.  I program for
  78.     a living, and what I write for work bears little or no
  79.     resemblence to this mess.  Please don't show this junk to
  80.     any beginning C programmer.  It's bad for their teeth.
  81.  
  82.     ---------------------------------------
  83.  
  84.     This program is a translation into C of the Bourne shell
  85.     script called "contact", posted to alt.sex.pictures.d
  86.     by Ron Schnell and modified by rekers@cwi.nl.  I had problems
  87.     with the original because I run on a Sys-V system with a
  88.     14 character file name limit.  The posted scripts immediately
  89.     ran afowl of this limit.  My modifications to the shell script
  90.     made it almost work, but things were still strange.  I hacked
  91.     this together in about an hour, and touched it up after some
  92.     debugging.  I'm posting it about 4 hours old.
  93.  
  94.     Note that this program differs from the original shell script
  95.     in several important ways --
  96.  
  97.     1)    It takes file name parameters rather than having a
  98.         hard coded source directory.
  99.     2)    The output and work directories can be changed without
  100.         recompiling through shell variables.
  101.     3)    ditto for the output file name
  102.     4)    ditto for the maximum image height
  103.     5)    It should take care of non-full last pages.
  104.  
  105.     This code is blecherous, uncommented garbage!  It doesn't catch
  106.     signals, have command line options, or create its own pipes.  It
  107.     uses "system()" for everything, and does not protect the user's
  108.     temporary files against other users' temporary files.  All of these
  109.     things could be added without too much difficulty, but I'm lazy.
  110.  
  111.     Usage:    csheet <gif_file_list>
  112.  
  113.     where <gif file list> is a space separated list of the files
  114.     (including paths if not in the current directory) to be included
  115.     in the contact sheet.  These files are expected to have the
  116.     extension ".gif", and if they don't, .gif is _not_ appended.
  117.  
  118.     A recent version of the PBMplus utility package (or at least
  119.     part of said package) must be accessable through the user's
  120.     search path (PATH) for system() to do its stuff.
  121.  
  122.     The program looks in the environment for four symbols,
  123.  
  124.         SHEETWORK    (defaults to /tmp)
  125.             The directory the work gets done in.  It
  126.             is a good idea to set this environment variable
  127.             to something other than /tmp, just in case someone
  128.             else is trying to run this program at the same
  129.             time you are.  There should be several megabytes
  130.             free in the file system containing this directory.
  131.  
  132.         SHEETDEST    (defaults to .)
  133.             The directory in which the resulting .gif file
  134.             will be placed.
  135.  
  136.         SHEETNAME    (defaults to sheet)
  137.             The first part of the name of the contact sheet
  138.             file.  It will have a two-digit sequence number
  139.             appended to it, followed by ".gif".
  140.  
  141.         SHEETHEIGHT    (defaults to 768)
  142.             This specifies the maximum height of the contact
  143.             sheet (in scan lines).
  144.  
  145.                 STARTPAGE         (defaults to 0 )
  146.             This specifies the page to begin with
  147.  
  148.     You can override the default default values at compile time
  149.     by defining DEFWORK, DEFDEST, DEFPREFIX, and DEFHEIGHT, respectively.
  150.  
  151.     bugs:    If the files names are not in wildcard expansion order
  152.         in the argument list to the program, the labels on the
  153.         images might be wrong.
  154.  
  155.         I'm sure there are many more, I've not seen them yet.
  156.  
  157.     todo:    The program should take switches to override both the
  158.         defaults and the environment.  Someone who cares should
  159.         add this.
  160.  
  161.         It's rather difficult to interrupt this program...
  162.         Appropriate signals should be caught and the return
  163.         status from 'system()' should be examined so the
  164.         program can tell when a child has been interrupted
  165.         rather than just failed.  Some cleanup of the work
  166.         directory should be done.
  167.  
  168.         There is no need to use the basename of the .gif
  169.         file as part of the temporary file names.  A unique
  170.         prefix should be generated for each instance of this
  171.         program along with the sequence number of the file
  172.         in the command line, thereby eliminating a bunch of
  173.         problems with wild-card expansion order and conflicts
  174.         between concurrent executions of this program.
  175.  
  176. */
  177.  
  178. #include <stdio.h>
  179.  
  180. #ifndef    DEFWORK
  181. #define    DEFWORK    "/tmp"
  182. #endif
  183.  
  184. #ifndef    DEFDEST
  185. #define    DEFDEST    "."
  186. #endif
  187.  
  188. #ifndef    DEFPREFIX
  189. #define    DEFPREFIX "sheet"
  190. #endif
  191.  
  192. #ifndef    DEFHEIGHT
  193. #define    DEFHEIGHT 768
  194. #endif
  195.  
  196. char command[257];
  197. int atoi();
  198. char *strchr();
  199. char *strrchr();
  200. char *getenv();
  201. int strlen();
  202.  
  203. char *workdir;
  204. char *destdir;
  205. char *prefix;
  206. int  maxheight;
  207.  
  208. void panic(str)
  209. char *str;
  210. {
  211.     fprintf("Panic on command\n%s\nPlease clean up %s yourself.\n",
  212.         str, workdir);
  213.     exit(1);
  214. }
  215.  
  216. int basename(dest, src, len)
  217. char *dest;
  218. char *src;
  219. int len;
  220. {
  221.     char *x;
  222.     int l;
  223.  
  224.     while (x = strchr(src, '/'))
  225.         src = x + 1;
  226.  
  227.     if ((x = strrchr(src, '.')) == NULL)
  228.     {
  229.         x = src + strlen(src);
  230.     }
  231.  
  232.     for (l=0; l < len; ++l)
  233.     {
  234.         if ((src == x) || (*src == '\0'))
  235.             break;
  236.         *dest++ = *src++;
  237.     }
  238.     *dest = '\0';
  239.     return l;
  240. }
  241.  
  242. int getval(str, fld)
  243. char *str;
  244. int fld;
  245. {
  246.     --fld;
  247.     while(fld)
  248.     {
  249.         while ((*str != ' ') && (*str != '\t'))
  250.         {
  251.             if (*str == '\0')
  252.                 return 0;
  253.             ++str;
  254.         }
  255.         while ((*str == ' ') || (*str == '\t'))
  256.             ++str;
  257.         --fld;
  258.     }
  259.     if (*str == '\0')
  260.         return 0;
  261.     else
  262.         return atoi(str);
  263. }
  264.  
  265. void linedone(row, page)
  266. int row;
  267. int page;
  268. {
  269.     printf("Compiling row %d of contact sheet %d\n", row, page);
  270.     sprintf(command,
  271.         "pnmcat -white -lr %s/*.s* | ppmquant 256 > %s/row%d.ppm",
  272.             workdir, workdir, row * 2 - 1);
  273.     printf("%s\n", command);
  274.     if (system(command)) panic(command);
  275.     
  276.     sprintf(command,
  277.         "pnmcat -white -lr %s/fname? > %s/row%d.ppm",
  278.             workdir, workdir, row * 2);
  279.     printf("%s\n", command);
  280.     if (system(command)) panic(command);
  281.     sprintf(command,
  282.         "rm -f %s/*.s* %s/fname?", workdir, workdir);
  283.     printf("%s\n", command);
  284.     if (system(command)) panic(command);
  285. }
  286.  
  287. void pagedone(row, page)
  288. int row;
  289. int page;
  290. {
  291.     char result[128];
  292.     FILE *fp;
  293.     int height;
  294.  
  295.     printf("Assembling contact sheet %d\n", page);
  296.     sprintf(command,
  297.         "pnmcat -white -tb %s/row?.ppm > %s/page%02d.ppm",
  298.             workdir, workdir, page);
  299.     
  300.     printf("%s\n", command);
  301.     if (system(command)) panic(command);
  302.  
  303.     sprintf(command, "rm -f %s/row?.ppm", workdir);
  304.     printf("%s\n", command);
  305.     if (system(command)) panic(command);
  306.  
  307.     sprintf(command, "pnmfile %s/page%02d.ppm > %s/size",
  308.                 workdir, page, workdir);
  309.     printf("%s\n", command);
  310.     if (system(command)) panic(command);
  311.     sprintf(command, "%s/size", workdir);
  312.     if ((fp = fopen(command, "r")) == NULL)
  313.     {
  314.         perror(command);
  315.         fprintf(stderr, "Fatal error, you'll have to clean %s up\n",
  316.                 workdir);
  317.         exit(1);
  318.     }
  319.     fgets(result, 128, fp);
  320.     fclose(fp);
  321.     printf("rm %s\n", command);
  322.     unlink(command);
  323.     height = getval(result, 6);
  324.  
  325.     if (height == 0) height = maxheight + 1;
  326.  
  327.     printf("Page height is %d\n", height);
  328.     if (height > maxheight)
  329.     {
  330.         printf("Scaling down to %d scans.\n", maxheight);
  331.         sprintf(command,
  332. "pnmscale -ysize %d < %s/page%02d.ppm | ppmquant 256 | ppmtogif > %s/%s%02d.gif",
  333.             maxheight, workdir, page, destdir, prefix, page);
  334.     }
  335.     else
  336.     {
  337.         sprintf(command,
  338.         "ppmquant 256 < %s/page%02d.ppm | ppmtogif > %s/%s%02d.gif",
  339.             workdir, page, destdir, prefix, page);
  340.     }
  341.     printf("%s\n", command);
  342.     if (system(command)) panic(command);
  343.  
  344.     sprintf(command, "rm -f %s/page%02d.ppm", workdir, page);
  345.     printf("%s\n", command);
  346.     if (system(command)) panic(command);
  347.  
  348.     printf("\n++++  file %s/%s%02d.gif is complete!\n",
  349.              destdir, prefix, page);
  350. }
  351.  
  352. main(argc, argv)
  353. int argc;
  354. char **argv;
  355. {
  356.     char base[32];
  357.     char workfile[64];
  358.     char *tmp;
  359.     int curfile;
  360.     int totalfiles;
  361.     int curpage;
  362.         int totalpages;
  363.     int currow;
  364.     int i;
  365.  
  366.     if (argc <= 1)
  367.     {
  368.         fprintf(stderr, "useage: %s list-of-gif-files\n",
  369.             argv[0]);
  370.         exit(1);
  371.     }
  372.     if ((workdir = getenv("SHEETWORK")) == NULL)
  373.         workdir = DEFWORK;
  374.     if ((destdir = getenv("SHEETDEST")) == NULL)
  375.         destdir = DEFDEST;
  376.     if ((prefix = getenv("SHEETNAME")) == NULL)
  377.         prefix = DEFPREFIX;
  378.  
  379.     if (tmp = getenv("SHEETHEIGHT"))
  380.     {
  381.         if ((maxheight = atoi(tmp)) <= 0)
  382.             maxheight = DEFHEIGHT;
  383.     }
  384.     else
  385.         maxheight = DEFHEIGHT;
  386.  
  387.     if (tmp = getenv("STARTPAGE"))
  388.     {
  389.         if ((curpage = atoi(tmp)) <= 0)
  390.             curpage = 1;
  391.     }
  392.     else
  393.     {
  394.         curpage = 1;
  395.         for (i=1; i<argc; ++i)
  396.                 {  
  397.            basename(base, argv[i], sizeof(base));
  398.            if ( strncmp(base,prefix,strlen(prefix)) == 0 ) ++curpage;
  399.                      }      
  400.     }
  401.         
  402.     curfile = 0;
  403.     currow = 0;
  404.         totalpages = 0;
  405.       totalfiles = 0;
  406.  
  407.     for (i=1; i<argc; ++i)
  408.     {
  409.         basename(base, argv[i], sizeof(base));
  410.                 if ( strncmp(base,prefix,strlen(prefix)) == 0 ) continue;
  411.         printf("\nProcessing %s\n", argv[i]);
  412.         strcpy(workfile, workdir);
  413.         strcat(workfile, "/");
  414.         strcat(workfile, base);
  415.         strcat(workfile, ".spm");
  416.  
  417.         sprintf(command, 
  418. "giftoppm < %s | pnmscale -xsize 102 | ppmquant 256 > %s",
  419.                 argv[i], workfile);
  420.         printf("%s\n", command);
  421.         if (system(command) != 0)
  422.         {
  423.             printf("Error processing %s, skipping...", argv[i]);
  424.             unlink(workfile);
  425.             continue;
  426.         }
  427.         sprintf(command,
  428. "pbmtext %s.gif | pnmscale -xsize 102 -ysize 20 > %s/fname%d",
  429.                 base, workdir, curfile);
  430.         if (system(command)) panic(command);
  431.         ++curfile;
  432.                 ++totalfiles;
  433.  
  434.         if (curfile >= 5)
  435.         {
  436.             currow++;
  437.             curfile = 0;
  438.             linedone(currow, curpage);
  439.  
  440.             if (currow == 4)
  441.             {
  442.                 pagedone(currow, curpage);
  443.                 ++curpage;
  444.                                 ++totalpages;
  445.                 currow = 0;
  446.             } /* end of page done */
  447.         } /* end of row done */
  448.     } /* end of for () */
  449.     if (currow != 0 || curfile != 0)
  450.     {
  451.         currow++;
  452.         if (curfile != 0) linedone(currow, curpage);
  453.         pagedone(currow, curpage);
  454.         ++curpage;
  455.                 ++totalpages;
  456.     }
  457.     printf("\nAll done, %d pages produced from %d image files.\n",
  458.             totalpages, totalfiles );
  459.     exit(0);
  460. }
  461. \End\Of\Shar\
  462. else
  463.   echo "will not over write ./csheet.c"
  464. fi
  465. if `test ! -s ./csheet.csh`
  466. then
  467. echo "writing ./csheet.csh"
  468. cat > ./csheet.csh << '\End\Of\Shar\'
  469. #
  470. setenv SHEETDEST /home/edsall/images/gif 
  471. setenv SHEETNAME images
  472. setenv SHEETWORK ~/tmp
  473. setenv STARTPAGE 40
  474. $xbin/csheet $gif/*.gif
  475. exit
  476. \End\Of\Shar\
  477. else
  478.   echo "will not over write ./csheet.csh"
  479. fi
  480. echo "Finished archive 1 of 1"
  481. exit
  482.  
  483.  
  484.