php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
gd_tga.c
Go to the documentation of this file.
1
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif /* HAVE_CONFIG_H */
10
11#include <stdio.h>
12#include <stddef.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include "gd_tga.h"
17#include "gd.h"
18#include "gd_errors.h"
19#include "gdhelpers.h"
20
21/*
22 Function: gdImageCreateFromTga
23
24 Creates a gdImage from a TGA file
25
26 Parameters:
27
28 infile - Pointer to TGA binary file
29 */
31{
32 gdImagePtr image;
33 gdIOCtx* in = gdNewFileCtx(fp);
34 if (in == NULL) return NULL;
35 image = gdImageCreateFromTgaCtx(in);
36 in->gd_free( in );
37 return image;
38}
39
40/*
41 Function: gdImageCreateFromTgaPtr
42*/
44{
45 gdImagePtr im;
47 if (in == NULL) return NULL;
49 in->gd_free(in);
50 return im;
51}
52
53
54/*
55 Function: gdImageCreateFromTgaCtx
56
57 Creates a gdImage from a gdIOCtx referencing a TGA binary file.
58
59 Parameters:
60 ctx - Pointer to a gdIOCtx structure
61 */
63{
64 int bitmap_caret = 0;
65 oTga *tga = NULL;
66 /* int pixel_block_size = 0;
67 int image_block_size = 0; */
68 volatile gdImagePtr image = NULL;
69 int x = 0;
70 int y = 0;
71
72 tga = (oTga *) gdMalloc(sizeof(oTga));
73 if (!tga) {
74 return NULL;
75 }
76
77 tga->bitmap = NULL;
78 tga->ident = NULL;
79
80 if (read_header_tga(ctx, tga) < 0) {
81 free_tga(tga);
82 return NULL;
83 }
84
85 /*TODO: Will this be used?
86 pixel_block_size = tga->bits / 8;
87 image_block_size = (tga->width * tga->height) * pixel_block_size;
88 */
89
90 if (read_image_tga(ctx, tga) < 0) {
91 free_tga(tga);
92 return NULL;
93 }
94
95 image = gdImageCreateTrueColor((int)tga->width, (int)tga->height );
96
97 if (image == 0) {
98 free_tga( tga );
99 return NULL;
100 }
101
106 if (tga->alphabits) {
107 gdImageAlphaBlending(image, 0);
108 gdImageSaveAlpha(image, 1);
109 }
110
111 /* TODO: use alphabits as soon as we support 24bit and other alpha bps (ie != 8bits) */
112 for (y = 0; y < tga->height; y++) {
113 register int *tpix = image->tpixels[y];
114 for ( x = 0; x < tga->width; x++, tpix++) {
115 if (tga->bits == TGA_BPP_24) {
116 *tpix = gdTrueColor(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret]);
117 bitmap_caret += 3;
118 } else if (tga->bits == TGA_BPP_32 && tga->alphabits) {
119 register int a = tga->bitmap[bitmap_caret + 3];
120
121 *tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], gdAlphaMax - (a >> 1));
122 bitmap_caret += 4;
123 }
124 }
125 }
126
127 if (tga->flipv && tga->fliph) {
128 gdImageFlipBoth(image);
129 } else if (tga->flipv) {
130 gdImageFlipVertical(image);
131 } else if (tga->fliph) {
133 }
134
135 free_tga(tga);
136
137 return image;
138}
139
147{
148
149 unsigned char header[18];
150
151 if (gdGetBuf(header, sizeof(header), ctx) < 18) {
152 gd_error("Fail to read header");
153 return -1;
154 }
155
156 tga->identsize = header[0];
157 tga->colormaptype = header[1];
158 tga->imagetype = header[2];
159 tga->colormapstart = header[3] + (header[4] << 8);
160 tga->colormaplength = header[5] + (header[6] << 8);
161 tga->colormapbits = header[7];
162 tga->xstart = header[8] + (header[9] << 8);
163 tga->ystart = header[10] + (header[11] << 8);
164 tga->width = header[12] + (header[13] << 8);
165 tga->height = header[14] + (header[15] << 8);
166 tga->bits = header[16];
167 tga->alphabits = header[17] & 0x0f;
168 tga->fliph = (header[17] & 0x10) ? 1 : 0;
169 tga->flipv = (header[17] & 0x20) ? 0 : 1;
170
171#ifdef DEBUG
172 printf("format bps: %i\n", tga->bits);
173 printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv);
174 printf("alpha: %i\n", tga->alphabits);
175 printf("wxh: %i %i\n", tga->width, tga->height);
176#endif
177
178 if (!((tga->bits == TGA_BPP_24 && tga->alphabits == 0)
179 || (tga->bits == TGA_BPP_32 && tga->alphabits == 8)))
180 {
181 gd_error_ex(GD_WARNING, "gd-tga: %u bits per pixel with %u alpha bits not supported\n",
182 tga->bits, tga->alphabits);
183 return -1;
184 }
185
186 tga->ident = NULL;
187
188 if (tga->identsize > 0) {
189 tga->ident = (char *) gdMalloc(tga->identsize * sizeof(char));
190 if(tga->ident == NULL) {
191 return -1;
192 }
193
194 if (gdGetBuf(tga->ident, tga->identsize, ctx) != tga->identsize) {
195 gd_error("fail to read header ident");
196 return -1;
197 }
198 }
199
200 return 1;
201}
202
209int read_image_tga( gdIOCtx *ctx, oTga *tga )
210{
211 int pixel_block_size = (tga->bits / 8);
212 int image_block_size;
213 int* decompression_buffer = NULL;
214 unsigned char* conversion_buffer = NULL;
215 int buffer_caret = 0;
216 int bitmap_caret = 0;
217 int i = 0;
218 int encoded_pixels;
219 int rle_size;
220
221 if(overflow2(tga->width, tga->height)) {
222 return -1;
223 }
224
225 if(overflow2(tga->width * tga->height, pixel_block_size)) {
226 return -1;
227 }
228
229 image_block_size = (tga->width * tga->height) * pixel_block_size;
230 if(overflow2(image_block_size, sizeof(int))) {
231 return -1;
232 }
233
236 if (tga->imagetype != TGA_TYPE_RGB && tga->imagetype != TGA_TYPE_RGB_RLE)
237 return -1;
238
242 tga->bitmap = (int *) gdMalloc(image_block_size * sizeof(int));
243 if (tga->bitmap == NULL)
244 return -1;
245
246 switch (tga->imagetype) {
247 case TGA_TYPE_RGB:
251 conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
252 if (conversion_buffer == NULL) {
253 return -1;
254 }
255
256 if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) {
257 gd_error("gd-tga: premature end of image data\n");
258 gdFree(conversion_buffer);
259 return -1;
260 }
261
262 while (buffer_caret < image_block_size) {
263 tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret];
264 buffer_caret++;
265 }
266
267 gdFree(conversion_buffer);
268 break;
269
270 case TGA_TYPE_RGB_RLE:
274 decompression_buffer = (int*) gdMalloc(image_block_size * sizeof(int));
275 if (decompression_buffer == NULL) {
276 return -1;
277 }
278 conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
279 if (conversion_buffer == NULL) {
280 gd_error("gd-tga: premature end of image data\n");
281 gdFree( decompression_buffer );
282 return -1;
283 }
284
285 rle_size = gdGetBuf(conversion_buffer, image_block_size, ctx);
286 if (rle_size <= 0) {
287 gdFree(conversion_buffer);
288 gdFree(decompression_buffer);
289 return -1;
290 }
291
292 buffer_caret = 0;
293
294 while( buffer_caret < rle_size) {
295 decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret];
296 buffer_caret++;
297 }
298
299 buffer_caret = 0;
300
301 while( bitmap_caret < image_block_size ) {
302
303 if (buffer_caret + pixel_block_size > rle_size) {
304 gdFree( decompression_buffer );
305 gdFree( conversion_buffer );
306 return -1;
307 }
308
309 if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) {
310 encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 );
311 buffer_caret++;
312
313 if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
314 || buffer_caret + pixel_block_size > rle_size) {
315 gdFree( decompression_buffer );
316 gdFree( conversion_buffer );
317 return -1;
318 }
319
320 for (i = 0; i < encoded_pixels; i++) {
321 memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size * sizeof(int));
322 bitmap_caret += pixel_block_size;
323 }
324 buffer_caret += pixel_block_size;
325
326 } else {
327 encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
328 buffer_caret++;
329
330 if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
331 || buffer_caret + (encoded_pixels * pixel_block_size) > rle_size) {
332 gdFree( decompression_buffer );
333 gdFree( conversion_buffer );
334 return -1;
335 }
336
337 memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size * sizeof(int));
338 bitmap_caret += (encoded_pixels * pixel_block_size);
339 buffer_caret += (encoded_pixels * pixel_block_size);
340 }
341 }
342 gdFree( decompression_buffer );
343 gdFree( conversion_buffer );
344 break;
345 }
346
347 return 1;
348}
349
354void free_tga(oTga * tga)
355{
356 if (tga) {
357 if (tga->ident)
358 gdFree(tga->ident);
359 if (tga->bitmap)
360 gdFree(tga->bitmap);
361 gdFree(tga);
362 }
363}
printf(string $format, mixed ... $values)
header(string $header, bool $replace=true, int $response_code=0)
new_type size
Definition ffi.c:4365
memcpy(ptr1, ptr2, size)
int overflow2(int a, int b)
Definition gd_compat.c:10
#define gdAlphaMax
Definition gd.h:79
void gdImageFlipVertical(gdImagePtr im)
Definition gd_transform.c:3
void gdImageFlipBoth(gdImagePtr im)
gdIOCtx * gdNewFileCtx(FILE *)
Definition gd_io_file.c:49
#define gdTrueColorAlpha(r, g, b, a)
Definition gd.h:545
void gdImageFlipHorizontal(gdImagePtr im)
#define gdTrueColor(r, g, b)
Definition gd.h:537
gdIOCtx * gdNewDynamicCtxEx(int size, void *data, int freeFlag)
Definition gd_io_dp.c:70
gdImage * gdImagePtr
Definition gd.h:248
#define GD_WARNING
Definition gd_errors.h:22
int gdGetBuf(void *buf, int size, gdIOCtx *ctx)
Definition gd_io.c:188
void free_tga(oTga *tga)
Cleans up a TGA structure. Dereferences the bitmap referenced in a TGA structure, then the structure ...
Definition gd_tga.c:354
gdImagePtr gdImageCreateFromTgaCtx(gdIOCtx *ctx)
Definition gd_tga.c:62
gdImagePtr gdImageCreateFromTga(FILE *fp)
Definition gd_tga.c:30
int read_image_tga(gdIOCtx *ctx, oTga *tga)
Reads a TGA image data into buffer. Reads the image data block from a binary TGA file populating the ...
Definition gd_tga.c:209
int read_header_tga(gdIOCtx *ctx, oTga *tga)
Reads a TGA header. Reads the header block from a binary TGA file populating the referenced TGA struc...
Definition gd_tga.c:146
gdImagePtr gdImageCreateFromTgaPtr(int size, void *data)
Definition gd_tga.c:43
#define TGA_TYPE_RGB
Definition gd_tga.h:33
#define TGA_BPP_32
Definition gd_tga.h:44
#define TGA_RLE_FLAG
Definition gd_tga.h:46
#define TGA_BPP_24
Definition gd_tga.h:43
#define TGA_TYPE_RGB_RLE
Definition gd_tga.h:36
struct oTga_ oTga
#define NULL
Definition gdcache.h:45
#define gdFree(ptr)
Definition gdhelpers.h:19
#define gdMalloc(size)
Definition gdhelpers.h:16
void gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg)
Definition gd.c:3037
void gd_error(const char *format,...)
Definition gd.c:103
void gd_error_ex(int priority, const char *format,...)
Definition gd.c:111
gdImagePtr gdImageCreateTrueColor(int sx, int sy)
Definition gd.c:195
void gdImageSaveAlpha(gdImagePtr im, int saveAlphaArg)
Definition gd.c:3042
zend_constant * data
void(* gd_free)(struct gdIOCtx *)
Definition gd_io.h:20
int ** tpixels
Definition gd.h:218
char * ident
Definition gd_tga.h:26
int width
Definition gd_tga.h:20
int ystart
Definition gd_tga.h:19
int colormaplength
Definition gd_tga.h:15
uint8_t alphabits
Definition gd_tga.h:23
uint8_t bits
Definition gd_tga.h:22
int colormapstart
Definition gd_tga.h:14
uint8_t colormapbits
Definition gd_tga.h:16
int height
Definition gd_tga.h:21
uint8_t identsize
Definition gd_tga.h:10
uint8_t fliph
Definition gd_tga.h:24
uint8_t flipv
Definition gd_tga.h:25
uint8_t imagetype
Definition gd_tga.h:12
int * bitmap
Definition gd_tga.h:27
int xstart
Definition gd_tga.h:18
uint8_t colormaptype
Definition gd_tga.h:11
$obj a
Definition test.php:84