diff options
Diffstat (limited to 'Build/source/libs/gd/libgd-src/src/gd_bmp.c')
-rw-r--r-- | Build/source/libs/gd/libgd-src/src/gd_bmp.c | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/Build/source/libs/gd/libgd-src/src/gd_bmp.c b/Build/source/libs/gd/libgd-src/src/gd_bmp.c index 7b29c1a5a3a..5bef2d2ab29 100644 --- a/Build/source/libs/gd/libgd-src/src/gd_bmp.c +++ b/Build/source/libs/gd/libgd-src/src/gd_bmp.c @@ -19,12 +19,12 @@ * Read and write BMP images. */ -/* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> +#include <limits.h> #include <math.h> #include <string.h> #include <stdlib.h> @@ -47,6 +47,8 @@ static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); static int bmp_read_rle(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info); +static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression); + #define BMP_DEBUG(s) static int gdBMPPutWord(gdIOCtx *out, int w) @@ -87,8 +89,10 @@ BGD_DECLARE(void *) gdImageBmpPtr(gdImagePtr im, int *size, int compression) void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); if (out == NULL) return NULL; - gdImageBmpCtx(im, out, compression); - rv = gdDPExtractData(out, size); + if (!_gdImageBmpCtx(im, out, compression)) + rv = gdDPExtractData(out, size); + else + rv = NULL; out->gd_free(out); return rv; } @@ -142,12 +146,18 @@ BGD_DECLARE(void) gdImageBmp(gdImagePtr im, FILE *outFile, int compression) */ BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) { + _gdImageBmpCtx(im, out, compression); +} + +static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) +{ int bitmap_size = 0, info_size, total_size, padding; int i, row, xpos, pixel; int error = 0; unsigned char *uncompressed_row = NULL, *uncompressed_row_start = NULL; FILE *tmpfile_for_compression = NULL; gdIOCtxPtr out_original = NULL; + int ret = 1; /* No compression if its true colour or we don't support seek */ if (im->trueColor) { @@ -325,6 +335,7 @@ BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) out_original = NULL; } + ret = 0; cleanup: if (tmpfile_for_compression) { #ifdef _WIN32 @@ -338,7 +349,7 @@ cleanup: if (out_original) { out_original->gd_free(out_original); } - return; + return ret; } static int compress_row(unsigned char *row, int length) @@ -636,6 +647,9 @@ static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info) return 1; } + /* Unlikely, but possible -- largest signed value won't fit in unsigned. */ + if (info->height == 0 || info->height == INT_MIN) + return 1; if (info->height < 0) { info->topdown = 1; info->height = -info->height; @@ -645,8 +659,9 @@ static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info) info->type = BMP_PALETTE_4; - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) { + /* Height was checked above. */ + if (info->width <= 0 || info->numplanes <= 0 || info->depth <= 0 || + info->numcolors < 0 || info->mincolors < 0) { return 1; } @@ -667,11 +682,16 @@ static int bmp_read_os2_v1_info(gdIOCtxPtr infile, bmp_info_t *info) /* OS2 v1 doesn't support topdown */ info->topdown = 0; + /* The spec says the depth can only be a few value values. */ + if (info->depth != 1 && info->depth != 4 && info->depth != 8 && + info->depth != 16 && info->depth != 24) { + return 1; + } + info->numcolors = 1 << info->depth; info->type = BMP_PALETTE_3; - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0) { + if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0) { return 1; } @@ -701,6 +721,9 @@ static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info) return 1; } + /* Unlikely, but possible -- largest signed value won't fit in unsigned. */ + if (info->height == 0 || info->height == INT_MIN) + return 1; if (info->height < 0) { info->topdown = 1; info->height = -info->height; @@ -710,12 +733,12 @@ static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info) info->type = BMP_PALETTE_4; - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) { + /* Height was checked above. */ + if (info->width <= 0 || info->numplanes <= 0 || info->depth <= 0 || + info->numcolors < 0 || info->mincolors < 0) { return 1; } - return 0; } @@ -758,7 +781,7 @@ static int bmp_read_direct(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, b return 1; } - /* There is a chance the data isn't until later, would be wierd but it is possible */ + /* There is a chance the data isn't until later, would be weird but it is possible */ if (gdTell(infile) != header->off) { /* Should make sure we don't seek past the file size */ if (!gdSeek(infile, header->off)) { @@ -855,7 +878,7 @@ static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp im->colorsTotal = info->numcolors; - /* There is a chance the data isn't until later, would be wierd but it is possible */ + /* There is a chance the data isn't until later, would be weird but it is possible */ if (gdTell(infile) != header->off) { /* Should make sure we don't seek past the file size */ if (!gdSeek(infile, header->off)) { @@ -863,8 +886,8 @@ static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp } } - /* The line must be divisible by 4, else its padded with NULLs */ - padding = ((int)ceil(0.1 * info->width)) % 4; + /* The line must be aligned on a 32 bits word, else it is padded with zeros */ + padding = (info->width + 7) / 8 % 4; if (padding) { padding = 4 - padding; } @@ -925,7 +948,7 @@ static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp im->colorsTotal = info->numcolors; - /* There is a chance the data isn't until later, would be wierd but it is possible */ + /* There is a chance the data isn't until later, would be weird but it is possible */ if (gdTell(infile) != header->off) { /* Should make sure we don't seek past the file size */ if (!gdSeek(infile, header->off)) { @@ -1012,7 +1035,7 @@ static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp im->colorsTotal = info->numcolors; - /* There is a chance the data isn't until later, would be wierd but it is possible */ + /* There is a chance the data isn't until later, would be weird but it is possible */ if (gdTell(infile) != header->off) { /* Should make sure we don't seek past the file size */ if (!gdSeek(infile, header->off)) { |