diff options
Diffstat (limited to 'converter')
-rw-r--r-- | converter/other/pamtogif.c | 292 |
1 files changed, 157 insertions, 135 deletions
diff --git a/converter/other/pamtogif.c b/converter/other/pamtogif.c index 11e9bdcd..bc89607d 100644 --- a/converter/other/pamtogif.c +++ b/converter/other/pamtogif.c @@ -118,7 +118,7 @@ pamAlphaPlane(struct pam * const pamP) { static void -parseCommandLine(int argc, char ** argv, +parseCommandLine(int argc, const char ** argv, struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Parse the program arguments (given by argc and argv) into a form @@ -172,7 +172,7 @@ parseCommandLine(int argc, char ** argv, 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. */ if (argc-1 == 0) @@ -316,7 +316,7 @@ rowReader_destroy(RowReader * const rdrP) { static void -rowReaderSkipRows(RowReader * const rdrP, +rowReader_skipRows(RowReader * const rdrP, unsigned int const rowCount, bool * const eofP) { /*---------------------------------------------------------------------------- @@ -347,7 +347,7 @@ rowReaderSkipRows(RowReader * const rdrP, static void -rowReaderGotoNextInterlaceRow(RowReader * const rdrP) { +rowReader_gotoNextInterlaceRow(RowReader * const rdrP) { /*---------------------------------------------------------------------------- Position reader to the next row in the interlace pattern, assuming it is now positioned immediately after the current row. @@ -363,16 +363,16 @@ rowReaderGotoNextInterlaceRow(RowReader * const rdrP) { switch (rdrP->pass) { case MULT8PLUS0: - rowReaderSkipRows(rdrP, 7, &endOfPass); + rowReader_skipRows(rdrP, 7, &endOfPass); break; case MULT8PLUS4: - rowReaderSkipRows(rdrP, 7, &endOfPass); + rowReader_skipRows(rdrP, 7, &endOfPass); break; case MULT4PLUS2: - rowReaderSkipRows(rdrP, 3, &endOfPass); + rowReader_skipRows(rdrP, 3, &endOfPass); break; case MULT2PLUS1: - rowReaderSkipRows(rdrP, 1, &endOfPass); + rowReader_skipRows(rdrP, 1, &endOfPass); break; } @@ -387,15 +387,15 @@ rowReaderGotoNextInterlaceRow(RowReader * const rdrP) { switch (rdrP->pass) { case MULT8PLUS0: rdrP->pass = MULT8PLUS4; - rowReaderSkipRows(rdrP, 4, &endOfPass); + rowReader_skipRows(rdrP, 4, &endOfPass); break; case MULT8PLUS4: rdrP->pass = MULT4PLUS2; - rowReaderSkipRows(rdrP, 2, &endOfPass); + rowReader_skipRows(rdrP, 2, &endOfPass); break; case MULT4PLUS2: rdrP->pass = MULT2PLUS1; - rowReaderSkipRows(rdrP, 1, &endOfPass); + rowReader_skipRows(rdrP, 1, &endOfPass); break; case MULT2PLUS1: rdrP->eof = TRUE; @@ -407,7 +407,7 @@ rowReaderGotoNextInterlaceRow(RowReader * const rdrP) { static void -rowReaderGotoNextStraightRow(RowReader * const rdrP) { +rowReader_gotoNextStraightRow(RowReader * const rdrP) { /*---------------------------------------------------------------------------- Position reader to the next row in a straight, non-interlace pattern, assuming the file is now positioned immediately after the @@ -434,9 +434,9 @@ rowReader_read(RowReader * const rdrP, ++rdrP->nextRow; if (rdrP->interlace) - rowReaderGotoNextInterlaceRow(rdrP); + rowReader_gotoNextInterlaceRow(rdrP); else - rowReaderGotoNextStraightRow(rdrP); + rowReader_gotoNextStraightRow(rdrP); } @@ -1270,89 +1270,6 @@ writePixelUncompressed(LzwCompressor * const lzwP, static void -writeRaster(struct pam * const pamP, - RowReader * const rowReaderP, - unsigned int const alphaPlane, - unsigned int const alphaThreshold, - struct Cmap * const cmapP, - unsigned int const initBits, - FILE * const ofP, - bool const lzw, - bool const noclear) { -/*---------------------------------------------------------------------------- - Write the raster to file 'ofP'. - - Get the raster to write from 'rowReaderP', which gives tuples whose - format is described by 'pamP'. - - 'alphaPlane' is the number of the plane in the tuples supplied by - 'rowReaderP' that we should use for transparency information, and - 'alphaThreshold' is the value in that plane below which we should consider - the pixel transparent for GIF purposes. - - 'alphaPlane' is zero to indicate we should not use any plane as an alpha - plane (so it's not possible to specify Plane 0 as alpha). - - Use the colormap 'cmapP' to generate the raster ('rowReaderP' gives - pixel values as RGB samples; the GIF raster is colormap indices). - - Write the raster using LZW compression, or uncompressed depending - on 'lzw'. - - If 'noclear', don't use any GIF clear codes in the output; i.e. don't - recompute the string table from current input. Once the string table gets - to maximum size, just keep using that table for the rest of the image. ------------------------------------------------------------------------------*/ - LzwCompressor * lzwP; - tuple * tuplerow; - unsigned int nRowsDone; - /* Number of rows we have read so far from the the input (the - last of which is the one we're working on now). Note that - in case of interlace, this is not the same thing as the row - number of the current row. - */ - - lzwP = lzw_create(ofP, initBits, lzw, noclear, pamP->height * pamP->width); - - tuplerow = pnm_allocpamrow(pamP); - - lzw_clearBlock(lzwP); - - nRowsDone = 0; - - while (nRowsDone < pamP->height) { - unsigned int col; - - rowReader_read(rowReaderP, tuplerow); - - for (col = 0; col < pamP->width; ++col) { - unsigned int const colorIndex = - gifPixel(pamP, tuplerow[col], alphaPlane, alphaThreshold, - cmapP); - - /* The value for the pixel in the GIF image. I.e. the colormap - index. - */ - if (lzw) - lzw_encodePixel(lzwP, colorIndex); - else - writePixelUncompressed(lzwP, colorIndex); - } - ++nRowsDone; - } - /* Gif is no good with no pixels; fortunately, that's impossible: */ - assert(nRowsDone > 0); - - lzw_flush(lzwP); - - pnm_freepamrow(tuplerow); - - lzw_destroy(lzwP); -} - - - -static void writeGlobalColorMap(FILE * const ofP, const struct Cmap * const cmapP, unsigned int const bitsPerPixel) { @@ -1404,6 +1321,23 @@ writeGlobalColorMap(FILE * const ofP, static void +reportImageInfo(bool const interlace, + unsigned int const background, + unsigned int const bitsPerPixel) { + + if (verbose) { + if (interlace) + pm_message("interlaced"); + else + pm_message("not interlaced"); + pm_message("Background color index = %u", background); + pm_message("%u bits per pixel", bitsPerPixel); + } +} + + + +static void writeGifHeader(FILE * const ofP, unsigned int const width, unsigned int const height, @@ -1460,6 +1394,15 @@ writeGifHeader(FILE * const ofP, static void +writeImageSeparator(FILE * const ofP) { + + fputc(',', ofP); + +} + + + +static void writeImageHeader(FILE * const ofP, unsigned int const leftOffset, unsigned int const topOffset, @@ -1486,35 +1429,119 @@ writeImageHeader(FILE * const ofP, static void -reportImageInfo(bool const interlace, - unsigned int const background, - unsigned int const bitsPerPixel) { +writeRaster(struct pam * const pamP, + RowReader * const rowReaderP, + unsigned int const alphaPlane, + unsigned int const alphaThreshold, + struct Cmap * const cmapP, + unsigned int const initBits, + FILE * const ofP, + bool const lzw, + bool const noclear) { +/*---------------------------------------------------------------------------- + Write the raster to file 'ofP'. - if (verbose) { - if (interlace) - pm_message("interlaced"); - else - pm_message("not interlaced"); - pm_message("Background color index = %u", background); - pm_message("%u bits per pixel", bitsPerPixel); + Get the raster to write from 'rowReaderP', which gives tuples whose + format is described by 'pamP'. + + 'alphaPlane' is the number of the plane in the tuples supplied by + 'rowReaderP' that we should use for transparency information, and + 'alphaThreshold' is the value in that plane below which we should consider + the pixel transparent for GIF purposes. + + 'alphaPlane' is zero to indicate we should not use any plane as an alpha + plane (so it's not possible to specify Plane 0 as alpha). + + Use the colormap 'cmapP' to generate the raster ('rowReaderP' gives + pixel values as RGB samples; the GIF raster is colormap indices). + + Write the raster using LZW compression, or uncompressed depending + on 'lzw'. + + If 'noclear', don't use any GIF clear codes in the output; i.e. don't + recompute the string table from current input. Once the string table gets + to maximum size, just keep using that table for the rest of the image. +-----------------------------------------------------------------------------*/ + LzwCompressor * lzwP; + tuple * tuplerow; + unsigned int nRowsDone; + /* Number of rows we have read so far from the the input (the + last of which is the one we're working on now). Note that + in case of interlace, this is not the same thing as the row + number of the current row. + */ + + lzwP = lzw_create(ofP, initBits, lzw, noclear, pamP->height * pamP->width); + + tuplerow = pnm_allocpamrow(pamP); + + lzw_clearBlock(lzwP); + + nRowsDone = 0; + + while (nRowsDone < pamP->height) { + unsigned int col; + + rowReader_read(rowReaderP, tuplerow); + + for (col = 0; col < pamP->width; ++col) { + unsigned int const colorIndex = + gifPixel(pamP, tuplerow[col], alphaPlane, alphaThreshold, + cmapP); + + /* The value for the pixel in the GIF image. I.e. the colormap + index. + */ + if (lzw) + lzw_encodePixel(lzwP, colorIndex); + else + writePixelUncompressed(lzwP, colorIndex); + } + ++nRowsDone; } + /* Gif is no good with no pixels; fortunately, that's impossible: */ + assert(nRowsDone > 0); + + lzw_flush(lzwP); + + pnm_freepamrow(tuplerow); + + lzw_destroy(lzwP); +} + + + +static void +writeEndOfImage(FILE * const ofP) { + + /* An empty block marks the end of a series of blocks */ + + fputc(0, ofP); } static void -gifEncode(struct pam * const pamP, - FILE * const ofP, - pm_filepos const rasterPos, - bool const gInterlace, - int const background, - unsigned int const bitsPerPixel, - struct Cmap * const cmapP, - char const comment[], - float const aspect, - bool const lzw, - bool const noclear, - bool const usingAlpha) { +writeGifStreamTerminator(FILE * const ofP) { + + fputc(';', ofP); +} + + + +static void +writeGifImage(struct pam * const pamP, + FILE * const ofP, + pm_filepos const rasterPos, + bool const gInterlace, + int const background, + unsigned int const bitsPerPixel, + struct Cmap * const cmapP, + char const comment[], + float const aspect, + bool const lzw, + bool const noclear, + bool const usingAlpha) { /*---------------------------------------------------------------------------- 'usingAlpha' means use the alpha (transparency) plane, if there is one, to determine which GIF pixels are transparent. When this is true, the @@ -1548,26 +1575,19 @@ gifEncode(struct pam * const pamP, writeGifHeader(ofP, pamP->width, pamP->height, background, bitsPerPixel, cmapP, comment, aspect); - /* Write an Image separator */ - fputc(',', ofP); + writeImageSeparator(ofP); writeImageHeader(ofP, leftOffset, topOffset, pamP->width, pamP->height, gInterlace, initCodeSize); rowReaderP = rowReader_create(pamP, rasterPos, gInterlace); - /* Write the actual raster */ - writeRaster(pamP, rowReaderP, alphaPlane, alphaThreshold, cmapP, initCodeSize + 1, ofP, lzw, noclear); rowReader_destroy(rowReaderP); - /* Write out a zero length data block (to end the series) */ - fputc(0, ofP); - - /* Write the GIF file terminator */ - fputc(';', ofP); + writeEndOfImage(ofP); } @@ -1985,7 +2005,8 @@ destroyCmap(struct Cmap * const cmapP) { int -main(int argc, char *argv[]) { +main(int argc, const char ** argv) { + struct CmdlineInfo cmdline; FILE * ifP; struct pam pam; @@ -2000,7 +2021,7 @@ main(int argc, char *argv[]) { TRANS_ALPHA. */ - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); @@ -2033,14 +2054,15 @@ main(int argc, char *argv[]) { computeTransparent(transType, cmdline.transparent, fakeTransparent, &cmap); - /* All set, let's do it. */ - gifEncode(&pam, stdout, rasterPos, - cmdline.interlace, 0, bitsPerPixel, &cmap, cmdline.comment, - cmdline.aspect, !cmdline.nolzw, cmdline.noclear, - transType==TRANS_ALPHA); + writeGifImage(&pam, stdout, rasterPos, + cmdline.interlace, 0, bitsPerPixel, &cmap, cmdline.comment, + cmdline.aspect, !cmdline.nolzw, cmdline.noclear, + transType==TRANS_ALPHA); destroyCmap(&cmap); + writeGifStreamTerminator(stdout); + pm_close(ifP); pm_close(stdout); |