[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    kimgio - xv-thumbnail-support - small, but significant improvement
From:       Torben Weis <weis () troll ! no>
Date:       1999-03-23 18:14:57
[Download RAW message or body]

Hi,

this looks like a solution to a stone old problem of my thumbnail code.

Could anybody test it and apply it if it works ?

I have no running konqueror here right now :-((

Bye
Torben


---------- Forwarded message ----------
Date: Tue, 23 Mar 1999 13:48:27 +0100
From: Oliver Eiden <o.eiden@pop.ruhr.de>
To: weis@kde.org,
    taj@kde.org
Subject: kimgio - xv-thumbnail-support - small, but significant improvement
Resent-Date: Tue, 23 Mar 1999 16:07:21 +0000
Resent-From: weis@stud.uni-frankfurt.de
Resent-To: weis@troll.no

Hi kimgio team !

I was wondering why thumbnails generated by xv doesn't look as nice when they are displayed in kfm
(or other KDE-Application) compared to xv. I have compared the source of xv and kimgio/xview.cpp for
loading thumbnails.

Kimgio decodes thumbnails differently to xv when loading and xv does it "better".

The problem is that in xview.cpp the 3-3-2 bits (rgb) aren't mapped "correctly" to 8-8-8 bits (rgb).
Kimgio just doesn't use the complete available color space. This lead to a "darker"/"murkier"
display.

For example the byte 0xFF (7-7-3) (rgb) should represents white, when saved in a xvthumnnails, but
in the current implemtation kimigio mapps 0xFF to 7<<5=224=0xE0, 7<<5=224=0xE0, 3<<6=192=0xCO, but
it should map 0xFF to 0xFF 0xFF 0xFF.

Below I have included an improved version of kimgio/xview.cpp. It is based on the kde-1.1 version.
It is just slightly modified, but the result is significantly "visually" better. Please let me know,
if you will include it in a next kde-release.

If you are not the right people to send those "patches" please let me know, where I should sent it
instead. 

BTW: This doen't increase the quality of kfm-generated thumbnails, because before saving them via
kimgio, they should be dithered with the correct color-table.


Have a nice day !

Oliver

["xview.cpp" (TEXT/PLAIN)]

// Oliver Eiden o.eiden@pop.ruhr.de
// 23.3.99
// changed the mapping from 3-3-2 decoded pixils to 8-8-8 decoded true-clour pixels
// now it uses the same mapping as xv, this leads to better visual results
//
// Oliver Eiden

#include <stdio.h>
#include <string.h>
#include <qiodev.h>
#include <qcolor.h>
#include <qfile.h>
#include <qwmatrix.h>

#include "xview.h"

#define BUFSIZE 1024

void kimgio_xv_read( QImageIO *_imageio )
{      
	int x=-1;
	int y=-1;
	int maxval=-1;
	QIODevice *iodev = _imageio->ioDevice();

	char str[ BUFSIZE ];

	// magic number must be "P7 332"
	iodev->readLine( str, BUFSIZE );
	if (strncmp(str,"P7 332",6)) return;

	// next line #XVVERSION
	iodev->readLine( str, BUFSIZE );
	if (strncmp(str, "#XVVERSION", 10)) 
		return;

	// now it gets interesting, #BUILTIN means we are out.
	// if IMGINFO comes, we are happy!
	iodev->readLine( str, BUFSIZE );
	if (strncmp(str, "#IMGINFO:", 9))
		return;

	// after this an #END_OF_COMMENTS signals everything to be ok!
	iodev->readLine( str, BUFSIZE );
	if (strncmp(str, "#END_OF", 7))
		return;

	// now a last line with width, height, maxval which is 
	// supposed to be 255
	iodev->readLine( str, BUFSIZE );
	sscanf(str, "%d %d %d", &x, &y, &maxval);

	if (maxval != 255) return;

	// now follows a binary block of x*y bytes. 
	int blocksize = x*y;
	char *block = new char[ blocksize ];

	if (iodev->readBlock(block, blocksize) != blocksize ) 
	{
		return;
	}

	// Create the image
	QImage image( x, y, 8, maxval + 1, QImage::BigEndian );

	// how do the color handling? they are absolute 24bpp
	// or at least can be calculated as such.
	int r,g,b;

	for ( int j = 0; j < 256; j++ )
	{
// OLE; OLIVER EIDEN
//      new look-up table to avaid 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

// 	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 multiplikations/divisions replaced by indexing
		r =  rg_255_7[((j >> 5) & 0x07)];
		g =  rg_255_7[((j >> 2) & 0x07)];
		b =  b_255_3[((j >> 0) & 0x03)];
// OLE; OLIVER EIDEN
		image.setColor( j, qRgb( r, g, b ) );
	}

	for ( int py = 0; py < y; py++ )
	{
		uchar *data = image.scanLine( py );	
		memcpy( data, block + py * x, x );
	}

	_imageio->setImage( image );
	_imageio->setStatus( 0 );

	delete [] block;
	return;
}

void kimgio_xv_write( QImageIO *imageio )
{
	QIODevice& f = *( imageio->ioDevice() );

	// Removed "f.open(...)" and "f.close()" (tanghus)

	const QImage& image = imageio->image();
	int w = image.width(), h = image.height();

	char str[ 1024 ];

	// magic number must be "P7 332"
	f.writeBlock( "P7 332\n", 7 );

	// next line #XVVERSION
	f.writeBlock( "#XVVERSION:\n", 12 );

	// now it gets interesting, #BUILTIN means we are out.
	// if IMGINFO comes, we are happy!
	f.writeBlock( "#IMGINFO:\n", 10 );

	// after this an #END_OF_COMMENTS signals everything to be ok!
	f.writeBlock( "#END_OF_COMMENTS:\n", 18 );

	// now a last line with width, height, maxval which is supposed to be 255
	sprintf( str, "%i %i 255\n", w, h );
	f.writeBlock( str, strlen( str ) );


	if ( image.depth() == 1 )
	{
		image.convertDepth( 8 );
	}

	uchar buffer[ 128 ];


	for ( int py = 0; py < h; py++ )
	{
		uchar *data = image.scanLine( py );
		for ( int px = 0; px < w; px++ )
		{
			int r, g, b;
			if ( image.depth() == 32 )
			{
				QRgb *data32 = (QRgb*) data;
				r = qRed( *data32 ) >> 5;
				g = qGreen( *data32 ) >> 5;		
				b = qBlue( *data32 ) >> 6;
				data += sizeof( QRgb );
			}
			else 
			{
				QRgb color = image.color( *data );
				r = qRed( color ) >> 5;
				g = qGreen( color ) >> 5;		
				b = qBlue( color ) >> 6;
				data++;
			}
			buffer[ px ] = ( r << 5 ) | ( g << 2 ) | b;
		}
		f.writeBlock( (const char*)buffer, w );
	}

	imageio->setStatus( 0 );
}


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic