From 7df75acc09a40b86739fc8f7f0e0ea2e248cd400 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 26 Apr 2015 16:38:51 +0000 Subject: cleanup git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2469 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/pbm/macp.h | 8 +- converter/pbm/pbmtomacp.c | 457 +++++++++++++++++++++++++--------------------- 2 files changed, 249 insertions(+), 216 deletions(-) diff --git a/converter/pbm/macp.h b/converter/pbm/macp.h index bc1231cd..d00dc5c9 100644 --- a/converter/pbm/macp.h +++ b/converter/pbm/macp.h @@ -1,6 +1,8 @@ -/* macp.h - header file for MacPaint files -*/ - +/*============================================================================= + macp.h +=============================================================================== + Information about MacPaint files +=============================================================================*/ #ifndef MACP_H_INCLUDED #define MACP_H_INCLUDED diff --git a/converter/pbm/pbmtomacp.c b/converter/pbm/pbmtomacp.c index ebaf3acb..7ddb1ef5 100644 --- a/converter/pbm/pbmtomacp.c +++ b/converter/pbm/pbmtomacp.c @@ -45,11 +45,11 @@ #define MIN3(a,b,c) (MIN((MIN((a),(b))),(c))) -struct cmdlineInfo { - /* All the information the user supplied in the command line, - in a form easy for the program to use. +struct CmdlineInfo { + /* All the information the user supplied in the command line, in a form + easy for the program to use. */ - const char * inputFilespec; /* Filespec of input file */ + const char * inputFileName; /* File name of input file */ unsigned int left; unsigned int right; unsigned int top; @@ -58,15 +58,15 @@ struct cmdlineInfo { unsigned int rightSpec; unsigned int topSpec; unsigned int bottomSpec; - bool norle; /* If true do not pack data */ + bool norle; }; static void parseCommandLine(int argc, - char ** const argv, - struct cmdlineInfo * const cmdlineP) { + const char ** const argv, + struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Parse program command line described in Unix standard form by argc and argv. Return the information in the options as *cmdlineP. @@ -97,20 +97,21 @@ parseCommandLine(int argc, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ - free(option_def); - cmdlineP->norle = norleSpec; - if (argc-1 == 0) - cmdlineP->inputFilespec = "-"; - else if (argc-1 != 1) - pm_error("Program takes zero or one argument (filename). You " - "specified %d", argc-1); - else - cmdlineP->inputFilespec = argv[1]; + 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 %d", argc-1); + } + + free(option_def); } @@ -128,196 +129,205 @@ struct CropPadDimensions { static void -calculateCropPad(struct cmdlineInfo const cmdline, - struct CropPadDimensions * cropPad, - int const cols, - int const rows ) { +calculateCropPad(struct CmdlineInfo const cmdline, + unsigned int const cols, + unsigned int const rows, + struct CropPadDimensions * const cropPadP) { /*-------------------------------------------------------------------------- -Validate -left -right -top -bottom from command line. Determine -what rows, columns to take from input if any of these are specified. + Validate -left -right -top -bottom from command line. -Center image if it is smaller than the fixed Macpaint format size. + Determine what rows, columns to take from input if any of these are + specified and return it as *cropPadP. + + 'cols and 'rows' are the dimensions of the input image. + + Center image if it is smaller than the fixed Macpaint format size. ----------------------------------------------------------------------------*/ - int right, bottom, width, height; - int const left = cmdline.leftSpec ? cmdline.left : 0; - int const top = cmdline.topSpec ? cmdline.top : 0; + unsigned int const left = cmdline.leftSpec ? cmdline.left : 0; + unsigned int const top = cmdline.topSpec ? cmdline.top : 0; - if( cmdline.leftSpec ) { - if(cmdline.rightSpec && left >= cmdline.right ) + unsigned int right, bottom, width, height; + + if (cmdline.leftSpec) { + if (cmdline.rightSpec && left >= cmdline.right) pm_error("-left value must be smaller than -right value"); - else if( left > cols -1 ) + else if (left + 1 > cols) pm_error("Specified -left value is beyond right edge " "of input image"); } - if( cmdline.topSpec ) { - if(cmdline.bottomSpec && top >= cmdline.bottom ) + if (cmdline.topSpec) { + if (cmdline.bottomSpec && top >= cmdline.bottom) pm_error("-top value must be smaller than -bottom value"); - else if( top > rows -1 ) + else if (top + 1 > rows) pm_error("Specified -top value is beyond bottom edge " "of input image"); } - - if( cmdline.rightSpec ) { - if( cmdline.right > cols -1 ) - pm_message("Specified -right value %d is beyond edge of " + if (cmdline.rightSpec) { + if (cmdline.right + 1 > cols) + pm_message("Specified -right value %u is beyond edge of " "input image", cmdline.right); - right = MIN3( cmdline.right, cols - 1, left + MACP_COLS - 1 ); - } - else - right = MIN( cols - 1, left + MACP_COLS - 1 ); + right = MIN3(cmdline.right, cols - 1, left + MACP_COLS - 1); + } else + right = MIN(cols - 1, left + MACP_COLS - 1); - if( cmdline.bottomSpec ) { - if( cmdline.bottom > rows -1 ) - pm_message("Specified -bottom value %d is beyond edge of " - "input image", cmdline.bottom); + if (cmdline.bottomSpec) { + if (cmdline.bottom + 1 > rows) + pm_message("Specified -bottom value %u is beyond edge of " + "input image", cmdline.bottom); - bottom = MIN3( cmdline.bottom, rows - 1, top + MACP_ROWS - 1); - } - else - bottom = MIN( rows - 1, top + MACP_ROWS - 1 ); + bottom = MIN3(cmdline.bottom, rows - 1, top + MACP_ROWS - 1); + } else + bottom = MIN(rows - 1, top + MACP_ROWS - 1); - cropPad->leftCrop = left; - cropPad->topCrop = top; + cropPadP->leftCrop = left; + cropPadP->topCrop = top; - width = right - left + 1; - cropPad->leftMargin = ( MACP_COLS - width ) / 2; + assert(right >= left); + width = right - left + 1; assert(width > 0 && width <= MACP_COLS); - if(width < cols) - pm_message("%d of %d input columns will be output", width, cols); - height = bottom - top + 1; - cropPad->topMargin = ( MACP_ROWS - height ) / 2; - cropPad->bottomMargin = cropPad->topMargin + height - 1; + cropPadP->leftMargin = (MACP_COLS - width) / 2; + + if (width < cols) + pm_message("%u of %u input columns will be output", width, cols); + height = bottom - top + 1; assert(height > 0 && height <= MACP_ROWS); - if(height < rows) - pm_message("%d out of %d input rows will be output", height, rows); - cropPad->imageWidth = width; - cropPad->imageHeight = height; + cropPadP->topMargin = (MACP_ROWS - height) / 2; + cropPadP->bottomMargin = cropPadP->topMargin + height - 1; + + if (height < rows) + pm_message("%u out of %u input rows will be output", height, rows); + cropPadP->imageWidth = width; + cropPadP->imageHeight = height; } static void -writeMacpHeader( ) { +writeMacpHeader(FILE * const ofP) { - int i; char const ch = 0x00; /* header contains nothing */ - for(i = 0; i < MACP_HEAD_LEN; i++ ) - fputc( ch, stdout ); + unsigned int i; + + for (i = 0; i < MACP_HEAD_LEN; ++i) + fputc(ch, ofP); } static void -writeMacpRowUnpacked( unsigned int const leftMarginChars, - const bit * const imageBits, - unsigned int const imageColChars) { +writeMacpRowUnpacked(const bit * const imageBits, + unsigned int const leftMarginCharCt, + unsigned int const imageColCharCt, + FILE * const ofP) { /*-------------------------------------------------------------------------- -Encode (without compression) and output one row. -The row comes divided into three parts: left margin, image, right margin. + Encode (without compression) and output one row. The row comes divided into + three parts: left margin, image, right margin. ----------------------------------------------------------------------------*/ - int i; char const marginByte = 0x00; /* White bits for margin */ - unsigned int const rightMarginChars = - MACP_COLCHARS - leftMarginChars - imageColChars; + unsigned int const rightMarginCharCt = + MACP_COLCHARS - leftMarginCharCt - imageColCharCt; + + unsigned int i; - fputc( MACP_COLCHARS - 1, stdout ); + fputc(MACP_COLCHARS - 1, ofP); - for(i = 0; i < leftMarginChars; ++i) - fputc( marginByte, stdout ); + for (i = 0; i < leftMarginCharCt; ++i) + fputc(marginByte, ofP); - if(imageColChars > 0) - fwrite(imageBits, 1, imageColChars, stdout); + if (imageColCharCt > 0) + fwrite(imageBits, 1, imageColCharCt, ofP); - for(i = 0; i < rightMarginChars; ++i) - fputc( marginByte, stdout ); + for (i = 0; i < rightMarginCharCt; ++i) + fputc(marginByte, ofP); } static void -writeMacpRowPacked( unsigned int const leftMarginChars, - const bit * const packedBits, - unsigned int const imageColChars, - unsigned int const rightMarginChars) { +writeMacpRowPacked(const bit * const packedBits, + unsigned int const leftMarginCharCt, + unsigned int const imageColCharCt, + unsigned int const rightMarginCharCt, + FILE * const ofP) { /*-------------------------------------------------------------------------- -Encode and output one row. -As in the unpacked case, the row comes divided into three parts: -left margin, image, right margin. Unlike the unpacked case we need to -know both the size of the packed data and the size of the right margin. + Encode one row and write it to *ofP. + + As in the unpacked case, the row comes divided into three parts: left + margin, image, right margin. Unlike the unpacked case we need to know both + the size of the packed data and the size of the right margin. ----------------------------------------------------------------------------*/ char const marginByte = 0x00; /* White bits for margin */ - if( leftMarginChars > 0 ) { - fputc( 257 - leftMarginChars, stdout ); - fputc( marginByte, stdout ); + if (leftMarginCharCt > 0) { + fputc(257 - leftMarginCharCt, ofP); + fputc(marginByte, ofP); } - if( imageColChars > 0) - fwrite( packedBits, 1, imageColChars, stdout); + if (imageColCharCt > 0) + fwrite(packedBits, 1, imageColCharCt, ofP); - if( rightMarginChars > 0 ) { - fputc( 257 - rightMarginChars, stdout ); - fputc( marginByte, stdout ); + if (rightMarginCharCt > 0) { + fputc(257 - rightMarginCharCt, ofP); + fputc(marginByte, ofP); } } static void -packit (const bit * const sourceBits, - unsigned int const imageColChars, - unsigned char * const packedBits, - unsigned int * const packedImageLengthP ) { +packit(const bit * const sourceBits, + unsigned int const imageColCharCt, + unsigned char * const packedBits, + unsigned int * const packedImageLengthP ) { /*-------------------------------------------------------------------------- -Compress according to packbits algorithm, a byte-level run-length -encoding scheme. + Compress according to packbits algorithm, a byte-level run-length encoding + scheme. -Each row is encoded separately. + Each row is encoded separately. -The following code does not produce optimum output when there are 2-byte -long sequences between longer ones: the 2-byte run in between does not -get packed, using up 3 bytes where 2 would do. + The following code does not produce optimum output when there are 2-byte + long sequences between longer ones: the 2-byte run in between does not get + packed, using up 3 bytes where 2 would do. ----------------------------------------------------------------------------*/ -#define EQUAL 1 -#define UNEQUAL 0 - - int charcount, newcount, packcount; - bool status; + int charcount, packcount; + enum {EQUAL, UNEQUAL} status; bit * count; - bit save; - packcount = charcount = 0; /* Initial values */ - status = EQUAL; - while( charcount < imageColChars ) { - save = sourceBits[charcount++]; + for (packcount = 0, charcount = 0, status = EQUAL; + charcount < imageColCharCt; + ) { + bit const save = sourceBits[charcount++]; + + int newcount; + newcount = 1; - while( charcount < imageColChars && sourceBits[charcount] == save ) { - charcount++; - newcount++; + while (charcount < imageColCharCt && sourceBits[charcount] == save) { + ++charcount; + ++newcount; } - if( newcount > 2 ) { - count = (unsigned char *) &packedBits[packcount++]; - *count = 257 - newcount; - packedBits[packcount++] = save; - status = EQUAL; + if (newcount > 2) { + count = (unsigned char *) &packedBits[packcount++]; + *count = 257 - newcount; + packedBits[packcount++] = save; + status = EQUAL; } else { - if( status == EQUAL ) { - count = (unsigned char *) &packedBits[packcount++]; - *count = newcount - 1; + if (status == EQUAL) { + count = (unsigned char *) &packedBits[packcount++]; + *count = newcount - 1; } else - *count += newcount; + *count += newcount; - for( ; newcount > 0; newcount-- ) { - packedBits[packcount++] = save; - } - status = UNEQUAL; + for( ; newcount > 0; --newcount) { + packedBits[packcount++] = save; + } + status = UNEQUAL; } } *packedImageLengthP = packcount; @@ -326,141 +336,162 @@ get packed, using up 3 bytes where 2 would do. static void -writeMacpRow( unsigned int const leftMarginChars, - bit * const imageBits, - unsigned int const imageColChars, - bool const norle) { +writeMacpRow(bit * const imageBits, + unsigned int const leftMarginCharCt, + unsigned int const imageColCharCt, + bool const norle, + FILE * const ofP) { /*-------------------------------------------------------------------------- -Determine whether a row should be packed (compressed) or not. + Write the row 'imageBits' to Standard Output. -If packing leads to unnecessary bloat, discard the packed data and write -in unpacked mode. + Write it packed, unless packing would lead to unnecessary bloat or 'norle' + is true. ----------------------------------------------------------------------------*/ - if (norle) - writeMacpRowUnpacked( leftMarginChars, imageBits, imageColChars ); - - else { - unsigned int packedImageLength; - unsigned int const rightMarginChars = - MACP_COLCHARS - leftMarginChars - imageColChars; - unsigned char * const packedBits = malloc(MACP_COLCHARS+1); - if(packedBits == NULL) - pm_error("Out of memory"); - - packit( imageBits, imageColChars, packedBits, &packedImageLength ); - /* Check if we are we better off with compression. - If not, send row unpacked. See note at top of file. - */ - if ( packedImageLength + (!!(leftMarginChars > 0)) *2 + - (!!(rightMarginChars > 0)) *2 < MACP_COLCHARS ) - writeMacpRowPacked( leftMarginChars, packedBits, - packedImageLength, rightMarginChars); - else /* Extremely rare */ - writeMacpRowUnpacked( leftMarginChars, imageBits, imageColChars ); - - free( packedBits ); - } + if (norle) + writeMacpRowUnpacked(imageBits, leftMarginCharCt, imageColCharCt, ofP); + else { + unsigned int const rightMarginCharCt = + MACP_COLCHARS - leftMarginCharCt - imageColCharCt; + unsigned char * const packedBits = malloc(MACP_COLCHARS+1); + + unsigned int packedImageLength; + + if (packedBits == NULL) + pm_error("Failed to get memory for a %u-column row buffer", + MACP_COLCHARS); + + packit(imageBits, imageColCharCt, packedBits, &packedImageLength); + + /* Check if we are we better off with compression. If not, send row + unpacked. See note at top of file. + */ + + if (packedImageLength + + (leftMarginCharCt > 0 ? 1 : 0) * 2 + + (rightMarginCharCt > 0 ? 1 : 0) * 2 + < MACP_COLCHARS) + writeMacpRowPacked(packedBits, leftMarginCharCt, + packedImageLength, rightMarginCharCt, ofP); + else /* Extremely rare */ + writeMacpRowUnpacked(imageBits, leftMarginCharCt, imageColCharCt, + ofP); + + free(packedBits); + } } static void -encodeRowsWithShift(bit * const bitrow, - FILE * const ifP, - int const inCols, - unsigned int const format, - bool const norle, - struct CropPadDimensions const cropPad ) { +encodeRowsWithShift(bit * const bitrow, + FILE * const ifP, + int const inCols, + int const format, + bool const norle, + struct CropPadDimensions const cropPad, + FILE * const ofP) { /*-------------------------------------------------------------------------- -Shift input rows to put only specified columns to output. -Add padding on left and right if necessary. + Shift input rows to put only specified columns to output. Add padding on + left and right if necessary. -No shift if the input image is the exact size (576 columns) of the Macpaint -format. If the input image is too wide and -left was not specified, extra -content on the right is discarded. + No shift if the input image is the exact size (576 columns) of the Macpaint + format. If the input image is too wide and -left was not specified, extra + content on the right is discarded. ----------------------------------------------------------------------------*/ - unsigned int row; + unsigned int const offset = + (cropPad.leftMargin + 8 - cropPad.leftCrop % 8) % 8; + unsigned int const leftTrim = + cropPad.leftMargin % 8; + unsigned int const rightTrim = + (8 - (leftTrim + cropPad.imageWidth) % 8 ) % 8; + unsigned int const startChar = + (cropPad.leftCrop + offset) / 8; + unsigned int const imageCharCt = + pbm_packed_bytes(leftTrim + cropPad.imageWidth); + unsigned int const leftMarginCharCt = + cropPad.leftMargin / 8; - int const offset = (cropPad.leftMargin + 8 - cropPad.leftCrop % 8) % 8; - int const leftTrim = cropPad.leftMargin % 8; - int const rightTrim = ( 8 - (leftTrim + cropPad.imageWidth) % 8 ) % 8; - int const startChar = (cropPad.leftCrop + offset) / 8; - int const imageChars = pbm_packed_bytes(leftTrim + cropPad.imageWidth); - int const leftMarginChars = cropPad.leftMargin / 8; + unsigned int row; - for(row = 0; row < cropPad.imageHeight; ++row ) { + for (row = 0; row < cropPad.imageHeight; ++row) { pbm_readpbmrow_bitoffset(ifP, bitrow, inCols, format, offset); - + /* Trim off fractional margin portion in first byte of image data */ - if(leftTrim > 0) { + if (leftTrim > 0) { bitrow[startChar] <<= leftTrim; bitrow[startChar] >>= leftTrim; } /* Do the same with bits in last byte of relevant image data */ - if(rightTrim > 0) { - bitrow[startChar + imageChars -1] >>= rightTrim; - bitrow[startChar + imageChars -1] <<= rightTrim; - } + if (rightTrim > 0) { + bitrow[startChar + imageCharCt - 1] >>= rightTrim; + bitrow[startChar + imageCharCt - 1] <<= rightTrim; + } - writeMacpRow( leftMarginChars, - &bitrow[startChar], imageChars, norle); + writeMacpRow(&bitrow[startChar], leftMarginCharCt, + imageCharCt, norle, ofP); } } static void -writeMacp( int const cols, - int const rows, - unsigned int const format, - FILE * const ifP, - bool const norle, - struct CropPadDimensions const cropPad ) { +writeMacp(unsigned int const cols, + unsigned int const rows, + int const format, + FILE * const ifP, + bool const norle, + struct CropPadDimensions const cropPad, + FILE * const ofP) { unsigned int row, skipRow; bit * bitrow; - writeMacpHeader( ); + writeMacpHeader(ofP); - for( row = 0; row < cropPad.topMargin; ++row ) - writeMacpRow( MACP_COLCHARS, NULL, 0, norle); + /* Write top padding */ + for (row = 0; row < cropPad.topMargin; ++row) + writeMacpRow(NULL, MACP_COLCHARS, 0, norle, ofP); /* Allocate PBM row with one extra byte for the shift case. */ bitrow = pbm_allocrow_packed(cols + 8); - for(skipRow = 0; skipRow < cropPad.topCrop; ++skipRow ) - pbm_readpbmrow_packed(ifP, bitrow, cols, format); + for (skipRow = 0; skipRow < cropPad.topCrop; ++skipRow) + pbm_readpbmrow_packed(ifP, bitrow, cols, format); - encodeRowsWithShift(bitrow, ifP, cols, format, norle, cropPad); + encodeRowsWithShift(bitrow, ifP, cols, format, norle, cropPad, ofP); pbm_freerow_packed(bitrow); - for(row = cropPad.bottomMargin + 1 ; row < MACP_ROWS ; ++row ) - writeMacpRow( MACP_COLCHARS, NULL, 0, norle); + /* Add bottom padding */ + for (row = cropPad.bottomMargin + 1; row < MACP_ROWS; ++row) + writeMacpRow(NULL, MACP_COLCHARS, 0, norle, ofP); } int -main( int argc, char *argv[] ) { +main(int argc, const char *argv[]) { + FILE * ifP; int rows, cols; int format; - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; struct CropPadDimensions cropPad; - pbm_init( &argc, argv ); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); - ifP = pm_openr(cmdline.inputFilespec); + + ifP = pm_openr(cmdline.inputFileName); pbm_readpbminit(ifP, &cols, &rows, &format); - calculateCropPad(cmdline, &cropPad, cols, rows); + calculateCropPad(cmdline, cols, rows, &cropPad); + + writeMacp(cols, rows, format, ifP, cmdline.norle, cropPad, stdout); - writeMacp( cols, rows, format, ifP, cmdline.norle, cropPad ); + pm_close(ifP); - pm_close( ifP ); - exit( 0 ); + return 0; } -- cgit 1.4.1