diff --git a/public/basetypes.h b/public/basetypes.h index 15661d21d..be9d6f7d8 100644 --- a/public/basetypes.h +++ b/public/basetypes.h @@ -80,4 +80,29 @@ enum #define DXT_ENCODE_ALPHA_SDF 0x1A04 // signed distance field #define DXT_ENCODE_NORMAL_AG_PARABOLOID 0x1A07 // paraboloid projection +#define Swap32( x ) (((uint32_t)((( x ) & 255 ) << 24 )) + ((uint32_t)(((( x ) >> 8 ) & 255 ) << 16 )) + ((uint32_t)((( x ) >> 16 ) & 255 ) << 8 ) + ((( x ) >> 24 ) & 255 )) +#define Swap16( x ) ((uint16_t)((((uint16_t)( x ) >> 8 ) & 255 ) + (((uint16_t)( x ) & 255 ) << 8 ))) +#define Swap32Store( x ) ( x = Swap32( x )) +#define Swap16Store( x ) ( x = Swap16( x )) + +#ifdef XASH_BIG_ENDIAN + #define LittleLong( x ) Swap32( x ) + #define LittleShort( x ) Swap16( x ) + #define LittleLongSW( x ) Swap32Store( x ) + #define LittleShortSW( x ) Swap16Store( x ) + #define LittleFloat( x ) SwapFloat( x ) + #define BigLong( x ) ( x ) + #define BigShort( x ) ( x ) + #define BigFloat( x ) ( x ) +#else + #define LittleLong( x ) ( x ) + #define LittleShort( x ) ( x ) + #define LittleFloat( x ) ( x ) + #define LittleLongSW( x ) + #define LittleShortSW( x ) + #define BigLong( x ) Swap32( x ) + #define BigShort( x ) Swap16( x ) + #define BigFloat( x ) SwapFloat( x ) +#endif + #endif // BASETYPES_H diff --git a/utils/common/imagelib/imagelib.cpp b/utils/common/imagelib/imagelib.cpp index 69750b19f..252b86815 100644 --- a/utils/common/imagelib/imagelib.cpp +++ b/utils/common/imagelib/imagelib.cpp @@ -1809,7 +1809,8 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix ) if( !pix->buffer ) return false; - pixel_size = 4; + pixel_size = (pix->flags & IMAGE_HAS_ALPHA) ? 4 : 3; + rowsize = pix->width * pixel_size; // get filtered image size @@ -1819,16 +1820,35 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix ) // apply adaptive filter to image for( y = 0; y < pix->height; y++ ) { - in = pix->buffer + y * pix->width * pixel_size; *out++ = PNG_F_NONE; - rowend = in + rowsize; - for( ; in < rowend; in += pixel_size ) + + if( pix->flags & IMAGE_QUANTIZED) { - *out++ = in[0]; - *out++ = in[1]; - *out++ = in[2]; - if( pix->flags & IMAGE_HAS_ALPHA ) - *out++ = in[3]; + in = pix->buffer + y * pix->width; + rowend = in + pix->width; + for (; in < rowend; in++) + { + *out++ = pix->palette[*in * 4 + 0]; + *out++ = pix->palette[*in * 4 + 1]; + *out++ = pix->palette[*in * 4 + 2]; + + if (pix->flags & IMAGE_HAS_ALPHA) + *out++ = pix->palette[*in * 4 + 3]; + } + } + else + { + in = pix->buffer + y * pix->width * pixel_size; + rowend = in + rowsize; + for( ; in < rowend; in += pixel_size ) + { + *out++ = in[0]; + *out++ = in[1]; + *out++ = in[2]; + + if( pix->flags & IMAGE_HAS_ALPHA ) + *out++ = in[3]; + } } } @@ -1849,16 +1869,16 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix ) memcpy( png_hdr.sign, png_sign, sizeof( png_sign ) ); // write IHDR chunk length - png_hdr.ihdr_len = htonl( ihdr_len ); + png_hdr.ihdr_len = BigLong( ihdr_len ); // write IHDR chunk signature memcpy( png_hdr.ihdr_sign, ihdr_sign, sizeof( ihdr_sign ) ); // write image width - png_hdr.ihdr_chunk.width = htonl( pix->width ); + png_hdr.ihdr_chunk.width = BigLong( pix->width ); // write image height - png_hdr.ihdr_chunk.height = htonl( pix->height ); + png_hdr.ihdr_chunk.height = BigLong( pix->height ); // write image bitdepth png_hdr.ihdr_chunk.bitdepth = 8; @@ -1881,7 +1901,7 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix ) crc32 = CRC32_Final( crc32 ); // write IHDR chunk CRC - png_hdr.ihdr_crc32 = htonl( crc32 ); + png_hdr.ihdr_crc32 = BigLong( crc32 ); out = buffer = (byte *)Mem_Alloc( outsize ); @@ -1921,7 +1941,7 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix ) out += sizeof( png_t ); // convert IDAT chunk length to big endian - big_idat_len = htonl( idat_len ); + big_idat_len = BigLong( idat_len ); // write IDAT chunk length memcpy( out, &big_idat_len, sizeof( idat_len ) ); @@ -1940,7 +1960,7 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix ) out += idat_len; // write IDAT chunk CRC - png_ftr.idat_crc32 = htonl( crc32 ); + png_ftr.idat_crc32 = BigLong( crc32 ); // write IEND chunk length png_ftr.iend_len = 0; @@ -1949,7 +1969,7 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix ) memcpy( png_ftr.iend_sign, iend_sign, sizeof( iend_sign ) ); // write IEND chunk CRC - png_ftr.iend_crc32 = htonl( iend_crc32 ); + png_ftr.iend_crc32 = BigLong( iend_crc32 ); // write PNG footer to buffer memcpy( out, &png_ftr, sizeof( png_ftr ) );