diff options
Diffstat (limited to 'converter/pbm')
-rw-r--r-- | converter/pbm/Makefile | 4 | ||||
-rw-r--r-- | converter/pbm/cmuwmtopbm.c | 181 | ||||
-rw-r--r-- | converter/pbm/mgrtopbm.c | 171 | ||||
-rw-r--r-- | converter/pbm/pbmtocmuwm.c | 167 | ||||
-rw-r--r-- | converter/pbm/pbmtogem.c | 6 | ||||
-rw-r--r-- | converter/pbm/pbmtogo.c | 10 | ||||
-rw-r--r-- | converter/pbm/pbmtoicon.c | 252 | ||||
-rw-r--r-- | converter/pbm/pbmtomgr.c | 192 | ||||
-rw-r--r-- | converter/pbm/pbmtopi3.c | 6 | ||||
-rw-r--r-- | converter/pbm/pbmtoptx.c | 6 | ||||
-rw-r--r-- | converter/pbm/pbmtox10bm | 45 | ||||
-rw-r--r-- | converter/pbm/pbmtox10bm.c | 120 | ||||
-rw-r--r-- | converter/pbm/pbmtoxbm.c | 394 | ||||
-rw-r--r-- | converter/pbm/pbmtoybm.c | 6 | ||||
-rw-r--r-- | converter/pbm/xbmtopbm.c | 567 |
15 files changed, 1212 insertions, 915 deletions
diff --git a/converter/pbm/Makefile b/converter/pbm/Makefile index 318b8e9e..f1533ab2 100644 --- a/converter/pbm/Makefile +++ b/converter/pbm/Makefile @@ -17,7 +17,7 @@ PORTBINARIES = atktopbm brushtopbm cmuwmtopbm ddbugtopbm g3topbm escp2topbm \ pbmtomacp pbmtomatrixorbital pbmtomda pbmtomgr pbmtomrf \ pbmtonokia \ pbmtopi3 pbmtoplot pbmtopsg3 pbmtoptx pbmtowbmp \ - pbmtox10bm pbmtoxbm pbmtoybm pbmtozinc \ + pbmtoxbm pbmtoybm pbmtozinc \ pi3topbm pktopbm \ wbmptopbm xbmtopbm ybmtopbm @@ -29,7 +29,7 @@ endif #in libm? MATHBINARIES = pbmtopk BINARIES = $(PORTBINARIES) $(MATHBINARIES) -SCRIPTS = +SCRIPTS = pbmtox10bm OBJECTS = $(BINARIES:%=%.o) diff --git a/converter/pbm/cmuwmtopbm.c b/converter/pbm/cmuwmtopbm.c index dce1d449..ce59491e 100644 --- a/converter/pbm/cmuwmtopbm.c +++ b/converter/pbm/cmuwmtopbm.c @@ -1,4 +1,4 @@ -/* cmuwmtopbm.c - read a CMU window manager bitmap and produce a portable bitmap +/* cmuwmtopbm.c - read a CMU window manager bitmap and produce a PBM image. ** ** Copyright (C) 1989 by Jef Poskanzer. ** @@ -10,105 +10,106 @@ ** implied warranty. */ +/* 2006.10 (afu) + Changed bitrow from plain to raw, read function from getc() to fread(), + write function from pbm_writepbmrow() to pbm_writepbmrow_packed(). + Retired bitwise transformation functions. + + This program does not check the pad bits at the end of each row. +*/ + + #include "pbm.h" #include "cmuwm.h" -static void getinit ARGS(( FILE* file, int* colsP, int* rowsP, short* depthP, int* padrightP )); -static bit getbit ARGS(( FILE* file )); -int -main( argc, argv ) - int argc; - char* argv[]; - { - FILE* ifp; - bit* bitrow; - register bit* bP; - int rows, cols, padright, row, col; - short depth; +static void +readCmuwmHeader(FILE * const ifP, + unsigned int * const colsP, + unsigned int * const rowsP, + unsigned int * const depthP) { - pbm_init( &argc, argv ); + const char * const initReadError = + "CMU window manager header EOF / read error"; - if ( argc > 2 ) - pm_usage( "[cmuwmfile]" ); + long l; + short s; + int rc; + + rc = pm_readbiglong(ifP, &l); + if (rc == -1 ) + pm_error(initReadError); + if (l != CMUWM_MAGIC) + pm_error("bad magic number in CMU window manager file"); + rc = pm_readbiglong(ifP, &l); + if (rc == -1) + pm_error(initReadError); + *colsP = l; + rc = pm_readbiglong(ifP, &l); + if (rc == -1 ) + pm_error(initReadError); + *rowsP = l; + rc = pm_readbigshort(ifP, &s); + if (rc == -1) + pm_error(initReadError); + *depthP = s; +} - if ( argc == 2 ) - ifp = pm_openr( argv[1] ); - else - ifp = stdin; - - getinit( ifp, &cols, &rows, &depth, &padright ); - if ( depth != 1 ) - pm_error( - "CMU window manager file has depth of %d, must be 1", - (int) depth ); - - pbm_writepbminit( stdout, cols, rows, 0 ); - bitrow = pbm_allocrow( cols ); - - for ( row = 0; row < rows; ++row ) - { - /* Get data. */ - for ( col = 0, bP = bitrow; col < cols; ++col, ++bP ) - *bP = getbit( ifp ); - /* Discard line padding */ - for ( col = 0; col < padright; ++col ) - (void) getbit( ifp ); - pbm_writepbmrow( stdout, bitrow, cols, 0 ); - } - - pm_close( ifp ); - pm_close( stdout ); - - exit( 0 ); - } -static int item, bitsperitem, bitshift; -static void -getinit( file, colsP, rowsP, depthP, padrightP ) - FILE* file; - int* colsP; - int* rowsP; - short* depthP; - int* padrightP; - { - long l; +int +main(int argc, + char * argv[]) { - if ( pm_readbiglong( file, &l ) == -1 ) - pm_error( "EOF / read error" ); - if ( l != CMUWM_MAGIC ) - pm_error( "bad magic number in CMU window manager file" ); - if ( pm_readbiglong( file, &l ) == -1 ) - pm_error( "EOF / read error" ); - *colsP = (int) l; - if ( pm_readbiglong( file, &l ) == -1 ) - pm_error( "EOF / read error" ); - *rowsP = (int) l; - if ( pm_readbigshort( file, depthP ) == -1 ) - pm_error( "EOF / read error" ); - *padrightP = ( ( *colsP + 7 ) / 8 ) * 8 - *colsP; - - bitsperitem = 0; - } + FILE * ifP; + unsigned char * bitrow; + unsigned int rows, cols, depth; + unsigned int row; + + const char * inputFileName; -static bit -getbit( file ) - FILE* file; - { - bit b; - - if ( bitsperitem == 0 ) - { - item = getc( file ); - if ( item == EOF ) - pm_error( "EOF / read error" ); - bitsperitem = 8; - bitshift = 7; - } - b = ( ( item >> bitshift) & 1 ) ? PBM_WHITE : PBM_BLACK; - --bitsperitem; - --bitshift; - return b; + pbm_init(&argc, argv); + + if (argc-1 > 1) + pm_error("Too many arguments (%u). " + "Only argument is optional input file", argc-1); + if (argc-1 == 1) + inputFileName = argv[1]; + else + inputFileName = "-"; + + ifP = pm_openr(inputFileName); + + readCmuwmHeader(ifP, &cols, &rows, &depth); + if (depth != 1) + pm_error("CMU window manager file has depth of %u, must be 1", depth); + + pbm_writepbminit(stdout, cols, rows, 0); + bitrow = pbm_allocrow_packed(cols); + + for (row = 0; row < rows; ++row) { + unsigned int const bytesPerRow = pbm_packed_bytes(cols); + unsigned int byteSeq; + size_t bytesRead; + + bytesRead = fread(bitrow, 1, bytesPerRow, ifP); + if (bytesRead != bytesPerRow) + pm_error("CWU window manager bitmap EOF / read error"); + + /* Invert all bits in row - raster formats are similar. + CMUWM Black:0 White:1 End of row padded with 1 + PBM Black:1 White:0 End preferably padded with 0 + */ + + for (byteSeq = 0; byteSeq < bytesPerRow; ++byteSeq) + bitrow[byteSeq] = ~bitrow[byteSeq]; + + pbm_writepbmrow_packed(stdout, bitrow, cols, 0); } + + pm_close(ifP); + pm_close(stdout); + + return 0; +} diff --git a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c index cea4be48..9f7004a1 100644 --- a/converter/pbm/mgrtopbm.c +++ b/converter/pbm/mgrtopbm.c @@ -1,13 +1,10 @@ -/* mgrtopbm.c - read a MGR bitmap and produce a portable bitmap -** -** Copyright (C) 1989 by Jef Poskanzer. -** -** Permission to use, copy, modify, and distribute this software and its -** documentation for any purpose and without fee is hereby granted, provided -** that the above copyright notice appear in all copies and that both that -** copyright notice and this permission notice appear in supporting -** documentation. This software is provided "as is" without express or -** implied warranty. +/* mgrtopbm.c - read a MGR bitmap and produce a PBM image. + + Copyright information is at end of file. + + You can find MGR and some MGR format test images at + ftp://sunsite.unc.edu/pub/Linux/apps/MGR/!INDEX.html + */ #include <string.h> @@ -17,29 +14,29 @@ #include "mgr.h" -static unsigned char item; -static int bitsperitem, bitshift; static void -getinit(FILE * const file, - int * const colsP, - int * const rowsP, - int * const depthP, - int * const padrightP, - int * const bitsperitemP) { - +readMgrHeader(FILE * const ifP, + unsigned int * const colsP, + unsigned int * const rowsP, + unsigned int * const depthP, + unsigned int * const padrightP ) { + struct b_header head; - int pad; + unsigned int pad; + size_t bytesRead; - if (fread(&head, sizeof(struct old_b_header), 1, file ) != 1) + bytesRead = fread(&head, sizeof(struct old_b_header), 1, ifP); + if (bytesRead != 1) pm_error("Unable to read 1st byte of file. " "fread() returns errno %d (%s)", errno, strerror(errno)); if (head.magic[0] == 'y' && head.magic[1] == 'z') { /* new style bitmap */ - if (fread(&head.depth, - sizeof(head) - sizeof(struct old_b_header), 1, file) - != 1 ) + size_t bytesRead; + bytesRead = fread(&head.depth, + sizeof(head) - sizeof(struct old_b_header), 1, ifP); + if (bytesRead != 1 ) pm_error("Unable to read header after 1st byte. " "fread() returns errno %d (%s)", errno, strerror(errno)); @@ -60,7 +57,7 @@ getinit(FILE * const file, } else { pm_error("bad magic chars in MGR file: '%c%c'", head.magic[0], head.magic[1] ); - pad = -1; /* should never reach here */ + pad = 0; /* should never reach here */ } if (head.h_wide < ' ' || head.l_wide < ' ') @@ -71,75 +68,79 @@ getinit(FILE * const file, *colsP = (((int)head.h_wide - ' ') << 6) + ((int)head.l_wide - ' '); *rowsP = (((int)head.h_high - ' ') << 6) + ((int) head.l_high - ' '); *padrightP = ( ( *colsP + pad - 1 ) / pad ) * pad - *colsP; - - *bitsperitemP = 8; } -static bit -getbit( file ) - FILE* file; - { - bit b; - - if ( bitsperitem == 8 ) - { - item = getc( file ); - bitsperitem = 0; - bitshift = 7; - } - bitsperitem++; - b = ( ( item >> bitshift) & 1 ) ? PBM_BLACK : PBM_WHITE; - bitshift--; - return b; - } - +int +main(int argc, + char * argv[]) { + + FILE * ifP; + unsigned char * bitrow; + unsigned int rows, cols, depth; + unsigned int padright; + unsigned int row; + unsigned int itemCount; + const char * inputFileName; + + pbm_init(&argc, argv); + + if (argc-1 > 1) + pm_error("Too many arguments (%u). " + "Only argument is optional input file", argc-1); + if (argc-1 == 1) + inputFileName = argv[1]; + else + inputFileName = "-"; + + ifP = pm_openr(inputFileName); + readMgrHeader(ifP, &cols, &rows, &depth, &padright); + if (depth != 1) + pm_error("MGR file has depth of %u, must be 1", depth); -int -main( argc, argv ) - int argc; - char* argv[]; - { - FILE* ifp; - bit* bitrow; - register bit* bP; - int rows, cols, depth, padright, row, col; + pbm_writepbminit(stdout, cols, rows, 0); + bitrow = pbm_allocrow_packed(cols + padright); + + itemCount = (cols + padright ) / 8; + + for (row = 0; row < rows; ++row) { + /* The raster formats are nearly identical. + MGR may have rows padded to 16 or 32 bit boundaries. + */ + size_t bytesRead; + bytesRead = fread(bitrow, 1, itemCount, ifP); + if (bytesRead < itemCount) + pm_error("fread() failed to read mgr bitmap data"); + + pbm_writepbmrow_packed(stdout, bitrow, cols, 0); + } + pm_close(ifP); + pm_close(stdout); + return 0; +} - pbm_init( &argc, argv ); - if ( argc > 2 ) - pm_usage( "[mgrfile]" ); - if ( argc == 2 ) - ifp = pm_openr( argv[1] ); - else - ifp = stdin; - - getinit( ifp, &cols, &rows, &depth, &padright, &bitsperitem ); - if ( depth != 1 ) - pm_error( "MGR file has depth of %d, must be 1", depth ); - - pbm_writepbminit( stdout, cols, rows, 0 ); - bitrow = pbm_allocrow( cols ); - - for ( row = 0; row < rows; row++ ) - { - /* Get data, bit-reversed within each byte. */ - for ( col = 0, bP = bitrow; col < cols; col++, bP++ ) - *bP = getbit( ifp ); - /* Discard line padding */ - for ( col = 0; col < padright; col ++ ) - (void) getbit( ifp ); - pbm_writepbmrow( stdout, bitrow, cols, 0 ); - } - - pm_close( ifp ); - pm_close( stdout ); - - exit( 0 ); - } +/* 2006.10 (afu) + Changed bitrow from plain to raw, read function from getc() to fread(), + write function from pbm_writepbmrow() to pbm_writepbmrow_packed(). + Retired bitwise transformation functions. + + NOT tested for old-style format files. Only one zz file in mgrsrc-0.69 . + +*/ +/* +** Copyright (C) 1989 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ diff --git a/converter/pbm/pbmtocmuwm.c b/converter/pbm/pbmtocmuwm.c index 64d7af40..773d988b 100644 --- a/converter/pbm/pbmtocmuwm.c +++ b/converter/pbm/pbmtocmuwm.c @@ -1,4 +1,4 @@ -/* pbmtocmuwm.c - read a portable bitmap and produce a CMU window manager bitmap +/* pbmtocmuwm.c - read a PBM image and produce a CMU window manager bitmap ** ** Copyright (C) 1989 by Jef Poskanzer. ** @@ -10,108 +10,95 @@ ** implied warranty. */ -#include "pbm.h" -#include "cmuwm.h" +/* 2006.10 (afu) + Changed bitrow from plain to raw, read function from pbm_readpbmrow() to + pbm_readpbmrow_packed(), write function from putc() to fwrite(). -static void putinit ARGS(( int rows, int cols )); -static void putbit ARGS(( bit b )); -static void putrest ARGS(( void )); -static void putitem ARGS(( void )); - -int -main( argc, argv ) - int argc; - char* argv[]; - { - FILE* ifp; - bit* bitrow; - register bit* bP; - int rows, cols, format, padright, row, col; + Retired bitwise transformation functions. +*/ +#include "pbm.h" +#include "cmuwm.h" - pbm_init( &argc, argv ); +static void +putinit(unsigned int const rows, + unsigned int const cols) { - if ( argc > 2 ) - pm_usage( "[pbmfile]" ); + const char * const initWriteError = + "CMU window manager header write error"; - if ( argc == 2 ) - ifp = pm_openr( argv[1] ); - else - ifp = stdin; + int rc; - pbm_readpbminit( ifp, &cols, &rows, &format ); - bitrow = pbm_allocrow( cols ); - - /* Round cols up to the nearest multiple of 8. */ - padright = ( ( cols + 7 ) / 8 ) * 8 - cols; + rc = pm_writebiglong(stdout, CMUWM_MAGIC); + if (rc == -1) + pm_error(initWriteError); + rc = pm_writebiglong(stdout, cols); + if (rc == -1) + pm_error(initWriteError); + rc = pm_writebiglong(stdout, rows); + if (rc == -1) + pm_error(initWriteError); + rc = pm_writebigshort(stdout, (short) 1); + if (rc == -1) + pm_error(initWriteError); +} - putinit( rows, cols ); - for ( row = 0; row < rows; row++ ) - { - pbm_readpbmrow( ifp, bitrow, cols, format ); - for ( col = 0, bP = bitrow; col < cols; col++, bP++ ) - putbit( *bP ); - for ( col = 0; col < padright; col++ ) - putbit( 0 ); - } - pm_close( ifp ); - putrest( ); +int +main(int argc, + char * argv[]) { - exit( 0 ); - } + FILE * ifP; + unsigned char * bitrow; + int rows, cols; + int format; + unsigned int row; + const char * inputFileName; -static unsigned char item; -static int bitsperitem, bitshift; + pbm_init(&argc, argv); -static void -putinit( rows, cols ) - int rows, cols; - { - if ( pm_writebiglong( stdout, CMUWM_MAGIC ) == -1 ) - pm_error( "write error" ); - if ( pm_writebiglong( stdout, cols ) == -1 ) - pm_error( "write error" ); - if ( pm_writebiglong( stdout, rows ) == -1 ) - pm_error( "write error" ); - if ( pm_writebigshort( stdout, (short) 1 ) == -1 ) - pm_error( "write error" ); - - item = 0; - bitsperitem = 0; - bitshift = 7; - } + if (argc-1 > 1) + pm_error("Too many arguments (%u). " + "Only argument is optional input file", argc-1); + if (argc-1 == 1) + inputFileName = argv[1]; + else + inputFileName = "-"; + + ifP = pm_openr(inputFileName); -#if __STDC__ -static void -putbit( bit b ) -#else /*__STDC__*/ -static void -putbit( b ) - bit b; -#endif /*__STDC__*/ - { - if ( bitsperitem == 8 ) - putitem( ); - if ( b == PBM_WHITE ) - item += 1 << bitshift; - bitsperitem++; - bitshift--; - } + pbm_readpbminit(ifP, &cols, &rows, &format); + bitrow = pbm_allocrow_packed(cols); -static void -putrest( ) - { - if ( bitsperitem > 0 ) - putitem( ); + putinit(rows, cols); + + /* Convert PBM raster data to CMUWM and write */ + for (row = 0; row < rows; ++row) { + unsigned int const bytesPerRow = pbm_packed_bytes(cols); + unsigned char const padding = + (cols % 8 == 0) ? 0x00 : ((unsigned char) ~0 >> (cols % 8)); + + unsigned int i; + size_t bytesWritten; + + pbm_readpbmrow_packed(ifP, bitrow, cols, format); + + /* Invert all bits in row - raster formats are similar. + PBM Black:1 White:0 "Don't care" bits at end of row + CMUWM Black:0 White:1 End of row padded with 1 + */ + + for (i = 0; i < bytesPerRow; ++i) + bitrow[i] = ~bitrow[i]; + + bitrow[bytesPerRow-1] |= padding; /* Set row end pad bits */ + + bytesWritten = fwrite(bitrow, 1, bytesPerRow, stdout); + if (bytesWritten != bytesPerRow) + pm_error("fwrite() failed to write CMU window manager bitmap"); } -static void -putitem( ) - { - (void) putc( item, stdout ); - item = 0; - bitsperitem = 0; - bitshift = 7; - } + pm_close(ifP); + return 0; +} diff --git a/converter/pbm/pbmtogem.c b/converter/pbm/pbmtogem.c index 59f2b9cf..cefbdc95 100644 --- a/converter/pbm/pbmtogem.c +++ b/converter/pbm/pbmtogem.c @@ -129,14 +129,8 @@ putinit (rows, cols) linerepeat = -1; } -#if __STDC__ static void putbit( bit b ) -#else /*__STDC__*/ -static void -putbit( b ) - bit b; -#endif /*__STDC__*/ { if ( bitsperitem == 8 ) putitem( ); diff --git a/converter/pbm/pbmtogo.c b/converter/pbm/pbmtogo.c index b7c12373..67fe5821 100644 --- a/converter/pbm/pbmtogo.c +++ b/converter/pbm/pbmtogo.c @@ -214,7 +214,7 @@ main( argc, argv ) fflush(stdout); /* Output the plot data */ - write(1, outbuffer, nout); + fwrite(outbuffer, 1, nout, stdout); /* Reset the counters */ linerepeat = 0; @@ -225,7 +225,7 @@ main( argc, argv ) putchar(linerepeat); printf("%d/", nout+1); fflush(stdout); - write(1, outbuffer, nout); + fwrite(outbuffer, 1, nout, stdout); linerepeat = 0; } } @@ -264,14 +264,8 @@ putinit() bitshift = 7; } -#if __STDC__ static void putbit(bit b) -#else /*__STDC__*/ -static void -putbit(b) -bit b; -#endif /*__STDC__*/ { if (b == PBM_BLACK) item += 1 << bitshift; diff --git a/converter/pbm/pbmtoicon.c b/converter/pbm/pbmtoicon.c index 0e21c202..d5fefb76 100644 --- a/converter/pbm/pbmtoicon.c +++ b/converter/pbm/pbmtoicon.c @@ -1,4 +1,4 @@ -/* pbmtoicon.c - read a portable bitmap and produce a Sun icon file +/* pbmtoicon.c - read a PBM image and produce a Sun icon file ** ** Copyright (C) 1988 by Jef Poskanzer. ** @@ -10,125 +10,177 @@ ** implied warranty. */ +/* 2006.10 (afu) + Changed bitrow from plain to raw, read function from pbm_readpbmrow() to + pbm_readpbmrow_packed. Applied wordint to scoop up 16 bit output items. + putitem changed to better express the output format. + Retired bitwise transformation functions. +*/ + +#include "wordaccess.h" #include "pbm.h" -static void putinit ARGS(( void )); -static void putbit ARGS(( bit b )); -static void putrest ARGS(( void )); -static void putitem ARGS(( void )); +static unsigned short int itemBuff[8]; +static unsigned int itemCnt; /* takes values 0 to 8 */ +FILE * putFp; -int -main( argc, argv ) - int argc; - char* argv[]; - { - FILE* ifp; - bit* bitrow; - register bit* bP; - int rows, cols, format, pad, padleft, padright, row, col; - pbm_init( &argc, argv ); +static void +putinit(FILE * const ofP) { + putFp = ofP; + itemCnt = 0; +} - if ( argc > 2 ) - pm_usage( "[pbmfile]" ); - if ( argc == 2 ) - ifp = pm_openr( argv[1] ); - else - ifp = stdin; - pbm_readpbminit( ifp, &cols, &rows, &format ); - bitrow = pbm_allocrow( cols ); +static void +putitem(wordint const item) { + + if (itemCnt == 8 ) { + /* Buffer is full. Write out one line. */ + int rc; - /* Round cols up to the nearest multiple of 16. */ - pad = ( ( cols + 15 ) / 16 ) * 16 - cols; - padleft = pad / 2; - padright = pad - padleft; - - printf( "/* Format_version=1, Width=%d, Height=%d", cols + pad, rows ); - printf( ", Depth=1, Valid_bits_per_item=16\n */\n" ); - - putinit( ); - for ( row = 0; row < rows; ++row ) - { - pbm_readpbmrow( ifp, bitrow, cols, format ); - for ( col = 0; col < padleft; ++col ) - putbit( 0 ); - for ( col = 0, bP = bitrow; col < cols; ++col, ++bP ) - putbit( *bP ); - for ( col = 0; col < padright; ++col ) - putbit( 0 ); - } + rc = fprintf(putFp, + "\t0x%04x,0x%04x,0x%04x,0x%04x," + "0x%04x,0x%04x,0x%04x,0x%04x,\n", + itemBuff[0],itemBuff[1],itemBuff[2],itemBuff[3], + itemBuff[4],itemBuff[5],itemBuff[6],itemBuff[7]); + if (rc < 0) + pm_error("fprintf() failed to write Icon bitmap"); + + itemCnt = 0; + } + itemBuff[itemCnt++] = item & 0xffff; /* Only lower 16 bits are used */ +} - pm_close( ifp ); - putrest( ); - exit( 0 ); - } +static void +putterm(void) { -static int item, bitsperitem, bitshift, itemsperline, firstitem; + unsigned int i; -static void -putinit( ) - { - itemsperline = 0; - bitsperitem = 0; - item = 0; - bitshift = 15; - firstitem = 1; + for (i = 0; i < itemCnt; ++i) { + int rc; + rc = fprintf(putFp, "%s0x%04x%c", i == 0 ? "\t" : "", itemBuff[i], + i == itemCnt - 1 ? '\n' : ','); + if (rc < 0) + pm_error("fprintf() failed to write Icon bitmap"); } +} + + -#if __STDC__ -static void -putbit( bit b ) -#else /*__STDC__*/ static void -putbit( b ) -bit b; -#endif /*__STDC__*/ - { - if ( bitsperitem == 16 ) - putitem( ); - ++bitsperitem; - if ( b == PBM_BLACK ) - item += 1 << bitshift; - --bitshift; - } +writeIconHeader(FILE * const ofP, + unsigned int const width, + unsigned int const height) { + + int rc; + + rc = fprintf(ofP, + "/* Format_version=1, Width=%u, Height=%u", width, height); + if (rc < 0) + pm_error("fprintf() failed to write Icon header"); + + rc = fprintf(ofP, ", Depth=1, Valid_bits_per_item=16\n */\n"); + if (rc < 0) + pm_error("fprintf() failed to write Icon header"); +} + + static void -putrest( ) - { - if ( bitsperitem > 0 ) - putitem( ); - putchar( '\n' ); +writeIcon(FILE * const ifP, + unsigned int const cols, + unsigned int const rows, + int const format, + FILE * const ofP) { + + unsigned int const wordintSize = sizeof(wordint) * 8; + /* wordintSize is usually 32 or 64 bits. Must be at least 24. */ + unsigned int const items = (cols + 15) / 16; + unsigned int const bitrowBytes = pbm_packed_bytes(cols); + unsigned int const pad = items * 16 - cols; + /* 'padleft' is added to the output. 'padbyte' is for cleaning + the input + */ + unsigned int const padleft = pad / 2; + unsigned int const padbyte = bitrowBytes * 8 - cols; + unsigned int const shift = (wordintSize - 24) + padleft; + + unsigned char * bitbuffer; + unsigned char * bitrow; + unsigned int row; + + bitbuffer = pbm_allocrow_packed(cols + wordintSize); + bitrow = &bitbuffer[1]; + bitbuffer[0] = 0; + bitrow[bitrowBytes] = 0; + + writeIconHeader(ofP, cols + pad, rows); + + putinit(ofP); + + for (row = 0; row < rows; ++row) { + unsigned int itemSeq; + pbm_readpbmrow_packed(ifP, bitrow, cols, format); + + /* Clear post-data junk in final partial byte */ + if (padbyte > 0) { + bitrow[bitrowBytes-1] >>= padbyte; + bitrow[bitrowBytes-1] <<= padbyte; + } + + for (itemSeq = 0; itemSeq < items; ++itemSeq) { + /* Scoop up bits, shift-align, send to format & print function. + + An item is 16 bits, typically spread over 3 bytes due to + left-padding. We use wordint here to scoop up 4 (or more) + consecutive bytes. An item always resides within the higher + 24 bits of each scoop. It is essential to use wordint + (or rather the wordaccess function bytesToWordInt() ); + simple long, uint_32t, etc. do not work for they are not + shift-tolerant. + */ + + wordint const scoop = bytesToWordint(&bitbuffer[itemSeq*2]); + putitem (scoop >> shift); + } } + putterm(); +} -static void -putitem( ) - { - const char* hexits = "0123456789abcdef"; - if ( firstitem ) - firstitem = 0; + +int +main(int argc, + char * argv[]) { + + FILE * ifP; + int rows, cols; + int format; + const char * inputFileName; + + pbm_init(&argc, argv); + + if (argc-1 > 1) + pm_error("Too many arguments (%u). " + "Only argument is optional input file", argc-1); + if (argc-1 == 1) + inputFileName = argv[1]; else - putchar( ',' ); - if ( itemsperline == 8 ) - { - putchar( '\n' ); - itemsperline = 0; - } - if ( itemsperline == 0 ) - putchar( '\t' ); - putchar( '0' ); - putchar( 'x' ); - putchar( hexits[item >> 12] ); - putchar( hexits[( item >> 8 ) & 15] ); - putchar( hexits[( item >> 4 ) & 15] ); - putchar( hexits[item & 15] ); - ++itemsperline; - bitsperitem = 0; - item = 0; - bitshift = 15; - } + inputFileName = "-"; + + ifP = pm_openr(inputFileName); + + pbm_readpbminit(ifP, &cols, &rows, &format); + + writeIcon(ifP, cols, rows, format, stdout); + + pm_close(ifP); + + return 0; +} + diff --git a/converter/pbm/pbmtomgr.c b/converter/pbm/pbmtomgr.c index 7a6e7fc1..2ca7c7d0 100644 --- a/converter/pbm/pbmtomgr.c +++ b/converter/pbm/pbmtomgr.c @@ -1,120 +1,114 @@ -/* pbmtomgr.c - read a portable bitmap and produce a MGR bitmap -** -** Copyright (C) 1989 by Jef Poskanzer. -** -** Permission to use, copy, modify, and distribute this software and its -** documentation for any purpose and without fee is hereby granted, provided -** that the above copyright notice appear in all copies and that both that -** copyright notice and this permission notice appear in supporting -** documentation. This software is provided "as is" without express or -** implied warranty. +/* pbmtomgr.c - read a PBM image and produce a MGR bitmap + + Copyright information is at end of file. + + You can find MGR and some MGR format test images at + ftp://sunsite.unc.edu/pub/Linux/apps/MGR/!INDEX.html */ #include "pbm.h" #include "mgr.h" -static void putinit ARGS(( int rows, int cols )); -static void putbit ARGS(( bit b )); -static void putrest ARGS(( void )); -static void putitem ARGS(( void )); +static void +putinit(unsigned int const rows, + unsigned int const cols) { -int -main( argc, argv ) - int argc; - char* argv[]; - { - FILE* ifp; - bit* bitrow; - register bit* bP; - int rows, cols, format, padright, row, col; + struct b_header head; + size_t writtenCount; + head.magic[0] = 'y'; + head.magic[1] = 'z'; + head.h_wide = ((cols >> 6) & 0x3f) + ' '; + head.l_wide = (cols & 0x3f) + ' '; + head.h_high = (( rows >> 6) & 0x3f) + ' '; + head.l_high = (rows & 0x3f) + ' '; + head.depth = (1 & 0x3f) + ' '; + head._reserved = ' '; + writtenCount = fwrite(&head, sizeof(head), 1, stdout); + if (writtenCount != 1) + pm_error("fwrite() failed to write the MGR header."); +} - pbm_init( &argc, argv ); - if ( argc > 2 ) - pm_usage( "[pbmfile]" ); - if ( argc == 2 ) - ifp = pm_openr( argv[1] ); +int +main(int argc, + char * argv[]) { + + FILE * ifP; + unsigned char * bitrow; + int rows; + int cols; + int format; + unsigned int row; + unsigned int bytesPerRow; + /* Number of packed bytes (8 columns per byte) in a row. */ + unsigned int padright; + /* Number of columns added to the right of each row to get up to + a multiple of 8, i.e. an integral number of packed bytes. + */ + const char * inputFileName; + + pbm_init(&argc, argv); + + if (argc-1 > 1) + pm_error("Too many arguments (%u). " + "Only argument is optional input file", argc-1); + if (argc-1 == 1) + inputFileName = argv[1]; else - ifp = stdin; - - pbm_readpbminit( ifp, &cols, &rows, &format ); - bitrow = pbm_allocrow( cols ); + inputFileName = "-"; - /* Round cols up to the nearest multiple of 8. */ - padright = ( ( cols + 7 ) / 8 ) * 8 - cols; - - putinit( rows, cols ); - for ( row = 0; row < rows; ++row ) - { - pbm_readpbmrow( ifp, bitrow, cols, format ); - for ( col = 0, bP = bitrow; col < cols; ++col, ++bP ) - putbit( *bP ); - for ( col = 0; col < padright; ++col ) - putbit( 0 ); - } + ifP = pm_openr(inputFileName); - pm_close( ifp ); + pbm_readpbminit(ifP, &cols, &rows, &format); + + bitrow = pbm_allocrow_packed(cols); + bytesPerRow = pbm_packed_bytes(cols); + padright = bytesPerRow * 8 - cols; - putrest( ); + putinit(rows, cols); + + for (row = 0; row < rows; ++row) { + /* The raster formats are identical. + The row end pad bits are set to 0 in mgr. + */ + size_t bytesWritten; + + pbm_readpbmrow_packed(ifP, bitrow, cols, format); + + if (padright > 0) { + bitrow[bytesPerRow-1] >>= padright; + bitrow[bytesPerRow-1] <<= padright; + } - exit( 0 ); + bytesWritten = fwrite(bitrow, 1, bytesPerRow, stdout); + if (bytesWritten != bytesPerRow ) + pm_error("fwrite() failed to write MGR bitmap " + "to Standard Output."); } + pm_close(ifP); + return 0; +} -static unsigned char item; -static int bitsperitem, bitshift; - -static void -putinit( rows, cols ) - int rows, cols; - { - struct b_header head; - - head.magic[0] = 'y'; - head.magic[1] = 'z'; - head.h_wide = ( ( cols >> 6 ) & 0x3f ) + ' '; - head.l_wide = ( cols & 0x3f ) + ' '; - head.h_high = ( ( rows >> 6 ) & 0x3f ) + ' '; - head.l_high = ( rows & 0x3f ) + ' '; - head.depth = ( 1 & 0x3f ) + ' '; - head._reserved = ' '; - fwrite( &head, sizeof(head), 1, stdout ); - item = 0; - bitsperitem = 0; - bitshift = 7; - } -#if __STDC__ -static void -putbit( bit b ) -#else /*__STDC__*/ -static void -putbit( b ) - bit b; -#endif /*__STDC__*/ - { - if ( bitsperitem == 8 ) - putitem( ); - ++bitsperitem; - if ( b == PBM_BLACK ) - item += 1 << bitshift; - --bitshift; - } +/* 2006.10 (afu) + Changed bitrow from plain to raw, read function from pbm_readpbmrow() to + pbm_readpbmrow_packed(), write function from putc() to fwrite(). -static void -putrest( ) - { - if ( bitsperitem > 0 ) - putitem( ); - } + Retired bitwise transformation functions. + + Produces only new style bitmap (8 bit padding.) See mgrtopbm.c . +*/ -static void -putitem( ) - { - fwrite( &item, sizeof(item), 1, stdout ); - item = 0; - bitsperitem = 0; - bitshift = 7; - } +/* +** Copyright (C) 1989 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ diff --git a/converter/pbm/pbmtopi3.c b/converter/pbm/pbmtopi3.c index 06023d7a..6a60af62 100644 --- a/converter/pbm/pbmtopi3.c +++ b/converter/pbm/pbmtopi3.c @@ -89,14 +89,8 @@ putinit( ) bitshift = 7; } -#if __STDC__ static void putbit( bit b ) -#else /*__STDC__*/ -static void -putbit( b ) - bit b; -#endif /*__STDC__*/ { if (bitsperitem == 8) putitem( ); diff --git a/converter/pbm/pbmtoptx.c b/converter/pbm/pbmtoptx.c index 5031efcb..8cd60326 100644 --- a/converter/pbm/pbmtoptx.c +++ b/converter/pbm/pbmtoptx.c @@ -67,14 +67,8 @@ putinit( ) bitshift = 0; } -#if __STDC__ static void putbit( bit b ) -#else /*__STDC__*/ -static void -putbit( b ) - bit b; -#endif /*__STDC__*/ { if ( bitsperitem == 6 ) putitem( ); diff --git a/converter/pbm/pbmtox10bm b/converter/pbm/pbmtox10bm new file mode 100644 index 00000000..9a1a7286 --- /dev/null +++ b/converter/pbm/pbmtox10bm @@ -0,0 +1,45 @@ +#! /usr/bin/perl + +#============================================================================ +# This is a compatibility interface to Pbmtoxbm. +# +# It exists so existing programs and procedures that rely on Pbmtox10bm +# syntax continue to work. You should not make new use of Pbmtox10bm and +# if you modify an old use, you should upgrade it to use Pbmtoxbm. +# +# Pbmtoxbm with the -x10 option is backward compatible with Pbmtox10bm. +#============================================================================ + +use strict; +use File::Basename; +use Cwd 'abs_path'; + +my $infile; + +foreach (@ARGV) { + if (/^-/) { + # It's an option. But Pbmtox10bm didn't have any options. + print(STDERR "Invalid option '$_'\n"); + exit(10); + } else { + # It's a parameter + if (defined($infile)) { + print(STDERR + "You may specify at most one non-option parameter.\n"); + exit(10); + } else { + $infile = $_; + } + } +} + +my $infileParm = defined($infile) ? $infile : "-"; + +# We want to get Pbmtoxbm from the same directory we came from if +# it's there. Frequently, the directory containing Netpbm programs is +# not in the PATH and we were invoked by absolute path. + +my $my_directory = abs_path(dirname($0)); +$ENV{"PATH"} = $my_directory . ":" . $ENV{"PATH"}; + +exec('pbmtoxbm', '-x10', $infileParm); diff --git a/converter/pbm/pbmtox10bm.c b/converter/pbm/pbmtox10bm.c deleted file mode 100644 index ef31fb9b..00000000 --- a/converter/pbm/pbmtox10bm.c +++ /dev/null @@ -1,120 +0,0 @@ -/* pbmtox10bm.c - read a portable bitmap and produce an X10 bitmap file -** -** Copyright (C) 1988 by Jef Poskanzer. -** -** Permission to use, copy, modify, and distribute this software and its -** documentation for any purpose and without fee is hereby granted, provided -** that the above copyright notice appear in all copies and that both that -** copyright notice and this permission notice appear in supporting -** documentation. This software is provided "as is" without express or -** implied warranty. -*/ - -#include <string.h> - -#include "nstring.h" -#include "pbm.h" - -int -main(int argc, char * argv[]) { - - FILE* ifp; - bit* bitrow; - bit * bP; - int rows, cols, format, padright, row; - int col; - char name[100]; - char* cp; - int itemsperline; - int bitsperitem; - int item; - int firstitem; - const char* const hexchar = "0123456789abcdef"; - - - pbm_init( &argc, argv ); - - if ( argc > 2 ) - pm_usage( "[pbmfile]" ); - - if ( argc == 2 ) - { - ifp = pm_openr( argv[1] ); - strcpy( name, argv[1] ); - if (STREQ( name, "-" )) - strcpy( name, "noname" ); - - if ( ( cp = strchr( name, '.' ) ) != 0 ) - *cp = '\0'; - } - else - { - ifp = stdin; - strcpy( name, "noname" ); - } - - pbm_readpbminit( ifp, &cols, &rows, &format ); - bitrow = pbm_allocrow( cols ); - - /* Compute padding to round cols up to the nearest multiple of 16. */ - padright = ( ( cols + 15 ) / 16 ) * 16 - cols; - - printf( "#define %s_width %d\n", name, cols ); - printf( "#define %s_height %d\n", name, rows ); - printf( "static short %s_bits[] = {\n", name ); - - itemsperline = 0; - bitsperitem = 0; - item = 0; - firstitem = 1; - -#define PUTITEM \ - { \ - if ( firstitem ) \ - firstitem = 0; \ - else \ - putchar( ',' ); \ - if ( itemsperline == 11 ) \ - { \ - putchar( '\n' ); \ - itemsperline = 0; \ - } \ - if ( itemsperline == 0 ) \ - putchar( ' ' ); \ - ++itemsperline; \ - putchar('0'); \ - putchar('x'); \ - putchar(hexchar[item >> 12]); \ - putchar(hexchar[(item >> 8) & 15]); \ - putchar(hexchar[(item >> 4) & 15]); \ - putchar(hexchar[item & 15]); \ - bitsperitem = 0; \ - item = 0; \ - } - -#define PUTBIT(b) \ - { \ - if ( bitsperitem == 16 ) \ - PUTITEM; \ - if ( (b) == PBM_BLACK ) \ - item += 1 << bitsperitem; \ - ++bitsperitem; \ - } - - for ( row = 0; row < rows; ++row ) - { - pbm_readpbmrow( ifp, bitrow, cols, format ); - for ( col = 0, bP = bitrow; col < cols; ++col, ++bP ) - PUTBIT(*bP); - for ( col = 0; col < padright; ++col ) - PUTBIT(0); - } - - pm_close( ifp ); - - if ( bitsperitem > 0 ) - PUTITEM; - printf( "};\n" ); - - return 0; -} diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c index 96830a0c..eb45f11b 100644 --- a/converter/pbm/pbmtoxbm.c +++ b/converter/pbm/pbmtoxbm.c @@ -1,4 +1,4 @@ -/* pbmtoxbm.c - read a portable bitmap and produce an X11 bitmap file +/* pbmtoxbm.c - read a PBM image and produce an X11/X10 bitmap file ** ** Copyright (C) 1988 by Jef Poskanzer. ** @@ -10,17 +10,113 @@ ** implied warranty. */ +/* 2006.10 (afu) + Changed bitrow from plain to raw, read function from pbm_readpbmrow() to + pbm_readpbmrow_packed(). Retired bitwise transformation functions. + + Output function putitem rewritten to handle both X10 and X11. + + Added -name option. There is no check for the string thus given. + +*/ + #define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ #include <string.h> #include "pbm.h" +#include "shhopt.h" +#include "mallocvar.h" +#include "bitreverse.h" #include "nstring.h" +enum xbmVersion { X10, X11 }; + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * inputFileName; + const char * name; + enum xbmVersion xbmVersion; +}; + static void -generateName(char const filenameArg[], const char ** const nameP) { +parseCommandLine(int argc, + char ** argv, + struct cmdlineInfo *cmdlineP ) { +/*---------------------------------------------------------------------------- + Parse program command line described in Unix standard form by argc + and argv. Return the information in the options as *cmdlineP. + + If command line is internally inconsistent (invalid options, etc.), + issue error message to stderr and abort program. + + Note that the strings we return are stored in the storage that + was passed to us as the argv array. We also trash *argv. +-----------------------------------------------------------------------------*/ + optEntry *option_def; + /* Instructions to optParseOptions3 on how to parse our options. */ + + optStruct3 opt; + unsigned int option_def_index; + unsigned int x10, x11, nameSpec; + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + + OPTENT3(0, "name", OPT_STRING, &cmdlineP->name, &nameSpec, 0); + OPTENT3(0, "x10" , OPT_FLAG, NULL, &x10, 0); + OPTENT3(0, "x11" , OPT_FLAG, NULL, &x11, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3( &argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (!nameSpec) + cmdlineP->name = NULL; + else if (strlen(cmdlineP->name) > 56) + pm_error("Image name too long: %d chars. (max 56)", + strlen(cmdlineP->name)); + else if (!ISALPHA(cmdlineP->name[0]) && cmdlineP->name[0] !='_') + pm_error("Image name '%s' starts with non-alphabet character.", + cmdlineP->name); + else { + unsigned int i; + for (i = 0 ; i < strlen(cmdlineP->name); ++i) + if (!ISALNUM(cmdlineP->name[i]) && cmdlineP->name[i] != '_') + pm_error("Image name '%s' contains invalid character (%c).", + cmdlineP->name, cmdlineP->name[i]); + } + + if (x10 && x11) + pm_error("You can't specify both -x10 and -x11"); + else if (x10) + cmdlineP->xbmVersion = X10; + else + cmdlineP->xbmVersion = X11; + + if (argc-1 < 1) + cmdlineP->inputFileName = "-"; + else { + cmdlineP->inputFileName = argv[1]; + + if (argc-1 > 1) + pm_error("Program takes zero or one argument (filename). You " + "specified %u", argc-1); + } +} + + + +static void +generateName(char const filenameArg[], + const char ** const nameP) { /*---------------------------------------------------------------------------- Generate a name for the image to put in the bitmap file. Derive it from the filename argument filenameArg[] and return it as a null-terminated @@ -67,99 +163,235 @@ generateName(char const filenameArg[], const char ** const nameP) { -int -main(int argc, char * argv[]) { +static unsigned short int itemBuff[22]; +static int itemCnt; /* takes values 0 to 15 (x11) or 21 (x10) */ +static enum xbmVersion itemVersion; - FILE* ifp; - bit* bitrow; - int rows, cols, format; - int padright; - int row; - const char * inputFilename; - const char *name; - int itemsperline; - int bitsperitem; - int item; - int firstitem; - const char hexchar[] = "0123456789abcdef"; - pbm_init(&argc, argv); - if (argc-1 > 1) - pm_error("Too many arguments (%d). The only valid argument is an " - "input file name.", argc-1); - else if (argc-1 == 1) - inputFilename = argv[1]; - else - inputFilename = "-"; +static void +putitemX10(unsigned char const item) { - generateName(inputFilename, &name); - ifp = pm_openr(inputFilename); - - pbm_readpbminit(ifp, &cols, &rows, &format); - bitrow = pbm_allocrow(cols); - - /* Compute padding to round cols up to the nearest multiple of 8. */ - padright = ((cols + 7)/8) * 8 - cols; - - printf("#define %s_width %d\n", name, cols); - printf("#define %s_height %d\n", name, rows); - printf("static char %s_bits[] = {\n", name); - - itemsperline = 0; - bitsperitem = 0; - item = 0; - firstitem = 1; - -#define PUTITEM \ - { \ - if ( firstitem ) \ - firstitem = 0; \ - else \ - putchar( ',' ); \ - if ( itemsperline == 15 ) \ - { \ - putchar( '\n' ); \ - itemsperline = 0; \ - } \ - if ( itemsperline == 0 ) \ - putchar( ' ' ); \ - ++itemsperline; \ - putchar('0'); \ - putchar('x'); \ - putchar(hexchar[item >> 4]); \ - putchar(hexchar[item & 15]); \ - bitsperitem = 0; \ - item = 0; \ + if (itemCnt == 22) { + /* Buffer is full. Write out one line. */ + int rc; + rc = printf(" 0x%02x%02x,0x%02x%02x,0x%02x%02x,0x%02x%02x," + "0x%02x%02x,0x%02x%02x,0x%02x%02x,0x%02x%02x," + "0x%02x%02x,0x%02x%02x,0x%02x%02x,\n", + itemBuff[ 1], itemBuff[ 0], itemBuff[ 3], itemBuff[ 2], + itemBuff[ 5], itemBuff[ 4], itemBuff[ 7], itemBuff[ 6], + itemBuff[ 9], itemBuff[ 8], itemBuff[11], itemBuff[10], + itemBuff[13], itemBuff[12], itemBuff[15], itemBuff[14], + itemBuff[17], itemBuff[16], itemBuff[19], itemBuff[18], + itemBuff[21], itemBuff[20] + ); + + if (rc < 0) + pm_error("Error writing X10 bitmap raster item. " + "printf() failed with errno %d (%s)", + errno, strerror(errno)); + + itemCnt = 0; } + itemBuff[itemCnt++] = bitreverse[item]; +} + -#define PUTBIT(b) \ - { \ - if ( bitsperitem == 8 ) \ - PUTITEM; \ - if ( (b) == PBM_BLACK ) \ - item += 1 << bitsperitem; \ - ++bitsperitem; \ + +static void +putitemX11(unsigned char const item) { + + if (itemCnt == 15 ) { + /* Buffer is full. Write out one line. */ + int rc; + rc = printf(" 0x%02x,0x%02x,0x%02x,0x%02x," + "0x%02x,0x%02x,0x%02x,0x%02x," + "0x%02x,0x%02x,0x%02x,0x%02x," + "0x%02x,0x%02x,0x%02x,\n", + itemBuff[0], itemBuff[1], itemBuff[2], itemBuff[3], + itemBuff[4], itemBuff[5], itemBuff[6], itemBuff[7], + itemBuff[8], itemBuff[9], itemBuff[10],itemBuff[11], + itemBuff[12],itemBuff[13],itemBuff[14] + ); + if (rc < 0) + pm_error("Error writing X11 bitmap raster item. " + "printf() failed with errno %d (%s)", + errno, strerror(errno)); + + itemCnt = 0; } + itemBuff[itemCnt++] = bitreverse[item]; +} - for (row = 0; row < rows; ++row) { - int col; - pbm_readpbmrow(ifp, bitrow, cols, format); - for (col = 0; col < cols; ++col) - PUTBIT(bitrow[col]); - for (col = 0; col < padright; ++col) - PUTBIT(0); + + +static void +putitem(unsigned char const item) { + + switch (itemVersion) { + case X10: putitemX10(item); break; + case X11: putitemX11(item); break; + } +} + + + +static void +puttermX10(void) { + + unsigned int i; + + for (i = 0; i < itemCnt; i += 2) { + int rc; + + rc = printf("%s0x%02x%02x%s", + (i == 0) ? " " : "", + itemBuff[i+1], + itemBuff[i], + (i == itemCnt - 2) ? "};\n" : ","); + if (rc < 0) + pm_error("Error writing end of X10 bitmap raster. " + "printf() failed with errno %d (%s)", + errno, strerror(errno)); + } +} + + + +static void +puttermX11(void) { + + unsigned int i; + + for (i = 0; i < itemCnt; ++i) { + int rc; + + rc = printf("%s0x%02x%s", + (i == 0) ? " " : "", + itemBuff[i], + (i == itemCnt - 1) ? "};\n" : ","); + + if (rc < 0) + pm_error("Error writing end of X11 bitmap raster. " + "printf() failed with errno %d (%s)", + errno, strerror(errno)); } +} + + + +static void +putinit(enum xbmVersion const xbmVersion) { + + itemCnt = 0; + itemVersion = xbmVersion; +} + - pm_close(ifp); - if (bitsperitem > 0) - PUTITEM; - printf("};\n"); +static void +putterm(void) { + + switch (itemVersion) { + case X10: puttermX10(); break; + case X11: puttermX11(); break; + } +} + + + +static void +writeXbmHeader(enum xbmVersion const xbmVersion, + const char * const name, + unsigned int const width, + unsigned int const height, + FILE * const ofP) { + + printf("#define %s_width %d\n", name, width); + printf("#define %s_height %d\n", name, height); + printf("static %s %s_bits[] = {\n", + xbmVersion == X10 ? "short" : "char", + name); +} + + + +static void +convertRaster(FILE * const ifP, + unsigned int const cols, + unsigned int const rows, + int const format, + FILE * const ofP, + enum xbmVersion const xbmVersion) { + + unsigned int const bitsPerUnit = xbmVersion == X10 ? 16 : 8; + unsigned int const padright = + ((cols + bitsPerUnit - 1 ) / bitsPerUnit) * bitsPerUnit - cols; + /* Amount of padding to round cols up to the nearest multiple of + 8 (if x11) or 16 (if x10). + */ + unsigned int const bitrowBytes = (cols + padright) / 8; + + unsigned char * bitrow; + unsigned int row; + + putinit(xbmVersion); + + bitrow = pbm_allocrow_packed(cols + padright); + bitrow[bitrowBytes-1] = 0; + + for (row = 0; row < rows; ++row) { + int const bitrowInBytes = pbm_packed_bytes(cols); + int const padrightIn = bitrowInBytes * 8 - cols; + + unsigned int i; + + pbm_readpbmrow_packed(ifP, bitrow, cols, format); + + if (padrightIn > 0) { + bitrow[bitrowInBytes - 1] >>= padrightIn; + bitrow[bitrowInBytes - 1] <<= padrightIn; + } + + for (i = 0; i < bitrowBytes; ++i) + putitem(bitrow[i]); + } + + putterm(); pbm_freerow(bitrow); +} + + + +int +main(int argc, + char * argv[]) { + + struct cmdlineInfo cmdline; + FILE * ifP; + int rows, cols, format; + const char * name; + + pbm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + if (cmdline.name == NULL) + generateName(cmdline.inputFileName, &name); + else + name = strdup(cmdline.name); + + ifP = pm_openr(cmdline.inputFileName); + + pbm_readpbminit(ifP, &cols, &rows, &format); + + writeXbmHeader(cmdline.xbmVersion, name, cols, rows, stdout); + + convertRaster(ifP, cols, rows, format, stdout, cmdline.xbmVersion); strfree(name); + pm_close(ifP); - exit(0); + return 0; } + diff --git a/converter/pbm/pbmtoybm.c b/converter/pbm/pbmtoybm.c index 1d2be3d9..508e8e92 100644 --- a/converter/pbm/pbmtoybm.c +++ b/converter/pbm/pbmtoybm.c @@ -80,14 +80,8 @@ putinit( cols, rows ) bitshift = 0; } -#if __STDC__ static void putbit( bit b ) -#else /*__STDC__*/ -static void -putbit( b ) - bit b; -#endif /*__STDC__*/ { if ( bitsperitem == 16 ) putitem( ); diff --git a/converter/pbm/xbmtopbm.c b/converter/pbm/xbmtopbm.c index 7779a9b5..63be16ef 100644 --- a/converter/pbm/xbmtopbm.c +++ b/converter/pbm/xbmtopbm.c @@ -1,4 +1,4 @@ -/* xbmtopbm.c - read an X bitmap file and produce a portable bitmap +/* xbmtopbm.c - read an X bitmap file and produce a PBM image ** ** Copyright (C) 1988 by Jef Poskanzer. ** @@ -10,246 +10,381 @@ ** implied warranty. */ + +#include <assert.h> #include <string.h> +#include "pm_c_util.h" +#include "mallocvar.h" #include "nstring.h" #include "pbm.h" +#include "bitreverse.h" -#define TRUE 1 -#define FALSE 0 -static void ReadBitmapFile ARGS(( FILE* stream, int* widthP, int* heightP, char** dataP )); -int -main( argc, argv ) - int argc; - char* argv[]; - { - FILE* ifp; - bit* bitrow; - register bit* bP; - int rows, cols, row, col, charcount; - char* data; - char mask; - - pbm_init( &argc, argv ); - - if ( argc > 2 ) - pm_usage( "[bitmapfile]" ); - - if ( argc == 2 ) - ifp = pm_openr( argv[1] ); - else - ifp = stdin; - - ReadBitmapFile( ifp, &cols, &rows, &data ); - - pm_close( ifp ); - - pbm_writepbminit( stdout, cols, rows, 0 ); - bitrow = pbm_allocrow( cols ); - - for ( row = 0; row < rows; ++row ) - { - charcount = 0; - mask = 1; - for ( col = 0, bP = bitrow; col < cols; ++col, ++bP ) - { - if ( charcount >= 8 ) - { - ++data; - charcount = 0; - mask = 1; - } - *bP = ( *data & mask ) ? PBM_BLACK : PBM_WHITE; - ++charcount; - mask = mask << 1; - } - ++data; - pbm_writepbmrow( stdout, bitrow, cols, 0 ); - } +#define MAX_LINE 500 + +static unsigned int hexTable[256]; + /* Hexadecimal ASCII translation table. Constant */ + +static void +initHexTable(void) { + + unsigned int i; + + for (i = 0; i < 256; ++i) + hexTable[i] = 256; + + hexTable['0'] = 0; + hexTable['1'] = 1; + hexTable['2'] = 2; + hexTable['3'] = 3; + hexTable['4'] = 4; + hexTable['5'] = 5; + hexTable['6'] = 6; + hexTable['7'] = 7; + hexTable['8'] = 8; + hexTable['9'] = 9; + hexTable['A'] = 10; + hexTable['B'] = 11; + hexTable['C'] = 12; + hexTable['D'] = 13; + hexTable['E'] = 14; + hexTable['F'] = 15; + hexTable['a'] = 10; + hexTable['b'] = 11; + hexTable['c'] = 12; + hexTable['d'] = 13; + hexTable['e'] = 14; + hexTable['f'] = 15; +} - pm_close( stdout ); - exit( 0 ); - } -#define MAX_LINE 500 static void -ReadBitmapFile( stream, widthP, heightP, dataP ) - FILE* stream; - int* widthP; - int* heightP; - char** dataP; -{ - char line[MAX_LINE], name_and_type[MAX_LINE]; - char* ptr; - char* t; - int version10, raster_length, v; - register int bytes, bytes_per_line, padding; - register int c1, c2, value1, value2; - int hex_table[256]; - int found_declaration; - /* In scanning through the bitmap file, we have found the first - line of the C declaration of the array (the "static char ..." - or whatever line) - */ - int eof; - /* We've encountered end of file while searching file */ - - *widthP = *heightP = -1; - - found_declaration = FALSE; /* Haven't found it yet; haven't even looked*/ - eof = FALSE; /* Haven't encountered end of file yet */ - - while (!found_declaration && !eof) { - if ( fgets( line, MAX_LINE, stream ) == NULL ) - eof = TRUE; - else { - if ( strlen( line ) == MAX_LINE - 1 ) - pm_error( "line too long" ); - - if ( sscanf( line, "#define %s %d", name_and_type, &v ) == 2 ) { - if ( ( t = strrchr( name_and_type, '_' ) ) == NULL ) - t = name_and_type; +parseWidthHeightLine(const char * const line, + bool * const gotWidthP, + unsigned int * const widthP, + bool * const gotHeightP, + unsigned int * const heightP) { + + int rc; + char nameAndType[MAX_LINE]; + unsigned int value; + + rc = sscanf(line, "#define %s %u", nameAndType, &value); + if (rc == 2) { + const char * underscorePos = strrchr(nameAndType, '_'); + const char * type; + if (underscorePos) + type = underscorePos + 1; else - ++t; - if ( STREQ( "width", t ) ) - *widthP = v; - else if ( STREQ( "height", t ) ) - *heightP = v; - continue; - } + type = nameAndType; + if (STREQ(type, "width")) { + *gotWidthP = TRUE; + *widthP = value; + } else if (STREQ(type, "height")) { + *gotHeightP = TRUE; + *heightP = value; + } + } +} + + + +static void +parseDeclaration(const char * const line, + bool * const isDeclarationP, + bool * const version10P) { +/*---------------------------------------------------------------------------- + Parse the XBM file line 'line' as the first line of the data structure + declaration, i.e. the one that looks like this: + + static unsigned char myImage = { + + Return as *isDeclarationP whether the line actually is such a line, + and if so, return as nameAndType what the variable name ('myImage' + in the example) is and as *version10P whether it's of the type used + by X10 as opposed to X11. +-----------------------------------------------------------------------------*/ + char nameAndType[MAX_LINE]; + int rc; - if ( sscanf( line, "static short %s = {", name_and_type ) == 1 ) { - version10 = TRUE; - found_declaration = TRUE; - } - else if ( sscanf( line, "static char %s = {", name_and_type ) == 1 ) { - version10 = FALSE; - found_declaration = TRUE; - } - else if (sscanf(line, - "static unsigned char %s = {", name_and_type ) == 1 ) { - version10 = FALSE; - found_declaration = TRUE; - } + rc = sscanf(line, "static short %s = {", nameAndType); + if (rc == 1) { + *version10P = TRUE; + *isDeclarationP = TRUE; + } else { + int rc; + rc = sscanf(line, "static char %s = {", nameAndType); + if (rc == 1) { + *version10P = FALSE; + *isDeclarationP = TRUE; + } else { + int rc; + rc = sscanf(line, "static unsigned char %s = {", nameAndType); + if (rc == 1) { + *version10P = FALSE; + *isDeclarationP = TRUE; + } else + *isDeclarationP = FALSE; + } } - } - - if (!found_declaration) - pm_error("Unable to find a line in the file containing the start " - "of C array declaration (\"static char\" or whatever)"); - - if ( *widthP == -1 ) - pm_error( "invalid width" ); - if ( *heightP == -1 ) - pm_error( "invalid height" ); - - padding = 0; - if ( ((*widthP % 16) >= 1) && ((*widthP % 16) <= 8) && version10 ) - padding = 1; - - bytes_per_line = (*widthP+7)/8 + padding; +} + + + +static void +getXbmHeader(FILE * const ifP, + unsigned int * const widthP, + unsigned int * const heightP, + bool * const version10P) { + + bool foundDeclaration; + /* In scanning through the bitmap file, we have found the first + line of the C declaration of the array (the "static char ..." + or whatever line) + */ + bool gotWidth, gotHeight; + /* We found the line in the bitmap file that gives the width + or height, respectively, of the image (and have set + *widthP or *heightP to the value in it). + */ + + bool eof; + /* We've encountered end of file while searching file */ + + gotWidth = FALSE; + gotHeight = FALSE; + foundDeclaration = FALSE; /* Haven't found it yet; haven't even looked*/ + eof = FALSE; /* Haven't encountered end of file yet */ + + while (!foundDeclaration && !eof) { + char * rc; + char line[MAX_LINE]; + + rc = fgets(line, MAX_LINE, ifP); + if (rc == NULL) + eof = TRUE; + else { + if (strlen(line) == MAX_LINE - 1) + pm_error("A line in the input file is %u characters long. " + "%u is the maximum we can handle", + strlen(line), MAX_LINE-1); + + parseWidthHeightLine(line, &gotWidth, widthP, &gotHeight, heightP); + + parseDeclaration(line, &foundDeclaration, version10P); + } + } + + if (!foundDeclaration) + pm_error("Unable to find a line in the file containing the start " + "of C array declaration (\"static char\" or whatever)"); + + if (!gotWidth) + pm_error("Unable to find the #define statement that gives the " + "width of the image, before the data structure " + "declaration."); + if (!gotHeight) + pm_error("Unable to find the #define statement that gives the " + "height of the image, before the data structure " + "declaration."); +} + + + +static void +getHexByte(FILE * const ifP, + unsigned int * const valueP) { + + int c1, c2; + unsigned int value; + + c1 = getc(ifP); + c2 = getc(ifP); + if (c1 == EOF || c2 == EOF) + pm_error("EOF / read error"); + + assert(c1 >= 0); assert(c1 < 256); + assert(c2 >= 0); assert(c2 < 256); - raster_length = bytes_per_line * *heightP; - *dataP = (char*) malloc( raster_length ); - if ( *dataP == (char*) 0 ) - pm_error( "out of memory" ); - - /* Initialize hex_table. */ - for ( c1 = 0; c1 < 256; ++c1 ) - hex_table[c1] = 256; - hex_table['0'] = 0; - hex_table['1'] = 1; - hex_table['2'] = 2; - hex_table['3'] = 3; - hex_table['4'] = 4; - hex_table['5'] = 5; - hex_table['6'] = 6; - hex_table['7'] = 7; - hex_table['8'] = 8; - hex_table['9'] = 9; - hex_table['A'] = 10; - hex_table['B'] = 11; - hex_table['C'] = 12; - hex_table['D'] = 13; - hex_table['E'] = 14; - hex_table['F'] = 15; - hex_table['a'] = 10; - hex_table['b'] = 11; - hex_table['c'] = 12; - hex_table['d'] = 13; - hex_table['e'] = 14; - hex_table['f'] = 15; - - if ( version10 ) - for ( bytes = 0, ptr = *dataP; bytes < raster_length; bytes += 2 ) { - while ( ( c1 = getc( stream ) ) != 'x' ) - if ( c1 == EOF ) - pm_error( "EOF / read error" ); - c1 = getc( stream ); - c2 = getc( stream ); - if ( c1 == EOF || c2 == EOF ) - pm_error( "EOF / read error" ); - value1 = ( hex_table[c1] << 4 ) + hex_table[c2]; - if ( value1 >= 256 ) - pm_error( "syntax error" ); - c1 = getc( stream ); - c2 = getc( stream ); - if ( c1 == EOF || c2 == EOF ) - pm_error( "EOF / read error" ); - value2 = ( hex_table[c1] << 4 ) + hex_table[c2]; - if ( value2 >= 256 ) - pm_error( "syntax error" ); - *ptr++ = value2; - if ( ( ! padding ) || ( ( bytes + 2 ) % bytes_per_line ) ) - *ptr++ = value1; + value = (hexTable[c1] << 4) + hexTable[c2]; + if (value >= 256) + pm_error("Invalid XBM input. What should be a two digit " + "hexadecimal cipher is instead '%c%c'", c1, c2); + + *valueP = value; +} + + + +static void +readX10Raster(FILE * const ifP, + unsigned int const rasterLength, + unsigned char * const data, + unsigned int const bytesPerLine, + bool const mustPad) { + + unsigned int bytesDone; + unsigned char * p; + + for (bytesDone = 0, p = &data[0]; + bytesDone < rasterLength; + bytesDone += 2) { + + unsigned int value1; + unsigned int value2; + + while (getc(ifP) != 'x') {} /* Read up through the 'x' in 0x1234 */ + + getHexByte(ifP, &value1); /* Read first two hex digits */ + getHexByte(ifP, &value2); /* Read last two hex digits */ + + *p++ = value2; + + if (!mustPad || ((bytesDone + 2) % bytesPerLine)) + *p++ = value1; } - else - for ( bytes = 0, ptr = *dataP; bytes < raster_length; ++bytes ) { - /* - ** Skip until digit is found. - */ - for ( ; ; ) - { - c1 = getc( stream ); - if ( c1 == EOF ) - pm_error( "EOF / read error" ); - value1 = hex_table[c1]; - if ( value1 != 256 ) - break; - } - /* - ** Loop on digits. - */ - for ( ; ; ) { - c2 = getc( stream ); - if ( c2 == EOF ) - pm_error( "EOF / read error" ); - value2 = hex_table[c2]; - if ( value2 != 256 ) { - value1 = (value1 << 4) | value2; - if ( value1 >= 256 ) - pm_error( "syntax error" ); +} + + + +static void +readX11Raster(FILE * const ifP, + unsigned int const rasterLength, + unsigned char * data) { + + unsigned int i; + + for (i = 0; i < rasterLength; ++i) { + unsigned int value; + int c; + + /* Read up through the 'x' in 0x12 */ + while ((c = getc(ifP))) { + if (c == EOF) + pm_error("EOF where 0x expected"); + else if (toupper(c) == 'X') + break; } - else if ( c2 == 'x' || c2 == 'X' ) - if ( value1 == 0 ) - continue; - else pm_error( "syntax error" ); - else break; - } - *ptr++ = value1; + + getHexByte(ifP, &value); /* Read the two hex digits */ + + assert(value < 256); + + data[i] = value; } } -/* CHANGE HISTORY: - 99.09.08 bryanh Recognize "static unsigned char" declaration. +static void +readBitmapFile(FILE * const ifP, + unsigned int * const widthP, + unsigned int * const heightP, + unsigned char ** const dataP) { + + bool version10; + unsigned int rasterLength; + unsigned int width, height; + unsigned char * data; + unsigned int bytesPerLine; + bool mustPad; + getXbmHeader(ifP, &width, &height, &version10); + *widthP = width; + *heightP = height; + mustPad = (width % 16 >= 1 && width % 16 <= 8 && version10); + + bytesPerLine = (width + 7) / 8 + (mustPad ? 1 : 0); + + rasterLength = bytesPerLine * height; + + MALLOCARRAY(data, rasterLength); + if (data == NULL) + pm_error("Unable to allocate memory for the %u-byte raster", + rasterLength); + + if (version10) + readX10Raster(ifP, rasterLength, data, bytesPerLine, mustPad); + else + readX11Raster(ifP, rasterLength, data); + + *dataP = data; +} + + + +int +main(int argc, + char * argv[]) { + + FILE * ifP; + bit * bitrow; + unsigned int rows, cols; + unsigned int row; + unsigned char * data; + const char * inputFileName; + unsigned char * p; + /* Cursor in raster data data[] */ + + initHexTable(); + + pbm_init(&argc, argv); + + if (argc-1 > 1) + pm_error("The only possible argument is the input file name. " + "You specified %u arguments", argc-1); + + if (argc-1 > 0) + inputFileName = argv[1]; + else + inputFileName = "-"; + + ifP = pm_openr(inputFileName); + + readBitmapFile(ifP, &cols, &rows, &data); + + pm_close(ifP); + + pbm_writepbminit(stdout, cols, rows, 0); + bitrow = pbm_allocrow_packed(cols); + + p = &data[0]; /* Start at beginning of raster */ + + for (row = 0; row < rows; ++row) { + unsigned int const bytesPerRow = pbm_packed_bytes(cols); + unsigned int i; + + for (i = 0; i < bytesPerRow; ++i) + bitrow[i] = bitreverse[*p++]; + + if (cols % 8 > 0) { + bitrow[bytesPerRow] >>= 8 - cols % 8; + bitrow[bytesPerRow] <<= 8 - cols % 8; + } + + pbm_writepbmrow_packed(stdout, bitrow, cols, 0); + } + + free(data); + pm_close(stdout); + + return 0; +} + +/* CHANGE HISTORY: + + 99.09.08 bryanh Recognize "static unsigned char" declaration. + + 06.10 (afu) + Changed bitrow from plain to raw, write function from pbm_writepbmrow() + to pbm_writepbmrow_packed(). + Retired bitwise transformation functions. */ + |