diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /common/tgaloader.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'common/tgaloader.cpp')
| -rw-r--r-- | common/tgaloader.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/common/tgaloader.cpp b/common/tgaloader.cpp new file mode 100644 index 0000000..88d6240 --- /dev/null +++ b/common/tgaloader.cpp @@ -0,0 +1,279 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "tgaloader.h" +#include "tier0/dbg.h" + +#pragma pack(1) +typedef struct _TargaHeader { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} TargaHeader; +#pragma pack() + +#define TGA_ATTRIBUTE_HFLIP 16 +#define TGA_ATTRIBUTE_VFLIP 32 + + +int fgetLittleShort (unsigned char **p) +{ + byte b1, b2; + + b1 = *((*p)++); + b2 = *((*p)++); + + return (short)(b1 + b2*256); +} + +int fgetLittleLong (unsigned char **p) +{ + byte b1, b2, b3, b4; + + b1 = *((*p)++); + b2 = *((*p)++); + b3 = *((*p)++); + b4 = *((*p)++); + + return b1 + (b2<<8) + (b3<<16) + (b4<<24); +} + + +bool GetTGADimensions( int32 iBytes, char *pData, int * width, int *height ) +{ + TargaHeader header; + unsigned char *p = (unsigned char *)pData; + if (width) *width = 0; + if (height) *height = 0; + + header.id_length = *(p++); + header.colormap_type = *(p++); + header.image_type = *(p++); + + header.colormap_index = fgetLittleShort(&p); + header.colormap_length = fgetLittleShort(&p); + header.colormap_size = *(p++); + header.x_origin = fgetLittleShort(&p); + header.y_origin = fgetLittleShort(&p); + header.width = fgetLittleShort(&p); + header.height = fgetLittleShort(&p); + header.pixel_size = *(p++); + header.attributes = *(p++); + + if ( header.image_type != 2 && header.image_type != 10 ) + { + Msg( "LoadTGA: Only type 2 and 10 targa RGB images supported\n" ); + return false; + } + + if ( header.colormap_type !=0 || ( header.pixel_size != 32 && header.pixel_size != 24 ) ) + { + Msg("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); + return false; + } + + if (width) *width = header.width; + if (height) *height = header.height; + return true; +} + + +bool LoadTGA( int32 iBytes, char *pData, byte **rawImage, int * rawImageBytes, int * width, int *height ) +{ + TargaHeader header; + unsigned char *p = (unsigned char *)pData; + if (width) *width = 0; + if (height) *height = 0; + + header.id_length = *(p++); + header.colormap_type = *(p++); + header.image_type = *(p++); + + header.colormap_index = fgetLittleShort(&p); + header.colormap_length = fgetLittleShort(&p); + header.colormap_size = *(p++); + header.x_origin = fgetLittleShort(&p); + header.y_origin = fgetLittleShort(&p); + header.width = fgetLittleShort(&p); + header.height = fgetLittleShort(&p); + header.pixel_size = *(p++); + header.attributes = *(p++); + + if ( header.image_type != 2 && header.image_type != 10 ) + { + Msg( "LoadTGA: Only type 2 and 10 targa RGB images supported\n" ); + return false; + } + + if ( header.colormap_type !=0 || ( header.pixel_size != 32 && header.pixel_size != 24 ) ) + { + Msg("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); + return false; + } + + int columns = header.width; + int rows = header.height; + int numPixels = columns * rows; + + if (width) *width = header.width; + if (height) *height = header.height; + if (rawImageBytes) *rawImageBytes = header.width * header.height * 4; + + *rawImage = new byte[ numPixels * 4 ]; + byte *pixbuf = *rawImage; + + if ( header.id_length != 0 ) + p += header.id_length; // skip TARGA image comment. + + if ( header.image_type == 2 ) { // Uncompressed, RGB images + for(int row = rows - 1; row >=0; row-- ) + { + if ( header.attributes & TGA_ATTRIBUTE_VFLIP ) + pixbuf = *rawImage + (rows-row-1)*columns*4; + else + pixbuf = *rawImage + row*columns*4; + + for(int column=0; column < columns; column++) + { + unsigned char red,green,blue,alphabyte; + switch ( header.pixel_size ) + { + case 24: + + blue = *(p++); + green = *(p++); + red = *(p++); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = *(p++); + green = *(p++); + red = *(p++); + alphabyte = *(p++); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = alphabyte; + break; + } + } + } + } + else if ( header.image_type == 10 ) + { + // Runlength encoded RGB images + unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j; + for( int row = rows - 1; row >= 0; row--) + { + if ( header.attributes & TGA_ATTRIBUTE_VFLIP ) + pixbuf = *rawImage + (rows-row-1)*columns*4; + else + pixbuf = *rawImage + row*columns*4; + + for( int column=0; column < columns; ) { + packetHeader=*(p++); + packetSize = 1 + (packetHeader & 0x7f); + if (packetHeader & 0x80) { // run-length packet + switch ( header.pixel_size ) + { + case 24: + blue = *(p++); + green = *(p++); + red = *(p++); + alphabyte = 255; + break; + case 32: + default: + blue = *(p++); + green = *(p++); + red = *(p++); + alphabyte = *(p++); + 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 = *rawImage + row*columns*4; + } + } + } + else + { // non run-length packet + for(j=0;j<packetSize;j++) { + switch (header.pixel_size) { + case 24: + blue = *(p++); + green = *(p++); + red = *(p++); + *pixbuf++ = red; + *pixbuf++ = green; + *pixbuf++ = blue; + *pixbuf++ = 255; + break; + case 32: + blue = *(p++); + green = *(p++); + red = *(p++); + alphabyte = *(p++); + *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 = *rawImage + row*columns*4; + } + } + } + } +breakOut:; + } + } + + return true; +} + +void WriteTGA( const char *pchFileName, void *rgba, int wide, int tall ) +{ + _TargaHeader header; + memset( &header, 0x0, sizeof(header) ); + header.width = wide; + header.height = tall; + header.image_type = 2; + header.pixel_size = 32; + + FILE *fp = fopen( pchFileName, "w+" ); + fwrite( &header, 1, sizeof(header), fp ); + fwrite( rgba, 1, wide*tall*4, fp ); + fclose(fp); + +} + + |