X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=plugins%2Fimage%2Fpcx.cpp;h=8d658a7994228332c144d29f03dd62c412d4cfff;hb=f715e5f69a891e0d27d2faa1f76a8ef8337a33b4;hp=46bffc056186dc5c69a0a6cc9b280c5cc1d09078;hpb=dac8329952745dbb494bad1c301e44bab05ec0db;p=xonotic%2Fnetradiant.git diff --git a/plugins/image/pcx.cpp b/plugins/image/pcx.cpp index 46bffc05..8d658a79 100644 --- a/plugins/image/pcx.cpp +++ b/plugins/image/pcx.cpp @@ -38,21 +38,20 @@ typedef unsigned char byte; ================================================================= */ -typedef struct -{ - unsigned char manufacturer; - unsigned char version; - unsigned char encoding; - unsigned char bits_per_pixel; - unsigned short xmin, ymin, xmax, ymax; - unsigned short hres, vres; - unsigned char palette[48]; - unsigned char reserved; - unsigned char color_planes; - unsigned short bytes_per_line; - unsigned short palette_type; - unsigned char filler[58]; - unsigned char data; // unbounded +typedef struct { + unsigned char manufacturer; + unsigned char version; + unsigned char encoding; + unsigned char bits_per_pixel; + unsigned short xmin, ymin, xmax, ymax; + unsigned short hres, vres; + unsigned char palette[48]; + unsigned char reserved; + unsigned char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + unsigned char filler[58]; + unsigned char data; // unbounded } pcx_t; /* @@ -61,119 +60,113 @@ typedef struct ============== */ -struct PCXRLEPacket -{ - byte data; - int length; +struct PCXRLEPacket { + byte data; + int length; }; -inline void ByteStream_readPCXRLEPacket( PointerInputStream& inputStream, PCXRLEPacket& packet ){ - byte d; - inputStream.read( &d, 1 ); - if ( ( d & 0xC0 ) == 0xC0 ) { - packet.length = d & 0x3F; - inputStream.read( &packet.data, 1 ); - } - else - { - packet.length = 1; - packet.data = d; - } +inline void ByteStream_readPCXRLEPacket(PointerInputStream &inputStream, PCXRLEPacket &packet) +{ + byte d; + inputStream.read(&d, 1); + if ((d & 0xC0) == 0xC0) { + packet.length = d & 0x3F; + inputStream.read(&packet.data, 1); + } else { + packet.length = 1; + packet.data = d; + } } -void LoadPCXBuff( byte* buffer, std::size_t len, byte **pic, byte **palette, int *width, int *height ){ - *pic = 0; - - pcx_t pcx; - int x, y, lsize; - byte *out, *pix; - - /* parse the PCX file */ - - PointerInputStream inputStream( buffer ); - - pcx.manufacturer = istream_read_byte( inputStream ); - pcx.version = istream_read_byte( inputStream ); - pcx.encoding = istream_read_byte( inputStream ); - pcx.bits_per_pixel = istream_read_byte( inputStream ); - pcx.xmin = istream_read_int16_le( inputStream ); - pcx.ymin = istream_read_int16_le( inputStream ); - pcx.xmax = istream_read_int16_le( inputStream ); - pcx.ymax = istream_read_int16_le( inputStream ); - pcx.hres = istream_read_int16_le( inputStream ); - pcx.vres = istream_read_int16_le( inputStream ); - inputStream.read( pcx.palette, 48 ); - pcx.reserved = istream_read_byte( inputStream ); - pcx.color_planes = istream_read_byte( inputStream ); - pcx.bytes_per_line = istream_read_int16_le( inputStream ); - pcx.palette_type = istream_read_int16_le( inputStream ); - inputStream.read( pcx.filler, 58 ); - - - if ( pcx.manufacturer != 0x0a - || pcx.version != 5 - || pcx.encoding != 1 - || pcx.bits_per_pixel != 8 ) { - return; - } - - if ( width ) { - *width = pcx.xmax + 1; - } - if ( height ) { - *height = pcx.ymax + 1; - } - - if ( !pic ) { - return; - } - - out = (byte *)malloc( ( pcx.ymax + 1 ) * ( pcx.xmax + 1 ) ); - - *pic = out; - pix = out; - - /* RR2DO2: pcx fix */ - lsize = pcx.color_planes * pcx.bytes_per_line; - - /* go scanline by scanline */ - for ( y = 0; y <= pcx.ymax; y++, pix += pcx.xmax + 1 ) - { - /* do a scanline */ - for ( x = 0; x <= pcx.xmax; ) - { - /* RR2DO2 */ - PCXRLEPacket packet; - ByteStream_readPCXRLEPacket( inputStream, packet ); - - while ( packet.length-- > 0 ) - { - pix[ x++ ] = packet.data; - } - } - - /* RR2DO2: discard any other data */ - PCXRLEPacket packet; - while ( x < lsize ) - { - ByteStream_readPCXRLEPacket( inputStream, packet ); - x++; - } - while ( packet.length-- > 0 ) - { - x++; - } - } - - /* validity check */ - if ( std::size_t( inputStream.get() - buffer ) > len ) { - *pic = 0; - } - - if ( palette ) { - *palette = (byte *)malloc( 768 ); - memcpy( *palette, buffer + len - 768, 768 ); - } +void LoadPCXBuff(byte *buffer, std::size_t len, byte **pic, byte **palette, int *width, int *height) +{ + *pic = 0; + + pcx_t pcx; + int x, y, lsize; + byte *out, *pix; + + /* parse the PCX file */ + + PointerInputStream inputStream(buffer); + + pcx.manufacturer = istream_read_byte(inputStream); + pcx.version = istream_read_byte(inputStream); + pcx.encoding = istream_read_byte(inputStream); + pcx.bits_per_pixel = istream_read_byte(inputStream); + pcx.xmin = istream_read_int16_le(inputStream); + pcx.ymin = istream_read_int16_le(inputStream); + pcx.xmax = istream_read_int16_le(inputStream); + pcx.ymax = istream_read_int16_le(inputStream); + pcx.hres = istream_read_int16_le(inputStream); + pcx.vres = istream_read_int16_le(inputStream); + inputStream.read(pcx.palette, 48); + pcx.reserved = istream_read_byte(inputStream); + pcx.color_planes = istream_read_byte(inputStream); + pcx.bytes_per_line = istream_read_int16_le(inputStream); + pcx.palette_type = istream_read_int16_le(inputStream); + inputStream.read(pcx.filler, 58); + + + if (pcx.manufacturer != 0x0a + || pcx.version != 5 + || pcx.encoding != 1 + || pcx.bits_per_pixel != 8) { + return; + } + + if (width) { + *width = pcx.xmax + 1; + } + if (height) { + *height = pcx.ymax + 1; + } + + if (!pic) { + return; + } + + out = (byte *) malloc((pcx.ymax + 1) * (pcx.xmax + 1)); + + *pic = out; + pix = out; + + /* RR2DO2: pcx fix */ + lsize = pcx.color_planes * pcx.bytes_per_line; + + /* go scanline by scanline */ + for (y = 0; y <= pcx.ymax; y++, pix += pcx.xmax + 1) { + /* do a scanline */ + for (x = 0; x <= pcx.xmax;) { + /* RR2DO2 */ + PCXRLEPacket packet; + ByteStream_readPCXRLEPacket(inputStream, packet); + + while (packet.length-- > 0) { + pix[x++] = packet.data; + } + } + + /* RR2DO2: discard any other data */ + PCXRLEPacket packet; + while (x < lsize) { + ByteStream_readPCXRLEPacket(inputStream, packet); + x++; + } + while (packet.length-- > 0) { + x++; + } + } + + /* validity check */ + if (std::size_t(inputStream.get() - buffer) > len) { + *pic = 0; + } + + if (palette) { + *palette = (byte *) malloc(768); + memcpy(*palette, buffer + len - 768, 768); + } } /* @@ -181,37 +174,38 @@ void LoadPCXBuff( byte* buffer, std::size_t len, byte **pic, byte **palette, int LoadPCX32 ============== */ -Image* LoadPCX32Buff( byte* buffer, std::size_t length ){ - byte *palette; - byte *pic8; - int i, c, p, width, height; - byte *pic32; - - LoadPCXBuff( buffer, length, &pic8, &palette, &width, &height ); - if ( !pic8 ) { - return 0; - } - - RGBAImage* image = new RGBAImage( width, height ); - c = ( width ) * ( height ); - pic32 = image->getRGBAPixels(); - for ( i = 0; i < c; i++ ) - { - p = pic8[i]; - pic32[0] = palette[p * 3]; - pic32[1] = palette[p * 3 + 1]; - pic32[2] = palette[p * 3 + 2]; - pic32[3] = 255; - pic32 += 4; - } - - free( pic8 ); - free( palette ); - - return image; +Image *LoadPCX32Buff(byte *buffer, std::size_t length) +{ + byte *palette; + byte *pic8; + int i, c, p, width, height; + byte *pic32; + + LoadPCXBuff(buffer, length, &pic8, &palette, &width, &height); + if (!pic8) { + return 0; + } + + RGBAImage *image = new RGBAImage(width, height); + c = (width) * (height); + pic32 = image->getRGBAPixels(); + for (i = 0; i < c; i++) { + p = pic8[i]; + pic32[0] = palette[p * 3]; + pic32[1] = palette[p * 3 + 1]; + pic32[2] = palette[p * 3 + 2]; + pic32[3] = 255; + pic32 += 4; + } + + free(pic8); + free(palette); + + return image; } -Image* LoadPCX32( ArchiveFile& file ){ - ScopedArchiveBuffer buffer( file ); - return LoadPCX32Buff( buffer.buffer, buffer.length ); +Image *LoadPCX32(ArchiveFile &file) +{ + ScopedArchiveBuffer buffer(file); + return LoadPCX32Buff(buffer.buffer, buffer.length); }