예제 #1
0
Adventure::ITexture* Adventure::Image::LoadTgaFromFile(File& file, IDisplay& display, Allocator* scratch)
{
	file.GetStream().seekg(2, std::ios::beg);
	
	File::UInt8 type;
	file.Read(type);
	
	if (type != 2) // Type 2 indicates a regular image
		return NULL;
	
	file.GetStream().seekg(12, std::ios::beg);
	
	File::UInt16 width, height;
	file.Read(width);
	file.Read(height);
	
	int pixels = width * height;
	
	file.GetStream().seekg(16, std::ios::beg);
	
	File::UInt8 bits;
	file.Read(bits);
	
	if (bits < 24)
		return NULL;
	
	file.GetStream().seekg(18, std::ios::beg);
	
	Color* pixelData = new(scratch) Color[pixels];
	
	for (int i = 0; i < pixels; i++)
	{
		// BGRA format
		file.Read(pixelData[i].Blue);
		file.Read(pixelData[i].Green);
		file.Read(pixelData[i].Red);
		
		if (bits == 32)
			file.Read(pixelData[i].Alpha);
		else
			pixelData[i].Alpha = Color::MaxChannelValue;
	}
	
	ITexture* texture = display.CreateTexture();
	
	if (texture == NULL)
	{
		Deallocate(pixelData, scratch);
		return NULL;
	}
	
	texture->SetData(pixelData, width, height, ITexture::Rgba8, ITexture::Point);
	
	Deallocate(pixelData, scratch);
		
	return texture;
}
예제 #2
0
Adventure::ITexture* Adventure::Image::LoadBmpFromFile(File& file, IDisplay& display, Allocator* scratch)
{
	struct
	{
		File::UInt8 Type[2];
		File::UInt32 Size;
		File::UInt32 Reserved;
		File::UInt32 Offset;
	} header;
	
	TRACE(DEBUG_FILE_LOADING, "Loading BMP file...");
	
	file.Read(header.Type[0]);
	file.Read(header.Type[1]);
	
	if (header.Type[0] != 'B' || header.Type[1] != 'M')
		return NULL;
	
	file.Read(header.Size);
	file.Read(header.Reserved);
	file.Read(header.Offset);
	
	TRACE(DEBUG_FILE_LOADING, "Loaded header.");
	
	struct
	{
		File::UInt32 Size;
		File::Int32 Width;
		File::Int32 Height;
		File::UInt16 Planes;
		File::UInt16 Bits;
		File::UInt32 Compression;
		File::UInt32 DataSize;
		File::Int32 XPixelsPerMeter;
		File::Int32 YPixelsPerMeter;
		File::UInt32 Colors;
		File::UInt32 ImportantColors;
	} info;
	
	file.Read(info.Size);
	file.Read(info.Width);
	file.Read(info.Height);
	file.Read(info.Planes);
	file.Read(info.Bits);
	
	if (!(info.Bits == 8 || info.Bits == 24))
		return NULL;
		
	TRACE(DEBUG_FILE_LOADING, "BMP is of valid bit depth (8 or 24 bits)");
	
	file.Read(info.Compression);
	file.Read(info.DataSize);
	file.Read(info.XPixelsPerMeter);
	file.Read(info.YPixelsPerMeter);
	file.Read(info.Colors);
	file.Read(info.ImportantColors);
	
	Color* table = NULL;
	if (info.Bits == 8)
	{
		TRACE(DEBUG_FILE_LOADING, "Reading color table...");
		
		table = new(scratch) Color[256];
		
		for (int i = 0; i < 256; i++)
		{
			file.Read(table[i].Blue);
			file.Read(table[i].Green);
			file.Read(table[i].Red);
			table[i].Alpha = Color::MaxChannelValue;
			
			File::UInt8 reserved;
			file.Read(reserved);
		}
		
		TRACE(DEBUG_FILE_LOADING, "Read color table.");
	}
	
	TRACE(DEBUG_FILE_LOADING, "Reading image data...");
	
	int size = header.Size - header.Offset;
	File::UInt8* data = new(scratch) File::UInt8[size];
	file.GetStream().read((char*)data, size);
	
	TRACE(DEBUG_FILE_LOADING, "Read image data.");
	
	Color* pixels = new(scratch) Color[info.Width * abs(info.Height)];
	
	int height = abs(info.Height);
	
	int width = info.Width * info.Bits / 8; // Only 24 and 8 bit formats supported
	int stride = (width + 3) & ~3; // Round to nearest multiple of four
	
	int y = 0;
	
	TRACE(DEBUG_FILE_LOADING, "Converting image data to RGBA...");
	
	while (y < height)
	{
		if (info.Bits == 8)
		{
			for (int i = 0; i < info.Width; i++)
			{
				int index = y * stride + i;
				pixels[index] = table[data[index]];
			}
		}
		else
		{
			for (int i = 0; i < info.Width; i++)
			{
				int index = y * stride + i;
				int dataIndex = y * stride + i * 4;
				pixels[index].Red = data[dataIndex + 2];
				pixels[index].Green = data[dataIndex + 1];
				pixels[index].Blue = data[dataIndex];
				
				pixels[index].Alpha = Color::MaxChannelValue;
			}
		}
		
		y++;
	}
	
	TRACE(DEBUG_FILE_LOADING, "Converted image data.");
	
	Deallocate(table, scratch);
	TRACE(DEBUG_FILE_LOADING, "Deallocated color table.");
	
	Deallocate(data, scratch);
	TRACE(DEBUG_FILE_LOADING, "Deallocated image data.");
	
	ITexture* texture = display.CreateTexture();
	
	if (texture == NULL)
	{
		TRACE(DEBUG_FILE_LOADING, "Could not create texture");
		
		Deallocate(pixels, scratch);
		return NULL;
	}
	
	texture->SetData(pixels, info.Width, height, ITexture::Rgba8, ITexture::Point);
	
	TRACE(DEBUG_FILE_LOADING, "Texture created and initialize.");
	
	Deallocate(pixels, scratch);
	
	TRACE(DEBUG_FILE_LOADING, "Deallocated final scratch data.");
	
	TRACE(DEBUG_FILE_LOADING, "Loaded BMP file.");
	
	return texture;
}