26 #ifdef SIMAGE_TGA_SUPPORT
44 #define ERR_NO_ERROR 0
48 #define ERR_UNSUPPORTED 4
56 strncpy(buffer,
"TGA loader: Error opening file", buflen);
59 strncpy(buffer,
"TGA loader: Error reading file", buflen);
62 strncpy(buffer,
"TGA loader: Out of memory error", buflen);
72 convert_16_to_24(
const unsigned char *
const src,
unsigned char *
const dest)
75 unsigned int t0 = src[0];
76 unsigned int t1 = src[1];
77 dest[0] = (
unsigned char) (t0 & 0x1f) << 2;
78 dest[1] = (
unsigned char) (t1 & 0x7c) >> 2;
79 dest[2] = (
unsigned char) ((t1 & 0x3)<<3) | ((t0&0xe)>>5);
83 convert_16_to_32(
const unsigned char *
const src,
unsigned char *
const dest)
86 unsigned int t0 = src[0];
87 unsigned int t1 = src[1];
88 dest[0] = (
unsigned char) (t0 & 0x1f) << 2;
89 dest[1] = (
unsigned char) (t1 & 0x7c) >> 2;
90 dest[2] = (
unsigned char) ((t1 & 0x3)<<3) | ((t0&0xe)>>5);
91 dest[3] = (t1&0x70)?255:0;
95 convert_24_to_24(
const unsigned char *
const src,
unsigned char *
const dest)
105 convert_32_to_32(
const unsigned char *
const src,
unsigned char *
const dest)
116 convert_data(
const unsigned char *
const src,
unsigned char *
const dest,
117 const int x,
const int srcformat,
118 const int destformat)
120 if (srcformat == 2) {
122 convert_16_to_24(src+x*srcformat,
125 assert(destformat == 4);
126 convert_16_to_32(src+x*srcformat,
130 else if (srcformat == 3) {
131 assert(destformat == 3);
132 convert_24_to_24(src+x*srcformat,
136 assert(srcformat == 4 && destformat == 4);
137 convert_32_to_32(src+x*srcformat,
143 static int getInt16(
unsigned char *ptr)
147 return res | (tmp<<8);
153 static unsigned char *
154 rle_new_packet(
unsigned char * src,
156 int * rleIsCompressed,
157 unsigned char *rleCurrent,
158 const int rleEntrySize)
165 *rleRemaining = (code & 127) + 1;
167 *rleIsCompressed = 1;
168 for (i = 0; i < rleEntrySize; i++)
169 rleCurrent[i] = *src++;
172 *rleIsCompressed = 0;
180 static unsigned char *
181 rle_decode(
unsigned char * src,
185 int * rleIsCompressed,
186 unsigned char *rleCurrent,
187 const int rleEntrySize)
190 int remain, compress, size;
191 unsigned char *stop = dest + numbytes;
194 remain = *rleRemaining;
195 compress = *rleIsCompressed;
197 while (dest < stop) {
199 src = rle_new_packet(src, &remain, &compress,
200 rleCurrent, rleEntrySize);
203 for (i = 0; i < size; i++) {
204 *dest++ = rleCurrent[i];
208 for (i = 0; i < size; i++) {
214 *rleRemaining = remain;
215 *rleIsCompressed = compress;
223 int *numComponents_ret)
226 unsigned char header[18];
233 unsigned char *colormap;
238 unsigned char rleCurrent[4];
239 unsigned char *buffer;
242 unsigned char *linebuf;
246 fp = fopen(filename,
"rb");
252 if (fread(header, 1, 18, fp) != 18) {
259 width = getInt16(&header[12]);
260 height = getInt16(&header[14]);
261 depth = header[16] >> 3;
265 if ((type != 2 && type != 10) ||
266 (width < 0 || width > 4096) ||
267 (height < 0 || height > 4096) ||
268 (depth < 2 || depth > 4)) {
275 fseek(fp, header[0], SEEK_CUR);
278 if (header[1] == 1) {
279 int len = getInt16(&header[5]);
280 indexsize = header[7]>>3;
281 colormap = (
unsigned char *)malloc((
size_t)len*indexsize);
282 fread(colormap, 1, (
size_t)len*indexsize, fp);
286 if (flags & 1) format = 4;
296 rleEntrySize = depth;
297 buffer = (
unsigned char*)malloc((
size_t)width*height*format);
299 bpr = format * width;
300 linebuf = (
unsigned char *)malloc((
size_t)width*depth);
315 for (y = 0; y < height; y++) {
316 if (fread(linebuf, 1, (
size_t)width*depth, fp) != (
size_t)width*depth) {
320 for (x = 0; x < width; x++) {
321 convert_data(linebuf, dest, x, depth, format);
342 fseek(fp, 0, SEEK_END);
343 size = ftell(fp) - pos;
344 fseek(fp, pos, SEEK_SET);
345 buf = (
unsigned char *)malloc(size);
351 if (fread(buf, 1, size, fp) != (
unsigned int) size) {
355 for (y = 0; y < height; y++) {
356 src = rle_decode(src, linebuf, width*depth, &rleRemaining,
357 &rleIsCompressed, rleCurrent, rleEntrySize);
358 assert(src <= buf + size);
359 for (x = 0; x < width; x++) {
360 convert_data(linebuf, dest, x, depth, format);
371 if (linebuf) free(linebuf);
375 if (buffer) free(buffer);
380 *height_ret = height;
381 *numComponents_ret = format;
389 const unsigned char *buf,
393 if (headerlen < 18)
return 0;
394 ptr = strrchr(filename,
'.');
397 if (strcmp(ptr,
".tga") && strcmp(ptr,
".TGA"))
return 0;
399 if (buf[1] == 1 && buf[2] == 1 && buf[17] < 64) {
404 if ((buf[1] == 0 || buf[1] == 1) && buf[2] == 2 && buf[17] < 64)
return 1;
405 if (buf[1] == 1 && buf[2] == 9 && buf[17] < 64) {
412 if ((buf[1] == 0 || buf[1] == 1) && buf[2] == 10 && buf[17] < 64) {
int simage_tga_error(char *buffer, int bufferlen)
unsigned char * simage_tga_load(const char *filename, int *width, int *height, int *numComponents)
int simage_tga_identify(const char *filename, const unsigned char *header, int headerlen)