Add sanity check in BMP reader module to avoid cjpeg crash for empty input
image; Support 32-bit BMPs
This commit is contained in:
57
rdbmp.c
57
rdbmp.c
@@ -2,6 +2,7 @@
|
|||||||
* rdbmp.c
|
* rdbmp.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||||
|
* Modified 2009-2010 by Guido Vollbeding.
|
||||||
* This file is part of the Independent JPEG Group's software.
|
* This file is part of the Independent JPEG Group's software.
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
* For conditions of distribution and use, see the accompanying README file.
|
||||||
*
|
*
|
||||||
@@ -177,10 +178,41 @@ get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
METHODDEF(JDIMENSION)
|
||||||
|
get_32bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||||
|
/* This version is for reading 32-bit pixels */
|
||||||
|
{
|
||||||
|
bmp_source_ptr source = (bmp_source_ptr) sinfo;
|
||||||
|
JSAMPARRAY image_ptr;
|
||||||
|
register JSAMPROW inptr, outptr;
|
||||||
|
register JDIMENSION col;
|
||||||
|
|
||||||
|
/* Fetch next row from virtual array */
|
||||||
|
source->source_row--;
|
||||||
|
image_ptr = (*cinfo->mem->access_virt_sarray)
|
||||||
|
((j_common_ptr) cinfo, source->whole_image,
|
||||||
|
source->source_row, (JDIMENSION) 1, FALSE);
|
||||||
|
/* Transfer data. Note source values are in BGR order
|
||||||
|
* (even though Microsoft's own documents say the opposite).
|
||||||
|
*/
|
||||||
|
inptr = image_ptr[0];
|
||||||
|
outptr = source->pub.buffer[0];
|
||||||
|
for (col = cinfo->image_width; col > 0; col--) {
|
||||||
|
outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */
|
||||||
|
outptr[1] = *inptr++;
|
||||||
|
outptr[0] = *inptr++;
|
||||||
|
inptr++; /* skip the 4th byte (Alpha channel) */
|
||||||
|
outptr += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method loads the image into whole_image during the first call on
|
* This method loads the image into whole_image during the first call on
|
||||||
* get_pixel_rows. The get_pixel_rows pointer is then adjusted to call
|
* get_pixel_rows. The get_pixel_rows pointer is then adjusted to call
|
||||||
* get_8bit_row or get_24bit_row on subsequent calls.
|
* get_8bit_row, get_24bit_row, or get_32bit_row on subsequent calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
METHODDEF(JDIMENSION)
|
METHODDEF(JDIMENSION)
|
||||||
@@ -223,6 +255,9 @@ preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
|||||||
case 24:
|
case 24:
|
||||||
source->pub.get_pixel_rows = get_24bit_row;
|
source->pub.get_pixel_rows = get_24bit_row;
|
||||||
break;
|
break;
|
||||||
|
case 32:
|
||||||
|
source->pub.get_pixel_rows = get_32bit_row;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
|
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
|
||||||
}
|
}
|
||||||
@@ -251,8 +286,8 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
|||||||
(((INT32) UCH(array[offset+3])) << 24))
|
(((INT32) UCH(array[offset+3])) << 24))
|
||||||
INT32 bfOffBits;
|
INT32 bfOffBits;
|
||||||
INT32 headerSize;
|
INT32 headerSize;
|
||||||
INT32 biWidth = 0; /* initialize to avoid compiler warning */
|
INT32 biWidth;
|
||||||
INT32 biHeight = 0;
|
INT32 biHeight;
|
||||||
unsigned int biPlanes;
|
unsigned int biPlanes;
|
||||||
INT32 biCompression;
|
INT32 biCompression;
|
||||||
INT32 biXPelsPerMeter,biYPelsPerMeter;
|
INT32 biXPelsPerMeter,biYPelsPerMeter;
|
||||||
@@ -300,8 +335,6 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
|||||||
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
|
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (biPlanes != 1)
|
|
||||||
ERREXIT(cinfo, JERR_BMP_BADPLANES);
|
|
||||||
break;
|
break;
|
||||||
case 40:
|
case 40:
|
||||||
case 64:
|
case 64:
|
||||||
@@ -325,12 +358,13 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
|||||||
case 24: /* RGB image */
|
case 24: /* RGB image */
|
||||||
TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight);
|
TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight);
|
||||||
break;
|
break;
|
||||||
|
case 32: /* RGB image + Alpha channel */
|
||||||
|
TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
|
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (biPlanes != 1)
|
|
||||||
ERREXIT(cinfo, JERR_BMP_BADPLANES);
|
|
||||||
if (biCompression != 0)
|
if (biCompression != 0)
|
||||||
ERREXIT(cinfo, JERR_BMP_COMPRESSED);
|
ERREXIT(cinfo, JERR_BMP_COMPRESSED);
|
||||||
|
|
||||||
@@ -343,9 +377,14 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERREXIT(cinfo, JERR_BMP_BADHEADER);
|
ERREXIT(cinfo, JERR_BMP_BADHEADER);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (biWidth <= 0 || biHeight <= 0)
|
||||||
|
ERREXIT(cinfo, JERR_BMP_EMPTY);
|
||||||
|
if (biPlanes != 1)
|
||||||
|
ERREXIT(cinfo, JERR_BMP_BADPLANES);
|
||||||
|
|
||||||
/* Compute distance to bitmap data --- will adjust for colormap below */
|
/* Compute distance to bitmap data --- will adjust for colormap below */
|
||||||
bPad = bfOffBits - (headerSize + 14);
|
bPad = bfOffBits - (headerSize + 14);
|
||||||
|
|
||||||
@@ -375,6 +414,8 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
|||||||
/* Compute row width in file, including padding to 4-byte boundary */
|
/* Compute row width in file, including padding to 4-byte boundary */
|
||||||
if (source->bits_per_pixel == 24)
|
if (source->bits_per_pixel == 24)
|
||||||
row_width = (JDIMENSION) (biWidth * 3);
|
row_width = (JDIMENSION) (biWidth * 3);
|
||||||
|
else if (source->bits_per_pixel == 32)
|
||||||
|
row_width = (JDIMENSION) (biWidth * 4);
|
||||||
else
|
else
|
||||||
row_width = (JDIMENSION) biWidth;
|
row_width = (JDIMENSION) biWidth;
|
||||||
while ((row_width & 3) != 0) row_width++;
|
while ((row_width & 3) != 0) row_width++;
|
||||||
|
|||||||
Reference in New Issue
Block a user