X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=plugins%2Fimage%2Fpcx.cpp;h=46bffc056186dc5c69a0a6cc9b280c5cc1d09078;hb=e4287c28bb2dafedc81c66e63951d947cfbeb225;hp=8853cb49cc4de85d118688f999bd4018b976c762;hpb=231225d6f97d0b926b2e896e5783cccfbc7c5619;p=xonotic%2Fnetradiant.git diff --git a/plugins/image/pcx.cpp b/plugins/image/pcx.cpp index 8853cb49..46bffc05 100644 --- a/plugins/image/pcx.cpp +++ b/plugins/image/pcx.cpp @@ -1,23 +1,23 @@ /* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "pcx.h" @@ -31,192 +31,187 @@ typedef unsigned char byte; #include "bytestreamutils.h" /* -================================================================= + ================================================================= -PCX LOADING + PCX LOADING -================================================================= -*/ + ================================================================= + */ 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 + 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; /* -============== -LoadPCX -============== -*/ + ============== + LoadPCX + ============== + */ struct PCXRLEPacket { - byte data; - int length; + 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 ); + } } /* -============== -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; + ============== + 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* 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 ); } -