home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / netpbm_src.lzh / NETPBM / PNM / tifftopnm.c < prev    next >
C/C++ Source or Header  |  1996-11-18  |  8KB  |  340 lines

  1. /*
  2. ** tifftopnm.c - converts a Tagged Image File to a portable anymap
  3. **
  4. ** Derived by Jef Poskanzer from tif2ras.c, which is:
  5. **
  6. ** Copyright (c) 1990 by Sun Microsystems, Inc.
  7. **
  8. ** Author: Patrick J. Naughton
  9. ** naughton@wind.sun.com
  10. **
  11. ** Permission to use, copy, modify, and distribute this software and its
  12. ** documentation for any purpose and without fee is hereby granted,
  13. ** provided that the above copyright notice appear in all copies and that
  14. ** both that copyright notice and this permission notice appear in
  15. ** supporting documentation.
  16. **
  17. ** This file is provided AS IS with no warranties of any kind.  The author
  18. ** shall have no liability with respect to the infringement of copyrights,
  19. ** trade secrets or any patents by this file or any part thereof.  In no
  20. ** event will the author be liable for any lost revenue or profits or
  21. ** other special, indirect and consequential damages.
  22. */
  23.  
  24. #include "pnm.h"
  25. #ifdef VMS
  26. #ifdef SYSV
  27. #undef SYSV
  28. #endif
  29. #include <tiffioP.h>
  30. #endif
  31. #include <tiffio.h>
  32.  
  33. #define MAXCOLORS 1024
  34. #ifndef PHOTOMETRIC_DEPTH
  35. #define PHOTOMETRIC_DEPTH 32768
  36. #endif
  37.  
  38. int
  39. main( argc, argv )
  40.     int argc;
  41.     char* argv[];
  42.     {
  43.     int argn, cols, rows, grayscale, format;
  44.     int numcolors;
  45.     register TIFF* tif;
  46.     int row, i;
  47.     register int col;
  48.     u_char* buf;
  49.     register u_char* inP;
  50.     int maxval;
  51.     xel* xelrow;
  52.     register xel* xP;
  53.     xel colormap[MAXCOLORS];
  54.     int headerdump;
  55.     register u_char sample;
  56.     register int bitsleft;
  57.     unsigned short bps, spp, photomet, planarconfig;
  58.     unsigned short* redcolormap;
  59.     unsigned short* greencolormap;
  60.     unsigned short* bluecolormap;
  61.     char* usage = "[-headerdump] [tifffile]";
  62.  
  63.  
  64.     pnm_init( &argc, argv );
  65.  
  66.     argn = 1;
  67.     headerdump = 0;
  68.  
  69.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  70.     {
  71.     if ( pm_keymatch( argv[argn], "-headerdump", 2 ) )
  72.         headerdump = 1;
  73.     else
  74.         pm_usage( usage );
  75.     ++argn;
  76.     }
  77.  
  78.     if ( argn != argc )
  79.     {
  80.     tif = TIFFOpen( argv[argn], "r" );
  81.     if ( tif == NULL )
  82.         pm_error( "error opening TIFF file %s", argv[argn] );
  83.     ++argn;
  84.     }
  85.     else
  86.     {
  87.     tif = TIFFFdOpen( 0, "Standard Input", "r" );
  88.     if ( tif == NULL )
  89.         pm_error( "error opening standard input as TIFF file" );
  90.     }
  91.  
  92.     if ( argn != argc )
  93.     pm_usage( usage );
  94.  
  95.     if ( headerdump )
  96.     TIFFPrintDirectory( tif, stderr, TIFFPRINT_NONE );
  97.  
  98.     if ( ! TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bps ) )
  99.     bps = 1;
  100.     if ( ! TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
  101.     spp = 1;
  102.     if ( ! TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photomet ) )
  103.     pm_error( "error getting photometric" );
  104.     if( spp > 1 ){
  105.     if ( ! TIFFGetField( tif, TIFFTAG_PLANARCONFIG, &planarconfig ) )
  106.         pm_error( "error getting planarconfig" );
  107.     }else{
  108.     planarconfig = PLANARCONFIG_CONTIG;
  109.     }
  110.  
  111.  
  112.     switch ( spp )
  113.     {
  114.     case 1:
  115.     case 3:
  116.     case 4:
  117.     break;
  118.  
  119.     default:
  120.     pm_error(
  121.         "can only handle 1-channel gray scale or 1- or 3-channel color" );
  122.     }
  123.  
  124.     switch( planarconfig )
  125.     {
  126.     case PLANARCONFIG_CONTIG:
  127.         break;
  128.     case PLANARCONFIG_SEPARATE:
  129.         if( photomet != PHOTOMETRIC_RGB )
  130.         pm_error( "can only handle separate planes with RGB data" );
  131.         break;
  132.     default:
  133.         pm_error("Unrecongnized PLANARCONFIG tag!\n");
  134.     }
  135.  
  136.     (void) TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &cols );
  137.     (void) TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &rows );
  138.  
  139.     if ( headerdump )
  140.     {
  141.     pm_message( "%dx%dx%d image", cols, rows, bps * spp );
  142.     pm_message( "%d bits/sample, %d samples/pixel", bps, spp );
  143.     }
  144.  
  145.     maxval = ( 1 << bps ) - 1;
  146.     if ( maxval == 1 && spp == 1 )
  147.     {
  148.     if ( headerdump )
  149.         pm_message("monochrome" );
  150.     grayscale = 1;
  151.     }
  152.     else
  153.     {
  154.     switch ( photomet )
  155.         {
  156.         case PHOTOMETRIC_MINISBLACK:
  157.         if ( headerdump )
  158.         pm_message( "%d graylevels (min=black)", maxval + 1 );
  159.         grayscale = 1;
  160.         break;
  161.  
  162.         case PHOTOMETRIC_MINISWHITE:
  163.         if ( headerdump )
  164.         pm_message( "%d graylevels (min=white)", maxval + 1 );
  165.         grayscale = 1;
  166.         break;
  167.  
  168.         case PHOTOMETRIC_PALETTE:
  169.         if ( headerdump )
  170.         pm_message( "colormapped" );
  171.         if ( ! TIFFGetField( tif, TIFFTAG_COLORMAP, &redcolormap, &greencolormap, &bluecolormap ) )
  172.         pm_error( "error getting colormaps" );
  173.         numcolors = maxval + 1;
  174.         if ( numcolors > MAXCOLORS )
  175.         pm_error( "too many colors" );
  176.         maxval = PNM_MAXMAXVAL;
  177.         grayscale = 0;
  178.         for ( i = 0; i < numcolors; ++i )
  179.         {
  180.         register xelval r, g, b;
  181.         r = (long) redcolormap[i] * PNM_MAXMAXVAL / 65535L;
  182.         g = (long) greencolormap[i] * PNM_MAXMAXVAL / 65535L;
  183.         b = (long) bluecolormap[i] * PNM_MAXMAXVAL / 65535L;
  184.         PPM_ASSIGN( colormap[i], r, g, b );
  185.         }
  186.         break;
  187.  
  188.         case PHOTOMETRIC_RGB:
  189.         if ( headerdump )
  190.         pm_message( "truecolor" );
  191.         grayscale = 0;
  192.         break;
  193.  
  194.         case PHOTOMETRIC_MASK:
  195.         pm_error( "don't know how to handle PHOTOMETRIC_MASK" );
  196.  
  197.         case PHOTOMETRIC_DEPTH:
  198.         pm_error( "don't know how to handle PHOTOMETRIC_DEPTH" );
  199.  
  200.         default:
  201.         pm_error( "unknown photometric: %d", photomet );
  202.         }
  203.     }
  204.     if ( maxval > PNM_MAXMAXVAL )
  205.     pm_error(
  206. "bits/sample is too large - try reconfiguring with PGM_BIGGRAYS\n    or without PPM_PACKCOLORS" );
  207.  
  208.  
  209.     if ( grayscale )
  210.     {
  211.     if ( maxval == 1 )
  212.         {
  213.         format = PBM_TYPE;
  214.         pm_message( "writing PBM file" );
  215.         }
  216.     else
  217.         {
  218.         format = PGM_TYPE;
  219.         pm_message( "writing PGM file" );
  220.         }
  221.     }
  222.     else
  223.     {
  224.     format = PPM_TYPE;
  225.     pm_message( "writing PPM file" );
  226.     }
  227.  
  228.     buf = (u_char*) malloc(TIFFScanlineSize(tif));
  229.     if ( buf == NULL )
  230.     pm_error( "can't allocate memory for scanline buffer" );
  231.     pnm_writepnminit( stdout, cols, rows, (xelval) maxval, format, 0 );
  232.     xelrow = pnm_allocrow( cols );
  233.  
  234. #define NEXTSAMPLE \
  235.     { \
  236.     if ( bitsleft == 0 ) \
  237.     { \
  238.     ++inP; \
  239.     bitsleft = 8; \
  240.     } \
  241.     bitsleft -= bps; \
  242.     sample = ( *inP >> bitsleft ) & maxval; \
  243.     }
  244.  
  245.     for ( row = 0; row < rows; ++row )
  246.     {
  247.     if ( TIFFReadScanline( tif, buf, row, 0 ) < 0 )
  248.         pm_error( "bad data read on line %d", row );
  249.     inP = buf;
  250.     bitsleft = 8;
  251.     xP = xelrow;
  252.  
  253.     switch ( photomet )
  254.         {
  255.         case PHOTOMETRIC_MINISBLACK:
  256.         for ( col = 0; col < cols; ++col, ++xP )
  257.         {
  258.         NEXTSAMPLE
  259.         PNM_ASSIGN1( *xP, sample );
  260.         }
  261.         break;
  262.  
  263.         case PHOTOMETRIC_MINISWHITE:
  264.         for ( col = 0; col < cols; ++col, ++xP )
  265.         {
  266.         NEXTSAMPLE
  267.         sample = maxval - sample;
  268.         PNM_ASSIGN1( *xP, sample );
  269.         }
  270.         break;
  271.  
  272.         case PHOTOMETRIC_PALETTE:
  273.         for ( col = 0; col < cols; ++col, ++xP )
  274.         {
  275.         NEXTSAMPLE
  276.         *xP = colormap[sample];
  277.         }
  278.         break;
  279.  
  280.         case PHOTOMETRIC_RGB:
  281.         if( planarconfig == PLANARCONFIG_CONTIG ){
  282.         for ( col = 0; col < cols; ++col, ++xP )
  283.             {
  284.             register xelval r, g, b;
  285.  
  286.             NEXTSAMPLE
  287.             r = sample;
  288.             NEXTSAMPLE
  289.             g = sample;
  290.             NEXTSAMPLE
  291.             b = sample;
  292.             if ( spp == 4 )
  293.                 NEXTSAMPLE /* skip alpha channel */
  294.             PPM_ASSIGN( *xP, r, g, b );
  295.             }
  296.         }else{
  297.         /* First clear the value and assign the reds */
  298.         for ( col = 0; col < cols; ++col, ++xP )
  299.             {
  300.             NEXTSAMPLE
  301.             PPM_ASSIGN( *xP, 0, 0, 0 );
  302.             PPM_PUTR( *xP, sample );
  303.             }
  304.  
  305.         /* Next the greens */
  306.         if ( TIFFReadScanline( tif, buf, row, 1 ) < 0 )
  307.             pm_error( "bad data read on green line %d", row );
  308.         xP = xelrow;
  309.         inP = buf;
  310.         bitsleft = 8;
  311.         for ( col = 0; col < cols; ++col, ++xP )
  312.             {
  313.             NEXTSAMPLE
  314.             PPM_PUTG( *xP, sample );
  315.             }
  316.  
  317.         /* And finally the blues */
  318.         if ( TIFFReadScanline( tif, buf, row, 2 ) < 0 )
  319.             pm_error( "bad data read on green line %d", row );
  320.         xP = xelrow;
  321.         inP = buf;
  322.         bitsleft = 8;
  323.         for ( col = 0; col < cols; ++col, ++xP )
  324.             {
  325.             NEXTSAMPLE
  326.             PPM_PUTB( *xP, sample );
  327.             }
  328.         }        
  329.         break;
  330.  
  331.         default:
  332.         pm_error( "unknown photometric: %d", photomet );
  333.         }
  334.     pnm_writepnmrow( stdout, xelrow, cols, (xelval) maxval, format, 0 );
  335.     }
  336.  
  337.     pm_close( stdout );
  338.     exit( 0 );
  339.     }
  340.