home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / pbm / tifftopbm.c < prev    next >
C/C++ Source or Header  |  1980-12-04  |  14KB  |  525 lines

  1. /*
  2. **---------------------------------------------------------------------
  3. ** tifftopbm.c
  4. **---------------------------------------------------------------------
  5. **
  6. **      Copyright 1988 by Paul J. Emerson 
  7. **                                                                     
  8. **      Permission to use, copy, modify, and distribute this software 
  9. **      and its documentation for any purpose and without fee is        
  10. **      hereby granted, provided that the above copyright notice        
  11. **      appear in all copies and that both that copyright notice and    
  12. **      this permission notice appear in supporting documentation, and  
  13. **      that the name of Paul J. Emerson not be used in advertising or 
  14. **      publicity pertaining to distribution of the software without 
  15. **      specific, written prior permission.  Paul J. Emerson makes no 
  16. **      representations about the suitability of this software for 
  17. **      any purpose.  It is provided "as is" without express or implied 
  18. **      warranty.          
  19. **
  20. **      Version 1.4
  21. **        Jef Poskanzer  (jef@helios.ee.lbl.gov)
  22. **        April 1989
  23. **
  24. **        Comments
  25. **          - Now uses new PBM error handling routine.
  26. **
  27. **    Version 1.3
  28. **      Lindsay F. Marshall (Lindsay.Marshall@newcastle.ac.uk)
  29. **      January 1989
  30. **
  31. **      Comments
  32. **        - Removed include of malloc.h and added extern for malloc.
  33. **
  34. **      Version 1.2
  35. **        Jef Poskanzer  (jef@rtsg.ee.lbl.gov)
  36. **        January 1989
  37. **
  38. **        Comments
  39. **          - Patch from Mike K. Peterson (mkp@hac2arpa.hac.com) to handle
  40. **            MicroTek VersaScan variant.
  41. **
  42. **      Version 1.1
  43. **        Jef Poskanzer  (jef@rtsg.ee.lbl.gov)
  44. **        December 1988
  45. **
  46. **        Comments
  47. **          - Changed name from tiff2pbm to tifftopbm.
  48. **          - Changed to use libpbm routines.
  49. **
  50. **      Version 1.0
  51. **        Paul J. Emerson  (ucf-cs!sdgsun!paul) 
  52. **        December 1988
  53. **
  54. **        Comments
  55. **          - TIFF Support:
  56. **            - Single Bit Plane
  57. **            - Black & White (No grey scale or color)
  58. **            - Uncompressed TIFF 
  59. **          - Supports PBM magic number
  60. **            - Usage: tifftopbm [-h] tifffile
  61. **                   -h  Dump TIFF file header info to stderr
  62. **                       This may be helpful in detecting unsuported aspects
  63. **                       of the TIFF file format.
  64. **
  65. **      Notes:
  66. **        Compile: cc -O tifftopbm.c -o tifftopbm
  67. **
  68. **---------------------------------------------------------------------
  69. */
  70.  
  71. #include <stdio.h>
  72. #include <fcntl.h>
  73. #include <errno.h>
  74. #include "tiff.h"
  75. #include "pbm.h"
  76.  
  77. #define TRUE  1
  78. #define FALSE 0
  79.  
  80. main(argc,argv)
  81. int argc;
  82. char *argv[];
  83. {
  84. int fd,
  85.     Dump=FALSE;
  86. struct Tiffstruct Tiff;
  87. struct TiffHeader Header;
  88. char fname[255];
  89. char *usage = "[-h] tifffile";
  90.  
  91.            pm_progname = argv[0];
  92.  
  93.        if (argc >= 2) 
  94.           {
  95.           if (!strcmp("-h",argv[1]))
  96.              {
  97.              Dump = TRUE;
  98.              if (argc == 3)
  99.                 strcpy(fname,argv[2]); 
  100.              else
  101.                 {
  102.                 printf(usage,argv[0]);
  103.                 exit(1); 
  104.                 }
  105.              }
  106.           else
  107.              strcpy(fname,argv[1]); 
  108.  
  109.           if ((fd = open(fname,O_RDONLY)) < 0 )
  110.              {
  111.              perror(fname);
  112.          exit(1); 
  113.              }
  114.           }
  115.        else
  116.           {
  117.           printf(usage,argv[0]);
  118.           exit(1); 
  119.           }
  120.  
  121.     if (readTiff(&Tiff,&Header,fd))
  122.        {
  123.        if (Dump)
  124.           dumpHeader(&Tiff,&Header);
  125.        PbmOut(fd,&Tiff);
  126.        }
  127.     else
  128.        pm_error( "readTiff failure", 0,0,0,0,0 );
  129.     close(fd);
  130.  
  131. }
  132.  
  133. /*
  134. **------------------------------------------------------------------------
  135. **  Send image to stdout in PBM format
  136. **------------------------------------------------------------------------
  137. */
  138. PbmOut(fd,t)
  139. int fd;
  140. struct Tiffstruct *t;
  141. {
  142. register int i, row;
  143. char *bptr;
  144. LONG *cntptr;
  145. LONG *dataptr;
  146. register bit **bits;
  147.  
  148. extern char *malloc();
  149.  
  150.     bits = pbm_allocarray(t->ImageWidth,t->ImageLength);
  151.     
  152.     dataptr = t->StripOffset;
  153.     cntptr  = t->SBytesCntOffset;
  154.  
  155.     for (i=0, row=0; i < t->StOffsetCnt; i++, row += t->RowsStrip)
  156.         {
  157.  
  158.         lseek(fd,(long) *dataptr,0);
  159.         bptr = malloc(*cntptr);
  160.         if ( bptr == 0 )
  161.         pm_error( "out of memory", 0,0,0,0,0 );
  162.         if  (read(fd,bptr,*cntptr) != *cntptr)
  163.             {
  164.             perror("StripOffset read ");
  165.         return;
  166.             }
  167.  
  168.         PbmDoRow(bptr,*cntptr,bits,row,t->ImageWidth);
  169.  
  170.         free(bptr);
  171.         cntptr++;
  172.         dataptr++;
  173.         }
  174.  
  175.     pbm_writepbm(stdout,bits,t->ImageWidth,t->ImageLength);
  176. }
  177. /*
  178. **------------------------------------------------------------------------
  179. ** Output a row in PBM format 
  180. **------------------------------------------------------------------------
  181. */
  182. PbmDoRow(buffer,count,bits,row,cols)
  183. char *buffer;
  184. int count;
  185. bit **bits;
  186. int row, cols;
  187. {
  188. register int i, col;
  189.  
  190.     col = 0;
  191.     while (count--)
  192.           {
  193.           for (i = 0 ; i < 8; i++)
  194.               {
  195.              bits[row][col++] =
  196.              ( ( *buffer << i ) & 0x80 ) ? PBM_BLACK : PBM_WHITE;
  197.          if ( col >= cols )
  198.              {
  199.              col = 0;
  200.              row++;
  201.              }
  202.              }
  203.           buffer++;
  204.           }
  205. }
  206.  
  207. /*
  208. **------------------------------------------------------------------------
  209. ** Read and decode a Tiff header. 
  210. ** Not all TIFF capabilities are supported. Only single plane bit maps. 
  211. **------------------------------------------------------------------------
  212. */
  213. int
  214. readTiff(T,H,fd)
  215. struct Tiffstruct *T;
  216. struct TiffHeader *H;
  217. int fd;
  218. {
  219. struct IDF idf;
  220. struct IDF_Entry  *ptr; 
  221. LONG TempRational[2];
  222.  
  223. #ifdef SYSV
  224.     memset((char *)T,0,sizeof(struct Tiffstruct));
  225. #else SYSV
  226.     bzero((char *)T,sizeof(struct Tiffstruct));
  227. #endif SYSV
  228.  
  229.     if (read(fd,H,sizeof(struct TiffHeader)) != sizeof(struct TiffHeader))
  230.        {
  231.        perror("Header "); 
  232.        return(FALSE);
  233.        }
  234.  
  235.     lseek(fd,(long)H->IdfOffset,0);
  236.  
  237.     if (read(fd,&idf.NumEntries,sizeof(SHORT)) != sizeof(SHORT))
  238.        {
  239.        perror("Idf count "); 
  240.        return(FALSE);
  241.        }
  242.  
  243.     if ((idf.idfptr = (struct IDF_Entry *)
  244.                       calloc(idf.NumEntries,sizeof(struct IDF_Entry))) == NULL)
  245.        {
  246.        perror("calloc ");
  247.        return(FALSE);
  248.        }
  249.  
  250.     if (read(fd,idf.idfptr,idf.NumEntries*sizeof(struct IDF_Entry))
  251.                != idf.NumEntries*sizeof(struct IDF_Entry))
  252.        {
  253.        perror("Idf count "); 
  254.        return(FALSE);
  255.        }
  256.  
  257.     ptr = idf.idfptr;
  258.  
  259.     while (idf.NumEntries--)
  260.           {
  261.           switch (ptr->Tag)
  262.                  {
  263.            case  0x00FF:
  264.                  T->SubFileType = (ptr->ValueOffset >> 16);
  265.                  break;
  266.                     
  267.            case  0x0100:
  268.                  T->ImageWidth = (ptr->ValueOffset >> 16);
  269.                  break;
  270.  
  271.            case  0x0101:
  272.                  T->ImageLength = (ptr->ValueOffset >> 16);
  273.                  break;
  274.  
  275.            case  0x0102:
  276.                  T->BitsPerSample = (ptr->ValueOffset >> 16);
  277.                  break;
  278.  
  279.            case  0x0103:
  280.                  T->Compression = (ptr->ValueOffset >> 16);
  281.                  break;
  282.  
  283.            case  0x0106:
  284.                  T->PhotoInterp = (ptr->ValueOffset >> 16);
  285.                  break;
  286.  
  287.            case  0x0107:
  288.                  T->Threshold = (ptr->ValueOffset >> 16);
  289.                  break;
  290.  
  291.            case  0x0108:
  292.                  T->CellWidth = (ptr->ValueOffset >> 16);
  293.                  break;
  294.  
  295.            case  0x0109:
  296.                  T->CellLength = (ptr->ValueOffset >> 16);
  297.                  break;
  298.  
  299.            case  0x010A:
  300.                  T->FillOrder = (ptr->ValueOffset >> 16);
  301.                  break;
  302.  
  303.            case  0x010D:
  304.                  fprintf(stderr,"Unsupported feature\n");
  305.                  /*
  306.                  lseek(fd,(long)ptr->ValueOffset,0);
  307.                  */
  308.                  break;
  309.  
  310.            case  0x010E:
  311.                  fprintf(stderr,"Unsupported feature\n");
  312.                  /*
  313.                  lseek(fd,(long)ptr->ValueOffset,0);
  314.                  */
  315.                  break;
  316.  
  317.            case  0x010F:
  318.                  /*
  319.                  lseek(fd,(long)ptr->ValueOffset,0);
  320.                  */
  321.                  fprintf(stderr,"Make: %s\n", T->Make); 
  322.                  break;
  323.  
  324.            case  0x0110:
  325.                  fprintf(stderr,"Unsupported feature\n");
  326.                  /*
  327.                  lseek(fd,(long)ptr->ValueOffset,0);
  328.                  */
  329.                  break;
  330.  
  331.            case  0x0111:
  332.                  T->StOffsetCnt = ptr->Length;
  333.                  if ((T->StripOffset = (LONG *) calloc(T->StOffsetCnt,
  334.                                                  sizeof (LONG)))== NULL)
  335.                     {
  336.                     perror("calloc Soffset ");
  337.                     return(FALSE); 
  338.                     }
  339.              if(T->StOffsetCnt == 1)
  340.                 *(T->StripOffset) = ptr->ValueOffset;
  341.              else
  342.                 {
  343.             lseek(fd, (long) ptr->ValueOffset, 0);
  344.             read(fd, T->StripOffset, T->StOffsetCnt * sizeof(LONG));
  345.             }
  346.                  break;
  347.  
  348.            case  0x0112:
  349.                  T->Orientation= (ptr->ValueOffset >> 16);
  350.                  break;
  351.  
  352.            case  0x0115:
  353.                  T->SamplesPixel= (ptr->ValueOffset >> 16);
  354.                  break;
  355.  
  356.            case  0x0116:
  357.                  T->RowsStrip= (ptr->ValueOffset);
  358.                  break;
  359.  
  360.            case  0x0117:
  361.                  T->StripByteCnt = (ptr->Length);
  362.                  if ((T->SBytesCntOffset = (LONG *) calloc(T->StripByteCnt,
  363.                                                  sizeof (LONG)))== NULL)
  364.                     {
  365.                     perror("calloc StripByteCnt ");
  366.                     return(FALSE); 
  367.                     }
  368.             if(T->StripByteCnt == 1)
  369.             *(T->SBytesCntOffset) = ptr->ValueOffset;
  370.              else
  371.             {
  372.             lseek(fd,(long)ptr->ValueOffset,0);
  373.             read(fd,T->SBytesCntOffset,T->StripByteCnt*sizeof(LONG));
  374.             }
  375.                  break;
  376.  
  377.            case  0x0118:
  378.                  T->MinSampleValue= (ptr->ValueOffset >> 16);
  379.                  break;
  380.  
  381.            case  0x0119:
  382.                  T->MaxSampleValue= (ptr->ValueOffset >> 16);
  383.                  break;
  384.  
  385.            case  0x011A:
  386.                  lseek(fd,(long)ptr->ValueOffset,0);
  387.                  read(fd,TempRational,sizeof(TempRational));
  388.                  T->Xres = TempRational[0]/TempRational[1];
  389.                  break;
  390.  
  391.            case  0x011B:
  392.                  lseek(fd,(long)ptr->ValueOffset,0);
  393.                  read(fd,TempRational,sizeof(TempRational));
  394.                  T->Yres = TempRational[0]/TempRational[1];
  395.                  break;
  396.  
  397.            case  0x011C:
  398.                  T->PlanarConfig= (ptr->ValueOffset >> 16);
  399.                  break;
  400.  
  401.            case  0x011D:
  402.                  fprintf(stderr,"Unsupported feature: PageName\n");
  403.                  /* T->PageName */
  404.                  break;
  405.  
  406.            case  0x011E:
  407.                  fprintf(stderr,"Unsupported feature: Xpos\n");
  408.                  /* T->XPos */ 
  409.                  break;
  410.  
  411.            case  0x011F:
  412.                  fprintf(stderr,"Unsupported feature: Ypos\n");
  413.                  /* T->YPos */
  414.                  break;
  415.  
  416.            case  0x0120:
  417.                  fprintf(stderr,"Unsupported feature: FreeOffsets\n");
  418.                  /* T->FreeOffsets */ 
  419.                  break;
  420.  
  421.            case  0x0121:
  422.                  fprintf(stderr,"Unsupported feature: FreeByteCount \n");
  423.                  /* T->FreeByteCount */ 
  424.                  break;
  425.  
  426.            case  0x0122:
  427.                  fprintf(stderr,"Unsupported feature: GrayResUnit\n");
  428.                  /* T->GrayResUnit */ 
  429.                  break;
  430.  
  431.            case  0x0123:
  432.                  fprintf(stderr,"Unsupported feature: GrayResCurve\n");
  433.                  /* T->GrayResCurve */ 
  434.                  break;
  435.  
  436.            case  0x0124:
  437.                  fprintf(stderr,"Unsupported feature: Group3Option\n");
  438.                  /* T->Group3Option */ 
  439.                  break;
  440.  
  441.            case  0x0125:
  442.                  fprintf(stderr,"Unsupported feature: Group4Option\n");
  443.                  /* T->Group4Option */ 
  444.                  break;
  445.  
  446.            case  0x0128:
  447.                  fprintf(stderr,"Unsupported feature: ResolutionUnit\n");
  448.                   /* T->ResolutionUnit */
  449.                  break;
  450.  
  451.            case  0x0129:
  452.                  fprintf(stderr,"Unsupported feature: PageNumber\n");
  453.                  /* T->PageNumber */ 
  454.                  break;
  455.  
  456.            case  0x012C:
  457.                  fprintf(stderr,"Unsupported feature: ColorResUnit\n");
  458.                  /* T->ColorResUnit */ 
  459.                  break;
  460.  
  461.            case  0x012D:
  462.                  fprintf(stderr,"Unsupported feature: ColorResCurv\n");
  463.                  /* T->ColorResCurv */
  464.                  break;
  465.  
  466.            default:
  467.                  fprintf(stderr,"Unsupported feature: Unknown Tag\n");
  468.                  fprintf(stderr,"Default\n");
  469.                  break;
  470.            }
  471.     ptr++;
  472.     }
  473.     return(TRUE);
  474. }
  475. /* 
  476. ** Dump header information
  477. */
  478. dumpHeader(T,H)
  479. struct Tiffstruct *T;
  480. struct TiffHeader *H;
  481. {
  482. int i;
  483. LONG *offptr;
  484.  
  485.        fprintf(stderr,"Version:        %d\n",H->Version);
  486.        fprintf(stderr,"ByteOrder:      %c%c\n",
  487.                        H->ByteOrder[0],
  488.                        H->ByteOrder[1]);
  489.        fprintf(stderr,"Subfile Type:   %d\n", T->SubFileType); 
  490.        fprintf(stderr,"ImageWidth:     %d\n", T->ImageWidth); 
  491.        fprintf(stderr,"ImageLength:    %d\n", T->ImageLength); 
  492.        fprintf(stderr,"BitsPerSample:  %d\n", T->BitsPerSample); 
  493.        fprintf(stderr,"Compression:    %d\n", T->Compression); 
  494.        fprintf(stderr,"PhotoInterp:    %d\n", T->PhotoInterp); 
  495.        fprintf(stderr,"Threshold:      %d\n", T->Threshold); 
  496.        fprintf(stderr,"CellWidth:      %d\n", T->CellWidth); 
  497.        fprintf(stderr,"CellLength:     %d\n", T->CellLength); 
  498.        fprintf(stderr,"FillOrder:      %d\n", T->FillOrder); 
  499.        fprintf(stderr,"DocName:        %s\n", T->DocName); 
  500.        fprintf(stderr,"ImageDescript:  %s\n", T->ImageDescript); 
  501.        fprintf(stderr,"Model:          %s\n", T->Model); 
  502.        fprintf(stderr,"StripOffsetCnt: %d\n", T->StOffsetCnt); 
  503.        offptr = T->StripOffset;
  504.        for(i=0; i < T->StOffsetCnt; i++)
  505.           {
  506.           fprintf(stderr,"Strip [%02d] starts at: %d \n", i,*offptr); 
  507.           offptr++; 
  508.           }
  509.        fprintf(stderr,"Orientation:    %d\n", T->Orientation); 
  510.        fprintf(stderr,"SamplesPixel:   %d\n", T->SamplesPixel); 
  511.        fprintf(stderr,"RowsStrip:      %d\n", T->RowsStrip); 
  512.        fprintf(stderr,"StripByteCnt:   %d\n", T->StripByteCnt); 
  513.        offptr = T->SBytesCntOffset;
  514.        for(i=0; i < T->StripByteCnt; i++)
  515.           {
  516.           fprintf(stderr,"Strip [%02d]: %d bytes\n", i,*offptr); 
  517.           offptr++; 
  518.           }
  519.        fprintf(stderr,"MinSampleValue: %d\n", T->MinSampleValue); 
  520.        fprintf(stderr,"MaxSampleValue: %d\n", T->MaxSampleValue); 
  521.        fprintf(stderr,"Xres:           %d\n", T->Xres); 
  522.        fprintf(stderr,"Yres:           %d\n", T->Yres); 
  523.        fprintf(stderr,"PlanarConfig:   %d\n", T->PlanarConfig); 
  524. }
  525.