diff --git a/NEWS b/NEWS index 50402e8411d..ef7507d0881 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,9 @@ PHP NEWS - Date: . Fixed #69044 (discrepency between time and microtime). (krakjoe) +- GD: + . Added TGA read support. (cmb) + - Opcache: . Fixed bug #78106 (Path resolution fails if opcache disabled during request). (Nikita) diff --git a/UPGRADING b/UPGRADING index 4acfa3e7755..be14f0699be 100644 --- a/UPGRADING +++ b/UPGRADING @@ -354,6 +354,12 @@ PHP 7.4 UPGRADE NOTES exception that it ignores overloaded array casts, such as used by ArrayObject. +- GD: + . Added imagecreatefromtga() function, which allows to read images in TGA + format. TGA support is now also indicated by gd_info() and imagetypes(). + Note that TGA images are not recognized by imagecreatefromstring() and + getimagesize(). + - OpenSSL: . Added openssl_x509_verify(mixed cert, mixed key) function that verifies the signature of the certificate using a public key. A wrapper around the diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index a13313c8e86..742ed412cdb 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -126,6 +126,7 @@ AC_DEFUN([PHP_GD_CHECK_VERSION],[ PHP_CHECK_LIBRARY(gd, gdImageCreateFromJpeg, [AC_DEFINE(HAVE_GD_JPG, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdImageCreateFromXpm, [AC_DEFINE(HAVE_GD_XPM, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdImageCreateFromBmp, [AC_DEFINE(HAVE_GD_BMP, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) + PHP_CHECK_LIBRARY(gd, gdImageCreateFromTga, [AC_DEFINE(HAVE_GD_TGA, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdImageStringFT, [AC_DEFINE(HAVE_GD_FREETYPE, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdVersionString, [AC_DEFINE(HAVE_GD_LIBVERSION, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) ]) @@ -146,7 +147,7 @@ if test "$PHP_GD" != "no"; then libgd/gd_topal.c libgd/gd_gif_in.c libgd/gd_xbm.c libgd/gd_gif_out.c libgd/gd_security.c \ libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_rotate.c libgd/gd_color_match.c \ libgd/gd_transform.c libgd/gd_crop.c libgd/gd_interpolation.c libgd/gd_matrix.c \ - libgd/gd_bmp.c" + libgd/gd_bmp.c libgd/gd_tga.c" dnl check for fabsf and floorf which are available since C99 AC_CHECK_FUNCS(fabsf floorf) @@ -155,6 +156,7 @@ dnl These are always available with bundled library AC_DEFINE(HAVE_GD_BUNDLED, 1, [ ]) AC_DEFINE(HAVE_GD_PNG, 1, [ ]) AC_DEFINE(HAVE_GD_BMP, 1, [ ]) + AC_DEFINE(HAVE_GD_TGA, 1, [ ]) dnl Various checks for GD features PHP_GD_ZLIB diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index bd73f572d35..6695976d0e2 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -40,7 +40,7 @@ if (PHP_GD != "no") { gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \ gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c gd_xbm.c gd_security.c gd_transform.c \ gd_filter.c gd_pixelate.c gd_rotate.c gd_color_match.c gd_webp.c \ - gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c", "gd"); + gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c gd_tga.c", "gd"); AC_DEFINE('HAVE_LIBGD', 1, 'GD support'); ADD_FLAG("CFLAGS_GD", " \ /D HAVE_GD_DYNAMIC_CTX_EX=1 \ @@ -63,6 +63,7 @@ if (PHP_GD != "no") { /D HAVE_GD_XPM \ /D HAVE_GD_FREETYPE=1 \ /D HAVE_GD_BMP \ +/D HAVE_GD_TGA \ /D HAVE_LIBGD13=1 \ /D HAVE_LIBGD15=1 \ /D HAVE_LIBGD20=1 \ diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 1bdcba71fba..96c0e23edf6 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -356,6 +356,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefrombmp, 0) ZEND_END_ARG_INFO() #endif +#if defined(HAVE_GD_TGA) +ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromtga, 0) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_INFO_EX(arginfo_imagexbm, 0, 0, 2) ZEND_ARG_INFO(0, im) ZEND_ARG_INFO(0, filename) @@ -942,6 +948,9 @@ static const zend_function_entry gd_functions[] = { #ifdef HAVE_GD_BMP PHP_FE(imagecreatefrombmp, arginfo_imagecreatefrombmp) #endif +#ifdef HAVE_GD_TGA + PHP_FE(imagecreatefromtga, arginfo_imagecreatefromtga) +#endif #ifdef HAVE_GD_PNG PHP_FE(imagepng, arginfo_imagepng) #endif @@ -1109,6 +1118,7 @@ PHP_MINIT_FUNCTION(gd) REGISTER_LONG_CONSTANT("IMG_XPM", PHP_IMG_XPM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_WEBP", PHP_IMG_WEBP, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_BMP", PHP_IMG_BMP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_TGA", PHP_IMG_TGA, CONST_CS | CONST_PERSISTENT); /* special colours for gd */ REGISTER_LONG_CONSTANT("IMG_COLOR_TILED", gdTiled, CONST_CS | CONST_PERSISTENT); @@ -1316,6 +1326,9 @@ PHP_MINFO_FUNCTION(gd) #endif #ifdef HAVE_GD_BMP php_info_print_table_row(2, "BMP Support", "enabled"); +#endif +#ifdef HAVE_GD_TGA + php_info_print_table_row(2, "TGA Read Support", "enabled"); #endif php_info_print_table_end(); DISPLAY_INI_ENTRIES(); @@ -1373,6 +1386,11 @@ PHP_FUNCTION(gd_info) #else add_assoc_bool(return_value, "BMP Support", 0); #endif +#ifdef HAVE_GD_TGA + add_assoc_bool(return_value, "TGA Read Support", 1); +#else + add_assoc_bool(return_value, "TGA Read Support", 0); +#endif #if defined(USE_GD_JISX0208) add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 1); #else @@ -2203,6 +2221,9 @@ PHP_FUNCTION(imagetypes) #ifdef HAVE_GD_BMP ret |= PHP_IMG_BMP; #endif +#ifdef HAVE_GD_TGA + ret |= PHP_IMG_TGA; +#endif if (zend_parse_parameters_none() == FAILURE) { return; @@ -2599,6 +2620,16 @@ PHP_FUNCTION(imagecreatefrombmp) /* }}} */ #endif +#if defined(HAVE_GD_TGA) +/* {{{ proto resource imagecreatefromtga(string filename) + Create a new image from TGA file or URL */ +PHP_FUNCTION(imagecreatefromtga) +{ + _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_TGA, "TGA", gdImageCreateFromTga, gdImageCreateFromTgaCtx); +} +/* }}} */ +#endif + /* {{{ _php_image_output */ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 30f59b38f64..461024f0f77 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -364,6 +364,10 @@ gdImagePtr gdImageCreateFromWebp(FILE *fd); gdImagePtr gdImageCreateFromWebpCtx(gdIOCtxPtr in); gdImagePtr gdImageCreateFromWebpPtr (int size, void *data); +gdImagePtr gdImageCreateFromTga( FILE * fp ); +gdImagePtr gdImageCreateFromTgaCtx(gdIOCtx* ctx); +gdImagePtr gdImageCreateFromTgaPtr(int size, void *data); + gdImagePtr gdImageCreateFromBmp (FILE * inFile); gdImagePtr gdImageCreateFromBmpPtr (int size, void *data); gdImagePtr gdImageCreateFromBmpCtx (gdIOCtxPtr infile); diff --git a/ext/gd/libgd/gd_tga.c b/ext/gd/libgd/gd_tga.c new file mode 100644 index 00000000000..67e77f7b986 --- /dev/null +++ b/ext/gd/libgd/gd_tga.c @@ -0,0 +1,360 @@ +/** + * File: TGA Input + * + * Read TGA images. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include + +#include "gd_tga.h" +#include "gd.h" +#include "gd_errors.h" +#include "gdhelpers.h" + +/* + Function: gdImageCreateFromTga + + Creates a gdImage from a TGA file + + Parameters: + + infile - Pointer to TGA binary file + */ +gdImagePtr gdImageCreateFromTga(FILE *fp) +{ + gdImagePtr image; + gdIOCtx* in = gdNewFileCtx(fp); + if (in == NULL) return NULL; + image = gdImageCreateFromTgaCtx(in); + in->gd_free( in ); + return image; +} + +/* + Function: gdImageCreateFromTgaPtr +*/ +gdImagePtr gdImageCreateFromTgaPtr(int size, void *data) +{ + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0); + if (in == NULL) return NULL; + im = gdImageCreateFromTgaCtx(in); + in->gd_free(in); + return im; +} + + +/* + Function: gdImageCreateFromTgaCtx + + Creates a gdImage from a gdIOCtx referencing a TGA binary file. + + Parameters: + ctx - Pointer to a gdIOCtx structure + */ +gdImagePtr gdImageCreateFromTgaCtx(gdIOCtx* ctx) +{ + int bitmap_caret = 0; + oTga *tga = NULL; + /* int pixel_block_size = 0; + int image_block_size = 0; */ + volatile gdImagePtr image = NULL; + int x = 0; + int y = 0; + + tga = (oTga *) gdMalloc(sizeof(oTga)); + if (!tga) { + return NULL; + } + + tga->bitmap = NULL; + tga->ident = NULL; + + if (read_header_tga(ctx, tga) < 0) { + free_tga(tga); + return NULL; + } + + /*TODO: Will this be used? + pixel_block_size = tga->bits / 8; + image_block_size = (tga->width * tga->height) * pixel_block_size; + */ + + if (read_image_tga(ctx, tga) < 0) { + free_tga(tga); + return NULL; + } + + image = gdImageCreateTrueColor((int)tga->width, (int)tga->height ); + + if (image == 0) { + free_tga( tga ); + return NULL; + } + + /*! \brief Populate GD image object + * Copy the pixel data from our tga bitmap buffer into the GD image + * Disable blending and save the alpha channel per default + */ + if (tga->alphabits) { + gdImageAlphaBlending(image, 0); + gdImageSaveAlpha(image, 1); + } + + /* TODO: use alphabits as soon as we support 24bit and other alpha bps (ie != 8bits) */ + for (y = 0; y < tga->height; y++) { + register int *tpix = image->tpixels[y]; + for ( x = 0; x < tga->width; x++, tpix++) { + if (tga->bits == TGA_BPP_24) { + *tpix = gdTrueColor(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret]); + bitmap_caret += 3; + } else if (tga->bits == TGA_BPP_32 && tga->alphabits) { + register int a = tga->bitmap[bitmap_caret + 3]; + + *tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], gdAlphaMax - (a >> 1)); + bitmap_caret += 4; + } + } + } + + if (tga->flipv && tga->fliph) { + gdImageFlipBoth(image); + } else if (tga->flipv) { + gdImageFlipVertical(image); + } else if (tga->fliph) { + gdImageFlipHorizontal(image); + } + + free_tga(tga); + + return image; +} + +/*! \brief Reads a TGA header. + * Reads the header block from a binary TGA file populating the referenced TGA structure. + * \param ctx Pointer to TGA binary file + * \param tga Pointer to TGA structure + * \return int 1 on sucess, -1 on failure + */ +int read_header_tga(gdIOCtx *ctx, oTga *tga) +{ + + unsigned char header[18]; + + if (gdGetBuf(header, sizeof(header), ctx) < 18) { + gd_error("fail to read header"); + return -1; + } + + tga->identsize = header[0]; + tga->colormaptype = header[1]; + tga->imagetype = header[2]; + tga->colormapstart = header[3] + (header[4] << 8); + tga->colormaplength = header[5] + (header[6] << 8); + tga->colormapbits = header[7]; + tga->xstart = header[8] + (header[9] << 8); + tga->ystart = header[10] + (header[11] << 8); + tga->width = header[12] + (header[13] << 8); + tga->height = header[14] + (header[15] << 8); + tga->bits = header[16]; + tga->alphabits = header[17] & 0x0f; + tga->fliph = (header[17] & 0x10) ? 1 : 0; + tga->flipv = (header[17] & 0x20) ? 0 : 1; + +#if DEBUG + printf("format bps: %i\n", tga->bits); + printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv); + printf("alpha: %i\n", tga->alphabits); + printf("wxh: %i %i\n", tga->width, tga->height); +#endif + + if (!((tga->bits == TGA_BPP_24 && tga->alphabits == 0) + || (tga->bits == TGA_BPP_32 && tga->alphabits == 8))) + { + gd_error_ex(GD_WARNING, "gd-tga: %u bits per pixel with %u alpha bits not supported\n", + tga->bits, tga->alphabits); + return -1; + } + + tga->ident = NULL; + + if (tga->identsize > 0) { + tga->ident = (char *) gdMalloc(tga->identsize * sizeof(char)); + if(tga->ident == NULL) { + return -1; + } + + gdGetBuf(tga->ident, tga->identsize, ctx); + } + + return 1; +} + +/*! \brief Reads a TGA image data into buffer. + * Reads the image data block from a binary TGA file populating the referenced TGA structure. + * \param ctx Pointer to TGA binary file + * \param tga Pointer to TGA structure + * \return int 0 on sucess, -1 on failure + */ +int read_image_tga( gdIOCtx *ctx, oTga *tga ) +{ + int pixel_block_size = (tga->bits / 8); + int image_block_size; + int* decompression_buffer = NULL; + unsigned char* conversion_buffer = NULL; + int buffer_caret = 0; + int bitmap_caret = 0; + int i = 0; + int encoded_pixels; + int rle_size; + + if(overflow2(tga->width, tga->height)) { + return -1; + } + + if(overflow2(tga->width * tga->height, pixel_block_size)) { + return -1; + } + + image_block_size = (tga->width * tga->height) * pixel_block_size; + if(overflow2(image_block_size, sizeof(int))) { + return -1; + } + + /*! \todo Add more image type support. + */ + if (tga->imagetype != TGA_TYPE_RGB && tga->imagetype != TGA_TYPE_RGB_RLE) + return -1; + + /*! \brief Allocate memmory for image block + * Allocate a chunk of memory for the image block to be passed into. + */ + tga->bitmap = (int *) gdMalloc(image_block_size * sizeof(int)); + if (tga->bitmap == NULL) + return -1; + + switch (tga->imagetype) { + case TGA_TYPE_RGB: + /*! \brief Read in uncompressed RGB TGA + * Chunk load the pixel data from an uncompressed RGB type TGA. + */ + conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char)); + if (conversion_buffer == NULL) { + return -1; + } + + if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) { + gd_error("gd-tga: premature end of image data\n"); + gdFree(conversion_buffer); + return -1; + } + + while (buffer_caret < image_block_size) { + tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret]; + buffer_caret++; + } + + gdFree(conversion_buffer); + break; + + case TGA_TYPE_RGB_RLE: + /*! \brief Read in RLE compressed RGB TGA + * Chunk load the pixel data from an RLE compressed RGB type TGA. + */ + decompression_buffer = (int*) gdMalloc(image_block_size * sizeof(int)); + if (decompression_buffer == NULL) { + return -1; + } + conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char)); + if (conversion_buffer == NULL) { + gd_error("gd-tga: premature end of image data\n"); + gdFree( decompression_buffer ); + return -1; + } + + rle_size = gdGetBuf(conversion_buffer, image_block_size, ctx); + if (rle_size <= 0) { + gdFree(conversion_buffer); + gdFree(decompression_buffer); + return -1; + } + + buffer_caret = 0; + + while( buffer_caret < rle_size) { + decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret]; + buffer_caret++; + } + + buffer_caret = 0; + + while( bitmap_caret < image_block_size ) { + + if (buffer_caret + pixel_block_size > rle_size) { + gdFree( decompression_buffer ); + gdFree( conversion_buffer ); + return -1; + } + + if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) { + encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 ); + buffer_caret++; + + if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size + || buffer_caret + pixel_block_size > rle_size) { + gdFree( decompression_buffer ); + gdFree( conversion_buffer ); + return -1; + } + + for (i = 0; i < encoded_pixels; i++) { + memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size * sizeof(int)); + bitmap_caret += pixel_block_size; + } + buffer_caret += pixel_block_size; + + } else { + encoded_pixels = decompression_buffer[ buffer_caret ] + 1; + buffer_caret++; + + if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size + || buffer_caret + (encoded_pixels * pixel_block_size) > rle_size) { + gdFree( decompression_buffer ); + gdFree( conversion_buffer ); + return -1; + } + + memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size * sizeof(int)); + bitmap_caret += (encoded_pixels * pixel_block_size); + buffer_caret += (encoded_pixels * pixel_block_size); + } + } + gdFree( decompression_buffer ); + gdFree( conversion_buffer ); + break; + } + + return 1; +} + +/*! \brief Cleans up a TGA structure. + * Dereferences the bitmap referenced in a TGA structure, then the structure itself + * \param tga Pointer to TGA structure + */ +void free_tga(oTga * tga) +{ + if (tga) { + if (tga->ident) + gdFree(tga->ident); + if (tga->bitmap) + gdFree(tga->bitmap); + gdFree(tga); + } +} diff --git a/ext/gd/libgd/gd_tga.h b/ext/gd/libgd/gd_tga.h new file mode 100644 index 00000000000..297f3dc99d6 --- /dev/null +++ b/ext/gd/libgd/gd_tga.h @@ -0,0 +1,52 @@ +#ifndef __TGA_H +#define __TGA_H 1 + +#include "gd.h" +#include "gdhelpers.h" + +#include "gd_intern.h" + +typedef struct oTga_ { + uint8_t identsize; // size of ID field that follows 18 uint8_t header (0 usually) + uint8_t colormaptype; // type of colour map 0=none, 1=has palette [IGNORED] Adrian requested no support + uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + int colormapstart; // first colour map entry in palette [IGNORED] Adrian requested no support + int colormaplength; // number of colours in palette [IGNORED] Adrian requested no support + uint8_t colormapbits; // number of bits per palette entry 15,16,24,32 [IGNORED] Adrian requested no support + + int xstart; // image x origin + int ystart; // image y origin + int width; // image width in pixels + int height; // image height in pixels + uint8_t bits; // image bits per pixel 8,16,24,32 + uint8_t alphabits; // alpha bits (low 4bits of header 17) + uint8_t fliph; // horizontal or vertical + uint8_t flipv; // flip + char *ident; // identifcation tag string + int *bitmap; // bitmap data + +} oTga; + +#define TGA_TYPE_NO_IMAGE 0 +#define TGA_TYPE_INDEXED 1 +#define TGA_TYPE_RGB 2 +#define TGA_TYPE_GREYSCALE 3 +#define TGA_TYPE_INDEXED_RLE 9 +#define TGA_TYPE_RGB_RLE 10 +#define TGA_TYPE_GREYSCALE_RLE 11 +#define TGA_TYPE_INDEXED_HUFFMAN_DELTA_RLE 32 +#define TGA_TYPE_RGB_HUFFMAN_DELTA_QUADTREE_RLE 33 + +#define TGA_BPP_8 8 +#define TGA_BPP_16 16 +#define TGA_BPP_24 24 +#define TGA_BPP_32 32 + +#define TGA_RLE_FLAG 128 + +int read_header_tga(gdIOCtx *ctx, oTga *tga); +int read_image_tga(gdIOCtx *ctx, oTga *tga); +void free_tga(oTga *tga); + +#endif //__TGA_H diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 982decd064e..e6db0c0ec06 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -47,6 +47,7 @@ #define PHP_GDIMG_TYPE_GD2PART 10 #define PHP_GDIMG_TYPE_WEBP 11 #define PHP_GDIMG_TYPE_BMP 12 +#define PHP_GDIMG_TYPE_TGA 13 #define PHP_IMG_GIF 1 #define PHP_IMG_JPG 2 @@ -56,6 +57,7 @@ #define PHP_IMG_XPM 16 #define PHP_IMG_WEBP 32 #define PHP_IMG_BMP 64 +#define PHP_IMG_TGA 128 #ifdef PHP_WIN32 # define PHP_GD_API __declspec(dllexport) @@ -163,6 +165,9 @@ PHP_FUNCTION(imagecreatefromgd2part); #if defined(HAVE_GD_BMP) PHP_FUNCTION(imagecreatefrombmp); #endif +#if defined(HAVE_GD_TGA) +PHP_FUNCTION(imagecreatefromtga); +#endif #if defined(HAVE_GD_XPM) PHP_FUNCTION(imagecreatefromxpm); #endif diff --git a/ext/gd/tests/imagecreatefromtga.png b/ext/gd/tests/imagecreatefromtga.png new file mode 100644 index 00000000000..4a3060d974e Binary files /dev/null and b/ext/gd/tests/imagecreatefromtga.png differ diff --git a/ext/gd/tests/imagecreatefromtga_basic.phpt b/ext/gd/tests/imagecreatefromtga_basic.phpt new file mode 100644 index 00000000000..3025e522d53 --- /dev/null +++ b/ext/gd/tests/imagecreatefromtga_basic.phpt @@ -0,0 +1,17 @@ +--TEST-- +imagecreatefromtga() - basic functionality +--SKIPIF-- + +--FILE-- + +--EXPECT-- +The images are equal. diff --git a/ext/gd/tests/imagecreatefromtga_basic.tga b/ext/gd/tests/imagecreatefromtga_basic.tga new file mode 100644 index 00000000000..5f11f5a080f Binary files /dev/null and b/ext/gd/tests/imagecreatefromtga_basic.tga differ diff --git a/ext/gd/tests/imagecreatefromtga_variation.phpt b/ext/gd/tests/imagecreatefromtga_variation.phpt new file mode 100644 index 00000000000..39dd4b0b598 --- /dev/null +++ b/ext/gd/tests/imagecreatefromtga_variation.phpt @@ -0,0 +1,17 @@ +--TEST-- +imagecreatefromtga() - RLE file reading +--SKIPIF-- + +--FILE-- + +--EXPECT-- +The images are equal. diff --git a/ext/gd/tests/imagecreatefromtga_variation.tga b/ext/gd/tests/imagecreatefromtga_variation.tga new file mode 100644 index 00000000000..ce845ad0c3d Binary files /dev/null and b/ext/gd/tests/imagecreatefromtga_variation.tga differ diff --git a/ext/gd/tests/imagetypes_tga.phpt b/ext/gd/tests/imagetypes_tga.phpt new file mode 100644 index 00000000000..56d6b3c2edf --- /dev/null +++ b/ext/gd/tests/imagetypes_tga.phpt @@ -0,0 +1,12 @@ +--TEST-- +imagetypes() - TGA support +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true)