cvs: gd /libgd/examples tgaread.c /libgd/src CMakeLists.txt gd_io.c gd_tga.c gd_tga.h

[email protected] ("Pierre-Alain Joye") Sun, 07 Oct 2007 19:41:52 -0000
Newsgroups php.gd.cvs
Message-ID <cvspajoye1191786112@cvsserver>
pajoye		Sun Oct  7 19:41:52 2007 UTC

  Added files:                 
    /gd/libgd/src	gd_tga.c gd_tga.h 
    /gd/libgd/examples	tgaread.c 

  Modified files:              
    /gd/libgd/src	CMakeLists.txt gd_io.c 
  Log:
  - #122, initial TGA support (read only)
pajoye-20071007194152.txt (text/plain, 12.5 KB)
http://cvs.php.net/viewvc.cgi/gd/libgd/src/CMakeLists.txt?r1=1.9&r2=1.10&diff_format=u
Index: gd/libgd/src/CMakeLists.txt
diff -u gd/libgd/src/CMakeLists.txt:1.9 gd/libgd/src/CMakeLists.txt:1.10
--- gd/libgd/src/CMakeLists.txt:1.9	Thu Oct  4 18:53:57 2007
+++ gd/libgd/src/CMakeLists.txt	Sun Oct  7 19:41:52 2007
@@ -14,6 +14,7 @@
 	gd_jpeg.c
 	gd_png.c
 	gd_tiff.c
+	gd_tga.c
 	gd_ss.c
 	gd_topal.c
 	gd_wbmp.c
http://cvs.php.net/viewvc.cgi/gd/libgd/src/gd_io.c?r1=1.5&r2=1.6&diff_format=u
Index: gd/libgd/src/gd_io.c
diff -u gd/libgd/src/gd_io.c:1.5 gd/libgd/src/gd_io.c:1.6
--- gd/libgd/src/gd_io.c:1.5	Wed Apr  5 15:49:38 2006
+++ gd/libgd/src/gd_io.c	Sun Oct  7 19:41:52 2007
@@ -26,6 +26,10 @@
 /*#define IO_DBG(s) (s) */
 #define IO_DBG(s)
 
+#define GD_IO_EOF_CHK(r) \
+	if (r == EOF) { \
+		return 0; \
+	}
 
 /*
  * Write out a word to the I/O context pointer
@@ -111,7 +115,6 @@
   return 1;
 }
 
-
 int
 gdGetInt (int *result, gdIOCtx * ctx)
 {

http://cvs.php.net/viewvc.cgi/gd/libgd/src/gd_tga.c?view=markup&rev=1.1
Index: gd/libgd/src/gd_tga.c
+++ gd/libgd/src/gd_tga.c
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "gd_tga.h"
#include "gd.h"
#include "gdhelpers.h"

/*!	\brief Creates a gdImage from a TGA file
 *	Creates a gdImage from a TGA binary file via a gdIOCtx.
 *	\param infile Pointer to TGA binary file
 *	\return gdImagePtr	
 */
BGD_DECLARE(gdImagePtr) gdImageCreateFromTga(FILE * fp)
{
	gdImagePtr image;
	gdIOCtx* in = gdNewFileCtx(fp);
	image = gdImageCreateFromTgaCtx(in);
	in->gd_free( in );
	return image;
}

BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaPtr(int size, void *data)
{
	gdImagePtr im;
	gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0);
	im = gdImageCreateFromTgaCtx(in);
	in->gd_free(in);
	return im;
}


/*!	\brief Creates a gdImage from a gdIOCtx
 *	Creates a gdImage from a gdIOCtx referencing a TGA binary file.
 *	\param ctx Pointer to a gdIOCtx structure
 *	\return gdImagePtr	
 */
BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaCtx(gdIOCtx* ctx)
{

	int bitmap_caret = 0;
	int i = 0;
	oTga *tga = NULL;
	int pixel_block_size = 0;
	int image_block_size = 0;
	volatile gdImagePtr image = NULL;
	int x = 0;
	int y = 0;
	int color = 0;

	tga = (oTga *) gdMalloc(sizeof(oTga));
	if (!tga) {
		return NULL;
	}

	tga->bitmap = NULL;
	tga->ident = NULL;

	if (!read_header_tga(ctx, tga)) {
		free_tga(tga);
		return NULL;    
	}

	pixel_block_size = tga->bits / 8;
	image_block_size = (tga->width * tga->height) * pixel_block_size;

	if (read_image_tga(ctx, tga)) {
		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
	 */

	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;
			}

			if (tga->bits == TGA_BPP_32) {
				*tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], tga->bitmap[bitmap_caret + 3]);
				bitmap_caret += 4; 
			}

		}
	}

	free_tga(tga);

	// Return pointer to our new image object
	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, 18, ctx) < 18) {
		printf("fail to read header");
		return -1;	
	}

	tga->identsize = header[0];
	tga->colourmaptype = header[1];
	tga->imagetype = header[2];
	tga->colourmapstart = header[3] + header[4] * 256;
	tga->colourmaplength = header[5] + header[6] * 256;
	tga->colourmapbits = header[7];
	tga->xstart = header[8] + header[9] * 256;
	tga->ystart = header[10] + header[11] * 256;
	tga->width = header[12] + header[13] * 256;
	tga->height = header[14] + header[15] * 256;
	tga->bits = header[16];

	if (tga->bits != 8 && tga->bits != 24 && tga->bits != 16 && tga->bits != 32) {
		return -1;
	}

	tga->descriptor = header[17];

	tga->ident = (char *) gdMalloc(tga->identsize * sizeof( char ));
	if (tga->ident == NULL) {
		return -1;
	}

	if (tga->identsize > 0) {
		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 = (tga->width * tga->height) * pixel_block_size;
	byte* decompression_buffer = NULL;
	unsigned char* conversion_buffer = NULL;
	int buffer_caret = 0;
	int bitmap_caret = 0;
	int i = 0;
	int j = 0;
	byte encoded_pixels;

	/*!	\brief Allocate memmory for image block
	 *  Allocate a chunk of memory for the image block to be passed into.
	 */
	tga->bitmap = (byte *) gdMalloc(image_block_size * sizeof(byte));
	if (tga->bitmap == NULL) {
		return -1;
	}

	/*! \todo Add image type support
	 *  Add support for this image type.
	 */
	if (tga->imagetype == TGA_TYPE_INDEXED) {
		return -1;
	}

	/*! \todo Add image type support
	 *  Add support for this image type.
	 */
	if (tga->imagetype == TGA_TYPE_INDEXED_RLE) {
		return -1;
	}

	/*! \brief Read in uncompressed RGB TGA
	 *  Chunk load the pixel data from an uncompressed RGB type TGA.
	 */
	if (tga->imagetype == TGA_TYPE_RGB) {
		conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
		if (conversion_buffer == NULL) {
			gdFree(conversion_buffer);
			return -1;
		}

		gdGetBuf(conversion_buffer, image_block_size, ctx);

		while (buffer_caret < image_block_size) { 
			tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret];
			buffer_caret++;
		}

		gdFree( conversion_buffer );
	}

	/*! \brief Read in RLE compressed RGB TGA
	 *  Chunk load the pixel data from an RLE compressed RGB type TGA.
	 */
	if (tga->imagetype == TGA_TYPE_RGB_RLE) {
		decompression_buffer = (byte*) gdMalloc(image_block_size * sizeof(byte));
		if (decompression_buffer == NULL) {
			gdFree( decompression_buffer );
			return -1;
		}
		conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));  
		if (conversion_buffer == NULL) {
			gdFree( decompression_buffer );
			gdFree( conversion_buffer );
			return -1;
		}

		gdGetBuf( conversion_buffer, image_block_size, ctx );

		buffer_caret = 0;

		while( buffer_caret < image_block_size ) { 
			decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret];
			buffer_caret++;
		}

		buffer_caret = 0;

		while( bitmap_caret < image_block_size ) {

			if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) {
				encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & 127 ) + 1 );
				buffer_caret++;

				for (i = 0; i < encoded_pixels; i++) {
					for (j = 0; j < pixel_block_size; j++, bitmap_caret++) {
						tga->bitmap[ bitmap_caret ] = decompression_buffer[ buffer_caret + j ];
					}
				}
				buffer_caret += pixel_block_size;
			} else {
				encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
				buffer_caret++;

				for (i = 0; i < encoded_pixels; i++) {
					for( j = 0; j < pixel_block_size; j++, bitmap_caret++ ) {
						tga->bitmap[ bitmap_caret ] = decompression_buffer[ buffer_caret + j ];
					}
					buffer_caret += pixel_block_size;
				}
			}
		}

		gdFree( decompression_buffer );
		gdFree( conversion_buffer );

	}

	/*!	\todo Add image type support
	 *  Add support for this image type.
	 */
	if( tga->imagetype == TGA_TYPE_GREYSCALE ) {
		return -1;
	}

	/*!	\todo Add image type support
	 *  Add support for this image type.
	 */
	if( tga->imagetype == TGA_TYPE_GREYSCALE_RLE ) {
		return -1;
	}

	return 0;
}

