summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2003-09-16 13:07:56 (UTC)
committer mickeyl <mickeyl>2003-09-16 13:07:56 (UTC)
commit9cd1a5708fa9f10e391bd18cbf1f5800cdc76851 (patch) (unidiff)
tree65404702ea418b9270158a941b408870d981eca4
parent81171716bb686e709f27fbbc0931740aa9d9462a (diff)
downloadopie-9cd1a5708fa9f10e391bd18cbf1f5800cdc76851.zip
opie-9cd1a5708fa9f10e391bd18cbf1f5800cdc76851.tar.gz
opie-9cd1a5708fa9f10e391bd18cbf1f5800cdc76851.tar.bz2
remove unneccessary #include
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opieui/oimageeffect.cpp1
1 files changed, 0 insertions, 1 deletions
diff --git a/libopie2/opieui/oimageeffect.cpp b/libopie2/opieui/oimageeffect.cpp
index 2855da6..01e7c6f 100644
--- a/libopie2/opieui/oimageeffect.cpp
+++ b/libopie2/opieui/oimageeffect.cpp
@@ -1,804 +1,803 @@
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>
37 36
38#include "oimageeffect.h" 37#include "oimageeffect.h"
39 38
40#define MaxRGB 255L 39#define MaxRGB 255L
41#define DegreesToRadians(x) ((x)*M_PI/180.0) 40#define DegreesToRadians(x) ((x)*M_PI/180.0)
42 41
43using namespace std; 42using namespace std;
44 43
45inline unsigned int intensityValue(unsigned int color) 44inline unsigned int intensityValue(unsigned int color)
46{ 45{
47 return((unsigned int)((0.299*qRed(color) + 46 return((unsigned int)((0.299*qRed(color) +
48 0.587*qGreen(color) + 47 0.587*qGreen(color) +
49 0.1140000000000001*qBlue(color)))); 48 0.1140000000000001*qBlue(color))));
50} 49}
51 50
52//====================================================================== 51//======================================================================
53// 52//
54// Gradient effects 53// Gradient effects
55// 54//
56//====================================================================== 55//======================================================================
57 56
58QImage OImageEffect::gradient(const QSize &size, const QColor &ca, 57QImage OImageEffect::gradient(const QSize &size, const QColor &ca,
59 const QColor &cb, GradientType eff, int ncols) 58 const QColor &cb, GradientType eff, int ncols)
60{ 59{
61 int rDiff, gDiff, bDiff; 60 int rDiff, gDiff, bDiff;
62 int rca, gca, bca, rcb, gcb, bcb; 61 int rca, gca, bca, rcb, gcb, bcb;
63 62
64 QImage image(size, 32); 63 QImage image(size, 32);
65 64
66 if (size.width() == 0 || size.height() == 0) { 65 if (size.width() == 0 || size.height() == 0) {
67 qDebug( "WARNING: OImageEffect::gradient: invalid image" ); 66 qDebug( "WARNING: OImageEffect::gradient: invalid image" );
68 return image; 67 return image;
69 } 68 }
70 69
71 register int x, y; 70 register int x, y;
72 71
73 rDiff = (rcb = cb.red()) - (rca = ca.red()); 72 rDiff = (rcb = cb.red()) - (rca = ca.red());
74 gDiff = (gcb = cb.green()) - (gca = ca.green()); 73 gDiff = (gcb = cb.green()) - (gca = ca.green());
75 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 74 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
76 75
77 if( eff == VerticalGradient || eff == HorizontalGradient ){ 76 if( eff == VerticalGradient || eff == HorizontalGradient ){
78 77
79 uint *p; 78 uint *p;
80 uint rgb; 79 uint rgb;
81 80
82 register int rl = rca << 16; 81 register int rl = rca << 16;
83 register int gl = gca << 16; 82 register int gl = gca << 16;
84 register int bl = bca << 16; 83 register int bl = bca << 16;
85 84
86 if( eff == VerticalGradient ) { 85 if( eff == VerticalGradient ) {
87 86
88 int rcdelta = ((1<<16) / size.height()) * rDiff; 87 int rcdelta = ((1<<16) / size.height()) * rDiff;
89 int gcdelta = ((1<<16) / size.height()) * gDiff; 88 int gcdelta = ((1<<16) / size.height()) * gDiff;
90 int bcdelta = ((1<<16) / size.height()) * bDiff; 89 int bcdelta = ((1<<16) / size.height()) * bDiff;
91 90
92 for ( y = 0; y < size.height(); y++ ) { 91 for ( y = 0; y < size.height(); y++ ) {
93 p = (uint *) image.scanLine(y); 92 p = (uint *) image.scanLine(y);
94 93
95 rl += rcdelta; 94 rl += rcdelta;
96 gl += gcdelta; 95 gl += gcdelta;
97 bl += bcdelta; 96 bl += bcdelta;
98 97
99 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); 98 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) );
100 99
101 for( x = 0; x < size.width(); x++ ) { 100 for( x = 0; x < size.width(); x++ ) {
102 *p = rgb; 101 *p = rgb;
103 p++; 102 p++;
104 } 103 }
105 } 104 }
106 105
107 } 106 }
108 else { // must be HorizontalGradient 107 else { // must be HorizontalGradient
109 108
110 unsigned int *o_src = (unsigned int *)image.scanLine(0); 109 unsigned int *o_src = (unsigned int *)image.scanLine(0);
111 unsigned int *src = o_src; 110 unsigned int *src = o_src;
112 111
113 int rcdelta = ((1<<16) / size.width()) * rDiff; 112 int rcdelta = ((1<<16) / size.width()) * rDiff;
114 int gcdelta = ((1<<16) / size.width()) * gDiff; 113 int gcdelta = ((1<<16) / size.width()) * gDiff;
115 int bcdelta = ((1<<16) / size.width()) * bDiff; 114 int bcdelta = ((1<<16) / size.width()) * bDiff;
116 115
117 for( x = 0; x < size.width(); x++) { 116 for( x = 0; x < size.width(); x++) {
118 117
119 rl += rcdelta; 118 rl += rcdelta;
120 gl += gcdelta; 119 gl += gcdelta;
121 bl += bcdelta; 120 bl += bcdelta;
122 121
123 *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16)); 122 *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16));
124 } 123 }
125 124
126 src = o_src; 125 src = o_src;
127 126
128 // Believe it or not, manually copying in a for loop is faster 127 // Believe it or not, manually copying in a for loop is faster
129 // than calling memcpy for each scanline (on the order of ms...). 128 // than calling memcpy for each scanline (on the order of ms...).
130 // I think this is due to the function call overhead (mosfet). 129 // I think this is due to the function call overhead (mosfet).
131 130
132 for (y = 1; y < size.height(); ++y) { 131 for (y = 1; y < size.height(); ++y) {
133 132
134 p = (unsigned int *)image.scanLine(y); 133 p = (unsigned int *)image.scanLine(y);
135 src = o_src; 134 src = o_src;
136 for(x=0; x < size.width(); ++x) 135 for(x=0; x < size.width(); ++x)
137 *p++ = *src++; 136 *p++ = *src++;
138 } 137 }
139 } 138 }
140 } 139 }
141 140
142 else { 141 else {
143 142
144 float rfd, gfd, bfd; 143 float rfd, gfd, bfd;
145 float rd = rca, gd = gca, bd = bca; 144 float rd = rca, gd = gca, bd = bca;
146 145
147 unsigned char *xtable[3]; 146 unsigned char *xtable[3];
148 unsigned char *ytable[3]; 147 unsigned char *ytable[3];
149 148
150 unsigned int w = size.width(), h = size.height(); 149 unsigned int w = size.width(), h = size.height();
151 xtable[0] = new unsigned char[w]; 150 xtable[0] = new unsigned char[w];
152 xtable[1] = new unsigned char[w]; 151 xtable[1] = new unsigned char[w];
153 xtable[2] = new unsigned char[w]; 152 xtable[2] = new unsigned char[w];
154 ytable[0] = new unsigned char[h]; 153 ytable[0] = new unsigned char[h];
155 ytable[1] = new unsigned char[h]; 154 ytable[1] = new unsigned char[h];
156 ytable[2] = new unsigned char[h]; 155 ytable[2] = new unsigned char[h];
157 w*=2, h*=2; 156 w*=2, h*=2;
158 157
159 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) { 158 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) {
160 // Diagonal dgradient code inspired by BlackBox (mosfet) 159 // Diagonal dgradient code inspired by BlackBox (mosfet)
161 // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and 160 // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and
162 // Mike Cole <mike@mydot.com>. 161 // Mike Cole <mike@mydot.com>.
163 162
164 rfd = (float)rDiff/w; 163 rfd = (float)rDiff/w;
165 gfd = (float)gDiff/w; 164 gfd = (float)gDiff/w;
166 bfd = (float)bDiff/w; 165 bfd = (float)bDiff/w;
167 166
168 int dir; 167 int dir;
169 for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) { 168 for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) {
170 dir = eff == DiagonalGradient? x : size.width() - x - 1; 169 dir = eff == DiagonalGradient? x : size.width() - x - 1;
171 xtable[0][dir] = (unsigned char) rd; 170 xtable[0][dir] = (unsigned char) rd;
172 xtable[1][dir] = (unsigned char) gd; 171 xtable[1][dir] = (unsigned char) gd;
173 xtable[2][dir] = (unsigned char) bd; 172 xtable[2][dir] = (unsigned char) bd;
174 } 173 }
175 rfd = (float)rDiff/h; 174 rfd = (float)rDiff/h;
176 gfd = (float)gDiff/h; 175 gfd = (float)gDiff/h;
177 bfd = (float)bDiff/h; 176 bfd = (float)bDiff/h;
178 rd = gd = bd = 0; 177 rd = gd = bd = 0;
179 for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) { 178 for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) {
180 ytable[0][y] = (unsigned char) rd; 179 ytable[0][y] = (unsigned char) rd;
181 ytable[1][y] = (unsigned char) gd; 180 ytable[1][y] = (unsigned char) gd;
182 ytable[2][y] = (unsigned char) bd; 181 ytable[2][y] = (unsigned char) bd;
183 } 182 }
184 183
185 for (y = 0; y < size.height(); y++) { 184 for (y = 0; y < size.height(); y++) {
186 unsigned int *scanline = (unsigned int *)image.scanLine(y); 185 unsigned int *scanline = (unsigned int *)image.scanLine(y);
187 for (x = 0; x < size.width(); x++) { 186 for (x = 0; x < size.width(); x++) {
188 scanline[x] = qRgb(xtable[0][x] + ytable[0][y], 187 scanline[x] = qRgb(xtable[0][x] + ytable[0][y],
189 xtable[1][x] + ytable[1][y], 188 xtable[1][x] + ytable[1][y],
190 xtable[2][x] + ytable[2][y]); 189 xtable[2][x] + ytable[2][y]);
191 } 190 }
192 } 191 }
193 } 192 }
194 193
195 else if (eff == RectangleGradient || 194 else if (eff == RectangleGradient ||
196 eff == PyramidGradient || 195 eff == PyramidGradient ||
197 eff == PipeCrossGradient || 196 eff == PipeCrossGradient ||
198 eff == EllipticGradient) 197 eff == EllipticGradient)
199 { 198 {
200 int rSign = rDiff>0? 1: -1; 199 int rSign = rDiff>0? 1: -1;
201 int gSign = gDiff>0? 1: -1; 200 int gSign = gDiff>0? 1: -1;
202 int bSign = bDiff>0? 1: -1; 201 int bSign = bDiff>0? 1: -1;
203 202
204 rfd = (float)rDiff / size.width(); 203 rfd = (float)rDiff / size.width();
205 gfd = (float)gDiff / size.width(); 204 gfd = (float)gDiff / size.width();
206 bfd = (float)bDiff / size.width(); 205 bfd = (float)bDiff / size.width();
207 206
208 rd = (float)rDiff/2; 207 rd = (float)rDiff/2;
209 gd = (float)gDiff/2; 208 gd = (float)gDiff/2;
210 bd = (float)bDiff/2; 209 bd = (float)bDiff/2;
211 210
212 for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd) 211 for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd)
213 { 212 {
214 xtable[0][x] = (unsigned char) abs((int)rd); 213 xtable[0][x] = (unsigned char) abs((int)rd);
215 xtable[1][x] = (unsigned char) abs((int)gd); 214 xtable[1][x] = (unsigned char) abs((int)gd);
216 xtable[2][x] = (unsigned char) abs((int)bd); 215 xtable[2][x] = (unsigned char) abs((int)bd);
217 } 216 }
218 217
219 rfd = (float)rDiff/size.height(); 218 rfd = (float)rDiff/size.height();
220 gfd = (float)gDiff/size.height(); 219 gfd = (float)gDiff/size.height();
221 bfd = (float)bDiff/size.height(); 220 bfd = (float)bDiff/size.height();
222 221
223 rd = (float)rDiff/2; 222 rd = (float)rDiff/2;
224 gd = (float)gDiff/2; 223 gd = (float)gDiff/2;
225 bd = (float)bDiff/2; 224 bd = (float)bDiff/2;
226 225
227 for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd) 226 for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd)
228 { 227 {
229 ytable[0][y] = (unsigned char) abs((int)rd); 228 ytable[0][y] = (unsigned char) abs((int)rd);
230 ytable[1][y] = (unsigned char) abs((int)gd); 229 ytable[1][y] = (unsigned char) abs((int)gd);
231 ytable[2][y] = (unsigned char) abs((int)bd); 230 ytable[2][y] = (unsigned char) abs((int)bd);
232 } 231 }
233 unsigned int rgb; 232 unsigned int rgb;
234 int h = (size.height()+1)>>1; 233 int h = (size.height()+1)>>1;
235 for (y = 0; y < h; y++) { 234 for (y = 0; y < h; y++) {
236 unsigned int *sl1 = (unsigned int *)image.scanLine(y); 235 unsigned int *sl1 = (unsigned int *)image.scanLine(y);
237 unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y)); 236 unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y));
238 237
239 int w = (size.width()+1)>>1; 238 int w = (size.width()+1)>>1;
240 int x2 = size.width()-1; 239 int x2 = size.width()-1;
241 240
242 for (x = 0; x < w; x++, x2--) { 241 for (x = 0; x < w; x++, x2--) {
243 rgb = 0; 242 rgb = 0;
244 if (eff == PyramidGradient) { 243 if (eff == PyramidGradient) {
245 rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), 244 rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]),
246 gcb-gSign*(xtable[1][x]+ytable[1][y]), 245 gcb-gSign*(xtable[1][x]+ytable[1][y]),
247 bcb-bSign*(xtable[2][x]+ytable[2][y])); 246 bcb-bSign*(xtable[2][x]+ytable[2][y]));
248 } 247 }
249 if (eff == RectangleGradient) { 248 if (eff == RectangleGradient) {
250 rgb = qRgb(rcb - rSign * 249 rgb = qRgb(rcb - rSign *
251 QMAX(xtable[0][x], ytable[0][y]) * 2, 250 QMAX(xtable[0][x], ytable[0][y]) * 2,
252 gcb - gSign * 251 gcb - gSign *
253 QMAX(xtable[1][x], ytable[1][y]) * 2, 252 QMAX(xtable[1][x], ytable[1][y]) * 2,
254 bcb - bSign * 253 bcb - bSign *
255 QMAX(xtable[2][x], ytable[2][y]) * 2); 254 QMAX(xtable[2][x], ytable[2][y]) * 2);
256 } 255 }
257 if (eff == PipeCrossGradient) { 256 if (eff == PipeCrossGradient) {
258 rgb = qRgb(rcb - rSign * 257 rgb = qRgb(rcb - rSign *
259 QMIN(xtable[0][x], ytable[0][y]) * 2, 258 QMIN(xtable[0][x], ytable[0][y]) * 2,
260 gcb - gSign * 259 gcb - gSign *
261 QMIN(xtable[1][x], ytable[1][y]) * 2, 260 QMIN(xtable[1][x], ytable[1][y]) * 2,
262 bcb - bSign * 261 bcb - bSign *
263 QMIN(xtable[2][x], ytable[2][y]) * 2); 262 QMIN(xtable[2][x], ytable[2][y]) * 2);
264 } 263 }
265 if (eff == EllipticGradient) { 264 if (eff == EllipticGradient) {
266 rgb = qRgb(rcb - rSign * 265 rgb = qRgb(rcb - rSign *
267 (int)sqrt((xtable[0][x]*xtable[0][x] + 266 (int)sqrt((xtable[0][x]*xtable[0][x] +
268 ytable[0][y]*ytable[0][y])*2.0), 267 ytable[0][y]*ytable[0][y])*2.0),
269 gcb - gSign * 268 gcb - gSign *
270 (int)sqrt((xtable[1][x]*xtable[1][x] + 269 (int)sqrt((xtable[1][x]*xtable[1][x] +
271 ytable[1][y]*ytable[1][y])*2.0), 270 ytable[1][y]*ytable[1][y])*2.0),
272 bcb - bSign * 271 bcb - bSign *
273 (int)sqrt((xtable[2][x]*xtable[2][x] + 272 (int)sqrt((xtable[2][x]*xtable[2][x] +
274 ytable[2][y]*ytable[2][y])*2.0)); 273 ytable[2][y]*ytable[2][y])*2.0));
275 } 274 }
276 275
277 sl1[x] = sl2[x] = rgb; 276 sl1[x] = sl2[x] = rgb;
278 sl1[x2] = sl2[x2] = rgb; 277 sl1[x2] = sl2[x2] = rgb;
279 } 278 }
280 } 279 }
281 } 280 }
282 281
283 delete [] xtable[0]; 282 delete [] xtable[0];
284 delete [] xtable[1]; 283 delete [] xtable[1];
285 delete [] xtable[2]; 284 delete [] xtable[2];
286 delete [] ytable[0]; 285 delete [] ytable[0];
287 delete [] ytable[1]; 286 delete [] ytable[1];
288 delete [] ytable[2]; 287 delete [] ytable[2];
289 } 288 }
290 289
291 // dither if necessary 290 // dither if necessary
292 if (ncols && (QPixmap::defaultDepth() < 15 )) { 291 if (ncols && (QPixmap::defaultDepth() < 15 )) {
293 if ( ncols < 2 || ncols > 256 ) 292 if ( ncols < 2 || ncols > 256 )
294 ncols = 3; 293 ncols = 3;
295 QColor *dPal = new QColor[ncols]; 294 QColor *dPal = new QColor[ncols];
296 for (int i=0; i<ncols; i++) { 295 for (int i=0; i<ncols; i++) {
297 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), 296 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ),
298 gca + gDiff * i / ( ncols - 1 ), 297 gca + gDiff * i / ( ncols - 1 ),
299 bca + bDiff * i / ( ncols - 1 ) ); 298 bca + bDiff * i / ( ncols - 1 ) );
300 } 299 }
301 dither(image, dPal, ncols); 300 dither(image, dPal, ncols);
302 delete [] dPal; 301 delete [] dPal;
303 } 302 }
304 303
305 return image; 304 return image;
306} 305}
307 306
308 307
309// ----------------------------------------------------------------------------- 308// -----------------------------------------------------------------------------
310 309
311//CT this was (before Dirk A. Mueller's speedup changes) 310//CT this was (before Dirk A. Mueller's speedup changes)
312// merely the same code as in the above method, but it's supposedly 311// merely the same code as in the above method, but it's supposedly
313// way less performant since it introduces a lot of supplementary tests 312// way less performant since it introduces a lot of supplementary tests
314// and simple math operations for the calculus of the balance. 313// and simple math operations for the calculus of the balance.
315// (surprizingly, it isn't less performant, in the contrary :-) 314// (surprizingly, it isn't less performant, in the contrary :-)
316// Yes, I could have merged them, but then the excellent performance of 315// Yes, I could have merged them, but then the excellent performance of
317// the balanced code would suffer with no other gain than a mere 316// the balanced code would suffer with no other gain than a mere
318// source code and byte code size economy. 317// source code and byte code size economy.
319 318
320QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca, 319QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca,
321 const QColor &cb, GradientType eff, int xfactor, int yfactor, 320 const QColor &cb, GradientType eff, int xfactor, int yfactor,
322 int ncols) 321 int ncols)
323{ 322{
324 int dir; // general parameter used for direction switches 323 int dir; // general parameter used for direction switches
325 324
326 bool _xanti = false , _yanti = false; 325 bool _xanti = false , _yanti = false;
327 326
328 if (xfactor < 0) _xanti = true; // negative on X direction 327 if (xfactor < 0) _xanti = true; // negative on X direction
329 if (yfactor < 0) _yanti = true; // negative on Y direction 328 if (yfactor < 0) _yanti = true; // negative on Y direction
330 329
331 xfactor = abs(xfactor); 330 xfactor = abs(xfactor);
332 yfactor = abs(yfactor); 331 yfactor = abs(yfactor);
333 332
334 if (!xfactor) xfactor = 1; 333 if (!xfactor) xfactor = 1;
335 if (!yfactor) yfactor = 1; 334 if (!yfactor) yfactor = 1;
336 335
337 if (xfactor > 200 ) xfactor = 200; 336 if (xfactor > 200 ) xfactor = 200;
338 if (yfactor > 200 ) yfactor = 200; 337 if (yfactor > 200 ) yfactor = 200;
339 338
340 339
341 // float xbal = xfactor/5000.; 340 // float xbal = xfactor/5000.;
342 // float ybal = yfactor/5000.; 341 // float ybal = yfactor/5000.;
343 float xbal = xfactor/30./size.width(); 342 float xbal = xfactor/30./size.width();
344 float ybal = yfactor/30./size.height(); 343 float ybal = yfactor/30./size.height();
345 float rat; 344 float rat;
346 345
347 int rDiff, gDiff, bDiff; 346 int rDiff, gDiff, bDiff;
348 int rca, gca, bca, rcb, gcb, bcb; 347 int rca, gca, bca, rcb, gcb, bcb;
349 348
350 QImage image(size, 32); 349 QImage image(size, 32);
351 350
352 if (size.width() == 0 || size.height() == 0) { 351 if (size.width() == 0 || size.height() == 0) {
353 qDebug( "WARNING: OImageEffect::unbalancedGradient : invalid image" ); 352 qDebug( "WARNING: OImageEffect::unbalancedGradient : invalid image" );
354 return image; 353 return image;
355 } 354 }
356 355
357 register int x, y; 356 register int x, y;
358 unsigned int *scanline; 357 unsigned int *scanline;
359 358
360 rDiff = (rcb = cb.red()) - (rca = ca.red()); 359 rDiff = (rcb = cb.red()) - (rca = ca.red());
361 gDiff = (gcb = cb.green()) - (gca = ca.green()); 360 gDiff = (gcb = cb.green()) - (gca = ca.green());
362 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 361 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
363 362
364 if( eff == VerticalGradient || eff == HorizontalGradient){ 363 if( eff == VerticalGradient || eff == HorizontalGradient){
365 QColor cRow; 364 QColor cRow;
366 365
367 uint *p; 366 uint *p;
368 uint rgbRow; 367 uint rgbRow;
369 368
370 if( eff == VerticalGradient) { 369 if( eff == VerticalGradient) {
371 for ( y = 0; y < size.height(); y++ ) { 370 for ( y = 0; y < size.height(); y++ ) {
372 dir = _yanti ? y : size.height() - 1 - y; 371 dir = _yanti ? y : size.height() - 1 - y;
373 p = (uint *) image.scanLine(dir); 372 p = (uint *) image.scanLine(dir);
374 rat = 1 - exp( - (float)y * ybal ); 373 rat = 1 - exp( - (float)y * ybal );
375 374
376 cRow.setRgb( rcb - (int) ( rDiff * rat ), 375 cRow.setRgb( rcb - (int) ( rDiff * rat ),
377 gcb - (int) ( gDiff * rat ), 376 gcb - (int) ( gDiff * rat ),
378 bcb - (int) ( bDiff * rat ) ); 377 bcb - (int) ( bDiff * rat ) );
379 378
380 rgbRow = cRow.rgb(); 379 rgbRow = cRow.rgb();
381 380
382 for( x = 0; x < size.width(); x++ ) { 381 for( x = 0; x < size.width(); x++ ) {
383 *p = rgbRow; 382 *p = rgbRow;
384 p++; 383 p++;
385 } 384 }
386 } 385 }
387 } 386 }
388 else { 387 else {
389 388
390 unsigned int *src = (unsigned int *)image.scanLine(0); 389 unsigned int *src = (unsigned int *)image.scanLine(0);
391 for(x = 0; x < size.width(); x++ ) 390 for(x = 0; x < size.width(); x++ )
392 { 391 {
393 dir = _xanti ? x : size.width() - 1 - x; 392 dir = _xanti ? x : size.width() - 1 - x;
394 rat = 1 - exp( - (float)x * xbal ); 393 rat = 1 - exp( - (float)x * xbal );
395 394
396 src[dir] = qRgb(rcb - (int) ( rDiff * rat ), 395 src[dir] = qRgb(rcb - (int) ( rDiff * rat ),
397 gcb - (int) ( gDiff * rat ), 396 gcb - (int) ( gDiff * rat ),
398 bcb - (int) ( bDiff * rat )); 397 bcb - (int) ( bDiff * rat ));
399 } 398 }
400 399
401 // Believe it or not, manually copying in a for loop is faster 400 // Believe it or not, manually copying in a for loop is faster
402 // than calling memcpy for each scanline (on the order of ms...). 401 // than calling memcpy for each scanline (on the order of ms...).
403 // I think this is due to the function call overhead (mosfet). 402 // I think this is due to the function call overhead (mosfet).
404 403
405 for(y = 1; y < size.height(); ++y) 404 for(y = 1; y < size.height(); ++y)
406 { 405 {
407 scanline = (unsigned int *)image.scanLine(y); 406 scanline = (unsigned int *)image.scanLine(y);
408 for(x=0; x < size.width(); ++x) 407 for(x=0; x < size.width(); ++x)
409 scanline[x] = src[x]; 408 scanline[x] = src[x];
410 } 409 }
411 } 410 }
412 } 411 }
413 412
414 else { 413 else {
415 int w=size.width(), h=size.height(); 414 int w=size.width(), h=size.height();
416 415
417 unsigned char *xtable[3]; 416 unsigned char *xtable[3];
418 unsigned char *ytable[3]; 417 unsigned char *ytable[3];
419 xtable[0] = new unsigned char[w]; 418 xtable[0] = new unsigned char[w];
420 xtable[1] = new unsigned char[w]; 419 xtable[1] = new unsigned char[w];
421 xtable[2] = new unsigned char[w]; 420 xtable[2] = new unsigned char[w];
422 ytable[0] = new unsigned char[h]; 421 ytable[0] = new unsigned char[h];
423 ytable[1] = new unsigned char[h]; 422 ytable[1] = new unsigned char[h];
424 ytable[2] = new unsigned char[h]; 423 ytable[2] = new unsigned char[h];
425 424
426 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) 425 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient)
427 { 426 {
428 for (x = 0; x < w; x++) { 427 for (x = 0; x < w; x++) {
429 dir = _xanti ? x : w - 1 - x; 428 dir = _xanti ? x : w - 1 - x;
430 rat = 1 - exp( - (float)x * xbal ); 429 rat = 1 - exp( - (float)x * xbal );
431 430
432 xtable[0][dir] = (unsigned char) ( rDiff/2 * rat ); 431 xtable[0][dir] = (unsigned char) ( rDiff/2 * rat );
433 xtable[1][dir] = (unsigned char) ( gDiff/2 * rat ); 432 xtable[1][dir] = (unsigned char) ( gDiff/2 * rat );
434 xtable[2][dir] = (unsigned char) ( bDiff/2 * rat ); 433 xtable[2][dir] = (unsigned char) ( bDiff/2 * rat );
435 } 434 }
436 435
437 for (y = 0; y < h; y++) { 436 for (y = 0; y < h; y++) {
438 dir = _yanti ? y : h - 1 - y; 437 dir = _yanti ? y : h - 1 - y;
439 rat = 1 - exp( - (float)y * ybal ); 438 rat = 1 - exp( - (float)y * ybal );
440 439
441 ytable[0][dir] = (unsigned char) ( rDiff/2 * rat ); 440 ytable[0][dir] = (unsigned char) ( rDiff/2 * rat );
442 ytable[1][dir] = (unsigned char) ( gDiff/2 * rat ); 441 ytable[1][dir] = (unsigned char) ( gDiff/2 * rat );
443 ytable[2][dir] = (unsigned char) ( bDiff/2 * rat ); 442 ytable[2][dir] = (unsigned char) ( bDiff/2 * rat );
444 } 443 }
445 444
446 for (y = 0; y < h; y++) { 445 for (y = 0; y < h; y++) {
447 unsigned int *scanline = (unsigned int *)image.scanLine(y); 446 unsigned int *scanline = (unsigned int *)image.scanLine(y);
448 for (x = 0; x < w; x++) { 447 for (x = 0; x < w; x++) {
449 scanline[x] = qRgb(rcb - (xtable[0][x] + ytable[0][y]), 448 scanline[x] = qRgb(rcb - (xtable[0][x] + ytable[0][y]),
450 gcb - (xtable[1][x] + ytable[1][y]), 449 gcb - (xtable[1][x] + ytable[1][y]),
451 bcb - (xtable[2][x] + ytable[2][y])); 450 bcb - (xtable[2][x] + ytable[2][y]));
452 } 451 }
453 } 452 }
454 } 453 }
455 454
456 else if (eff == RectangleGradient || 455 else if (eff == RectangleGradient ||
457 eff == PyramidGradient || 456 eff == PyramidGradient ||
458 eff == PipeCrossGradient || 457 eff == PipeCrossGradient ||
459 eff == EllipticGradient) 458 eff == EllipticGradient)
460 { 459 {
461 int rSign = rDiff>0? 1: -1; 460 int rSign = rDiff>0? 1: -1;
462 int gSign = gDiff>0? 1: -1; 461 int gSign = gDiff>0? 1: -1;
463 int bSign = bDiff>0? 1: -1; 462 int bSign = bDiff>0? 1: -1;
464 463
465 for (x = 0; x < w; x++) 464 for (x = 0; x < w; x++)
466 { 465 {
467 dir = _xanti ? x : w - 1 - x; 466 dir = _xanti ? x : w - 1 - x;
468 rat = 1 - exp( - (float)x * xbal ); 467 rat = 1 - exp( - (float)x * xbal );
469 468
470 xtable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); 469 xtable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat)));
471 xtable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); 470 xtable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat)));
472 xtable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); 471 xtable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat)));
473 } 472 }
474 473
475 for (y = 0; y < h; y++) 474 for (y = 0; y < h; y++)
476 { 475 {
477 dir = _yanti ? y : h - 1 - y; 476 dir = _yanti ? y : h - 1 - y;
478 477
479 rat = 1 - exp( - (float)y * ybal ); 478 rat = 1 - exp( - (float)y * ybal );
480 479
481 ytable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); 480 ytable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat)));
482 ytable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); 481 ytable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat)));
483 ytable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); 482 ytable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat)));
484 } 483 }
485 484
486 for (y = 0; y < h; y++) { 485 for (y = 0; y < h; y++) {
487 unsigned int *scanline = (unsigned int *)image.scanLine(y); 486 unsigned int *scanline = (unsigned int *)image.scanLine(y);
488 for (x = 0; x < w; x++) { 487 for (x = 0; x < w; x++) {
489 if (eff == PyramidGradient) 488 if (eff == PyramidGradient)
490 { 489 {
491 scanline[x] = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), 490 scanline[x] = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]),
492 gcb-gSign*(xtable[1][x]+ytable[1][y]), 491 gcb-gSign*(xtable[1][x]+ytable[1][y]),
493 bcb-bSign*(xtable[2][x]+ytable[2][y])); 492 bcb-bSign*(xtable[2][x]+ytable[2][y]));
494 } 493 }
495 if (eff == RectangleGradient) 494 if (eff == RectangleGradient)
496 { 495 {
497 scanline[x] = qRgb(rcb - rSign * 496 scanline[x] = qRgb(rcb - rSign *
498 QMAX(xtable[0][x], ytable[0][y]) * 2, 497 QMAX(xtable[0][x], ytable[0][y]) * 2,
499 gcb - gSign * 498 gcb - gSign *
500 QMAX(xtable[1][x], ytable[1][y]) * 2, 499 QMAX(xtable[1][x], ytable[1][y]) * 2,
501 bcb - bSign * 500 bcb - bSign *
502 QMAX(xtable[2][x], ytable[2][y]) * 2); 501 QMAX(xtable[2][x], ytable[2][y]) * 2);
503 } 502 }
504 if (eff == PipeCrossGradient) 503 if (eff == PipeCrossGradient)
505 { 504 {
506 scanline[x] = qRgb(rcb - rSign * 505 scanline[x] = qRgb(rcb - rSign *
507 QMIN(xtable[0][x], ytable[0][y]) * 2, 506 QMIN(xtable[0][x], ytable[0][y]) * 2,
508 gcb - gSign * 507 gcb - gSign *
509 QMIN(xtable[1][x], ytable[1][y]) * 2, 508 QMIN(xtable[1][x], ytable[1][y]) * 2,
510 bcb - bSign * 509 bcb - bSign *
511 QMIN(xtable[2][x], ytable[2][y]) * 2); 510 QMIN(xtable[2][x], ytable[2][y]) * 2);
512 } 511 }
513 if (eff == EllipticGradient) 512 if (eff == EllipticGradient)
514 { 513 {
515 scanline[x] = qRgb(rcb - rSign * 514 scanline[x] = qRgb(rcb - rSign *
516 (int)sqrt((xtable[0][x]*xtable[0][x] + 515 (int)sqrt((xtable[0][x]*xtable[0][x] +
517 ytable[0][y]*ytable[0][y])*2.0), 516 ytable[0][y]*ytable[0][y])*2.0),
518 gcb - gSign * 517 gcb - gSign *
519 (int)sqrt((xtable[1][x]*xtable[1][x] + 518 (int)sqrt((xtable[1][x]*xtable[1][x] +
520 ytable[1][y]*ytable[1][y])*2.0), 519 ytable[1][y]*ytable[1][y])*2.0),
521 bcb - bSign * 520 bcb - bSign *
522 (int)sqrt((xtable[2][x]*xtable[2][x] + 521 (int)sqrt((xtable[2][x]*xtable[2][x] +
523 ytable[2][y]*ytable[2][y])*2.0)); 522 ytable[2][y]*ytable[2][y])*2.0));
524 } 523 }
525 } 524 }
526 } 525 }
527 } 526 }
528 527
529 if (ncols && (QPixmap::defaultDepth() < 15 )) { 528 if (ncols && (QPixmap::defaultDepth() < 15 )) {
530 if ( ncols < 2 || ncols > 256 ) 529 if ( ncols < 2 || ncols > 256 )
531 ncols = 3; 530 ncols = 3;
532 QColor *dPal = new QColor[ncols]; 531 QColor *dPal = new QColor[ncols];
533 for (int i=0; i<ncols; i++) { 532 for (int i=0; i<ncols; i++) {
534 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), 533 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ),
535 gca + gDiff * i / ( ncols - 1 ), 534 gca + gDiff * i / ( ncols - 1 ),
536 bca + bDiff * i / ( ncols - 1 ) ); 535 bca + bDiff * i / ( ncols - 1 ) );
537 } 536 }
538 dither(image, dPal, ncols); 537 dither(image, dPal, ncols);
539 delete [] dPal; 538 delete [] dPal;
540 } 539 }
541 540
542 delete [] xtable[0]; 541 delete [] xtable[0];
543 delete [] xtable[1]; 542 delete [] xtable[1];
544 delete [] xtable[2]; 543 delete [] xtable[2];
545 delete [] ytable[0]; 544 delete [] ytable[0];
546 delete [] ytable[1]; 545 delete [] ytable[1];
547 delete [] ytable[2]; 546 delete [] ytable[2];
548 547
549 } 548 }
550 549
551 return image; 550 return image;
552} 551}
553 552
554 553
555//====================================================================== 554//======================================================================
556// 555//
557// Intensity effects 556// Intensity effects
558// 557//
559//====================================================================== 558//======================================================================
560 559
561 560
562/* This builds a 256 byte unsigned char lookup table with all 561/* This builds a 256 byte unsigned char lookup table with all
563 * the possible percent values prior to applying the effect, then uses 562 * the possible percent values prior to applying the effect, then uses
564 * integer math for the pixels. For any image larger than 9x9 this will be 563 * integer math for the pixels. For any image larger than 9x9 this will be
565 * less expensive than doing a float operation on the 3 color components of 564 * less expensive than doing a float operation on the 3 color components of
566 * each pixel. (mosfet) 565 * each pixel. (mosfet)
567 */ 566 */
568 567
569QImage& OImageEffect::intensity(QImage &image, float percent) 568QImage& OImageEffect::intensity(QImage &image, float percent)
570{ 569{
571 if (image.width() == 0 || image.height() == 0) { 570 if (image.width() == 0 || image.height() == 0) {
572 qDebug( "WARNING: OImageEffect::intensity : invalid image" ); 571 qDebug( "WARNING: OImageEffect::intensity : invalid image" );
573 return image; 572 return image;
574 } 573 }
575 574
576 int segColors = image.depth() > 8 ? 256 : image.numColors(); 575 int segColors = image.depth() > 8 ? 256 : image.numColors();
577 unsigned char *segTbl = new unsigned char[segColors]; 576 unsigned char *segTbl = new unsigned char[segColors];
578 int pixels = image.depth() > 8 ? image.width()*image.height() : 577 int pixels = image.depth() > 8 ? image.width()*image.height() :
579 image.numColors(); 578 image.numColors();
580 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 579 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
581 (unsigned int *)image.colorTable(); 580 (unsigned int *)image.colorTable();
582 581
583 bool brighten = (percent >= 0); 582 bool brighten = (percent >= 0);
584 if(percent < 0) 583 if(percent < 0)
585 percent = -percent; 584 percent = -percent;
586 585
587 if(brighten){ // keep overflow check out of loops 586 if(brighten){ // keep overflow check out of loops
588 for(int i=0; i < segColors; ++i){ 587 for(int i=0; i < segColors; ++i){
589 int tmp = (int)(i*percent); 588 int tmp = (int)(i*percent);
590 if(tmp > 255) 589 if(tmp > 255)
591 tmp = 255; 590 tmp = 255;
592 segTbl[i] = tmp; 591 segTbl[i] = tmp;
593 } 592 }
594 } 593 }
595 else{ 594 else{
596 for(int i=0; i < segColors; ++i){ 595 for(int i=0; i < segColors; ++i){
597 int tmp = (int)(i*percent); 596 int tmp = (int)(i*percent);
598 if(tmp < 0) 597 if(tmp < 0)
599 tmp = 0; 598 tmp = 0;
600 segTbl[i] = tmp; 599 segTbl[i] = tmp;
601 } 600 }
602 } 601 }
603 602
604 if(brighten){ // same here 603 if(brighten){ // same here
605 for(int i=0; i < pixels; ++i){ 604 for(int i=0; i < pixels; ++i){
606 int r = qRed(data[i]); 605 int r = qRed(data[i]);
607 int g = qGreen(data[i]); 606 int g = qGreen(data[i]);
608 int b = qBlue(data[i]); 607 int b = qBlue(data[i]);
609 int a = qAlpha(data[i]); 608 int a = qAlpha(data[i]);
610 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; 609 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r];
611 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; 610 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g];
612 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; 611 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b];
613 data[i] = qRgba(r, g, b,a); 612 data[i] = qRgba(r, g, b,a);
614 } 613 }
615 } 614 }
616 else{ 615 else{
617 for(int i=0; i < pixels; ++i){ 616 for(int i=0; i < pixels; ++i){
618 int r = qRed(data[i]); 617 int r = qRed(data[i]);
619 int g = qGreen(data[i]); 618 int g = qGreen(data[i]);
620 int b = qBlue(data[i]); 619 int b = qBlue(data[i]);
621 int a = qAlpha(data[i]); 620 int a = qAlpha(data[i]);
622 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; 621 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r];
623 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; 622 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g];
624 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; 623 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b];
625 data[i] = qRgba(r, g, b, a); 624 data[i] = qRgba(r, g, b, a);
626 } 625 }
627 } 626 }
628 delete [] segTbl; 627 delete [] segTbl;
629 628
630 return image; 629 return image;
631} 630}
632 631
633QImage& OImageEffect::channelIntensity(QImage &image, float percent, 632QImage& OImageEffect::channelIntensity(QImage &image, float percent,
634 RGBComponent channel) 633 RGBComponent channel)
635{ 634{
636 if (image.width() == 0 || image.height() == 0) { 635 if (image.width() == 0 || image.height() == 0) {
637 qDebug( "WARNING: OImageEffect::channelIntensity : invalid image" ); 636 qDebug( "WARNING: OImageEffect::channelIntensity : invalid image" );
638 return image; 637 return image;
639 } 638 }
640 639
641 int segColors = image.depth() > 8 ? 256 : image.numColors(); 640 int segColors = image.depth() > 8 ? 256 : image.numColors();
642 unsigned char *segTbl = new unsigned char[segColors]; 641 unsigned char *segTbl = new unsigned char[segColors];
643 int pixels = image.depth() > 8 ? image.width()*image.height() : 642 int pixels = image.depth() > 8 ? image.width()*image.height() :
644 image.numColors(); 643 image.numColors();
645 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 644 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
646 (unsigned int *)image.colorTable(); 645 (unsigned int *)image.colorTable();
647 bool brighten = (percent >= 0); 646 bool brighten = (percent >= 0);
648 if(percent < 0) 647 if(percent < 0)
649 percent = -percent; 648 percent = -percent;
650 649
651 if(brighten){ // keep overflow check out of loops 650 if(brighten){ // keep overflow check out of loops
652 for(int i=0; i < segColors; ++i){ 651 for(int i=0; i < segColors; ++i){
653 int tmp = (int)(i*percent); 652 int tmp = (int)(i*percent);
654 if(tmp > 255) 653 if(tmp > 255)
655 tmp = 255; 654 tmp = 255;
656 segTbl[i] = tmp; 655 segTbl[i] = tmp;
657 } 656 }
658 } 657 }
659 else{ 658 else{
660 for(int i=0; i < segColors; ++i){ 659 for(int i=0; i < segColors; ++i){
661 int tmp = (int)(i*percent); 660 int tmp = (int)(i*percent);
662 if(tmp < 0) 661 if(tmp < 0)
663 tmp = 0; 662 tmp = 0;
664 segTbl[i] = tmp; 663 segTbl[i] = tmp;
665 } 664 }
666 } 665 }
667 666
668 if(brighten){ // same here 667 if(brighten){ // same here
669 if(channel == Red){ // and here ;-) 668 if(channel == Red){ // and here ;-)
670 for(int i=0; i < pixels; ++i){ 669 for(int i=0; i < pixels; ++i){
671 int c = qRed(data[i]); 670 int c = qRed(data[i]);
672 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 671 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
673 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i])); 672 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i]));
674 } 673 }
675 } 674 }
676 if(channel == Green){ 675 if(channel == Green){
677 for(int i=0; i < pixels; ++i){ 676 for(int i=0; i < pixels; ++i){
678 int c = qGreen(data[i]); 677 int c = qGreen(data[i]);
679 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 678 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
680 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i])); 679 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i]));
681 } 680 }
682 } 681 }
683 else{ 682 else{
684 for(int i=0; i < pixels; ++i){ 683 for(int i=0; i < pixels; ++i){
685 int c = qBlue(data[i]); 684 int c = qBlue(data[i]);
686 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 685 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
687 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i])); 686 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i]));
688 } 687 }
689 } 688 }
690 689
691 } 690 }
692 else{ 691 else{
693 if(channel == Red){ 692 if(channel == Red){
694 for(int i=0; i < pixels; ++i){ 693 for(int i=0; i < pixels; ++i){
695 int c = qRed(data[i]); 694 int c = qRed(data[i]);
696 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 695 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
697 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i])); 696 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i]));
698 } 697 }
699 } 698 }
700 if(channel == Green){ 699 if(channel == Green){
701 for(int i=0; i < pixels; ++i){ 700 for(int i=0; i < pixels; ++i){
702 int c = qGreen(data[i]); 701 int c = qGreen(data[i]);
703 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 702 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
704 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i])); 703 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i]));
705 } 704 }
706 } 705 }
707 else{ 706 else{
708 for(int i=0; i < pixels; ++i){ 707 for(int i=0; i < pixels; ++i){
709 int c = qBlue(data[i]); 708 int c = qBlue(data[i]);
710 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 709 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
711 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i])); 710 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i]));
712 } 711 }
713 } 712 }
714 } 713 }
715 delete [] segTbl; 714 delete [] segTbl;
716 715
717 return image; 716 return image;
718} 717}
719 718
720// Modulate an image with an RBG channel of another image 719// Modulate an image with an RBG channel of another image
721// 720//
722QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse, 721QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse,
723 ModulationType type, int factor, RGBComponent channel) 722 ModulationType type, int factor, RGBComponent channel)
724{ 723{
725 if (image.width() == 0 || image.height() == 0 || 724 if (image.width() == 0 || image.height() == 0 ||
726 modImage.width() == 0 || modImage.height() == 0) { 725 modImage.width() == 0 || modImage.height() == 0) {
727 qDebug( "WARNING: OImageEffect::modulate : invalid image" ); 726 qDebug( "WARNING: OImageEffect::modulate : invalid image" );
728 return image; 727 return image;
729 } 728 }
730 729
731 int r, g, b, h, s, v, a; 730 int r, g, b, h, s, v, a;
732 QColor clr; 731 QColor clr;
733 int mod=0; 732 int mod=0;
734 unsigned int x1, x2, y1, y2; 733 unsigned int x1, x2, y1, y2;
735 register int x, y; 734 register int x, y;
736 735
737 // for image, we handle only depth 32 736 // for image, we handle only depth 32
738 if (image.depth()<32) image = image.convertDepth(32); 737 if (image.depth()<32) image = image.convertDepth(32);
739 738
740 // for modImage, we handle depth 8 and 32 739 // for modImage, we handle depth 8 and 32
741 if (modImage.depth()<8) modImage = modImage.convertDepth(8); 740 if (modImage.depth()<8) modImage = modImage.convertDepth(8);
742 741
743 unsigned int *colorTable2 = (modImage.depth()==8) ? 742 unsigned int *colorTable2 = (modImage.depth()==8) ?
744 modImage.colorTable():0; 743 modImage.colorTable():0;
745 unsigned int *data1, *data2; 744 unsigned int *data1, *data2;
746 unsigned char *data2b; 745 unsigned char *data2b;
747 unsigned int color1, color2; 746 unsigned int color1, color2;
748 747
749 x1 = image.width(); y1 = image.height(); 748 x1 = image.width(); y1 = image.height();
750 x2 = modImage.width(); y2 = modImage.height(); 749 x2 = modImage.width(); y2 = modImage.height();
751 750
752 for (y = 0; y < (int)y1; y++) { 751 for (y = 0; y < (int)y1; y++) {
753 data1 = (unsigned int *) image.scanLine(y); 752 data1 = (unsigned int *) image.scanLine(y);
754 data2 = (unsigned int *) modImage.scanLine( y%y2 ); 753 data2 = (unsigned int *) modImage.scanLine( y%y2 );
755 data2b = (unsigned char *) modImage.scanLine( y%y2 ); 754 data2b = (unsigned char *) modImage.scanLine( y%y2 );
756 755
757 x=0; 756 x=0;
758 while(x < (int)x1) { 757 while(x < (int)x1) {
759 color2 = (colorTable2) ? colorTable2[*data2b] : *data2; 758 color2 = (colorTable2) ? colorTable2[*data2b] : *data2;
760 if (reverse) { 759 if (reverse) {
761 color1 = color2; 760 color1 = color2;
762 color2 = *data1; 761 color2 = *data1;
763 } 762 }
764 else 763 else
765 color1 = *data1; 764 color1 = *data1;
766 765
767 if (type == Intensity || type == Contrast) { 766 if (type == Intensity || type == Contrast) {
768 r = qRed(color1); 767 r = qRed(color1);
769 g = qGreen(color1); 768 g = qGreen(color1);
770 b = qBlue(color1); 769 b = qBlue(color1);
771 if (channel != All) { 770 if (channel != All) {
772 mod = (channel == Red) ? qRed(color2) : 771 mod = (channel == Red) ? qRed(color2) :
773 (channel == Green) ? qGreen(color2) : 772 (channel == Green) ? qGreen(color2) :
774 (channel == Blue) ? qBlue(color2) : 773 (channel == Blue) ? qBlue(color2) :
775 (channel == Gray) ? qGray(color2) : 0; 774 (channel == Gray) ? qGray(color2) : 0;
776 mod = mod*factor/50; 775 mod = mod*factor/50;
777 } 776 }
778 777
779 if (type == Intensity) { 778 if (type == Intensity) {
780 if (channel == All) { 779 if (channel == All) {
781 r += r * factor/50 * qRed(color2)/256; 780 r += r * factor/50 * qRed(color2)/256;
782 g += g * factor/50 * qGreen(color2)/256; 781 g += g * factor/50 * qGreen(color2)/256;
783 b += b * factor/50 * qBlue(color2)/256; 782 b += b * factor/50 * qBlue(color2)/256;
784 } 783 }
785 else { 784 else {
786 r += r * mod/256; 785 r += r * mod/256;
787 g += g * mod/256; 786 g += g * mod/256;
788 b += b * mod/256; 787 b += b * mod/256;
789 } 788 }
790 } 789 }
791 else { // Contrast 790 else { // Contrast
792 if (channel == All) { 791 if (channel == All) {
793 r += (r-128) * factor/50 * qRed(color2)/128; 792 r += (r-128) * factor/50 * qRed(color2)/128;
794 g += (g-128) * factor/50 * qGreen(color2)/128; 793 g += (g-128) * factor/50 * qGreen(color2)/128;
795 b += (b-128) * factor/50 * qBlue(color2)/128; 794 b += (b-128) * factor/50 * qBlue(color2)/128;
796 } 795 }
797 else { 796 else {
798 r += (r-128) * mod/128; 797 r += (r-128) * mod/128;
799 g += (g-128) * mod/128; 798 g += (g-128) * mod/128;
800 b += (b-128) * mod/128; 799 b += (b-128) * mod/128;
801 } 800 }
802 } 801 }
803 802
804 if (r<0) r=0; if (r>255) r=255; 803 if (r<0) r=0; if (r>255) r=255;