Ejemplo n.º 1
0
// FIXME: assumes that we don't need to do gamma correction.
bool Write( unsigned char *pImageData, const char *fileName, int width, int height, 
            enum ImageFormat srcFormat, enum ImageFormat dstFormat )
{
	TGAHeader_t header;
	int x, y;

	// FIXME: need to handle conversion here.
	if( srcFormat != dstFormat )
	{
		return false;
	}

#ifdef TGAWRITER_USE_FOPEN
	FILE *fp;
	fp = fopen( fileName, "wb" );
	if( !fp )
	{
		return false;
	}
#else
	assert( s_pFileSystem );
	if( !s_pFileSystem )
	{
		return false;
	}
	FileHandle_t fp;
	fp = s_pFileSystem->Open( fileName, "wb" );
#endif

	header.id_length = 0; // comment length
	header.colormap_type = 0; // ???

	// Brian?: FIXME: should use BGR, etc, so that we can just fwrite the data.
	// Gary: TGA doesn't support BGR.
	switch( dstFormat )
	{
	case IMAGE_FORMAT_RGB888:
		header.image_type = 2; // 24/32 bit uncompressed TGA
		header.pixel_size = 24;
		break;
	case IMAGE_FORMAT_RGBA8888:
		header.image_type = 2; // 24/32 bit uncompressed TGA
		header.pixel_size = 32;
		break;
	case IMAGE_FORMAT_I8:
		header.image_type = 1; // 8 bit uncompressed TGA
		header.pixel_size = 8;
		break;
	default:
#ifdef TGAWRITER_USE_FOPEN
		fclose( fp );
#else
		s_pFileSystem->Close( fp );
#endif
		return false;
		break;
	}

	header.colormap_index = 0;
	header.colormap_length = 0;
	header.colormap_size = 0;
	// can I flip this so that I can write the image out directly?
	header.x_origin = 0;
	header.y_origin = 0;
	header.width = ( unsigned short )width;
	header.height = ( unsigned short )height;
	header.attributes = 0;

	fputc( header.id_length, fp );
	fputc( header.colormap_type, fp );
	fputc( header.image_type, fp );
	fputLittleShort( header.colormap_index, fp );
	fputLittleShort( header.colormap_length, fp );
	fputc( header.colormap_size, fp );
	fputLittleShort( header.x_origin, fp );
	fputLittleShort( header.y_origin, fp );
	fputLittleShort( header.width, fp );
	fputLittleShort( header.height, fp );
	fputc( header.pixel_size, fp );
	fputc( header.attributes, fp );
	
	unsigned char *pbuf = (unsigned char *)_alloca( width * 4 );
	switch( dstFormat )
	{
	case IMAGE_FORMAT_RGB888:
		for( y = height - 1; y >= 0; y-- )
		{
			int start = y * width * 3;
			int out = 0;
			for( x = 0; x < width; x++ )
			{
				pbuf[out++] = pImageData[start + 2];
				pbuf[out++] = pImageData[start + 1];
				pbuf[out++] = pImageData[start + 0];
				start += 3;
			}
			fwrite( pbuf, width, 3, fp ); // write a line
		}
		break;
	case IMAGE_FORMAT_RGBA8888:
		for( y = height - 1; y >= 0; y-- )
		{
			int start = y * width * 4;
			int out = 0;
			for( x = 0; x < width; x++ )
			{
				pbuf[out++] = pImageData[start + 2];
				pbuf[out++] = pImageData[start + 1];
				pbuf[out++] = pImageData[start + 0];
				pbuf[out++] = pImageData[start + 3];
				start += 4;
			}
			fwrite( pbuf, width, 4, fp ); // write a line
		}
		break;
	// FIXME: some programs don't understand our I8 files. . probably need to put
	// a linear ramp palette in the file.
	case IMAGE_FORMAT_I8:
		for( y = height - 1; y >= 0; y-- )
		{
			fwrite( &pImageData[ y * width ], width, 1, fp );
		}
		break;
	default:
#ifdef TGAWRITER_USE_FOPEN
		fclose( fp );
#else
	s_pFileSystem->Close( fp );
#endif
		return false;
		break;
	}
#ifdef TGAWRITER_USE_FOPEN
	fclose( fp );
#else
	s_pFileSystem->Close( fp );
#endif
	return true;
}
Ejemplo n.º 2
0
//-----------------------------------------------------------------------------
// FIXME: assumes that we don't need to do gamma correction.
//-----------------------------------------------------------------------------
bool WriteToBuffer( unsigned char *pImageData, CUtlBuffer &buffer, int width, int height, 
					ImageFormat srcFormat, ImageFormat dstFormat )
{
	TGAHeader_t header;

	// Fix the dstFormat to match what actually is going to go into the file
	switch( dstFormat )
	{
	case IMAGE_FORMAT_RGB888:
		dstFormat = IMAGE_FORMAT_BGR888;
		break;
#if defined( _X360 )
	case IMAGE_FORMAT_LINEAR_RGB888:
		dstFormat = IMAGE_FORMAT_LINEAR_BGR888;
		break;
#endif
	case IMAGE_FORMAT_RGBA8888:
		dstFormat = IMAGE_FORMAT_BGRA8888;
		break;
	}

	header.id_length = 0; // comment length
	header.colormap_type = 0; // ???

	switch( dstFormat )
	{
	case IMAGE_FORMAT_BGR888:
#if defined( _X360 )
	case IMAGE_FORMAT_LINEAR_BGR888:
#endif
		header.image_type = 2; // 24/32 bit uncompressed TGA
		header.pixel_size = 24;
		break;
	case IMAGE_FORMAT_BGRA8888:
		header.image_type = 2; // 24/32 bit uncompressed TGA
		header.pixel_size = 32;
		break;
	case IMAGE_FORMAT_I8:
		header.image_type = 1; // 8 bit uncompressed TGA
		header.pixel_size = 8;
		break;
	default:
		return false;
		break;
	}

	header.colormap_index = 0;
	header.colormap_length = 0;
	header.colormap_size = 0;
	header.x_origin = 0;
	header.y_origin = 0;
	header.width = ( unsigned short )width;
	header.height = ( unsigned short )height;
	header.attributes = 0x20;	// Makes it so we don't have to vertically flip the image

	buffer.PutChar( header.id_length );
	buffer.PutChar( header.colormap_type );
	buffer.PutChar( header.image_type );
	fputLittleShort( header.colormap_index, buffer );
	fputLittleShort( header.colormap_length, buffer );
	buffer.PutChar( header.colormap_size );
	fputLittleShort( header.x_origin, buffer );
	fputLittleShort( header.y_origin, buffer );
	fputLittleShort( header.width, buffer );
	fputLittleShort( header.height, buffer );
	buffer.PutChar( header.pixel_size );
	buffer.PutChar( header.attributes );

	int nSizeInBytes = width * height * ImageLoader::SizeInBytes( dstFormat );
	buffer.EnsureCapacity( buffer.TellPut() + nSizeInBytes );
	unsigned char *pDst = (unsigned char*)buffer.PeekPut();

	if ( !ImageLoader::ConvertImageFormat( pImageData, srcFormat, pDst, dstFormat, width, height ) )
		return false;

	buffer.SeekPut( CUtlBuffer::SEEK_CURRENT, nSizeInBytes );
	return true;
}