diff options
-rw-r--r-- | converter/ppm/ppmtosixel.c | 183 | ||||
-rw-r--r-- | doc/HISTORY | 3 |
2 files changed, 109 insertions, 77 deletions
diff --git a/converter/ppm/ppmtosixel.c b/converter/ppm/ppmtosixel.c index 5f361e45..b2491e23 100644 --- a/converter/ppm/ppmtosixel.c +++ b/converter/ppm/ppmtosixel.c @@ -8,12 +8,15 @@ ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. +** +** "-7bit" option added August 2023 by Scott Pakin <scott+pbm@pakin.org>. */ #include "ppm.h" +static void init_escape_sequences ARGS((const int nbits)); static void WriteHeader ARGS((void)); -static void WriteColorMap +static void WriteColorMap ARGS((colorhist_vector chv, int colors, pixval maxval)); static void WriteRawImage ARGS((colorhash_table cht, int rows, int cols)); static void WritePackedImage ARGS((colorhash_table cht, int rows, int cols)); @@ -21,17 +24,17 @@ static void WriteEnd ARGS((void)); #define MAXVAL 100 #define MAXCOLORS 256 -#define DCS '\220' /* Device Control String */ -#define ST '\234' /* String Terminator */ -#define CSI '\233' /* Control String Introducer */ -#define ESC '\033' /* Escape character */ +/* Named escape sequences */ +static struct { + const char * DCS; /* Device Control String */ + const char * ST; /* String Terminator */ + const char * CSI; /* Control String Introducer */ + const char * ESC; /* Escape character */ +} eseqs; static pixel** pixels; /* stored ppm pixmap input */ static colorhash_table cht; int margin; - - - int main( argc, argv ) int argc; @@ -40,6 +43,7 @@ main( argc, argv ) FILE* ifp; int argn, rows, cols, colors; int raw; + int nbits; pixval maxval; colorhist_vector chv; const char* const usage = "[-raw] [-margin] [ppmfile]"; @@ -50,29 +54,32 @@ main( argc, argv ) argn = 1; raw = 0; margin = 0; + nbits = 8; /* Parse args. */ while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) - { - if ( pm_keymatch( argv[argn], "-raw", 2 ) ) - raw = 1; - else if ( pm_keymatch( argv[argn], "-margin", 2 ) ) - margin = 1; - else - pm_usage( usage ); - ++argn; - } + { + if ( pm_keymatch( argv[argn], "-raw", 2 ) ) + raw = 1; + else if ( pm_keymatch( argv[argn], "-margin", 2 ) ) + margin = 1; + else if ( pm_keymatch( argv[argn], "-7bit", 2 ) ) + nbits = 7; + else + pm_usage( usage ); + ++argn; + } if ( argn < argc ) - { - ifp = pm_openr( argv[argn] ); - ++argn; - } + { + ifp = pm_openr( argv[argn] ); + ++argn; + } else - ifp = stdin; + ifp = stdin; if ( argn != argc ) - pm_usage( usage ); + pm_usage( usage ); /* Read in the whole ppmfile. */ pixels = ppm_readppm( ifp, &cols, &rows, &maxval ); @@ -80,25 +87,26 @@ main( argc, argv ) /* Print a warning if we could lose accuracy when rescaling colors. */ if ( maxval > MAXVAL ) - pm_message( - "maxval is not %d - automatically rescaling colors", MAXVAL ); + pm_message( + "maxval is not %d - automatically rescaling colors", MAXVAL ); /* Figure out the colormap. */ pm_message( "computing colormap..." ); chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors ); if ( chv == (colorhist_vector) 0 ) - pm_error( "too many colors - try doing a 'pnmquant %d'", MAXCOLORS ); + pm_error( "too many colors - try doing a 'pnmquant %d'", MAXCOLORS ); pm_message( "%d colors found", colors ); /* Make a hash table for fast color lookup. */ cht = ppm_colorhisttocolorhash( chv, colors ); + init_escape_sequences( nbits ); WriteHeader(); WriteColorMap( chv, colors, maxval ); if ( raw == 1 ) - WriteRawImage( cht, rows, cols ); + WriteRawImage( cht, rows, cols ); else - WritePackedImage( cht, rows, cols ); + WritePackedImage( cht, rows, cols ); WriteEnd(); /* If the program failed, it previously aborted with nonzero completion @@ -110,11 +118,32 @@ main( argc, argv ) static void +init_escape_sequences(const int nbits) +{ + if (nbits == 8) { + eseqs.DCS = "\220"; + eseqs.ST = "\234"; + eseqs.CSI = "\233"; + eseqs.ESC = "\033"; + } + else if (nbits == 7) { + eseqs.DCS = "\033P"; + eseqs.ST = "\033\\"; + eseqs.CSI = "\033["; + eseqs.ESC = "\033"; + } + else + pm_error("internal error: bad bit count"); +} + + + +static void WriteHeader() { if ( margin == 1 ) - printf( "%c%d;%ds", CSI, 14, 72 ); - printf( "%c", DCS ); /* start with Device Control String */ + printf( "%s%d;%ds", eseqs.CSI, 14, 72 ); + printf( "%s", eseqs.DCS ); /* start with Device Control String */ printf( "0;0;8q" ); /* Horizontal Grid Size at 1/90" and graphics On */ printf( "\"1;1\n" ); /* set aspect ratio 1:1 */ } @@ -128,13 +157,13 @@ WriteColorMap( colorhist_vector chv, int colors, pixval maxval ) pixel p; for ( colornum = 0; colornum < colors ; ++colornum ) - { - p = chv[colornum].color; - if ( maxval != MAXVAL ) - PPM_DEPTH( p, p, maxval, MAXVAL ); - printf( "#%d;2;%d;%d;%d", colornum, - (int) PPM_GETR( p ), (int) PPM_GETG( p ), (int) PPM_GETB( p ) ); - } + { + p = chv[colornum].color; + if ( maxval != MAXVAL ) + PPM_DEPTH( p, p, maxval, MAXVAL ); + printf( "#%d;2;%d;%d;%d", colornum, + (int) PPM_GETR( p ), (int) PPM_GETG( p ), (int) PPM_GETB( p ) ); + } printf( "\n" ); } @@ -150,14 +179,14 @@ WriteRawImage( cht, rows, cols ) register pixel* pP; for ( rownum = 0; rownum < rows; ++rownum ) - { - b = rownum % 6; - for ( colnum = 0, pP = pixels[rownum]; colnum < cols; ++colnum, ++pP ) - printf( "#%d%c", ppm_lookupcolor(cht, pP), sixel[b] ); - printf( "$\n" ); /* Carriage Return */ - if ( b == 5 ) - printf( "-\n" ); /* Line Feed (one sixel height) */ - } + { + b = rownum % 6; + for ( colnum = 0, pP = pixels[rownum]; colnum < cols; ++colnum, ++pP ) + printf( "#%d%c", ppm_lookupcolor(cht, pP), sixel[b] ); + printf( "$\n" ); /* Carriage Return */ + if ( b == 5 ) + printf( "-\n" ); /* Line Feed (one sixel height) */ + } } @@ -172,36 +201,36 @@ WritePackedImage( cht, rows, cols ) register pixel* pP; for ( rownum = 0; rownum < rows; ++rownum ) - { - b = rownum % 6; - repeat = 1; - for ( colnum = 0, pP = pixels[rownum]; colnum < cols; ++colnum, ++pP ) - { - thiscolor = ppm_lookupcolor(cht, pP); - if ( colnum == cols -1 ) /* last pixel in row */ - if ( repeat == 1 ) - printf( "#%d%c", thiscolor, sixel[b] ); - else - printf( "#%d!%d%c", thiscolor, repeat, sixel[b] ); - else /* not last pixel in row */ - { - nextcolor = ppm_lookupcolor(cht, pP+1); - if ( thiscolor == nextcolor ) - ++repeat; - else - if ( repeat == 1 ) - printf( "#%d%c", thiscolor, sixel[b] ); - else - { - printf( "#%d!%d%c", thiscolor, repeat, sixel[b] ); - repeat = 1; - } - } - } /* end column loop */ - printf( "$\n" ); /* Carriage Return */ - if ( b == 5 ) - printf( "-\n" ); /* Line Feed (one sixel height) */ - } + { + b = rownum % 6; + repeat = 1; + for ( colnum = 0, pP = pixels[rownum]; colnum < cols; ++colnum, ++pP ) + { + thiscolor = ppm_lookupcolor(cht, pP); + if ( colnum == cols -1 ) /* last pixel in row */ + if ( repeat == 1 ) + printf( "#%d%c", thiscolor, sixel[b] ); + else + printf( "#%d!%d%c", thiscolor, repeat, sixel[b] ); + else /* not last pixel in row */ + { + nextcolor = ppm_lookupcolor(cht, pP+1); + if ( thiscolor == nextcolor ) + ++repeat; + else + if ( repeat == 1 ) + printf( "#%d%c", thiscolor, sixel[b] ); + else + { + printf( "#%d!%d%c", thiscolor, repeat, sixel[b] ); + repeat = 1; + } + } + } /* end column loop */ + printf( "$\n" ); /* Carriage Return */ + if ( b == 5 ) + printf( "-\n" ); /* Line Feed (one sixel height) */ + } } @@ -210,6 +239,6 @@ static void WriteEnd() { if ( margin == 1 ) - printf ( "%c%d;%ds", CSI, 1, 80 ); - printf( "%c\n", ST ); + printf ( "%s%d;%ds", eseqs.CSI, 1, 80 ); + printf( "%s\n", eseqs.ST ); } diff --git a/doc/HISTORY b/doc/HISTORY index 8bd31abb..3b124c3b 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -6,6 +6,9 @@ CHANGE HISTORY not yet BJH Release 11.04.00 + ppmtosixel: Add -7bit, so it works on more terminals, including + xterms. Thanks Scott Pakin. + g3topbm: Add -correctlong build: Add COMPILED_BY environment variable to control the |