• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdefx
 

tdefx

  • tdefx
kpixmap.cpp
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1998 Mark Donohoe <donohoe@kde.org>
4 * Stephan Kulow <coolo@kde.org>
5 *
6 * $Id$
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include <tqpixmap.h>
25#include <tqpainter.h>
26#include <tqimage.h>
27#include <tqbitmap.h>
28#include <tqcolor.h>
29
30#include <stdlib.h>
31#include "kpixmap.h"
32
33// Fast diffuse dither to 3x3x3 color cube
34// Based on Qt's image conversion functions
35static bool kdither_32_to_8( const TQImage *src, TQImage *dst )
36{
37 // TQRgb *p;
38 uchar *b;
39 int y;
40
41 if ( !dst->create(src->width(), src->height(), 8, 256) ) {
42 tqWarning("KPixmap: destination image not valid\n");
43 return false;
44 }
45
46 dst->setNumColors( 256 );
47
48#define MAX_R 2
49#define MAX_G 2
50#define MAX_B 2
51#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
52
53 int rc, gc, bc;
54
55 for ( rc=0; rc<=MAX_R; rc++ ) // build 2x2x2 color cube
56 for ( gc=0; gc<=MAX_G; gc++ )
57 for ( bc=0; bc<=MAX_B; bc++ ) {
58 dst->setColor( INDEXOF(rc,gc,bc),
59 tqRgb( rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B ) );
60 }
61
62 int sw = src->width();
63 int* line1[3];
64 int* line2[3];
65 int* pv[3];
66
67 line1[0] = new int[src->width()];
68 line2[0] = new int[src->width()];
69 line1[1] = new int[src->width()];
70 line2[1] = new int[src->width()];
71 line1[2] = new int[src->width()];
72 line2[2] = new int[src->width()];
73 pv[0] = new int[sw];
74 pv[1] = new int[sw];
75 pv[2] = new int[sw];
76
77 for ( y=0; y < src->height(); y++ ) {
78 // p = (TQRgb *)src->scanLine(y);
79 b = dst->scanLine(y);
80 int endian = (TQImage::systemBitOrder() == TQImage::BigEndian);
81 int x;
82 uchar* q = const_cast<TQImage*>(src)->scanLine(y);
83 uchar* q2 = const_cast<TQImage*>(src)->scanLine(y+1 < src->height() ? y + 1 : 0);
84
85 for (int chan = 0; chan < 3; chan++) {
86 b = dst->scanLine(y);
87 int *l1 = (y&1) ? line2[chan] : line1[chan];
88 int *l2 = (y&1) ? line1[chan] : line2[chan];
89 if ( y == 0 ) {
90 for (int i=0; i<sw; i++)
91 l1[i] = q[i*4+chan+endian];
92 }
93 if ( y+1 < src->height() ) {
94 for (int i=0; i<sw; i++)
95 l2[i] = q2[i*4+chan+endian];
96 }
97
98 // Bi-directional error diffusion
99 if ( y&1 ) {
100 for (x=0; x<sw; x++) {
101 int pix = TQMAX(TQMIN(2, (l1[x] * 2 + 128)/ 255), 0);
102 int err = l1[x] - pix * 255 / 2;
103 pv[chan][x] = pix;
104
105 // Spread the error around...
106 if ( x+1<sw ) {
107 l1[x+1] += (err*7)>>4;
108 l2[x+1] += err>>4;
109 }
110 l2[x]+=(err*5)>>4;
111 if (x>1)
112 l2[x-1]+=(err*3)>>4;
113 }
114 } else {
115 for (x=sw; x-->0; ) {
116 int pix = TQMAX(TQMIN(2, (l1[x] * 2 + 128)/ 255), 0);
117 int err = l1[x] - pix * 255 / 2;
118 pv[chan][x] = pix;
119
120 // Spread the error around...
121 if ( x > 0 ) {
122 l1[x-1] += (err*7)>>4;
123 l2[x-1] += err>>4;
124 }
125 l2[x]+=(err*5)>>4;
126 if (x+1 < sw)
127 l2[x+1]+=(err*3)>>4;
128 }
129 }
130 }
131
132 if (!endian) {
133 for (x=0; x<sw; x++)
134 *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
135 } else {
136 for (x=0; x<sw; x++)
137 *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
138 }
139
140 }
141
142 delete [] line1[0];
143 delete [] line2[0];
144 delete [] line1[1];
145 delete [] line2[1];
146 delete [] line1[2];
147 delete [] line2[2];
148 delete [] pv[0];
149 delete [] pv[1];
150 delete [] pv[2];
151
152#undef MAX_R
153#undef MAX_G
154#undef MAX_B
155#undef INDEXOF
156
157 return true;
158}
159
160KPixmap::~KPixmap()
161{
162}
163
164bool KPixmap::load( const TQString& fileName, const char *format,
165 int conversion_flags )
166{
167 TQImageIO io( fileName, format );
168
169 bool result = io.read();
170
171 if ( result ) {
172 detach();
173 result = convertFromImage( io.image(), conversion_flags );
174 }
175 return result;
176}
177
178bool KPixmap::load( const TQString& fileName, const char *format,
179 ColorMode mode )
180{
181 int conversion_flags = 0;
182 switch (mode) {
183 case Color:
184 conversion_flags |= ColorOnly;
185 break;
186 case Mono:
187 conversion_flags |= MonoOnly;
188 break;
189 case LowColor:
190 conversion_flags |= LowOnly;
191 break;
192 case WebColor:
193 conversion_flags |= WebOnly;
194 break;
195 default:
196 break;// Nothing.
197 }
198 return load( fileName, format, conversion_flags );
199}
200
201bool KPixmap::convertFromImage( const TQImage &img, ColorMode mode )
202{
203 int conversion_flags = 0;
204 switch (mode) {
205 case Color:
206 conversion_flags |= ColorOnly;
207 break;
208 case Mono:
209 conversion_flags |= MonoOnly;
210 break;
211 case LowColor:
212 conversion_flags |= LowOnly;
213 break;
214 case WebColor:
215 conversion_flags |= WebOnly;
216 break;
217 default:
218 break; // Nothing.
219 }
220 return convertFromImage( img, conversion_flags );
221}
222
223bool KPixmap::convertFromImage( const TQImage &img, int conversion_flags )
224{
225 if ( img.isNull() ) {
226#if defined(CHECK_NULL)
227 tqWarning( "KPixmap::convertFromImage: Cannot convert a null image" );
228#endif
229 return false;
230 }
231 detach(); // detach other references
232
233 int dd = defaultDepth();
234
235 // If color mode not one of KPixmaps extra modes nothing to do
236 if ( ( conversion_flags & KColorMode_Mask ) != LowOnly &&
237 ( conversion_flags & KColorMode_Mask ) != WebOnly ) {
238 return TQPixmap::convertFromImage ( img, conversion_flags );
239 }
240
241 // If the default pixmap depth is not 8bpp, KPixmap color modes have no
242 // effect. Ignore them and use AutoColor instead.
243 if ( dd > 8 ) {
244 if ( ( conversion_flags & KColorMode_Mask ) == LowOnly ||
245 ( conversion_flags & KColorMode_Mask ) == WebOnly )
246 conversion_flags = (conversion_flags & ~KColorMode_Mask) | Auto;
247 return TQPixmap::convertFromImage ( img, conversion_flags );
248 }
249
250 if ( ( conversion_flags & KColorMode_Mask ) == LowOnly ) {
251 // Here we skimp a little on the possible conversion modes
252 // Don't offer ordered or threshold dither of RGB channels or
253 // diffuse or ordered dither of alpha channel. It hardly seems
254 // worth the effort for this specialized mode.
255
256 // If image uses icon palette don't dither it.
257 if( img.numColors() > 0 && img.numColors() <=40 ) {
258 if ( checkColorTable( img ) )
259 return TQPixmap::convertFromImage( img, TQPixmap::Auto );
260 }
261
262 TQBitmap mask;
263 bool isMask = false;
264
265 TQImage image = img.convertDepth(32);
266 TQImage tImage( image.width(), image.height(), 8, 256 );
267
268 if( img.hasAlphaBuffer() ) {
269 image.setAlphaBuffer( true );
270 tImage.setAlphaBuffer( true );
271 isMask = mask.convertFromImage( img.createAlphaMask() );
272 }
273
274 kdither_32_to_8( &image, &tImage );
275
276 if( TQPixmap::convertFromImage( tImage ) ) {
277 if ( isMask ) TQPixmap::setMask( mask );
278 return true;
279 } else
280 return false;
281 } else {
282 TQImage image = img.convertDepth( 32 );
283 image.setAlphaBuffer( img.hasAlphaBuffer() );
284 conversion_flags = (conversion_flags & ~ColorMode_Mask) | Auto;
285 return TQPixmap::convertFromImage ( image, conversion_flags );
286 }
287}
288
289static TQColor* kpixmap_iconPalette = 0;
290
291bool KPixmap::checkColorTable( const TQImage &image )
292{
293 int i = 0;
294
295 if (kpixmap_iconPalette == 0) {
296 kpixmap_iconPalette = new TQColor[40];
297
298 // Standard palette
299 kpixmap_iconPalette[i++] = red;
300 kpixmap_iconPalette[i++] = green;
301 kpixmap_iconPalette[i++] = blue;
302 kpixmap_iconPalette[i++] = cyan;
303 kpixmap_iconPalette[i++] = magenta;
304 kpixmap_iconPalette[i++] = yellow;
305 kpixmap_iconPalette[i++] = darkRed;
306 kpixmap_iconPalette[i++] = darkGreen;
307 kpixmap_iconPalette[i++] = darkBlue;
308 kpixmap_iconPalette[i++] = darkCyan;
309 kpixmap_iconPalette[i++] = darkMagenta;
310 kpixmap_iconPalette[i++] = darkYellow;
311 kpixmap_iconPalette[i++] = white;
312 kpixmap_iconPalette[i++] = lightGray;
313 kpixmap_iconPalette[i++] = gray;
314 kpixmap_iconPalette[i++] = darkGray;
315 kpixmap_iconPalette[i++] = black;
316
317 // Pastels
318 kpixmap_iconPalette[i++] = TQColor( 255, 192, 192 );
319 kpixmap_iconPalette[i++] = TQColor( 192, 255, 192 );
320 kpixmap_iconPalette[i++] = TQColor( 192, 192, 255 );
321 kpixmap_iconPalette[i++] = TQColor( 255, 255, 192 );
322 kpixmap_iconPalette[i++] = TQColor( 255, 192, 255 );
323 kpixmap_iconPalette[i++] = TQColor( 192, 255, 255 );
324
325 // Reds
326 kpixmap_iconPalette[i++] = TQColor( 64, 0, 0 );
327 kpixmap_iconPalette[i++] = TQColor( 192, 0, 0 );
328
329 // Oranges
330 kpixmap_iconPalette[i++] = TQColor( 255, 128, 0 );
331 kpixmap_iconPalette[i++] = TQColor( 192, 88, 0 );
332 kpixmap_iconPalette[i++] = TQColor( 255, 168, 88 );
333 kpixmap_iconPalette[i++] = TQColor( 255, 220, 168 );
334
335 // Blues
336 kpixmap_iconPalette[i++] = TQColor( 0, 0, 192 );
337
338 // Turquoise
339 kpixmap_iconPalette[i++] = TQColor( 0, 64, 64 );
340 kpixmap_iconPalette[i++] = TQColor( 0, 192, 192 );
341
342 // Yellows
343 kpixmap_iconPalette[i++] = TQColor( 64, 64, 0 );
344 kpixmap_iconPalette[i++] = TQColor( 192, 192, 0 );
345
346 // Greens
347 kpixmap_iconPalette[i++] = TQColor( 0, 64, 0 );
348 kpixmap_iconPalette[i++] = TQColor( 0, 192, 0 );
349
350 // Purples
351 kpixmap_iconPalette[i++] = TQColor( 192, 0, 192 );
352
353 // Greys
354 kpixmap_iconPalette[i++] = TQColor( 88, 88, 88 );
355 kpixmap_iconPalette[i++] = TQColor( 48, 48, 48 );
356 kpixmap_iconPalette[i++] = TQColor( 220, 220, 220 );
357
358 }
359
360 TQRgb* ctable = image.colorTable();
361
362 int ncols = image.numColors();
363 int j;
364
365 // Allow one failure which could be transparent background
366 int failures = 0;
367
368 for ( i=0; i<ncols; i++ ) {
369 for ( j=0; j<40; j++ ) {
370 if ( kpixmap_iconPalette[j].red() == tqRed( ctable[i] ) &&
371 kpixmap_iconPalette[j].green() == tqGreen( ctable[i] ) &&
372 kpixmap_iconPalette[j].blue() == tqBlue( ctable[i] ) ) {
373 break;
374 }
375 }
376
377 if ( j == 40 ) {
378 failures ++;
379 }
380 }
381
382 return ( failures <= 1 );
383
384}
385
386KPixmap::KPixmap(const TQPixmap& p)
387 : TQPixmap(p)
388{
389}
KPixmap::KPixmap
KPixmap()
Constructs a null pixmap.
Definition: kpixmap.h:82
KPixmap::convertFromImage
bool convertFromImage(const TQImage &img, int conversion_flags)
Converts an image and sets this pixmap.
Definition: kpixmap.cpp:223
KPixmap::~KPixmap
~KPixmap()
Destructs the pixmap.
Definition: kpixmap.cpp:160
KPixmap::checkColorTable
bool checkColorTable(const TQImage &image)
Returns true if the image posesses a color table that matches the Icon palette or false otherwise.
Definition: kpixmap.cpp:291
KPixmap::ColorMode
ColorMode
This enumeration provides a color pallete specification.
Definition: kpixmap.h:64
KPixmap::LowColor
@ LowColor
3x3x3 color cube (or monochrome)
Definition: kpixmap.h:67
KPixmap::WebColor
@ WebColor
Netscape pallete (or monochrome)
Definition: kpixmap.h:68
KPixmap::Auto
@ Auto
Convert to monochrome if possible.
Definition: kpixmap.h:64
KPixmap::Mono
@ Mono
Monochrome pixmap.
Definition: kpixmap.h:66
KPixmap::Color
@ Color
Native display depth.
Definition: kpixmap.h:65
KPixmap::load
bool load(const TQString &fileName, const char *format, int conversion_flags)
Loads a pixmap from the file fileName.
Definition: kpixmap.cpp:164

tdefx

Skip menu "tdefx"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdefx

Skip menu "tdefx"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdefx by doxygen 1.9.4
This website is maintained by Timothy Pearson.