home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / ppmtosixel.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  5KB  |  207 lines

  1. /* ppmtosix.c - read a portable pixmap and produce a color sixel file
  2. **
  3. ** Copyright (C) 1991 by Rick Vinci.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "ppm.h"
  14. #include "ppmcmap.h"
  15.  
  16. int WriteHeader ARGS((void));
  17. int WriteColorMap ARGS((colorhist_vector chv, int colors, pixval maxval));
  18. int WriteRawImage ARGS((colorhash_table cht, int rows, int cols));
  19. int WritePackedImage ARGS((colorhash_table cht, int rows, int cols));
  20. int WriteEnd ARGS((void));
  21. #define MAXVAL 100
  22. #define MAXCOLORS 256
  23.  
  24. #define DCS '\220'   /* Device Control String */
  25. #define ST  '\234'   /* String Terminator */
  26. #define CSI '\233'   /* Control String Introducer */
  27. #define ESC '\033'   /* Escape character */
  28.  
  29. static pixel** pixels;   /* stored ppm pixmap input */
  30. static colorhash_table cht;
  31. int margin;
  32.  
  33. int
  34. main( argc, argv )
  35.     int argc;
  36.     char* argv[];
  37.     {
  38.     FILE* ifp;
  39.     int argn, rows, cols, colors;
  40.     int Red, Grn, Blue, rownum, colnum;
  41.     int raw;
  42.     pixval maxval;
  43.     colorhist_vector chv;
  44.     char* usage = "[-raw] [-margin] [ppmfile]";
  45.  
  46.  
  47.     ppm_init( &argc, argv );
  48.  
  49.     argn = 1;
  50.     raw = 0;
  51.     margin = 0;
  52.  
  53.     /* Parse args. */
  54.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  55.     {
  56.     if ( pm_keymatch( argv[argn], "-raw", 2 ) )
  57.         raw = 1;
  58.     else if ( pm_keymatch( argv[argn], "-margin", 2 ) )
  59.         margin = 1;
  60.     else
  61.         pm_usage( usage );
  62.     ++argn;
  63.     }
  64.  
  65.     if ( argn < argc )
  66.     {
  67.     ifp = pm_openr( argv[argn] );
  68.     ++argn;
  69.     }
  70.     else
  71.     ifp = stdin;
  72.  
  73.     if ( argn != argc )
  74.     pm_usage( usage );
  75.  
  76.     /* Read in the whole ppmfile. */
  77.     pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
  78.     pm_close( ifp );
  79.  
  80.     /* Print a warning if we're could to lose accuracy when rescaling colors. */
  81.     if ( maxval > MAXVAL )
  82.     pm_message(
  83.         "maxval is not %d - automatically rescaling colors", MAXVAL );
  84.  
  85.     /* Figure out the colormap. */
  86.     pm_message( "computing colormap..." );
  87.     chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
  88.     if ( chv == (colorhist_vector) 0 )
  89.     pm_error( "too many colors - try doing a 'ppmquant %d'", MAXCOLORS );
  90.     pm_message( "%d colors found", colors );
  91.  
  92.     /* Make a hash table for fast color lookup. */
  93.     cht = ppm_colorhisttocolorhash( chv, colors );
  94.  
  95.     pm_message( "delivering sixel image..." );
  96.     WriteHeader();
  97.     WriteColorMap( chv, colors, maxval );
  98.     if ( raw == 1 )
  99.     WriteRawImage( cht, rows, cols );
  100.     else
  101.     WritePackedImage( cht, rows, cols );
  102.     WriteEnd();
  103.  
  104.     exit( 0 );
  105.     }
  106.  
  107.  
  108. int
  109. WriteHeader()
  110.     {
  111.     if ( margin == 1 )
  112.     printf( "%c%d;%ds", CSI, 14, 72 );
  113.     printf( "%c", DCS );  /* start with Device Control String */
  114.     printf( "0;0;8q" );   /* Horizontal Grid Size at 1/90" and graphics On */
  115.     printf( "\"1;1\n" );  /* set aspect ratio 1:1 */
  116.     }
  117.  
  118. int
  119. WriteColorMap( chv, colors, maxval )
  120.     colorhist_vector chv;
  121.     int colors;
  122.     pixval maxval;
  123.     {
  124.     register int colornum;
  125.     pixel p;
  126.  
  127.     for ( colornum = 0; colornum < colors ; ++colornum )
  128.     {
  129.     p = chv[colornum].color;
  130.     if ( maxval != MAXVAL )
  131.         PPM_DEPTH( p, p, maxval, MAXVAL );
  132.     printf( "#%d;2;%d;%d;%d", colornum,
  133.         (int) PPM_GETR( p ), (int) PPM_GETG( p ), (int) PPM_GETB( p ) );
  134.     }
  135.     printf( "\n" );
  136.     }
  137.  
  138. int
  139. WriteRawImage( cht, rows, cols )
  140.     colorhash_table cht;
  141.     int rows, cols;
  142.     {
  143.     int rownum, colnum, b;
  144.     char* sixel = "@ACGO_";
  145.     register pixel* pP;
  146.  
  147.     for ( rownum = 0; rownum < rows; ++rownum )
  148.     {
  149.     b = rownum % 6;
  150.     for ( colnum = 0, pP = pixels[rownum]; colnum < cols; ++colnum, ++pP )
  151.         printf( "#%d%c", ppm_lookupcolor(cht, pP), sixel[b] );
  152.     printf( "$\n" );   /* Carriage Return */
  153.     if ( b == 5 )
  154.         printf( "-\n" );   /* Line Feed (one sixel height) */
  155.     }
  156.     }
  157.  
  158. int
  159. WritePackedImage( cht, rows, cols )
  160.     colorhash_table cht;
  161.     int rows, cols;
  162.     {
  163.     int rownum, colnum, b, repeat, thiscolor, nextcolor;
  164.     char* sixel = "@ACGO_";
  165.     register pixel* pP;
  166.  
  167.     for ( rownum = 0; rownum < rows; ++rownum )
  168.     {
  169.     b = rownum % 6;
  170.     repeat = 1;
  171.     for ( colnum = 0, pP = pixels[rownum]; colnum < cols; ++colnum, ++pP )
  172.         {
  173.         thiscolor = ppm_lookupcolor(cht, pP);
  174.         if ( colnum == cols -1 )   /* last pixel in row */
  175.         if ( repeat == 1 )
  176.             printf( "#%d%c", thiscolor, sixel[b] );
  177.         else
  178.             printf( "#%d!%d%c", thiscolor, repeat, sixel[b] );
  179.         else   /* not last pixel in row */
  180.         {
  181.         nextcolor =  ppm_lookupcolor(cht, pP+1);
  182.         if ( thiscolor == nextcolor )
  183.             ++repeat;
  184.         else
  185.             if ( repeat == 1 )
  186.             printf( "#%d%c", thiscolor, sixel[b] );
  187.             else
  188.             {
  189.             printf( "#%d!%d%c", thiscolor, repeat, sixel[b] );
  190.             repeat = 1;
  191.             }
  192.         }
  193.         }   /* end column loop */
  194.     printf( "$\n" );   /* Carriage Return */
  195.     if ( b == 5 )
  196.         printf( "-\n" );   /* Line Feed (one sixel height) */
  197.     }
  198.     }
  199.  
  200. int
  201. WriteEnd()
  202.     {
  203.     if ( margin == 1 )
  204.     printf ( "%c%d;%ds", CSI, 1, 80 );
  205.     printf( "%c\n", ST );
  206.     }
  207.