images: more strict check of pcx
checked with https://samples.ffmpeg.org/image-samples/pcx/
This commit is contained in:
parent
3ba0f35636
commit
4e61cbccc2
|
@ -135,7 +135,8 @@ fixQuitScreen(byte* px)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const byte *
|
static const byte *
|
||||||
PCX_RLE_Decode(byte *pix, byte *pix_max, const byte *raw, const byte *raw_max, int bytes_per_line)
|
PCX_RLE_Decode(byte *pix, byte *pix_max, const byte *raw, const byte *raw_max,
|
||||||
|
int bytes_per_line, qboolean *image_issues)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
@ -147,6 +148,7 @@ PCX_RLE_Decode(byte *pix, byte *pix_max, const byte *raw, const byte *raw_max, i
|
||||||
if (raw >= raw_max)
|
if (raw >= raw_max)
|
||||||
{
|
{
|
||||||
// no place for read
|
// no place for read
|
||||||
|
*image_issues = true;
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
dataByte = *raw++;
|
dataByte = *raw++;
|
||||||
|
@ -157,6 +159,7 @@ PCX_RLE_Decode(byte *pix, byte *pix_max, const byte *raw, const byte *raw_max, i
|
||||||
if (raw >= raw_max)
|
if (raw >= raw_max)
|
||||||
{
|
{
|
||||||
// no place for read
|
// no place for read
|
||||||
|
*image_issues = true;
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
dataByte = *raw++;
|
dataByte = *raw++;
|
||||||
|
@ -171,6 +174,7 @@ PCX_RLE_Decode(byte *pix, byte *pix_max, const byte *raw, const byte *raw_max, i
|
||||||
if (pix_max <= (pix + x))
|
if (pix_max <= (pix + x))
|
||||||
{
|
{
|
||||||
// no place for write
|
// no place for write
|
||||||
|
*image_issues = true;
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -217,7 +221,12 @@ PCX_Decode(const char *name, const byte *raw, int len, byte **pic, byte **palett
|
||||||
|
|
||||||
if ((pcx->manufacturer != 0x0a) ||
|
if ((pcx->manufacturer != 0x0a) ||
|
||||||
(pcx->version != 5) ||
|
(pcx->version != 5) ||
|
||||||
(pcx->encoding != 1))
|
(pcx->encoding != 1) ||
|
||||||
|
(pcx_width <= 0) ||
|
||||||
|
(pcx_height <= 0) ||
|
||||||
|
(bytes_per_line <= 0) ||
|
||||||
|
(pcx->color_planes <= 0) ||
|
||||||
|
(pcx->bits_per_pixel <= 0))
|
||||||
{
|
{
|
||||||
Com_Printf("%s: Bad pcx file %s: version: %d:%d, encoding: %d\n",
|
Com_Printf("%s: Bad pcx file %s: version: %d:%d, encoding: %d\n",
|
||||||
__func__, name, pcx->manufacturer, pcx->version, pcx->encoding);
|
__func__, name, pcx->manufacturer, pcx->version, pcx->encoding);
|
||||||
|
@ -273,7 +282,7 @@ PCX_Decode(const char *name, const byte *raw, int len, byte **pic, byte **palett
|
||||||
{
|
{
|
||||||
data = PCX_RLE_Decode(line, line + (pcx_width + 1) * pcx->color_planes,
|
data = PCX_RLE_Decode(line, line + (pcx_width + 1) * pcx->color_planes,
|
||||||
data, (byte *)pcx + len,
|
data, (byte *)pcx + len,
|
||||||
bytes_per_line * pcx->color_planes);
|
bytes_per_line * pcx->color_planes, &image_issues);
|
||||||
|
|
||||||
for (x = 0; x <= pcx_width; x++) {
|
for (x = 0; x <= pcx_width; x++) {
|
||||||
int j;
|
int j;
|
||||||
|
@ -314,7 +323,7 @@ PCX_Decode(const char *name, const byte *raw, int len, byte **pic, byte **palett
|
||||||
|
|
||||||
data = PCX_RLE_Decode(line, line + bytes_per_line * pcx->color_planes,
|
data = PCX_RLE_Decode(line, line + bytes_per_line * pcx->color_planes,
|
||||||
data, (byte *)pcx + len,
|
data, (byte *)pcx + len,
|
||||||
bytes_per_line * pcx->color_planes);
|
bytes_per_line * pcx->color_planes, &image_issues);
|
||||||
|
|
||||||
for (x = 0; x <= pcx_width; x++)
|
for (x = 0; x <= pcx_width; x++)
|
||||||
{
|
{
|
||||||
|
@ -332,100 +341,95 @@ PCX_Decode(const char *name, const byte *raw, int len, byte **pic, byte **palett
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
else if (pcx->color_planes == 1 &&
|
else if (pcx->color_planes == 1 && pcx->bits_per_pixel == 8)
|
||||||
(pcx->bits_per_pixel == 2 ||
|
|
||||||
pcx->bits_per_pixel == 4 ||
|
|
||||||
pcx->bits_per_pixel == 8))
|
|
||||||
{
|
{
|
||||||
if (pcx->bits_per_pixel == 8)
|
int y;
|
||||||
|
|
||||||
|
if (palette)
|
||||||
{
|
{
|
||||||
int y;
|
*palette = malloc(768);
|
||||||
|
|
||||||
if (palette)
|
if (!(*palette))
|
||||||
{
|
{
|
||||||
*palette = malloc(768);
|
Com_Printf("%s: Can't allocate for %s\n", __func__, name);
|
||||||
|
free(out);
|
||||||
if (!(*palette))
|
return;
|
||||||
{
|
|
||||||
Com_Printf("%s: Can't allocate for %s\n", __func__, name);
|
|
||||||
free(out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((len > 768) && (((byte *)pcx)[len - 769] == 0x0C))
|
|
||||||
{
|
|
||||||
memcpy(*palette, (byte *)pcx + len - 768, 768);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
image_issues = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes_per_line <= pcx_width)
|
if ((len > 768) && (((byte *)pcx)[len - 769] == 0x0C))
|
||||||
|
{
|
||||||
|
memcpy(*palette, (byte *)pcx + len - 768, 768);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
bytes_per_line = pcx_width + 1;
|
|
||||||
image_issues = true;
|
image_issues = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y <= pcx_height; y++, pix += pcx_width + 1)
|
|
||||||
{
|
|
||||||
data = PCX_RLE_Decode(pix, pix + pcx_width + 1,
|
|
||||||
data, (byte *)pcx + len,
|
|
||||||
bytes_per_line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (bytes_per_line <= pcx_width)
|
||||||
{
|
{
|
||||||
int y;
|
bytes_per_line = pcx_width + 1;
|
||||||
|
image_issues = true;
|
||||||
byte *line;
|
|
||||||
|
|
||||||
if (palette)
|
|
||||||
{
|
|
||||||
*palette = malloc(768);
|
|
||||||
|
|
||||||
if (!(*palette))
|
|
||||||
{
|
|
||||||
Com_Printf("%s: Can't allocate for %s\n", __func__, name);
|
|
||||||
free(out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(*palette, pcx->palette, sizeof(pcx->palette));
|
|
||||||
}
|
|
||||||
|
|
||||||
line = malloc(bytes_per_line);
|
|
||||||
|
|
||||||
for (y = 0; y <= pcx_height; y++, pix += pcx_width + 1)
|
|
||||||
{
|
|
||||||
int x, mask, div;
|
|
||||||
|
|
||||||
data = PCX_RLE_Decode(line, line + bytes_per_line,
|
|
||||||
data, (byte *)pcx + len,
|
|
||||||
bytes_per_line);
|
|
||||||
|
|
||||||
mask = (1 << pcx->bits_per_pixel) - 1;
|
|
||||||
div = 8 / pcx->bits_per_pixel;
|
|
||||||
|
|
||||||
for (x = 0; x <= pcx_width; x++)
|
|
||||||
{
|
|
||||||
unsigned v, shift;
|
|
||||||
|
|
||||||
v = line[x / div] & 0xFF;
|
|
||||||
/* for 2 bits:
|
|
||||||
* 0 -> 6
|
|
||||||
* 1 -> 4
|
|
||||||
* 3 -> 2
|
|
||||||
* 4 -> 0
|
|
||||||
*/
|
|
||||||
shift = pcx->bits_per_pixel * ((div - 1) - x % div);
|
|
||||||
pix[x] = (v >> shift) & mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (y = 0; y <= pcx_height; y++, pix += pcx_width + 1)
|
||||||
|
{
|
||||||
|
data = PCX_RLE_Decode(pix, pix + pcx_width + 1,
|
||||||
|
data, (byte *)pcx + len,
|
||||||
|
bytes_per_line, &image_issues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pcx->color_planes == 1 &&
|
||||||
|
(pcx->bits_per_pixel == 2 || pcx->bits_per_pixel == 4))
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
|
||||||
|
byte *line;
|
||||||
|
|
||||||
|
if (palette)
|
||||||
|
{
|
||||||
|
*palette = malloc(768);
|
||||||
|
|
||||||
|
if (!(*palette))
|
||||||
|
{
|
||||||
|
Com_Printf("%s: Can't allocate for %s\n", __func__, name);
|
||||||
|
free(out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(*palette, pcx->palette, sizeof(pcx->palette));
|
||||||
|
}
|
||||||
|
|
||||||
|
line = malloc(bytes_per_line);
|
||||||
|
|
||||||
|
for (y = 0; y <= pcx_height; y++, pix += pcx_width + 1)
|
||||||
|
{
|
||||||
|
int x, mask, div;
|
||||||
|
|
||||||
|
data = PCX_RLE_Decode(line, line + bytes_per_line,
|
||||||
|
data, (byte *)pcx + len,
|
||||||
|
bytes_per_line, &image_issues);
|
||||||
|
|
||||||
|
mask = (1 << pcx->bits_per_pixel) - 1;
|
||||||
|
div = 8 / pcx->bits_per_pixel;
|
||||||
|
|
||||||
|
for (x = 0; x <= pcx_width; x++)
|
||||||
|
{
|
||||||
|
unsigned v, shift;
|
||||||
|
|
||||||
|
v = line[x / div] & 0xFF;
|
||||||
|
/* for 2 bits:
|
||||||
|
* 0 -> 6
|
||||||
|
* 1 -> 4
|
||||||
|
* 3 -> 2
|
||||||
|
* 4 -> 0
|
||||||
|
*/
|
||||||
|
shift = pcx->bits_per_pixel * ((div - 1) - x % div);
|
||||||
|
pix[x] = (v >> shift) & mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(line);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue