--- ppm/ppmtobmp.c.orig Mon Oct 4 18:12:36 1993 +++ ppm/ppmtobmp.c Sat Oct 16 02:53:18 1999 @@ -75,7 +75,7 @@ unsigned short cBitCount, pixel **pixels, colorhash_table cht)); static int colorstobpp ARGS((int colors)); static void BMPEncode ARGS((FILE *fp, int class, int x, int y, pixel **pixels, - int colors, colorhash_table cht, pixval *R, pixval *G, pixval *B)); + int bpp, int colors, colorhash_table cht, pixval *R, pixval *G, pixval *B)); static void PutByte(fp, v) FILE *fp; @@ -253,19 +253,23 @@ int i; long ncolors; - for (i = 0; i < colors; i++) - { - nbyte += BMPwritergb(fp,class,R[i],G[i],B[i]); - } - - ncolors = (1 << bpp); + if (bpp != 24) + { - for (; i < ncolors; i++) - { - nbyte += BMPwritergb(fp,class,0,0,0); - } + for (i = 0; i < colors; i++) + { + nbyte += BMPwritergb(fp,class,R[i],G[i],B[i]); + } + + ncolors = (1 << bpp); + + for (; i < ncolors; i++) + { + nbyte += BMPwritergb(fp,class,0,0,0); + } + } - return nbyte; + return nbyte; } /* @@ -284,26 +288,38 @@ int rc; unsigned x; - if ((b = pm_bitinit(fp, "w")) == (BITSTREAM) 0) - { - return -1; - } - - for (x = 0; x < cx; x++, row++) - { - if ((rc = pm_bitwrite(b, bpp, ppm_lookupcolor(cht, row))) == -1) - { - return -1; - } - nbyte += rc; - } - - if ((rc = pm_bitfini(b)) == -1) - { - return -1; - } - nbyte += rc; - + if (bpp != 24) + { + if ((b = pm_bitinit(fp, "w")) == (BITSTREAM) 0) + { + return -1; + } + + for (x = 0; x < cx; x++, row++) + { + if ((rc = pm_bitwrite(b, bpp, ppm_lookupcolor(cht, row))) == -1) + { + return -1; + } + nbyte += rc; + } + + if ((rc = pm_bitfini(b)) == -1) + { + return -1; + } + nbyte += rc; + } + else + { + for (x = 0; x < cx; x++, row++) + { + PutByte(fp, PPM_GETB(*row)); + PutByte(fp, PPM_GETG(*row)); + PutByte(fp, PPM_GETR(*row)); + nbyte += 3; + } + } /* * Make sure we write a multiple of 4 bytes. */ @@ -394,48 +410,21 @@ * arrays are undefined. */ static void -BMPEncode(fp, class, x, y, pixels, colors, cht, R, G, B) +BMPEncode(fp, class, x, y, pixels, bpp, colors, cht, R, G, B) FILE *fp; int class; int x; int y; pixel **pixels; + int bpp; /* bits per pixel */ int colors; /* number of valid entries in R,G,B */ colorhash_table cht; pixval *R; pixval *G; pixval *B; { - int bpp; /* bits per pixel */ unsigned long nbyte = 0; - bpp = colorstobpp(colors); - - /* - * I have found empirically at least one BMP-displaying program - * that can't deal with (for instance) using 3 bits per pixel. - * I have seen no programs that can deal with using 3 bits per - * pixel. I have seen programs which can deal with 1, 4, and - * 8 bits per pixel. - * - * Based on this, I adjust actual the number of bits per pixel - * as follows. If anyone knows better, PLEASE tell me! - */ - switch(bpp) - { - case 2: - case 3: - bpp = 4; - break; - case 5: - case 6: - case 7: - bpp = 8; - break; - } - - pm_message("Using %d bits per pixel", bpp); - nbyte += BMPwritefileheader(fp, class, bpp, x, y); nbyte += BMPwriteinfoheader(fp, class, bpp, x, y); nbyte += BMPwritergbtable(fp, class, bpp, colors, R, G, B); @@ -517,13 +506,15 @@ char **argv; { FILE *ifp = stdin; - char *usage = "[-windows] [-os2] [ppmfile]"; + char *usage = "[-windows] [-os2] [-1/4/8/24bits] [ppmfile]"; int class = C_OS2; int argn; int rows; int cols; int colors; + int maxcolors = MAXCOLORS; + int bpp = 0; int i; pixval maxval; colorhist_vector chv; @@ -545,6 +536,14 @@ class = C_WIN; else if (pm_keymatch(argv[argn], "-os2", 2)) class = C_OS2; + else if (pm_keymatch(argv[argn], "-24bits", 3)) + bpp = 24, maxcolors = 256; + else if (pm_keymatch(argv[argn], "-8bits", 2)) + bpp = 8, maxcolors = 256; + else if (pm_keymatch(argv[argn], "-4bits", 2)) + bpp = 4, maxcolors = 16; + else if (pm_keymatch(argv[argn], "-1bit", 2)) + bpp = 1, maxcolors = 2; else pm_usage(usage); ++argn; @@ -585,44 +584,90 @@ #endif /* Figure out the colormap. */ - pm_message("computing colormap..."); - chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors); + chv = (colorhist_vector) 0; + if(bpp != 24) + { + pm_message("computing colormap..."); + chv = ppm_computecolorhist(pixels, cols, rows, maxcolors, &colors); + } if (chv == (colorhist_vector) 0) - pm_error("too many colors - try doing a 'ppmquant %d'" - , MAXCOLORS); - pm_message("%d colors found", colors); - - /* - * Now turn the ppm colormap into the appropriate GIF - * colormap. - */ - if (maxval > 255) - { - pm_message("maxval is not 255 - automatically rescaling colors"); - } - for (i = 0; i < colors; ++i) - { - if (maxval == 255) - { - Red[i] = PPM_GETR(chv[i].color); - Green[i] = PPM_GETG(chv[i].color); - Blue[i] = PPM_GETB(chv[i].color); - } - else - { - Red[i] = (pixval) PPM_GETR(chv[i].color) * 255 / maxval; - Green[i] = (pixval) PPM_GETG(chv[i].color) * 255 / maxval; - Blue[i] = (pixval) PPM_GETB(chv[i].color) * 255 / maxval; - } - } + { + if (bpp == 0) + { + pm_message("over 256 colors found"); + bpp = 24; + } + else if (bpp != 24) + pm_error("too many colors - try doing a 'ppmquant %d'" + , maxcolors); + } + else + { + pm_message("%d colors found", colors); + + /* + * I have found empirically at least one BMP-displaying program + * that can't deal with (for instance) using 3 bits per pixel. + * I have seen no programs that can deal with using 3 bits per + * pixel. I have seen programs which can deal with 1, 4, and + * 8 bits per pixel. + * + * Based on this, I adjust actual the number of bits per pixel + * as follows. If anyone knows better, PLEASE tell me! + */ + + if (!bpp) + { + bpp = colorstobpp(colors); + + switch(bpp) + { + case 2: + case 3: + bpp = 4; + break; + case 5: + case 6: + case 7: + bpp = 8; + break; + } + } + + /* + * Now turn the ppm colormap into the appropriate GIF + * colormap. + */ + if (maxval > 255) + { + pm_message("maxval is not 255 - automatically rescaling colors"); + } + for (i = 0; i < colors; ++i) + { + if (maxval == 255) + { + Red[i] = PPM_GETR(chv[i].color); + Green[i] = PPM_GETG(chv[i].color); + Blue[i] = PPM_GETB(chv[i].color); + } + else + { + Red[i] = (pixval) PPM_GETR(chv[i].color) * 255 / maxval; + Green[i] = (pixval) PPM_GETG(chv[i].color) * 255 / maxval; + Blue[i] = (pixval) PPM_GETB(chv[i].color) * 255 / maxval; + } + } + + /* And make a hash table for fast lookup. */ + cht = ppm_colorhisttocolorhash(chv, colors); + ppm_freecolorhist(chv); + } - /* And make a hash table for fast lookup. */ - cht = ppm_colorhisttocolorhash(chv, colors); - ppm_freecolorhist(chv); + pm_message("Using %d bits per pixel", bpp); /* All set, let's do it. */ BMPEncode(stdout, class - , cols, rows, pixels, colors, cht + , cols, rows, pixels, bpp, colors, cht ,Red, Green, Blue); pm_close(stdout);