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 / pnmtotiff.c < prev    next >
C/C++ Source or Header  |  1996-11-18  |  9KB  |  349 lines

  1. /*
  2. ** pnmtotiff.c - converts a portable anymap to a Tagged Image File
  3. **
  4. ** Derived by Jef Poskanzer from ras2tif.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. #include "ppmcmap.h"
  34. #define MAXCOLORS 256
  35.  
  36. int
  37. main( argc, argv )
  38.     int argc;
  39.     char* argv[];
  40.     {
  41.     int argn;
  42.     char* inf = NULL;
  43.     FILE* ifp;
  44.     xel** xels;
  45.     register xel* xP;
  46.     colorhist_vector chv;
  47.     colorhash_table cht;
  48.     unsigned short red[MAXCOLORS], grn[MAXCOLORS], blu[MAXCOLORS];
  49.     int cols, rows, format, row, colors, i;
  50.     register int col;
  51.     xelval maxval;
  52.     int grayscale;
  53.     TIFF* tif;
  54.     long g3options;
  55.     long rowsperstrip;
  56.     unsigned short compression;
  57.     unsigned short fillorder;
  58.     short predictor;
  59.     short photometric;
  60.     short samplesperpixel;
  61.     short bitspersample;
  62.     int bytesperrow;
  63.     unsigned char* buf;
  64.     unsigned char* tP;
  65.     char* usage = "[-none|-packbits|-lzw|-g3|-g4] [-msb2lsb|-lsb2msb] [-2d] [-fill] [-predictor n] [-rowsperstrip n] [pnmfile]";
  66.  
  67.  
  68.     pnm_init( &argc, argv );
  69.  
  70.     argn = 1;
  71.     compression = COMPRESSION_LZW;
  72.     g3options = 0;
  73.     fillorder = FILLORDER_MSB2LSB;
  74.     predictor = 0;
  75.     rowsperstrip = 0;
  76.  
  77.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  78.     {
  79.     if ( pm_keymatch( argv[argn], "-none", 2 ) )
  80.         compression = COMPRESSION_NONE;
  81.     else if ( pm_keymatch( argv[argn], "-packbits", 3 ) ) 
  82.         compression = COMPRESSION_PACKBITS;
  83.     else if ( pm_keymatch( argv[argn], "-lzw", 3 ) ) 
  84.         compression = COMPRESSION_LZW;
  85.     else if ( pm_keymatch( argv[argn], "-g3", 3 ) ) 
  86.         compression = COMPRESSION_CCITTFAX3;
  87.     else if ( pm_keymatch( argv[argn], "-g4", 3 ) ) 
  88.         compression = COMPRESSION_CCITTFAX4;
  89.     else if ( pm_keymatch( argv[argn], "-msb2lsb", 3 ) )
  90.         fillorder = FILLORDER_MSB2LSB;
  91.     else if ( pm_keymatch( argv[argn], "-lsb2msb", 3 ) )
  92.         fillorder = FILLORDER_LSB2MSB;
  93.     else if ( pm_keymatch( argv[argn], "-2d", 2 ) )
  94.         g3options |= GROUP3OPT_2DENCODING;
  95.     else if ( pm_keymatch( argv[argn], "-fill", 2 ) )
  96.         g3options |= GROUP3OPT_FILLBITS;
  97.     else if ( pm_keymatch( argv[argn], "-predictor", 3) )
  98.         {
  99.         ++argn;
  100.         if ( argn == argc || sscanf( argv[argn], "%hd", &predictor ) != 1 )
  101.         pm_usage( usage );
  102.         if ( predictor != 1 && predictor != 2 )
  103.         pm_usage( usage );
  104.         }
  105.     else if ( pm_keymatch( argv[argn], "-rowsperstrip", 2 ) )
  106.         {
  107.         ++argn;
  108.         if ( argn == argc ||
  109.          sscanf( argv[argn], "%ld", &rowsperstrip ) != 1 )
  110.         pm_usage( usage );
  111.         if ( rowsperstrip < 1 )
  112.         pm_usage( usage );
  113.         }
  114.     else
  115.         pm_usage( usage );
  116.     ++argn;
  117.     }
  118.  
  119.     if ( argn != argc )
  120.     {
  121.     inf = argv[argn];
  122.     ifp = pm_openr( inf );
  123.     ++argn;
  124.     }
  125.     else
  126.     {
  127.     inf = "Standard Input";
  128.     ifp = stdin;
  129.     }
  130.  
  131.     if ( argn != argc )
  132.     pm_usage( usage );
  133.  
  134.     xels = pnm_readpnm( ifp, &cols, &rows, &maxval, &format );
  135.     pm_close( ifp );
  136.  
  137.     /* Check for grayscale. */
  138.     switch ( PNM_FORMAT_TYPE(format) )
  139.     {
  140.     case PPM_TYPE:
  141.     pm_message( "computing colormap..." );
  142.     chv = ppm_computecolorhist( xels, cols, rows, MAXCOLORS, &colors );
  143.     if ( chv == (colorhist_vector) 0 )
  144.         {
  145.         pm_message(
  146.         "Too many colors - proceeding to write a 24-bit RGB file." );
  147.         pm_message(
  148.         "If you want an 8-bit palette file, try doing a 'ppmquant %d'.",
  149.         MAXCOLORS );
  150.         grayscale = 0;
  151.         }
  152.     else
  153.         {
  154.         pm_message( "%d colors found", colors );
  155.         grayscale = 1;
  156.         for ( i = 0; i < colors; ++i )
  157.         {
  158.         register xelval r, g, b;
  159.  
  160.         r = PPM_GETR( chv[i].color );
  161.         g = PPM_GETG( chv[i].color );
  162.         b = PPM_GETB( chv[i].color );
  163.         if ( r != g || g != b )
  164.             {
  165.             grayscale = 0;
  166.             break;
  167.             }
  168.         }
  169.         }
  170.     break;
  171.  
  172.     default:
  173.     chv = (colorhist_vector) 0;
  174.     grayscale = 1;
  175.     break;
  176.     }
  177.  
  178.     /* Open output file. */
  179.     tif = TIFFFdOpen( 1, "Standard Output", "w" );
  180.     if ( tif == NULL )
  181.     pm_error( "error opening standard output as TIFF file" );
  182.  
  183.     /* Figure out TIFF parameters. */
  184.     switch ( PNM_FORMAT_TYPE(format) )
  185.     {
  186.     case PPM_TYPE:
  187.     if ( chv == (colorhist_vector) 0 )
  188.         {
  189.         samplesperpixel = 3;
  190.         bitspersample = 8;
  191.         photometric = PHOTOMETRIC_RGB;
  192.         bytesperrow = cols * 3;
  193.         }
  194.     else if ( grayscale )
  195.         {
  196.         samplesperpixel = 1;
  197.         bitspersample = pm_maxvaltobits( maxval );
  198.         photometric = PHOTOMETRIC_MINISBLACK;
  199.         i = 8 / bitspersample;
  200.         bytesperrow = ( cols + i - 1 ) / i;
  201.         }
  202.     else
  203.         {
  204.         samplesperpixel = 1;
  205.         bitspersample = 8;
  206.         photometric = PHOTOMETRIC_PALETTE;
  207.         bytesperrow = cols;
  208.         }
  209.     break;
  210.  
  211.     case PGM_TYPE:
  212.     samplesperpixel = 1;
  213.     bitspersample = pm_maxvaltobits( maxval );
  214.     photometric = PHOTOMETRIC_MINISBLACK;
  215.     i = 8 / bitspersample;
  216.     bytesperrow = ( cols + i - 1 ) / i;
  217.     break;
  218.  
  219.     default:
  220.     samplesperpixel = 1;
  221.     bitspersample = 1;
  222.     photometric = PHOTOMETRIC_MINISBLACK;
  223.     bytesperrow = ( cols + 7 ) / 8;
  224.     break;
  225.     }
  226.  
  227.     if ( rowsperstrip == 0 )
  228.     rowsperstrip = ( 8 * 1024 ) / bytesperrow;
  229.     buf = (unsigned char*) malloc( bytesperrow );
  230.     if ( buf == (unsigned char*) 0 )
  231.     pm_error( "can't allocate memory for row buffer" );
  232.  
  233.     /* Set TIFF parameters. */
  234.     TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, cols );
  235.     TIFFSetField( tif, TIFFTAG_IMAGELENGTH, rows );
  236.     TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, bitspersample );
  237.     TIFFSetField( tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
  238.     TIFFSetField( tif, TIFFTAG_COMPRESSION, compression );
  239.     if ( compression == COMPRESSION_CCITTFAX3 && g3options != 0 )
  240.     TIFFSetField( tif, TIFFTAG_GROUP3OPTIONS, g3options );
  241.     if ( compression == COMPRESSION_LZW && predictor != 0 )
  242.     TIFFSetField( tif, TIFFTAG_PREDICTOR, predictor );
  243.     TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, photometric );
  244.     TIFFSetField( tif, TIFFTAG_FILLORDER, fillorder );
  245.     TIFFSetField( tif, TIFFTAG_DOCUMENTNAME, inf );
  246.     TIFFSetField( tif, TIFFTAG_IMAGEDESCRIPTION, "converted PNM file" );
  247.     TIFFSetField( tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel );
  248.     TIFFSetField( tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip );
  249.     /* TIFFSetField( tif, TIFFTAG_STRIPBYTECOUNTS, rows / rowsperstrip ); */
  250.     TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
  251.  
  252.     if ( chv == (colorhist_vector) 0 )
  253.     cht = (colorhash_table) 0;
  254.     else
  255.     {
  256.     /* Make TIFF colormap. */
  257.     for ( i = 0; i < colors; ++i )
  258.         {
  259.         red[i] = (long) PPM_GETR( chv[i].color ) * 65535L / maxval;
  260.         grn[i] = (long) PPM_GETG( chv[i].color ) * 65535L / maxval;
  261.         blu[i] = (long) PPM_GETB( chv[i].color ) * 65535L / maxval;
  262.         }
  263.     TIFFSetField( tif, TIFFTAG_COLORMAP, red, grn, blu );
  264.  
  265.     /* Convert color vector to color hash table, for fast lookup. */
  266.     cht = ppm_colorhisttocolorhash( chv, colors );
  267.     ppm_freecolorhist( chv );
  268.     }
  269.  
  270.     /* Now write the TIFF data. */
  271.     for ( row = 0; row < rows; ++row )
  272.     {
  273.     if ( PNM_FORMAT_TYPE(format) == PPM_TYPE && ! grayscale )
  274.         {
  275.         if ( cht == (colorhash_table) 0 )
  276.         {
  277.         for ( col = 0, xP = xels[row], tP = buf;
  278.               col < cols; ++col, ++xP )
  279.             {
  280.             register xelval s;
  281.  
  282.             s = PPM_GETR( *xP );
  283.             if ( maxval != 255 )
  284.             s = s * 255 / maxval;
  285.             *tP++ = (unsigned char)s;
  286.             s = PPM_GETG( *xP );
  287.             if ( maxval != 255 )
  288.             s = s * 255 / maxval;
  289.             *tP++ = (unsigned char)s;
  290.             s = PPM_GETB( *xP );
  291.             if ( maxval != 255 )
  292.             s = s * 255 / maxval;
  293.             *tP++ = (unsigned char)s;
  294.             }
  295.         }
  296.         else
  297.         {
  298.         for ( col = 0, xP = xels[row], tP = buf;
  299.               col < cols; ++col, ++xP )
  300.             {
  301.             register int s;
  302.  
  303.             s = ppm_lookupcolor( cht, xP );
  304.             if ( s == -1 )
  305.             pm_error(
  306.                 "color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
  307.                 row, col, PPM_GETR( *xP ), PPM_GETG( *xP ),
  308.                 PPM_GETB( *xP ) );
  309.             *tP++ = (unsigned char) s;
  310.             }
  311.         }
  312.         }
  313.     else
  314.         {
  315.         register xelval bigger_maxval;
  316.         register int bitshift;
  317.         register unsigned char byte;
  318.         register xelval s;
  319.  
  320.         bigger_maxval = pm_bitstomaxval( bitspersample );
  321.         bitshift = 8 - bitspersample;
  322.         byte = 0;
  323.         for ( col = 0, xP = xels[row], tP = buf; col < cols; ++col, ++xP )
  324.         {
  325.         s = PNM_GET1( *xP );
  326.         if ( maxval != bigger_maxval )
  327.             s = (long) s * bigger_maxval / maxval;
  328.         byte |= s << bitshift;
  329.         bitshift -= bitspersample;
  330.         if ( bitshift < 0 )
  331.             {
  332.             *tP++ = byte;
  333.             bitshift = 8 - bitspersample;
  334.             byte = 0;
  335.             }
  336.         }
  337.         if ( bitshift != 8 - bitspersample )
  338.         *tP++ = byte;
  339.         }
  340.  
  341.     if ( TIFFWriteScanline( tif, buf, row, 0 ) < 0 )
  342.         pm_error( "failed a scanline write on row %d", row );
  343.     }
  344.     TIFFFlushData( tif );
  345.     TIFFClose( tif );
  346.  
  347.     exit( 0 );
  348.     }
  349.