00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include <qpixmap.h>
00025
#include <qpainter.h>
00026
#include <qimage.h>
00027
#include <qbitmap.h>
00028
#include <qcolor.h>
00029
00030
#include <stdlib.h>
00031
#include "kpixmap.h"
00032
00033
00034
00035
static bool kdither_32_to_8(
const QImage *src,
QImage *dst )
00036 {
00037
00038 uchar *b;
00039
int y;
00040
00041
if ( !dst->
create(src->
width(), src->
height(), 8, 256) ) {
00042 qWarning(
"KPixmap: destination image not valid\n");
00043
return false;
00044 }
00045
00046
int ncols = 256;
00047
00048
static uint bm[16][16];
00049
static int init=0;
00050
if (!init) {
00051
00052
00053 init = 1;
00054
int n, i, j;
00055
00056 bm[0][0]=0;
00057
00058
for (n=1; n<16; n*=2)
00059
for (i=0; i<n; i++)
00060
for (j=0; j<n; j++) {
00061 bm[i][j]*=4;
00062 bm[i+n][j]=bm[i][j]+2;
00063 bm[i][j+n]=bm[i][j]+3;
00064 bm[i+n][j+n]=bm[i][j]+1;
00065 }
00066
00067
for (i=0; i<16; i++)
00068
for (j=0; j<16; j++)
00069 bm[i][j]<<=8;
00070 }
00071
00072 dst->
setNumColors( ncols );
00073
00074
#define MAX_R 2
00075
#define MAX_G 2
00076
#define MAX_B 2
00077
#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
00078
00079
int rc, gc, bc;
00080
00081
for ( rc=0; rc<=MAX_R; rc++ )
00082
for ( gc=0; gc<=MAX_G; gc++ )
00083
for ( bc=0; bc<=MAX_B; bc++ ) {
00084 dst->
setColor( INDEXOF(rc,gc,bc),
00085 qRgb( rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B ) );
00086 }
00087
00088
int sw = src->
width();
00089
int* line1[3];
00090
int* line2[3];
00091
int* pv[3];
00092
00093 line1[0] =
new int[src->
width()];
00094 line2[0] =
new int[src->
width()];
00095 line1[1] =
new int[src->
width()];
00096 line2[1] =
new int[src->
width()];
00097 line1[2] =
new int[src->
width()];
00098 line2[2] =
new int[src->
width()];
00099 pv[0] =
new int[sw];
00100 pv[1] =
new int[sw];
00101 pv[2] =
new int[sw];
00102
00103
for ( y=0; y < src->
height(); y++ ) {
00104
00105 b = dst->
scanLine(y);
00106
int endian = (
QImage::systemBitOrder() == QImage::BigEndian);
00107
int x;
00108 uchar* q = src->
scanLine(y);
00109 uchar* q2 = src->
scanLine(y+1 < src->
height() ? y + 1 : 0);
00110
00111
for (
int chan = 0; chan < 3; chan++) {
00112 b = dst->
scanLine(y);
00113
int *l1 = (y&1) ? line2[chan] : line1[chan];
00114
int *l2 = (y&1) ? line1[chan] : line2[chan];
00115
if ( y == 0 ) {
00116
for (
int i=0; i<sw; i++)
00117 l1[i] = q[i*4+chan+endian];
00118 }
00119
if ( y+1 < src->
height() ) {
00120
for (
int i=0; i<sw; i++)
00121 l2[i] = q2[i*4+chan+endian];
00122 }
00123
00124
00125
if ( y&1 ) {
00126
for (x=0; x<sw; x++) {
00127
int pix = QMAX(QMIN(2, (l1[x] * 2 + 128)/ 255), 0);
00128
int err = l1[x] - pix * 255 / 2;
00129 pv[chan][x] = pix;
00130
00131
00132
if ( x+1<sw ) {
00133 l1[x+1] += (err*7)>>4;
00134 l2[x+1] += err>>4;
00135 }
00136 l2[x]+=(err*5)>>4;
00137
if (x>1)
00138 l2[x-1]+=(err*3)>>4;
00139 }
00140 }
else {
00141
for (x=sw; x-->0; ) {
00142
int pix = QMAX(QMIN(2, (l1[x] * 2 + 128)/ 255), 0);
00143
int err = l1[x] - pix * 255 / 2;
00144 pv[chan][x] = pix;
00145
00146
00147
if ( x > 0 ) {
00148 l1[x-1] += (err*7)>>4;
00149 l2[x-1] += err>>4;
00150 }
00151 l2[x]+=(err*5)>>4;
00152
if (x+1 < sw)
00153 l2[x+1]+=(err*3)>>4;
00154 }
00155 }
00156 }
00157
00158
if (!endian) {
00159
for (x=0; x<sw; x++)
00160 *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
00161 }
else {
00162
for (x=0; x<sw; x++)
00163 *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
00164 }
00165
00166 }
00167
00168
delete [] line1[0];
00169
delete [] line2[0];
00170
delete [] line1[1];
00171
delete [] line2[1];
00172
delete [] line1[2];
00173
delete [] line2[2];
00174
delete [] pv[0];
00175
delete [] pv[1];
00176
delete [] pv[2];
00177
00178
#undef MAX_R
00179
#undef MAX_G
00180
#undef MAX_B
00181
#undef INDEXOF
00182
00183
return true;
00184 }
00185
00186 KPixmap::~KPixmap()
00187 {
00188 }
00189
00190 bool KPixmap::load(
const QString& fileName,
const char *format,
00191
int conversion_flags )
00192 {
00193
QImageIO io( fileName, format );
00194
00195
bool result = io.
read();
00196
00197
if ( result ) {
00198
detach();
00199 result =
convertFromImage( io.
image(), conversion_flags );
00200 }
00201
return result;
00202 }
00203
00204 bool KPixmap::load(
const QString& fileName,
const char *format,
00205 ColorMode mode )
00206 {
00207
int conversion_flags = 0;
00208
switch (mode) {
00209
case Color:
00210 conversion_flags |= ColorOnly;
00211
break;
00212
case Mono:
00213 conversion_flags |= MonoOnly;
00214
break;
00215
case LowColor:
00216 conversion_flags |= LowOnly;
00217
break;
00218
case WebColor:
00219 conversion_flags |= WebOnly;
00220
break;
00221
default:
00222
break;
00223 }
00224
return load( fileName, format, conversion_flags );
00225 }
00226
00227 bool KPixmap::convertFromImage(
const QImage &img, ColorMode mode )
00228 {
00229
int conversion_flags = 0;
00230
switch (mode) {
00231
case Color:
00232 conversion_flags |= ColorOnly;
00233
break;
00234
case Mono:
00235 conversion_flags |= MonoOnly;
00236
break;
00237
case LowColor:
00238 conversion_flags |= LowOnly;
00239
break;
00240
case WebColor:
00241 conversion_flags |= WebOnly;
00242
break;
00243
default:
00244
break;
00245 }
00246
return convertFromImage( img, conversion_flags );
00247 }
00248
00249 bool KPixmap::convertFromImage(
const QImage &img,
int conversion_flags )
00250 {
00251
if ( img.
isNull() ) {
00252
#if defined(CHECK_NULL)
00253
qWarning(
"KPixmap::convertFromImage: Cannot convert a null image" );
00254
#endif
00255
return false;
00256 }
00257
detach();
00258
00259
int dd =
defaultDepth();
00260
00261
00262
if ( ( conversion_flags & KColorMode_Mask ) != LowOnly &&
00263 ( conversion_flags & KColorMode_Mask ) != WebOnly ) {
00264
return QPixmap::convertFromImage ( img, conversion_flags );
00265 }
00266
00267
00268
00269
if ( dd > 8 ) {
00270
if ( ( conversion_flags & KColorMode_Mask ) == LowOnly ||
00271 ( conversion_flags & KColorMode_Mask ) == WebOnly )
00272 conversion_flags = (conversion_flags & ~KColorMode_Mask) |
Auto;
00273
return QPixmap::convertFromImage ( img, conversion_flags );
00274 }
00275
00276
if ( ( conversion_flags & KColorMode_Mask ) == LowOnly ) {
00277
00278
00279
00280
00281
00282
00283
if( img.
numColors() > 0 && img.
numColors() <=40 ) {
00284
if (
checkColorTable( img ) )
00285
return QPixmap::convertFromImage( img, QPixmap::Auto );
00286 }
00287
00288
QBitmap mask;
00289
bool isMask =
false;
00290
00291
QImage image = img.
convertDepth(32);
00292
QImage tImage( image.
width(), image.
height(), 8, 256 );
00293
00294
if( img.
hasAlphaBuffer() ) {
00295 image.
setAlphaBuffer(
true );
00296 tImage.
setAlphaBuffer(
true );
00297 isMask = mask.convertFromImage( img.
createAlphaMask() );
00298 }
00299
00300 kdither_32_to_8( &image, &tImage );
00301
00302
if( QPixmap::convertFromImage( tImage ) ) {
00303
if ( isMask ) QPixmap::setMask( mask );
00304
return true;
00305 }
else
00306
return false;
00307 }
else {
00308
QImage image = img.
convertDepth( 32 );
00309 image.
setAlphaBuffer( img.
hasAlphaBuffer() );
00310 conversion_flags = (conversion_flags & ~ColorMode_Mask) |
Auto;
00311
return QPixmap::convertFromImage ( image, conversion_flags );
00312 }
00313 }
00314
00315
static QColor* kpixmap_iconPalette = 0;
00316
00317 bool KPixmap::checkColorTable(
const QImage &image )
00318 {
00319
int i = 0;
00320
00321
if (kpixmap_iconPalette == 0) {
00322 kpixmap_iconPalette =
new QColor[40];
00323
00324
00325 kpixmap_iconPalette[i++] = red;
00326 kpixmap_iconPalette[i++] = green;
00327 kpixmap_iconPalette[i++] = blue;
00328 kpixmap_iconPalette[i++] = cyan;
00329 kpixmap_iconPalette[i++] = magenta;
00330 kpixmap_iconPalette[i++] = yellow;
00331 kpixmap_iconPalette[i++] = darkRed;
00332 kpixmap_iconPalette[i++] = darkGreen;
00333 kpixmap_iconPalette[i++] = darkBlue;
00334 kpixmap_iconPalette[i++] = darkCyan;
00335 kpixmap_iconPalette[i++] = darkMagenta;
00336 kpixmap_iconPalette[i++] = darkYellow;
00337 kpixmap_iconPalette[i++] = white;
00338 kpixmap_iconPalette[i++] = lightGray;
00339 kpixmap_iconPalette[i++] = gray;
00340 kpixmap_iconPalette[i++] = darkGray;
00341 kpixmap_iconPalette[i++] = black;
00342
00343
00344 kpixmap_iconPalette[i++] = QColor( 255, 192, 192 );
00345 kpixmap_iconPalette[i++] = QColor( 192, 255, 192 );
00346 kpixmap_iconPalette[i++] = QColor( 192, 192, 255 );
00347 kpixmap_iconPalette[i++] = QColor( 255, 255, 192 );
00348 kpixmap_iconPalette[i++] = QColor( 255, 192, 255 );
00349 kpixmap_iconPalette[i++] = QColor( 192, 255, 255 );
00350
00351
00352 kpixmap_iconPalette[i++] = QColor( 64, 0, 0 );
00353 kpixmap_iconPalette[i++] = QColor( 192, 0, 0 );
00354
00355
00356 kpixmap_iconPalette[i++] = QColor( 255, 128, 0 );
00357 kpixmap_iconPalette[i++] = QColor( 192, 88, 0 );
00358 kpixmap_iconPalette[i++] = QColor( 255, 168, 88 );
00359 kpixmap_iconPalette[i++] = QColor( 255, 220, 168 );
00360
00361
00362 kpixmap_iconPalette[i++] = QColor( 0, 0, 192 );
00363
00364
00365 kpixmap_iconPalette[i++] = QColor( 0, 64, 64 );
00366 kpixmap_iconPalette[i++] = QColor( 0, 192, 192 );
00367
00368
00369 kpixmap_iconPalette[i++] = QColor( 64, 64, 0 );
00370 kpixmap_iconPalette[i++] = QColor( 192, 192, 0 );
00371
00372
00373 kpixmap_iconPalette[i++] = QColor( 0, 64, 0 );
00374 kpixmap_iconPalette[i++] = QColor( 0, 192, 0 );
00375
00376
00377 kpixmap_iconPalette[i++] = QColor( 192, 0, 192 );
00378
00379
00380 kpixmap_iconPalette[i++] = QColor( 88, 88, 88 );
00381 kpixmap_iconPalette[i++] = QColor( 48, 48, 48 );
00382 kpixmap_iconPalette[i++] = QColor( 220, 220, 220 );
00383
00384 }
00385
00386 QRgb* ctable = image.
colorTable();
00387
00388
int ncols = image.
numColors();
00389
int j;
00390
00391
00392
int failures = 0;
00393
00394
for ( i=0; i<ncols; i++ ) {
00395
for ( j=0; j<40; j++ ) {
00396
if ( kpixmap_iconPalette[j].
red() == qRed( ctable[i] ) &&
00397 kpixmap_iconPalette[j].
green() == qGreen( ctable[i] ) &&
00398 kpixmap_iconPalette[j].
blue() == qBlue( ctable[i] ) ) {
00399
break;
00400 }
00401 }
00402
00403
if ( j == 40 ) {
00404 failures ++;
00405 }
00406 }
00407
00408
return ( failures <= 1 );
00409
00410 }
00411
00412 KPixmap::KPixmap(
const QPixmap& p)
00413 :
QPixmap(p)
00414 {
00415 }