Репозиторий ALT Linux backports/2.4
Последнее обновление: 9 июля 2008 | Пакетов: 497 | Посещений: 1493749
 поиск   регистрация   авторизация 
 
Группа :: Графические оболочки/KDE
Пакет: kdelibs

 Главная   Изменения   Спек   Патчи   Загрузить   Bugs and FR 

Патч: post-3.3.2-kdelibs-kimgio-fixed.diff


diff -u -3 -d -p -r1.4 -r1.4.2.1
--- dds.cpp	2 Aug 2004 20:34:50 -0000	1.4
+++ dds.cpp	19 Apr 2005 11:11:09 -0000	1.4.2.1
@@ -26,6 +26,12 @@
 
 #include <kdebug.h>
 
+#include <math.h> // sqrtf
+
+#ifndef __USE_ISOC99
+#define sqrtf(x) ((float)sqrt(x))
+#endif
+
 typedef Q_UINT32 uint;
 typedef Q_UINT16 ushort;
 typedef Q_UINT8 uchar;
@@ -44,34 +50,71 @@ namespace {	// Private.
 #define VERTICAL 2
 #define CUBE_LAYOUT	HORIZONTAL
 
+	struct Color8888
+	{
+		uchar r, g, b, a;
+	};
 
-	const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
-	const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
-	const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
-	const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3');
-	const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4');
-	const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5');
+	union Color565
+	{
+		struct {
+			ushort b : 5;
+			ushort g : 6;
+			ushort r : 5;
+		} c;
+		ushort u;
+	};
 
-	const uint DDSD_CAPS = 0x00000001l;
-	const uint DDSD_PIXELFORMAT = 0x00001000l;
-	const uint DDSD_WIDTH = 0x00000004l;
-	const uint DDSD_HEIGHT = 0x00000002l;
-	const uint DDSD_PITCH = 0x00000008l;
+	union Color1555 {
+		struct {
+			ushort b : 5;
+			ushort g : 5;
+			ushort r : 5;
+			ushort a : 1;
+		} c;
+		ushort u;
+	};
 
-	const uint DDSCAPS_TEXTURE = 0x00001000l;
-	const uint DDSCAPS2_VOLUME = 0x00200000l;
-	const uint DDSCAPS2_CUBEMAP = 0x00000200l;
+	union Color4444 {
+		struct {
+			ushort b : 4;
+			ushort g : 4;
+			ushort r : 4;
+			ushort a : 4;
+		} c;
+		ushort u;
+	};
 
-	const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400l;
-	const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800l;
-	const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000l;
-	const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000l;
-	const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000l;
-	const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000l;
 
-	const uint DDPF_RGB = 0x00000040l;
- 	const uint DDPF_FOURCC = 0x00000004l;
- 	const uint DDPF_ALPHAPIXELS = 0x00000001l;
+	static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
+	static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
+	static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
+	static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3');
+	static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4');
+	static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5');
+	static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B');
+	static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2');
+
+	static const uint DDSD_CAPS = 0x00000001l;
+	static const uint DDSD_PIXELFORMAT = 0x00001000l;
+	static const uint DDSD_WIDTH = 0x00000004l;
+	static const uint DDSD_HEIGHT = 0x00000002l;
+	static const uint DDSD_PITCH = 0x00000008l;
+
+	static const uint DDSCAPS_TEXTURE = 0x00001000l;
+	static const uint DDSCAPS2_VOLUME = 0x00200000l;
+	static const uint DDSCAPS2_CUBEMAP = 0x00000200l;
+
+	static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400l;
+	static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800l;
+	static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000l;
+	static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000l;
+	static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000l;
+	static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000l;
+
+	static const uint DDPF_RGB = 0x00000040l;
+ 	static const uint DDPF_FOURCC = 0x00000004l;
+ 	static const uint DDPF_ALPHAPIXELS = 0x00000001l;
 
 	enum DDSType {
 		DDS_A8R8G8B8 = 0,
@@ -84,6 +127,8 @@ namespace {	// Private.
 		DDS_DXT3 = 7,
 		DDS_DXT4 = 8,
 		DDS_DXT5 = 9,
+		DDS_RXGB = 10,
+		DDS_ATI2 = 11,
 		DDS_UNKNOWN
 	};
 
@@ -99,7 +144,7 @@ namespace {	// Private.
 		uint amask;
 	};
 
-	QDataStream & operator>> ( QDataStream & s, DDSPixelFormat & pf )
+	static QDataStream & operator>> ( QDataStream & s, DDSPixelFormat & pf )
 	{
 		s >> pf.size;
 		s >> pf.flags;
@@ -119,7 +164,7 @@ namespace {	// Private.
 		uint caps4;
 	};
 
-	QDataStream & operator>> ( QDataStream & s, DDSCaps & caps )
+	static QDataStream & operator>> ( QDataStream & s, DDSCaps & caps )
 	{
 		s >> caps.caps1;
 		s >> caps.caps2;
@@ -142,7 +187,7 @@ namespace {	// Private.
 		uint notused;
 	};
 
-	QDataStream & operator>> ( QDataStream & s, DDSHeader & header )
+	static QDataStream & operator>> ( QDataStream & s, DDSHeader & header )
 	{
 		s >> header.size;
 		s >> header.flags;
@@ -160,7 +205,7 @@ namespace {	// Private.
 		return s;
 	}
 
-	bool IsValid( const DDSHeader & header )
+	static bool IsValid( const DDSHeader & header )
 	{
 		if( header.size != 124 ) {
 			return false;
@@ -180,7 +225,7 @@ namespace {	// Private.
 
 
 	// Get supported type. We currently support 10 different types.
-	DDSType GetType( const DDSHeader & header )
+	static DDSType GetType( const DDSHeader & header )
 	{
 		if( header.pf.flags & DDPF_RGB ) {
 			if( header.pf.flags & DDPF_ALPHAPIXELS ) {
@@ -212,27 +257,28 @@ namespace {	// Private.
 					return DDS_DXT4;
 				case FOURCC_DXT5:
 					return DDS_DXT5;
+				case FOURCC_RXGB:
+					return DDS_RXGB;
+				case FOURCC_ATI2:
+					return DDS_ATI2;
 			}
 		}
 		return DDS_UNKNOWN;
 	}
 
 
-	bool HasAlpha( const DDSHeader & header )
+	static bool HasAlpha( const DDSHeader & header )
 	{
 		return header.pf.flags & DDPF_ALPHAPIXELS;
 	}
 
-	bool IsCubeMap( const DDSHeader & header )
+	static bool IsCubeMap( const DDSHeader & header )
 	{
 		return header.caps.caps2 & DDSCAPS2_CUBEMAP;
 	}
 
-	bool IsSupported( const DDSHeader & header )
+	static bool IsSupported( const DDSHeader & header )
 	{
-		/*if( IsCubeMap(header) ) {
-			return false;
-		}*/
 		if( header.caps.caps2 & DDSCAPS2_VOLUME ) {
 			return false;
 		}
@@ -243,7 +289,7 @@ namespace {	// Private.
 	}
 
 
-	bool LoadA8R8G8B8( QDataStream & s, const DDSHeader & header, QImage img  )
+	static bool LoadA8R8G8B8( QDataStream & s, const DDSHeader & header, QImage & img  )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -260,7 +306,7 @@ namespace {	// Private.
 		return true;
 	}
 
-	bool LoadR8G8B8( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadR8G8B8( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -277,7 +323,7 @@ namespace {	// Private.
 		return true;
 	}
 
-	bool LoadA1R5G5B5( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadA1R5G5B5( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -285,13 +331,12 @@ namespace {	// Private.
 		for( uint y = 0; y < h; y++ ) {
 			QRgb * scanline = (QRgb *) img.scanLine( y );
 			for( uint x = 0; x < w; x++ ) {
-				ushort u;
-				s >> u;
-				uchar r, g, b, a;
-				a = (u & header.pf.amask) != 0 ? 0xFF : 0;
-				r = ((u & header.pf.rmask) >> 10) << 3;
-				g = ((u & header.pf.gmask) >> 5) << 3;
-				b = (u & header.pf.bmask) << 3;
+				Color1555 color;
+				s >> color.u;
+				uchar a = (color.c.a != 0) ? 0xFF : 0;
+				uchar r = (color.c.r << 3) | (color.c.r >> 2);
+				uchar g = (color.c.g << 3) | (color.c.g >> 2);
+				uchar b = (color.c.b << 3) | (color.c.b >> 2);
 				scanline[x] = qRgba(r, g, b, a);
 			}
 		}
@@ -299,7 +344,7 @@ namespace {	// Private.
 		return true;
 	}
 
-	bool LoadA4R4G4B4( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadA4R4G4B4( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -307,13 +352,12 @@ namespace {	// Private.
 		for( uint y = 0; y < h; y++ ) {
 			QRgb * scanline = (QRgb *) img.scanLine( y );
 			for( uint x = 0; x < w; x++ ) {
-				unsigned short u;
-				s >> u;
-				uchar r, g, b, a;
-				a = ((u & header.pf.amask) >> 12) << 4;
-				r = ((u & header.pf.rmask) >> 8) << 4;
-				g = ((u & header.pf.gmask) >> 4) << 4;
-				b = (u & header.pf.bmask) << 4;
+				Color4444 color;
+				s >> color.u;
+				uchar a = (color.c.a << 4) | color.c.a;
+				uchar r = (color.c.r << 4) | color.c.r;
+				uchar g = (color.c.g << 4) | color.c.g;
+				uchar b = (color.c.b << 4) | color.c.b;
 				scanline[x] = qRgba(r, g, b, a);
 			}
 		}
@@ -321,7 +365,7 @@ namespace {	// Private.
 		return true;
 	}
 
-	bool LoadR5G6B5( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadR5G6B5( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -329,12 +373,11 @@ namespace {	// Private.
 		for( uint y = 0; y < h; y++ ) {
 			QRgb * scanline = (QRgb *) img.scanLine( y );
 			for( uint x = 0; x < w; x++ ) {
-				unsigned short u;
-				s >> u;
-				uchar r, g, b;
-				r = ((u & header.pf.rmask) >> 11) << 3;
-				g = ((u & header.pf.gmask) >> 5) << 2;
-				b = (u & header.pf.bmask) << 3;
+				Color565 color;
+				s >> color.u;
+				uchar r = (color.c.r << 3) | (color.c.r >> 2);
+				uchar g = (color.c.g << 2) | (color.c.g >> 4);
+				uchar b = (color.c.b << 3) | (color.c.b >> 2);
 				scanline[x] = qRgb(r, g, b);
 			}
 		}
@@ -342,22 +385,7 @@ namespace {	// Private.
 		return true;
 	}
 
-	struct Color8888
-	{
-		uchar r, g, b, a;
-	};
-
-	union Color565
-	{
-		struct {
-			ushort b : 5;
-			ushort g : 6;
-			ushort r : 5;
-		} c;
-		ushort u;
-	};
-
-	QDataStream & operator>> ( QDataStream & s, Color565 & c )
+	static QDataStream & operator>> ( QDataStream & s, Color565 & c )
 	{
 		return s >> c.u;
 	}
@@ -400,17 +428,17 @@ namespace {	// Private.
 				color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
 				color_array[2].a = 0xFF;
 
-				// magenta to indicate transparent color.
-				color_array[3].r = color_array[2].r;
-				color_array[3].g = color_array[2].g;
-				color_array[3].b = color_array[2].b;
+				// Set all components to 0 to match DXT specs.
+				color_array[3].r = 0x00; // color_array[2].r;
+				color_array[3].g = 0x00; // color_array[2].g;
+				color_array[3].b = 0x00; // color_array[2].b;
 				color_array[3].a = 0x00;
 			}
 		}
 	};
 
 
-	QDataStream & operator>> ( QDataStream & s, BlockDXT & c )
+	static QDataStream & operator>> ( QDataStream & s, BlockDXT & c )
 	{
 		return s >> c.col0 >> c.col1 >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3];
 	}
@@ -419,7 +447,7 @@ namespace {	// Private.
 		ushort row[4];
 	};
 
-	QDataStream & operator>> ( QDataStream & s, BlockDXTAlphaExplicit & c )
+	static QDataStream & operator>> ( QDataStream & s, BlockDXTAlphaExplicit & c )
 	{
 		return s >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3];
 	}
@@ -485,13 +513,13 @@ namespace {	// Private.
 		}
 	};
 
-	QDataStream & operator>> ( QDataStream & s, BlockDXTAlphaLinear & c )
+	static QDataStream & operator>> ( QDataStream & s, BlockDXTAlphaLinear & c )
 	{
 		s >> c.alpha0 >> c.alpha1;
 		return s >> c.bits[0] >> c.bits[1] >> c.bits[2] >> c.bits[3] >> c.bits[4] >> c.bits[5];
 	}
 
-	bool LoadDXT1( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadDXT1( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -530,7 +558,7 @@ namespace {	// Private.
 		return true;
 	}
 
-	bool LoadDXT3( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadDXT3( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -575,14 +603,14 @@ namespace {	// Private.
 		return true;
 	}
 
-	bool LoadDXT2( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadDXT2( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		if( !LoadDXT3(s, header, img) ) return false;
 		//UndoPremultiplyAlpha(img);
 		return true;
 	}
 
-	bool LoadDXT5( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadDXT5( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		const uint w = header.width;
 		const uint h = header.height;
@@ -630,19 +658,122 @@ namespace {	// Private.
 
 		return true;
 	}
-	
-	bool LoadDXT4( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadDXT4( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		if( !LoadDXT5(s, header, img) ) return false;
 		//UndoPremultiplyAlpha(img);
 		return true;
 	}
 
+	static bool LoadRXGB( QDataStream & s, const DDSHeader & header, QImage & img )
+	{
+		const uint w = header.width;
+		const uint h = header.height;
+
+		BlockDXT block;
+		BlockDXTAlphaLinear alpha;
+		QRgb * scanline[4];
 
-	typedef bool (* TextureLoader)( QDataStream & s, const DDSHeader & header, QImage img );
+		for( uint y = 0; y < h; y += 4 ) {
+			for( uint j = 0; j < 4; j++ ) {
+				scanline[j] = (QRgb *) img.scanLine( y + j );
+			}
+			for( uint x = 0; x < w; x += 4 ) {
+
+				// Read 128bit color block.
+				s >> alpha;
+				s >> block;
+
+				// Decode color block.
+				Color8888 color_array[4];
+				block.GetColors(color_array);
+
+				uchar alpha_array[8];
+				alpha.GetAlphas(alpha_array);
+
+				uchar bit_array[16];
+				alpha.GetBits(bit_array);
+
+				// bit masks = 00000011, 00001100, 00110000, 11000000
+				const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 };
+				const int shift[4] = { 0, 2, 4, 6 };
+
+				// Write color block.
+				for( uint j = 0; j < 4; j++ ) {
+					for( uint i = 0; i < 4; i++ ) {
+						if( img.valid( x+i, y+j ) ) {
+							uint idx = (block.row[j] & masks[i]) >> shift[i];
+							color_array[idx].a = alpha_array[bit_array[j*4+i]];
+							scanline[j][x+i] = qRgb(color_array[idx].a, color_array[idx].g, color_array[idx].b);
+						}
+					}
+				}
+			}
+		}
+
+		return true;
+	}
+
+	static bool LoadATI2( QDataStream & s, const DDSHeader & header, QImage & img )
+	{
+		const uint w = header.width;
+		const uint h = header.height;
+
+		BlockDXTAlphaLinear xblock;
+		BlockDXTAlphaLinear yblock;
+		QRgb * scanline[4];
+
+		for( uint y = 0; y < h; y += 4 ) {
+			for( uint j = 0; j < 4; j++ ) {
+				scanline[j] = (QRgb *) img.scanLine( y + j );
+			}
+			for( uint x = 0; x < w; x += 4 ) {
+
+				// Read 128bit color block.
+				s >> xblock;
+				s >> yblock;
+
+				// Decode color block.
+				uchar xblock_array[8];
+				xblock.GetAlphas(xblock_array);
+
+				uchar xbit_array[16];
+				xblock.GetBits(xbit_array);
+
+				uchar yblock_array[8];
+				yblock.GetAlphas(yblock_array);
+
+				uchar ybit_array[16];
+				yblock.GetBits(ybit_array);
+
+				// Write color block.
+				for( uint j = 0; j < 4; j++ ) {
+					for( uint i = 0; i < 4; i++ ) {
+						if( img.valid( x+i, y+j ) ) {
+							const uchar nx = xblock_array[xbit_array[j*4+i]];
+							const uchar ny = yblock_array[ybit_array[j*4+i]];
+							
+							const float fx = float(nx) / 127.5f - 1.0f;
+							const float fy = float(ny) / 127.5f - 1.0f;
+							const float fz = sqrtf(1.0f - fx*fx - fy*fy);
+							const uchar nz = uchar((fz + 1.0f) * 127.5f);
+							
+							scanline[j][x+i] = qRgb(nx, ny, nz);
+						}
+					}
+				}
+			}
+		}
+
+		return true;
+	}
+
+
+
+	typedef bool (* TextureLoader)( QDataStream & s, const DDSHeader & header, QImage & img );
 
 	// Get an appropiate texture loader for the given type.
-	TextureLoader GetTextureLoader( DDSType type ) {
+	static TextureLoader GetTextureLoader( DDSType type ) {
 		switch( type ) {
 			case DDS_A8R8G8B8:
 				return LoadA8R8G8B8;
@@ -664,6 +795,10 @@ namespace {	// Private.
 				return LoadDXT4;
 			case DDS_DXT5:
 				return LoadDXT5;
+			case DDS_RXGB:
+				return LoadRXGB;
+			case DDS_ATI2:
+				return LoadATI2;
 			default:
 				return NULL;
 		};
@@ -671,7 +806,7 @@ namespace {	// Private.
 
 
 	// Load a 2d texture.
-	bool LoadTexture( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadTexture( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		// Create dst image.
 		if( !img.create( header.width, header.height, 32 )) {
@@ -695,7 +830,7 @@ namespace {	// Private.
 	}
 
 
-	int FaceOffset( const DDSHeader & header ) {
+	static int FaceOffset( const DDSHeader & header ) {
 
 		DDSType type = GetType( header );
 
@@ -727,11 +862,11 @@ namespace {	// Private.
 	}
 
 #if CUBE_LAYOUT == HORIZONTAL
-	int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {3, 1} };
+	static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {3, 1} };
 #elif CUBE_LAYOUT == VERTICAL
-	int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {1, 3} };
+	static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {1, 3} };
 #endif
-	int face_flags[6] = {
+	static int face_flags[6] = {
 		DDSCAPS2_CUBEMAP_POSITIVEX,
 		DDSCAPS2_CUBEMAP_NEGATIVEX,
 		DDSCAPS2_CUBEMAP_POSITIVEY,
@@ -741,7 +876,7 @@ namespace {	// Private.
 	};
 
 	// Load unwrapped cube map.
-	bool LoadCubeMap( QDataStream & s, const DDSHeader & header, QImage img )
+	static bool LoadCubeMap( QDataStream & s, const DDSHeader & header, QImage & img )
 	{
 		// Create dst image.
 #if CUBE_LAYOUT == HORIZONTAL
diff -u -3 -d -p -r1.3 -r1.3.2.1
--- exr.cpp	9 Jun 2004 08:28:36 -0000	1.3
+++ exr.cpp	19 Apr 2005 11:11:09 -0000	1.3.2.1
@@ -136,6 +136,8 @@ void kimgio_exr_read( QImageIO *io )
         file.readPixels (dw.min.y, dw.max.y);
 
 		QImage image(width, height, 32, 0, QImage::BigEndian);
+		if( image.isNull())
+			return;
 
 		// somehow copy pixels into image
 		for ( int y=0; y < height; y++ ) {
diff -u -3 -d -p -r1.21 -r1.21.2.1
--- ico.cpp	9 Jun 2004 08:28:36 -0000	1.21
+++ ico.cpp	19 Apr 2005 11:11:09 -0000	1.21.2.1
@@ -113,6 +113,8 @@ namespace
             // closest size match precedes everything else
             if ( std::abs( int( lhs.width - size ) ) <
                  std::abs( int( rhs.width - size ) ) ) return true;
+            else if ( std::abs( int( lhs.width - size ) ) >
+                 std::abs( int( rhs.width - size ) ) ) return false;
             else if ( colors == 0 )
             {
                 // high/true color requested
@@ -144,17 +146,31 @@ namespace
                header.biBitCount != 8 && header.biBitCount != 24 &&
                header.biBitCount != 32 ) ) return false;
 
-        unsigned colors = header.biBitCount >= 24 ?
-                          0 : header.biClrUsed ?
-                          header.biClrUsed : 1 << header.biBitCount;
+        unsigned paletteSize, paletteEntries;
+
+        if (header.biBitCount > 8)
+        {
+            paletteEntries = 0;
+            paletteSize    = 0;
+        }
+        else
+        {
+            paletteSize    = (1 << header.biBitCount);
+            paletteEntries = paletteSize;
+            if (header.biClrUsed && header.biClrUsed < paletteSize)
+                paletteEntries = header.biClrUsed;
+        }
+        
         // Always create a 32-bit image to get the mask right
+        // Note: this is safe as rec.width, rec.height are bytes
         icon.create( rec.width, rec.height, 32 );
         if ( icon.isNull() ) return false;
         icon.setAlphaBuffer( true );
 
-        QMemArray< QRgb > colorTable( 1 << header.biBitCount );
+        QMemArray< QRgb > colorTable( paletteSize );
+        
         colorTable.fill( QRgb( 0 ) );
-        for ( unsigned i = 0; i < colors; ++i )
+        for ( unsigned i = 0; i < paletteEntries; ++i )
         {
             unsigned char rgb[ 4 ];
             stream.readRawBytes( reinterpret_cast< char* >( &rgb ),
@@ -163,6 +179,7 @@ namespace
         }
 
         unsigned bpl = ( rec.width * header.biBitCount + 31 ) / 32 * 4;
+        
         unsigned char* buf = new unsigned char[ bpl ];
         unsigned char** lines = icon.jumpTable();
         for ( unsigned y = rec.height; !stream.atEnd() && y--; )
@@ -265,11 +282,13 @@ extern "C" void kimgio_ico_read( QImageI
         stream >> rec;
         icons.push_back( rec );
     }
-    IconList::const_iterator selected =
-        requestedIndex >= 0 ?
-        std::min( icons.begin() + requestedIndex, icons.end() ) :
-        std::min_element( icons.begin(), icons.end(),
+    IconList::const_iterator selected;
+    if (requestedIndex >= 0) {
+        selected = std::min( icons.begin() + requestedIndex, icons.end() );
+    } else {
+        selected = std::min_element( icons.begin(), icons.end(),
                           LessDifference( requestedSize, requestedColors ) );
+    }
     if ( stream.atEnd() || selected == icons.end() ||
          offset + selected->offset > io->ioDevice()->size() )
         return;
diff -u -3 -d -p -r1.13 -r1.13.6.1
--- jp2.cpp	30 Sep 2003 12:49:01 -0000	1.13
+++ jp2.cpp	19 Apr 2005 11:11:09 -0000	1.13.6.1
@@ -157,8 +157,9 @@ namespace {
 	void
 	draw_view_gray( gs_t& gs, QImage& qti )
 	{
-		qti.create( jas_image_width( gs.image ), jas_image_height( gs.image ),
-			8, 256 );
+		if( !qti.create( jas_image_width( gs.image ), jas_image_height( gs.image ),
+			8, 256 ))
+			return;
 		for( int i = 0; i < 256; ++i )
 			qti.setColor( i, qRgb( i, i, i ) );
 
diff -u -3 -d -p -r1.11 -r1.11.6.1
--- pcx.cpp	23 Oct 2003 13:17:27 -0000	1.11
+++ pcx.cpp	19 Apr 2005 11:11:09 -0000	1.11.6.1
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2002-2003 Nadeem Hasan <nhasan@kde.org>
+   Copyright (C) 2002-2005 Nadeem Hasan <nhasan@kde.org>
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -44,6 +44,11 @@ static QDataStream &operator>>( QDataStr
   s >> ph.HScreenSize;
   s >> ph.VScreenSize;
 
+  // Skip the rest of the header
+  Q_UINT8 byte;
+  while ( s.device()->at() < 128 )
+    s >> byte;
+
   return s;
 }
 
@@ -85,25 +90,22 @@ static QDataStream &operator<<( QDataStr
   return s;
 }
 
-static PCXHEADER header;
-static QImage img;
-static Q_UINT16 w, h;
-
-void PCXHEADER::reset()
+PCXHEADER::PCXHEADER()
 {
+  // Initialize all data to zero
   QByteArray dummy( 128 );
   dummy.fill( 0 );
   QDataStream s( dummy, IO_ReadOnly );
   s >> *this;
 }
 
-static void readLine( QDataStream &s, QByteArray &buf )
+static void readLine( QDataStream &s, QByteArray &buf, const PCXHEADER &header )
 {
   Q_UINT32 i=0;
   Q_UINT32 size = buf.size();
   Q_UINT8 byte, count;
 
-  if ( header.Encoding == 1 )
+  if ( header.isCompressed() )
   {
     // Uncompress the image data
     while ( i < size )
@@ -130,13 +132,14 @@ static void readLine( QDataStream &s, QB
   }
 }
 
-static void readImage1( QDataStream &s )
+static void readImage1( QImage &img, QDataStream &s, const PCXHEADER &header )
 {
   QByteArray buf( header.BytesPerLine );
 
-  img.create( w, h, 1, 2, QImage::BigEndian );
+  if(!img.create( header.width(), header.height(), 1, 2, QImage::BigEndian ))
+    return;
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     if ( s.atEnd() )
     {
@@ -144,10 +147,11 @@ static void readImage1( QDataStream &s )
       return;
     }
 
-    readLine( s, buf );
-
-    for ( int x=0; x<header.BytesPerLine; ++x )
-      *( img.scanLine( y )+x ) = buf[ x ];
+    readLine( s, buf, header );
+    uchar *p = img.scanLine( y );
+    unsigned int bpl = QMIN((header.width()+7)/8, header.BytesPerLine);
+    for ( unsigned int x=0; x< bpl; ++x )
+      p[ x ] = buf[x];
   }
 
   // Set the color palette
@@ -155,14 +159,15 @@ static void readImage1( QDataStream &s )
   img.setColor( 1, qRgb( 255, 255, 255 ) );
 }
 
-static void readImage4( QDataStream &s )
+static void readImage4( QImage &img, QDataStream &s, const PCXHEADER &header )
 {
   QByteArray buf( header.BytesPerLine*4 );
-  QByteArray pixbuf( w );
+  QByteArray pixbuf( header.width() );
 
-  img.create( w, h, 8, 16, QImage::IgnoreEndian );
+  if(!img.create( header.width(), header.height(), 8, 16 ))
+    return;
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     if ( s.atEnd() )
     {
@@ -171,20 +176,19 @@ static void readImage4( QDataStream &s )
     }
 
     pixbuf.fill( 0 );
-    readLine( s, buf );
+    readLine( s, buf, header );
 
     for ( int i=0; i<4; i++ )
     {
       Q_UINT32 offset = i*header.BytesPerLine;
-      for ( int x=0; x<w; ++x )
+      for ( unsigned int x=0; x<header.width(); ++x )
         if ( buf[ offset + ( x/8 ) ] & ( 128 >> ( x%8 ) ) )
           pixbuf[ x ] += ( 1 << i );
     }
 
     uchar *p = img.scanLine( y );
-
-    for ( int x=0; x<w; ++x )
-      *p++ = pixbuf[ x ];
+    for ( unsigned int x=0; x<header.width(); ++x )
+      p[ x ] = pixbuf[ x ];
   }
 
   // Read the palette
@@ -192,13 +196,14 @@ static void readImage4( QDataStream &s )
     img.setColor( i, header.ColorMap.color( i ) );
 }
 
-static void readImage8( QDataStream &s )
+static void readImage8( QImage &img, QDataStream &s, const PCXHEADER &header )
 {
   QByteArray buf( header.BytesPerLine );
 
-  img.create( w, h, 8, 256, QImage::IgnoreEndian );
+  if(!img.create( header.width(), header.height(), 8, 256 ))
+    return;
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     if ( s.atEnd() )
     {
@@ -206,19 +211,19 @@ static void readImage8( QDataStream &s )
       return;
     }
 
-    readLine( s, buf );
+    readLine( s, buf, header );
 
     uchar *p = img.scanLine( y );
-
-    for ( int x=0; x<header.BytesPerLine; ++x )
-      *p++ = buf[ x ];
+    unsigned int bpl = QMIN(header.BytesPerLine, header.width());
+    for ( unsigned int x=0; x<bpl; ++x )
+      p[ x ] = buf[ x ];
   }
 
   Q_UINT8 flag;
   s >> flag;
-  kdDebug() << "Flag: " << flag << endl;
+  kdDebug( 399 ) << "Palette Flag: " << flag << endl;
 
-  if ( flag == 12 && header.Version == 5 )
+  if ( flag == 12 && ( header.Version == 5 || header.Version == 2 ) )
   {
     // Read the palette
     Q_UINT8 r, g, b;
@@ -230,15 +235,16 @@ static void readImage8( QDataStream &s )
   }
 }
 
-static void readImage24( QDataStream &s )
+static void readImage24( QImage &img, QDataStream &s, const PCXHEADER &header )
 {
   QByteArray r_buf( header.BytesPerLine );
   QByteArray g_buf( header.BytesPerLine );
   QByteArray b_buf( header.BytesPerLine );
 
-  img.create( w, h, 32 );
+  if(!img.create( header.width(), header.height(), 32 ))
+    return;
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     if ( s.atEnd() )
     {
@@ -246,14 +252,13 @@ static void readImage24( QDataStream &s 
       return;
     }
 
-    readLine( s, r_buf );
-    readLine( s, g_buf );
-    readLine( s, b_buf );
+    readLine( s, r_buf, header );
+    readLine( s, g_buf, header );
+    readLine( s, b_buf, header );
 
     uint *p = ( uint * )img.scanLine( y );
-
-    for ( int x=0; x<header.BytesPerLine; ++x )
-      *p++ = qRgb( r_buf[ x ], g_buf[ x ], b_buf[ x ] );
+    for ( unsigned int x=0; x<header.width(); ++x )
+      p[ x ] = qRgb( r_buf[ x ], g_buf[ x ], b_buf[ x ] );
   }
 }
 
@@ -268,6 +273,8 @@ void kimgio_pcx_read( QImageIO *io )
     return;
   }
 
+  PCXHEADER header;
+
   s >> header;
 
   if ( header.Manufacturer != 10 || s.atEnd())
@@ -276,10 +283,8 @@ void kimgio_pcx_read( QImageIO *io )
     return;
   }
 
-  w = ( header.XMax-header.XMin ) + 1;
-  h = ( header.YMax-header.YMin ) + 1;
-
-  img.reset();
+  int w = header.width();
+  int h = header.height();
 
   kdDebug( 399 ) << "Manufacturer: " << header.Manufacturer << endl;
   kdDebug( 399 ) << "Version: " << header.Version << endl;
@@ -288,30 +293,27 @@ void kimgio_pcx_read( QImageIO *io )
   kdDebug( 399 ) << "Width: " << w << endl;
   kdDebug( 399 ) << "Height: " << h << endl;
   kdDebug( 399 ) << "Window: " << header.XMin << "," << header.XMax << "," 
-            << header.YMin << "," << header.YMax << endl;
+                 << header.YMin << "," << header.YMax << endl;
   kdDebug( 399 ) << "BytesPerLine: " << header.BytesPerLine << endl;
   kdDebug( 399 ) << "NPlanes: " << header.NPlanes << endl;
 
-  // Skip the rest of the header
-  Q_UINT8 byte;
-  while ( s.device()->at() < 128 )
-    s >> byte;
+  QImage img;
 
   if ( header.Bpp == 1 && header.NPlanes == 1 )
   {
-    readImage1( s );
+    readImage1( img, s, header );
   }
   else if ( header.Bpp == 1 && header.NPlanes == 4 )
   {
-    readImage4( s );
+    readImage4( img, s, header );
   }
   else if ( header.Bpp == 8 && header.NPlanes == 1 )
   {
-    readImage8( s );
+    readImage8( img, s, header );
   }
   else if ( header.Bpp == 8 && header.NPlanes == 3 )
   {
-    readImage24( s );
+    readImage24( img, s, header );
   }
 
   kdDebug( 399 ) << "Image Bytes: " << img.numBytes() << endl;
@@ -359,7 +361,7 @@ static void writeLine( QDataStream &s, Q
   }
 }
 
-static void writeImage1( QDataStream &s )
+static void writeImage1( QImage &img, QDataStream &s, PCXHEADER &header )
 {
   img = img.convertBitOrder( QImage::BigEndian );
 
@@ -367,29 +369,27 @@ static void writeImage1( QDataStream &s 
   header.NPlanes = 1;
   header.BytesPerLine = img.bytesPerLine();
 
-  header.ColorMap.setColor( 0, qRgb( 0, 0, 0 ) );
-  header.ColorMap.setColor( 1, qRgb( 255, 255, 255 ) );
-
   s << header;
 
   QByteArray buf( header.BytesPerLine );
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     Q_UINT8 *p = img.scanLine( y );
 
+    // Invert as QImage uses reverse palette for monochrome images?
     for ( int i=0; i<header.BytesPerLine; ++i )
-      buf[ i ] = p[ i ];
+      buf[ i ] = ~p[ i ];
 
     writeLine( s, buf );
   }
 }
 
-static void writeImage4( QDataStream &s )
+static void writeImage4( QImage &img, QDataStream &s, PCXHEADER &header )
 {
   header.Bpp = 1;
   header.NPlanes = 4;
-  header.BytesPerLine = w/8;
+  header.BytesPerLine = header.width()/8;
 
   for ( int i=0; i<16; ++i )
     header.ColorMap.setColor( i, img.color( i ) );
@@ -401,14 +401,14 @@ static void writeImage4( QDataStream &s 
   for ( int i=0; i<4; ++i )
       buf[ i ].resize( header.BytesPerLine );
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     Q_UINT8 *p = img.scanLine( y );
 
     for ( int i=0; i<4; ++i )
       buf[ i ].fill( 0 );
 
-    for ( int x=0; x<w; ++x )
+    for ( unsigned int x=0; x<header.width(); ++x )
     {
       for ( int i=0; i<4; ++i )
         if ( *( p+x ) & ( 1 << i ) )
@@ -420,7 +420,7 @@ static void writeImage4( QDataStream &s 
   }
 }
 
-static void writeImage8( QDataStream &s )
+static void writeImage8( QImage &img, QDataStream &s, PCXHEADER &header )
 {
   header.Bpp = 8;
   header.NPlanes = 1;
@@ -430,7 +430,7 @@ static void writeImage8( QDataStream &s 
 
   QByteArray buf( header.BytesPerLine );
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     Q_UINT8 *p = img.scanLine( y );
 
@@ -449,23 +449,23 @@ static void writeImage8( QDataStream &s 
     s << RGB( img.color( i ) );
 }
 
-static void writeImage24( QDataStream &s )
+static void writeImage24( QImage &img, QDataStream &s, PCXHEADER &header )
 {
   header.Bpp = 8;
   header.NPlanes = 3;
-  header.BytesPerLine = w;
+  header.BytesPerLine = header.width();
 
   s << header;
 
-  QByteArray r_buf( w );
-  QByteArray g_buf( w );
-  QByteArray b_buf( w );
+  QByteArray r_buf( header.width() );
+  QByteArray g_buf( header.width() );
+  QByteArray b_buf( header.width() );
 
-  for ( int y=0; y<h; ++y )
+  for ( int y=0; y<header.height(); ++y )
   {
     uint *p = ( uint * )img.scanLine( y );
 
-    for ( int x=0; x<w; ++x )
+    for ( unsigned int x=0; x<header.width(); ++x )
     {
       QRgb rgb = *p++;
       r_buf[ x ] = qRed( rgb );
@@ -484,10 +484,10 @@ void kimgio_pcx_write( QImageIO *io )
   QDataStream s( io->ioDevice() );
   s.setByteOrder( QDataStream::LittleEndian );
 
-  img = io->image();
+  QImage img = io->image();
 
-  w = img.width();
-  h = img.height();
+  int w = img.width();
+  int h = img.height();
 
   kdDebug( 399 ) << "Width: " << w << endl;
   kdDebug( 399 ) << "Height: " << h << endl;
@@ -495,6 +495,8 @@ void kimgio_pcx_write( QImageIO *io )
   kdDebug( 399 ) << "BytesPerLine: " << img.bytesPerLine() << endl;
   kdDebug( 399 ) << "Num Colors: " << img.numColors() << endl;
 
+  PCXHEADER header;
+
   header.Manufacturer = 10;
   header.Version = 5;
   header.Encoding = 1;
@@ -509,19 +511,19 @@ void kimgio_pcx_write( QImageIO *io )
 
   if ( img.depth() == 1 )
   {
-    writeImage1( s );
+    writeImage1( img, s, header );
   }
   else if ( img.depth() == 8 && img.numColors() <= 16 )
   {
-    writeImage4( s );
+    writeImage4( img, s, header );
   }
   else if ( img.depth() == 8 )
   {
-    writeImage8( s );
+    writeImage8( img, s, header );
   }
   else if ( img.depth() == 32 )
   {
-    writeImage24( s );
+    writeImage24( img, s, header );
   }
 
   io->setStatus( 0 );
Index: pcx.h
===================================================================
RCS file: /home/kde/kdelibs/kimgio/pcx.h,v
retrieving revision 1.4
retrieving revision 1.4.6.1
diff -u -3 -d -p -r1.4 -r1.4.6.1
--- pcx.h	4 Jan 2003 00:48:25 -0000	1.4
+++ pcx.h	19 Apr 2005 11:11:09 -0000	1.4.6.1
@@ -49,7 +49,7 @@ class Palette
       rgb[ i ] = RGB( color );
     }
 
-    QRgb color( int i )
+    QRgb color( int i ) const
     {
       return qRgb( rgb[ i ].r, rgb[ i ].g, rgb[ i ].b );
     }
@@ -60,12 +60,11 @@ class Palette
 class PCXHEADER
 {
   public:
-    PCXHEADER()
-    {
-      reset();
-    }
+    PCXHEADER();
 
-    void reset();
+    inline int width() const { return ( XMax-XMin ) + 1; }
+    inline int height() const { return ( YMax-YMin ) + 1; }
+    inline bool isCompressed() const { return ( Encoding==1 ); }
 
     Q_UINT8  Manufacturer;    // Constant Flag, 10 = ZSoft .pcx
     Q_UINT8  Version;         // Version information╥
@@ -99,7 +98,7 @@ class PCXHEADER
                               // found only in PB IV/IV Plus
     Q_UINT16 VScreenSize;     // Vertical screen size in pixels. New field
                               // found only in PB IV/IV Plus
-};
+} KDE_PACKED;
 
 #endif // PCX_H
 
diff -u -3 -d -p -r1.25 -r1.25.2.1
--- rgb.cpp	9 Jun 2004 08:28:36 -0000	1.25
+++ rgb.cpp	19 Apr 2005 11:11:09 -0000	1.25.2.1
@@ -87,7 +87,9 @@ bool SGIImage::getRow(uchar *dest)
 	int n, i;
 	if (!m_rle) {
 		for (i = 0; i < m_xsize; i++) {
-			*dest++ = uchar(*m_pos);
+			if(m_pos >= m_data.end())
+				return false;
+			dest[i] = uchar(*m_pos);
 			m_pos += m_bpc;
 		}
 		return true;
@@ -120,7 +122,7 @@ bool SGIImage::readData(QImage& img)
 {
 	QRgb *c;
 	Q_UINT32 *start = m_starttab;
-	QCString lguard(m_xsize);
+	QByteArray lguard(m_xsize);
 	uchar *line = (uchar *)lguard.data();
 	unsigned x, y;
 
@@ -128,7 +130,7 @@ bool SGIImage::readData(QImage& img)
 		m_pos = m_data.begin();
 
 	for (y = 0; y < m_ysize; y++) {
-		c = reinterpret_cast<QRgb *>(img.scanLine(m_ysize - y - 1));
+		c = (QRgb *) img.scanLine(m_ysize - y - 1);
 		if (m_rle)
 			m_pos = m_data.begin() + *start++;
 		if (!getRow(line))
@@ -166,11 +168,11 @@ bool SGIImage::readData(QImage& img)
 	}
 
 	for (y = 0; y < m_ysize; y++) {
-		c = reinterpret_cast<QRgb *>(img.scanLine(m_ysize - y - 1));
 		if (m_rle)
 			m_pos = m_data.begin() + *start++;
 		if (!getRow(line))
 			return false;
+		c = (QRgb*) img.scanLine(m_ysize - y - 1);
 		for (x = 0; x < m_xsize; x++, c++)
 			*c = qRgba(qRed(*c), qGreen(*c), qBlue(*c), line[x]);
 	}
@@ -351,24 +353,32 @@ uchar SGIImage::intensity(uchar c)
 
 uint SGIImage::compact(uchar *d, uchar *s)
 {
-	uchar *dest = d, *src = s, patt, *cnt;
-	int n;
-	while (src - s < m_xsize) {
-		if (src - s + 1 == m_xsize) {		// last bit
-			*dest++ = 0x81;
-			*dest++ = *src;
+	uchar *dest = d, *src = s, patt, *t, *end = s + m_xsize;
+	int i, n;
+	while (src < end) {
+		for (n = 0, t = src; t + 2 < end && !(*t == t[1] && *t == t[2]); t++)
+			n++;
+
+		while (n) {
+			i = n > 126 ? 126 : n;
+			n -= i;
+			*dest++ = 0x80 | i;
+			while (i--)
+				*dest++ = *src++;
+		}
+
+		if (src == end)
 			break;
-		} else if (*src == src[1]) {
-			patt = *src++;
-			for (n = 1; src - s < m_xsize && n < 126 && *src == patt; src++)
-				n++;
-			*dest++ = n;
+
+		patt = *src++;
+		for (n = 1; src < end && *src == patt; src++)
+			n++;
+
+		while (n) {
+			i = n > 126 ? 126 : n;
+			n -= i;
+			*dest++ = i;
 			*dest++ = patt;
-		} else {
-			cnt = dest++;
-			for (n = 0; src - s < m_xsize && n < 126 && *src != src[1]; n++)
-				*dest++ = *src++;
-			*cnt = 0x80 | n;
 		}
 	}
 	*dest++ = 0;
@@ -444,16 +454,12 @@ void SGIImage::writeHeader()
 	kdDebug(399) << "Description: " << desc << endl;
 	desc.truncate(79);
 
-	char id[] = "KDE kimgio", *s = id;
 	for (i = 0; i < desc.length(); i++)
 		m_imagename[i] = desc.latin1()[i];
 	for (; i < 80; i++)
 		m_imagename[i] = '\0';
-	if (desc.length() < 68)
-		for (i = 69; *s; i++)
-			m_imagename[i] = *s++;
-
 	m_stream.writeRawBytes(m_imagename, 80);
+
 	m_stream << m_colormap;
 	for (i = 0; i < 404; i++)
 		m_stream << Q_UINT8(0);
@@ -551,13 +557,6 @@ bool SGIImage::writeImage(QImage& img)
 
 	m_numrows = m_ysize * m_zsize;
 
-	// compressing a row with up to 11 pixels takes 11 or more bytes
-	// (start/length table: 8, smallest possible RLE packet: 3)
-	if (m_xsize <= 11) {
-		writeVerbatim(img);
-		return true;
-	}
-
 	m_starttab = new Q_UINT32[m_numrows];
 	m_rlemap.setBaseOffset(512 + m_numrows * 2 * sizeof(Q_UINT32));
 
@@ -579,7 +578,7 @@ bool SGIImage::writeImage(QImage& img)
 	kdDebug(399) << "total savings: " << (verbatim_size - rle_size) << " bytes" << endl;
 	kdDebug(399) << "compression: " << (rle_size * 100.0 / verbatim_size) << '%' << endl;
 
-	if (verbatim_size <= rle_size)
+	if (verbatim_size <= rle_size || m_io->quality() > 50)
 		writeVerbatim(img);
 	else
 		writeRle();
diff -u -3 -d -p -r1.7 -r1.7.2.1
--- tga.cpp	1 Aug 2004 16:45:53 -0000	1.7
+++ tga.cpp	19 Apr 2005 11:11:09 -0000	1.7.2.1
@@ -1,5 +1,6 @@
 /* This file is part of the KDE project
    Copyright (C) 2003 Dominik Seichter <domseichter@web.de>
+   Copyright (C) 2004 Ignacio CastaЯo <castano@ludicon.com>
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the Lesser GNU General Public
@@ -9,213 +10,347 @@
 
 /* this code supports:
  * reading:
- *     run length encoded true color tga files
- *     uncompressed true color tga files
+ *     uncompressed and run length encoded indexed, grey and color tga files.
+ *     image types 1, 2, 3, 9, 10 and 11.
+ *     only RGB color maps with no more than 256 colors.
+ *     pixel formats 8, 15, 24 and 32.
  * writing:
  *     uncompressed true color tga files
  */
 
 #include "tga.h"
 
+#include <assert.h>
+
 #include <qimage.h>
 #include <qdatastream.h>
 
-/*
- * uncompressed TGA magic header
- */
-unsigned char targaMagic[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+#include <kdebug.h>
 
-/* 
- * compressed TGA magic header
- */
-unsigned char compMagic[12] = { 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+typedef Q_UINT32 uint;
+typedef Q_UINT16 ushort;
+typedef Q_UINT8 uchar;
 
-/*
- * the origin of the image (default is TOP_LEFT)
- */
-enum { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT };
+namespace {	// Private.
 
-/*
- * Read one pixel and return its color 
- */
-int getData( QDataStream* s, int bpp )
-{
-    unsigned char* data = new unsigned char[bpp];
+	// Header format of saved files.
+	uchar targaMagic[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
-    for( int d = 0; d < bpp; d++ )
-        *s >> data[d];
+	enum TGAType {
+		TGA_TYPE_INDEXED		= 1,
+		TGA_TYPE_RGB			= 2,
+		TGA_TYPE_GREY			= 3,
+		TGA_TYPE_RLE_INDEXED	= 9,
+		TGA_TYPE_RLE_RGB		= 10,
+		TGA_TYPE_RLE_GREY		= 11
+	};
 
-    int color = 0;
-    if( bpp == 4 )
-        color = qRgba( data[0], data[1], data[2], data[3] );
-    else 
-        color = qRgb( data[0], data[1], data[2] );
+#define TGA_INTERLEAVE_MASK	0xc0
+#define TGA_INTERLEAVE_NONE	0x00
+#define TGA_INTERLEAVE_2WAY	0x40
+#define TGA_INTERLEAVE_4WAY	0x80
 
-    delete [] data;
-    return color;
-}
+#define TGA_ORIGIN_MASK		0x30
+#define TGA_ORIGIN_LEFT		0x00
+#define TGA_ORIGIN_RIGHT	0x10
+#define TGA_ORIGIN_LOWER	0x00
+#define TGA_ORIGIN_UPPER	0x20
 
-/*
- * checks wether y is inside of the image
- * when origin is of mode m
- */
-bool checky( int y, int h, int m ) 
-{
-    if( m == TOP_LEFT ) 
-	return (y < h);
-    else if( m == BOTTOM_LEFT || m == BOTTOM_RIGHT )
-	return ( y >= 0 );
+	/** Tga Header. */
+	struct TgaHeader {
+		uchar id_length;
+		uchar colormap_type;
+		uchar image_type;
+		ushort colormap_index;
+		ushort colormap_length;
+		uchar colormap_size;
+		ushort x_origin;
+		ushort y_origin;
+		ushort width;
+		ushort height;
+		uchar pixel_size;
+		uchar flags;
+	
+		enum { SIZE = 18 }; // const static int SIZE = 18;
+	};
 
-    return false;
-}
+	static QDataStream & operator>> ( QDataStream & s, TgaHeader & head )
+	{
+		s >> head.id_length;
+		s >> head.colormap_type;
+		s >> head.image_type;
+		s >> head.colormap_index;
+		s >> head.colormap_length;
+		s >> head.colormap_size;
+		s >> head.x_origin;
+		s >> head.y_origin;
+		s >> head.width;
+		s >> head.height;
+		s >> head.pixel_size;
+		s >> head.flags;
+		return s;
+	}
 
-  /*
-   * checks wether x is inside of the image
-   * when origin is of mode m
-   */
-  bool checkx( int x, int w, int m ) 
-  {
-      if( m == TOP_LEFT || m == BOTTOM_LEFT ) 
-	  return (x < w);
-      else if( m == BOTTOM_RIGHT )
-	  return ( x >= 0 );
+	static bool IsSupported( const TgaHeader & head )
+	{
+		if( head.image_type != TGA_TYPE_INDEXED &&
+			head.image_type != TGA_TYPE_RGB &&
+			head.image_type != TGA_TYPE_GREY &&
+			head.image_type != TGA_TYPE_RLE_INDEXED &&
+			head.image_type != TGA_TYPE_RLE_RGB &&
+			head.image_type != TGA_TYPE_RLE_GREY )
+		{
+			return false;
+		}
+		if( head.image_type == TGA_TYPE_INDEXED ||
+			head.image_type == TGA_TYPE_RLE_INDEXED )
+		{
+			if( head.colormap_length > 256 || head.colormap_size != 24 )
+			{
+				return false;
+			}
+		}
+		if( head.width == 0 || head.height == 0 )
+		{
+			return false;
+		}
+		if( head.pixel_size != 8 && head.pixel_size != 16 &&
+			head.pixel_size != 24 && head.pixel_size != 32 )
+		{
+			return false;
+		}
+		return true;
+	}
 
-      return false;
-  }
+	struct Color555 {
+		ushort b : 5;
+		ushort g : 5;
+		ushort r : 5;
+	};
+	
+	static bool HasAlpha( const TgaHeader & tga )
+	{
+		return tga.pixel_size == 32;
+	}
 
-  void kimgio_tga_read( QImageIO *io )
-  {
-      unsigned char header[6];
-      bool compressed = false;
+	struct TgaHeaderInfo {
+		bool rle;
+		bool pal;
+		bool rgb;
+		bool grey;
+		bool supported;
+	
+		TgaHeaderInfo( const TgaHeader & tga ) : rle(false), pal(false), rgb(false), grey(false), supported(true)
+		{
+			switch( tga.image_type ) {
+				case TGA_TYPE_RLE_INDEXED:
+					rle = true;
+					// no break is intended!
+				case TGA_TYPE_INDEXED:
+					if( tga.colormap_type!=1 || tga.colormap_size!=24 || tga.colormap_length>256 ) {
+						supported = false;
+					}
+					pal = true;
+					break;
+		
+				case TGA_TYPE_RLE_RGB:
+					rle = true;
+					// no break is intended!
+				case TGA_TYPE_RGB:
+					rgb = true;
+					break;
+		
+				case TGA_TYPE_RLE_GREY:
+					rle = true;
+					// no break is intended!
+				case TGA_TYPE_GREY:
+					grey = true;
+					break;
+		
+				default:
+					// Error, unknown image type.
+					supported = false;
+			}
+		}
+	};
+	
 
-      QDataStream s( io->ioDevice() );
-      s.setByteOrder( QDataStream::LittleEndian );
 
-      /*
-       * check whether it is a targa file or not
-       */
-      for( int i = 0; i < 12; i++ ) {
-	  unsigned char a;
-	  s >> a;
-	  if( a != targaMagic[i] && a!= compMagic[i]) {
-	      io->setImage( 0 );
-	      io->setStatus( -1 );            
-	      return;
-	  }
+	static bool LoadTGA( QDataStream & s, const TgaHeader & tga, QImage &img )
+	{
+		// Create image.
+		if( !img.create( tga.width, tga.height, 32 )) {
+			return false;
+		}
 
-	  // check if it is a compressed targa file
-	  if( i == 2 && a == compMagic[i] )
-	      compressed = true;
-      }
+		TgaHeaderInfo info(tga);
+		if( !info.supported ) {
+			// File not supported.
+  			kdDebug(399) << "This TGA file is not supported." << endl;
+			return false;
+		}
+		
+		// Enable alpha buffer for transparent images.
+		if( HasAlpha( tga ) ) {
+			img.setAlphaBuffer( true );
+		}
 
-      for( int i = 0; i < 6; i++ )
-	  s >> header[i];
-      if( s.atEnd()) {
-	  io->setImage( 0 );
-	  io->setStatus( -1 );            
-	  return;
-      }
+		uint pixel_size = (tga.pixel_size/8);
+		uint size = tga.width * tga.height * pixel_size;
 
-      int width  = header[1] * 256 + header[0];
-      int height = header[3] * 256 + header[2];
-      int bpp = header[4];
-      int bit = header[5];
-      int bytesPerPixel = bpp / 8;
+		
+		// Read palette.
+		char palette[768];
+		if( info.pal ) {
+			// @todo Support palettes in other formats!
+			s.readRawBytes( palette, 3 * tga.colormap_length );
+		}
 
-    /* Bit values:
-     * bit 0-3: number of alpha bits per fixel 
-     * bit 4-5: origin of image:
-     *  - 0 0 bottom left
-     *  - 1 0 bottom right
-     *  - 0 1 top left // that's what we write
-     *  - 1 1 top right
-     */
+		// Allocate image.
+		uchar * const image = new uchar[size];
 
-    int mode;
-    if( (bit | 0)  == 0 )
-	mode = BOTTOM_LEFT;
-    else if( (bit & 8) == 8 )
-	/*
-	 * should be BOTTOM_RIGHT,
-	 * but GIMP writes them this way.
-	 */
-	mode = BOTTOM_LEFT;
-    else if( (bit & 32) == 32 )
-	mode = TOP_LEFT;
-    else
-	mode = TOP_LEFT;
+		if( info.rle ) {
+			// Decode image.
+			char * dst = (char *)image;
+			int num = size;
+	
+			while (num > 0) {
+				// Get packet header.
+				uchar c; 
+				s >> c;
+	
+				uint count = (c & 0x7f) + 1;
+				num -= count * pixel_size;
+	
+				if (c & 0x80) {
+					// RLE pixels.
+                                        assert(pixel_size <= 8);
+					char pixel[8];
+					s.readRawBytes( pixel, pixel_size );
+					do {
+						memcpy(dst, pixel, pixel_size);
+						dst += pixel_size;
+					} while (--count);
+				}
+				else {
+					// Raw pixels.
+					count *= pixel_size;
+					s.readRawBytes( dst, count );
+					dst += count;
+				}
+			}
+		}
+		else {
+			// Read raw image.
+			s.readRawBytes( (char *)image, size );
+		}
 
-    if( bytesPerPixel != 3 &&  bytesPerPixel != 4 ) {	
-	io->setImage( 0 );
-	io->setStatus( -1 );
-	return;
-    }
+		// Convert image to internal format.				
+		int y_start, y_step, y_end;
+		if( tga.flags & TGA_ORIGIN_UPPER ) {
+			y_start = 0;
+			y_step = 1;
+			y_end = tga.height - 1;
+		}
+		else {
+			y_start = tga.height - 1;
+			y_step = -1;
+			y_end = 0;
+		}
 
-    QImage img;
-    if( !img.create( width, height, (bpp == 24 ? 32 : bpp) )) {
-        io->setImage( 0 );
-        io->setStatus( -1 );
-        return;
-    }
+		uchar * src = image;
 
-    /*
-     * Enable alpha buffer for transparent images
-     */
-    if( img.depth() == 32 ) 
-	img.setAlphaBuffer( true );
+		for( int y = y_start; y != y_end; y += y_step ) {
+			QRgb * scanline = (QRgb *) img.scanLine( y );
+		
+			if( info.pal ) {
+				// Paletted.
+				for( int x = 0; x < tga.width; x++ ) {
+					uchar idx = *src++;
+					scanline[x] = qRgb( palette[3*idx+2], palette[3*idx+1], palette[3*idx+0] );
+				}
+			}
+			else if( info.grey ) {
+				// Greyscale.
+				for( int x = 0; x < tga.width; x++ ) {
+					scanline[x] = qRgb( *src, *src, *src );
+					src++;
+				}
+			}
+			else {
+				// True Color.
+				if( tga.pixel_size == 16 ) {
+					for( int x = 0; x < tga.width; x++ ) {
+						Color555 c = *reinterpret_cast<Color555 *>(src);
+						scanline[x] = qRgb( (c.r << 3) | (c.r >> 2), (c.g << 3) | (c.g >> 2), (c.b << 3) | (c.b >> 2) );
+						src += 2;
+					}
+				}
+				else if( tga.pixel_size == 24 ) {
+					for( int x = 0; x < tga.width; x++ ) {
+						scanline[x] = qRgb( src[2], src[1], src[0] );
+						src += 3;
+					}
+				}
+				else if( tga.pixel_size == 32 ) {
+					for( int x = 0; x < tga.width; x++ ) {
+						scanline[x] = qRgba( src[2], src[1], src[0], src[3] );
+						src += 4;
+					}
+				}
+			}
+		}
 
+		// Free image.
+		delete [] image;
+		
+		return true;
+	}
+	
+} // namespace
 
-    int x = 0;
-    int y = 0;
-    int addy = 1;
-    int addx = 1;
-    if( mode == BOTTOM_LEFT || mode == BOTTOM_RIGHT ) {
-	y = height - 1;
-	addy = -1;
-    }
 
-    if( mode == BOTTOM_RIGHT || mode == TOP_RIGHT ) {
-	x = width - 1;
-	addx = -1;
-    }
+void kimgio_tga_read( QImageIO *io )
+{
+	//kdDebug(399) << "Loading TGA file!" << endl;
+	
+	QDataStream s( io->ioDevice() );
+	s.setByteOrder( QDataStream::LittleEndian );
+
+
+	// Read image header.
+	TgaHeader tga;
+	s >> tga;
+	s.device()->at( TgaHeader::SIZE + tga.id_length );
+
+	// Check image file format.
+	if( s.atEnd() ) {
+		kdDebug(399) << "This TGA file is not valid." << endl;
+		io->setImage( 0 );
+		io->setStatus( -1 );
+		return;
+	}
+
+	// Check supported file types.
+	if( !IsSupported(tga) ) {
+		kdDebug(399) << "This TGA file is not supported." << endl;
+		io->setImage( 0 );
+		io->setStatus( -1 );
+		return;
+	}
+				
+
+	QImage img;
+	bool result = LoadTGA(s, tga, img);
+		
+	if( result == false ) {
+  		kdDebug(399) << "Error loading TGA file." << endl;
+		io->setImage( 0 );
+		io->setStatus( -1 );
+		return;
+	}
 
-    /*
-     * we have to restore the value of x after each loop
-     */
-    int oldx = x;
-    if( !compressed ) {
-	for( ; !s.atEnd() && checky( y, height, mode ); y += addy )
-	    for( x = oldx; checkx( x, width, mode ); x += addx  ) {
-		img.setPixel( x, y, getData( &s, bytesPerPixel ) );
-	    }
-    } else {
-        unsigned char cur;
-        while( !s.atEnd() && checky( y, height, mode ) ) {
-            while( checkx( x, width, mode ) ) {
-                s >> cur;
-                if( (cur & 128) == 128 ) {
-                    // found a RLE chunk
-                    int length = (cur & 127) + 1;
-                    int color = getData( &s, bytesPerPixel );
-                    for( int i = 0; i < length; i++ ) {
-                        img.setPixel( x, y, color );
-                        x += addx;
-                    }
-                } else {
-                    int length = (cur & 127) + 1;
-                    for( int i = 0; i < length; i++ ) {
-                        img.setPixel( x, y, getData( &s, bytesPerPixel ) );
-                        x += addx;
-                   }
-                }
-            }
-            y += addy;
-            x = oldx;
-        }
-    }
 
-    img = img.swapRGB();
-    
     io->setImage( img );
     io->setStatus( 0 );
 }
diff -u -3 -d -p -r1.12 -r1.12.2.1
--- tiffr.cpp	9 Jun 2004 08:28:36 -0000	1.12
+++ tiffr.cpp	19 Apr 2005 11:11:09 -0000	1.12.2.1
@@ -83,6 +83,10 @@ void kimgio_tiff_read( QImageIO *io )
             return;
 
 	QImage image( width, height, 32 );
+	if( image.isNull()) {
+		TIFFClose( tiff );
+		return;
+	}
 	data = (uint32 *)image.bits();
 
 	//Sven: changed to %ld for 64bit machines
diff -u -3 -d -p -r1.10 -r1.10.6.1
--- xview.cpp	6 Sep 2003 19:06:36 -0000	1.10
+++ xview.cpp	19 Apr 2005 11:11:09 -0000	1.10.6.1
@@ -7,12 +7,16 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include <qimage.h>
 
 #include "xview.h"
 
 #define BUFSIZE 1024
 
+static const int b_255_3[]= {0,85,170,255},  // index*255/3
+           rg_255_7[]={0,36,72,109,145,182,218,255}; // index *255/7
+
 void kimgio_xv_read( QImageIO *_imageio )
 {      
 	int x=-1;
@@ -48,10 +52,14 @@ void kimgio_xv_read( QImageIO *_imageio 
 	sscanf(str, "%d %d %d", &x, &y, &maxval);
 
 	if (maxval != 255) return;
+	int blocksize = x*y;
+        if(x < 0 || y < 0 || blocksize < x || blocksize < y)
+            return;
 
 	// now follows a binary block of x*y bytes. 
-	int blocksize = x*y;
-	char *block = new char[ blocksize ];
+	char *block = (char*) malloc(blocksize);
+        if(!block)
+            return;
 
 	if (iodev->readBlock(block, blocksize) != blocksize ) 
 	{
@@ -60,6 +68,10 @@ void kimgio_xv_read( QImageIO *_imageio 
 
 	// Create the image
 	QImage image( x, y, 8, maxval + 1, QImage::BigEndian );
+	if( image.isNull()) {
+                free(block);
+		return;
+        }
 
 	// how do the color handling? they are absolute 24bpp
 	// or at least can be calculated as such.
@@ -67,29 +79,9 @@ void kimgio_xv_read( QImageIO *_imageio 
 
 	for ( int j = 0; j < 256; j++ )
 	{
-// ----------- OLIVER EIDEN
-// 	That is the old-code !
-/*		r =  ((int) ((j >> 5) & 0x07)) << 5;
-		g =  ((int) ((j >> 2) & 0x07)) << 5;
-		b =  ((int) ((j >> 0) & 0x03)) << 6;*/
-
-
-// 	That is the code-how xv, decode 3-3-2 pixmaps, it is slighly different,
-//	but yields much better visuals results
-/*		r =  (((int) ((j >> 5) & 0x07)) *255) / 7;
-		g =  (((int) ((j >> 2) & 0x07)) *255) / 7;
-		b =  (((int) ((j >> 0) & 0x03)) *255) / 3;*/
-
-//	This is the same as xv, with multiplications/divisions replaced by indexing
-
-//      Look-up table to avoid multiplications and divisons
-	static int b_255_3[]= {0,85,170,255},  // index*255/3
-		   rg_255_7[]={0,36,72,109,145,182,218,255}; // index *255/7
-
 		r =  rg_255_7[((j >> 5) & 0x07)];
 		g =  rg_255_7[((j >> 2) & 0x07)];
 		b =  b_255_3[((j >> 0) & 0x03)];
-// ---------------
 		image.setColor( j, qRgb( r, g, b ) );
 	}
 
@@ -102,7 +94,7 @@ void kimgio_xv_read( QImageIO *_imageio 
 	_imageio->setImage( image );
 	_imageio->setStatus( 0 );
 
-	delete [] block;
+	free(block);
 	return;
 }
 
 
design & coding: Vladimir Lettiev aka crux © 2004-2005