summaryrefslogtreecommitdiff
path: root/Build/source/libs/gd/libgd-src/src/gd_bmp.c
diff options
context:
space:
mode:
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.c57
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)) {