Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions public/basetypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
52 changes: 36 additions & 16 deletions utils/common/imagelib/imagelib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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];
}
}
}

Expand All @@ -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;
Expand All @@ -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 );

Expand Down Expand Up @@ -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 ) );
Expand All @@ -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;
Expand All @@ -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 ) );
Expand Down
Loading