summaryrefslogtreecommitdiffstats
path: root/kimgio/xview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kimgio/xview.cpp')
-rw-r--r--kimgio/xview.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/kimgio/xview.cpp b/kimgio/xview.cpp
new file mode 100644
index 000000000..d61a60fde
--- /dev/null
+++ b/kimgio/xview.cpp
@@ -0,0 +1,169 @@
+// Oliver Eiden <[email protected]>
+// 23.3.99
+// changed the mapping from 3-3-2 decoded pixels to 8-8-8 decoded true-color pixels
+// now it uses the same mapping as xv, this leads to better visual results
+// Patch merged in HEAD by Chris Spiegel <[email protected]>
+// This library is distributed under the conditions of the GNU LGPL.
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <qimage.h>
+
+#include <kdelibs_export.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
+
+KDE_EXPORT 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;
+ int blocksize = x*y;
+ if(x < 0 || y < 0 || blocksize < x || blocksize < y)
+ return;
+
+ // now follows a binary block of x*y bytes.
+ char *block = (char*) malloc(blocksize);
+ if(!block)
+ return;
+
+ if (iodev->readBlock(block, blocksize) != blocksize )
+ {
+ return;
+ }
+
+ // 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.
+ int r,g,b;
+
+ for ( int j = 0; j < 256; j++ )
+ {
+ 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 ) );
+ }
+
+ for ( int py = 0; py < y; py++ )
+ {
+ uchar *data = image.scanLine( py );
+ memcpy( data, block + py * x, x );
+ }
+
+ _imageio->setImage( image );
+ _imageio->setStatus( 0 );
+
+ free(block);
+ return;
+}
+
+KDE_EXPORT 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 = new uchar[ w ];
+
+ 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 );
+ }
+ delete[] buffer;
+
+ imageio->setStatus( 0 );
+}
+