diff --git a/config/gdlib-config.in b/config/gdlib-config.in index 24baa78..6e4e494 100755 --- a/config/gdlib-config.in +++ b/config/gdlib-config.in @@ -10,10 +10,9 @@ echo "gdlib-config: warning: this script is deprecated;" \ # installation directories prefix=@prefix@ exec_prefix=@exec_prefix@ -libdir=`pkg-config gdlib --variable=libdir` +libdir=@libdir@ includedir=@includedir@ bindir=@bindir@ -ldflags=`pkg-config gdlib --variable=ldflags` usage() { @@ -72,7 +71,7 @@ while test $# -gt 0; do echo @GDLIB_REVISION@ ;; --ldflags) - echo $ldflags + echo @LDFLAGS@ ;; --libs) echo -lgd @LIBS@ @LIBICONV@ @@ -87,7 +86,7 @@ while test $# -gt 0; do echo "GD library @VERSION@" echo "includedir: $includedir" echo "cflags: -I@includedir@" - echo "ldflags: $ldflags" + echo "ldflags: @LDFLAGS@" echo "libs: @LIBS@ @LIBICONV@" echo "libdir: $libdir" echo "features: @FEATURES@" diff --git a/config/gdlib-config.in.mlib b/config/gdlib-config.in.mlib deleted file mode 100755 index 6e4e494..0000000 --- a/config/gdlib-config.in.mlib +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/sh -# -# Return information about the local GD library installation -# -# Modeled after pdflib-config - -echo "gdlib-config: warning: this script is deprecated;" \ - "please use the pkg-config file instead." >&2 - -# installation directories -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -bindir=@bindir@ - -usage() -{ - cat <&2 -fi - -while test $# -gt 0; do - case "$1" in - -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - case $1 in - --libdir) - echo $libdir - ;; - --includedir) - echo $includedir - ;; - --version) - echo @VERSION@ - ;; - --majorversion) - echo @GDLIB_MAJOR@ - ;; - --minorversion) - echo @GDLIB_MINOR@ - ;; - --revision) - echo @GDLIB_REVISION@ - ;; - --ldflags) - echo @LDFLAGS@ - ;; - --libs) - echo -lgd @LIBS@ @LIBICONV@ - ;; - --cflags|--includes) - echo -I@includedir@ - ;; - --features) - echo @FEATURES@ - ;; - --all) - echo "GD library @VERSION@" - echo "includedir: $includedir" - echo "cflags: -I@includedir@" - echo "ldflags: @LDFLAGS@" - echo "libs: @LIBS@ @LIBICONV@" - echo "libdir: $libdir" - echo "features: @FEATURES@" - ;; - *) - usage 1 1>&2 - ;; - esac - shift -done diff --git a/src/gd.c b/src/gd.c index 45ee762..7f0a258 100755 --- a/src/gd.c +++ b/src/gd.c @@ -2855,6 +2855,14 @@ BGD_DECLARE(gdImagePtr) gdImageClone (gdImagePtr src) { } } + if (src->styleLength > 0) { + dst->styleLength = src->styleLength; + dst->stylePos = src->stylePos; + for (i = 0; i < src->styleLength; i++) { + dst->style[i] = src->style[i]; + } + } + dst->interlace = src->interlace; dst->alphaBlendingFlag = src->alphaBlendingFlag; @@ -2889,7 +2897,6 @@ BGD_DECLARE(gdImagePtr) gdImageClone (gdImagePtr src) { if (src->style) { gdImageSetStyle(dst, src->style, src->styleLength); - dst->stylePos = src->stylePos; } for (i = 0; i < gdMaxColors; i++) { diff --git a/src/gd_bmp.c b/src/gd_bmp.c index 34494ff..7b29c1a 100755 --- a/src/gd_bmp.c +++ b/src/gd_bmp.c @@ -47,8 +47,6 @@ 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) @@ -89,10 +87,8 @@ BGD_DECLARE(void *) gdImageBmpPtr(gdImagePtr im, int *size, int compression) void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); if (out == NULL) return NULL; - if (!_gdImageBmpCtx(im, out, compression)) - rv = gdDPExtractData(out, size); - else - rv = NULL; + gdImageBmpCtx(im, out, compression); + rv = gdDPExtractData(out, size); out->gd_free(out); return rv; } @@ -146,18 +142,12 @@ 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) { @@ -335,7 +325,6 @@ static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) out_original = NULL; } - ret = 0; cleanup: if (tmpfile_for_compression) { #ifdef _WIN32 @@ -349,7 +338,7 @@ cleanup: if (out_original) { out_original->gd_free(out_original); } - return ret; + return; } static int compress_row(unsigned char *row, int length) diff --git a/src/gd_bmp.c.gdImageBmpPtr-free b/src/gd_bmp.c.gdImageBmpPtr-free deleted file mode 100755 index 7b29c1a..0000000 --- a/src/gd_bmp.c.gdImageBmpPtr-free +++ /dev/null @@ -1,1142 +0,0 @@ -/* - gd_bmp.c - - Bitmap format support for libgd - - * Written 2007, Scott MacVicar - --------------------------------------------------------------------------- - - Todo: - - Bitfield encoding - - ---------------------------------------------------------------------------- - */ - -/** - * File: BMP IO - * - * Read and write BMP images. - */ - -/* $Id$ */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include "gd.h" -#include "gdhelpers.h" -#include "bmp.h" - -static int compress_row(unsigned char *uncompressed_row, int length); -static int build_rle_packet(unsigned char *row, int packet_type, int length, unsigned char *data); - -static int bmp_read_header(gdIOCtxPtr infile, bmp_hdr_t *hdr); -static int bmp_read_info(gdIOCtxPtr infile, bmp_info_t *info); -static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info); -static int bmp_read_os2_v1_info(gdIOCtxPtr infile, bmp_info_t *info); -static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info); - -static int bmp_read_direct(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); -static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); -static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); -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); - -#define BMP_DEBUG(s) - -static int gdBMPPutWord(gdIOCtx *out, int w) -{ - /* Byte order is little-endian */ - gdPutC(w & 0xFF, out); - gdPutC((w >> 8) & 0xFF, out); - return 0; -} - -static int gdBMPPutInt(gdIOCtx *out, int w) -{ - /* Byte order is little-endian */ - gdPutC(w & 0xFF, out); - gdPutC((w >> 8) & 0xFF, out); - gdPutC((w >> 16) & 0xFF, out); - gdPutC((w >> 24) & 0xFF, out); - return 0; -} - -/* - Function: gdImageBmpPtr - - Outputs the given image as BMP data, but using a instead - of a file. See . - - Parameters: - im - the image to save. - size - Output: size in bytes of the result. - compression - whether to apply RLE or not. - - Returns: - - A pointer to memory containing the image data or NULL on error. -*/ -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); - out->gd_free(out); - return rv; -} - -/* - Function: gdImageBmp - - outputs the specified image to the specified file in - BMP format. The file must be open for writing. Under MSDOS and all - versions of Windows, it is important to use "wb" as opposed to - simply "w" as the mode when opening the file, and under Unix there - is no penalty for doing so. does not close the file; - your code must do so. - - In addition, allows to specify whether RLE compression - should be applied. - - Variants: - - write via a instead of a file handle. - - store the image file to memory. - - Parameters: - - im - the image to save. - outFile - the output FILE* object. - compression - whether to apply RLE or not. - - Returns: - nothing -*/ -BGD_DECLARE(void) gdImageBmp(gdImagePtr im, FILE *outFile, int compression) -{ - gdIOCtx *out = gdNewFileCtx(outFile); - if (out == NULL) return; - gdImageBmpCtx(im, out, compression); - out->gd_free(out); -} - -/* - Function: gdImageBmpCtx - - Outputs the given image as BMP data, but using a instead - of a file. See . - - Parameters: - im - the image to save. - out - the to write to. - compression - whether to apply RLE or not. -*/ -BGD_DECLARE(void) 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; - - /* No compression if its true colour or we don't support seek */ - if (im->trueColor) { - compression = 0; - } - - if (compression && !out->seek) { - /* Try to create a temp file where we can seek */ - if ((tmpfile_for_compression = tmpfile()) == NULL) { - compression = 0; - } else { - out_original = out; - if ((out = (gdIOCtxPtr)gdNewFileCtx(tmpfile_for_compression)) == NULL) { - out = out_original; - out_original = NULL; - compression = 0; - } - } - } - - bitmap_size = ((im->sx * (im->trueColor ? 24 : 8)) / 8) * im->sy; - - /* 40 byte Windows v3 header */ - info_size = BMP_WINDOWS_V3; - - /* data for the palette */ - if (!im->trueColor) { - info_size += im->colorsTotal * 4; - if (compression) { - bitmap_size = 0; - } - } - - /* bitmap header + info header + data */ - total_size = 14 + info_size + bitmap_size; - - /* write bmp header info */ - gdPutBuf("BM", 2, out); - gdBMPPutInt(out, total_size); - gdBMPPutWord(out, 0); - gdBMPPutWord(out, 0); - gdBMPPutInt(out, 14 + info_size); - - /* write Windows v3 headers */ - gdBMPPutInt(out, BMP_WINDOWS_V3); /* header size */ - gdBMPPutInt(out, im->sx); /* width */ - gdBMPPutInt(out, im->sy); /* height */ - gdBMPPutWord(out, 1); /* colour planes */ - gdBMPPutWord(out, (im->trueColor ? 24 : 8)); /* bit count */ - gdBMPPutInt(out, (compression ? BMP_BI_RLE8 : BMP_BI_RGB)); /* compression */ - gdBMPPutInt(out, bitmap_size); /* image size */ - gdBMPPutInt(out, 0); /* H resolution */ - gdBMPPutInt(out, 0); /* V ressolution */ - gdBMPPutInt(out, im->colorsTotal); /* colours used */ - gdBMPPutInt(out, 0); /* important colours */ - - /* The line must be divisible by 4, else its padded with NULLs */ - padding = ((int)(im->trueColor ? 3 : 1) * im->sx) % 4; - if (padding) { - padding = 4 - padding; - } - - /* 8-bit colours */ - if (!im->trueColor) { - for(i = 0; i< im->colorsTotal; ++i) { - Putchar(gdImageBlue(im, i), out); - Putchar(gdImageGreen(im, i), out); - Putchar(gdImageRed(im, i), out); - Putchar(0, out); - } - - if (compression) { - /* Can potentially change this to X + ((X / 128) * 3) */ - uncompressed_row = uncompressed_row_start = (unsigned char *) gdCalloc(gdImageSX(im) * 2, sizeof(char)); - if (!uncompressed_row) { - /* malloc failed */ - goto cleanup; - } - } - - for (row = (im->sy - 1); row >= 0; row--) { - if (compression) { - memset (uncompressed_row, 0, gdImageSX(im)); - } - - for (xpos = 0; xpos < im->sx; xpos++) { - if (compression) { - *uncompressed_row++ = (unsigned char)gdImageGetPixel(im, xpos, row); - } else { - Putchar(gdImageGetPixel(im, xpos, row), out); - } - } - - if (!compression) { - /* Add padding to make sure we have n mod 4 == 0 bytes per row */ - for (xpos = padding; xpos > 0; --xpos) { - Putchar('\0', out); - } - } else { - int compressed_size = 0; - uncompressed_row = uncompressed_row_start; - if ((compressed_size = compress_row(uncompressed_row, gdImageSX(im))) < 0) { - error = 1; - break; - } - bitmap_size += compressed_size; - - - gdPutBuf(uncompressed_row, compressed_size, out); - Putchar(BMP_RLE_COMMAND, out); - Putchar(BMP_RLE_ENDOFLINE, out); - bitmap_size += 2; - } - } - - if (compression && uncompressed_row) { - gdFree(uncompressed_row); - if (error != 0) { - goto cleanup; - } - /* Update filesize based on new values and set compression flag */ - Putchar(BMP_RLE_COMMAND, out); - Putchar(BMP_RLE_ENDOFBITMAP, out); - bitmap_size += 2; - - /* Write new total bitmap size */ - gdSeek(out, 2); - gdBMPPutInt(out, total_size + bitmap_size); - - /* Total length of image data */ - gdSeek(out, 34); - gdBMPPutInt(out, bitmap_size); - } - - } else { - for (row = (im->sy - 1); row >= 0; row--) { - for (xpos = 0; xpos < im->sx; xpos++) { - pixel = gdImageGetPixel(im, xpos, row); - - Putchar(gdTrueColorGetBlue(pixel), out); - Putchar(gdTrueColorGetGreen(pixel), out); - Putchar(gdTrueColorGetRed(pixel), out); - } - - /* Add padding to make sure we have n mod 4 == 0 bytes per row */ - for (xpos = padding; xpos > 0; --xpos) { - Putchar('\0', out); - } - } - } - - - /* If we needed a tmpfile for compression copy it over to out_original */ - if (tmpfile_for_compression) { - unsigned char* copy_buffer = NULL; - int buffer_size = 0; - - gdSeek(out, 0); - copy_buffer = (unsigned char *) gdMalloc(1024 * sizeof(unsigned char)); - if (copy_buffer == NULL) { - goto cleanup; - } - - while ((buffer_size = gdGetBuf(copy_buffer, 1024, out)) != EOF) { - if (buffer_size == 0) { - break; - } - gdPutBuf(copy_buffer , buffer_size, out_original); - } - gdFree(copy_buffer); - - /* Replace the temp with the original which now has data */ - out->gd_free(out); - out = out_original; - out_original = NULL; - } - -cleanup: - if (tmpfile_for_compression) { -#ifdef _WIN32 - _rmtmp(); -#else - fclose(tmpfile_for_compression); -#endif - tmpfile_for_compression = NULL; - } - - if (out_original) { - out_original->gd_free(out_original); - } - return; -} - -static int compress_row(unsigned char *row, int length) -{ - int rle_type = 0; - int compressed_length = 0; - int pixel = 0, compressed_run = 0, rle_compression = 0; - unsigned char *uncompressed_row = NULL, *uncompressed_rowp = NULL, *uncompressed_start = NULL; - - uncompressed_row = (unsigned char *) gdMalloc(length); - if (!uncompressed_row) { - return -1; - } - - memcpy(uncompressed_row, row, length); - uncompressed_start = uncompressed_rowp = uncompressed_row; - - for (pixel = 0; pixel < length; pixel++) { - if (compressed_run == 0) { - uncompressed_row = uncompressed_rowp; - compressed_run++; - uncompressed_rowp++; - rle_type = BMP_RLE_TYPE_RAW; - continue; - } - - if (compressed_run == 1) { - /* Compare next byte */ - if (memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) { - rle_type = BMP_RLE_TYPE_RLE; - } - } - - if (rle_type == BMP_RLE_TYPE_RLE) { - if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) != 0) { - /* more than what we can store in a single run or run is over due to non match, force write */ - rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row); - row += rle_compression; - compressed_length += rle_compression; - compressed_run = 0; - pixel--; - } else { - compressed_run++; - uncompressed_rowp++; - } - } else { - if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) { - /* more than what we can store in a single run or run is over due to match, force write */ - rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row); - row += rle_compression; - compressed_length += rle_compression; - compressed_run = 0; - pixel--; - } else { - /* add this pixel to the row */ - compressed_run++; - uncompressed_rowp++; - } - - } - } - - if (compressed_run) { - compressed_length += build_rle_packet(row, rle_type, compressed_run, uncompressed_row); - } - - gdFree(uncompressed_start); - - return compressed_length; -} - -static int build_rle_packet(unsigned char *row, int packet_type, int length, unsigned char *data) -{ - int compressed_size = 0; - if (length < 1 || length > 128) { - return 0; - } - - /* Bitmap specific cases is that we can't have uncompressed rows of length 1 or 2 */ - if (packet_type == BMP_RLE_TYPE_RAW && length < 3) { - int i = 0; - for (i = 0; i < length; i++) { - compressed_size += 2; - memset(row, 1, 1); - row++; - - memcpy(row, data++, 1); - row++; - } - } else if (packet_type == BMP_RLE_TYPE_RLE) { - compressed_size = 2; - memset(row, length, 1); - row++; - - memcpy(row, data, 1); - row++; - } else { - compressed_size = 2 + length; - memset(row, BMP_RLE_COMMAND, 1); - row++; - - memset(row, length, 1); - row++; - - memcpy(row, data, length); - row += length; - - /* Must be an even number for an uncompressed run */ - if (length % 2) { - memset(row, 0, 1); - row++; - compressed_size++; - } - } - return compressed_size; -} - -/* - Function: gdImageCreateFromBmp -*/ -BGD_DECLARE(gdImagePtr) gdImageCreateFromBmp(FILE * inFile) -{ - gdImagePtr im = 0; - gdIOCtx *in = gdNewFileCtx(inFile); - if (in == NULL) return NULL; - im = gdImageCreateFromBmpCtx(in); - in->gd_free(in); - return im; -} - -/* - Function: gdImageCreateFromBmpPtr -*/ -BGD_DECLARE(gdImagePtr) gdImageCreateFromBmpPtr(int size, void *data) -{ - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - if (in == NULL) return NULL; - im = gdImageCreateFromBmpCtx(in); - in->gd_free(in); - return im; -} - -/* - Function: gdImageCreateFromBmpCtx -*/ -BGD_DECLARE(gdImagePtr) gdImageCreateFromBmpCtx(gdIOCtxPtr infile) -{ - bmp_hdr_t *hdr; - bmp_info_t *info; - gdImagePtr im = NULL; - int error = 0; - - if (!(hdr= (bmp_hdr_t *)gdCalloc(1, sizeof(bmp_hdr_t)))) { - return NULL; - } - - if (bmp_read_header(infile, hdr)) { - gdFree(hdr); - return NULL; - } - - if (hdr->magic != 0x4d42) { - gdFree(hdr); - return NULL; - } - - if (!(info = (bmp_info_t *)gdCalloc(1, sizeof(bmp_info_t)))) { - gdFree(hdr); - return NULL; - } - - if (bmp_read_info(infile, info)) { - gdFree(hdr); - gdFree(info); - return NULL; - } - - BMP_DEBUG(printf("Numcolours: %d\n", info->numcolors)); - BMP_DEBUG(printf("Width: %d\n", info->width)); - BMP_DEBUG(printf("Height: %d\n", info->height)); - BMP_DEBUG(printf("Planes: %d\n", info->numplanes)); - BMP_DEBUG(printf("Depth: %d\n", info->depth)); - BMP_DEBUG(printf("Offset: %d\n", hdr->off)); - - if (info->depth >= 16) { - im = gdImageCreateTrueColor(info->width, info->height); - } else { - im = gdImageCreate(info->width, info->height); - } - - if (!im) { - gdFree(hdr); - gdFree(info); - return NULL; - } - - switch (info->depth) { - case 1: - BMP_DEBUG(printf("1-bit image\n")); - error = bmp_read_1bit(im, infile, info, hdr); - break; - case 4: - BMP_DEBUG(printf("4-bit image\n")); - error = bmp_read_4bit(im, infile, info, hdr); - break; - case 8: - BMP_DEBUG(printf("8-bit image\n")); - error = bmp_read_8bit(im, infile, info, hdr); - break; - case 16: - case 24: - case 32: - BMP_DEBUG(printf("Direct BMP image\n")); - error = bmp_read_direct(im, infile, info, hdr); - break; - default: - BMP_DEBUG(printf("Unknown bit count\n")); - error = 1; - } - - gdFree(hdr); - gdFree(info); - - if (error) { - gdImageDestroy(im); - return NULL; - } - - return im; -} - -static int bmp_read_header(gdIOCtx *infile, bmp_hdr_t *hdr) -{ - if( - !gdGetWordLSB(&hdr->magic, infile) || - !gdGetIntLSB(&hdr->size, infile) || - !gdGetWordLSB(&hdr->reserved1, infile) || - !gdGetWordLSB(&hdr->reserved2 , infile) || - !gdGetIntLSB(&hdr->off , infile) - ) { - return 1; - } - return 0; -} - -static int bmp_read_info(gdIOCtx *infile, bmp_info_t *info) -{ - /* read BMP length so we can work out the version */ - if (!gdGetIntLSB(&info->len, infile)) { - return 1; - } - - switch (info->len) { - /* For now treat Windows v4 + v5 as v3 */ - case BMP_WINDOWS_V3: - case BMP_WINDOWS_V4: - case BMP_WINDOWS_V5: - BMP_DEBUG(printf("Reading Windows Header\n")); - if (bmp_read_windows_v3_info(infile, info)) { - return 1; - } - break; - case BMP_OS2_V1: - if (bmp_read_os2_v1_info(infile, info)) { - return 1; - } - break; - case BMP_OS2_V2: - if (bmp_read_os2_v2_info(infile, info)) { - return 1; - } - break; - default: - BMP_DEBUG(printf("Unhandled bitmap\n")); - return 1; - } - return 0; -} - -static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info) -{ - if ( - !gdGetIntLSB(&info->width, infile) || - !gdGetIntLSB(&info->height, infile) || - !gdGetWordLSB(&info->numplanes, infile) || - !gdGetWordLSB(&info->depth, infile) || - !gdGetIntLSB(&info->enctype, infile) || - !gdGetIntLSB(&info->size, infile) || - !gdGetIntLSB(&info->hres, infile) || - !gdGetIntLSB(&info->vres, infile) || - !gdGetIntLSB(&info->numcolors, infile) || - !gdGetIntLSB(&info->mincolors, infile) - ) { - return 1; - } - - if (info->height < 0) { - info->topdown = 1; - info->height = -info->height; - } else { - info->topdown = 0; - } - - info->type = BMP_PALETTE_4; - - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) { - return 1; - } - - return 0; -} - -static int bmp_read_os2_v1_info(gdIOCtxPtr infile, bmp_info_t *info) -{ - if ( - !gdGetWordLSB((signed short int *)&info->width, infile) || - !gdGetWordLSB((signed short int *)&info->height, infile) || - !gdGetWordLSB(&info->numplanes, infile) || - !gdGetWordLSB(&info->depth, infile) - ) { - return 1; - } - - /* OS2 v1 doesn't support topdown */ - info->topdown = 0; - - 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) { - return 1; - } - - return 0; -} - -static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info) -{ - char useless_bytes[24]; - if ( - !gdGetIntLSB(&info->width, infile) || - !gdGetIntLSB(&info->height, infile) || - !gdGetWordLSB(&info->numplanes, infile) || - !gdGetWordLSB(&info->depth, infile) || - !gdGetIntLSB(&info->enctype, infile) || - !gdGetIntLSB(&info->size, infile) || - !gdGetIntLSB(&info->hres, infile) || - !gdGetIntLSB(&info->vres, infile) || - !gdGetIntLSB(&info->numcolors, infile) || - !gdGetIntLSB(&info->mincolors, infile) - ) { - return 1; - } - - /* Lets seek the next 24 pointless bytes, we don't care too much about it */ - if (!gdGetBuf(useless_bytes, 24, infile)) { - return 1; - } - - if (info->height < 0) { - info->topdown = 1; - info->height = -info->height; - } else { - info->topdown = 0; - } - - info->type = BMP_PALETTE_4; - - if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 || - info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) { - return 1; - } - - - return 0; -} - -static int bmp_read_direct(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) -{ - int ypos = 0, xpos = 0, row = 0; - int padding = 0, alpha = 0, red = 0, green = 0, blue = 0; - signed short int data = 0; - - switch(info->enctype) { - case BMP_BI_RGB: - /* no-op */ - break; - - case BMP_BI_BITFIELDS: - if (info->depth == 24) { - BMP_DEBUG(printf("Bitfield compression isn't supported for 24-bit\n")); - return 1; - } - BMP_DEBUG(printf("Currently no bitfield support\n")); - return 1; - break; - - case BMP_BI_RLE8: - if (info->depth != 8) { - BMP_DEBUG(printf("RLE is only valid for 8-bit images\n")); - return 1; - } - break; - case BMP_BI_RLE4: - if (info->depth != 4) { - BMP_DEBUG(printf("RLE is only valid for 4-bit images\n")); - return 1; - } - break; - case BMP_BI_JPEG: - case BMP_BI_PNG: - default: - BMP_DEBUG(printf("Unsupported BMP compression format\n")); - return 1; - } - - /* There is a chance the data isn't until later, would be wierd 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)) { - return 1; - } - } - - /* The line must be divisible by 4, else its padded with NULLs */ - padding = ((int)(info->depth / 8) * info->width) % 4; - if (padding) { - padding = 4 - padding; - } - - - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; xpos++) { - if (info->depth == 16) { - if (!gdGetWordLSB(&data, infile)) { - return 1; - } - BMP_DEBUG(printf("Data: %X\n", data)); - red = ((data & 0x7C00) >> 10) << 3; - green = ((data & 0x3E0) >> 5) << 3; - blue = (data & 0x1F) << 3; - BMP_DEBUG(printf("R: %d, G: %d, B: %d\n", red, green, blue)); - } else if (info->depth == 24) { - if (!gdGetByte(&blue, infile) || !gdGetByte(&green, infile) || !gdGetByte(&red, infile)) { - return 1; - } - } else { - if (!gdGetByte(&blue, infile) || !gdGetByte(&green, infile) || !gdGetByte(&red, infile) || !gdGetByte(&alpha, infile)) { - return 1; - } - } - /*alpha = gdAlphaMax - (alpha >> 1);*/ - gdImageSetPixel(im, xpos, row, gdTrueColor(red, green, blue)); - } - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&red, infile)) { - return 1; - } - } - } - - return 0; -} - -static int bmp_read_palette(gdImagePtr im, gdIOCtxPtr infile, int count, int read_four) -{ - int i; - int r, g, b, z; - - for (i = 0; i < count; i++) { - if ( - !gdGetByte(&b, infile) || - !gdGetByte(&g, infile) || - !gdGetByte(&r, infile) || - (read_four && !gdGetByte(&z, infile)) - ) { - return 1; - } - im->red[i] = r; - im->green[i] = g; - im->blue[i] = b; - im->open[i] = 1; - } - return 0; -} - -static int bmp_read_1bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) -{ - int ypos = 0, xpos = 0, row = 0, index = 0; - int padding = 0, current_byte = 0, bit = 0; - - if (info->enctype != BMP_BI_RGB) { - return 1; - } - - if (!info->numcolors) { - info->numcolors = 2; - } else if (info->numcolors < 0 || info->numcolors > 2) { - return 1; - } - - if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { - return 1; - } - - im->colorsTotal = info->numcolors; - - /* There is a chance the data isn't until later, would be wierd 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)) { - return 1; - } - } - - /* The line must be divisible by 4, else its padded with NULLs */ - padding = ((int)ceil(0.1 * info->width)) % 4; - if (padding) { - padding = 4 - padding; - } - - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; xpos += 8) { - /* Bitmaps are always aligned in bytes so we'll never overflow */ - if (!gdGetByte(¤t_byte, infile)) { - return 1; - } - - for (bit = 0; bit < 8; bit++) { - index = ((current_byte & (0x80 >> bit)) != 0 ? 0x01 : 0x00); - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos + bit, row, index); - /* No need to read anything extra */ - if ((xpos + bit) >= info->width) { - break; - } - } - } - - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - } - } - return 0; -} - -static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) -{ - int ypos = 0, xpos = 0, row = 0, index = 0; - int padding = 0, current_byte = 0; - - if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE4) { - return 1; - } - - if (!info->numcolors) { - info->numcolors = 16; - } else if (info->numcolors < 0 || info->numcolors > 16) { - return 1; - } - - if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { - return 1; - } - - im->colorsTotal = info->numcolors; - - /* There is a chance the data isn't until later, would be wierd 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)) { - return 1; - } - } - - /* The line must be divisible by 4, else its padded with NULLs */ - padding = ((int)ceil(0.5 * info->width)) % 4; - if (padding) { - padding = 4 - padding; - } - - switch (info->enctype) { - case BMP_BI_RGB: - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; xpos += 2) { - if (!gdGetByte(¤t_byte, infile)) { - return 1; - } - - index = (current_byte >> 4) & 0x0f; - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos, row, index); - - /* This condition may get called often, potential optimsations */ - if (xpos >= info->width) { - break; - } - - index = current_byte & 0x0f; - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos + 1, row, index); - } - - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - } - } - break; - - case BMP_BI_RLE4: - if (bmp_read_rle(im, infile, info)) { - return 1; - } - break; - - default: - return 1; - } - return 0; -} - -static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header) -{ - int ypos = 0, xpos = 0, row = 0, index = 0; - int padding = 0; - - if (info->enctype != BMP_BI_RGB && info->enctype != BMP_BI_RLE8) { - return 1; - } - - if (!info->numcolors) { - info->numcolors = 256; - } else if (info->numcolors < 0 || info->numcolors > 256) { - return 1; - } - - if (bmp_read_palette(im, infile, info->numcolors, (info->type == BMP_PALETTE_4))) { - return 1; - } - - im->colorsTotal = info->numcolors; - - /* There is a chance the data isn't until later, would be wierd 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)) { - return 1; - } - } - - /* The line must be divisible by 4, else its padded with NULLs */ - padding = (1 * info->width) % 4; - if (padding) { - padding = 4 - padding; - } - - switch (info->enctype) { - case BMP_BI_RGB: - for (ypos = 0; ypos < info->height; ++ypos) { - if (info->topdown) { - row = ypos; - } else { - row = info->height - ypos - 1; - } - - for (xpos = 0; xpos < info->width; ++xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos, row, index); - } - /* Could create a new variable, but it isn't really worth it */ - for (xpos = padding; xpos > 0; --xpos) { - if (!gdGetByte(&index, infile)) { - return 1; - } - } - } - break; - - case BMP_BI_RLE8: - if (bmp_read_rle(im, infile, info)) { - return 1; - } - break; - - default: - return 1; - } - return 0; -} - -static int bmp_read_rle(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info) -{ - int ypos = 0, xpos = 0, row = 0, index = 0; - int rle_length = 0, rle_data = 0; - int padding = 0; - int i = 0, j = 0; - int pixels_per_byte = 8 / info->depth; - - for (ypos = 0; ypos < info->height && xpos <= info->width;) { - if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) { - return 1; - } - row = info->height - ypos - 1; - - if (rle_length != BMP_RLE_COMMAND) { - if (im->open[rle_data]) { - im->open[rle_data] = 0; - } - - for (i = 0; (i < rle_length) && (xpos < info->width);) { - for (j = 1; (j <= pixels_per_byte) && (xpos < info->width) && (i < rle_length); j++, xpos++, i++) { - index = (rle_data & (((1 << info->depth) - 1) << (8 - (j * info->depth)))) >> (8 - (j * info->depth)); - if (im->open[index]) { - im->open[index] = 0; - } - gdImageSetPixel(im, xpos, row, index); - } - } - } else if (rle_length == BMP_RLE_COMMAND && rle_data > 2) { - /* Uncompressed RLE needs to be even */ - padding = 0; - for (i = 0; (i < rle_data) && (xpos < info->width); i += pixels_per_byte) { - int max_pixels = pixels_per_byte; - - if (!gdGetByte(&index, infile)) { - return 1; - } - padding++; - - if (rle_data - i < max_pixels) { - max_pixels = rle_data - i; - } - - for (j = 1; (j <= max_pixels) && (xpos < info->width); j++, xpos++) { - int temp = (index >> (8 - (j * info->depth))) & ((1 << info->depth) - 1); - if (im->open[temp]) { - im->open[temp] = 0; - } - gdImageSetPixel(im, xpos, row, temp); - } - } - - /* Make sure the bytes read are even */ - if (padding % 2 && !gdGetByte(&index, infile)) { - return 1; - } - } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFLINE) { - /* Next Line */ - xpos = 0; - ypos++; - } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_DELTA) { - /* Delta Record, used for bmp files that contain other data*/ - if (!gdGetByte(&rle_length, infile) || !gdGetByte(&rle_data, infile)) { - return 1; - } - xpos += rle_length; - ypos += rle_data; - } else if (rle_length == BMP_RLE_COMMAND && rle_data == BMP_RLE_ENDOFBITMAP) { - /* End of bitmap */ - break; - } - } - return 0; -} diff --git a/src/gd_color_match.c b/src/gd_color_match.c index a94a841..f0842b6 100755 --- a/src/gd_color_match.c +++ b/src/gd_color_match.c @@ -31,8 +31,8 @@ BGD_DECLARE(int) gdImageColorMatch (gdImagePtr im1, gdImagePtr im2) return -4; /* At least 1 color must be allocated */ } - buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * gdMaxColors); - memset (buf, 0, sizeof(unsigned long) * 5 * gdMaxColors ); + buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * im2->colorsTotal); + memset (buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal ); for (x=0; x < im1->sx; x++) { for( y=0; ysy; y++ ) { diff --git a/src/gd_gif_in.c b/src/gd_gif_in.c index db4a973..c195448 100755 --- a/src/gd_gif_in.c +++ b/src/gd_gif_in.c @@ -335,6 +335,11 @@ terminated: return 0; } + if(!im->colorsTotal) { + gdImageDestroy(im); + return 0; + } + /* Check for open colors at the end, so * we can reduce colorsTotal and ultimately * BitsPerPixel */ @@ -346,11 +351,6 @@ terminated: } } - if(!im->colorsTotal) { - gdImageDestroy(im); - return 0; - } - return im; } @@ -447,7 +447,7 @@ static int GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) { int i, j, ret; - int count; + unsigned char count; if(flag) { scd->curbit = 0; diff --git a/src/gd_gif_in.c.upstream b/src/gd_gif_in.c.upstream deleted file mode 100755 index c195448..0000000 --- a/src/gd_gif_in.c.upstream +++ /dev/null @@ -1,751 +0,0 @@ -/** - * File: GIF Input - * - * Read GIF images. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include "gd.h" - -/* Used only when debugging GIF compression code */ -/* #define DEBUGGING_ENVARS */ - -#ifdef DEBUGGING_ENVARS - -static int verbose_set = 0; -static int verbose; - -#define VERBOSE (verbose_set ? verbose : set_verbose()) - -static int set_verbose(void) -{ - verbose = !!getenv("GIF_VERBOSE"); - verbose_set = 1; - return(verbose); -} - -#else - -#define VERBOSE 0 - -#endif - -#define MAXCOLORMAPSIZE 256 - -#define TRUE 1 -#define FALSE 0 - -#define CM_RED 0 -#define CM_GREEN 1 -#define CM_BLUE 2 - -#define MAX_LWZ_BITS 12 - -#define INTERLACE 0x40 -#define LOCALCOLORMAP 0x80 - -#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) - -#define ReadOK(file, buffer, len) (gdGetBuf(buffer, len, file) > 0) - -#define LM_to_uint(a, b) (((b)<<8)|(a)) - -/* We may eventually want to use this information, but def it out for now */ -#if 0 -static struct { - unsigned int Width; - unsigned int Height; - unsigned char ColorMap[3][MAXCOLORMAPSIZE]; - unsigned int BitPixel; - unsigned int ColorResolution; - unsigned int Background; - unsigned int AspectRatio; -} GifScreen; -#endif - -#if 0 -static struct { - int transparent; - int delayTime; - int inputFlag; - int disposal; -} Gif89 = { -1, -1, -1, 0 }; -#endif - -#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) - -#define CSD_BUF_SIZE 280 - -typedef struct { - unsigned char buf[CSD_BUF_SIZE]; - int curbit; - int lastbit; - int done; - int last_byte; -} CODE_STATIC_DATA; - -typedef struct { - int fresh; - int code_size, set_code_size; - int max_code, max_code_size; - int firstcode, oldcode; - int clear_code, end_code; - int table[2][(1<< MAX_LWZ_BITS)]; - int stack[STACK_SIZE], *sp; - CODE_STATIC_DATA scd; -} LZW_STATIC_DATA; - -static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); -static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP); -static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP); -static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP); -static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP); - -static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */ - -/* - Function: gdImageCreateFromGif - - is called to load images from GIF format - files. Invoke with an already opened - pointer to a file containing the desired - image. - - returns a to the new image, or - NULL if unable to load the image (most often because the file is - corrupt or does not contain a GIF image). - does not close the file. You can inspect the sx and sy members of - the image to determine its size. The image must eventually be - destroyed using . - - Variants: - - creates an image from GIF data (i.e. the - contents of a GIF file) already in memory. - - reads in an image using the functions in - a struct. - - Parameters: - - infile - The input FILE pointer - - Returns: - - A pointer to the new image or NULL if an error occurred. - - Example: - - > gdImagePtr im; - > ... inside a function ... - > FILE *in; - > in = fopen("mygif.gif", "rb"); - > im = gdImageCreateFromGif(in); - > fclose(in); - > // ... Use the image ... - > gdImageDestroy(im); - -*/ -BGD_DECLARE(gdImagePtr) gdImageCreateFromGif(FILE *fdFile) -{ - gdIOCtx *fd = gdNewFileCtx(fdFile); - gdImagePtr im; - - if (fd == NULL) return NULL; - im = gdImageCreateFromGifCtx(fd); - - fd->gd_free(fd); - - return im; -} - -/* - Function: gdImageCreateFromGifPtr - - Parameters: - - size - size of GIF data in bytes. - data - GIF data (i.e. contents of a GIF file). - - See . -*/ -BGD_DECLARE(gdImagePtr) gdImageCreateFromGifPtr (int size, void *data) -{ - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); - if(!in) { - return 0; - } - im = gdImageCreateFromGifCtx(in); - in->gd_free(in); - return im; -} - -/* - Function: gdImageCreateFromGifCtx - - See . -*/ -BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd) -{ - int BitPixel; -#if 0 - int ColorResolution; - int Background; - int AspectRatio; -#endif - int Transparent = (-1); - unsigned char buf[16]; - unsigned char c; - unsigned char ColorMap[3][MAXCOLORMAPSIZE]; - unsigned char localColorMap[3][MAXCOLORMAPSIZE]; - int imw, imh, screen_width, screen_height; - int useGlobalColormap; - int bitPixel, i; - /*1.4//int imageCount = 0; */ - /* 2.0.28: threadsafe storage */ - int ZeroDataBlock = FALSE; - int haveGlobalColormap; - - gdImagePtr im = 0; - - memset(ColorMap, 0, 3 * MAXCOLORMAPSIZE); - memset(localColorMap, 0, 3 * MAXCOLORMAPSIZE); - - if(!ReadOK(fd, buf, 6)) { - return 0; - } - - if(strncmp((char *)buf, "GIF", 3) != 0) { - return 0; - } - - if(memcmp((char *)buf + 3, "87a", 3) == 0) { - /* GIF87a */ - } else if(memcmp((char *)buf + 3, "89a", 3) == 0) { - /* GIF89a */ - } else { - return 0; - } - - if(!ReadOK(fd, buf, 7)) { - return 0; - } - - BitPixel = 2 << (buf[4] & 0x07); -#if 0 - ColorResolution = (int) (((buf[4]&0x70)>>3)+1); - Background = buf[5]; - AspectRatio = buf[6]; -#endif - screen_width = imw = LM_to_uint(buf[0], buf[1]); - screen_height = imh = LM_to_uint(buf[2], buf[3]); - - haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */ - if(haveGlobalColormap) { - if(ReadColorMap(fd, BitPixel, ColorMap)) { - return 0; - } - } - - for (;;) { - int top, left; - int width, height; - - if(!ReadOK(fd, &c, 1)) { - return 0; - } - - if (c == ';') { /* GIF terminator */ - goto terminated; - } - - if(c == '!') { /* Extension */ - if(!ReadOK(fd, &c, 1)) { - return 0; - } - - DoExtension(fd, c, &Transparent, &ZeroDataBlock); - continue; - } - - if(c != ',') { /* Not a valid start character */ - continue; - } - - /*1.4//++imageCount; */ - - if(!ReadOK(fd, buf, 9)) { - return 0; - } - - useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP); - - bitPixel = 1 << ((buf[8] & 0x07) + 1); - left = LM_to_uint(buf[0], buf[1]); - top = LM_to_uint(buf[2], buf[3]); - width = LM_to_uint(buf[4], buf[5]); - height = LM_to_uint(buf[6], buf[7]); - - if(((left + width) > screen_width) || ((top + height) > screen_height)) { - if(VERBOSE) { - printf("Frame is not confined to screen dimension.\n"); - } - return 0; - } - - if(!(im = gdImageCreate(width, height))) { - return 0; - } - - im->interlace = BitSet(buf[8], INTERLACE); - if(!useGlobalColormap) { - if(ReadColorMap(fd, bitPixel, localColorMap)) { - gdImageDestroy(im); - return 0; - } - - ReadImage(im, fd, width, height, localColorMap, BitSet(buf[8], INTERLACE), &ZeroDataBlock); - } else { - if(!haveGlobalColormap) { - gdImageDestroy(im); - return 0; - } - - ReadImage(im, fd, width, height, ColorMap, BitSet(buf[8], INTERLACE), &ZeroDataBlock); - } - - if(Transparent != (-1)) { - gdImageColorTransparent(im, Transparent); - } - - goto terminated; - } - -terminated: - /* Terminator before any image was declared! */ - if(!im) { - return 0; - } - - if(!im->colorsTotal) { - gdImageDestroy(im); - return 0; - } - - /* Check for open colors at the end, so - * we can reduce colorsTotal and ultimately - * BitsPerPixel */ - for(i = im->colorsTotal - 1; i >= 0; i--) { - if(im->open[i]) { - im->colorsTotal--; - } else { - break; - } - } - - return im; -} - -static int -ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) -{ - int i; - unsigned char rgb[3]; - - for(i = 0; i < number; ++i) { - if(!ReadOK(fd, rgb, sizeof(rgb))) { - return TRUE; - } - - buffer[CM_RED][i] = rgb[0]; - buffer[CM_GREEN][i] = rgb[1]; - buffer[CM_BLUE][i] = rgb[2]; - } - - return FALSE; -} - -static int -DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP) -{ - unsigned char buf[256]; - - switch(label) { - case 0xf9: /* Graphic Control Extension */ - memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */ - (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP); -#if 0 - Gif89.disposal = (buf[0] >> 2) & 0x7; - Gif89.inputFlag = (buf[0] >> 1) & 0x1; - Gif89.delayTime = LM_to_uint(buf[1], buf[2]); -#endif - if((buf[0] & 0x1) != 0) { - *Transparent = buf[3]; - } - - while(GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0); - - return FALSE; - - default: - break; - } - - while(GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0); - - return FALSE; -} - -static int -GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) -{ - unsigned char count; - - if(!ReadOK(fd, &count, 1)) { - return -1; - } - - *ZeroDataBlockP = count == 0; - - if((count != 0) && (!ReadOK(fd, buf, count))) { - return -1; - } - - return count; -} - -static int -GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) -{ - int rv, i; - - rv = GetDataBlock_(fd,buf, ZeroDataBlockP); - - if(VERBOSE) { - printf("[GetDataBlock returning %d",rv); - if(rv > 0) { - printf(":"); - for(i = 0; i < rv; i++) { - printf(" %02x",buf[i]); - } - } - printf("]\n"); - } - - return rv; -} - -static int -GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) -{ - int i, j, ret; - unsigned char count; - - if(flag) { - scd->curbit = 0; - scd->lastbit = 0; - scd->last_byte = 2; - scd->done = FALSE; - return 0; - } - - if((scd->curbit + code_size) >= scd->lastbit) { - if(scd->done) { - if(scd->curbit >= scd->lastbit) { - /* Oh well */ - } - return -1; - } - - scd->buf[0] = scd->buf[scd->last_byte - 2]; - scd->buf[1] = scd->buf[scd->last_byte - 1]; - - if((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0) { - scd->done = TRUE; - } - - scd->last_byte = 2 + count; - scd->curbit = (scd->curbit - scd->lastbit) + 16; - scd->lastbit = (2 + count) * 8; - } - - if ((scd->curbit + code_size - 1) >= (CSD_BUF_SIZE * 8)) { - ret = -1; - } else { - ret = 0; - for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) { - ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j; - } - } - - scd->curbit += code_size; - - return ret; -} - -static int -GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP) -{ - int rv; - - rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP); - - if(VERBOSE) { - printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv); - } - - return rv; -} - -static int -LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) -{ - int code, incode, i; - - if(flag) { - sd->set_code_size = input_code_size; - sd->code_size = sd->set_code_size + 1; - sd->clear_code = 1 << sd->set_code_size; - sd->end_code = sd->clear_code + 1; - sd->max_code_size = 2 * sd->clear_code; - sd->max_code = sd->clear_code + 2; - - GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP); - - sd->fresh = TRUE; - - for(i = 0; i < sd->clear_code; ++i) { - sd->table[0][i] = 0; - sd->table[1][i] = i; - } - - for(; i < (1 << MAX_LWZ_BITS); ++i) { - sd->table[0][i] = sd->table[1][0] = 0; - } - - sd->sp = sd->stack; - - return 0; - - } else if(sd->fresh) { - sd->fresh = FALSE; - - do { - sd->firstcode = sd->oldcode = - GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); - } while(sd->firstcode == sd->clear_code); - - return sd->firstcode; - } - - if(sd->sp > sd->stack) { - return *--sd->sp; - } - - while((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) { - if(code == sd->clear_code) { - for(i = 0; i < sd->clear_code; ++i) { - sd->table[0][i] = 0; - sd->table[1][i] = i; - } - - for (; i < (1 << MAX_LWZ_BITS); ++i) { - sd->table[0][i] = sd->table[1][i] = 0; - } - - sd->code_size = sd->set_code_size + 1; - sd->max_code_size = 2 * sd->clear_code; - sd->max_code = sd->clear_code + 2; - sd->sp = sd->stack; - sd->firstcode = sd->oldcode = - GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP); - - return sd->firstcode; - } else if(code == sd->end_code) { - int count; - unsigned char buf[260]; - - if(*ZeroDataBlockP) { - return -2; - } - - while((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0); - - if(count != 0) { - return -2; - } - } - - incode = code; - - if(sd->sp == (sd->stack + STACK_SIZE)) { - /* Bad compressed data stream */ - return -1; - } - - if(code >= sd->max_code) { - *sd->sp++ = sd->firstcode; - code = sd->oldcode; - } - - while(code >= sd->clear_code) { - if(sd->sp == (sd->stack + STACK_SIZE)) { - /* Bad compressed data stream */ - return -1; - } - - *sd->sp++ = sd->table[1][code]; - - if(code == sd->table[0][code]) { - /* Oh well */ - } - - code = sd->table[0][code]; - } - - *sd->sp++ = sd->firstcode = sd->table[1][code]; - - if((code = sd->max_code) < (1 << MAX_LWZ_BITS)) { - sd->table[0][code] = sd->oldcode; - sd->table[1][code] = sd->firstcode; - ++sd->max_code; - - if((sd->max_code >= sd->max_code_size) && (sd->max_code_size < (1<max_code_size *= 2; - ++sd->code_size; - } - } - - sd->oldcode = incode; - - if(sd->sp > sd->stack) { - return *--sd->sp; - } - } - - return code; -} - -static int -LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP) -{ - int rv; - - rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP); - - if(VERBOSE) { - printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv); - } - - return rv; -} - -static void -ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */ -{ - unsigned char c; - int xpos = 0, ypos = 0, pass = 0; - int v, i; - LZW_STATIC_DATA sd; - - /* Initialize the Compression routines */ - if(!ReadOK(fd, &c, 1)) { - return; - } - - if(c > MAX_LWZ_BITS) { - return; - } - - /* Stash the color map into the image */ - for(i=0; (i < gdMaxColors); i++) { - im->red[i] = cmap[CM_RED][i]; - im->green[i] = cmap[CM_GREEN][i]; - im->blue[i] = cmap[CM_BLUE][i]; - im->open[i] = 1; - } - - /* Many (perhaps most) of these colors will remain marked open. */ - im->colorsTotal = gdMaxColors; - if(LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) { - return; - } - - /* - ** If this is an "uninteresting picture" ignore it. - ** REMOVED For 1.4 - */ - /*if (ignore) { */ - /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */ - /* ; */ - /* return; */ - /*} */ - - while((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) { - if(v >= gdMaxColors) { - v = 0; - } - - /* This how we recognize which colors are actually used. */ - if(im->open[v]) { - im->open[v] = 0; - } - - gdImageSetPixel(im, xpos, ypos, v); - - ++xpos; - if(xpos == len) { - xpos = 0; - if(interlace) { - switch (pass) { - case 0: - case 1: - ypos += 8; - break; - case 2: - ypos += 4; - break; - case 3: - ypos += 2; - break; - } - - if(ypos >= height) { - ++pass; - switch (pass) { - case 1: - ypos = 4; - break; - case 2: - ypos = 2; - break; - case 3: - ypos = 1; - break; - default: - goto fini; - } - } - } else { - ++ypos; - } - } - - if(ypos >= height) { - break; - } - } - -fini: - if(LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) { - /* Ignore extra */ - } -} diff --git a/src/gd_gif_out.c b/src/gd_gif_out.c index 4a05c09..6fe707d 100755 --- a/src/gd_gif_out.c +++ b/src/gd_gif_out.c @@ -99,7 +99,7 @@ static void char_init(GifCtx *ctx); static void char_out(int c, GifCtx *ctx); static void flush_char(GifCtx *ctx); -static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out); + /* @@ -131,11 +131,8 @@ BGD_DECLARE(void *) gdImageGifPtr(gdImagePtr im, int *size) void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); if (out == NULL) return NULL; - if (!_gdImageGifCtx(im, out)) { - rv = gdDPExtractData(out, size); - } else { - rv = NULL; - } + gdImageGifCtx(im, out); + rv = gdDPExtractData(out, size); out->gd_free(out); return rv; } @@ -224,12 +221,6 @@ BGD_DECLARE(void) gdImageGif(gdImagePtr im, FILE *outFile) */ BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) { - _gdImageGifCtx(im, out); -} - -/* returns 0 on success, 1 on failure */ -static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) -{ gdImagePtr pim = 0, tim = im; int interlace, BitsPerPixel; interlace = im->interlace; @@ -240,7 +231,7 @@ static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) based temporary image. */ pim = gdImageCreatePaletteFromTrueColor(im, 1, 256); if(!pim) { - return 1; + return; } tim = pim; } @@ -256,8 +247,6 @@ static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) /* Destroy palette based temporary image. */ gdImageDestroy( pim); } - - return 0; } diff --git a/src/gd_jpeg.c b/src/gd_jpeg.c index bd8fc27..271ef46 100755 --- a/src/gd_jpeg.c +++ b/src/gd_jpeg.c @@ -123,8 +123,6 @@ static void fatal_jpeg_error(j_common_ptr cinfo) exit(99); } -static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality); - /* * Write IM to OUTFILE as a JFIF-formatted JPEG image, using quality * QUALITY. If QUALITY is in the range 0-100, increasing values @@ -239,11 +237,8 @@ BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality) void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); if (out == NULL) return NULL; - if (!_gdImageJpegCtx(im, out, quality)) { - rv = gdDPExtractData(out, size); - } else { - rv = NULL; - } + gdImageJpegCtx(im, out, quality); + rv = gdDPExtractData(out, size); out->gd_free(out); return rv; } @@ -265,12 +260,6 @@ void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile); */ BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) { - _gdImageJpegCtx(im, outfile, quality); -} - -/* returns 0 on success, 1 on failure */ -static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) -{ struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int i, j, jidx; @@ -304,7 +293,7 @@ static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) if(row) { gdFree(row); } - return 1; + return; } cinfo.err->emit_message = jpeg_emit_message; @@ -345,7 +334,7 @@ static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) if(row == 0) { gd_error("gd-jpeg: error: unable to allocate JPEG row structure: gdCalloc returns NULL\n"); jpeg_destroy_compress(&cinfo); - return 1; + return; } rowptr[0] = row; @@ -422,7 +411,6 @@ static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); gdFree(row); - return 0; } diff --git a/src/gd_wbmp.c b/src/gd_wbmp.c index 341ff6e..0028273 100755 --- a/src/gd_wbmp.c +++ b/src/gd_wbmp.c @@ -88,8 +88,6 @@ int gd_getin(void *in) return (gdGetC((gdIOCtx *)in)); } -static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); - /* Function: gdImageWBMPCtx @@ -103,19 +101,13 @@ static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); */ BGD_DECLARE(void) gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out) { - _gdImageWBMPCtx(image, fg, out); -} - -/* returns 0 on success, 1 on failure */ -static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out) -{ int x, y, pos; Wbmp *wbmp; /* create the WBMP */ if((wbmp = createwbmp(gdImageSX(image), gdImageSY(image), WBMP_WHITE)) == NULL) { gd_error("Could not create WBMP\n"); - return 1; + return; } /* fill up the WBMP structure */ @@ -131,15 +123,11 @@ static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out) /* write the WBMP to a gd file descriptor */ if(writewbmp(wbmp, &gd_putout, out)) { - freewbmp(wbmp); gd_error("Could not save WBMP\n"); - return 1; } /* des submitted this bugfix: gdFree the memory. */ freewbmp(wbmp); - - return 0; } /* @@ -283,11 +271,8 @@ BGD_DECLARE(void *) gdImageWBMPPtr(gdImagePtr im, int *size, int fg) void *rv; gdIOCtx *out = gdNewDynamicCtx(2048, NULL); if (out == NULL) return NULL; - if (!_gdImageWBMPCtx(im, fg, out)) { - rv = gdDPExtractData(out, size); - } else { - rv = NULL; - } + gdImageWBMPCtx(im, fg, out); + rv = gdDPExtractData(out, size); out->gd_free(out); return rv; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6979416..7eef4bf 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,7 +31,6 @@ if (BUILD_TEST) gdimagecolordeallocate gdimagecolorexact gdimagecolorreplace - gdimagecolormatch gdimagecolorresolve gdimagecolortransparent gdimagecontrast diff --git a/tests/Makefile.am b/tests/Makefile.am index 1a44112..5f8b624 100755 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,7 +26,6 @@ include gdimagecolorclosest/Makemodule.am include gdimagecolordeallocate/Makemodule.am include gdimagecolorexact/Makemodule.am include gdimagecolorreplace/Makemodule.am -include gdimagecolormatch/Makemodule.am include gdimagecolorresolve/Makemodule.am include gdimagecolortransparent/Makemodule.am include gdimagecontrast/Makemodule.am diff --git a/tests/gdimageclone/style.c b/tests/gdimageclone/style.c deleted file mode 100644 index c2b246e..0000000 --- a/tests/gdimageclone/style.c +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Cloning an image should exactly reproduce all style related data - */ - - -#include -#include "gd.h" -#include "gdtest.h" - - -int main() -{ - gdImagePtr im, clone; - int style[] = {0, 0, 0}; - - im = gdImageCreate(8, 8); - gdImageSetStyle(im, style, sizeof(style)/sizeof(style[0])); - - clone = gdImageClone(im); - gdTestAssert(clone != NULL); - - gdTestAssert(clone->styleLength == im->styleLength); - gdTestAssert(clone->stylePos == im->stylePos); - gdTestAssert(!memcmp(clone->style, im->style, sizeof(style)/sizeof(style[0]))); - - gdImageDestroy(clone); - gdImageDestroy(im); - - return gdNumFailures(); -} diff --git a/tests/gdimagecolormatch/CMakeLists.txt b/tests/gdimagecolormatch/CMakeLists.txt deleted file mode 100644 index 591938f..0000000 --- a/tests/gdimagecolormatch/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -LIST(APPEND TESTS_FILES - cve_2019_6977 -) - -ADD_GD_TESTS() diff --git a/tests/gdimagecolormatch/Makemodule.am b/tests/gdimagecolormatch/Makemodule.am deleted file mode 100644 index e8e09a9..0000000 --- a/tests/gdimagecolormatch/Makemodule.am +++ /dev/null @@ -1,5 +0,0 @@ -libgd_test_programs += \ - gdimagecolormatch/cve_2019_6977 - -EXTRA_DIST += \ - gdimagecolormatch/CMakeLists.txt diff --git a/tests/gdimagecolormatch/cve_2019_6977.c b/tests/gdimagecolormatch/cve_2019_6977.c deleted file mode 100644 index fdd7af5..0000000 --- a/tests/gdimagecolormatch/cve_2019_6977.c +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Test for CVE-2019-6977 - */ - -#include "gd.h" - -int main() -{ - gdImagePtr im1; - gdImagePtr im2; - - im1 = gdImageCreateTrueColor(0xfff, 0xfff); - im2 = gdImageCreate(0xfff, 0xfff); - if (gdImageColorAllocate(im2, 0, 0, 0) < 0) - { - gdImageDestroy(im1); - gdImageDestroy(im2); - return 1; - } - gdImageSetPixel(im2, 0, 0, 255); - gdImageColorMatch(im1, im2); - gdImageDestroy(im1); - gdImageDestroy(im2); - return 0; -} diff --git a/tests/jpeg/CMakeLists.txt b/tests/jpeg/CMakeLists.txt index a8d8162..19964b0 100755 --- a/tests/jpeg/CMakeLists.txt +++ b/tests/jpeg/CMakeLists.txt @@ -2,7 +2,6 @@ IF(JPEG_FOUND) LIST(APPEND TESTS_FILES jpeg_empty_file jpeg_im2im - jpeg_ptr_double_free jpeg_null ) diff --git a/tests/jpeg/Makemodule.am b/tests/jpeg/Makemodule.am index b89e169..7e5d317 100755 --- a/tests/jpeg/Makemodule.am +++ b/tests/jpeg/Makemodule.am @@ -2,8 +2,7 @@ if HAVE_LIBJPEG libgd_test_programs += \ jpeg/jpeg_empty_file \ jpeg/jpeg_im2im \ - jpeg/jpeg_null \ - jpeg/jpeg_ptr_double_free + jpeg/jpeg_null if HAVE_LIBPNG libgd_test_programs += \ diff --git a/tests/jpeg/jpeg_ptr_double_free.c b/tests/jpeg/jpeg_ptr_double_free.c deleted file mode 100644 index c80aeb6..0000000 --- a/tests/jpeg/jpeg_ptr_double_free.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Test that failure to convert to JPEG returns NULL - * - * We are creating an image, set its width to zero, and pass this image to - * `gdImageJpegPtr()` which is supposed to fail, and as such should return NULL. - * - * See also - */ - - -#include "gd.h" -#include "gdtest.h" - - -int main() -{ - gdImagePtr src, dst; - int size; - - src = gdImageCreateTrueColor(1, 10); - gdTestAssert(src != NULL); - - src->sx = 0; /* this hack forces gdImageJpegPtr() to fail */ - - dst = gdImageJpegPtr(src, &size, 0); - gdTestAssert(dst == NULL); - - gdImageDestroy(src); - - return gdNumFailures(); -} \ No newline at end of file