xview.cpp
00001 // Oliver Eiden <o.eiden@pop.ruhr.de> 00002 // 23.3.99 00003 // changed the mapping from 3-3-2 decoded pixels to 8-8-8 decoded true-color pixels 00004 // now it uses the same mapping as xv, this leads to better visual results 00005 // Patch merged in HEAD by Chris Spiegel <matrix@xirtam.org> 00006 // This library is distributed under the conditions of the GNU LGPL. 00007 00008 #include <stdio.h> 00009 #include <string.h> 00010 #include <stdlib.h> 00011 #include <tqimage.h> 00012 00013 #include <kdelibs_export.h> 00014 00015 #include "xview.h" 00016 00017 #define BUFSIZE 1024 00018 00019 static const int b_255_3[]= {0,85,170,255}, // index*255/3 00020 rg_255_7[]={0,36,72,109,145,182,218,255}; // index *255/7 00021 00022 KDE_EXPORT void kimgio_xv_read( TQImageIO *_imageio ) 00023 { 00024 int x=-1; 00025 int y=-1; 00026 int maxval=-1; 00027 TQIODevice *iodev = _imageio->ioDevice(); 00028 00029 char str[ BUFSIZE ]; 00030 00031 // magic number must be "P7 332" 00032 iodev->readLine( str, BUFSIZE ); 00033 if (strncmp(str,"P7 332",6)) return; 00034 00035 // next line #XVVERSION 00036 iodev->readLine( str, BUFSIZE ); 00037 if (strncmp(str, "#XVVERSION", 10)) 00038 return; 00039 00040 // now it gets interesting, #BUILTIN means we are out. 00041 // if IMGINFO comes, we are happy! 00042 iodev->readLine( str, BUFSIZE ); 00043 if (strncmp(str, "#IMGINFO:", 9)) 00044 return; 00045 00046 // after this an #END_OF_COMMENTS signals everything to be ok! 00047 iodev->readLine( str, BUFSIZE ); 00048 if (strncmp(str, "#END_OF", 7)) 00049 return; 00050 00051 // now a last line with width, height, maxval which is 00052 // supposed to be 255 00053 iodev->readLine( str, BUFSIZE ); 00054 sscanf(str, "%d %d %d", &x, &y, &maxval); 00055 00056 if (maxval != 255) return; 00057 int blocksize = x*y; 00058 if(x < 0 || y < 0 || blocksize < x || blocksize < y) 00059 return; 00060 00061 // now follows a binary block of x*y bytes. 00062 char *block = (char*) malloc(blocksize); 00063 if(!block) 00064 return; 00065 00066 if (iodev->readBlock(block, blocksize) != blocksize ) 00067 { 00068 return; 00069 } 00070 00071 // Create the image 00072 TQImage image( x, y, 8, maxval + 1, TQImage::BigEndian ); 00073 if( image.isNull()) { 00074 free(block); 00075 return; 00076 } 00077 00078 // how do the color handling? they are absolute 24bpp 00079 // or at least can be calculated as such. 00080 int r,g,b; 00081 00082 for ( int j = 0; j < 256; j++ ) 00083 { 00084 r = rg_255_7[((j >> 5) & 0x07)]; 00085 g = rg_255_7[((j >> 2) & 0x07)]; 00086 b = b_255_3[((j >> 0) & 0x03)]; 00087 image.setColor( j, tqRgb( r, g, b ) ); 00088 } 00089 00090 for ( int py = 0; py < y; py++ ) 00091 { 00092 uchar *data = image.scanLine( py ); 00093 memcpy( data, block + py * x, x ); 00094 } 00095 00096 _imageio->setImage( image ); 00097 _imageio->setStatus( 0 ); 00098 00099 free(block); 00100 return; 00101 } 00102 00103 KDE_EXPORT void kimgio_xv_write( TQImageIO *imageio ) 00104 { 00105 TQIODevice& f = *( imageio->ioDevice() ); 00106 00107 // Removed "f.open(...)" and "f.close()" (tanghus) 00108 00109 const TQImage& image = imageio->image(); 00110 int w = image.width(), h = image.height(); 00111 00112 char str[ 1024 ]; 00113 00114 // magic number must be "P7 332" 00115 f.writeBlock( "P7 332\n", 7 ); 00116 00117 // next line #XVVERSION 00118 f.writeBlock( "#XVVERSION:\n", 12 ); 00119 00120 // now it gets interesting, #BUILTIN means we are out. 00121 // if IMGINFO comes, we are happy! 00122 f.writeBlock( "#IMGINFO:\n", 10 ); 00123 00124 // after this an #END_OF_COMMENTS signals everything to be ok! 00125 f.writeBlock( "#END_OF_COMMENTS:\n", 18 ); 00126 00127 // now a last line with width, height, maxval which is supposed to be 255 00128 sprintf( str, "%i %i 255\n", w, h ); 00129 f.writeBlock( str, strlen( str ) ); 00130 00131 00132 if ( image.depth() == 1 ) 00133 { 00134 image.convertDepth( 8 ); 00135 } 00136 00137 uchar* buffer = new uchar[ w ]; 00138 00139 for ( int py = 0; py < h; py++ ) 00140 { 00141 uchar *data = const_cast<TQImage&>(image).scanLine( py ); 00142 for ( int px = 0; px < w; px++ ) 00143 { 00144 int r, g, b; 00145 if ( image.depth() == 32 ) 00146 { 00147 QRgb *data32 = (QRgb*) data; 00148 r = tqRed( *data32 ) >> 5; 00149 g = tqGreen( *data32 ) >> 5; 00150 b = tqBlue( *data32 ) >> 6; 00151 data += sizeof( QRgb ); 00152 } 00153 else 00154 { 00155 QRgb color = image.color( *data ); 00156 r = tqRed( color ) >> 5; 00157 g = tqGreen( color ) >> 5; 00158 b = tqBlue( color ) >> 6; 00159 data++; 00160 } 00161 buffer[ px ] = ( r << 5 ) | ( g << 2 ) | b; 00162 } 00163 f.writeBlock( (const char*)buffer, w ); 00164 } 00165 delete[] buffer; 00166 00167 imageio->setStatus( 0 ); 00168 } 00169