• 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
35 static 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 
160 KPixmap::~KPixmap()
161 {
162 }
163 
164 bool 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 
178 bool 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 
201 bool 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 
223 bool 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 
289 static TQColor* kpixmap_iconPalette = 0;
290 
291 bool 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 
386 KPixmap::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.1
This website is maintained by Timothy Pearson.