/* LoadTGA */ byte * LoadTGA (QFile *fin) { int columns, rows, numPixels; byte *pixbuf; int row, column; unsigned char red = 0, green = 0, blue = 0, alphabyte = 0; TargaHeader targa_header; byte *targa_rgba; targa_header.id_length = Qgetc (fin); targa_header.colormap_type = Qgetc (fin); targa_header.image_type = Qgetc (fin); targa_header.colormap_index = fgetLittleShort (fin); targa_header.colormap_length = fgetLittleShort (fin); targa_header.colormap_size = Qgetc (fin); targa_header.x_origin = fgetLittleShort (fin); targa_header.y_origin = fgetLittleShort (fin); targa_header.width = fgetLittleShort (fin); targa_header.height = fgetLittleShort (fin); targa_header.pixel_size = Qgetc (fin); targa_header.attributes = Qgetc (fin); if (targa_header.image_type != 2 && targa_header.image_type != 10) Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n"); if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24)) Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); columns = targa_header.width; rows = targa_header.height; numPixels = columns * rows; targa_rgba = malloc (numPixels * 4); if (targa_header.id_length != 0) Qseek (fin, targa_header.id_length, SEEK_CUR); // skip TARGA image // comment if (targa_header.image_type == 2) { // Uncompressed, RGB images for (row = rows - 1; row >= 0; row--) { pixbuf = targa_rgba + row * columns * 4; for (column = 0; column < columns; column++) { switch (targa_header.pixel_size) { case 24: blue = Qgetc (fin); green = Qgetc (fin); red = Qgetc (fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = 255; break; case 32: blue = Qgetc (fin); green = Qgetc (fin); red = Qgetc (fin); alphabyte = Qgetc (fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; break; } } } } else if (targa_header.image_type == 10) { // Runlength encoded RGB // images unsigned char packetHeader, packetSize, j; for (row = rows - 1; row >= 0; row--) { pixbuf = targa_rgba + row * columns * 4; for (column = 0; column < columns;) { packetHeader = Qgetc (fin); packetSize = 1 + (packetHeader & 0x7f); if (packetHeader & 0x80) { // run-length packet switch (targa_header.pixel_size) { case 24: blue = Qgetc (fin); green = Qgetc (fin); red = Qgetc (fin); alphabyte = 255; break; case 32: blue = Qgetc (fin); green = Qgetc (fin); red = Qgetc (fin); alphabyte = Qgetc (fin); break; } for (j = 0; j < packetSize; j++) { *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; column++; if (column == columns) { // run spans across rows column = 0; if (row > 0) row--; else goto breakOut; pixbuf = targa_rgba + row * columns * 4; } } } else { // non run-length packet for (j = 0; j < packetSize; j++) { switch (targa_header.pixel_size) { case 24: blue = Qgetc (fin); green = Qgetc (fin); red = Qgetc (fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = 255; break; case 32: blue = Qgetc (fin); green = Qgetc (fin); red = Qgetc (fin); alphabyte = Qgetc (fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; break; } column++; if (column == columns) { // pixel packet run spans // across rows column = 0; if (row > 0) row--; else goto breakOut; pixbuf = targa_rgba + row * columns * 4; } } } } breakOut:; } } Qclose (fin); return targa_rgba; }
/* ============= LoadTGA ============= */ void LoadTGA (FILE *fin) { int columns, rows, numPixels; byte *pixbuf; int row, column; targa_header.id_length = fgetc(fin); targa_header.colormap_type = fgetc(fin); targa_header.image_type = fgetc(fin); targa_header.colormap_index = fgetLittleShort(fin); targa_header.colormap_length = fgetLittleShort(fin); targa_header.colormap_size = fgetc(fin); targa_header.x_origin = fgetLittleShort(fin); targa_header.y_origin = fgetLittleShort(fin); targa_header.width = fgetLittleShort(fin); targa_header.height = fgetLittleShort(fin); targa_header.pixel_size = fgetc(fin); targa_header.attributes = fgetc(fin); if (targa_header.image_type != 2 && targa_header.image_type != 10) Sys_Error ("%s: Only type 2 and 10 targa RGB images supported", __thisfunc__); if ((targa_header.pixel_size != 32 && targa_header.pixel_size != 24) || targa_header.colormap_type !=0) Sys_Error ("%s: Only 32 or 24 bit images supported (no colormaps)", __thisfunc__); columns = targa_header.width; rows = targa_header.height; numPixels = columns * rows; targa_rgba = Hunk_AllocName(numPixels * 4, "tgafile_data"); if (targa_header.id_length != 0) // skip TARGA image comment fseek(fin, targa_header.id_length, SEEK_CUR); if (targa_header.image_type == 2) { // Uncompressed, RGB images for (row = rows-1; row >= 0; row--) { pixbuf = targa_rgba + row*columns*4; for (column = 0; column < columns; column++) { unsigned char red, green, blue, alphabyte; switch (targa_header.pixel_size) { case 24: blue = getc(fin); green = getc(fin); red = getc(fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = 255; break; case 32: blue = getc(fin); green = getc(fin); red = getc(fin); alphabyte = getc(fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; break; } } } } else if (targa_header.image_type == 10) { // Runlength encoded RGB images unsigned char red, green, blue, alphabyte; unsigned char packetHeader, packetSize, j; for (row = rows-1; row >= 0; row--) { pixbuf = targa_rgba + row*columns*4; for (column = 0 ; column < columns ; ) { packetHeader = getc(fin); packetSize = 1 + (packetHeader & 0x7f); if (packetHeader & 0x80) { // run-length packet switch (targa_header.pixel_size) { case 24: blue = getc(fin); green = getc(fin); red = getc(fin); alphabyte = 255; break; case 32: blue = getc(fin); green = getc(fin); red = getc(fin); alphabyte = getc(fin); break; } for (j = 0; j < packetSize; j++) { *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; column++; if (column == columns) { // run spans across rows column = 0; if (row > 0) row--; else goto breakOut; pixbuf = targa_rgba + row*columns*4; } } } else { // non run-length packet for (j = 0; j < packetSize; j++) { switch (targa_header.pixel_size) { case 24: blue = getc(fin); green = getc(fin); red = getc(fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = 255; break; case 32: blue = getc(fin); green = getc(fin); red = getc(fin); alphabyte = getc(fin); *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; break; } column++; if (column == columns) { // pixel packet run spans across rows column = 0; if (row > 0) row--; else goto breakOut; pixbuf = targa_rgba + row*columns*4; } } } } breakOut:; } } fclose(fin); }