#include #include #include "txd.h" void correctindices(int width, int height, char *indices) { int i; unsigned char temp; char map[4] = {0, 16, 8, 24}; for (i = 0; i < width*height; i++) { temp = indices[i]; indices[i] = (temp & ~24) | map[(temp & 24) >> 3]; } } void swizzle8(unsigned char *indices, unsigned char *rawindices, int width, int height) { int y, x; for (y = 0; y < height; y++) for (x = 0; x < width; x++) { int block_loc = (y&(~0x0F))*width + (x&(~0x0F))*2; unsigned int swap_sel = (((y+2)>>2)&0x01)*4; int ypos = (((y&(~3))>>1) + (y&1))&0x07; int column_loc = ypos*width*2 + ((x+swap_sel)&0x07)*4; int byte_sum = ((y>>1)&1) + ((x>>2)&2); int swizzled = block_loc + column_loc + byte_sum; indices[swizzled] = rawindices[y*width+x]; } } unsigned char *ReadTga(unsigned char colors[][4], unsigned char *indices, image *img, FILE *tga) { int i; unsigned short pallength; unsigned short txdpallength; unsigned char tempc; unsigned short temps; unsigned char bpp; unsigned short width; unsigned short height; int hasalpha; unsigned char *rawindices; /* Id length */ fseek(tga, 1, 0); /* Has palette */ fread(&tempc, 1, 1, tga); if (tempc != 1) { fprintf(stderr, "Only indexed pictures supported\n"); exit(4); } /* picture type (1 = indexed) */ fread(&tempc, 1, 1, tga); if (tempc != 1) { fprintf(stderr, "Only indexed pictures supported\n"); exit(4); } /* begin of palette */ fseek(tga, 2, SEEK_CUR); /* length of palette */ fread(&pallength, 2, 1, tga); /* bits per palette entry */ fread(&tempc, 1, 1, tga); if (tempc == 0x18) hasalpha = 0; else hasalpha = 1; /* X origin */ fread(&temps, 2, 1, tga); if (temps != 0) { fprintf(stderr, "X origin must be 0\n"); exit(4); } /* Y origin */ fread(&temps, 2, 1, tga); if (temps != 0) { fprintf(stderr, "Y origin must be 0\n"); exit(4); } /* Width */ fread(&width, 2, 1, tga); /* Height */ fread(&height, 2, 1, tga); /* bits per pixel */ fread(&bpp, 1, 1, tga); if (bpp != 8) { fprintf(stderr, "Only 8 bit pictures supported\n"); exit(4); } /* attributes */ fread(&tempc, 1, 1, tga); if ((tempc & 0x20) == 0) { fprintf(stderr, "Origin must be at upper left\n"); exit(4); } /* Set pallength either as 16 or 256 */ if (pallength > 16 && pallength <= 256) txdpallength = 256; else if (pallength <= 16) txdpallength = 16; else { fprintf(stderr, "Unsupported palette\n"); exit(4); } printf("%lX\n", ftell(tga)); for (i = 0; i < pallength; i++) { colors[i][2] = getc(tga); colors[i][1] = getc(tga); colors[i][0] = getc(tga); if (hasalpha) colors[i][3] = getc(tga) / 2 + 1; else colors[i][3] = 0x80; } for (; i < txdpallength; i++) { colors[i][2] = 0; colors[i][1] = 0; colors[i][0] = 0; colors[i][3] = 0x80; } indices = (unsigned char *) malloc(width*height); rawindices = (unsigned char *) malloc(width*height); fread(rawindices, 1, width*height, tga); correctindices(width, height, rawindices); swizzle8(indices, rawindices, width, height); free(rawindices); return indices; }