From e5261249335b2e6f5f6c2b42af3e70d6ba2259a0 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Tue, 16 Mar 2021 02:26:01 +0600 Subject: [PATCH] - added Targa loading code --- src_rebuild/utils/targa.cpp | 180 ++++++++++++++++++++++++++++++++++++ src_rebuild/utils/targa.h | 28 ++++++ 2 files changed, 208 insertions(+) create mode 100644 src_rebuild/utils/targa.cpp create mode 100644 src_rebuild/utils/targa.h diff --git a/src_rebuild/utils/targa.cpp b/src_rebuild/utils/targa.cpp new file mode 100644 index 00000000..24d45df1 --- /dev/null +++ b/src_rebuild/utils/targa.cpp @@ -0,0 +1,180 @@ +#include "targa.h" +#include +#include + +bool LoadTGAImage(const char* filename, u_char** data, int& width, int& height, int& bpp) +{ + FILE* fp; + TGAHeader header; + + int size, x, y, pixelSize, palLength; + u_char* tempBuffer, * fBuffer, * dest, * src; + uint tempPixel; + u_char palette[768]; + + fp = fopen(filename, "rb"); + if (!fp) + return false; + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + // Read the header + fread(&header, sizeof(header), 1, fp); + + width = header.width; + height = header.height; + + pixelSize = header.bpp / 8; + + if ((palLength = header.descriptionlen + header.cmapentries * header.cmapbits / 8) > 0) + fread(palette, sizeof(palette), 1, fp); + + // Read the file data + fBuffer = new u_char[size - sizeof(header) - palLength]; + fread(fBuffer, size - sizeof(header) - palLength, 1, fp); + fclose(fp); + + size = width * height * pixelSize; + + // Decode if rle compressed. Bit 3 of .imagetype tells if the file is compressed + if (header.imagetype & 0x08) + { + uint c, count; + + tempBuffer = new u_char[size]; + + dest = tempBuffer; + src = fBuffer; + + while (size > 0) + { + // Get packet header + c = *src++; + + count = (c & 0x7f) + 1; + size -= count * pixelSize; + + if (c & 0x80) + { + // Rle packet + do + { + memcpy(dest, src, pixelSize); + dest += pixelSize; + } while (--count); + + src += pixelSize; + } + else + { + // Raw packet + count *= pixelSize; + memcpy(dest, src, count); + src += count; + dest += count; + } + } + + src = tempBuffer; + } + else + { + tempBuffer = NULL; + src = fBuffer; + } + + src += (header.bpp / 8) * width * (height - 1); + + bpp = header.bpp; + + switch (header.bpp) + { + case 8: + if (palLength > 0) + { + bpp = 24; + dest = *data = new u_char[width * height * 3]; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + tempPixel = 3 * (*src++); + *dest++ = palette[tempPixel + 2]; + *dest++ = palette[tempPixel + 1]; + *dest++ = palette[tempPixel]; + } + src -= 2 * width; + } + } + else + { + bpp = 8; + dest = *data = new u_char[width * height]; + for (y = 0; y < height; y++) + { + memcpy(dest, src, width); + dest += width; + src -= width; + } + } + break; + case 16: + bpp = 32; + dest = *data = new u_char[width * height * 4]; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + tempPixel = *((unsigned short*)src); + + dest[0] = ((tempPixel >> 10) & 0x1F) << 3; + dest[1] = ((tempPixel >> 5) & 0x1F) << 3; + dest[2] = ((tempPixel) & 0x1F) << 3; + dest[3] = ((tempPixel >> 15) ? 0xFF : 0); + dest += 4; + src += 2; + } + src -= 4 * width; + } + break; + case 24: + bpp = 24; + dest = *data = new u_char[width * height * 3]; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + *dest++ = src[2]; + *dest++ = src[1]; + *dest++ = src[0]; + src += 3; + } + src -= 6 * width; + } + break; + case 32: + bpp = 32; + dest = *data = new u_char[width * height * 4]; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + *dest++ = src[2]; + *dest++ = src[1]; + *dest++ = src[0]; + *dest++ = src[3]; + src += 4; + } + src -= 8 * width; + } + break; + } + + delete[] tempBuffer; + delete[] fBuffer; + + return true; +} \ No newline at end of file diff --git a/src_rebuild/utils/targa.h b/src_rebuild/utils/targa.h new file mode 100644 index 00000000..12423c0b --- /dev/null +++ b/src_rebuild/utils/targa.h @@ -0,0 +1,28 @@ +#ifndef TARGA_H +#define TARGA_H + +#include "TYPES.H" + +#pragma pack (push, 1) + +struct TGAHeader +{ + u_char descriptionlen; + u_char cmaptype; + u_char imagetype; + u_short cmapstart; + u_short cmapentries; + u_char cmapbits; + u_short xoffset; + u_short yoffset; + u_short width; + u_short height; + u_char bpp; + u_char attrib; +}; + +#pragma pack (pop) + +bool LoadTGAImage(const char* filename, u_char** data, int& width, int& height, int& bpp); + +#endif // TARGA_H \ No newline at end of file