void palette_cache_add( int r, int g, int b, int index ) { int value = ((r/4)<<12)+((g/4)<<6)+(b/4); if ( !palman_is_nondarkening(r,g,b)) { palette_lookup[value] = (ubyte)index; } }
int palette_cache_find( int r, int g, int b ) { if ( !palman_is_nondarkening(r,g,b)) { int value = ((r/4)<<12)+((g/4)<<6)+(b/4); if ( palette_lookup[value] != 255 ) { return palette_lookup[value]; } } return -1; }
int pcx_read_bitmap_16bpp_nondark( char * real_filename, ubyte *org_data ) { PCXHeader header; CFILE * PCXfile; int row, col, count, xsize, ysize; ubyte data=0; int buffer_size, buffer_pos; ubyte buffer[1024]; ubyte *pixdata; char filename[MAX_FILENAME_LEN]; ubyte palette[768]; ushort bit_16; ubyte r, g, b, al; strcpy( filename, real_filename ); char *p = strchr( filename, '.' ); if ( p ) *p = 0; strcat( filename, ".pcx" ); PCXfile = cfopen( filename , "rb" ); if ( !PCXfile ){ return PCX_ERROR_OPENING; } // read 128 char PCX header if (cfread( &header, sizeof(PCXHeader), 1, PCXfile )!=1) { cfclose( PCXfile ); return PCX_ERROR_NO_HEADER; } header.Xmin = INTEL_SHORT( header.Xmin ); header.Ymin = INTEL_SHORT( header.Ymin ); header.Xmax = INTEL_SHORT( header.Xmax ); header.Ymax = INTEL_SHORT( header.Ymax ); header.Hdpi = INTEL_SHORT( header.Hdpi ); header.Vdpi = INTEL_SHORT( header.Vdpi ); header.BytesPerLine = INTEL_SHORT( header.BytesPerLine ); // Is it a 256 color PCX file? if ((header.Manufacturer != 10)||(header.Encoding != 1)||(header.Nplanes != 1)||(header.BitsPerPixel != 8)||(header.Version != 5)) { cfclose( PCXfile ); return PCX_ERROR_WRONG_VERSION; } // Find the size of the image xsize = header.Xmax - header.Xmin + 1; ysize = header.Ymax - header.Ymin + 1; // Read the extended palette at the end of PCX file // Read in a character which should be 12 to be extended palette file cfseek( PCXfile, -768, CF_SEEK_END ); cfread( palette, 3, 256, PCXfile ); cfseek( PCXfile, sizeof(PCXHeader), CF_SEEK_SET ); buffer_size = 1024; buffer_pos = 0; // Assert( buffer_size == 1024 ); // AL: removed to avoid optimized warning 'unreachable code' buffer_size = cfread( buffer, 1, buffer_size, PCXfile ); count = 0; for (row=0; row<ysize;row++) { pixdata = org_data; for (col=0; col<header.BytesPerLine;col++) { if ( count == 0 ) { data = buffer[buffer_pos++]; if ( buffer_pos == buffer_size ) { buffer_size = cfread( buffer, 1, buffer_size, PCXfile ); Assert( buffer_size > 0 ); buffer_pos = 0; } if ((data & 0xC0) == 0xC0) { count = data & 0x3F; data = buffer[buffer_pos++]; if ( buffer_pos == buffer_size ) { buffer_size = cfread( buffer, 1, buffer_size, PCXfile ); Assert( buffer_size > 0 ); buffer_pos = 0; } } else { count = 1; } } // stuff the pixel if ( col < xsize ){ // stuff the 24 bit value r = palette[data*3]; g = palette[data*3 + 1]; b = palette[data*3 + 2]; // if this is a nondarkening texture // if this color matches a nondarkening pixel color, set the alpha to high al = 0; if(palman_is_nondarkening(r, g, b)){ al = 255; } // set the pixel bit_16 = 0; bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al); // stuff the pixel *((ushort*)pixdata) = bit_16; pixdata += 2; } count--; } org_data += (xsize * 2); } cfclose(PCXfile); return PCX_ERROR_NONE; }
//int pcx_read_bitmap_16bpp( char * real_filename, ubyte *org_data, ubyte bpp, int aabitmap, int nondark ) int pcx_read_bitmap( const char * real_filename, ubyte *org_data, ubyte *pal, int byte_size, int aabitmap, int nondark, int cf_type ) { PCXHeader header; CFILE * PCXfile; int row, col, count, xsize, ysize; ubyte data=0; int buffer_size, buffer_pos; ubyte buffer[1024]; ubyte *pixdata; char filename[MAX_FILENAME_LEN]; ubyte palette[768]; ushort bit_16; COLOR32 bit_32; ubyte r, g, b, al; strcpy_s( filename, real_filename ); char *p = strchr( filename, '.' ); if ( p ) *p = 0; strcat_s( filename, ".pcx" ); PCXfile = cfopen( filename , "rb", CFILE_NORMAL, cf_type ); if ( !PCXfile ){ return PCX_ERROR_OPENING; } // read 128 char PCX header if (cfread( &header, sizeof(PCXHeader), 1, PCXfile )!=1) { cfclose( PCXfile ); return PCX_ERROR_NO_HEADER; } header.Xmin = INTEL_SHORT( header.Xmin ); //-V570 header.Ymin = INTEL_SHORT( header.Ymin ); //-V570 header.Xmax = INTEL_SHORT( header.Xmax ); //-V570 header.Ymax = INTEL_SHORT( header.Ymax ); //-V570 header.Hdpi = INTEL_SHORT( header.Hdpi ); //-V570 header.Vdpi = INTEL_SHORT( header.Vdpi ); //-V570 header.BytesPerLine = INTEL_SHORT( header.BytesPerLine ); //-V570 // Is it a 256 color PCX file? if ((header.Manufacturer != 10)||(header.Encoding != 1)||(header.Nplanes != 1)||(header.BitsPerPixel != 8)||(header.Version != 5)) { cfclose( PCXfile ); return PCX_ERROR_WRONG_VERSION; } // Find the size of the image xsize = header.Xmax - header.Xmin + 1; ysize = header.Ymax - header.Ymin + 1; // Read the extended palette at the end of PCX file // Read in a character which should be 12 to be extended palette file cfseek( PCXfile, -768, CF_SEEK_END ); cfread( palette, 1, (3 * 256), PCXfile ); cfseek( PCXfile, sizeof(PCXHeader), CF_SEEK_SET ); buffer_size = 1024; buffer_pos = 0; // Assert( buffer_size == 1024 ); // AL: removed to avoid optimized warning 'unreachable code' buffer_size = cfread( buffer, 1, buffer_size, PCXfile ); count = 0; for (row=0; row<ysize;row++) { pixdata = org_data; for (col=0; col<header.BytesPerLine;col++) { if ( count == 0 ) { data = buffer[buffer_pos++]; if ( buffer_pos == buffer_size ) { buffer_size = cfread( buffer, 1, buffer_size, PCXfile ); Assert( buffer_size > 0 ); buffer_pos = 0; } if ((data & 0xC0) == 0xC0) { count = data & 0x3F; data = buffer[buffer_pos++]; if ( buffer_pos == buffer_size ) { buffer_size = cfread( buffer, 1, buffer_size, PCXfile ); Assert( buffer_size > 0 ); buffer_pos = 0; } } else { count = 1; } } // stuff the pixel if ( col < xsize ) { // 8-bit PCX reads if ( byte_size == 1 ) { *pixdata++ = data; } else { // 16-bit AABITMAP reads if ( (byte_size == 2) && aabitmap ) { // stuff the pixel // memcpy(pixdata, &data, 2); *((ushort*)pixdata) = (ushort)data; } else { // stuff the 24 bit value r = palette[data*3]; g = palette[data*3 + 1]; b = palette[data*3 + 2]; // clear the pixel bit_16 = 0; memset(&bit_32, 0, sizeof(COLOR32)); // 16-bit non-darkening reads if ( (byte_size == 2) && nondark ) { al = 0; if (palman_is_nondarkening(r, g, b)) { al = 255; } } else { // if the color matches the transparent color, make it so al = 255; if ( (0 == (int)palette[data*3]) && (255 == (int)palette[data*3+1]) && (0 == (int)palette[data*3+2]) ) { r = b = 0; g = (byte_size == 4) ? 0 : 255; al = 0; } } // normal 16-bit reads if ( byte_size == 2 ) { // stuff the color bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al); // stuff the pixel *((ushort*)pixdata) = bit_16; } // normal 32-bit reads else if ( byte_size == 4 ) { if ( /*(r == 0) && (b == 0) && (g == 255) && (al == 0)*/ 0 ) { memset(&bit_32, 0, sizeof(COLOR32)); } else { bit_32.r = r; bit_32.g = g; bit_32.b = b; bit_32.a = al; } // stuff the pixel *((COLOR32*)pixdata) = bit_32; } } pixdata += byte_size; } } count--; } org_data += (xsize * byte_size); } cfclose(PCXfile); return PCX_ERROR_NONE; }