/*!	\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);
			tga->ident = NULL;
		}
		if (tga->bitmap) {
			gdFree(tga->bitmap);
			tga->bitmap = NULL;
		}
		gdFree(tga);
		tga = NULL;
	}
}

http://cvs.php.net/viewvc.cgi/gd/libgd/src/gd_tga.h?view=markup&rev=1.1
Index: gd/libgd/src/gd_tga.h
+++ gd/libgd/src/gd_tga.h
/*
 * TGA Image read support
 * Copyright (C) 2005  Andrew Ireland, Jon Keto, Michael Beal
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 */

#define TGA_LINE_LENGTH 1024

#ifndef __TGA_H
#define __TGA_H	1


#include "gd.h"
#include "gdhelpers.h"


#ifndef O_BYTE
#define O_BYTE    1
    typedef int byte;
#endif
#ifndef O_SHORT_INT
#define O_SHORT_INT     1
    typedef int short_int;
#endif

typedef struct oTga_
{
    byte  identsize;			// size of ID field that follows 18 byte header (0 usually)
    byte  colourmaptype;		// type of colour map 0=none, 1=has palette					[IGNORED] Adrian requested no support
    byte  imagetype;			// type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed

    int colourmapstart;		        // first colour map entry in palette						[IGNORED] Adrian requested no support
    int colourmaplength;		// number of colours in palette								[IGNORED] Adrian requested no support
    byte  colourmapbits;		// 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
    byte  bits;				// image bits per pixel 8,16,24,32
    byte  descriptor;			// image descriptor bits (vh flip bits)
    
    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

gdImagePtr gdImageCreateFromTGA( FILE * fp );
gdImagePtr gdImageCreateFromTGACtx( gdIOCtx* ctx );

int read_header_tga(gdIOCtx *ctx, oTga *tga);
int read_image_tga(gdIOCtx *ctx, oTga *tga);
void free_tga(oTga * tga);

#endif //__TGA_H

http://cvs.php.net/viewvc.cgi/gd/libgd/examples/tgaread.c?view=markup&rev=1.1
Index: gd/libgd/examples/tgaread.c
+++ gd/libgd/examples/tgaread.c
/* $Id: tgaread.c,v 1.1 2007/10/07 19:41:52 pajoye Exp $ */
/*
 * You can fetch a set of samples TIFF images here:
 * ftp://ftp.remotesensing.org/pub/libtiff/ 
 * (pics-x.y.z.tar.gz)
 */

#include <gd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
 	gdImagePtr im;
	FILE *fp;
	char path[3][2048];
	int i;
	char dst[2048];

	sprintf(path[0], "noIcon.tga");
	sprintf(path[1], "noIcon.sgi");
	sprintf(path[2], "noIcon.pic");

	for (i = 0; i < 2; i++) {
		printf("opening %s\n", path[i]);
		fp = fopen(path[i], "rb");
		if (!fp) {
			printf("failed, cannot open file\n");
			return 1;
		}

		im = gdImageCreateFromTga(fp);
		fclose(fp);
		if (!im) {
			fprintf(stderr, "Can't load TIFF image %s\n", path[i]);
			return 1;
		}


		sprintf(dst, "%i.png", i);

		fp = fopen(dst, "wb");
		if (!fp) {
			fprintf(stderr, "Can't save png image fromtiff.png\n");
			gdImageDestroy(im);
			return 1;
		}

		gdImagePng(im, fp);
		fclose(fp);
		gdImageDestroy(im);
	}
}