File indexing completed on 2024-05-12 05:10:16
0001 /* 0002 Copyright (C) 1998, 1999, 2001, 2002, 2004, 2005, 2007 0003 Daniel M. Duley <daniel.duley@verizon.net> 0004 (C) 2004 Zack Rusin <zack@kde.org> 0005 (C) 2000 Josef Weidendorfer <weidendo@in.tum.de> 0006 (C) 1999 Geert Jansen <g.t.jansen@stud.tue.nl> 0007 (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> 0008 (C) 1998, 1999 Dirk Mueller <mueller@kde.org> 0009 0010 Redistribution and use in source and binary forms, with or without 0011 modification, are permitted provided that the following conditions 0012 are met: 0013 0014 1. Redistributions of source code must retain the above copyright 0015 notice, this list of conditions and the following disclaimer. 0016 2. Redistributions in binary form must reproduce the above copyright 0017 notice, this list of conditions and the following disclaimer in the 0018 documentation and/or other materials provided with the distribution. 0019 0020 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0021 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0022 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0023 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0024 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0025 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0026 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0027 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0028 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0029 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0030 */ 0031 0032 /* 0033 Diagonal gradient code was inspired by BlackBox. BlackBox gradients are 0034 (C) Brad Hughes, <bhughes@tcac.net> and Mike Cole <mike@mydot.com>. 0035 */ 0036 0037 #include "gradient.h" 0038 0039 #include <QColor> 0040 #include <QVector> 0041 0042 #include <cmath> 0043 0044 QImage Tellico::gradient(QSize size, const QColor &ca, 0045 const QColor &cb, Tellico::GradientType eff) 0046 { 0047 QImage image(size, QImage::Format_RGB32); 0048 if(!size.isValid()) 0049 return(image); 0050 0051 int rca, gca, bca, rcb, gcb, bcb; 0052 int rDiff = (rcb = cb.red()) - (rca = ca.red()); 0053 int gDiff = (gcb = cb.green()) - (gca = ca.green()); 0054 int bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 0055 int x, y; 0056 QRgb rgb; 0057 0058 if(eff == VerticalGradient || eff == HorizontalGradient){ 0059 int rl = rca << 16; 0060 int gl = gca << 16; 0061 int bl = bca << 16; 0062 QRgb *p; 0063 if(eff == VerticalGradient){ 0064 int rcdelta = ((1<<16) / size.height()) * rDiff; 0065 int gcdelta = ((1<<16) / size.height()) * gDiff; 0066 int bcdelta = ((1<<16) / size.height()) * bDiff; 0067 for(y=0; y < size.height(); ++y){ 0068 rl += rcdelta; 0069 gl += gcdelta; 0070 bl += bcdelta; 0071 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); 0072 0073 p = reinterpret_cast<QRgb*>(image.scanLine(y)); 0074 for(x = 0; x < size.width(); ++x) 0075 *p++ = rgb; 0076 } 0077 } 0078 else{ // must be HorizontalGradient 0079 int rcdelta = ((1<<16) / size.width()) * rDiff; 0080 int gcdelta = ((1<<16) / size.width()) * gDiff; 0081 int bcdelta = ((1<<16) / size.width()) * bDiff; 0082 p = reinterpret_cast<QRgb*>(image.scanLine(0)); 0083 for(x = 0; x < size.width(); ++x){ 0084 rl += rcdelta; 0085 gl += gcdelta; 0086 bl += bcdelta; 0087 *p++ = qRgb((rl>>16), (gl>>16), (bl>>16)); 0088 } 0089 p = reinterpret_cast<QRgb*>(image.scanLine(0)); 0090 for(y = 1; y < size.height(); ++y) 0091 memcpy(image.scanLine(y), p, size.width()*sizeof(QRgb)); 0092 } 0093 } 0094 else{ 0095 float rfd, gfd, bfd; 0096 float rd = rca, gd = gca, bd = bca; 0097 0098 int w = size.width(), h = size.height(); 0099 int dw = w*2, dh = h*2; 0100 unsigned char *xtable = new unsigned char[w*3]; 0101 unsigned char *ytable = new unsigned char[h*3]; 0102 0103 if(eff == DiagonalGradient || eff == CrossDiagonalGradient){ 0104 rfd = (float)rDiff/dw; 0105 gfd = (float)gDiff/dw; 0106 bfd = (float)bDiff/dw; 0107 0108 int dir; 0109 for(x=0; x < w; x++, rd+=rfd, gd+=gfd, bd+=bfd) { 0110 dir = eff == DiagonalGradient? x : w - x - 1; 0111 xtable[dir*3] = (unsigned char) rd; 0112 xtable[dir*3+1] = (unsigned char) gd; 0113 xtable[dir*3+2] = (unsigned char) bd; 0114 } 0115 rfd = (float)rDiff/dh; 0116 gfd = (float)gDiff/dh; 0117 bfd = (float)bDiff/dh; 0118 rd = gd = bd = 0; 0119 for(y = 0; y < h; y++, rd+=rfd, gd+=gfd, bd+=bfd){ 0120 ytable[y*3] = (unsigned char) rd; 0121 ytable[y*3+1] = (unsigned char) gd; 0122 ytable[y*3+2] = (unsigned char) bd; 0123 } 0124 0125 for(y = 0; y < h; y++){ 0126 QRgb *p = reinterpret_cast<QRgb*>(image.scanLine(y)); 0127 for(x = 0; x < w; x++){ 0128 *p++ = qRgb(xtable[x*3] + ytable[y*3], 0129 xtable[x*3+1] + ytable[y*3+1], 0130 xtable[x*3+2] + ytable[y*3+2]); 0131 } 0132 } 0133 } 0134 else{ 0135 int rSign = rDiff>0? 1: -1; 0136 int gSign = gDiff>0? 1: -1; 0137 int bSign = bDiff>0? 1: -1; 0138 0139 rfd = (float)rDiff/w; 0140 gfd = (float)gDiff/w; 0141 bfd = (float)bDiff/w; 0142 0143 rd = (float)rDiff/2; 0144 gd = (float)gDiff/2; 0145 bd = (float)bDiff/2; 0146 0147 for(x=0; x < w; x++, rd-=rfd, gd-=gfd, bd-=bfd){ 0148 xtable[x*3] = (unsigned char) qAbs((int)rd); 0149 xtable[x*3+1] = (unsigned char) qAbs((int)gd); 0150 xtable[x*3+2] = (unsigned char) qAbs((int)bd); 0151 } 0152 0153 rfd = (float)rDiff/h; 0154 gfd = (float)gDiff/h; 0155 bfd = (float)bDiff/h; 0156 0157 rd = (float)rDiff/2; 0158 gd = (float)gDiff/2; 0159 bd = (float)bDiff/2; 0160 0161 for(y=0; y < h; y++, rd-=rfd, gd-=gfd, bd-=bfd){ 0162 ytable[y*3] = (unsigned char) qAbs((int)rd); 0163 ytable[y*3+1] = (unsigned char) qAbs((int)gd); 0164 ytable[y*3+2] = (unsigned char) qAbs((int)bd); 0165 } 0166 0167 dw = (w+1)>>1; 0168 dh = (h+1)>>1; 0169 int x2; 0170 QRgb *sl1, *sl2; 0171 for(y = 0; y < dh; y++){ 0172 sl1 = reinterpret_cast<QRgb*>(image.scanLine(y)); 0173 sl2 = reinterpret_cast<QRgb*>(image.scanLine(qMax(h-y-1, y))); 0174 for(x = 0, x2 = w-1; x < dw; x++, x2--){ 0175 switch(eff){ 0176 case PyramidGradient: 0177 rgb = qRgb(rcb-rSign*(xtable[x*3]+ytable[y*3]), 0178 gcb-gSign*(xtable[x*3+1]+ytable[y*3+1]), 0179 bcb-bSign*(xtable[x*3+2]+ytable[y*3+2])); 0180 break; 0181 case RectangleGradient: 0182 rgb = qRgb(rcb - rSign * 0183 qMax(xtable[x*3], ytable[y*3]) * 2, 0184 gcb - gSign * 0185 qMax(xtable[x*3+1], ytable[y*3+1]) * 2, 0186 bcb - bSign * 0187 qMax(xtable[x*3+2], ytable[y*3+2]) * 2); 0188 break; 0189 case PipeCrossGradient: 0190 rgb = qRgb(rcb - rSign * 0191 qMin(xtable[x*3], ytable[y*3]) * 2, 0192 gcb - gSign * 0193 qMin(xtable[x*3+1], ytable[y*3+1]) * 2, 0194 bcb - bSign * 0195 qMin(xtable[x*3+2], ytable[y*3+2]) * 2); 0196 break; 0197 case EllipticGradient: 0198 default: 0199 rgb = qRgb(rcb - rSign * 0200 (int)std::sqrt((xtable[x*3]*xtable[x*3] + 0201 ytable[y*3]*ytable[y*3])*2.0f), 0202 gcb - gSign * 0203 (int)std::sqrt((xtable[x*3+1]*xtable[x*3+1] + 0204 ytable[y*3+1]*ytable[y*3+1])*2.0f), 0205 bcb - bSign * 0206 (int)std::sqrt((xtable[x*3+2]*xtable[x*3+2] + 0207 ytable[y*3+2]*ytable[y*3+2])*2.0f)); 0208 break; 0209 } 0210 sl1[x] = sl2[x] = rgb; 0211 sl1[x2] = sl2[x2] = rgb; 0212 } 0213 } 0214 } 0215 delete [] xtable; 0216 delete [] ytable; 0217 } 0218 return(image); 0219 } 0220 0221 QImage Tellico::grayGradient(QSize size, unsigned char ca, 0222 unsigned char cb, Tellico::GradientType eff) 0223 { 0224 QImage image(size, QImage::Format_Indexed8); 0225 if(!size.isValid()) 0226 return(image); 0227 QVector<QRgb> colorTable(256); 0228 for(int i=0; i < 256; ++i) 0229 colorTable[i] = qRgba(i, i, i, 255); 0230 image.setColorTable(colorTable); 0231 0232 int diff = cb - ca; 0233 int x, y; 0234 unsigned char idx; 0235 0236 if(eff == VerticalGradient || eff == HorizontalGradient){ 0237 int val = ca << 16; 0238 unsigned char *p; 0239 if(eff == VerticalGradient){ 0240 int delta = ((1<<16) / size.height()) * diff; 0241 for(y=0; y < size.height(); ++y){ 0242 val += delta; 0243 idx = val >> 16; 0244 p = image.scanLine(y); 0245 for(x = 0; x < size.width(); ++x) 0246 *p++ = idx; 0247 } 0248 } 0249 else{ // must be HorizontalGradient 0250 int delta = ((1<<16) / size.width()) * diff; 0251 p = image.scanLine(0); 0252 for(x = 0; x < size.width(); ++x){ 0253 val += delta; 0254 *p++ = val >> 16; 0255 } 0256 p = image.scanLine(0); 0257 for(y = 1; y < size.height(); ++y) 0258 memcpy(image.scanLine(y), p, image.bytesPerLine()); 0259 } 0260 } 0261 else{ 0262 float delta, val=ca; 0263 0264 unsigned int w = size.width(), h = size.height(); 0265 unsigned char *xtable = new unsigned char[w]; 0266 unsigned char *ytable = new unsigned char[h]; 0267 w*=2, h*=2; 0268 0269 if(eff == DiagonalGradient || eff == CrossDiagonalGradient){ 0270 delta = (float)diff/w; 0271 int dir; 0272 for(x=0; x < size.width(); x++, val+=delta){ 0273 dir = eff == DiagonalGradient? x : size.width() - x - 1; 0274 xtable[dir] = (unsigned char) val; 0275 } 0276 delta = (float)diff/h; 0277 val = 0; 0278 for(y = 0; y < size.height(); y++, val+=delta) 0279 ytable[y] = (unsigned char) val; 0280 0281 for(y = 0; y < size.height(); y++){ 0282 unsigned char *p = image.scanLine(y); 0283 for(x = 0; x < size.width(); x++) 0284 *p++ = xtable[x] + ytable[y]; 0285 } 0286 } 0287 else{ 0288 int sign = diff>0? 1: -1; 0289 delta = (float)diff / size.width(); 0290 val = (float)diff/2; 0291 for(x=0; x < size.width(); x++, val-=delta) 0292 xtable[x] = (unsigned char) qAbs((int)val); 0293 0294 delta = (float)diff/size.height(); 0295 val = (float)diff/2; 0296 for(y=0; y < size.height(); y++, val-=delta) 0297 ytable[y] = (unsigned char) qAbs((int)val); 0298 0299 int w = (size.width()+1)>>1; 0300 int h = (size.height()+1)>>1; 0301 int x2; 0302 unsigned char *sl1, *sl2; 0303 for(y = 0; y < h; y++){ 0304 sl1 = image.scanLine(y); 0305 sl2 = image.scanLine(qMax(size.height()-y-1, y)); 0306 for(x = 0, x2 = size.width()-1; x < w; x++, x2--){ 0307 switch(eff){ 0308 case PyramidGradient: 0309 idx = cb-sign*(xtable[x]+ytable[y]); 0310 break; 0311 case RectangleGradient: 0312 idx = cb-sign*qMax(xtable[x], ytable[y])*2; 0313 break; 0314 case PipeCrossGradient: 0315 idx = cb-sign*qMin(xtable[x], ytable[y])*2; 0316 break; 0317 case EllipticGradient: 0318 default: 0319 idx = cb - sign * 0320 (int)std::sqrt((xtable[x]*xtable[x] + 0321 ytable[y]*ytable[y])*2.0f); 0322 break; 0323 } 0324 sl1[x] = sl2[x] = idx; 0325 sl1[x2] = sl2[x2] = idx; 0326 } 0327 } 0328 } 0329 delete [] xtable; 0330 delete [] ytable; 0331 } 0332 return(image); 0333 } 0334 0335 QImage Tellico::unbalancedGradient(QSize size, const QColor &ca, 0336 const QColor &cb, Tellico::GradientType eff, 0337 int xfactor, int yfactor) 0338 { 0339 QImage image(size, QImage::Format_RGB32); 0340 if(!size.isValid()) 0341 return image; 0342 0343 int dir; // general parameter used for direction switches 0344 bool _xanti = (xfactor < 0); // negative on X direction 0345 bool _yanti = (yfactor < 0); // negative on Y direction 0346 xfactor = qBound(1, qAbs(xfactor), 200); 0347 yfactor = qBound(1, qAbs(yfactor), 200); 0348 // float xbal = xfactor/5000.; 0349 // float ybal = yfactor/5000.; 0350 float xbal = xfactor/30.0f/size.width(); 0351 float ybal = yfactor/30.0f/size.height(); 0352 float rat; 0353 0354 int x, y; 0355 int rca, gca, bca, rcb, gcb, bcb; 0356 int rDiff = (rcb = cb.red()) - (rca = ca.red()); 0357 int gDiff = (gcb = cb.green()) - (gca = ca.green()); 0358 int bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 0359 0360 if(eff == VerticalGradient || eff == HorizontalGradient){ 0361 QRgb *p; 0362 if(eff == VerticalGradient){ 0363 QRgb rgbRow; 0364 for(y=0; y < size.height(); y++){ 0365 dir = _yanti ? y : size.height() - 1 - y; 0366 rat = 1 - std::exp( - (float)y * ybal ); 0367 p = reinterpret_cast<QRgb*>(image.scanLine(dir)); 0368 rgbRow = qRgb(rcb - (int) ( rDiff * rat ), 0369 gcb - (int) ( gDiff * rat ), 0370 bcb - (int) ( bDiff * rat )); 0371 for(x = 0; x < size.width(); x++) 0372 *p++ = rgbRow; 0373 } 0374 } 0375 else{ 0376 p = reinterpret_cast<QRgb*>(image.scanLine(0)); 0377 for(x = 0; x < size.width(); x++){ 0378 dir = _xanti ? x : size.width() - 1 - x; 0379 rat = 1 - std::exp( - (float)x * xbal ); 0380 p[dir] = qRgb(rcb - (int) ( rDiff * rat ), 0381 gcb - (int) ( gDiff * rat ), 0382 bcb - (int) ( bDiff * rat )); 0383 } 0384 0385 p = reinterpret_cast<QRgb*>(image.scanLine(0)); 0386 for(y = 1; y < size.height(); ++y){ 0387 memcpy(image.scanLine(y), p, 0388 size.width()*sizeof(QRgb)); 0389 } 0390 } 0391 } 0392 else{ 0393 int w=size.width(), h=size.height(); 0394 unsigned char *xtable = new unsigned char[w*3]; 0395 unsigned char *ytable = new unsigned char[h*3]; 0396 QRgb *p; 0397 0398 if(eff == DiagonalGradient || eff == CrossDiagonalGradient){ 0399 for(x = 0; x < w; x++){ 0400 dir = _xanti ? x : w - 1 - x; 0401 rat = 1 - std::exp( - (float)x * xbal ); 0402 0403 xtable[dir*3] = (unsigned char) ( rDiff/2 * rat ); 0404 xtable[dir*3+1] = (unsigned char) ( gDiff/2 * rat ); 0405 xtable[dir*3+2] = (unsigned char) ( bDiff/2 * rat ); 0406 } 0407 0408 for(y = 0; y < h; y++){ 0409 dir = _yanti ? y : h - 1 - y; 0410 rat = 1 - std::exp( - (float)y * ybal ); 0411 0412 ytable[dir*3] = (unsigned char) ( rDiff/2 * rat ); 0413 ytable[dir*3+1] = (unsigned char) ( gDiff/2 * rat ); 0414 ytable[dir*3+2] = (unsigned char) ( bDiff/2 * rat ); 0415 } 0416 0417 for(y = 0; y < h; y++){ 0418 p = reinterpret_cast<QRgb*>(image.scanLine(y)); 0419 for(x = 0; x < w; x++){ 0420 *p++ = qRgb(rcb - (xtable[x*3] + ytable[y*3]), 0421 gcb - (xtable[x*3+1] + ytable[y*3+1]), 0422 bcb - (xtable[x*3+2] + ytable[y*3+2])); 0423 } 0424 } 0425 } 0426 else{ 0427 int rSign = rDiff>0? 1: -1; 0428 int gSign = gDiff>0? 1: -1; 0429 int bSign = bDiff>0? 1: -1; 0430 0431 for(x = 0; x < w; x++){ 0432 dir = _xanti ? x : w - 1 - x; 0433 rat = 1 - std::exp( - (float)x * xbal ); 0434 0435 xtable[dir*3] = (unsigned char) qAbs((int)(rDiff*(0.5-rat))); 0436 xtable[dir*3+1] = (unsigned char) qAbs((int)(gDiff*(0.5-rat))); 0437 xtable[dir*3+2] = (unsigned char) qAbs((int)(bDiff*(0.5-rat))); 0438 } 0439 0440 for(y = 0; y < h; y++){ 0441 dir = _yanti ? y : h - 1 - y; 0442 rat = 1 - std::exp( - (float)y * ybal ); 0443 0444 ytable[dir*3] = (unsigned char) qAbs((int)(rDiff*(0.5-rat))); 0445 ytable[dir*3+1] = (unsigned char) qAbs((int)(gDiff*(0.5-rat))); 0446 ytable[dir*3+2] = (unsigned char) qAbs((int)(bDiff*(0.5-rat))); 0447 } 0448 0449 for(y = 0; y < h; y++){ 0450 p = reinterpret_cast<QRgb*>(image.scanLine(y)); 0451 for(x = 0; x < w; x++) { 0452 if (eff == PyramidGradient){ 0453 *p++ = qRgb(rcb-rSign*(xtable[x*3]+ytable[y*3]), 0454 gcb-gSign*(xtable[x*3+1]+ytable[y*3+1]), 0455 bcb-bSign*(xtable[x*3+2]+ytable[y*3+2])); 0456 } 0457 else if (eff == RectangleGradient){ 0458 *p++ = qRgb(rcb - rSign * 0459 qMax(xtable[x*3], ytable[y*3]) * 2, 0460 gcb - gSign * 0461 qMax(xtable[x*3+1], ytable[y*3+1]) * 2, 0462 bcb - bSign * 0463 qMax(xtable[x*3+2], ytable[y*3+2]) * 2); 0464 } 0465 else if (eff == PipeCrossGradient){ 0466 *p++ = qRgb(rcb - rSign * 0467 qMin(xtable[x*3], ytable[y*3]) * 2, 0468 gcb - gSign * 0469 qMin(xtable[x*3+1], ytable[y*3+1]) * 2, 0470 bcb - bSign * 0471 qMin(xtable[x*3+2], ytable[y*3+2]) * 2); 0472 } 0473 else if (eff == EllipticGradient){ 0474 *p++ = qRgb(rcb - rSign * 0475 (int)std::sqrt((xtable[x*3]*xtable[x*3] + 0476 ytable[y*3]*ytable[y*3])*2.0), 0477 gcb - gSign * 0478 (int)std::sqrt((xtable[x*3+1]*xtable[x*3+1] + 0479 ytable[y*3+1]*ytable[y*3+1])*2.0), 0480 bcb - bSign * 0481 (int)std::sqrt((xtable[x*3+2]*xtable[x*3+2] + 0482 ytable[y*3+2]*ytable[y*3+2])*2.0)); 0483 } 0484 } 0485 } 0486 } 0487 delete [] xtable; 0488 delete [] ytable; 0489 } 0490 return(image); 0491 } 0492 0493 QImage Tellico::grayUnbalancedGradient(QSize size, unsigned char ca, 0494 unsigned char cb, Tellico::GradientType eff, 0495 int xfactor, int yfactor) 0496 { 0497 QImage image(size, QImage::Format_Indexed8); 0498 if(!size.isValid()) 0499 return(image); 0500 QVector<QRgb> colorTable(256); 0501 for(int i=0; i < 256; ++i) 0502 colorTable[i] = qRgba(i, i, i, 255); 0503 image.setColorTable(colorTable); 0504 0505 int dir; // general parameter used for direction switches 0506 bool _xanti = (xfactor < 0); // negative on X direction 0507 bool _yanti = (yfactor < 0); // negative on Y direction 0508 xfactor = qBound(1, qAbs(xfactor), 200); 0509 yfactor = qBound(1, qAbs(yfactor), 200); 0510 float xbal = xfactor/30.0f/size.width(); 0511 float ybal = yfactor/30.0f/size.height(); 0512 float rat; 0513 0514 int x, y; 0515 int diff = cb-ca; 0516 0517 if(eff == VerticalGradient || eff == HorizontalGradient){ 0518 unsigned char *p; 0519 if(eff == VerticalGradient){ 0520 unsigned char idx; 0521 for(y=0; y < size.height(); y++){ 0522 dir = _yanti ? y : size.height() - 1 - y; 0523 rat = 1 - std::exp( - (float)y * ybal ); 0524 p = image.scanLine(dir); 0525 idx = cb - (int)( diff * rat ); 0526 for(x = 0; x < size.width(); x++) 0527 *p++ = idx; 0528 } 0529 } 0530 else{ 0531 p = image.scanLine(0); 0532 for(x = 0; x < size.width(); x++){ 0533 dir = _xanti ? x : size.width() - 1 - x; 0534 rat = 1 - std::exp( - (float)x * xbal ); 0535 p[dir] = cb - (int)( diff * rat ); 0536 } 0537 0538 p = image.scanLine(0); 0539 for(y = 1; y < size.height(); ++y) 0540 memcpy(image.scanLine(y), p, image.bytesPerLine()); 0541 } 0542 } 0543 else{ 0544 int w=size.width(), h=size.height(); 0545 unsigned char *xtable = new unsigned char[w]; 0546 unsigned char *ytable = new unsigned char[h]; 0547 unsigned char *p; 0548 0549 if(eff == DiagonalGradient || eff == CrossDiagonalGradient){ 0550 for(x = 0; x < w; x++){ 0551 dir = _xanti ? x : w - 1 - x; 0552 rat = 1 - std::exp( - (float)x * xbal ); 0553 xtable[dir] = (unsigned char) ( diff/2 * rat ); 0554 } 0555 0556 for(y = 0; y < h; y++){ 0557 dir = _yanti ? y : h - 1 - y; 0558 rat = 1 - std::exp( - (float)y * ybal ); 0559 ytable[dir] = (unsigned char) ( diff/2 * rat ); 0560 } 0561 0562 for(y = 0; y < h; y++){ 0563 p = image.scanLine(y); 0564 for(x = 0; x < w; x++) 0565 *p++ = cb - (xtable[x] + ytable[y]); 0566 } 0567 } 0568 else{ 0569 int sign = diff>0? 1: -1; 0570 for(x = 0; x < w; x++){ 0571 dir = _xanti ? x : w - 1 - x; 0572 rat = 1 - std::exp( - (float)x * xbal ); 0573 xtable[dir] = (unsigned char) qAbs((int)(diff*(0.5-rat))); 0574 } 0575 0576 for(y = 0; y < h; y++){ 0577 dir = _yanti ? y : h - 1 - y; 0578 rat = 1 - std::exp( - (float)y * ybal ); 0579 ytable[dir] = (unsigned char) qAbs((int)(diff*(0.5-rat))); 0580 } 0581 0582 for(y = 0; y < h; y++){ 0583 p = image.scanLine(y); 0584 for(x = 0; x < w; x++) { 0585 if (eff == PyramidGradient) 0586 *p++ = cb-sign*(xtable[x]+ytable[y]); 0587 else if (eff == RectangleGradient) 0588 *p++ = cb -sign*qMax(xtable[x], ytable[y])*2; 0589 else if (eff == PipeCrossGradient) 0590 *p++ = cb-sign*qMin(xtable[x], ytable[y])*2; 0591 else if (eff == EllipticGradient) 0592 *p++ = cb-sign * (int)std::sqrt((xtable[x]*xtable[x] + 0593 ytable[y]*ytable[y])*2.0); 0594 } 0595 } 0596 } 0597 delete [] xtable; 0598 delete [] ytable; 0599 } 0600 return(image); 0601 }