mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Merge branch 'PHP-7.4'
* PHP-7.4: Support TGA reading
This commit is contained in:
commit
7469d572f2
@ -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
|
||||
|
@ -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 \
|
||||
|
31
ext/gd/gd.c
31
ext/gd/gd.c
@ -355,6 +355,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)
|
||||
@ -915,6 +921,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
|
||||
@ -1075,6 +1084,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);
|
||||
@ -1282,6 +1292,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();
|
||||
@ -1339,6 +1352,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
|
||||
@ -2169,6 +2187,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;
|
||||
@ -2561,6 +2582,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)())
|
||||
|
@ -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);
|
||||
|
360
ext/gd/libgd/gd_tga.c
Normal file
360
ext/gd/libgd/gd_tga.c
Normal file
@ -0,0 +1,360 @@
|
||||
/**
|
||||
* File: TGA Input
|
||||
*
|
||||
* Read TGA images.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
52
ext/gd/libgd/gd_tga.h
Normal file
52
ext/gd/libgd/gd_tga.h
Normal file
@ -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
|
@ -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
|
||||
|
BIN
ext/gd/tests/imagecreatefromtga.png
Normal file
BIN
ext/gd/tests/imagecreatefromtga.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
17
ext/gd/tests/imagecreatefromtga_basic.phpt
Normal file
17
ext/gd/tests/imagecreatefromtga_basic.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
imagecreatefromtga() - basic functionality
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip ext/gd required');
|
||||
if (!(imagetypes() & IMG_TGA)) die('skip TGA support required');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
// create an image from a TGA file
|
||||
$im = imagecreatefromtga(__DIR__ . '/imagecreatefromtga_basic.tga');
|
||||
|
||||
include_once __DIR__ . '/func.inc';
|
||||
test_image_equals_file(__DIR__ . '/imagecreatefromtga.png', $im);
|
||||
?>
|
||||
--EXPECT--
|
||||
The images are equal.
|
BIN
ext/gd/tests/imagecreatefromtga_basic.tga
Normal file
BIN
ext/gd/tests/imagecreatefromtga_basic.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
17
ext/gd/tests/imagecreatefromtga_variation.phpt
Normal file
17
ext/gd/tests/imagecreatefromtga_variation.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
imagecreatefromtga() - RLE file reading
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip ext/gd required');
|
||||
if (!(imagetypes() & IMG_TGA)) die('skip TGA support required');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
// create an image from a TGA file
|
||||
$im = imagecreatefromtga(__DIR__ . '/imagecreatefromtga_variation.tga');
|
||||
|
||||
include_once __DIR__ . '/func.inc';
|
||||
test_image_equals_file(__DIR__ . '/imagecreatefromtga.png', $im);
|
||||
?>
|
||||
--EXPECT--
|
||||
The images are equal.
|
BIN
ext/gd/tests/imagecreatefromtga_variation.tga
Normal file
BIN
ext/gd/tests/imagecreatefromtga_variation.tga
Normal file
Binary file not shown.
12
ext/gd/tests/imagetypes_tga.phpt
Normal file
12
ext/gd/tests/imagetypes_tga.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
imagetypes() - TGA support
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip ext/gd required');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump((imagetypes() & IMG_TGA) == function_exists('imagecreatefromtga'));
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
Loading…
Reference in New Issue
Block a user