diff options
Diffstat (limited to 'converter')
-rw-r--r-- | converter/other/bmptopnm.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/converter/other/bmptopnm.c b/converter/other/bmptopnm.c index 018b8326..ad92db26 100644 --- a/converter/other/bmptopnm.c +++ b/converter/other/bmptopnm.c @@ -895,6 +895,15 @@ convertRow32(unsigned char const bmprow[], } +static void +validateIndex(unsigned int const index, + unsigned int const cmapsize ) { + + if (index >= cmapsize) + pm_error("Error: invalid index to color palette."); +} + + static void convertRow(unsigned char const bmprow[], @@ -902,7 +911,8 @@ convertRow(unsigned char const bmprow[], int const cols, unsigned int const cBitCount, struct pixelformat const pixelformat, - xel const colormap[] + xel const colormap[], + unsigned int const cmapsize ) { /*---------------------------------------------------------------------------- Convert a row in raw BMP raster format bmprow[] to a row of xels xelrow[]. @@ -922,9 +932,12 @@ convertRow(unsigned char const bmprow[], convertRow32(bmprow, xelrow, cols, pixelformat); else if (cBitCount == 8) { /* It's a whole byte colormap index */ - unsigned int col; - for (col = 0; col < cols; ++col) - xelrow[col] = colormap[bmprow[col]]; + unsigned int col; + for (col = 0; col < cols; ++col) { + unsigned int const index = bmprow[col]; + validateIndex(index, cmapsize); + xelrow[col] = colormap[index]; + } } else if (cBitCount == 1 || cBitCount == 2 || cBitCount == 4) { /* It's a bit field color index */ unsigned char const mask = ( 1 << cBitCount ) - 1; @@ -936,6 +949,7 @@ convertRow(unsigned char const bmprow[], unsigned int const shift = 8 - ((col*cBitCount) % 8) - cBitCount; unsigned int const index = (bmprow[cursor] & (mask << shift)) >> shift; + validateIndex(index, cmapsize); xelrow[col] = colormap[index]; } } else { @@ -1407,6 +1421,7 @@ readBmp(FILE * const ifP, unsigned int * const cBitCountP, struct pixelformat * const pixelformatP, xel ** const colormapP, + unsigned int * const cmapsizeP, bool const verbose) { xel * colormap; /* malloc'ed */ @@ -1467,6 +1482,7 @@ readBmp(FILE * const ifP, *rowsP = bmpHeader.rows; *pixelformatP = bmpHeader.pixelformat; *colormapP = colormap; + *cmapsizeP = bmpHeader.cmapsize; } @@ -1478,7 +1494,8 @@ writeRasterGen(unsigned char ** const bmpRaster, int const format, unsigned int const cBitCount, struct pixelformat const pixelformat, - xel const colormap[]) { + xel const colormap[], + unsigned int const cmapsize) { /*---------------------------------------------------------------------------- Write the PNM raster to Standard Output, corresponding to the raw BMP raster bmpRaster. Write the raster assuming the PNM image has @@ -1499,7 +1516,7 @@ writeRasterGen(unsigned char ** const bmpRaster, for (row = 0; row < rows; ++row) { convertRow(bmpRaster[row], xelrow, cols, cBitCount, pixelformat, - colormap); + colormap, cmapsize); pnm_writepnmrow(stdout, xelrow, cols, bmpMaxval, format, FALSE); } pnm_freerow(xelrow); @@ -1581,6 +1598,13 @@ main(int argc, const char ** argv) { /* Malloc'ed colormap (palette) from the BMP. Contents of map undefined if not a colormapped BMP. */ + unsigned int cmapsize; + /* Number of colormap entries. Described in the BMP header. + Note that a file may be 8 bits per pixel but have less than + 256 colors. In the 1 bit per pixel case, there should be + 2 entries according to the official specification, but we + allow files with just 1. + */ pm_proginit(&argc, argv); @@ -1593,7 +1617,7 @@ main(int argc, const char ** argv) { ifname = cmdline.inputFileName; readBmp(ifP, &bmpRaster, &cols, &rows, &grayPresent, &colorPresent, - &cBitCount, &pixelformat, &colormap, + &cBitCount, &pixelformat, &colormap, &cmapsize, cmdline.verbose); pm_close(ifP); @@ -1614,7 +1638,7 @@ main(int argc, const char ** argv) { } else { pnm_writepnminit(stdout, cols, rows, bmpMaxval, outputType, FALSE); writeRasterGen(bmpRaster, cols, rows, outputType, cBitCount, - pixelformat, colormap); + pixelformat, colormap, cmapsize); } free(colormap); free(bmpRaster); |