home *** CD-ROM | disk | FTP | other *** search
/ Peanuts NeXT Software Archives / Peanuts-3.iso / Graphics / convertors / tifftoeps.README / text0000.txt < prev   
Encoding:
Text File  |  1993-07-23  |  18.8 KB  |  756 lines

  1. Hi
  2.  
  3. Many, many thanks for your tiff2eps source it came in very handy for something
  4. I needed to do. Unfortunately I don't have a MAC and the only way I can scan
  5. pictures is with a handy scanner on my PC (I'd rather get a scanner for my
  6. NeXT, but it's still not out).
  7.  
  8. So I needed to read little endian tiff files and while I was at it, I
  9. decided to include the capability to read 32773 compressed files as well.
  10. The feature of showing some parameters above and below the eps-image is
  11. inteded for archiving and out of curiosity (same goes for the added tags
  12. recognized).
  13.  
  14. I was really in a hurry to get the thing working, so it's not nice code but it
  15. works on all kind of tiff files from NeXT and PC I've tried so far.
  16.  
  17. I assume you have extended the program yourself already since you wrote it
  18. in September. Anyway I thought you might be interested. Since I'm not
  19. expereinced with SCCS I didn't change the id string.
  20.  
  21. You may do whatever you like with this code. I didn't want to post this on the
  22. net since it's grown quite a bit and it's originally yours, so you decide.
  23.  
  24. What's missing:
  25.     - color and/or alpha
  26.     - some tags
  27.     - graceful handling of errors and defaults
  28.     - handling of dithering (but that's discouraged anyway)
  29.  
  30. Many thanks again.
  31.         Richard
  32.  
  33. Richard H. E. Eiger    (Foreign student from Switzerland)
  34. rheiger@ccng.waterloo.edu
  35.  
  36. --------------------------------------------------------------------------
  37. /*
  38.  * tifftoeps - convert AppleScanned .tiff file to EPSF
  39.  * Eric P. Scott, San Francisco State University, September 1989
  40.  *
  41.  * Disclaimer: this is a cheap hack; it does not attempt to
  42.  * handle arbitrary .tiff files, nor does it make use of all the
  43.  * information available to it.  In particular, the XResolution
  44.  * and YResolution tags are ignored.  Heck, it doesn't even
  45.  * accept little-endian TIFF...
  46.  *
  47.  * Future versions may (will?) support other kinds of scanners.
  48.  *
  49.  * Extension by Richard H. E. Eiger (RHE^2)
  50.  *
  51.  * 19. Feb. 90    Code to support little-endian
  52.  *        Code to support some more tags (ie. XRes & YRes influence PostScript !!
  53.  *              Code to support 32773 Compression Scheme
  54.  *              Image Info written above and below eps image (if selected at 
  55.  *                                                             compile-time
  56.  *                                                             ->#undef NO_INFO)
  57.  *
  58.  */
  59.  
  60. #include <stdio.h>
  61. #include <string.h>
  62. #include <assert.h>
  63.  
  64.  
  65.  
  66. #define LITTLE_END 1
  67. #define BIG_END   -1
  68.  
  69. /* PS uses inch/72 units ( = mm/2.835)    */
  70. #define PS_metric 72
  71.  
  72. #ifdef NO_INFO
  73. #define FONTSIZE 0
  74. #else
  75. #define FONTSIZE 3
  76. #endif
  77.  
  78.  
  79.  
  80.  
  81. int endian = 0;
  82.  
  83. static char sccsid[]="@(#)tifftoeps   1.0  (SFSU)  9/15/89";
  84.  
  85. int iwidth=0, ilen=0, invert=255, compr = 1;
  86. long stripoff=0L, strip_b_count=0L,strips_p_image=0L;
  87. short str_off_typ,str_b_typ;
  88.  
  89. int vsiz[6] = {{255},{sizeof(unsigned char)},{sizeof(unsigned char)},
  90.             {sizeof(unsigned short)},{sizeof(long)},{2*sizeof(long)}};
  91.             
  92. struct ifdent {
  93.     unsigned short ifd_tag;
  94.     unsigned short ifd_type;
  95.     long ifd_len;
  96.     union {
  97.         unsigned long ifd_long;
  98.         unsigned short ifd_short[2];
  99.         unsigned char ifd_byte[4];
  100.     } ifd_off;
  101. };
  102.  
  103. void quit(int rc, char *outf)
  104. {
  105.     extern int unlink(char *);
  106.     
  107.     if(strcmp(outf,"-"))
  108.     unlink(outf);
  109.     exit(rc);
  110. }
  111.  
  112. #ifndef NO_INFO
  113. unsigned char *unparen(unsigned char *s)
  114. {
  115.     int parcount;
  116.     unsigned char *t,*tt;
  117.     
  118.     if(s == (unsigned char *)0)
  119.     return ("");
  120.     
  121.     t = (char *)s;
  122.     parcount = 0;
  123.     while(*s++)
  124.     if((*s == '(') || (*s == ')'))
  125.         parcount++;
  126.     
  127.     if(parcount != 0){
  128.     s = (unsigned char *)t;
  129.     tt = t = (unsigned char *)malloc(strlen(s)+1 + parcount);
  130.     assert(t != (char *)0);
  131.     while(*s){
  132.         if((*s == '(') || (*s == ')'))
  133.         *t++ = '\\';
  134.         *t++ = *s++;
  135.     }
  136.     *t = '\0';
  137.     t = tt;
  138.     free(s);
  139.     }
  140.     return (t);
  141. }
  142. #endif /* NO_INFO */
  143.  
  144.  
  145. int readid(FILE *f)
  146. {
  147.     long id;
  148.     
  149.     if(fread(&id, sizeof(id), 1, f) != 1) {
  150.     perror("fread in readid");
  151.     exit(1);
  152.     }
  153.     return (id==0x4d4d002a ? BIG_END : (id == 0x49492a00 ? LITTLE_END : 0));
  154. }
  155.  
  156. void longfread(long *l, size_t n, FILE *f)
  157. {
  158.     unsigned char *from, *to;
  159.     unsigned char buf;
  160.     
  161.     for(;n;n--){
  162.     from = (unsigned char *)l;
  163.     if(fread(l,sizeof(long),1,f) != 1) {
  164.         perror("fread in longfread");
  165.         exit(1);
  166.     }
  167.     if(endian == LITTLE_END){
  168.         to = from + sizeof(long) - 1;
  169.         while(from < to){
  170.         buf = *from;
  171.         *from++ = *to;
  172.         *to-- = buf;
  173.         }
  174.     }
  175.     l++;
  176.     }
  177. }
  178.     
  179. void shortfread(unsigned short *l, size_t n, FILE *f)
  180. {
  181.     unsigned char *from, *to;
  182.     unsigned char buf;
  183.     
  184.     for(;n;n--){
  185.     from = (unsigned char *)l;
  186.     if(fread(l,sizeof(short),1,f) != 1) {
  187.         perror("fread in shortfread");
  188.         exit(1);
  189.     }
  190.     if(endian == LITTLE_END){
  191.         to = from + sizeof(short) - 1;
  192.         while(from < to){
  193.         buf = *from;
  194.         *from++ = *to;
  195.         *to-- = buf;
  196.         }
  197.     }
  198.     l++;
  199.     }
  200. }
  201.     
  202. int get_tiff_img_byte(FILE *f,char *ofname)
  203. {
  204.     static long bytes_left=0,stripstart,i,position=0;
  205.     int c,j;
  206.     static int curstrip=0;
  207.     static unsigned char *unpacked=(unsigned char *)0;
  208.     unsigned short shtemp;
  209.     
  210.     if(bytes_left==0){
  211.     if(strips_p_image<=0){
  212.         return(EOF);
  213.     }
  214.     if(strips_p_image>1){
  215.         if (fseek(stdin, strip_b_count + curstrip * (str_b_typ==3 ? sizeof(short) :
  216.         sizeof(long)), 0)<0L) {
  217.             perror("fseek");
  218.             quit(1,ofname);
  219.         }
  220.         if(str_b_typ==3){
  221.         shortfread(&shtemp,1,f);
  222.         bytes_left = (long)shtemp;
  223.         }
  224.         else{
  225.         longfread(&bytes_left,1,f);
  226.         }
  227.     }
  228.     else{
  229.         bytes_left = strip_b_count;
  230.     }
  231.     if(strips_p_image>1){
  232.         if (fseek(stdin, stripoff + curstrip * (str_off_typ==3 ? sizeof(short) :
  233.         sizeof(long)), 0)<0L) {
  234.             perror("fseek");
  235.             quit(1,ofname);
  236.         }
  237.         if(str_off_typ==3){
  238.         shortfread(&shtemp,1,f);
  239.         stripstart = (long)shtemp;
  240.         }
  241.         else{
  242.         longfread(&stripstart,1,f);
  243.         }
  244.     }
  245.     else{
  246.         stripstart = stripoff;
  247.     }
  248.     if (fseek(stdin, stripstart, 0)<0L) {
  249.         perror("fseek");
  250.         quit(1,ofname);
  251.     }
  252.     strips_p_image--;
  253.     curstrip++;
  254.     }
  255.     switch(compr){
  256.     case 1:
  257.         c = fgetc(f);
  258.     break;
  259.     case 32773:
  260.     if(position==0){
  261.         if(unpacked != (unsigned char *)0){
  262.         free(unpacked);
  263.         }
  264.         unpacked = (unsigned char *)malloc(bytes_left);
  265.         assert(unpacked != (unsigned char *)0);
  266.         /* start unpacking    */
  267.         i = 0;
  268.         while(i<bytes_left){
  269.         c = fgetc(f);
  270.         if(c == EOF){
  271.             fprintf(stderr,"Invalid TIFF-File. Missing data.\n");
  272.             quit(4,ofname);
  273.         }
  274.         if((c>=0) && (c<=127)){
  275.             for(j=0;j<=c;j++)
  276.             unpacked[i++] = fgetc(f);
  277.         }
  278.         else{
  279.             if(c!=128){
  280.             j = 1-(int)(signed char)c;
  281.             c = fgetc(f);
  282.             while(j--)
  283.                 unpacked[i++] = c;
  284.             }
  285.         }
  286.         }
  287.     }
  288.     c = unpacked[position++];
  289.     break;
  290.     default:
  291.         fprintf(stderr,"This error can never hapen!!\n");
  292.     quit(5,ofname);
  293.     break;
  294.     }
  295.     bytes_left--;
  296.     return(c);
  297. }
  298.         
  299.     
  300.  
  301.  
  302. int ifditemfread(struct ifdent *l, size_t n, FILE *f)
  303. {
  304.     long buf;
  305.     
  306.     for(;n;n--){
  307.     shortfread(&(l->ifd_tag),1,f);
  308.     shortfread(&(l->ifd_type),1,f);
  309.     longfread(&(l->ifd_len),1,f);
  310.     if(l->ifd_len*vsiz[l->ifd_type]<sizeof(long)){
  311.         switch(l->ifd_type){
  312.         case 1:
  313.         case 2:
  314.         if(fread(&(l->ifd_off.ifd_byte[0]), sizeof(unsigned char),
  315.              l->ifd_len,f) !=1 ){
  316.             perror("fread in ifditemread");
  317.             return(1);
  318.         }
  319.         if(fread((char *)&buf,sizeof(unsigned char),
  320.             4-l->ifd_len,f)!=4-l->ifd_len){
  321.             perror("fread in ifditemread");
  322.             return(1);
  323.         }
  324.     
  325.         break;
  326.         case 3:
  327.         shortfread(&(l->ifd_off.ifd_short[0]),2-l->ifd_len,f);
  328.         if(l->ifd_len < 2)
  329.             shortfread((unsigned short *)&buf,1,f);
  330.         break;
  331.         default:
  332.         fprintf(stderr,"ifdfread: unsupported type %d tag %d len %d.\n",
  333.         l->ifd_type,l->ifd_tag,l->ifd_len);
  334.         return(2);
  335.         }
  336.     }
  337.     else {
  338.         longfread((long *)&(l->ifd_off.ifd_long),1,f);
  339.     }
  340.     l++;
  341.     }
  342.     return(0);
  343. }
  344.     
  345.  
  346.     
  347.  
  348. int main(int argc, char *argv[])
  349. {
  350.     register int i;
  351.     register long value;
  352.     long sig, ifdoff,rows_p_strip=0L;
  353.     unsigned short ifditems,bits;
  354.     unsigned short values[2],res_unit,cel_len,cel_wid,thresh;
  355.     unsigned char valuec[4];
  356.     struct ifdent *ifdp;
  357.     char *resolname[4]={"NA","Undef.","\"","cm"};
  358.     char *thrname[4]={"NA","line art","dithered","error diffused"};
  359.     long xres[2],yres[2],white[2],primchrom[2],xscale,yscale;
  360.     unsigned char *artist,*datetime,*hostcomputer,
  361.             *imagedesc,*make,*model,*software;
  362.  
  363.     artist = datetime = hostcomputer = (unsigned char *)0;
  364.     imagedesc = make = model = software = (unsigned char *)0;
  365.     res_unit = 0;
  366.     thresh = 0;
  367.     cel_len = cel_wid = 0;
  368.     xres[0] = xres[1] = yres[0] = yres[1] = 0L;
  369.  
  370.      if (argc!=3) {
  371.         fprintf(stderr, "Usage: %s tiff-file eps-file\n", *argv);
  372.         exit(1);
  373.     }
  374.     if (strcmp(argv[1], "-")&&!freopen(argv[1], "r", stdin)) {
  375.         perror(argv[0]);
  376.         exit(1);
  377.     }
  378.     if (strcmp(argv[2], "-")&&!freopen(argv[2], "w", stdout)) {
  379.         perror(argv[2]);
  380.         exit(1);
  381.     }
  382.     if (!(endian = readid(stdin))) {
  383.         fprintf(stderr, "%s: that's not a TIFF file!\n", argv[0]);
  384.         quit(1,argv[2]);
  385.     }
  386.     longfread(&ifdoff, 1, stdin);
  387.     if (fseek(stdin, ifdoff, 0)<0L) {
  388.         perror("fseek");
  389.         quit(1,argv[2]);
  390.     }
  391.     shortfread(&ifditems, 1, stdin);
  392.     if (!(ifdp=(struct ifdent *)malloc(ifditems*sizeof (struct ifdent)))) {
  393.         perror("malloc");
  394.         quit(1,argv[2]);
  395.     }
  396.     if(ifditemfread(ifdp, ifditems, stdin))
  397.         quit(3,argv[2]);
  398.     for (i=0;i<ifditems;i++) {
  399.         switch (ifdp->ifd_type) {
  400.         case 1:
  401.         case 2:
  402.             if(ifdp->ifd_len > 4){
  403.                 if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
  404.                     perror("fseek");
  405.                     quit(1,argv[2]);
  406.                 }
  407.             }
  408.             else {
  409.                 valuec[0] = ifdp->ifd_off.ifd_byte[0];
  410.                 valuec[1] = ifdp->ifd_off.ifd_byte[1];
  411.                 valuec[2] = ifdp->ifd_off.ifd_byte[2];
  412.                 valuec[3] = ifdp->ifd_off.ifd_byte[3];
  413.             }
  414.             break;
  415.         case 3:
  416.             if(ifdp->ifd_len > 2){
  417.                 if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
  418.                     perror("fseek");
  419.                     quit(1,argv[2]);
  420.                 }
  421.             }
  422.             else {
  423.                 values[0]=ifdp->ifd_off.ifd_short[0];
  424.                 values[1]=ifdp->ifd_off.ifd_short[1];
  425.             }
  426.             break;
  427.         case 4:
  428.             if(ifdp->ifd_len > 1){
  429.                 if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
  430.                     perror("fseek");
  431.                     quit(1,argv[2]);
  432.                 }
  433.             }
  434.             else
  435.                 value=ifdp->ifd_off.ifd_long;
  436.             break;
  437.         case 5:
  438.             if (fseek(stdin, ifdp->ifd_off.ifd_long, 0L)<0L) {
  439.                 perror("fseek");
  440.                 quit(1,argv[2]);
  441.             }
  442.             break;
  443.         default: /* ifdp->ifd_off.ifd_long is offset */
  444.             value=0L;    /* do The Wrong Thing(tm) */
  445.             break;
  446.         }
  447. /**********     Analyze Tags *************/
  448.         switch (ifdp->ifd_tag) {
  449.         case 255:    /* SubfileType - not recommended (ignored)    */
  450.             break;
  451.         case 256:    /* ImageWidth */
  452.             iwidth=values[0];
  453.             break;
  454.         case 257:    /* ImageLength */
  455.             ilen=values[0];
  456.             break;
  457.         case 258:    /* BitsPerSample */
  458.             bits=values[0];
  459.             break;
  460.         case 259:    /* Compression */
  461.             compr = values[0];
  462.             if ((values[0]!=1) && (values[0]!=32773)) {
  463.                 fprintf(stderr, "%s: Compression=%ld\n",
  464.                     argv[1], values[0]);
  465.                 quit(1,argv[2]);
  466.             }
  467.             break;
  468.         case 262:    /* PhotometricInterpretation */
  469.             switch (values[0]) {
  470.             case 0:
  471.                 invert=255;
  472.                 break;
  473.             case 1:
  474.                 invert=0;
  475.                 break;
  476.             default:
  477.                 fprintf(stderr,
  478.                     "%s: PhotometricInterpretation=%ld\n",
  479.                          argv[0], values[0]);
  480.                 if (values[0]==5)
  481.                     fputs("\tI don't grok alpha\n",stderr);
  482.                 quit(1,argv[2]);
  483.                 break;
  484.             }
  485.             break;
  486.         case 263:    /* Thresholding - not recommended */
  487.             thresh = values[0];
  488.             break;
  489.         case 264:    /* CellWidth - not recommended    */
  490.             cel_wid = values[0];
  491.             break;
  492.         case 265:    /* CellLength - not recommended    */
  493.             cel_len = values[0];
  494.             break;
  495.         case 270:    /* Image description */
  496.             imagedesc = malloc(ifdp->ifd_len+1);
  497.             assert(imagedesc != (unsigned char *)0);
  498.             if(ifdp->ifd_len>4){
  499.                 if(fread((char *)imagedesc,sizeof(unsigned char),
  500.                     ifdp->ifd_len,stdin) != ifdp->ifd_len){
  501.                 perror("Reading image description");
  502.                 free(imagedesc);
  503.                 imagedesc = (unsigned char *)0;
  504.                 }
  505.             }
  506.             else
  507.                 strcpy(imagedesc,ifdp->ifd_off.ifd_byte);
  508.             if(imagedesc != (unsigned char *)0)
  509.                 imagedesc[ifdp->ifd_len] = '\0';
  510.             break;
  511.         case 271:    /* Make */
  512.             make = malloc(ifdp->ifd_len+1);
  513.             assert(make != (unsigned char *)0);
  514.             if(ifdp->ifd_len>4){
  515.                 if(fread((char *)make,sizeof(unsigned char),
  516.                     ifdp->ifd_len,stdin) != ifdp->ifd_len){
  517.                 perror("Reading Make");
  518.                 free(make);
  519.                 make = (unsigned char *)0;
  520.                 }
  521.             }
  522.             else
  523.                 strcpy(make,ifdp->ifd_off.ifd_byte);
  524.             if(make != (unsigned char *)0)
  525.                 make[ifdp->ifd_len] = '\0';
  526.             break;
  527.         case 272:    /* Model */
  528.             model = malloc(ifdp->ifd_len+1);
  529.             assert(model != (unsigned char *)0);
  530.             if(ifdp->ifd_len>4){
  531.                 if(fread((char *)model,sizeof(unsigned char),
  532.                     ifdp->ifd_len,stdin) != ifdp->ifd_len){
  533.                 perror("Reading Model");
  534.                 free(model);
  535.                 model = (unsigned char *)0;
  536.                 }
  537.             }
  538.             else
  539.                 strcpy(model,ifdp->ifd_off.ifd_byte);
  540.             if(model != (unsigned char *)0)
  541.                 model[ifdp->ifd_len] = '\0';
  542.             break;
  543.         case 273:
  544.             stripoff=(long)ifdp->ifd_type==3 ? values[0] : value;
  545.             break;
  546.         case 277:    /* SamplesPerPixel */
  547.             if (values[0]!=1) {
  548.                 fprintf(stderr, "%s: SamplesPerPixel=%ld\n",
  549.                     argv[0], values[0]);
  550.                 quit(1,argv[2]);
  551.             }
  552.             break;
  553.         case 278:    /* RowsPerStrip        */
  554.             rows_p_strip=(long)ifdp->ifd_type==3 ? values[0] : value;
  555.             break;
  556.         case 279:    /* StripByteCount        */
  557.             strip_b_count=(long)ifdp->ifd_type==3 ? values[0] : value;
  558.             break;
  559.         case 282:/* XResolution RATIONAL    */
  560.             longfread((long *)&xres,2,stdin);
  561.             break;
  562.         case 283:/* YResolution            */
  563.             longfread((long *)&yres,2,stdin);
  564.             break;
  565.  
  566.         case 284:    /* PlanarConfiguration */
  567.             break;
  568.  
  569.         case 296:/* Resolution Unit        */
  570.             res_unit = values[0];
  571.             break;
  572.         case 305:    /* Software */
  573.             software = malloc(ifdp->ifd_len+1);
  574.             assert(software != (unsigned char *)0);
  575.             if(ifdp->ifd_len>4){
  576.                 if(fread((char *)software,sizeof(unsigned char),
  577.                     ifdp->ifd_len,stdin) != ifdp->ifd_len){
  578.                 perror("Reading Software");
  579.                 free(software);
  580.                 software = (unsigned char *)0;
  581.                 }
  582.             }
  583.             else
  584.                 strcpy(software,ifdp->ifd_off.ifd_byte);
  585.             if(software != (unsigned char *)0)
  586.                 software[ifdp->ifd_len] = '\0';
  587.             break;
  588.         case 306:    /* DateTime */
  589.             datetime = malloc(ifdp->ifd_len+1);
  590.             assert(datetime != (unsigned char *)0);
  591.             if(ifdp->ifd_len>4){
  592.                 if(fread((char *)datetime,sizeof(unsigned char),
  593.                     ifdp->ifd_len,stdin) != ifdp->ifd_len){
  594.                 perror("Reading DateTime");
  595.                 free(datetime);
  596.                 datetime = (unsigned char *)0;
  597.                 }
  598.             }
  599.             else
  600.                 strcpy(datetime,ifdp->ifd_off.ifd_byte);
  601.             if(datetime != (unsigned char *)0)
  602.                 datetime[ifdp->ifd_len] = '\0';
  603.             break;
  604.         case 315:    /* Artist */
  605.             artist = malloc(ifdp->ifd_len+1);
  606.             assert(artist != (unsigned char *)0);
  607.             if(ifdp->ifd_len>4){
  608.                 if(fread((char *)artist,sizeof(unsigned char),
  609.                     ifdp->ifd_len,stdin) != ifdp->ifd_len){
  610.                 perror("Reading Artist");
  611.                 free(artist);
  612.                 artist = (unsigned char *)0;
  613.                 }
  614.             }
  615.             else
  616.                 strcpy(artist,ifdp->ifd_off.ifd_byte);
  617.             if(artist != (unsigned char *)0)
  618.                 artist[ifdp->ifd_len] = '\0';
  619.             break;
  620.         case 316:    /* HostComputer */
  621.             hostcomputer = malloc(ifdp->ifd_len+1);
  622.             assert(hostcomputer != (unsigned char *)0);
  623.             if(ifdp->ifd_len>4){
  624.                 if(fread((char *)hostcomputer,sizeof(unsigned char),
  625.                     ifdp->ifd_len,stdin) != ifdp->ifd_len){
  626.                 perror("Reading HostComputer");
  627.                 free(hostcomputer);
  628.                 hostcomputer = (unsigned char *)0;
  629.                 }
  630.             }
  631.             else
  632.                 strcpy(hostcomputer,ifdp->ifd_off.ifd_byte);
  633.             if(hostcomputer != (unsigned char *)0)
  634.                 hostcomputer[ifdp->ifd_len] = '\0';
  635.             break;
  636.         case 318:/* WhitePoint            */
  637.             longfread((long *)&white,2,stdin);
  638.             break;
  639.         case 319:/* PrimaryChromaticities    */
  640.             longfread((long *)&primchrom,2,stdin);
  641.             break;
  642.         default:
  643.             fprintf(stderr,"%s:Unknown tag %d - ignored\n",
  644.                 argv[0],ifdp->ifd_tag);
  645.             break;
  646.         }
  647.         ifdp++;
  648.     }
  649.     if (iwidth<=0L) {
  650.         fprintf(stderr, "%s: missing ImageWidth\n", argv[0]);
  651.         quit(1,argv[2]);
  652.     }
  653.     if (ilen<=0L) {
  654.         fprintf(stderr, "%s: missing ImageLength\n", argv[0]);
  655.         quit(1,argv[2]);
  656.     }
  657.     if (bits<=0L) {
  658.         fprintf(stderr, "%s: missing BitsPerSample\n", argv[0]);
  659.         quit(1,argv[2]);
  660.     }
  661.     sig=(((long)iwidth*bits+7L)/8L)*ilen;
  662.     if (stripoff<=0L) {
  663.         fprintf(stderr, "%s: missing StripOffsets\n", argv[0]);
  664.         quit(1,argv[2]);
  665.     }
  666.     if (rows_p_strip<=0L) {
  667.         strips_p_image = 1;
  668.     }
  669.     else{
  670.         strips_p_image = (ilen + rows_p_strip - 1)/rows_p_strip;
  671.     }
  672.     if(strip_b_count==0){
  673.          if(strips_p_image==1){
  674.          strip_b_count = sig;
  675.          }
  676.          else{
  677.          fprintf(stderr,"Can't handle multiple strips without bytecount.\n");
  678.          quit(1,argv[2]);
  679.          }
  680.      }
  681. /*****************************************************
  682. *
  683. * If tags XResolution and/or YResolution are present (and != 0) they are used to size
  684. * the image to the original size.
  685. * If you don't want that feature, just set xscal = iwidth and yscale = ilen.
  686. *
  687. ******************************************************/    
  688.     if((xres[1]==0L) || (xres[0]/xres[1] == 0L))
  689.         xscale = iwidth;
  690.     else
  691.         xscale = (PS_metric*iwidth)/(xres[0]/xres[1]);
  692.     if((yres[1]==0L) || (yres[0]/yres[1] == 0L))
  693.         yscale = ilen;
  694.     else
  695.         yscale =  (PS_metric*ilen)/(yres[0]/yres[1]);
  696.     fputs("%!PS-Adobe-2.0 EPSF-1.2\n%%Creator:tifftoeps\n\
  697. %%Origin:0 720\n%%BoundingBox: 0 0 ", stdout);
  698.     printf("%ld %ld", xscale, yscale+2*(FONTSIZE+4));
  699.     fputs("\n%%DocumentFonts: Helvetica",stdout);
  700.     fputs("\n%%EndComments\n/picstr ", stdout);
  701.     printf("%ld", ((long)iwidth*bits+7L)/8L);
  702.     printf(" string def\ngsave\n0 %d translate\n1 1 scale\n",(FONTSIZE+2));
  703. #ifndef NO_INFO
  704.     printf("gsave\n");
  705. #endif
  706.     printf("%ld %ld scale\n%d %d %d\n", xscale, yscale, iwidth, ilen, bits);
  707.     printf("[%d 0 0 %d neg 0 %d]\n", iwidth, ilen, ilen);
  708.     fputs("{currentfile picstr readhexstring pop}\nimage", stdout);
  709.     value=0L; while ((i=get_tiff_img_byte(stdin,argv[2]))!=EOF) {
  710.         if (value>=sig) break;
  711.         if ((value&31)==0) putchar('\n');
  712.         printf("%02X", i^invert);
  713.         value++;
  714.     }
  715.     if(value<sig){
  716.         fprintf(stderr,"Insufficient data read %ld expected %ld.\n",value,sig);
  717.     }
  718. #ifndef NO_INFO
  719.     fputs("\n\n\ngrestore\n", stdout);
  720.     printf("0 -%d moveto\n/Helvetica %d selectfont\n",FONTSIZE+2,FONTSIZE);
  721.     fputs("0 setgray\n",stdout);
  722.     printf("(File : %s   ",argv[1]);
  723.     if(imagedesc != (unsigned char *)0)
  724.         printf("I-desc : %s  ",unparen(imagedesc));
  725.     if(datetime != (unsigned char *)0)
  726.         printf("Date : %s  ",unparen(datetime));
  727.     if(artist != (unsigned char *)0)
  728.         printf("Artist : %s  ",unparen(artist));
  729.     if(cel_wid > 0)
  730.         printf("CelWid : %d  ",cel_wid);
  731.     if(cel_len > 0)
  732.         printf("CelLen : %d  ",cel_len);
  733.     printf("thr : %s  Bits : %d",thrname[thresh],bits);
  734.     printf(") show\n");
  735.  
  736.     printf("0 %d moveto\n(",yscale+2);
  737.     if(hostcomputer != (unsigned char *)0)
  738.         printf("Host : %s  ",unparen(hostcomputer));
  739.     if(model != (unsigned char *)0)
  740.         printf("Model : %s  ",unparen(model));
  741.     if(make != (unsigned char *)0)
  742.         printf("Make : %s  ",unparen(make));
  743.     if(software != (unsigned char *)0)
  744.         printf("Software : %s  ",unparen(software));
  745.         
  746.     if((xres[1]!=0L) && (yres[0]!=0L)){
  747.         printf("  XRes x YRes : %g x %g [%s] Pixels: %d x %d",
  748.             (double)xres[0]/(double)xres[1],(double)yres[0]/(double)yres[1],
  749.             resolname[res_unit],iwidth,ilen);
  750.     }
  751.     printf(") show\n");
  752. #endif /* NO_INFO */
  753.     exit(0);
  754. }
  755.  
  756.