summaryrefslogtreecommitdiff
path: root/libopie2
authormickeyl <mickeyl>2003-03-30 03:12:23 (UTC)
committer mickeyl <mickeyl>2003-03-30 03:12:23 (UTC)
commit161d9299ad2448092d62a1cff16e64c1b5b3a436 (patch) (unidiff)
tree057fc5da398fc6927c9fd6a6ebafa8256fb87d02 /libopie2
parent8e1504c3e8b8e5af509147f0b33f4e92a7c1c041 (diff)
downloadopie-161d9299ad2448092d62a1cff16e64c1b5b3a436.zip
opie-161d9299ad2448092d62a1cff16e64c1b5b3a436.tar.gz
opie-161d9299ad2448092d62a1cff16e64c1b5b3a436.tar.bz2
remove unnecessary usage of and thus the dependency on libstdc++
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opieui/oimageeffect.cpp76
1 files changed, 25 insertions, 51 deletions
diff --git a/libopie2/opieui/oimageeffect.cpp b/libopie2/opieui/oimageeffect.cpp
index 3c28bbe..2855da6 100644
--- a/libopie2/opieui/oimageeffect.cpp
+++ b/libopie2/opieui/oimageeffect.cpp
@@ -1,197 +1,195 @@
1/* This file is part of the KDE libraries 1/* This file is part of the KDE libraries
2 Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@kde.org> 2 Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@kde.org>
3 (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> 3 (C) 1998, 1999 Christian Tibirna <ctibirna@total.net>
4 (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> 4 (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org>
5 (C) 2000 Josef Weidendorfer <weidendo@in.tum.de> 5 (C) 2000 Josef Weidendorfer <weidendo@in.tum.de>
6 6
7Redistribution and use in source and binary forms, with or without 7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions 8modification, are permitted provided that the following conditions
9are met: 9are met:
10 10
111. Redistributions of source code must retain the above copyright 111. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer. 12 notice, this list of conditions and the following disclaimer.
132. Redistributions in binary form must reproduce the above copyright 132. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the 14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution. 15 documentation and/or other materials provided with the distribution.
16 16
17THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28*/ 28*/
29 29
30// $Id$ 30// $Id$
31 31
32#include <math.h> 32#include <math.h>
33 33
34#include <qimage.h> 34#include <qimage.h>
35#include <stdlib.h> 35#include <stdlib.h>
36#include <iostream> 36#include <iostream>
37 37
38#include "oimageeffect.h" 38#include "oimageeffect.h"
39 39
40#define MaxRGB 255L 40#define MaxRGB 255L
41#define DegreesToRadians(x) ((x)*M_PI/180.0) 41#define DegreesToRadians(x) ((x)*M_PI/180.0)
42 42
43using namespace std; 43using namespace std;
44 44
45inline unsigned int intensityValue(unsigned int color) 45inline unsigned int intensityValue(unsigned int color)
46{ 46{
47 return((unsigned int)((0.299*qRed(color) + 47 return((unsigned int)((0.299*qRed(color) +
48 0.587*qGreen(color) + 48 0.587*qGreen(color) +
49 0.1140000000000001*qBlue(color)))); 49 0.1140000000000001*qBlue(color))));
50} 50}
51 51
52//====================================================================== 52//======================================================================
53// 53//
54// Gradient effects 54// Gradient effects
55// 55//
56//====================================================================== 56//======================================================================
57 57
58QImage OImageEffect::gradient(const QSize &size, const QColor &ca, 58QImage OImageEffect::gradient(const QSize &size, const QColor &ca,
59 const QColor &cb, GradientType eff, int ncols) 59 const QColor &cb, GradientType eff, int ncols)
60{ 60{
61 int rDiff, gDiff, bDiff; 61 int rDiff, gDiff, bDiff;
62 int rca, gca, bca, rcb, gcb, bcb; 62 int rca, gca, bca, rcb, gcb, bcb;
63 63
64 QImage image(size, 32); 64 QImage image(size, 32);
65 65
66 if (size.width() == 0 || size.height() == 0) { 66 if (size.width() == 0 || size.height() == 0) {
67#ifndef NDEBUG 67 qDebug( "WARNING: OImageEffect::gradient: invalid image" );
68 cerr << "WARNING: OImageEffect::gradient: invalid image" << endl;
69#endif
70 return image; 68 return image;
71 } 69 }
72 70
73 register int x, y; 71 register int x, y;
74 72
75 rDiff = (rcb = cb.red()) - (rca = ca.red()); 73 rDiff = (rcb = cb.red()) - (rca = ca.red());
76 gDiff = (gcb = cb.green()) - (gca = ca.green()); 74 gDiff = (gcb = cb.green()) - (gca = ca.green());
77 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 75 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
78 76
79 if( eff == VerticalGradient || eff == HorizontalGradient ){ 77 if( eff == VerticalGradient || eff == HorizontalGradient ){
80 78
81 uint *p; 79 uint *p;
82 uint rgb; 80 uint rgb;
83 81
84 register int rl = rca << 16; 82 register int rl = rca << 16;
85 register int gl = gca << 16; 83 register int gl = gca << 16;
86 register int bl = bca << 16; 84 register int bl = bca << 16;
87 85
88 if( eff == VerticalGradient ) { 86 if( eff == VerticalGradient ) {
89 87
90 int rcdelta = ((1<<16) / size.height()) * rDiff; 88 int rcdelta = ((1<<16) / size.height()) * rDiff;
91 int gcdelta = ((1<<16) / size.height()) * gDiff; 89 int gcdelta = ((1<<16) / size.height()) * gDiff;
92 int bcdelta = ((1<<16) / size.height()) * bDiff; 90 int bcdelta = ((1<<16) / size.height()) * bDiff;
93 91
94 for ( y = 0; y < size.height(); y++ ) { 92 for ( y = 0; y < size.height(); y++ ) {
95 p = (uint *) image.scanLine(y); 93 p = (uint *) image.scanLine(y);
96 94
97 rl += rcdelta; 95 rl += rcdelta;
98 gl += gcdelta; 96 gl += gcdelta;
99 bl += bcdelta; 97 bl += bcdelta;
100 98
101 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); 99 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) );
102 100
103 for( x = 0; x < size.width(); x++ ) { 101 for( x = 0; x < size.width(); x++ ) {
104 *p = rgb; 102 *p = rgb;
105 p++; 103 p++;
106 } 104 }
107 } 105 }
108 106
109 } 107 }
110 else { // must be HorizontalGradient 108 else { // must be HorizontalGradient
111 109
112 unsigned int *o_src = (unsigned int *)image.scanLine(0); 110 unsigned int *o_src = (unsigned int *)image.scanLine(0);
113 unsigned int *src = o_src; 111 unsigned int *src = o_src;
114 112
115 int rcdelta = ((1<<16) / size.width()) * rDiff; 113 int rcdelta = ((1<<16) / size.width()) * rDiff;
116 int gcdelta = ((1<<16) / size.width()) * gDiff; 114 int gcdelta = ((1<<16) / size.width()) * gDiff;
117 int bcdelta = ((1<<16) / size.width()) * bDiff; 115 int bcdelta = ((1<<16) / size.width()) * bDiff;
118 116
119 for( x = 0; x < size.width(); x++) { 117 for( x = 0; x < size.width(); x++) {
120 118
121 rl += rcdelta; 119 rl += rcdelta;
122 gl += gcdelta; 120 gl += gcdelta;
123 bl += bcdelta; 121 bl += bcdelta;
124 122
125 *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16)); 123 *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16));
126 } 124 }
127 125
128 src = o_src; 126 src = o_src;
129 127
130 // Believe it or not, manually copying in a for loop is faster 128 // Believe it or not, manually copying in a for loop is faster
131 // than calling memcpy for each scanline (on the order of ms...). 129 // than calling memcpy for each scanline (on the order of ms...).
132 // I think this is due to the function call overhead (mosfet). 130 // I think this is due to the function call overhead (mosfet).
133 131
134 for (y = 1; y < size.height(); ++y) { 132 for (y = 1; y < size.height(); ++y) {
135 133
136 p = (unsigned int *)image.scanLine(y); 134 p = (unsigned int *)image.scanLine(y);
137 src = o_src; 135 src = o_src;
138 for(x=0; x < size.width(); ++x) 136 for(x=0; x < size.width(); ++x)
139 *p++ = *src++; 137 *p++ = *src++;
140 } 138 }
141 } 139 }
142 } 140 }
143 141
144 else { 142 else {
145 143
146 float rfd, gfd, bfd; 144 float rfd, gfd, bfd;
147 float rd = rca, gd = gca, bd = bca; 145 float rd = rca, gd = gca, bd = bca;
148 146
149 unsigned char *xtable[3]; 147 unsigned char *xtable[3];
150 unsigned char *ytable[3]; 148 unsigned char *ytable[3];
151 149
152 unsigned int w = size.width(), h = size.height(); 150 unsigned int w = size.width(), h = size.height();
153 xtable[0] = new unsigned char[w]; 151 xtable[0] = new unsigned char[w];
154 xtable[1] = new unsigned char[w]; 152 xtable[1] = new unsigned char[w];
155 xtable[2] = new unsigned char[w]; 153 xtable[2] = new unsigned char[w];
156 ytable[0] = new unsigned char[h]; 154 ytable[0] = new unsigned char[h];
157 ytable[1] = new unsigned char[h]; 155 ytable[1] = new unsigned char[h];
158 ytable[2] = new unsigned char[h]; 156 ytable[2] = new unsigned char[h];
159 w*=2, h*=2; 157 w*=2, h*=2;
160 158
161 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) { 159 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) {
162 // Diagonal dgradient code inspired by BlackBox (mosfet) 160 // Diagonal dgradient code inspired by BlackBox (mosfet)
163 // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and 161 // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and
164 // Mike Cole <mike@mydot.com>. 162 // Mike Cole <mike@mydot.com>.
165 163
166 rfd = (float)rDiff/w; 164 rfd = (float)rDiff/w;
167 gfd = (float)gDiff/w; 165 gfd = (float)gDiff/w;
168 bfd = (float)bDiff/w; 166 bfd = (float)bDiff/w;
169 167
170 int dir; 168 int dir;
171 for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) { 169 for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) {
172 dir = eff == DiagonalGradient? x : size.width() - x - 1; 170 dir = eff == DiagonalGradient? x : size.width() - x - 1;
173 xtable[0][dir] = (unsigned char) rd; 171 xtable[0][dir] = (unsigned char) rd;
174 xtable[1][dir] = (unsigned char) gd; 172 xtable[1][dir] = (unsigned char) gd;
175 xtable[2][dir] = (unsigned char) bd; 173 xtable[2][dir] = (unsigned char) bd;
176 } 174 }
177 rfd = (float)rDiff/h; 175 rfd = (float)rDiff/h;
178 gfd = (float)gDiff/h; 176 gfd = (float)gDiff/h;
179 bfd = (float)bDiff/h; 177 bfd = (float)bDiff/h;
180 rd = gd = bd = 0; 178 rd = gd = bd = 0;
181 for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) { 179 for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) {
182 ytable[0][y] = (unsigned char) rd; 180 ytable[0][y] = (unsigned char) rd;
183 ytable[1][y] = (unsigned char) gd; 181 ytable[1][y] = (unsigned char) gd;
184 ytable[2][y] = (unsigned char) bd; 182 ytable[2][y] = (unsigned char) bd;
185 } 183 }
186 184
187 for (y = 0; y < size.height(); y++) { 185 for (y = 0; y < size.height(); y++) {
188 unsigned int *scanline = (unsigned int *)image.scanLine(y); 186 unsigned int *scanline = (unsigned int *)image.scanLine(y);
189 for (x = 0; x < size.width(); x++) { 187 for (x = 0; x < size.width(); x++) {
190 scanline[x] = qRgb(xtable[0][x] + ytable[0][y], 188 scanline[x] = qRgb(xtable[0][x] + ytable[0][y],
191 xtable[1][x] + ytable[1][y], 189 xtable[1][x] + ytable[1][y],
192 xtable[2][x] + ytable[2][y]); 190 xtable[2][x] + ytable[2][y]);
193 } 191 }
194 } 192 }
195 } 193 }
196 194
197 else if (eff == RectangleGradient || 195 else if (eff == RectangleGradient ||
@@ -227,1192 +225,1170 @@ QImage OImageEffect::gradient(const QSize &size, const QColor &ca,
227 bd = (float)bDiff/2; 225 bd = (float)bDiff/2;
228 226
229 for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd) 227 for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd)
230 { 228 {
231 ytable[0][y] = (unsigned char) abs((int)rd); 229 ytable[0][y] = (unsigned char) abs((int)rd);
232 ytable[1][y] = (unsigned char) abs((int)gd); 230 ytable[1][y] = (unsigned char) abs((int)gd);
233 ytable[2][y] = (unsigned char) abs((int)bd); 231 ytable[2][y] = (unsigned char) abs((int)bd);
234 } 232 }
235 unsigned int rgb; 233 unsigned int rgb;
236 int h = (size.height()+1)>>1; 234 int h = (size.height()+1)>>1;
237 for (y = 0; y < h; y++) { 235 for (y = 0; y < h; y++) {
238 unsigned int *sl1 = (unsigned int *)image.scanLine(y); 236 unsigned int *sl1 = (unsigned int *)image.scanLine(y);
239 unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y)); 237 unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y));
240 238
241 int w = (size.width()+1)>>1; 239 int w = (size.width()+1)>>1;
242 int x2 = size.width()-1; 240 int x2 = size.width()-1;
243 241
244 for (x = 0; x < w; x++, x2--) { 242 for (x = 0; x < w; x++, x2--) {
245 rgb = 0; 243 rgb = 0;
246 if (eff == PyramidGradient) { 244 if (eff == PyramidGradient) {
247 rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), 245 rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]),
248 gcb-gSign*(xtable[1][x]+ytable[1][y]), 246 gcb-gSign*(xtable[1][x]+ytable[1][y]),
249 bcb-bSign*(xtable[2][x]+ytable[2][y])); 247 bcb-bSign*(xtable[2][x]+ytable[2][y]));
250 } 248 }
251 if (eff == RectangleGradient) { 249 if (eff == RectangleGradient) {
252 rgb = qRgb(rcb - rSign * 250 rgb = qRgb(rcb - rSign *
253 QMAX(xtable[0][x], ytable[0][y]) * 2, 251 QMAX(xtable[0][x], ytable[0][y]) * 2,
254 gcb - gSign * 252 gcb - gSign *
255 QMAX(xtable[1][x], ytable[1][y]) * 2, 253 QMAX(xtable[1][x], ytable[1][y]) * 2,
256 bcb - bSign * 254 bcb - bSign *
257 QMAX(xtable[2][x], ytable[2][y]) * 2); 255 QMAX(xtable[2][x], ytable[2][y]) * 2);
258 } 256 }
259 if (eff == PipeCrossGradient) { 257 if (eff == PipeCrossGradient) {
260 rgb = qRgb(rcb - rSign * 258 rgb = qRgb(rcb - rSign *
261 QMIN(xtable[0][x], ytable[0][y]) * 2, 259 QMIN(xtable[0][x], ytable[0][y]) * 2,
262 gcb - gSign * 260 gcb - gSign *
263 QMIN(xtable[1][x], ytable[1][y]) * 2, 261 QMIN(xtable[1][x], ytable[1][y]) * 2,
264 bcb - bSign * 262 bcb - bSign *
265 QMIN(xtable[2][x], ytable[2][y]) * 2); 263 QMIN(xtable[2][x], ytable[2][y]) * 2);
266 } 264 }
267 if (eff == EllipticGradient) { 265 if (eff == EllipticGradient) {
268 rgb = qRgb(rcb - rSign * 266 rgb = qRgb(rcb - rSign *
269 (int)sqrt((xtable[0][x]*xtable[0][x] + 267 (int)sqrt((xtable[0][x]*xtable[0][x] +
270 ytable[0][y]*ytable[0][y])*2.0), 268 ytable[0][y]*ytable[0][y])*2.0),
271 gcb - gSign * 269 gcb - gSign *
272 (int)sqrt((xtable[1][x]*xtable[1][x] + 270 (int)sqrt((xtable[1][x]*xtable[1][x] +
273 ytable[1][y]*ytable[1][y])*2.0), 271 ytable[1][y]*ytable[1][y])*2.0),
274 bcb - bSign * 272 bcb - bSign *
275 (int)sqrt((xtable[2][x]*xtable[2][x] + 273 (int)sqrt((xtable[2][x]*xtable[2][x] +
276 ytable[2][y]*ytable[2][y])*2.0)); 274 ytable[2][y]*ytable[2][y])*2.0));
277 } 275 }
278 276
279 sl1[x] = sl2[x] = rgb; 277 sl1[x] = sl2[x] = rgb;
280 sl1[x2] = sl2[x2] = rgb; 278 sl1[x2] = sl2[x2] = rgb;
281 } 279 }
282 } 280 }
283 } 281 }
284 282
285 delete [] xtable[0]; 283 delete [] xtable[0];
286 delete [] xtable[1]; 284 delete [] xtable[1];
287 delete [] xtable[2]; 285 delete [] xtable[2];
288 delete [] ytable[0]; 286 delete [] ytable[0];
289 delete [] ytable[1]; 287 delete [] ytable[1];
290 delete [] ytable[2]; 288 delete [] ytable[2];
291 } 289 }
292 290
293 // dither if necessary 291 // dither if necessary
294 if (ncols && (QPixmap::defaultDepth() < 15 )) { 292 if (ncols && (QPixmap::defaultDepth() < 15 )) {
295 if ( ncols < 2 || ncols > 256 ) 293 if ( ncols < 2 || ncols > 256 )
296 ncols = 3; 294 ncols = 3;
297 QColor *dPal = new QColor[ncols]; 295 QColor *dPal = new QColor[ncols];
298 for (int i=0; i<ncols; i++) { 296 for (int i=0; i<ncols; i++) {
299 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), 297 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ),
300 gca + gDiff * i / ( ncols - 1 ), 298 gca + gDiff * i / ( ncols - 1 ),
301 bca + bDiff * i / ( ncols - 1 ) ); 299 bca + bDiff * i / ( ncols - 1 ) );
302 } 300 }
303 dither(image, dPal, ncols); 301 dither(image, dPal, ncols);
304 delete [] dPal; 302 delete [] dPal;
305 } 303 }
306 304
307 return image; 305 return image;
308} 306}
309 307
310 308
311// ----------------------------------------------------------------------------- 309// -----------------------------------------------------------------------------
312 310
313//CT this was (before Dirk A. Mueller's speedup changes) 311//CT this was (before Dirk A. Mueller's speedup changes)
314// merely the same code as in the above method, but it's supposedly 312// merely the same code as in the above method, but it's supposedly
315// way less performant since it introduces a lot of supplementary tests 313// way less performant since it introduces a lot of supplementary tests
316// and simple math operations for the calculus of the balance. 314// and simple math operations for the calculus of the balance.
317// (surprizingly, it isn't less performant, in the contrary :-) 315// (surprizingly, it isn't less performant, in the contrary :-)
318// Yes, I could have merged them, but then the excellent performance of 316// Yes, I could have merged them, but then the excellent performance of
319// the balanced code would suffer with no other gain than a mere 317// the balanced code would suffer with no other gain than a mere
320// source code and byte code size economy. 318// source code and byte code size economy.
321 319
322QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca, 320QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca,
323 const QColor &cb, GradientType eff, int xfactor, int yfactor, 321 const QColor &cb, GradientType eff, int xfactor, int yfactor,
324 int ncols) 322 int ncols)
325{ 323{
326 int dir; // general parameter used for direction switches 324 int dir; // general parameter used for direction switches
327 325
328 bool _xanti = false , _yanti = false; 326 bool _xanti = false , _yanti = false;
329 327
330 if (xfactor < 0) _xanti = true; // negative on X direction 328 if (xfactor < 0) _xanti = true; // negative on X direction
331 if (yfactor < 0) _yanti = true; // negative on Y direction 329 if (yfactor < 0) _yanti = true; // negative on Y direction
332 330
333 xfactor = abs(xfactor); 331 xfactor = abs(xfactor);
334 yfactor = abs(yfactor); 332 yfactor = abs(yfactor);
335 333
336 if (!xfactor) xfactor = 1; 334 if (!xfactor) xfactor = 1;
337 if (!yfactor) yfactor = 1; 335 if (!yfactor) yfactor = 1;
338 336
339 if (xfactor > 200 ) xfactor = 200; 337 if (xfactor > 200 ) xfactor = 200;
340 if (yfactor > 200 ) yfactor = 200; 338 if (yfactor > 200 ) yfactor = 200;
341 339
342 340
343 // float xbal = xfactor/5000.; 341 // float xbal = xfactor/5000.;
344 // float ybal = yfactor/5000.; 342 // float ybal = yfactor/5000.;
345 float xbal = xfactor/30./size.width(); 343 float xbal = xfactor/30./size.width();
346 float ybal = yfactor/30./size.height(); 344 float ybal = yfactor/30./size.height();
347 float rat; 345 float rat;
348 346
349 int rDiff, gDiff, bDiff; 347 int rDiff, gDiff, bDiff;
350 int rca, gca, bca, rcb, gcb, bcb; 348 int rca, gca, bca, rcb, gcb, bcb;
351 349
352 QImage image(size, 32); 350 QImage image(size, 32);
353 351
354 if (size.width() == 0 || size.height() == 0) { 352 if (size.width() == 0 || size.height() == 0) {
355#ifndef NDEBUG 353 qDebug( "WARNING: OImageEffect::unbalancedGradient : invalid image" );
356 cerr << "WARNING: OImageEffect::unbalancedGradient : invalid image\n";
357#endif
358 return image; 354 return image;
359 } 355 }
360 356
361 register int x, y; 357 register int x, y;
362 unsigned int *scanline; 358 unsigned int *scanline;
363 359
364 rDiff = (rcb = cb.red()) - (rca = ca.red()); 360 rDiff = (rcb = cb.red()) - (rca = ca.red());
365 gDiff = (gcb = cb.green()) - (gca = ca.green()); 361 gDiff = (gcb = cb.green()) - (gca = ca.green());
366 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 362 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
367 363
368 if( eff == VerticalGradient || eff == HorizontalGradient){ 364 if( eff == VerticalGradient || eff == HorizontalGradient){
369 QColor cRow; 365 QColor cRow;
370 366
371 uint *p; 367 uint *p;
372 uint rgbRow; 368 uint rgbRow;
373 369
374 if( eff == VerticalGradient) { 370 if( eff == VerticalGradient) {
375 for ( y = 0; y < size.height(); y++ ) { 371 for ( y = 0; y < size.height(); y++ ) {
376 dir = _yanti ? y : size.height() - 1 - y; 372 dir = _yanti ? y : size.height() - 1 - y;
377 p = (uint *) image.scanLine(dir); 373 p = (uint *) image.scanLine(dir);
378 rat = 1 - exp( - (float)y * ybal ); 374 rat = 1 - exp( - (float)y * ybal );
379 375
380 cRow.setRgb( rcb - (int) ( rDiff * rat ), 376 cRow.setRgb( rcb - (int) ( rDiff * rat ),
381 gcb - (int) ( gDiff * rat ), 377 gcb - (int) ( gDiff * rat ),
382 bcb - (int) ( bDiff * rat ) ); 378 bcb - (int) ( bDiff * rat ) );
383 379
384 rgbRow = cRow.rgb(); 380 rgbRow = cRow.rgb();
385 381
386 for( x = 0; x < size.width(); x++ ) { 382 for( x = 0; x < size.width(); x++ ) {
387 *p = rgbRow; 383 *p = rgbRow;
388 p++; 384 p++;
389 } 385 }
390 } 386 }
391 } 387 }
392 else { 388 else {
393 389
394 unsigned int *src = (unsigned int *)image.scanLine(0); 390 unsigned int *src = (unsigned int *)image.scanLine(0);
395 for(x = 0; x < size.width(); x++ ) 391 for(x = 0; x < size.width(); x++ )
396 { 392 {
397 dir = _xanti ? x : size.width() - 1 - x; 393 dir = _xanti ? x : size.width() - 1 - x;
398 rat = 1 - exp( - (float)x * xbal ); 394 rat = 1 - exp( - (float)x * xbal );
399 395
400 src[dir] = qRgb(rcb - (int) ( rDiff * rat ), 396 src[dir] = qRgb(rcb - (int) ( rDiff * rat ),
401 gcb - (int) ( gDiff * rat ), 397 gcb - (int) ( gDiff * rat ),
402 bcb - (int) ( bDiff * rat )); 398 bcb - (int) ( bDiff * rat ));
403 } 399 }
404 400
405 // Believe it or not, manually copying in a for loop is faster 401 // Believe it or not, manually copying in a for loop is faster
406 // than calling memcpy for each scanline (on the order of ms...). 402 // than calling memcpy for each scanline (on the order of ms...).
407 // I think this is due to the function call overhead (mosfet). 403 // I think this is due to the function call overhead (mosfet).
408 404
409 for(y = 1; y < size.height(); ++y) 405 for(y = 1; y < size.height(); ++y)
410 { 406 {
411 scanline = (unsigned int *)image.scanLine(y); 407 scanline = (unsigned int *)image.scanLine(y);
412 for(x=0; x < size.width(); ++x) 408 for(x=0; x < size.width(); ++x)
413 scanline[x] = src[x]; 409 scanline[x] = src[x];
414 } 410 }
415 } 411 }
416 } 412 }
417 413
418 else { 414 else {
419 int w=size.width(), h=size.height(); 415 int w=size.width(), h=size.height();
420 416
421 unsigned char *xtable[3]; 417 unsigned char *xtable[3];
422 unsigned char *ytable[3]; 418 unsigned char *ytable[3];
423 xtable[0] = new unsigned char[w]; 419 xtable[0] = new unsigned char[w];
424 xtable[1] = new unsigned char[w]; 420 xtable[1] = new unsigned char[w];
425 xtable[2] = new unsigned char[w]; 421 xtable[2] = new unsigned char[w];
426 ytable[0] = new unsigned char[h]; 422 ytable[0] = new unsigned char[h];
427 ytable[1] = new unsigned char[h]; 423 ytable[1] = new unsigned char[h];
428 ytable[2] = new unsigned char[h]; 424 ytable[2] = new unsigned char[h];
429 425
430 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) 426 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient)
431 { 427 {
432 for (x = 0; x < w; x++) { 428 for (x = 0; x < w; x++) {
433 dir = _xanti ? x : w - 1 - x; 429 dir = _xanti ? x : w - 1 - x;
434 rat = 1 - exp( - (float)x * xbal ); 430 rat = 1 - exp( - (float)x * xbal );
435 431
436 xtable[0][dir] = (unsigned char) ( rDiff/2 * rat ); 432 xtable[0][dir] = (unsigned char) ( rDiff/2 * rat );
437 xtable[1][dir] = (unsigned char) ( gDiff/2 * rat ); 433 xtable[1][dir] = (unsigned char) ( gDiff/2 * rat );
438 xtable[2][dir] = (unsigned char) ( bDiff/2 * rat ); 434 xtable[2][dir] = (unsigned char) ( bDiff/2 * rat );
439 } 435 }
440 436
441 for (y = 0; y < h; y++) { 437 for (y = 0; y < h; y++) {
442 dir = _yanti ? y : h - 1 - y; 438 dir = _yanti ? y : h - 1 - y;
443 rat = 1 - exp( - (float)y * ybal ); 439 rat = 1 - exp( - (float)y * ybal );
444 440
445 ytable[0][dir] = (unsigned char) ( rDiff/2 * rat ); 441 ytable[0][dir] = (unsigned char) ( rDiff/2 * rat );
446 ytable[1][dir] = (unsigned char) ( gDiff/2 * rat ); 442 ytable[1][dir] = (unsigned char) ( gDiff/2 * rat );
447 ytable[2][dir] = (unsigned char) ( bDiff/2 * rat ); 443 ytable[2][dir] = (unsigned char) ( bDiff/2 * rat );
448 } 444 }
449 445
450 for (y = 0; y < h; y++) { 446 for (y = 0; y < h; y++) {
451 unsigned int *scanline = (unsigned int *)image.scanLine(y); 447 unsigned int *scanline = (unsigned int *)image.scanLine(y);
452 for (x = 0; x < w; x++) { 448 for (x = 0; x < w; x++) {
453 scanline[x] = qRgb(rcb - (xtable[0][x] + ytable[0][y]), 449 scanline[x] = qRgb(rcb - (xtable[0][x] + ytable[0][y]),
454 gcb - (xtable[1][x] + ytable[1][y]), 450 gcb - (xtable[1][x] + ytable[1][y]),
455 bcb - (xtable[2][x] + ytable[2][y])); 451 bcb - (xtable[2][x] + ytable[2][y]));
456 } 452 }
457 } 453 }
458 } 454 }
459 455
460 else if (eff == RectangleGradient || 456 else if (eff == RectangleGradient ||
461 eff == PyramidGradient || 457 eff == PyramidGradient ||
462 eff == PipeCrossGradient || 458 eff == PipeCrossGradient ||
463 eff == EllipticGradient) 459 eff == EllipticGradient)
464 { 460 {
465 int rSign = rDiff>0? 1: -1; 461 int rSign = rDiff>0? 1: -1;
466 int gSign = gDiff>0? 1: -1; 462 int gSign = gDiff>0? 1: -1;
467 int bSign = bDiff>0? 1: -1; 463 int bSign = bDiff>0? 1: -1;
468 464
469 for (x = 0; x < w; x++) 465 for (x = 0; x < w; x++)
470 { 466 {
471 dir = _xanti ? x : w - 1 - x; 467 dir = _xanti ? x : w - 1 - x;
472 rat = 1 - exp( - (float)x * xbal ); 468 rat = 1 - exp( - (float)x * xbal );
473 469
474 xtable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); 470 xtable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat)));
475 xtable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); 471 xtable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat)));
476 xtable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); 472 xtable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat)));
477 } 473 }
478 474
479 for (y = 0; y < h; y++) 475 for (y = 0; y < h; y++)
480 { 476 {
481 dir = _yanti ? y : h - 1 - y; 477 dir = _yanti ? y : h - 1 - y;
482 478
483 rat = 1 - exp( - (float)y * ybal ); 479 rat = 1 - exp( - (float)y * ybal );
484 480
485 ytable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); 481 ytable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat)));
486 ytable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); 482 ytable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat)));
487 ytable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); 483 ytable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat)));
488 } 484 }
489 485
490 for (y = 0; y < h; y++) { 486 for (y = 0; y < h; y++) {
491 unsigned int *scanline = (unsigned int *)image.scanLine(y); 487 unsigned int *scanline = (unsigned int *)image.scanLine(y);
492 for (x = 0; x < w; x++) { 488 for (x = 0; x < w; x++) {
493 if (eff == PyramidGradient) 489 if (eff == PyramidGradient)
494 { 490 {
495 scanline[x] = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), 491 scanline[x] = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]),
496 gcb-gSign*(xtable[1][x]+ytable[1][y]), 492 gcb-gSign*(xtable[1][x]+ytable[1][y]),
497 bcb-bSign*(xtable[2][x]+ytable[2][y])); 493 bcb-bSign*(xtable[2][x]+ytable[2][y]));
498 } 494 }
499 if (eff == RectangleGradient) 495 if (eff == RectangleGradient)
500 { 496 {
501 scanline[x] = qRgb(rcb - rSign * 497 scanline[x] = qRgb(rcb - rSign *
502 QMAX(xtable[0][x], ytable[0][y]) * 2, 498 QMAX(xtable[0][x], ytable[0][y]) * 2,
503 gcb - gSign * 499 gcb - gSign *
504 QMAX(xtable[1][x], ytable[1][y]) * 2, 500 QMAX(xtable[1][x], ytable[1][y]) * 2,
505 bcb - bSign * 501 bcb - bSign *
506 QMAX(xtable[2][x], ytable[2][y]) * 2); 502 QMAX(xtable[2][x], ytable[2][y]) * 2);
507 } 503 }
508 if (eff == PipeCrossGradient) 504 if (eff == PipeCrossGradient)
509 { 505 {
510 scanline[x] = qRgb(rcb - rSign * 506 scanline[x] = qRgb(rcb - rSign *
511 QMIN(xtable[0][x], ytable[0][y]) * 2, 507 QMIN(xtable[0][x], ytable[0][y]) * 2,
512 gcb - gSign * 508 gcb - gSign *
513 QMIN(xtable[1][x], ytable[1][y]) * 2, 509 QMIN(xtable[1][x], ytable[1][y]) * 2,
514 bcb - bSign * 510 bcb - bSign *
515 QMIN(xtable[2][x], ytable[2][y]) * 2); 511 QMIN(xtable[2][x], ytable[2][y]) * 2);
516 } 512 }
517 if (eff == EllipticGradient) 513 if (eff == EllipticGradient)
518 { 514 {
519 scanline[x] = qRgb(rcb - rSign * 515 scanline[x] = qRgb(rcb - rSign *
520 (int)sqrt((xtable[0][x]*xtable[0][x] + 516 (int)sqrt((xtable[0][x]*xtable[0][x] +
521 ytable[0][y]*ytable[0][y])*2.0), 517 ytable[0][y]*ytable[0][y])*2.0),
522 gcb - gSign * 518 gcb - gSign *
523 (int)sqrt((xtable[1][x]*xtable[1][x] + 519 (int)sqrt((xtable[1][x]*xtable[1][x] +
524 ytable[1][y]*ytable[1][y])*2.0), 520 ytable[1][y]*ytable[1][y])*2.0),
525 bcb - bSign * 521 bcb - bSign *
526 (int)sqrt((xtable[2][x]*xtable[2][x] + 522 (int)sqrt((xtable[2][x]*xtable[2][x] +
527 ytable[2][y]*ytable[2][y])*2.0)); 523 ytable[2][y]*ytable[2][y])*2.0));
528 } 524 }
529 } 525 }
530 } 526 }
531 } 527 }
532 528
533 if (ncols && (QPixmap::defaultDepth() < 15 )) { 529 if (ncols && (QPixmap::defaultDepth() < 15 )) {
534 if ( ncols < 2 || ncols > 256 ) 530 if ( ncols < 2 || ncols > 256 )
535 ncols = 3; 531 ncols = 3;
536 QColor *dPal = new QColor[ncols]; 532 QColor *dPal = new QColor[ncols];
537 for (int i=0; i<ncols; i++) { 533 for (int i=0; i<ncols; i++) {
538 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), 534 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ),
539 gca + gDiff * i / ( ncols - 1 ), 535 gca + gDiff * i / ( ncols - 1 ),
540 bca + bDiff * i / ( ncols - 1 ) ); 536 bca + bDiff * i / ( ncols - 1 ) );
541 } 537 }
542 dither(image, dPal, ncols); 538 dither(image, dPal, ncols);
543 delete [] dPal; 539 delete [] dPal;
544 } 540 }
545 541
546 delete [] xtable[0]; 542 delete [] xtable[0];
547 delete [] xtable[1]; 543 delete [] xtable[1];
548 delete [] xtable[2]; 544 delete [] xtable[2];
549 delete [] ytable[0]; 545 delete [] ytable[0];
550 delete [] ytable[1]; 546 delete [] ytable[1];
551 delete [] ytable[2]; 547 delete [] ytable[2];
552 548
553 } 549 }
554 550
555 return image; 551 return image;
556} 552}
557 553
558 554
559//====================================================================== 555//======================================================================
560// 556//
561// Intensity effects 557// Intensity effects
562// 558//
563//====================================================================== 559//======================================================================
564 560
565 561
566/* This builds a 256 byte unsigned char lookup table with all 562/* This builds a 256 byte unsigned char lookup table with all
567 * the possible percent values prior to applying the effect, then uses 563 * the possible percent values prior to applying the effect, then uses
568 * integer math for the pixels. For any image larger than 9x9 this will be 564 * integer math for the pixels. For any image larger than 9x9 this will be
569 * less expensive than doing a float operation on the 3 color components of 565 * less expensive than doing a float operation on the 3 color components of
570 * each pixel. (mosfet) 566 * each pixel. (mosfet)
571 */ 567 */
572 568
573QImage& OImageEffect::intensity(QImage &image, float percent) 569QImage& OImageEffect::intensity(QImage &image, float percent)
574{ 570{
575 if (image.width() == 0 || image.height() == 0) { 571 if (image.width() == 0 || image.height() == 0) {
576#ifndef NDEBUG 572 qDebug( "WARNING: OImageEffect::intensity : invalid image" );
577 cerr << "WARNING: OImageEffect::intensity : invalid image\n";
578#endif
579 return image; 573 return image;
580 } 574 }
581 575
582 int segColors = image.depth() > 8 ? 256 : image.numColors(); 576 int segColors = image.depth() > 8 ? 256 : image.numColors();
583 unsigned char *segTbl = new unsigned char[segColors]; 577 unsigned char *segTbl = new unsigned char[segColors];
584 int pixels = image.depth() > 8 ? image.width()*image.height() : 578 int pixels = image.depth() > 8 ? image.width()*image.height() :
585 image.numColors(); 579 image.numColors();
586 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 580 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
587 (unsigned int *)image.colorTable(); 581 (unsigned int *)image.colorTable();
588 582
589 bool brighten = (percent >= 0); 583 bool brighten = (percent >= 0);
590 if(percent < 0) 584 if(percent < 0)
591 percent = -percent; 585 percent = -percent;
592 586
593 if(brighten){ // keep overflow check out of loops 587 if(brighten){ // keep overflow check out of loops
594 for(int i=0; i < segColors; ++i){ 588 for(int i=0; i < segColors; ++i){
595 int tmp = (int)(i*percent); 589 int tmp = (int)(i*percent);
596 if(tmp > 255) 590 if(tmp > 255)
597 tmp = 255; 591 tmp = 255;
598 segTbl[i] = tmp; 592 segTbl[i] = tmp;
599 } 593 }
600 } 594 }
601 else{ 595 else{
602 for(int i=0; i < segColors; ++i){ 596 for(int i=0; i < segColors; ++i){
603 int tmp = (int)(i*percent); 597 int tmp = (int)(i*percent);
604 if(tmp < 0) 598 if(tmp < 0)
605 tmp = 0; 599 tmp = 0;
606 segTbl[i] = tmp; 600 segTbl[i] = tmp;
607 } 601 }
608 } 602 }
609 603
610 if(brighten){ // same here 604 if(brighten){ // same here
611 for(int i=0; i < pixels; ++i){ 605 for(int i=0; i < pixels; ++i){
612 int r = qRed(data[i]); 606 int r = qRed(data[i]);
613 int g = qGreen(data[i]); 607 int g = qGreen(data[i]);
614 int b = qBlue(data[i]); 608 int b = qBlue(data[i]);
615 int a = qAlpha(data[i]); 609 int a = qAlpha(data[i]);
616 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; 610 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r];
617 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; 611 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g];
618 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; 612 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b];
619 data[i] = qRgba(r, g, b,a); 613 data[i] = qRgba(r, g, b,a);
620 } 614 }
621 } 615 }
622 else{ 616 else{
623 for(int i=0; i < pixels; ++i){ 617 for(int i=0; i < pixels; ++i){
624 int r = qRed(data[i]); 618 int r = qRed(data[i]);
625 int g = qGreen(data[i]); 619 int g = qGreen(data[i]);
626 int b = qBlue(data[i]); 620 int b = qBlue(data[i]);
627 int a = qAlpha(data[i]); 621 int a = qAlpha(data[i]);
628 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; 622 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r];
629 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; 623 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g];
630 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; 624 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b];
631 data[i] = qRgba(r, g, b, a); 625 data[i] = qRgba(r, g, b, a);
632 } 626 }
633 } 627 }
634 delete [] segTbl; 628 delete [] segTbl;
635 629
636 return image; 630 return image;
637} 631}
638 632
639QImage& OImageEffect::channelIntensity(QImage &image, float percent, 633QImage& OImageEffect::channelIntensity(QImage &image, float percent,
640 RGBComponent channel) 634 RGBComponent channel)
641{ 635{
642 if (image.width() == 0 || image.height() == 0) { 636 if (image.width() == 0 || image.height() == 0) {
643#ifndef NDEBUG 637 qDebug( "WARNING: OImageEffect::channelIntensity : invalid image" );
644 cerr << "WARNING: OImageEffect::channelIntensity : invalid image\n";
645#endif
646 return image; 638 return image;
647 } 639 }
648 640
649 int segColors = image.depth() > 8 ? 256 : image.numColors(); 641 int segColors = image.depth() > 8 ? 256 : image.numColors();
650 unsigned char *segTbl = new unsigned char[segColors]; 642 unsigned char *segTbl = new unsigned char[segColors];
651 int pixels = image.depth() > 8 ? image.width()*image.height() : 643 int pixels = image.depth() > 8 ? image.width()*image.height() :
652 image.numColors(); 644 image.numColors();
653 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 645 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
654 (unsigned int *)image.colorTable(); 646 (unsigned int *)image.colorTable();
655 bool brighten = (percent >= 0); 647 bool brighten = (percent >= 0);
656 if(percent < 0) 648 if(percent < 0)
657 percent = -percent; 649 percent = -percent;
658 650
659 if(brighten){ // keep overflow check out of loops 651 if(brighten){ // keep overflow check out of loops
660 for(int i=0; i < segColors; ++i){ 652 for(int i=0; i < segColors; ++i){
661 int tmp = (int)(i*percent); 653 int tmp = (int)(i*percent);
662 if(tmp > 255) 654 if(tmp > 255)
663 tmp = 255; 655 tmp = 255;
664 segTbl[i] = tmp; 656 segTbl[i] = tmp;
665 } 657 }
666 } 658 }
667 else{ 659 else{
668 for(int i=0; i < segColors; ++i){ 660 for(int i=0; i < segColors; ++i){
669 int tmp = (int)(i*percent); 661 int tmp = (int)(i*percent);
670 if(tmp < 0) 662 if(tmp < 0)
671 tmp = 0; 663 tmp = 0;
672 segTbl[i] = tmp; 664 segTbl[i] = tmp;
673 } 665 }
674 } 666 }
675 667
676 if(brighten){ // same here 668 if(brighten){ // same here
677 if(channel == Red){ // and here ;-) 669 if(channel == Red){ // and here ;-)
678 for(int i=0; i < pixels; ++i){ 670 for(int i=0; i < pixels; ++i){
679 int c = qRed(data[i]); 671 int c = qRed(data[i]);
680 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 672 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
681 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i])); 673 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i]));
682 } 674 }
683 } 675 }
684 if(channel == Green){ 676 if(channel == Green){
685 for(int i=0; i < pixels; ++i){ 677 for(int i=0; i < pixels; ++i){
686 int c = qGreen(data[i]); 678 int c = qGreen(data[i]);
687 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 679 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
688 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i])); 680 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i]));
689 } 681 }
690 } 682 }
691 else{ 683 else{
692 for(int i=0; i < pixels; ++i){ 684 for(int i=0; i < pixels; ++i){
693 int c = qBlue(data[i]); 685 int c = qBlue(data[i]);
694 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 686 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
695 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i])); 687 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i]));
696 } 688 }
697 } 689 }
698 690
699 } 691 }
700 else{ 692 else{
701 if(channel == Red){ 693 if(channel == Red){
702 for(int i=0; i < pixels; ++i){ 694 for(int i=0; i < pixels; ++i){
703 int c = qRed(data[i]); 695 int c = qRed(data[i]);
704 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 696 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
705 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i])); 697 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i]));
706 } 698 }
707 } 699 }
708 if(channel == Green){ 700 if(channel == Green){
709 for(int i=0; i < pixels; ++i){ 701 for(int i=0; i < pixels; ++i){
710 int c = qGreen(data[i]); 702 int c = qGreen(data[i]);
711 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 703 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
712 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i])); 704 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i]));
713 } 705 }
714 } 706 }
715 else{ 707 else{
716 for(int i=0; i < pixels; ++i){ 708 for(int i=0; i < pixels; ++i){
717 int c = qBlue(data[i]); 709 int c = qBlue(data[i]);
718 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 710 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
719 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i])); 711 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i]));
720 } 712 }
721 } 713 }
722 } 714 }
723 delete [] segTbl; 715 delete [] segTbl;
724 716
725 return image; 717 return image;
726} 718}
727 719
728// Modulate an image with an RBG channel of another image 720// Modulate an image with an RBG channel of another image
729// 721//
730QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse, 722QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse,
731 ModulationType type, int factor, RGBComponent channel) 723 ModulationType type, int factor, RGBComponent channel)
732{ 724{
733 if (image.width() == 0 || image.height() == 0 || 725 if (image.width() == 0 || image.height() == 0 ||
734 modImage.width() == 0 || modImage.height() == 0) { 726 modImage.width() == 0 || modImage.height() == 0) {
735#ifndef NDEBUG 727 qDebug( "WARNING: OImageEffect::modulate : invalid image" );
736 cerr << "WARNING: OImageEffect::modulate : invalid image\n"; 728 return image;
737#endif
738 return image;
739 } 729 }
740 730
741 int r, g, b, h, s, v, a; 731 int r, g, b, h, s, v, a;
742 QColor clr; 732 QColor clr;
743 int mod=0; 733 int mod=0;
744 unsigned int x1, x2, y1, y2; 734 unsigned int x1, x2, y1, y2;
745 register int x, y; 735 register int x, y;
746 736
747 // for image, we handle only depth 32 737 // for image, we handle only depth 32
748 if (image.depth()<32) image = image.convertDepth(32); 738 if (image.depth()<32) image = image.convertDepth(32);
749 739
750 // for modImage, we handle depth 8 and 32 740 // for modImage, we handle depth 8 and 32
751 if (modImage.depth()<8) modImage = modImage.convertDepth(8); 741 if (modImage.depth()<8) modImage = modImage.convertDepth(8);
752 742
753 unsigned int *colorTable2 = (modImage.depth()==8) ? 743 unsigned int *colorTable2 = (modImage.depth()==8) ?
754 modImage.colorTable():0; 744 modImage.colorTable():0;
755 unsigned int *data1, *data2; 745 unsigned int *data1, *data2;
756 unsigned char *data2b; 746 unsigned char *data2b;
757 unsigned int color1, color2; 747 unsigned int color1, color2;
758 748
759 x1 = image.width(); y1 = image.height(); 749 x1 = image.width(); y1 = image.height();
760 x2 = modImage.width(); y2 = modImage.height(); 750 x2 = modImage.width(); y2 = modImage.height();
761 751
762 for (y = 0; y < (int)y1; y++) { 752 for (y = 0; y < (int)y1; y++) {
763 data1 = (unsigned int *) image.scanLine(y); 753 data1 = (unsigned int *) image.scanLine(y);
764 data2 = (unsigned int *) modImage.scanLine( y%y2 ); 754 data2 = (unsigned int *) modImage.scanLine( y%y2 );
765 data2b = (unsigned char *) modImage.scanLine( y%y2 ); 755 data2b = (unsigned char *) modImage.scanLine( y%y2 );
766 756
767 x=0; 757 x=0;
768 while(x < (int)x1) { 758 while(x < (int)x1) {
769 color2 = (colorTable2) ? colorTable2[*data2b] : *data2; 759 color2 = (colorTable2) ? colorTable2[*data2b] : *data2;
770 if (reverse) { 760 if (reverse) {
771 color1 = color2; 761 color1 = color2;
772 color2 = *data1; 762 color2 = *data1;
773 } 763 }
774 else 764 else
775 color1 = *data1; 765 color1 = *data1;
776 766
777 if (type == Intensity || type == Contrast) { 767 if (type == Intensity || type == Contrast) {
778 r = qRed(color1); 768 r = qRed(color1);
779 g = qGreen(color1); 769 g = qGreen(color1);
780 b = qBlue(color1); 770 b = qBlue(color1);
781 if (channel != All) { 771 if (channel != All) {
782 mod = (channel == Red) ? qRed(color2) : 772 mod = (channel == Red) ? qRed(color2) :
783 (channel == Green) ? qGreen(color2) : 773 (channel == Green) ? qGreen(color2) :
784 (channel == Blue) ? qBlue(color2) : 774 (channel == Blue) ? qBlue(color2) :
785 (channel == Gray) ? qGray(color2) : 0; 775 (channel == Gray) ? qGray(color2) : 0;
786 mod = mod*factor/50; 776 mod = mod*factor/50;
787 } 777 }
788 778
789 if (type == Intensity) { 779 if (type == Intensity) {
790 if (channel == All) { 780 if (channel == All) {
791 r += r * factor/50 * qRed(color2)/256; 781 r += r * factor/50 * qRed(color2)/256;
792 g += g * factor/50 * qGreen(color2)/256; 782 g += g * factor/50 * qGreen(color2)/256;
793 b += b * factor/50 * qBlue(color2)/256; 783 b += b * factor/50 * qBlue(color2)/256;
794 } 784 }
795 else { 785 else {
796 r += r * mod/256; 786 r += r * mod/256;
797 g += g * mod/256; 787 g += g * mod/256;
798 b += b * mod/256; 788 b += b * mod/256;
799 } 789 }
800 } 790 }
801 else { // Contrast 791 else { // Contrast
802 if (channel == All) { 792 if (channel == All) {
803 r += (r-128) * factor/50 * qRed(color2)/128; 793 r += (r-128) * factor/50 * qRed(color2)/128;
804 g += (g-128) * factor/50 * qGreen(color2)/128; 794 g += (g-128) * factor/50 * qGreen(color2)/128;
805 b += (b-128) * factor/50 * qBlue(color2)/128; 795 b += (b-128) * factor/50 * qBlue(color2)/128;
806 } 796 }
807 else { 797 else {
808 r += (r-128) * mod/128; 798 r += (r-128) * mod/128;
809 g += (g-128) * mod/128; 799 g += (g-128) * mod/128;
810 b += (b-128) * mod/128; 800 b += (b-128) * mod/128;
811 } 801 }
812 } 802 }
813 803
814 if (r<0) r=0; if (r>255) r=255; 804 if (r<0) r=0; if (r>255) r=255;
815 if (g<0) g=0; if (g>255) g=255; 805 if (g<0) g=0; if (g>255) g=255;
816 if (b<0) b=0; if (b>255) b=255; 806 if (b<0) b=0; if (b>255) b=255;
817 a = qAlpha(*data1); 807 a = qAlpha(*data1);
818 *data1 = qRgba(r, g, b, a); 808 *data1 = qRgba(r, g, b, a);
819 } 809 }
820 else if (type == Saturation || type == HueShift) { 810 else if (type == Saturation || type == HueShift) {
821 clr.setRgb(color1); 811 clr.setRgb(color1);
822 clr.hsv(&h, &s, &v); 812 clr.hsv(&h, &s, &v);
823 mod = (channel == Red) ? qRed(color2) : 813 mod = (channel == Red) ? qRed(color2) :
824 (channel == Green) ? qGreen(color2) : 814 (channel == Green) ? qGreen(color2) :
825 (channel == Blue) ? qBlue(color2) : 815 (channel == Blue) ? qBlue(color2) :
826 (channel == Gray) ? qGray(color2) : 0; 816 (channel == Gray) ? qGray(color2) : 0;
827 mod = mod*factor/50; 817 mod = mod*factor/50;
828 818
829 if (type == Saturation) { 819 if (type == Saturation) {
830 s -= s * mod/256; 820 s -= s * mod/256;
831 if (s<0) s=0; if (s>255) s=255; 821 if (s<0) s=0; if (s>255) s=255;
832 } 822 }
833 else { // HueShift 823 else { // HueShift
834 h += mod; 824 h += mod;
835 while(h<0) h+=360; 825 while(h<0) h+=360;
836 h %= 360; 826 h %= 360;
837 } 827 }
838 828
839 clr.setHsv(h, s, v); 829 clr.setHsv(h, s, v);
840 a = qAlpha(*data1); 830 a = qAlpha(*data1);
841 *data1 = clr.rgb() | ((uint)(a & 0xff) << 24); 831 *data1 = clr.rgb() | ((uint)(a & 0xff) << 24);
842 } 832 }
843 data1++; data2++; data2b++; x++; 833 data1++; data2++; data2b++; x++;
844 if ( (x%x2) ==0) { data2 -= x2; data2b -= x2; } 834 if ( (x%x2) ==0) { data2 -= x2; data2b -= x2; }
845 } 835 }
846 } 836 }
847 return image; 837 return image;
848} 838}
849 839
850 840
851 841
852//====================================================================== 842//======================================================================
853// 843//
854// Blend effects 844// Blend effects
855// 845//
856//====================================================================== 846//======================================================================
857 847
858 848
859// Nice and fast direct pixel manipulation 849// Nice and fast direct pixel manipulation
860QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity) 850QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity)
861{ 851{
862 if (dst.width() <= 0 || dst.height() <= 0) 852 if (dst.width() <= 0 || dst.height() <= 0)
863 return dst; 853 return dst;
864 854
865 if (opacity < 0.0 || opacity > 1.0) { 855 if (opacity < 0.0 || opacity > 1.0) {
866#ifndef NDEBUG 856 qDebug( "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1] ");
867 cerr << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]\n"; 857 return dst;
868#endif
869 return dst;
870 } 858 }
871 859
872 int depth = dst.depth(); 860 int depth = dst.depth();
873 if (depth != 32) 861 if (depth != 32)
874 dst = dst.convertDepth(32); 862 dst = dst.convertDepth(32);
875 863
876 int pixels = dst.width() * dst.height(); 864 int pixels = dst.width() * dst.height();
877 int rcol, gcol, bcol; 865 int rcol, gcol, bcol;
878 clr.rgb(&rcol, &gcol, &bcol); 866 clr.rgb(&rcol, &gcol, &bcol);
879 867
880#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) 868#ifdef WORDS_BIGENDIAN // ARGB (skip alpha)
881 register unsigned char *data = (unsigned char *)dst.bits() + 1; 869 register unsigned char *data = (unsigned char *)dst.bits() + 1;
882#else // BGRA 870#else // BGRA
883 register unsigned char *data = (unsigned char *)dst.bits(); 871 register unsigned char *data = (unsigned char *)dst.bits();
884#endif 872#endif
885 873
886 for (register int i=0; i<pixels; i++) 874 for (register int i=0; i<pixels; i++)
887 { 875 {
888#ifdef WORDS_BIGENDIAN 876#ifdef WORDS_BIGENDIAN
889 *(data++) += (unsigned char)((rcol - *data) * opacity); 877 *(data++) += (unsigned char)((rcol - *data) * opacity);
890 *(data++) += (unsigned char)((gcol - *data) * opacity); 878 *(data++) += (unsigned char)((gcol - *data) * opacity);
891 *(data++) += (unsigned char)((bcol - *data) * opacity); 879 *(data++) += (unsigned char)((bcol - *data) * opacity);
892#else 880#else
893 *(data++) += (unsigned char)((bcol - *data) * opacity); 881 *(data++) += (unsigned char)((bcol - *data) * opacity);
894 *(data++) += (unsigned char)((gcol - *data) * opacity); 882 *(data++) += (unsigned char)((gcol - *data) * opacity);
895 *(data++) += (unsigned char)((rcol - *data) * opacity); 883 *(data++) += (unsigned char)((rcol - *data) * opacity);
896#endif 884#endif
897 data++; // skip alpha 885 data++; // skip alpha
898 } 886 }
899 return dst; 887 return dst;
900} 888}
901 889
902// Nice and fast direct pixel manipulation 890// Nice and fast direct pixel manipulation
903QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity) 891QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity)
904{ 892{
905 if (src.width() <= 0 || src.height() <= 0) 893 if (src.width() <= 0 || src.height() <= 0)
906 return dst; 894 return dst;
907 if (dst.width() <= 0 || dst.height() <= 0) 895 if (dst.width() <= 0 || dst.height() <= 0)
908 return dst; 896 return dst;
909 897
910 if (src.width() != dst.width() || src.height() != dst.height()) { 898 if (src.width() != dst.width() || src.height() != dst.height()) {
911#ifndef NDEBUG 899 qDebug( "WARNING: OImageEffect::blend : src and destination images are not the same size" );
912 cerr << "WARNING: OImageEffect::blend : src and destination images are not the same size\n"; 900 return dst;
913#endif
914 return dst;
915 } 901 }
916 902
917 if (opacity < 0.0 || opacity > 1.0) { 903 if (opacity < 0.0 || opacity > 1.0) {
918#ifndef NDEBUG 904 qDebug( "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]" );
919 cerr << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]\n"; 905 return dst;
920#endif
921 return dst;
922 } 906 }
923 907
924 if (src.depth() != 32) src = src.convertDepth(32); 908 if (src.depth() != 32) src = src.convertDepth(32);
925 if (dst.depth() != 32) dst = dst.convertDepth(32); 909 if (dst.depth() != 32) dst = dst.convertDepth(32);
926 910
927 int pixels = src.width() * src.height(); 911 int pixels = src.width() * src.height();
928#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) 912#ifdef WORDS_BIGENDIAN // ARGB (skip alpha)
929 register unsigned char *data1 = (unsigned char *)dst.bits() + 1; 913 register unsigned char *data1 = (unsigned char *)dst.bits() + 1;
930 register unsigned char *data2 = (unsigned char *)src.bits() + 1; 914 register unsigned char *data2 = (unsigned char *)src.bits() + 1;
931#else // BGRA 915#else // BGRA
932 register unsigned char *data1 = (unsigned char *)dst.bits(); 916 register unsigned char *data1 = (unsigned char *)dst.bits();
933 register unsigned char *data2 = (unsigned char *)src.bits(); 917 register unsigned char *data2 = (unsigned char *)src.bits();
934#endif 918#endif
935 919
936 for (register int i=0; i<pixels; i++) 920 for (register int i=0; i<pixels; i++)
937 { 921 {
938#ifdef WORDS_BIGENDIAN 922#ifdef WORDS_BIGENDIAN
939 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 923 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
940 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 924 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
941 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 925 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
942#else 926#else
943 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 927 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
944 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 928 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
945 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 929 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
946#endif 930#endif
947 data1++; // skip alpha 931 data1++; // skip alpha
948 data2++; 932 data2++;
949 } 933 }
950 934
951 return dst; 935 return dst;
952} 936}
953 937
954 938
955QImage& OImageEffect::blend(QImage &image, float initial_intensity, 939QImage& OImageEffect::blend(QImage &image, float initial_intensity,
956 const QColor &bgnd, GradientType eff, 940 const QColor &bgnd, GradientType eff,
957 bool anti_dir) 941 bool anti_dir)
958{ 942{
959 if (image.width() == 0 || image.height() == 0 || image.depth()!=32 ) { 943 if (image.width() == 0 || image.height() == 0 || image.depth()!=32 ) {
960#ifndef NDEBUG 944 qDebug( "WARNING: OImageEffect::blend : invalid image" );
961 cerr << "WARNING: OImageEffect::blend : invalid image\n"; 945 return image;
962#endif
963 return image;
964 } 946 }
965 947
966 int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue(); 948 int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue();
967 int r, g, b; 949 int r, g, b;
968 int ind; 950 int ind;
969 951
970 unsigned int xi, xf, yi, yf; 952 unsigned int xi, xf, yi, yf;
971 unsigned int a; 953 unsigned int a;
972 954
973 // check the boundaries of the initial intesity param 955 // check the boundaries of the initial intesity param
974 float unaffected = 1; 956 float unaffected = 1;
975 if (initial_intensity > 1) initial_intensity = 1; 957 if (initial_intensity > 1) initial_intensity = 1;
976 if (initial_intensity < -1) initial_intensity = -1; 958 if (initial_intensity < -1) initial_intensity = -1;
977 if (initial_intensity < 0) { 959 if (initial_intensity < 0) {
978 unaffected = 1. + initial_intensity; 960 unaffected = 1. + initial_intensity;
979 initial_intensity = 0; 961 initial_intensity = 0;
980 } 962 }
981 963
982 964
983 float intensity = initial_intensity; 965 float intensity = initial_intensity;
984 float var = 1. - initial_intensity; 966 float var = 1. - initial_intensity;
985 967
986 if (anti_dir) { 968 if (anti_dir) {
987 initial_intensity = intensity = 1.; 969 initial_intensity = intensity = 1.;
988 var = -var; 970 var = -var;
989 } 971 }
990 972
991 register int x, y; 973 register int x, y;
992 974
993 unsigned int *data = (unsigned int *)image.bits(); 975 unsigned int *data = (unsigned int *)image.bits();
994 976
995 int image_width = image.width(); //Those can't change 977 int image_width = image.width(); //Those can't change
996 int image_height = image.height(); 978 int image_height = image.height();
997 979
998 980
999 if( eff == VerticalGradient || eff == HorizontalGradient ) { 981 if( eff == VerticalGradient || eff == HorizontalGradient ) {
1000 982
1001 // set the image domain to apply the effect to 983 // set the image domain to apply the effect to
1002 xi = 0, xf = image_width; 984 xi = 0, xf = image_width;
1003 yi = 0, yf = image_height; 985 yi = 0, yf = image_height;
1004 if (eff == VerticalGradient) { 986 if (eff == VerticalGradient) {
1005 if (anti_dir) yf = (int)(image_height * unaffected); 987 if (anti_dir) yf = (int)(image_height * unaffected);
1006 else yi = (int)(image_height * (1 - unaffected)); 988 else yi = (int)(image_height * (1 - unaffected));
1007 } 989 }
1008 else { 990 else {
1009 if (anti_dir) xf = (int)(image_width * unaffected); 991 if (anti_dir) xf = (int)(image_width * unaffected);
1010 else xi = (int)(image_height * (1 - unaffected)); 992 else xi = (int)(image_height * (1 - unaffected));
1011 } 993 }
1012 994
1013 var /= (eff == VerticalGradient?yf-yi:xf-xi); 995 var /= (eff == VerticalGradient?yf-yi:xf-xi);
1014 996
1015 int ind_base; 997 int ind_base;
1016 for (y = yi; y < (int)yf; y++) { 998 for (y = yi; y < (int)yf; y++) {
1017 intensity = eff == VerticalGradient? intensity + var : 999 intensity = eff == VerticalGradient? intensity + var :
1018 initial_intensity; 1000 initial_intensity;
1019 ind_base = image_width * y ; 1001 ind_base = image_width * y ;
1020 for (x = xi; x < (int)xf ; x++) { 1002 for (x = xi; x < (int)xf ; x++) {
1021 if (eff == HorizontalGradient) intensity += var; 1003 if (eff == HorizontalGradient) intensity += var;
1022 ind = x + ind_base; 1004 ind = x + ind_base;
1023 r = qRed (data[ind]) + (int)(intensity * 1005 r = qRed (data[ind]) + (int)(intensity *
1024 (r_bgnd - qRed (data[ind]))); 1006 (r_bgnd - qRed (data[ind])));
1025 g = qGreen(data[ind]) + (int)(intensity * 1007 g = qGreen(data[ind]) + (int)(intensity *
1026 (g_bgnd - qGreen(data[ind]))); 1008 (g_bgnd - qGreen(data[ind])));
1027 b = qBlue (data[ind]) + (int)(intensity * 1009 b = qBlue (data[ind]) + (int)(intensity *
1028 (b_bgnd - qBlue (data[ind]))); 1010 (b_bgnd - qBlue (data[ind])));
1029 if (r > 255) r = 255; if (r < 0 ) r = 0; 1011 if (r > 255) r = 255; if (r < 0 ) r = 0;
1030 if (g > 255) g = 255; if (g < 0 ) g = 0; 1012 if (g > 255) g = 255; if (g < 0 ) g = 0;
1031 if (b > 255) b = 255; if (b < 0 ) b = 0; 1013 if (b > 255) b = 255; if (b < 0 ) b = 0;
1032 a = qAlpha(data[ind]); 1014 a = qAlpha(data[ind]);
1033 data[ind] = qRgba(r, g, b, a); 1015 data[ind] = qRgba(r, g, b, a);
1034 } 1016 }
1035 } 1017 }
1036 } 1018 }
1037 else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) { 1019 else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) {
1038 float xvar = var / 2 / image_width; // / unaffected; 1020 float xvar = var / 2 / image_width; // / unaffected;
1039 float yvar = var / 2 / image_height; // / unaffected; 1021 float yvar = var / 2 / image_height; // / unaffected;
1040 float tmp; 1022 float tmp;
1041 1023
1042 for (x = 0; x < image_width ; x++) { 1024 for (x = 0; x < image_width ; x++) {
1043 tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1); 1025 tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1);
1044 ind = x; 1026 ind = x;
1045 for (y = 0; y < image_height ; y++) { 1027 for (y = 0; y < image_height ; y++) {
1046 intensity = initial_intensity + tmp + yvar * y; 1028 intensity = initial_intensity + tmp + yvar * y;
1047 1029
1048 r = qRed (data[ind]) + (int)(intensity * 1030 r = qRed (data[ind]) + (int)(intensity *
1049 (r_bgnd - qRed (data[ind]))); 1031 (r_bgnd - qRed (data[ind])));
1050 g = qGreen(data[ind]) + (int)(intensity * 1032 g = qGreen(data[ind]) + (int)(intensity *
1051 (g_bgnd - qGreen(data[ind]))); 1033 (g_bgnd - qGreen(data[ind])));
1052 b = qBlue (data[ind]) + (int)(intensity * 1034 b = qBlue (data[ind]) + (int)(intensity *
1053 (b_bgnd - qBlue (data[ind]))); 1035 (b_bgnd - qBlue (data[ind])));
1054 if (r > 255) r = 255; if (r < 0 ) r = 0; 1036 if (r > 255) r = 255; if (r < 0 ) r = 0;
1055 if (g > 255) g = 255; if (g < 0 ) g = 0; 1037 if (g > 255) g = 255; if (g < 0 ) g = 0;
1056 if (b > 255) b = 255; if (b < 0 ) b = 0; 1038 if (b > 255) b = 255; if (b < 0 ) b = 0;
1057 a = qAlpha(data[ind]); 1039 a = qAlpha(data[ind]);
1058 data[ind] = qRgba(r, g, b, a); 1040 data[ind] = qRgba(r, g, b, a);
1059 1041
1060 ind += image_width; 1042 ind += image_width;
1061 } 1043 }
1062 } 1044 }
1063 } 1045 }
1064 1046
1065 else if (eff == RectangleGradient || eff == EllipticGradient) { 1047 else if (eff == RectangleGradient || eff == EllipticGradient) {
1066 float xvar; 1048 float xvar;
1067 float yvar; 1049 float yvar;
1068 1050
1069 for (x = 0; x < image_width / 2 + image_width % 2; x++) { 1051 for (x = 0; x < image_width / 2 + image_width % 2; x++) {
1070 xvar = var / image_width * (image_width - x*2/unaffected-1); 1052 xvar = var / image_width * (image_width - x*2/unaffected-1);
1071 for (y = 0; y < image_height / 2 + image_height % 2; y++) { 1053 for (y = 0; y < image_height / 2 + image_height % 2; y++) {
1072 yvar = var / image_height * (image_height - y*2/unaffected -1); 1054 yvar = var / image_height * (image_height - y*2/unaffected -1);
1073 1055
1074 if (eff == RectangleGradient) 1056 if (eff == RectangleGradient)
1075 intensity = initial_intensity + QMAX(xvar, yvar); 1057 intensity = initial_intensity + QMAX(xvar, yvar);
1076 else 1058 else
1077 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar); 1059 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar);
1078 if (intensity > 1) intensity = 1; 1060 if (intensity > 1) intensity = 1;
1079 if (intensity < 0) intensity = 0; 1061 if (intensity < 0) intensity = 0;
1080 1062
1081 //NW 1063 //NW
1082 ind = x + image_width * y ; 1064 ind = x + image_width * y ;
1083 r = qRed (data[ind]) + (int)(intensity * 1065 r = qRed (data[ind]) + (int)(intensity *
1084 (r_bgnd - qRed (data[ind]))); 1066 (r_bgnd - qRed (data[ind])));
1085 g = qGreen(data[ind]) + (int)(intensity * 1067 g = qGreen(data[ind]) + (int)(intensity *
1086 (g_bgnd - qGreen(data[ind]))); 1068 (g_bgnd - qGreen(data[ind])));
1087 b = qBlue (data[ind]) + (int)(intensity * 1069 b = qBlue (data[ind]) + (int)(intensity *
1088 (b_bgnd - qBlue (data[ind]))); 1070 (b_bgnd - qBlue (data[ind])));
1089 if (r > 255) r = 255; if (r < 0 ) r = 0; 1071 if (r > 255) r = 255; if (r < 0 ) r = 0;
1090 if (g > 255) g = 255; if (g < 0 ) g = 0; 1072 if (g > 255) g = 255; if (g < 0 ) g = 0;
1091 if (b > 255) b = 255; if (b < 0 ) b = 0; 1073 if (b > 255) b = 255; if (b < 0 ) b = 0;
1092 a = qAlpha(data[ind]); 1074 a = qAlpha(data[ind]);
1093 data[ind] = qRgba(r, g, b, a); 1075 data[ind] = qRgba(r, g, b, a);
1094 1076
1095 //NE 1077 //NE
1096 ind = image_width - x - 1 + image_width * y ; 1078 ind = image_width - x - 1 + image_width * y ;
1097 r = qRed (data[ind]) + (int)(intensity * 1079 r = qRed (data[ind]) + (int)(intensity *
1098 (r_bgnd - qRed (data[ind]))); 1080 (r_bgnd - qRed (data[ind])));
1099 g = qGreen(data[ind]) + (int)(intensity * 1081 g = qGreen(data[ind]) + (int)(intensity *
1100 (g_bgnd - qGreen(data[ind]))); 1082 (g_bgnd - qGreen(data[ind])));
1101 b = qBlue (data[ind]) + (int)(intensity * 1083 b = qBlue (data[ind]) + (int)(intensity *
1102 (b_bgnd - qBlue (data[ind]))); 1084 (b_bgnd - qBlue (data[ind])));
1103 if (r > 255) r = 255; if (r < 0 ) r = 0; 1085 if (r > 255) r = 255; if (r < 0 ) r = 0;
1104 if (g > 255) g = 255; if (g < 0 ) g = 0; 1086 if (g > 255) g = 255; if (g < 0 ) g = 0;
1105 if (b > 255) b = 255; if (b < 0 ) b = 0; 1087 if (b > 255) b = 255; if (b < 0 ) b = 0;
1106 a = qAlpha(data[ind]); 1088 a = qAlpha(data[ind]);
1107 data[ind] = qRgba(r, g, b, a); 1089 data[ind] = qRgba(r, g, b, a);
1108 } 1090 }
1109 } 1091 }
1110 1092
1111 //CT loop is doubled because of stupid central row/column issue. 1093 //CT loop is doubled because of stupid central row/column issue.
1112 // other solution? 1094 // other solution?
1113 for (x = 0; x < image_width / 2; x++) { 1095 for (x = 0; x < image_width / 2; x++) {
1114 xvar = var / image_width * (image_width - x*2/unaffected-1); 1096 xvar = var / image_width * (image_width - x*2/unaffected-1);
1115 for (y = 0; y < image_height / 2; y++) { 1097 for (y = 0; y < image_height / 2; y++) {
1116 yvar = var / image_height * (image_height - y*2/unaffected -1); 1098 yvar = var / image_height * (image_height - y*2/unaffected -1);
1117 1099
1118 if (eff == RectangleGradient) 1100 if (eff == RectangleGradient)
1119 intensity = initial_intensity + QMAX(xvar, yvar); 1101 intensity = initial_intensity + QMAX(xvar, yvar);
1120 else 1102 else
1121 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar); 1103 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar);
1122 if (intensity > 1) intensity = 1; 1104 if (intensity > 1) intensity = 1;
1123 if (intensity < 0) intensity = 0; 1105 if (intensity < 0) intensity = 0;
1124 1106
1125 //SW 1107 //SW
1126 ind = x + image_width * (image_height - y -1) ; 1108 ind = x + image_width * (image_height - y -1) ;
1127 r = qRed (data[ind]) + (int)(intensity * 1109 r = qRed (data[ind]) + (int)(intensity *
1128 (r_bgnd - qRed (data[ind]))); 1110 (r_bgnd - qRed (data[ind])));
1129 g = qGreen(data[ind]) + (int)(intensity * 1111 g = qGreen(data[ind]) + (int)(intensity *
1130 (g_bgnd - qGreen(data[ind]))); 1112 (g_bgnd - qGreen(data[ind])));
1131 b = qBlue (data[ind]) + (int)(intensity * 1113 b = qBlue (data[ind]) + (int)(intensity *
1132 (b_bgnd - qBlue (data[ind]))); 1114 (b_bgnd - qBlue (data[ind])));
1133 if (r > 255) r = 255; if (r < 0 ) r = 0; 1115 if (r > 255) r = 255; if (r < 0 ) r = 0;
1134 if (g > 255) g = 255; if (g < 0 ) g = 0; 1116 if (g > 255) g = 255; if (g < 0 ) g = 0;
1135 if (b > 255) b = 255; if (b < 0 ) b = 0; 1117 if (b > 255) b = 255; if (b < 0 ) b = 0;
1136 a = qAlpha(data[ind]); 1118 a = qAlpha(data[ind]);
1137 data[ind] = qRgba(r, g, b, a); 1119 data[ind] = qRgba(r, g, b, a);
1138 1120
1139 //SE 1121 //SE
1140 ind = image_width-x-1 + image_width * (image_height - y - 1) ; 1122 ind = image_width-x-1 + image_width * (image_height - y - 1) ;
1141 r = qRed (data[ind]) + (int)(intensity * 1123 r = qRed (data[ind]) + (int)(intensity *
1142 (r_bgnd - qRed (data[ind]))); 1124 (r_bgnd - qRed (data[ind])));
1143 g = qGreen(data[ind]) + (int)(intensity * 1125 g = qGreen(data[ind]) + (int)(intensity *
1144 (g_bgnd - qGreen(data[ind]))); 1126 (g_bgnd - qGreen(data[ind])));
1145 b = qBlue (data[ind]) + (int)(intensity * 1127 b = qBlue (data[ind]) + (int)(intensity *
1146 (b_bgnd - qBlue (data[ind]))); 1128 (b_bgnd - qBlue (data[ind])));
1147 if (r > 255) r = 255; if (r < 0 ) r = 0; 1129 if (r > 255) r = 255; if (r < 0 ) r = 0;
1148 if (g > 255) g = 255; if (g < 0 ) g = 0; 1130 if (g > 255) g = 255; if (g < 0 ) g = 0;
1149 if (b > 255) b = 255; if (b < 0 ) b = 0; 1131 if (b > 255) b = 255; if (b < 0 ) b = 0;
1150 a = qAlpha(data[ind]); 1132 a = qAlpha(data[ind]);
1151 data[ind] = qRgba(r, g, b, a); 1133 data[ind] = qRgba(r, g, b, a);
1152 } 1134 }
1153 } 1135 }
1154 } 1136 }
1155#ifndef NDEBUG 1137 else qDebug( "OImageEffect::blend effect not implemented" );
1156 else cerr << "OImageEffect::blend effect not implemented" << endl;
1157#endif
1158 return image; 1138 return image;
1159} 1139}
1160 1140
1161// Not very efficient as we create a third big image... 1141// Not very efficient as we create a third big image...
1162// 1142//
1163QImage& OImageEffect::blend(QImage &image1, QImage &image2, 1143QImage& OImageEffect::blend(QImage &image1, QImage &image2,
1164 GradientType gt, int xf, int yf) 1144 GradientType gt, int xf, int yf)
1165{ 1145{
1166 if (image1.width() == 0 || image1.height() == 0 || 1146 if (image1.width() == 0 || image1.height() == 0 ||
1167 image2.width() == 0 || image2.height() == 0) 1147 image2.width() == 0 || image2.height() == 0)
1168 return image1; 1148 return image1;
1169 1149
1170 QImage image3; 1150 QImage image3;
1171 1151
1172 image3 = OImageEffect::unbalancedGradient(image1.size(), 1152 image3 = OImageEffect::unbalancedGradient(image1.size(),
1173 QColor(0,0,0), QColor(255,255,255), 1153 QColor(0,0,0), QColor(255,255,255),
1174 gt, xf, yf, 0); 1154 gt, xf, yf, 0);
1175 1155
1176 return blend(image1,image2,image3, Red); // Channel to use is arbitrary 1156 return blend(image1,image2,image3, Red); // Channel to use is arbitrary
1177} 1157}
1178 1158
1179// Blend image2 into image1, using an RBG channel of blendImage 1159// Blend image2 into image1, using an RBG channel of blendImage
1180// 1160//
1181QImage& OImageEffect::blend(QImage &image1, QImage &image2, 1161QImage& OImageEffect::blend(QImage &image1, QImage &image2,
1182 QImage &blendImage, RGBComponent channel) 1162 QImage &blendImage, RGBComponent channel)
1183{ 1163{
1184 if (image1.width() == 0 || image1.height() == 0 || 1164 if (image1.width() == 0 || image1.height() == 0 ||
1185 image2.width() == 0 || image2.height() == 0 || 1165 image2.width() == 0 || image2.height() == 0 ||
1186 blendImage.width() == 0 || blendImage.height() == 0) { 1166 blendImage.width() == 0 || blendImage.height() == 0) {
1187#ifndef NDEBUG 1167 qDebug( "OImageEffect::blend effect invalid image" );
1188 cerr << "OImageEffect::blend effect invalid image" << endl; 1168 return image1;
1189#endif
1190 return image1;
1191 } 1169 }
1192 1170
1193 int r, g, b; 1171 int r, g, b;
1194 int ind1, ind2, ind3; 1172 int ind1, ind2, ind3;
1195 1173
1196 unsigned int x1, x2, x3, y1, y2, y3; 1174 unsigned int x1, x2, x3, y1, y2, y3;
1197 unsigned int a; 1175 unsigned int a;
1198 1176
1199 register int x, y; 1177 register int x, y;
1200 1178
1201 // for image1 and image2, we only handle depth 32 1179 // for image1 and image2, we only handle depth 32
1202 if (image1.depth()<32) image1 = image1.convertDepth(32); 1180 if (image1.depth()<32) image1 = image1.convertDepth(32);
1203 if (image2.depth()<32) image2 = image2.convertDepth(32); 1181 if (image2.depth()<32) image2 = image2.convertDepth(32);
1204 1182
1205 // for blendImage, we handle depth 8 and 32 1183 // for blendImage, we handle depth 8 and 32
1206 if (blendImage.depth()<8) blendImage = blendImage.convertDepth(8); 1184 if (blendImage.depth()<8) blendImage = blendImage.convertDepth(8);
1207 1185
1208 unsigned int *colorTable3 = (blendImage.depth()==8) ? 1186 unsigned int *colorTable3 = (blendImage.depth()==8) ?
1209 blendImage.colorTable():0; 1187 blendImage.colorTable():0;
1210 1188
1211 unsigned int *data1 = (unsigned int *)image1.bits(); 1189 unsigned int *data1 = (unsigned int *)image1.bits();
1212 unsigned int *data2 = (unsigned int *)image2.bits(); 1190 unsigned int *data2 = (unsigned int *)image2.bits();
1213 unsigned int *data3 = (unsigned int *)blendImage.bits(); 1191 unsigned int *data3 = (unsigned int *)blendImage.bits();
1214 unsigned char *data3b = (unsigned char *)blendImage.bits(); 1192 unsigned char *data3b = (unsigned char *)blendImage.bits();
1215 unsigned int color3; 1193 unsigned int color3;
1216 1194
1217 x1 = image1.width(); y1 = image1.height(); 1195 x1 = image1.width(); y1 = image1.height();
1218 x2 = image2.width(); y2 = image2.height(); 1196 x2 = image2.width(); y2 = image2.height();
1219 x3 = blendImage.width(); y3 = blendImage.height(); 1197 x3 = blendImage.width(); y3 = blendImage.height();
1220 1198
1221 for (y = 0; y < (int)y1; y++) { 1199 for (y = 0; y < (int)y1; y++) {
1222 ind1 = x1*y; 1200 ind1 = x1*y;
1223 ind2 = x2*(y%y2); 1201 ind2 = x2*(y%y2);
1224 ind3 = x3*(y%y3); 1202 ind3 = x3*(y%y3);
1225 1203
1226 x=0; 1204 x=0;
1227 while(x < (int)x1) { 1205 while(x < (int)x1) {
1228 color3 = (colorTable3) ? colorTable3[data3b[ind3]] : data3[ind3]; 1206 color3 = (colorTable3) ? colorTable3[data3b[ind3]] : data3[ind3];
1229 1207
1230 a = (channel == Red) ? qRed(color3) : 1208 a = (channel == Red) ? qRed(color3) :
1231 (channel == Green) ? qGreen(color3) : 1209 (channel == Green) ? qGreen(color3) :
1232 (channel == Blue) ? qBlue(color3) : qGray(color3); 1210 (channel == Blue) ? qBlue(color3) : qGray(color3);
1233 1211
1234 r = (a*qRed(data1[ind1]) + (256-a)*qRed(data2[ind2]))/256; 1212 r = (a*qRed(data1[ind1]) + (256-a)*qRed(data2[ind2]))/256;
1235 g = (a*qGreen(data1[ind1]) + (256-a)*qGreen(data2[ind2]))/256; 1213 g = (a*qGreen(data1[ind1]) + (256-a)*qGreen(data2[ind2]))/256;
1236 b = (a*qBlue(data1[ind1]) + (256-a)*qBlue(data2[ind2]))/256; 1214 b = (a*qBlue(data1[ind1]) + (256-a)*qBlue(data2[ind2]))/256;
1237 1215
1238 a = qAlpha(data1[ind1]); 1216 a = qAlpha(data1[ind1]);
1239 data1[ind1] = qRgba(r, g, b, a); 1217 data1[ind1] = qRgba(r, g, b, a);
1240 1218
1241 ind1++; ind2++; ind3++; x++; 1219 ind1++; ind2++; ind3++; x++;
1242 if ( (x%x2) ==0) ind2 -= x2; 1220 if ( (x%x2) ==0) ind2 -= x2;
1243 if ( (x%x3) ==0) ind3 -= x3; 1221 if ( (x%x3) ==0) ind3 -= x3;
1244 } 1222 }
1245 } 1223 }
1246 return image1; 1224 return image1;
1247} 1225}
1248 1226
1249 1227
1250//====================================================================== 1228//======================================================================
1251// 1229//
1252// Hash effects 1230// Hash effects
1253// 1231//
1254//====================================================================== 1232//======================================================================
1255 1233
1256unsigned int OImageEffect::lHash(unsigned int c) 1234unsigned int OImageEffect::lHash(unsigned int c)
1257{ 1235{
1258 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c); 1236 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c);
1259 unsigned char nr, ng, nb; 1237 unsigned char nr, ng, nb;
1260 nr =(r >> 1) + (r >> 2); nr = nr > r ? 0 : nr; 1238 nr =(r >> 1) + (r >> 2); nr = nr > r ? 0 : nr;
1261 ng =(g >> 1) + (g >> 2); ng = ng > g ? 0 : ng; 1239 ng =(g >> 1) + (g >> 2); ng = ng > g ? 0 : ng;
1262 nb =(b >> 1) + (b >> 2); nb = nb > b ? 0 : nb; 1240 nb =(b >> 1) + (b >> 2); nb = nb > b ? 0 : nb;
1263 1241
1264 return qRgba(nr, ng, nb, a); 1242 return qRgba(nr, ng, nb, a);
1265} 1243}
1266 1244
1267 1245
1268// ----------------------------------------------------------------------------- 1246// -----------------------------------------------------------------------------
1269 1247
1270unsigned int OImageEffect::uHash(unsigned int c) 1248unsigned int OImageEffect::uHash(unsigned int c)
1271{ 1249{
1272 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c); 1250 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c);
1273 unsigned char nr, ng, nb; 1251 unsigned char nr, ng, nb;
1274 nr = r + (r >> 3); nr = nr < r ? ~0 : nr; 1252 nr = r + (r >> 3); nr = nr < r ? ~0 : nr;
1275 ng = g + (g >> 3); ng = ng < g ? ~0 : ng; 1253 ng = g + (g >> 3); ng = ng < g ? ~0 : ng;
1276 nb = b + (b >> 3); nb = nb < b ? ~0 : nb; 1254 nb = b + (b >> 3); nb = nb < b ? ~0 : nb;
1277 1255
1278 return qRgba(nr, ng, nb, a); 1256 return qRgba(nr, ng, nb, a);
1279} 1257}
1280 1258
1281 1259
1282// ----------------------------------------------------------------------------- 1260// -----------------------------------------------------------------------------
1283 1261
1284QImage& OImageEffect::hash(QImage &image, Lighting lite, unsigned int spacing) 1262QImage& OImageEffect::hash(QImage &image, Lighting lite, unsigned int spacing)
1285{ 1263{
1286 if (image.width() == 0 || image.height() == 0) { 1264 if (image.width() == 0 || image.height() == 0) {
1287#ifndef NDEBUG 1265 qDebug( "OImageEffect::hash effect invalid image" );
1288 cerr << "OImageEffect::hash effect invalid image" << endl; 1266 return image;
1289#endif
1290 return image;
1291 } 1267 }
1292 1268
1293 register int x, y; 1269 register int x, y;
1294 unsigned int *data = (unsigned int *)image.bits(); 1270 unsigned int *data = (unsigned int *)image.bits();
1295 unsigned int ind; 1271 unsigned int ind;
1296 1272
1297 //CT no need to do it if not enough space 1273 //CT no need to do it if not enough space
1298 if ((lite == NorthLite || 1274 if ((lite == NorthLite ||
1299 lite == SouthLite)&& 1275 lite == SouthLite)&&
1300 (unsigned)image.height() < 2+spacing) return image; 1276 (unsigned)image.height() < 2+spacing) return image;
1301 if ((lite == EastLite || 1277 if ((lite == EastLite ||
1302 lite == WestLite)&& 1278 lite == WestLite)&&
1303 (unsigned)image.height() < 2+spacing) return image; 1279 (unsigned)image.height() < 2+spacing) return image;
1304 1280
1305 if (lite == NorthLite || lite == SouthLite) { 1281 if (lite == NorthLite || lite == SouthLite) {
1306 for (y = 0 ; y < image.height(); y = y + 2 + spacing) { 1282 for (y = 0 ; y < image.height(); y = y + 2 + spacing) {
1307 for (x = 0; x < image.width(); x++) { 1283 for (x = 0; x < image.width(); x++) {
1308 ind = x + image.width() * y; 1284 ind = x + image.width() * y;
1309 data[ind] = lite==NorthLite?uHash(data[ind]):lHash(data[ind]); 1285 data[ind] = lite==NorthLite?uHash(data[ind]):lHash(data[ind]);
1310 1286
1311 ind = ind + image.width(); 1287 ind = ind + image.width();
1312 data[ind] = lite==NorthLite?lHash(data[ind]):uHash(data[ind]); 1288 data[ind] = lite==NorthLite?lHash(data[ind]):uHash(data[ind]);
1313 } 1289 }
1314 } 1290 }
1315 } 1291 }
1316 1292
1317 else if (lite == EastLite || lite == WestLite) { 1293 else if (lite == EastLite || lite == WestLite) {
1318 for (y = 0 ; y < image.height(); y++) { 1294 for (y = 0 ; y < image.height(); y++) {
1319 for (x = 0; x < image.width(); x = x + 2 + spacing) { 1295 for (x = 0; x < image.width(); x = x + 2 + spacing) {
1320 ind = x + image.width() * y; 1296 ind = x + image.width() * y;
1321 data[ind] = lite==EastLite?uHash(data[ind]):lHash(data[ind]); 1297 data[ind] = lite==EastLite?uHash(data[ind]):lHash(data[ind]);
1322 1298
1323 ind++; 1299 ind++;
1324 data[ind] = lite==EastLite?lHash(data[ind]):uHash(data[ind]); 1300 data[ind] = lite==EastLite?lHash(data[ind]):uHash(data[ind]);
1325 } 1301 }
1326 } 1302 }
1327 } 1303 }
1328 1304
1329 else if (lite == NWLite || lite == SELite) { 1305 else if (lite == NWLite || lite == SELite) {
1330 for (y = 0 ; y < image.height(); y++) { 1306 for (y = 0 ; y < image.height(); y++) {
1331 for (x = 0; 1307 for (x = 0;
1332 x < (int)(image.width() - ((y & 1)? 1 : 0) * spacing); 1308 x < (int)(image.width() - ((y & 1)? 1 : 0) * spacing);
1333 x = x + 2 + spacing) { 1309 x = x + 2 + spacing) {
1334 ind = x + image.width() * y + ((y & 1)? 1 : 0); 1310 ind = x + image.width() * y + ((y & 1)? 1 : 0);
1335 data[ind] = lite==NWLite?uHash(data[ind]):lHash(data[ind]); 1311 data[ind] = lite==NWLite?uHash(data[ind]):lHash(data[ind]);
1336 1312
1337 ind++; 1313 ind++;
1338 data[ind] = lite==NWLite?lHash(data[ind]):uHash(data[ind]); 1314 data[ind] = lite==NWLite?lHash(data[ind]):uHash(data[ind]);
1339 } 1315 }
1340 } 1316 }
1341 } 1317 }
1342 1318
1343 else if (lite == SWLite || lite == NELite) { 1319 else if (lite == SWLite || lite == NELite) {
1344 for (y = 0 ; y < image.height(); y++) { 1320 for (y = 0 ; y < image.height(); y++) {
1345 for (x = 0 + ((y & 1)? 1 : 0); x < image.width(); x = x + 2 + spacing) { 1321 for (x = 0 + ((y & 1)? 1 : 0); x < image.width(); x = x + 2 + spacing) {
1346 ind = x + image.width() * y - ((y & 1)? 1 : 0); 1322 ind = x + image.width() * y - ((y & 1)? 1 : 0);
1347 data[ind] = lite==SWLite?uHash(data[ind]):lHash(data[ind]); 1323 data[ind] = lite==SWLite?uHash(data[ind]):lHash(data[ind]);
1348 1324
1349 ind++; 1325 ind++;
1350 data[ind] = lite==SWLite?lHash(data[ind]):uHash(data[ind]); 1326 data[ind] = lite==SWLite?lHash(data[ind]):uHash(data[ind]);
1351 } 1327 }
1352 } 1328 }
1353 } 1329 }
1354 1330
1355 return image; 1331 return image;
1356} 1332}
1357 1333
1358 1334
1359//====================================================================== 1335//======================================================================
1360// 1336//
1361// Flatten effects 1337// Flatten effects
1362// 1338//
1363//====================================================================== 1339//======================================================================
1364 1340
1365QImage& OImageEffect::flatten(QImage &img, const QColor &ca, 1341QImage& OImageEffect::flatten(QImage &img, const QColor &ca,
1366 const QColor &cb, int ncols) 1342 const QColor &cb, int ncols)
1367{ 1343{
1368 if (img.width() == 0 || img.height() == 0) 1344 if (img.width() == 0 || img.height() == 0)
1369 return img; 1345 return img;
1370 1346
1371 // a bitmap is easy... 1347 // a bitmap is easy...
1372 if (img.depth() == 1) { 1348 if (img.depth() == 1) {
1373 img.setColor(0, ca.rgb()); 1349 img.setColor(0, ca.rgb());
1374 img.setColor(1, cb.rgb()); 1350 img.setColor(1, cb.rgb());
1375 return img; 1351 return img;
1376 } 1352 }
1377 1353
1378 int r1 = ca.red(); int r2 = cb.red(); 1354 int r1 = ca.red(); int r2 = cb.red();
1379 int g1 = ca.green(); int g2 = cb.green(); 1355 int g1 = ca.green(); int g2 = cb.green();
1380 int b1 = ca.blue(); int b2 = cb.blue(); 1356 int b1 = ca.blue(); int b2 = cb.blue();
1381 int min = 0, max = 255; 1357 int min = 0, max = 255;
1382 1358
1383 QRgb col; 1359 QRgb col;
1384 1360
1385 // Get minimum and maximum greylevel. 1361 // Get minimum and maximum greylevel.
1386 if (img.numColors()) { 1362 if (img.numColors()) {
1387 // pseudocolor 1363 // pseudocolor
1388 for (int i = 0; i < img.numColors(); i++) { 1364 for (int i = 0; i < img.numColors(); i++) {
1389 col = img.color(i); 1365 col = img.color(i);
1390 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3; 1366 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3;
1391 min = QMIN(min, mean); 1367 min = QMIN(min, mean);
1392 max = QMAX(max, mean); 1368 max = QMAX(max, mean);
1393 } 1369 }
1394 } else { 1370 } else {
1395 // truecolor 1371 // truecolor
1396 for (int y=0; y < img.height(); y++) 1372 for (int y=0; y < img.height(); y++)
1397 for (int x=0; x < img.width(); x++) { 1373 for (int x=0; x < img.width(); x++) {
1398 col = img.pixel(x, y); 1374 col = img.pixel(x, y);
1399 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3; 1375 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3;
1400 min = QMIN(min, mean); 1376 min = QMIN(min, mean);
1401 max = QMAX(max, mean); 1377 max = QMAX(max, mean);
1402 } 1378 }
1403 } 1379 }
1404 1380
1405 // Conversion factors 1381 // Conversion factors
1406 float sr = ((float) r2 - r1) / (max - min); 1382 float sr = ((float) r2 - r1) / (max - min);
1407 float sg = ((float) g2 - g1) / (max - min); 1383 float sg = ((float) g2 - g1) / (max - min);
1408 float sb = ((float) b2 - b1) / (max - min); 1384 float sb = ((float) b2 - b1) / (max - min);
1409 1385
1410 1386
1411 // Repaint the image 1387 // Repaint the image
1412 if (img.numColors()) { 1388 if (img.numColors()) {
1413 for (int i=0; i < img.numColors(); i++) { 1389 for (int i=0; i < img.numColors(); i++) {
1414 col = img.color(i); 1390 col = img.color(i);
1415 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3; 1391 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3;
1416 int r = (int) (sr * (mean - min) + r1 + 0.5); 1392 int r = (int) (sr * (mean - min) + r1 + 0.5);
1417 int g = (int) (sg * (mean - min) + g1 + 0.5); 1393 int g = (int) (sg * (mean - min) + g1 + 0.5);
1418 int b = (int) (sb * (mean - min) + b1 + 0.5); 1394 int b = (int) (sb * (mean - min) + b1 + 0.5);
@@ -1669,260 +1645,258 @@ QImage& OImageEffect::dither(QImage &img, const QColor *palette, int size)
1669 if (img.width() == 0 || img.height() == 0 || 1645 if (img.width() == 0 || img.height() == 0 ||
1670 palette == 0 || img.depth() <= 8) 1646 palette == 0 || img.depth() <= 8)
1671 return img; 1647 return img;
1672 1648
1673 QImage dImage( img.width(), img.height(), 8, size ); 1649 QImage dImage( img.width(), img.height(), 8, size );
1674 int i; 1650 int i;
1675 1651
1676 dImage.setNumColors( size ); 1652 dImage.setNumColors( size );
1677 for ( i = 0; i < size; i++ ) 1653 for ( i = 0; i < size; i++ )
1678 dImage.setColor( i, palette[ i ].rgb() ); 1654 dImage.setColor( i, palette[ i ].rgb() );
1679 1655
1680 int *rerr1 = new int [ img.width() * 2 ]; 1656 int *rerr1 = new int [ img.width() * 2 ];
1681 int *gerr1 = new int [ img.width() * 2 ]; 1657 int *gerr1 = new int [ img.width() * 2 ];
1682 int *berr1 = new int [ img.width() * 2 ]; 1658 int *berr1 = new int [ img.width() * 2 ];
1683 1659
1684 memset( rerr1, 0, sizeof( int ) * img.width() * 2 ); 1660 memset( rerr1, 0, sizeof( int ) * img.width() * 2 );
1685 memset( gerr1, 0, sizeof( int ) * img.width() * 2 ); 1661 memset( gerr1, 0, sizeof( int ) * img.width() * 2 );
1686 memset( berr1, 0, sizeof( int ) * img.width() * 2 ); 1662 memset( berr1, 0, sizeof( int ) * img.width() * 2 );
1687 1663
1688 int *rerr2 = rerr1 + img.width(); 1664 int *rerr2 = rerr1 + img.width();
1689 int *gerr2 = gerr1 + img.width(); 1665 int *gerr2 = gerr1 + img.width();
1690 int *berr2 = berr1 + img.width(); 1666 int *berr2 = berr1 + img.width();
1691 1667
1692 for ( int j = 0; j < img.height(); j++ ) 1668 for ( int j = 0; j < img.height(); j++ )
1693 { 1669 {
1694 uint *ip = (uint * )img.scanLine( j ); 1670 uint *ip = (uint * )img.scanLine( j );
1695 uchar *dp = dImage.scanLine( j ); 1671 uchar *dp = dImage.scanLine( j );
1696 1672
1697 for ( i = 0; i < img.width(); i++ ) 1673 for ( i = 0; i < img.width(); i++ )
1698 { 1674 {
1699 rerr1[i] = rerr2[i] + qRed( *ip ); 1675 rerr1[i] = rerr2[i] + qRed( *ip );
1700 rerr2[i] = 0; 1676 rerr2[i] = 0;
1701 gerr1[i] = gerr2[i] + qGreen( *ip ); 1677 gerr1[i] = gerr2[i] + qGreen( *ip );
1702 gerr2[i] = 0; 1678 gerr2[i] = 0;
1703 berr1[i] = berr2[i] + qBlue( *ip ); 1679 berr1[i] = berr2[i] + qBlue( *ip );
1704 berr2[i] = 0; 1680 berr2[i] = 0;
1705 ip++; 1681 ip++;
1706 } 1682 }
1707 1683
1708 *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size ); 1684 *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size );
1709 1685
1710 for ( i = 1; i < img.width()-1; i++ ) 1686 for ( i = 1; i < img.width()-1; i++ )
1711 { 1687 {
1712 int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); 1688 int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size );
1713 *dp = indx; 1689 *dp = indx;
1714 1690
1715 int rerr = rerr1[i]; 1691 int rerr = rerr1[i];
1716 rerr -= palette[indx].red(); 1692 rerr -= palette[indx].red();
1717 int gerr = gerr1[i]; 1693 int gerr = gerr1[i];
1718 gerr -= palette[indx].green(); 1694 gerr -= palette[indx].green();
1719 int berr = berr1[i]; 1695 int berr = berr1[i];
1720 berr -= palette[indx].blue(); 1696 berr -= palette[indx].blue();
1721 1697
1722 // diffuse red error 1698 // diffuse red error
1723 rerr1[ i+1 ] += ( rerr * 7 ) >> 4; 1699 rerr1[ i+1 ] += ( rerr * 7 ) >> 4;
1724 rerr2[ i-1 ] += ( rerr * 3 ) >> 4; 1700 rerr2[ i-1 ] += ( rerr * 3 ) >> 4;
1725 rerr2[ i ] += ( rerr * 5 ) >> 4; 1701 rerr2[ i ] += ( rerr * 5 ) >> 4;
1726 rerr2[ i+1 ] += ( rerr ) >> 4; 1702 rerr2[ i+1 ] += ( rerr ) >> 4;
1727 1703
1728 // diffuse green error 1704 // diffuse green error
1729 gerr1[ i+1 ] += ( gerr * 7 ) >> 4; 1705 gerr1[ i+1 ] += ( gerr * 7 ) >> 4;
1730 gerr2[ i-1 ] += ( gerr * 3 ) >> 4; 1706 gerr2[ i-1 ] += ( gerr * 3 ) >> 4;
1731 gerr2[ i ] += ( gerr * 5 ) >> 4; 1707 gerr2[ i ] += ( gerr * 5 ) >> 4;
1732 gerr2[ i+1 ] += ( gerr ) >> 4; 1708 gerr2[ i+1 ] += ( gerr ) >> 4;
1733 1709
1734 // diffuse red error 1710 // diffuse red error
1735 berr1[ i+1 ] += ( berr * 7 ) >> 4; 1711 berr1[ i+1 ] += ( berr * 7 ) >> 4;
1736 berr2[ i-1 ] += ( berr * 3 ) >> 4; 1712 berr2[ i-1 ] += ( berr * 3 ) >> 4;
1737 berr2[ i ] += ( berr * 5 ) >> 4; 1713 berr2[ i ] += ( berr * 5 ) >> 4;
1738 berr2[ i+1 ] += ( berr ) >> 4; 1714 berr2[ i+1 ] += ( berr ) >> 4;
1739 1715
1740 dp++; 1716 dp++;
1741 } 1717 }
1742 1718
1743 *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); 1719 *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size );
1744 } 1720 }
1745 1721
1746 delete [] rerr1; 1722 delete [] rerr1;
1747 delete [] gerr1; 1723 delete [] gerr1;
1748 delete [] berr1; 1724 delete [] berr1;
1749 1725
1750 img = dImage; 1726 img = dImage;
1751 return img; 1727 return img;
1752} 1728}
1753 1729
1754int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size ) 1730int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size )
1755{ 1731{
1756 if (palette == 0) 1732 if (palette == 0)
1757 return 0; 1733 return 0;
1758 1734
1759 int dr = palette[0].red() - r; 1735 int dr = palette[0].red() - r;
1760 int dg = palette[0].green() - g; 1736 int dg = palette[0].green() - g;
1761 int db = palette[0].blue() - b; 1737 int db = palette[0].blue() - b;
1762 1738
1763 int minDist = dr*dr + dg*dg + db*db; 1739 int minDist = dr*dr + dg*dg + db*db;
1764 int nearest = 0; 1740 int nearest = 0;
1765 1741
1766 for (int i = 1; i < size; i++ ) 1742 for (int i = 1; i < size; i++ )
1767 { 1743 {
1768 dr = palette[i].red() - r; 1744 dr = palette[i].red() - r;
1769 dg = palette[i].green() - g; 1745 dg = palette[i].green() - g;
1770 db = palette[i].blue() - b; 1746 db = palette[i].blue() - b;
1771 1747
1772 int dist = dr*dr + dg*dg + db*db; 1748 int dist = dr*dr + dg*dg + db*db;
1773 1749
1774 if ( dist < minDist ) 1750 if ( dist < minDist )
1775 { 1751 {
1776 minDist = dist; 1752 minDist = dist;
1777 nearest = i; 1753 nearest = i;
1778 } 1754 }
1779 } 1755 }
1780 1756
1781 return nearest; 1757 return nearest;
1782} 1758}
1783 1759
1784bool OImageEffect::blend( 1760bool OImageEffect::blend(
1785 const QImage & upper, 1761 const QImage & upper,
1786 const QImage & lower, 1762 const QImage & lower,
1787 QImage & output 1763 QImage & output
1788) 1764)
1789{ 1765{
1790 if ( 1766 if (
1791 upper.width() > lower.width() || 1767 upper.width() > lower.width() ||
1792 upper.height() > lower.height() || 1768 upper.height() > lower.height() ||
1793 upper.depth() != 32 || 1769 upper.depth() != 32 ||
1794 lower.depth() != 32 1770 lower.depth() != 32
1795 ) 1771 )
1796 { 1772 {
1797#ifndef NDEBUG 1773 qDebug( "OImageEffect::blend : Sizes not correct" );
1798 cerr << "OImageEffect::blend : Sizes not correct\n" ; 1774 return false;
1799#endif
1800 return false;
1801 } 1775 }
1802 1776
1803 output = lower.copy(); 1777 output = lower.copy();
1804 1778
1805 register uchar *i, *o; 1779 register uchar *i, *o;
1806 register int a; 1780 register int a;
1807 register int col; 1781 register int col;
1808 register int w = upper.width(); 1782 register int w = upper.width();
1809 int row(upper.height() - 1); 1783 int row(upper.height() - 1);
1810 1784
1811 do { 1785 do {
1812 1786
1813 i = upper.scanLine(row); 1787 i = upper.scanLine(row);
1814 o = output.scanLine(row); 1788 o = output.scanLine(row);
1815 1789
1816 col = w << 2; 1790 col = w << 2;
1817 --col; 1791 --col;
1818 1792
1819 do { 1793 do {
1820 1794
1821 while (!(a = i[col]) && (col != 3)) { 1795 while (!(a = i[col]) && (col != 3)) {
1822 --col; --col; --col; --col; 1796 --col; --col; --col; --col;
1823 } 1797 }
1824 1798
1825 --col; 1799 --col;
1826 o[col] += ((i[col] - o[col]) * a) >> 8; 1800 o[col] += ((i[col] - o[col]) * a) >> 8;
1827 1801
1828 --col; 1802 --col;
1829 o[col] += ((i[col] - o[col]) * a) >> 8; 1803 o[col] += ((i[col] - o[col]) * a) >> 8;
1830 1804
1831 --col; 1805 --col;
1832 o[col] += ((i[col] - o[col]) * a) >> 8; 1806 o[col] += ((i[col] - o[col]) * a) >> 8;
1833 1807
1834 } while (col--); 1808 } while (col--);
1835 1809
1836 } while (row--); 1810 } while (row--);
1837 1811
1838 return true; 1812 return true;
1839} 1813}
1840 1814
1841#if 0 1815#if 0
1842// Not yet... 1816// Not yet...
1843bool OImageEffect::blend( 1817bool OImageEffect::blend(
1844 const QImage & upper, 1818 const QImage & upper,
1845 const QImage & lower, 1819 const QImage & lower,
1846 QImage & output, 1820 QImage & output,
1847 const QRect & destRect 1821 const QRect & destRect
1848) 1822)
1849{ 1823{
1850 output = lower.copy(); 1824 output = lower.copy();
1851 return output; 1825 return output;
1852} 1826}
1853 1827
1854#endif 1828#endif
1855 1829
1856bool OImageEffect::blend( 1830bool OImageEffect::blend(
1857 int &x, int &y, 1831 int &x, int &y,
1858 const QImage & upper, 1832 const QImage & upper,
1859 const QImage & lower, 1833 const QImage & lower,
1860 QImage & output 1834 QImage & output
1861) 1835)
1862{ 1836{
1863 int cx=0, cy=0, cw=upper.width(), ch=upper.height(); 1837 int cx=0, cy=0, cw=upper.width(), ch=upper.height();
1864 1838
1865 if ( upper.width() + x > lower.width() || 1839 if ( upper.width() + x > lower.width() ||
1866 upper.height() + y > lower.height() || 1840 upper.height() + y > lower.height() ||
1867 x < 0 || y < 0 || 1841 x < 0 || y < 0 ||
1868 upper.depth() != 32 || lower.depth() != 32 ) 1842 upper.depth() != 32 || lower.depth() != 32 )
1869 { 1843 {
1870 if ( x > lower.width() || y > lower.height() ) return false; 1844 if ( x > lower.width() || y > lower.height() ) return false;
1871 if ( upper.width()<=0 || upper.height() <= 0 ) return false; 1845 if ( upper.width()<=0 || upper.height() <= 0 ) return false;
1872 if ( lower.width()<=0 || lower.height() <= 0 ) return false; 1846 if ( lower.width()<=0 || lower.height() <= 0 ) return false;
1873 1847
1874 if (x<0) {cx=-x; cw+=x; x=0; }; 1848 if (x<0) {cx=-x; cw+=x; x=0; };
1875 if (cw + x > lower.width()) { cw=lower.width()-x; }; 1849 if (cw + x > lower.width()) { cw=lower.width()-x; };
1876 if (y<0) {cy=-y; ch+=y; y=0; }; 1850 if (y<0) {cy=-y; ch+=y; y=0; };
1877 if (ch + y > lower.height()) { ch=lower.height()-y; }; 1851 if (ch + y > lower.height()) { ch=lower.height()-y; };
1878 1852
1879 if ( cx >= upper.width() || cy >= upper.height() ) return true; 1853 if ( cx >= upper.width() || cy >= upper.height() ) return true;
1880 if ( cw <= 0 || ch <= 0 ) return true; 1854 if ( cw <= 0 || ch <= 0 ) return true;
1881 } 1855 }
1882 1856
1883 output.create(cw,ch,32); 1857 output.create(cw,ch,32);
1884// output.setAlphaBuffer(true); // I should do some benchmarks to see if 1858// output.setAlphaBuffer(true); // I should do some benchmarks to see if
1885 // this is worth the effort 1859 // this is worth the effort
1886 1860
1887 register QRgb *i, *o, *b; 1861 register QRgb *i, *o, *b;
1888 1862
1889 register int a; 1863 register int a;
1890 register int j,k; 1864 register int j,k;
1891 for (j=0; j<ch; j++) 1865 for (j=0; j<ch; j++)
1892 { 1866 {
1893 b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]); 1867 b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]);
1894 i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]); 1868 i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]);
1895 o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]); 1869 o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]);
1896 1870
1897 k=cw-1; 1871 k=cw-1;
1898 --b; --i; --o; 1872 --b; --i; --o;
1899 do 1873 do
1900 { 1874 {
1901 while ( !(a=qAlpha(*i)) && k>0 ) 1875 while ( !(a=qAlpha(*i)) && k>0 )
1902 { 1876 {
1903 i--; 1877 i--;
1904 //*o=0; 1878 //*o=0;
1905 *o=*b; 1879 *o=*b;
1906 --o; --b; 1880 --o; --b;
1907 k--; 1881 k--;
1908 }; 1882 };
1909// *o=0xFF; 1883// *o=0xFF;
1910 *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8), 1884 *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8),
1911 qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8), 1885 qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8),
1912 qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8)); 1886 qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8));
1913 --i; --o; --b; 1887 --i; --o; --b;
1914 } while (k--); 1888 } while (k--);
1915 } 1889 }
1916 1890
1917 return true; 1891 return true;
1918} 1892}
1919 1893
1920bool OImageEffect::blendOnLower( 1894bool OImageEffect::blendOnLower(
1921 int x, int y, 1895 int x, int y,
1922 const QImage & upper, 1896 const QImage & upper,
1923 const QImage & lower 1897 const QImage & lower
1924) 1898)
1925{ 1899{
1926 int cx=0, cy=0, cw=upper.width(), ch=upper.height(); 1900 int cx=0, cy=0, cw=upper.width(), ch=upper.height();
1927 1901
1928 if ( upper.depth() != 32 || lower.depth() != 32 ) return false; 1902 if ( upper.depth() != 32 || lower.depth() != 32 ) return false;