30 #define TARGA_FOOTER_SIZE 26 // using sizeof(targa_footer) doesn't work unless we
33 #define MAX_TARGA_RUN_LENGTH_PACKET 128
34 #define TARGA_HEADER_LENGTH 18
35 #define ULORIGIN (header.image_descriptor & 0x20)
81 static int targa_copy_data(
char *to,
char *from,
int pixels,
int fromsize,
int tosize)
83 if ( (fromsize == 2) && (tosize==2) ) {
90 *dst++ = (
ushort)((*src++) ^ 0x8000);
93 }
else if ( (fromsize == 2) && (tosize == 3) ) {
100 *to++ = (
ubyte)((pixel & 0x1f) * 8);
101 *to++ = (
ubyte)(((pixel >> 5) & 63) * 4);
102 *to++ = (
ubyte)(((pixel >> 11) & 0x1f) * 8);
106 Assert(fromsize == tosize);
107 memcpy(to, from, pixels * fromsize);
119 static int targa_pixels_equal(
char *pix1,
char *pix2,
int pixbytes)
122 if ( *pix1++ != *pix2++ ) {
125 }
while ( --pixbytes > 0 );
143 char *inputpixel=NULL;
144 char *matchpixel=NULL;
170 if ( pixcount == 129 ) {
175 if ( rlcount >= rlthresh ) {
182 flagbyte += targa_copy_data(flagbyte, copyloc, pixcount-1, pixsize, outsize);
190 if ( pixcount == 1 ) {
192 copyloc = inputpixel;
193 matchpixel = inputpixel;
195 inputpixel += pixsize;
202 if ( targa_pixels_equal(inputpixel, matchpixel, outsize) ) {
209 if ( ++rlcount == rlthresh ) {
213 if ( pixcount > (rlcount+1) ) {
216 *flagbyte++ = (char)(pixcount - 2 - rlthresh);
218 flagbyte += targa_copy_data(flagbyte, copyloc, (pixcount-1-rlcount), pixsize, outsize);
220 copyloc = inputpixel;
221 pixcount = rlcount + 1;
231 if ( rlcount >= rlthresh ) {
233 *flagbyte++ = (char)(0x80 | rlcount);
234 flagbyte += targa_copy_data(flagbyte, copyloc, 1, pixsize, outsize);
243 matchpixel = inputpixel;
247 inputpixel += pixsize;
248 }
while ( inputpixel < (in + bytecount));
252 if ( --pixcount >= 1 ) {
253 *flagbyte = (char)(pixcount - 1);
254 if ( rlcount >= rlthresh ) {
261 flagbyte += targa_copy_data(flagbyte, copyloc, pixcount, pixsize, outsize);
263 return(flagbyte-out);
278 static void targa_read_pixel(
int num_pixels,
ubyte **
dst,
ubyte **src,
int bytes_per_pixel,
int dest_size )
287 for(idx=0; idx<num_pixels; idx++){
289 if ( (bytes_per_pixel == 3) || (bytes_per_pixel == 4) ) {
290 memset( &pixel32, 0xff,
sizeof(
int) );
291 memcpy( &pixel32, *src, bytes_per_pixel );
293 #if BYTE_ORDER == BIG_ENDIAN
295 if ( dest_size == 4 ) {
301 memcpy( *dst, &pixel32, dest_size );
306 memcpy(&pixel, *src, bytes_per_pixel);
311 if(((pixel & 0x7c00) == 0) && ((pixel & 0x03e0) == 0x03e0) && ((pixel & 0x001f) == 0)){
318 r = (
ubyte)(((pixel & 0x7c00) >> 10) * 8);
319 g = (
ubyte)(((pixel & 0x03e0) >> 5) * 8);
320 b = (
ubyte)((pixel & 0x001f) * 8);
331 memcpy( *dst, &pixel, bytes_per_pixel );
342 (*src) += bytes_per_pixel;
364 CFILE *targa_file = NULL;
367 if (img_cfp == NULL) {
368 strcpy_s( filename, real_filename );
370 char *
p = strchr( filename,
'.' );
377 targa_file =
cfopen( filename ,
"rb" );
383 targa_file = img_cfp;
422 if (img_cfp == NULL) {
432 if (w) *w = header.
width;
433 if (h) *h = header.
height;
456 while (pixel_count < bitmap_width ) {
459 int run_count = *src_pixels++;
462 Assert(pixel_count + (run_count & 0x7f) + 1 <= bitmap_width );
465 if ( run_count & 0x80 ) {
469 pixel_count += (run_count + 1);
471 ubyte pixel_value[4];
472 ubyte *tmp = pixel_value;
473 targa_read_pixel( 1, &tmp, &src_pixels, bytes_per_pixel, dest_size );
477 memcpy( pixdata, pixel_value, dest_size );
478 pixdata += dest_size;
479 }
while (run_count--);
483 pixel_count += (run_count + 1);
486 targa_read_pixel(run_count+1, &pixdata, &src_pixels, bytes_per_pixel, dest_size );
490 Assert( pixel_count == bitmap_width );
492 return src_pixels -
src;
511 int xfile_offset = 0;
514 strcpy_s( filename, real_filename );
515 char *
p = strchr( filename,
'.' );
584 Assert( (bytes_per_pixel == 2) || (bytes_per_pixel == 3) || (bytes_per_pixel == 4) );
586 if ( (bytes_per_pixel < 2) || (bytes_per_pixel > 4) ) {
631 for (; i < 256; i++) {
639 int bytes_remaining =
cfilelength(targa_file) -
cftell(targa_file) - xfile_offset;
641 Assert(bytes_remaining > 0);
649 ubyte *src_pixels = fileptr;
651 cfread(fileptr, bytes_remaining, 1, targa_file);
653 int rowsize = header.
width * dest_size;
658 for (
int i = 0;
i < header.
height;
i++) {
662 pixptr = image_data +
i * rowsize;
664 pixptr = image_data + ((header.
height -
i - 1) * rowsize);
667 targa_read_pixel(header.
width, &pixptr, &src_pixels, bytes_per_pixel, dest_size );
674 for (
int i = 0;
i < header.
height;
i++) {
678 pixdata = image_data +
i * rowsize;
680 pixdata = image_data + ((header.
height -
i - 1) * rowsize);
711 int bytes_per_pixel = (bpp >> 3);
714 strcpy_s( filename, real_filename );
715 char *
p = strchr( filename,
'.' );
719 f =
cfopen( filename ,
"wb" );
761 ubyte *compressed_data;
764 if(compressed_data == NULL){
769 int compressed_data_len;
770 compressed_data_len =
targa_compress((
char*)compressed_data, (
char*)data, 3, bytes_per_pixel, w * h * bytes_per_pixel);
771 if (compressed_data_len < 0) {
777 cfwrite(compressed_data, compressed_data_len, 1, f);
int cfwrite_ushort(ushort s, CFILE *file)
GLfloat GLfloat GLfloat GLfloat h
int cfread(void *buf, int elsize, int nelem, CFILE *fp)
int cfwrite_ubyte(ubyte b, CFILE *file)
int targa_read_header(const char *real_filename, CFILE *img_cfp, int *w, int *h, int *bpp, ubyte *palette)
int targa_read_bitmap(const char *real_filename, ubyte *image_data, ubyte *palette, int dest_size, int cf_type)
#define Assertion(expr, msg,...)
void cfread_string(char *buf, int n, CFILE *file)
#define TARGA_FOOTER_SIZE
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define TARGA_ERROR_READING
GLdouble GLdouble GLdouble r
void(* bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
Functional pointer that references any of the bm_set_components functions.
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
short cfread_short(CFILE *file, int ver, short deflt)
uint palette_find(int r, int g, int b)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
ubyte cfread_ubyte(CFILE *file, int ver, ubyte deflt)
GLboolean GLboolean GLboolean b
int targa_write_bitmap(char *real_filename, ubyte *data, ubyte *palette, int w, int h, int bpp)
GLubyte GLubyte GLubyte GLubyte w
struct targa_footer targa_footer
int targa_uncompress(ubyte *dst, ubyte *src, int bitmap_width, int bytes_per_pixel, int dest_size)
GLenum GLsizei GLenum GLenum const GLvoid * data
int cfclose(CFILE *cfile)
int targa_compress(char *out, char *in, int outsize, int pixsize, int bytecount)
struct targa_header targa_header
int cfilelength(CFILE *cfile)
uint cfread_uint(CFILE *file, int ver, uint deflt)
int cfseek(CFILE *fp, int offset, int where)