home *** CD-ROM | disk | FTP | other *** search
/ Hand Held Organizer Toolkit / walnutcreekcdrom-handheldorganizertoolkit-march1998.iso / PalmPilot / development / ppmtotbmp_tar.gz / ppmtotbmp_tar / ppmtoTbmp-1.1 / ppmtoTbmp.c < prev    next >
C/C++ Source or Header  |  1997-06-25  |  4KB  |  135 lines

  1. /* ppmtoTbmp.c - read a portable pixmap and write a pilot Tbmp file
  2.  *
  3.  * Program by Ian Goldberg <iang@cs.berkeley.edu>
  4.  *
  5.  * Based on ppmtopuzz.c by Jef Paskanzer, from the netpbm-1mar1994 package.
  6.  */
  7.  
  8. #include "ppm.h"
  9. #include "ppmcmap.h"
  10.  
  11. static int colcompare(const void *a, const void *b)
  12. {
  13.     colorhist_vector ch1 = (colorhist_vector)a;
  14.     colorhist_vector ch2 = (colorhist_vector)b;
  15.     return
  16.     (int) PPM_GETR(ch1->color) - (int) PPM_GETR(ch2->color) +
  17.     (int) PPM_GETG(ch1->color) - (int) PPM_GETG(ch2->color) +
  18.     (int) PPM_GETB(ch1->color) - (int) PPM_GETB(ch2->color);
  19. }
  20.  
  21. int
  22. main( int argc, char **argv )
  23. {
  24.     FILE* ifp;
  25.     pixel** pixels;
  26.     register pixel* pP;
  27.     colorhist_vector chv;
  28.     colorhash_table cht;
  29.     int rows, cols, row, colors;
  30.     register int col;
  31.     pixval maxval;
  32.     unsigned char outbyte, outbit;
  33.     int twobit = 0;
  34.  
  35.     /* Parse default params */
  36.     ppm_init( &argc, argv );
  37.  
  38.     if (argc > 1 && !strcmp(argv[1], "-2bit")) {
  39.     twobit = 1;
  40.     --argc; ++argv;
  41.     }
  42.     if ( argc > 2 || (argc == 2 && argv[1][0] == '-')) {
  43.     pm_usage( "[-2bit] [ppmfile]" );
  44.     }
  45.  
  46.     if ( argc == 2 )
  47.     ifp = pm_openr( argv[1] );
  48.     else
  49.     ifp = stdin;
  50.  
  51.     pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
  52.     pm_close( ifp );
  53.  
  54.     pm_message( "computing colormap..." );
  55.     chv = ppm_computecolorhist( pixels, cols, rows, twobit ? 4 : 2, &colors );
  56.     if ( chv == (colorhist_vector) 0 )
  57.     {
  58.     pm_message(
  59.         "too many colors - try doing a 'ppmquant %d'", twobit ? 4 : 2 );
  60.     exit( 1 );
  61.     }
  62.     qsort((char *)chv, colors, sizeof(struct colorhist_item), colcompare);
  63.     pm_message( "%d colors found", colors );
  64.  
  65.     /* Write Tbmp header. */
  66.     (void) pm_writebigshort( stdout, cols*(twobit ? 2 : 1) );   /* width */
  67.     (void) pm_writebigshort( stdout, rows );                    /* height */
  68.     if (twobit) {
  69.     (void) pm_writebigshort( stdout, ((cols+7)/8)*2 );      /* chars/row */
  70.     } else {
  71.     (void) pm_writebigshort( stdout, ((cols+15)/16)*2 );    /* chars/row */
  72.     }
  73.     (void) pm_writebigshort( stdout, 0 );                       /* flags */
  74.     (void) pm_writebiglong( stdout, 0 );                        /* pad */
  75.     (void) pm_writebiglong( stdout, 0 );                        /* pad */
  76.  
  77.     /* Convert color vector to color hash table, for fast lookup. */
  78.     cht = ppm_colorhisttocolorhash( chv, colors );
  79.     ppm_freecolorhist( chv );
  80.  
  81.     /* And write out the data. */
  82.     for ( row = 0; row < rows; ++row ) {
  83.     outbyte = 0x00;
  84.     outbit = twobit ? 6 : 7;
  85.     for ( col = 0, pP = pixels[row]; col < cols; ++col, ++pP ) {
  86.         register int color;
  87.  
  88.         color = ppm_lookupcolor( cht, pP );
  89.         if ( color == -1 )
  90.         pm_error(
  91.             "color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
  92.             row, col, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP) );
  93.         if (twobit) {
  94.         if (color == 0) {
  95.             outbyte |= (3 << outbit);
  96.         } else if (color == 1) {
  97.             outbyte |= (2 << outbit);
  98.         } else if (color == 2) {
  99.             outbyte |= (1 << outbit);
  100.         }
  101.         } else {
  102.         if (color == 0) {
  103.             outbyte |= (1 << outbit);
  104.         }
  105.         }
  106.         if (!outbit) {
  107.         (void) putchar(outbyte);
  108.         outbyte = 0x00;
  109.         outbit = (twobit ? 6 : 7);
  110.         } else {
  111.         outbit -= (twobit ? 2 : 1);
  112.         }
  113.     }
  114.     if (twobit) {
  115.         /* Output any partial byte remaining */
  116.         if (cols & 0x03) {
  117.         (void) putchar(outbyte);
  118.         }
  119.         if (!((cols+7) & 0x04)) {
  120.         (void) putchar(0x00);
  121.         }
  122.     } else {
  123.         /* Output any partial byte remaining */
  124.         if (cols & 0x07) {
  125.         (void) putchar(outbyte);
  126.         }
  127.         if (!((cols+15) & 0x08)) {
  128.         (void) putchar(0x00);
  129.         }
  130.     }
  131.     }
  132.  
  133.     exit( 0 );
  134. }
  135.