/* loads and converts a targa from disk */ void * tga_load( const char * filename, int * width, int * height, unsigned int format ) { ubyte idlen; // length of the image_id string below. ubyte cmap_type; // paletted image <=> cmap_type ubyte image_type; // can be any of the IMG_TYPE constants above. uint16 cmap_first; // uint16 cmap_length; // how long the colormap is ubyte cmap_entry_size; // how big a palette entry is. uint16 img_spec_xorig; // the x origin of the image in the image data. uint16 img_spec_yorig; // the y origin of the image in the image data. uint16 img_spec_width; // the width of the image. uint16 img_spec_height; // the height of the image. ubyte img_spec_pix_depth; // the depth of a pixel in the image. ubyte img_spec_img_desc; // the image descriptor. FILE * targafile; ubyte * tga_hdr = NULL; ubyte * colormap = NULL; //*********************************************************************** // Add by Yu-Chi because of variable initialization. // Add all = 0 to all the following variables //*********************************************************************** ubyte cmap_bytes_entry = 0; uint32 cmap_bytes = 0; uint32 tmp_col = 0; uint32 tmp_int32 = 0; ubyte tmp_byte = 0; ubyte alphabits = 0; uint32 num_pixels = 0; uint32 i = 0; uint32 j = 0; ubyte * image_data = 0; uint32 img_dat_len = 0; ubyte bytes_per_pix = 0; ubyte true_bits_per_pixel = 0; uint32 bytes_total = 0; ubyte packet_header = 0; ubyte repcount = 0; switch( format ) { case TGA_TRUECOLOR_24: case TGA_TRUECOLOR_32: break; default: TargaError = TGA_ERR_BAD_FORMAT; return( NULL ); } /* open binary image file */ targafile = fopen( filename, "rb" ); if( targafile == NULL ) { TargaError = TGA_ERR_OPEN_FAILS; return( NULL ); } /* allocate memory for the header */ tga_hdr = (ubyte *)malloc( HDR_LENGTH ); /* read the header in. */ if( fread( (void *)tga_hdr, 1, HDR_LENGTH, targafile ) != HDR_LENGTH ) { free( tga_hdr ); TargaError = TGA_ERR_BAD_HEADER; return( NULL ); } /* byte order is important here. */ idlen = (ubyte)tga_hdr[HDR_IDLEN]; image_type = (ubyte)tga_hdr[HDR_IMAGE_TYPE]; cmap_type = (ubyte)tga_hdr[HDR_CMAP_TYPE]; cmap_first = ttohs( *(uint16 *)(&tga_hdr[HDR_CMAP_FIRST]) ); cmap_length = ttohs( *(uint16 *)(&tga_hdr[HDR_CMAP_LENGTH]) ); cmap_entry_size = (ubyte)tga_hdr[HDR_CMAP_ENTRY_SIZE]; img_spec_xorig = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_XORIGIN]) ); img_spec_yorig = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_YORIGIN]) ); img_spec_width = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_WIDTH]) ); img_spec_height = ttohs( *(uint16 *)(&tga_hdr[HDR_IMG_SPEC_HEIGHT]) ); img_spec_pix_depth = (ubyte)tga_hdr[HDR_IMG_SPEC_PIX_DEPTH]; img_spec_img_desc = (ubyte)tga_hdr[HDR_IMG_SPEC_IMG_DESC]; free( tga_hdr ); num_pixels = img_spec_width * img_spec_height; if( num_pixels == 0 ) { TargaError = TGA_ERR_BAD_DIMENSIONS; return( NULL ); } alphabits = img_spec_img_desc & 0x0F; /* seek past the image id, if there is one */ if( idlen ) { if( fseek( targafile, idlen, SEEK_CUR ) ) { TargaError = TGA_ERR_UNEXPECTED_EOF; return( NULL ); } } /* if this is a 'nodata' image, just jump out. */ if( image_type == TGA_IMG_NODATA ) { TargaError = TGA_ERR_NODATA_IMAGE; return( NULL ); } /* now we're starting to get into the meat of the matter. */ /* deal with the colormap, if there is one. */ if( cmap_type ) { switch( image_type ) { case TGA_IMG_UNC_PALETTED: case TGA_IMG_RLE_PALETTED: break; case TGA_IMG_UNC_TRUECOLOR: case TGA_IMG_RLE_TRUECOLOR: // this should really be an error, but some really old // crusty targas might actually be like this (created by TrueVision, no less!) // so, we'll hack our way through it. break; case TGA_IMG_UNC_GRAYSCALE: case TGA_IMG_RLE_GRAYSCALE: TargaError = TGA_ERR_COLORMAP_FOR_GRAY; return( NULL ); } /* ensure colormap entry size is something we support */ if( !(cmap_entry_size == 15 || cmap_entry_size == 16 || cmap_entry_size == 24 || cmap_entry_size == 32) ) { TargaError = TGA_ERR_BAD_COLORMAP_ENTRY_SIZE; return( NULL ); } /* allocate memory for a colormap */ if( cmap_entry_size & 0x07 ) { cmap_bytes_entry = (((8 - (cmap_entry_size & 0x07)) + cmap_entry_size) >> 3); } else {
void write_short( int16 value, FILE * file ) { value = ttohs( value ); fwrite( &value, 2, 1, file ); }