diff options
Diffstat (limited to 'core/tga.cpp')
| -rw-r--r-- | core/tga.cpp | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/core/tga.cpp b/core/tga.cpp new file mode 100644 index 0000000..802b9ec --- /dev/null +++ b/core/tga.cpp @@ -0,0 +1,263 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2013-2016 NVIDIA Corporation. All rights reserved. + +#include "tga.h" +#include "core.h" +#include "types.h" + +#include <stdio.h> +#include <string.h> + +using namespace std; + +struct TgaHeader +{ + uint8_t identsize; // size of ID field that follows 18 uint8_t header (0 usually) + uint8_t colourmaptype; // type of colour map 0=none, 1=has palette + uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + uint16_t colourmapstart; // first colour map entry in palette + uint16_t colourmaplength; // number of colours in palette + uint8_t colourmapbits; // number of bits per palette entry 15,16,24,32 + + uint16_t xstart; // image x origin + uint16_t ystart; // image y origin + uint16_t width; // image width in pixels + uint16_t height; // image height in pixels + uint8_t bits; // image bits per pixel 8,16,24,32 + uint8_t descriptor; // image descriptor bits (vh flip bits) + + // pixel data follows header +}; + +namespace +{ + + void memwrite(void* src, uint32_t size, unsigned char*& buffer) + { + memcpy(buffer, src, size); + buffer += size; + } +} + + + +bool TgaSave(const char* filename, const TgaImage& image, bool rle) +{ + FILE* f = fopen(filename, "wb"); + if (f) + { + bool b = TgaSave(f, image, rle); + fclose(f); + + return b; + } + + return false; +} + +bool TgaSave(FILE* f, const TgaImage& image, bool rle) +{ + TgaHeader header; + + header.identsize = 0; + header.colourmaptype = 0; + header.imagetype = rle?9:2; + header.colourmapstart = 0; + header.colourmaplength = 0; + header.colourmapbits = 0; + header.xstart = 0; + header.ystart = 0; + header.width = image.m_width; + header.height = image.m_height; + header.bits = 32; + header.descriptor = 0;//uint16((1<<3)|(1<<5)); + + if (f) + { + unsigned char* data = (unsigned char*)new uint32_t[image.m_width*image.m_height + sizeof(header)]; + unsigned char* writeptr = data; + + memwrite(&header.identsize, sizeof(header.identsize), writeptr); + memwrite(&header.colourmaptype, sizeof(header.colourmaptype), writeptr); + memwrite(&header.imagetype, sizeof(header.imagetype), writeptr); + memwrite(&header.colourmapstart, sizeof(header.colourmapstart), writeptr); + memwrite(&header.colourmaplength, sizeof(header.colourmaplength), writeptr); + memwrite(&header.colourmapbits, sizeof(header.colourmapbits), writeptr); + memwrite(&header.xstart, sizeof(header.xstart), writeptr); + memwrite(&header.ystart, sizeof(header.ystart), writeptr); + memwrite(&header.width, sizeof(header.width), writeptr); + memwrite(&header.height, sizeof(header.height), writeptr); + memwrite(&header.bits, sizeof(header.bits), writeptr); + memwrite(&header.descriptor, sizeof(header.descriptor), writeptr); + + union texel + { + uint32_t u32; + uint8_t u8[4]; + }; + + texel* t = (texel*)image.m_data; + for (int i=0; i < image.m_width*image.m_height; ++i) + { + texel tmp = t[i]; + swap(tmp.u8[0], tmp.u8[2]); + memwrite(&tmp.u32, 4, writeptr); + } + + fwrite(data, writeptr-data, 1, f); + //fclose(f); + + delete[] data; + + return true; + } + else + { + return false; + } +} + + +bool TgaLoad(const char* filename, TgaImage& image) +{ + if (!filename) + return false; + + FILE* aTGAFile = fopen(filename, "rb"); + if (aTGAFile == NULL) + { + printf("Texture: could not open %s for reading.\n", filename); + return NULL; + } + + char aHeaderIDLen; + size_t err; + err = fread(&aHeaderIDLen, sizeof(uint8_t), 1, aTGAFile); + + char aColorMapType; + err = fread(&aColorMapType, sizeof(uint8_t), 1, aTGAFile); + + char anImageType; + err = fread(&anImageType, sizeof(uint8_t), 1, aTGAFile); + + short aFirstEntryIdx; + err = fread(&aFirstEntryIdx, sizeof(uint16_t), 1, aTGAFile); + + short aColorMapLen; + err = fread(&aColorMapLen, sizeof(uint16_t), 1, aTGAFile); + + char aColorMapEntrySize; + err = fread(&aColorMapEntrySize, sizeof(uint8_t), 1, aTGAFile); + + short anXOrigin; + err = fread(&anXOrigin, sizeof(uint16_t), 1, aTGAFile); + + short aYOrigin; + err = fread(&aYOrigin, sizeof(uint16_t), 1, aTGAFile); + + short anImageWidth; + err = fread(&anImageWidth, sizeof(uint16_t), 1, aTGAFile); + + short anImageHeight; + err = fread(&anImageHeight, sizeof(uint16_t), 1, aTGAFile); + + char aBitCount = 32; + err = fread(&aBitCount, sizeof(uint8_t), 1, aTGAFile); + + char anImageDescriptor;// = 8 | (1<<5); + err = fread((char*)&anImageDescriptor, sizeof(uint8_t), 1, aTGAFile); + + // supress warning + (void)err; + + // total is the number of bytes we'll have to read + uint8_t numComponents = aBitCount / 8; + uint32_t numTexels = anImageWidth * anImageHeight; + + // allocate memory for image pixels + image.m_width = anImageWidth; + image.m_height = anImageHeight; + image.m_data = new uint32_t[numTexels]; + + // load the image pixels + for (uint32_t i=0; i < numTexels; ++i) + { + union texel + { + uint32_t u32; + uint8_t u8[4]; + }; + + texel t; + t.u32 = 0; + + if (!fread(&t.u32, numComponents, 1, aTGAFile)) + { + printf("Texture: file not fully read, may be corrupt (%s)\n", filename); + } + + // stores it as BGR(A) so we'll have to swap R and B. + swap(t.u8[0], t.u8[2]); + + + image.m_data[i] = t.u32; + } + + // if bit 5 of the descriptor is set then the image is flipped vertically so we fix it up + if (anImageDescriptor & (1 << 5)) + { + + // swap all the rows + int rowSize = image.m_width*4; + + uint8_t* buf = new uint8_t[image.m_width*4]; + uint8_t* start = (uint8_t*)image.m_data; + uint8_t* end = &((uint8_t*)image.m_data)[rowSize*(image.m_height-1)]; + + while (start < end) + { + memcpy(buf, end, rowSize); + memcpy(end, start, rowSize); + memcpy(start, buf, rowSize); + + start += rowSize; + end -= rowSize; + } + + delete[] buf; + } + + fclose(aTGAFile); + + return true; +} + +void TgaFree(const TgaImage& image) +{ + delete[] image.m_data; +} |