コード例 #1
0
//==============================================================================
static ANKI_USE_RESULT Error loadCompressedTga(
	File& fs, U32& width, U32& height, U32& bpp, DArray<U8>& data,
	GenericMemoryPoolAllocator<U8>& alloc)
{
	Array<U8, 6> header6;
	ANKI_CHECK(fs.read(reinterpret_cast<char*>(&header6[0]), sizeof(header6)));

	width  = header6[1] * 256 + header6[0];
	height = header6[3] * 256 + header6[2];
	bpp	= header6[4];

	if((width <= 0) || (height <= 0) || ((bpp != 24) && (bpp != 32)))
	{
		ANKI_LOGE("Invalid texture information");
		return ErrorCode::USER_DATA;
	}

	I bytesPerPxl = (bpp / 8);
	I imageSize = bytesPerPxl * width * height;
	data.create(alloc, imageSize);

	U pixelcount = height * width;
	U currentpixel = 0;
	U currentbyte = 0;
	U8 colorbuffer[4];

	do
	{
		U8 chunkheader = 0;

		ANKI_CHECK(fs.read((char*)&chunkheader, sizeof(U8)));

		if(chunkheader < 128)
		{
			chunkheader++;
			for(int counter = 0; counter < chunkheader; counter++)
			{
				ANKI_CHECK(fs.read((char*)&colorbuffer[0], bytesPerPxl));

				data[currentbyte] = colorbuffer[2];
				data[currentbyte + 1] = colorbuffer[1];
				data[currentbyte + 2] = colorbuffer[0];

				if(bytesPerPxl == 4)
				{
					data[currentbyte + 3] = colorbuffer[3];
				}

				currentbyte += bytesPerPxl;
				currentpixel++;

				if(currentpixel > pixelcount)
				{
					ANKI_LOGE("Too many pixels read");
					return ErrorCode::USER_DATA;
				}
			}
		}
		else
		{
			chunkheader -= 127;
			ANKI_CHECK(fs.read((char*)&colorbuffer[0], bytesPerPxl));

			for(int counter = 0; counter < chunkheader; counter++)
			{
				data[currentbyte] = colorbuffer[2];
				data[currentbyte + 1] = colorbuffer[1];
				data[currentbyte + 2] = colorbuffer[0];

				if(bytesPerPxl == 4)
				{
					data[currentbyte + 3] = colorbuffer[3];
				}

				currentbyte += bytesPerPxl;
				currentpixel++;

				if(currentpixel > pixelcount)
				{
					ANKI_LOGE("Too many pixels read");
					data.destroy(alloc);
					return ErrorCode::USER_DATA;
				}
			}
		}
	} while(currentpixel < pixelcount);

	return ErrorCode::NONE;
}