gd_tga.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /**
  2. * File: TGA Input
  3. *
  4. * Read TGA images.
  5. */
  6. #ifdef HAVE_CONFIG_H
  7. #include "config.h"
  8. #endif /* HAVE_CONFIG_H */
  9. #include <stdio.h>
  10. #include <stddef.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "gd_tga.h"
  14. #include "gd.h"
  15. #include "gd_errors.h"
  16. #include "gdhelpers.h"
  17. /*
  18. Function: gdImageCreateFromTga
  19. Creates a gdImage from a TGA file
  20. Parameters:
  21. infile - Pointer to TGA binary file
  22. */
  23. gdImagePtr gdImageCreateFromTga(FILE *fp)
  24. {
  25. gdImagePtr image;
  26. gdIOCtx* in = gdNewFileCtx(fp);
  27. if (in == NULL) return NULL;
  28. image = gdImageCreateFromTgaCtx(in);
  29. in->gd_free( in );
  30. return image;
  31. }
  32. /*
  33. Function: gdImageCreateFromTgaPtr
  34. */
  35. gdImagePtr gdImageCreateFromTgaPtr(int size, void *data)
  36. {
  37. gdImagePtr im;
  38. gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0);
  39. if (in == NULL) return NULL;
  40. im = gdImageCreateFromTgaCtx(in);
  41. in->gd_free(in);
  42. return im;
  43. }
  44. /*
  45. Function: gdImageCreateFromTgaCtx
  46. Creates a gdImage from a gdIOCtx referencing a TGA binary file.
  47. Parameters:
  48. ctx - Pointer to a gdIOCtx structure
  49. */
  50. gdImagePtr gdImageCreateFromTgaCtx(gdIOCtx* ctx)
  51. {
  52. int bitmap_caret = 0;
  53. oTga *tga = NULL;
  54. /* int pixel_block_size = 0;
  55. int image_block_size = 0; */
  56. volatile gdImagePtr image = NULL;
  57. int x = 0;
  58. int y = 0;
  59. tga = (oTga *) gdMalloc(sizeof(oTga));
  60. if (!tga) {
  61. return NULL;
  62. }
  63. tga->bitmap = NULL;
  64. tga->ident = NULL;
  65. if (read_header_tga(ctx, tga) < 0) {
  66. free_tga(tga);
  67. return NULL;
  68. }
  69. /*TODO: Will this be used?
  70. pixel_block_size = tga->bits / 8;
  71. image_block_size = (tga->width * tga->height) * pixel_block_size;
  72. */
  73. if (read_image_tga(ctx, tga) < 0) {
  74. free_tga(tga);
  75. return NULL;
  76. }
  77. image = gdImageCreateTrueColor((int)tga->width, (int)tga->height );
  78. if (image == 0) {
  79. free_tga( tga );
  80. return NULL;
  81. }
  82. /*! \brief Populate GD image object
  83. * Copy the pixel data from our tga bitmap buffer into the GD image
  84. * Disable blending and save the alpha channel per default
  85. */
  86. if (tga->alphabits) {
  87. gdImageAlphaBlending(image, 0);
  88. gdImageSaveAlpha(image, 1);
  89. }
  90. /* TODO: use alphabits as soon as we support 24bit and other alpha bps (ie != 8bits) */
  91. for (y = 0; y < tga->height; y++) {
  92. register int *tpix = image->tpixels[y];
  93. for ( x = 0; x < tga->width; x++, tpix++) {
  94. if (tga->bits == TGA_BPP_24) {
  95. *tpix = gdTrueColor(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret]);
  96. bitmap_caret += 3;
  97. } else if (tga->bits == TGA_BPP_32 && tga->alphabits) {
  98. register int a = tga->bitmap[bitmap_caret + 3];
  99. *tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], gdAlphaMax - (a >> 1));
  100. bitmap_caret += 4;
  101. }
  102. }
  103. }
  104. if (tga->flipv && tga->fliph) {
  105. gdImageFlipBoth(image);
  106. } else if (tga->flipv) {
  107. gdImageFlipVertical(image);
  108. } else if (tga->fliph) {
  109. gdImageFlipHorizontal(image);
  110. }
  111. free_tga(tga);
  112. return image;
  113. }
  114. /*! \brief Reads a TGA header.
  115. * Reads the header block from a binary TGA file populating the referenced TGA structure.
  116. * \param ctx Pointer to TGA binary file
  117. * \param tga Pointer to TGA structure
  118. * \return int 1 on success, -1 on failure
  119. */
  120. int read_header_tga(gdIOCtx *ctx, oTga *tga)
  121. {
  122. unsigned char header[18];
  123. if (gdGetBuf(header, sizeof(header), ctx) < 18) {
  124. gd_error("Fail to read header");
  125. return -1;
  126. }
  127. tga->identsize = header[0];
  128. tga->colormaptype = header[1];
  129. tga->imagetype = header[2];
  130. tga->colormapstart = header[3] + (header[4] << 8);
  131. tga->colormaplength = header[5] + (header[6] << 8);
  132. tga->colormapbits = header[7];
  133. tga->xstart = header[8] + (header[9] << 8);
  134. tga->ystart = header[10] + (header[11] << 8);
  135. tga->width = header[12] + (header[13] << 8);
  136. tga->height = header[14] + (header[15] << 8);
  137. tga->bits = header[16];
  138. tga->alphabits = header[17] & 0x0f;
  139. tga->fliph = (header[17] & 0x10) ? 1 : 0;
  140. tga->flipv = (header[17] & 0x20) ? 0 : 1;
  141. #ifdef DEBUG
  142. printf("format bps: %i\n", tga->bits);
  143. printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv);
  144. printf("alpha: %i\n", tga->alphabits);
  145. printf("wxh: %i %i\n", tga->width, tga->height);
  146. #endif
  147. if (!((tga->bits == TGA_BPP_24 && tga->alphabits == 0)
  148. || (tga->bits == TGA_BPP_32 && tga->alphabits == 8)))
  149. {
  150. gd_error_ex(GD_WARNING, "gd-tga: %u bits per pixel with %u alpha bits not supported\n",
  151. tga->bits, tga->alphabits);
  152. return -1;
  153. }
  154. tga->ident = NULL;
  155. if (tga->identsize > 0) {
  156. tga->ident = (char *) gdMalloc(tga->identsize * sizeof(char));
  157. if(tga->ident == NULL) {
  158. return -1;
  159. }
  160. gdGetBuf(tga->ident, tga->identsize, ctx);
  161. }
  162. return 1;
  163. }
  164. /*! \brief Reads a TGA image data into buffer.
  165. * Reads the image data block from a binary TGA file populating the referenced TGA structure.
  166. * \param ctx Pointer to TGA binary file
  167. * \param tga Pointer to TGA structure
  168. * \return int 0 on success, -1 on failure
  169. */
  170. int read_image_tga( gdIOCtx *ctx, oTga *tga )
  171. {
  172. int pixel_block_size = (tga->bits / 8);
  173. int image_block_size;
  174. int* decompression_buffer = NULL;
  175. unsigned char* conversion_buffer = NULL;
  176. int buffer_caret = 0;
  177. int bitmap_caret = 0;
  178. int i = 0;
  179. int encoded_pixels;
  180. int rle_size;
  181. if(overflow2(tga->width, tga->height)) {
  182. return -1;
  183. }
  184. if(overflow2(tga->width * tga->height, pixel_block_size)) {
  185. return -1;
  186. }
  187. image_block_size = (tga->width * tga->height) * pixel_block_size;
  188. if(overflow2(image_block_size, sizeof(int))) {
  189. return -1;
  190. }
  191. /*! \todo Add more image type support.
  192. */
  193. if (tga->imagetype != TGA_TYPE_RGB && tga->imagetype != TGA_TYPE_RGB_RLE)
  194. return -1;
  195. /*! \brief Allocate memmory for image block
  196. * Allocate a chunk of memory for the image block to be passed into.
  197. */
  198. tga->bitmap = (int *) gdMalloc(image_block_size * sizeof(int));
  199. if (tga->bitmap == NULL)
  200. return -1;
  201. switch (tga->imagetype) {
  202. case TGA_TYPE_RGB:
  203. /*! \brief Read in uncompressed RGB TGA
  204. * Chunk load the pixel data from an uncompressed RGB type TGA.
  205. */
  206. conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
  207. if (conversion_buffer == NULL) {
  208. return -1;
  209. }
  210. if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) {
  211. gd_error("gd-tga: premature end of image data\n");
  212. gdFree(conversion_buffer);
  213. return -1;
  214. }
  215. while (buffer_caret < image_block_size) {
  216. tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret];
  217. buffer_caret++;
  218. }
  219. gdFree(conversion_buffer);
  220. break;
  221. case TGA_TYPE_RGB_RLE:
  222. /*! \brief Read in RLE compressed RGB TGA
  223. * Chunk load the pixel data from an RLE compressed RGB type TGA.
  224. */
  225. decompression_buffer = (int*) gdMalloc(image_block_size * sizeof(int));
  226. if (decompression_buffer == NULL) {
  227. return -1;
  228. }
  229. conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
  230. if (conversion_buffer == NULL) {
  231. gd_error("gd-tga: premature end of image data\n");
  232. gdFree( decompression_buffer );
  233. return -1;
  234. }
  235. rle_size = gdGetBuf(conversion_buffer, image_block_size, ctx);
  236. if (rle_size <= 0) {
  237. gdFree(conversion_buffer);
  238. gdFree(decompression_buffer);
  239. return -1;
  240. }
  241. buffer_caret = 0;
  242. while( buffer_caret < rle_size) {
  243. decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret];
  244. buffer_caret++;
  245. }
  246. buffer_caret = 0;
  247. while( bitmap_caret < image_block_size ) {
  248. if (buffer_caret + pixel_block_size > rle_size) {
  249. gdFree( decompression_buffer );
  250. gdFree( conversion_buffer );
  251. return -1;
  252. }
  253. if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) {
  254. encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 );
  255. buffer_caret++;
  256. if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
  257. || buffer_caret + pixel_block_size > rle_size) {
  258. gdFree( decompression_buffer );
  259. gdFree( conversion_buffer );
  260. return -1;
  261. }
  262. for (i = 0; i < encoded_pixels; i++) {
  263. memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size * sizeof(int));
  264. bitmap_caret += pixel_block_size;
  265. }
  266. buffer_caret += pixel_block_size;
  267. } else {
  268. encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
  269. buffer_caret++;
  270. if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
  271. || buffer_caret + (encoded_pixels * pixel_block_size) > rle_size) {
  272. gdFree( decompression_buffer );
  273. gdFree( conversion_buffer );
  274. return -1;
  275. }
  276. memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size * sizeof(int));
  277. bitmap_caret += (encoded_pixels * pixel_block_size);
  278. buffer_caret += (encoded_pixels * pixel_block_size);
  279. }
  280. }
  281. gdFree( decompression_buffer );
  282. gdFree( conversion_buffer );
  283. break;
  284. }
  285. return 1;
  286. }
  287. /*! \brief Cleans up a TGA structure.
  288. * Dereferences the bitmap referenced in a TGA structure, then the structure itself
  289. * \param tga Pointer to TGA structure
  290. */
  291. void free_tga(oTga * tga)
  292. {
  293. if (tga) {
  294. if (tga->ident)
  295. gdFree(tga->ident);
  296. if (tga->bitmap)
  297. gdFree(tga->bitmap);
  298. gdFree(tga);
  299. }
  300. }