source: trunk/src/gui/painting/qimagescale.cpp@ 719

Last change on this file since 719 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 35.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41#include <private/qimagescale_p.h>
42#include <private/qdrawhelper_p.h>
43
44#include "qimage.h"
45#include "qcolor.h"
46
47QT_BEGIN_NAMESPACE
48
49namespace QImageScale {
50 struct QImageScaleInfo;
51}
52
53typedef void (*qt_qimageScaleFunc)(QImageScale::QImageScaleInfo *isi, unsigned int *dest,
54 int dxx, int dyy, int dx, int dy, int dw,
55 int dh, int dow, int sow);
56
57static void qt_qimageScaleAARGB(QImageScale::QImageScaleInfo *isi, unsigned int *dest,
58 int dxx, int dyy, int dx, int dy, int dw,
59 int dh, int dow, int sow);
60
61static void qt_qimageScaleAARGBA(QImageScale::QImageScaleInfo *isi, unsigned int *dest,
62 int dxx, int dyy, int dx, int dy, int dw,
63 int dh, int dow, int sow);
64
65qt_qimageScaleFunc qt_qimageScaleArgb = qt_qimageScaleAARGBA;
66qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB;
67
68
69/*
70 * Copyright (C) 2004, 2005 Daniel M. Duley
71 *
72 * Redistribution and use in source and binary forms, with or without
73 * modification, are permitted provided that the following conditions
74 * are met:
75 *
76 * 1. Redistributions of source code must retain the above copyright
77 * notice, this list of conditions and the following disclaimer.
78 * 2. Redistributions in binary form must reproduce the above copyright
79 * notice, this list of conditions and the following disclaimer in the
80 * documentation and/or other materials provided with the distribution.
81 *
82 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
83 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
84 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
85 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
86 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
87 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
88 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
89 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
91 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92 *
93 */
94
95/* OTHER CREDITS:
96 *
97 * This is the normal smoothscale method, based on Imlib2's smoothscale.
98 *
99 * Originally I took the algorithm used in NetPBM and Qt and added MMX/3dnow
100 * optimizations. It ran in about 1/2 the time as Qt. Then I ported Imlib's
101 * C algorithm and it ran at about the same speed as my MMX optimized one...
102 * Finally I ported Imlib's MMX version and it ran in less than half the
103 * time as my MMX algorithm, (taking only a quarter of the time Qt does).
104 * After further optimization it seems to run at around 1/6th.
105 *
106 * Changes include formatting, namespaces and other C++'ings, removal of old
107 * #ifdef'ed code, and removal of unneeded border calculation code.
108 *
109 * Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code
110 * is by Willem Monsuwe <[email protected]>. All other modifications are
111 * (C) Daniel M. Duley.
112 */
113
114
115namespace QImageScale {
116 struct QImageScaleInfo {
117 int *xpoints;
118 unsigned int **ypoints;
119 int *xapoints, *yapoints;
120 int xup_yup;
121 };
122
123 unsigned int** qimageCalcYPoints(unsigned int *src, int sw, int sh,
124 int dh);
125 int* qimageCalcXPoints(int sw, int dw);
126 int* qimageCalcApoints(int s, int d, int up);
127 QImageScaleInfo* qimageFreeScaleInfo(QImageScaleInfo *isi);
128 QImageScaleInfo *qimageCalcScaleInfo(const QImage &img, int sw, int sh,
129 int dw, int dh, char aa);
130}
131
132using namespace QImageScale;
133
134//
135// Code ported from Imlib...
136//
137
138// FIXME: replace with qRed, etc... These work on pointers to pixels, not
139// pixel values
140#define A_VAL(p) (qAlpha(*p))
141#define R_VAL(p) (qRed(*p))
142#define G_VAL(p) (qGreen(*p))
143#define B_VAL(p) (qBlue(*p))
144
145#define INV_XAP (256 - xapoints[x])
146#define XAP (xapoints[x])
147#define INV_YAP (256 - yapoints[dyy + y])
148#define YAP (yapoints[dyy + y])
149
150unsigned int** QImageScale::qimageCalcYPoints(unsigned int *src,
151 int sw, int sh, int dh)
152{
153 unsigned int **p;
154 int i, j = 0;
155 int val, inc, rv = 0;
156
157 if(dh < 0){
158 dh = -dh;
159 rv = 1;
160 }
161 p = new unsigned int* [dh+1];
162
163 int up = qAbs(dh) >= sh;
164 val = up ? 0x8000 * sh / dh - 0x8000 : 0;
165 inc = (sh << 16) / dh;
166 for(i = 0; i < dh; i++){
167 p[j++] = src + qMax(0, val >> 16) * sw;
168 val += inc;
169 }
170 if(rv){
171 for(i = dh / 2; --i >= 0; ){
172 unsigned int *tmp = p[i];
173 p[i] = p[dh - i - 1];
174 p[dh - i - 1] = tmp;
175 }
176 }
177 return(p);
178}
179
180int* QImageScale::qimageCalcXPoints(int sw, int dw)
181{
182 int *p, i, j = 0;
183 int val, inc, rv = 0;
184
185 if(dw < 0){
186 dw = -dw;
187 rv = 1;
188 }
189 p = new int[dw+1];
190
191 int up = qAbs(dw) >= sw;
192 val = up ? 0x8000 * sw / dw - 0x8000 : 0;
193 inc = (sw << 16) / dw;
194 for(i = 0; i < dw; i++){
195 p[j++] = qMax(0, val >> 16);
196 val += inc;
197 }
198
199 if(rv){
200 for(i = dw / 2; --i >= 0; ){
201 int tmp = p[i];
202 p[i] = p[dw - i - 1];
203 p[dw - i - 1] = tmp;
204 }
205 }
206 return(p);
207}
208
209int* QImageScale::qimageCalcApoints(int s, int d, int up)
210{
211 int *p, i, j = 0, rv = 0;
212
213 if(d < 0){
214 rv = 1;
215 d = -d;
216 }
217 p = new int[d];
218
219 /* scaling up */
220 if(up){
221 int val, inc;
222
223 val = 0x8000 * s / d - 0x8000;
224 inc = (s << 16) / d;
225 for(i = 0; i < d; i++){
226 int pos = val >> 16;
227 if (pos < 0)
228 p[j++] = 0;
229 else if (pos >= (s - 1))
230 p[j++] = 0;
231 else
232 p[j++] = (val >> 8) - ((val >> 8) & 0xffffff00);
233 val += inc;
234 }
235 }
236 /* scaling down */
237 else{
238 int val, inc, ap, Cp;
239 val = 0;
240 inc = (s << 16) / d;
241 Cp = ((d << 14) / s) + 1;
242 for(i = 0; i < d; i++){
243 ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8;
244 p[j] = ap | (Cp << 16);
245 j++;
246 val += inc;
247 }
248 }
249 if(rv){
250 int tmp;
251 for(i = d / 2; --i >= 0; ){
252 tmp = p[i];
253 p[i] = p[d - i - 1];
254 p[d - i - 1] = tmp;
255 }
256 }
257 return(p);
258}
259
260QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi)
261{
262 if(isi){
263 delete[] isi->xpoints;
264 delete[] isi->ypoints;
265 delete[] isi->xapoints;
266 delete[] isi->yapoints;
267 delete isi;
268 }
269 return 0;
270}
271
272QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
273 int sw, int sh,
274 int dw, int dh, char aa)
275{
276 QImageScaleInfo *isi;
277 int scw, sch;
278
279 scw = dw * qlonglong(img.width()) / sw;
280 sch = dh * qlonglong(img.height()) / sh;
281
282 isi = new QImageScaleInfo;
283 if(!isi)
284 return 0;
285 memset(isi, 0, sizeof(QImageScaleInfo));
286
287 isi->xup_yup = (qAbs(dw) >= sw) + ((qAbs(dh) >= sh) << 1);
288
289 isi->xpoints = qimageCalcXPoints(img.width(), scw);
290 if(!isi->xpoints)
291 return(qimageFreeScaleInfo(isi));
292 isi->ypoints = qimageCalcYPoints((unsigned int *)img.scanLine(0),
293 img.bytesPerLine() / 4, img.height(), sch);
294 if (!isi->ypoints)
295 return(qimageFreeScaleInfo(isi));
296 if(aa) {
297 isi->xapoints = qimageCalcApoints(img.width(), scw, isi->xup_yup & 1);
298 if(!isi->xapoints)
299 return(qimageFreeScaleInfo(isi));
300 isi->yapoints = qimageCalcApoints(img.height(), sch, isi->xup_yup & 2);
301 if(!isi->yapoints)
302 return(qimageFreeScaleInfo(isi));
303 }
304 return(isi);
305}
306
307/* FIXME: NEED to optimise ScaleAARGBA - currently its "ok" but needs work*/
308
309/* scale by area sampling */
310static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
311 int dxx, int dyy, int dx, int dy, int dw,
312 int dh, int dow, int sow)
313{
314 unsigned int *sptr, *dptr;
315 int x, y, end;
316 unsigned int **ypoints = isi->ypoints;
317 int *xpoints = isi->xpoints;
318 int *xapoints = isi->xapoints;
319 int *yapoints = isi->yapoints;
320
321 end = dxx + dw;
322 /* scaling up both ways */
323 if(isi->xup_yup == 3){
324 /* go through every scanline in the output buffer */
325 for(y = 0; y < dh; y++){
326 /* calculate the source line we'll scan from */
327 dptr = dest + dx + ((y + dy) * dow);
328 sptr = ypoints[dyy + y];
329 if(YAP > 0){
330 for(x = dxx; x < end; x++){
331 int r, g, b, a;
332 int rr, gg, bb, aa;
333 unsigned int *pix;
334
335 if(XAP > 0){
336 pix = ypoints[dyy + y] + xpoints[x];
337 r = R_VAL(pix) * INV_XAP;
338 g = G_VAL(pix) * INV_XAP;
339 b = B_VAL(pix) * INV_XAP;
340 a = A_VAL(pix) * INV_XAP;
341 pix++;
342 r += R_VAL(pix) * XAP;
343 g += G_VAL(pix) * XAP;
344 b += B_VAL(pix) * XAP;
345 a += A_VAL(pix) * XAP;
346 pix += sow;
347 rr = R_VAL(pix) * XAP;
348 gg = G_VAL(pix) * XAP;
349 bb = B_VAL(pix) * XAP;
350 aa = A_VAL(pix) * XAP;
351 pix--;
352 rr += R_VAL(pix) * INV_XAP;
353 gg += G_VAL(pix) * INV_XAP;
354 bb += B_VAL(pix) * INV_XAP;
355 aa += A_VAL(pix) * INV_XAP;
356 r = ((rr * YAP) + (r * INV_YAP)) >> 16;
357 g = ((gg * YAP) + (g * INV_YAP)) >> 16;
358 b = ((bb * YAP) + (b * INV_YAP)) >> 16;
359 a = ((aa * YAP) + (a * INV_YAP)) >> 16;
360 *dptr++ = qRgba(r, g, b, a);
361 }
362 else{
363 pix = ypoints[dyy + y] + xpoints[x];
364 r = R_VAL(pix) * INV_YAP;
365 g = G_VAL(pix) * INV_YAP;
366 b = B_VAL(pix) * INV_YAP;
367 a = A_VAL(pix) * INV_YAP;
368 pix += sow;
369 r += R_VAL(pix) * YAP;
370 g += G_VAL(pix) * YAP;
371 b += B_VAL(pix) * YAP;
372 a += A_VAL(pix) * YAP;
373 r >>= 8;
374 g >>= 8;
375 b >>= 8;
376 a >>= 8;
377 *dptr++ = qRgba(r, g, b, a);
378 }
379 }
380 }
381 else{
382 for(x = dxx; x < end; x++){
383 int r, g, b, a;
384 unsigned int *pix;
385
386 if(XAP > 0){
387 pix = ypoints[dyy + y] + xpoints[x];
388 r = R_VAL(pix) * INV_XAP;
389 g = G_VAL(pix) * INV_XAP;
390 b = B_VAL(pix) * INV_XAP;
391 a = A_VAL(pix) * INV_XAP;
392 pix++;
393 r += R_VAL(pix) * XAP;
394 g += G_VAL(pix) * XAP;
395 b += B_VAL(pix) * XAP;
396 a += A_VAL(pix) * XAP;
397 r >>= 8;
398 g >>= 8;
399 b >>= 8;
400 a >>= 8;
401 *dptr++ = qRgba(r, g, b, a);
402 }
403 else
404 *dptr++ = sptr[xpoints[x] ];
405 }
406 }
407 }
408 }
409 /* if we're scaling down vertically */
410 else if(isi->xup_yup == 1){
411 /*\ 'Correct' version, with math units prepared for MMXification \*/
412 int Cy, j;
413 unsigned int *pix;
414 int r, g, b, a, rr, gg, bb, aa;
415 int yap;
416
417 /* go through every scanline in the output buffer */
418 for(y = 0; y < dh; y++){
419 Cy = YAP >> 16;
420 yap = YAP & 0xffff;
421
422 dptr = dest + dx + ((y + dy) * dow);
423 for(x = dxx; x < end; x++){
424 pix = ypoints[dyy + y] + xpoints[x];
425 r = R_VAL(pix) * yap;
426 g = G_VAL(pix) * yap;
427 b = B_VAL(pix) * yap;
428 a = A_VAL(pix) * yap;
429 for(j = (1 << 14) - yap; j > Cy; j -= Cy){
430 pix += sow;
431 r += R_VAL(pix) * Cy;
432 g += G_VAL(pix) * Cy;
433 b += B_VAL(pix) * Cy;
434 a += A_VAL(pix) * Cy;
435 }
436 if(j > 0){
437 pix += sow;
438 r += R_VAL(pix) * j;
439 g += G_VAL(pix) * j;
440 b += B_VAL(pix) * j;
441 a += A_VAL(pix) * j;
442 }
443 if(XAP > 0){
444 pix = ypoints[dyy + y] + xpoints[x] + 1;
445 rr = R_VAL(pix) * yap;
446 gg = G_VAL(pix) * yap;
447 bb = B_VAL(pix) * yap;
448 aa = A_VAL(pix) * yap;
449 for(j = (1 << 14) - yap; j > Cy; j -= Cy){
450 pix += sow;
451 rr += R_VAL(pix) * Cy;
452 gg += G_VAL(pix) * Cy;
453 bb += B_VAL(pix) * Cy;
454 aa += A_VAL(pix) * Cy;
455 }
456 if(j > 0){
457 pix += sow;
458 rr += R_VAL(pix) * j;
459 gg += G_VAL(pix) * j;
460 bb += B_VAL(pix) * j;
461 aa += A_VAL(pix) * j;
462 }
463 r = r * INV_XAP;
464 g = g * INV_XAP;
465 b = b * INV_XAP;
466 a = a * INV_XAP;
467 r = (r + ((rr * XAP))) >> 12;
468 g = (g + ((gg * XAP))) >> 12;
469 b = (b + ((bb * XAP))) >> 12;
470 a = (a + ((aa * XAP))) >> 12;
471 }
472 else{
473 r >>= 4;
474 g >>= 4;
475 b >>= 4;
476 a >>= 4;
477 }
478 *dptr = qRgba(r >> 10, g >> 10, b >> 10, a >> 10);
479 dptr++;
480 }
481 }
482 }
483 /* if we're scaling down horizontally */
484 else if(isi->xup_yup == 2){
485 /*\ 'Correct' version, with math units prepared for MMXification \*/
486 int Cx, j;
487 unsigned int *pix;
488 int r, g, b, a, rr, gg, bb, aa;
489 int xap;
490
491 /* go through every scanline in the output buffer */
492 for(y = 0; y < dh; y++){
493 dptr = dest + dx + ((y + dy) * dow);
494 for(x = dxx; x < end; x++){
495 Cx = XAP >> 16;
496 xap = XAP & 0xffff;
497
498 pix = ypoints[dyy + y] + xpoints[x];
499 r = R_VAL(pix) * xap;
500 g = G_VAL(pix) * xap;
501 b = B_VAL(pix) * xap;
502 a = A_VAL(pix) * xap;
503 for(j = (1 << 14) - xap; j > Cx; j -= Cx){
504 pix++;
505 r += R_VAL(pix) * Cx;
506 g += G_VAL(pix) * Cx;
507 b += B_VAL(pix) * Cx;
508 a += A_VAL(pix) * Cx;
509 }
510 if(j > 0){
511 pix++;
512 r += R_VAL(pix) * j;
513 g += G_VAL(pix) * j;
514 b += B_VAL(pix) * j;
515 a += A_VAL(pix) * j;
516 }
517 if(YAP > 0){
518 pix = ypoints[dyy + y] + xpoints[x] + sow;
519 rr = R_VAL(pix) * xap;
520 gg = G_VAL(pix) * xap;
521 bb = B_VAL(pix) * xap;
522 aa = A_VAL(pix) * xap;
523 for(j = (1 << 14) - xap; j > Cx; j -= Cx){
524 pix++;
525 rr += R_VAL(pix) * Cx;
526 gg += G_VAL(pix) * Cx;
527 bb += B_VAL(pix) * Cx;
528 aa += A_VAL(pix) * Cx;
529 }
530 if(j > 0){
531 pix++;
532 rr += R_VAL(pix) * j;
533 gg += G_VAL(pix) * j;
534 bb += B_VAL(pix) * j;
535 aa += A_VAL(pix) * j;
536 }
537 r = r * INV_YAP;
538 g = g * INV_YAP;
539 b = b * INV_YAP;
540 a = a * INV_YAP;
541 r = (r + ((rr * YAP))) >> 12;
542 g = (g + ((gg * YAP))) >> 12;
543 b = (b + ((bb * YAP))) >> 12;
544 a = (a + ((aa * YAP))) >> 12;
545 }
546 else{
547 r >>= 4;
548 g >>= 4;
549 b >>= 4;
550 a >>= 4;
551 }
552 *dptr = qRgba(r >> 10, g >> 10, b >> 10, a >> 10);
553 dptr++;
554 }
555 }
556 }
557 /* if we're scaling down horizontally & vertically */
558 else{
559 /*\ 'Correct' version, with math units prepared for MMXification:
560 |*| The operation 'b = (b * c) >> 16' translates to pmulhw,
561 |*| so the operation 'b = (b * c) >> d' would translate to
562 |*| psllw (16 - d), %mmb; pmulh %mmc, %mmb
563 \*/
564 int Cx, Cy, i, j;
565 unsigned int *pix;
566 int a, r, g, b, ax, rx, gx, bx;
567 int xap, yap;
568
569 for(y = 0; y < dh; y++){
570 Cy = YAP >> 16;
571 yap = YAP & 0xffff;
572
573 dptr = dest + dx + ((y + dy) * dow);
574 for(x = dxx; x < end; x++){
575 Cx = XAP >> 16;
576 xap = XAP & 0xffff;
577
578 sptr = ypoints[dyy + y] + xpoints[x];
579 pix = sptr;
580 sptr += sow;
581 rx = R_VAL(pix) * xap;
582 gx = G_VAL(pix) * xap;
583 bx = B_VAL(pix) * xap;
584 ax = A_VAL(pix) * xap;
585
586 pix++;
587 for(i = (1 << 14) - xap; i > Cx; i -= Cx){
588 rx += R_VAL(pix) * Cx;
589 gx += G_VAL(pix) * Cx;
590 bx += B_VAL(pix) * Cx;
591 ax += A_VAL(pix) * Cx;
592 pix++;
593 }
594 if(i > 0){
595 rx += R_VAL(pix) * i;
596 gx += G_VAL(pix) * i;
597 bx += B_VAL(pix) * i;
598 ax += A_VAL(pix) * i;
599 }
600
601 r = (rx >> 5) * yap;
602 g = (gx >> 5) * yap;
603 b = (bx >> 5) * yap;
604 a = (ax >> 5) * yap;
605
606 for(j = (1 << 14) - yap; j > Cy; j -= Cy){
607 pix = sptr;
608 sptr += sow;
609 rx = R_VAL(pix) * xap;
610 gx = G_VAL(pix) * xap;
611 bx = B_VAL(pix) * xap;
612 ax = A_VAL(pix) * xap;
613 pix++;
614 for(i = (1 << 14) - xap; i > Cx; i -= Cx){
615 rx += R_VAL(pix) * Cx;
616 gx += G_VAL(pix) * Cx;
617 bx += B_VAL(pix) * Cx;
618 ax += A_VAL(pix) * Cx;
619 pix++;
620 }
621 if(i > 0){
622 rx += R_VAL(pix) * i;
623 gx += G_VAL(pix) * i;
624 bx += B_VAL(pix) * i;
625 ax += A_VAL(pix) * i;
626 }
627
628 r += (rx >> 5) * Cy;
629 g += (gx >> 5) * Cy;
630 b += (bx >> 5) * Cy;
631 a += (ax >> 5) * Cy;
632 }
633 if(j > 0){
634 pix = sptr;
635 sptr += sow;
636 rx = R_VAL(pix) * xap;
637 gx = G_VAL(pix) * xap;
638 bx = B_VAL(pix) * xap;
639 ax = A_VAL(pix) * xap;
640 pix++;
641 for(i = (1 << 14) - xap; i > Cx; i -= Cx){
642 rx += R_VAL(pix) * Cx;
643 gx += G_VAL(pix) * Cx;
644 bx += B_VAL(pix) * Cx;
645 ax += A_VAL(pix) * Cx;
646 pix++;
647 }
648 if(i > 0){
649 rx += R_VAL(pix) * i;
650 gx += G_VAL(pix) * i;
651 bx += B_VAL(pix) * i;
652 ax += A_VAL(pix) * i;
653 }
654
655 r += (rx >> 5) * j;
656 g += (gx >> 5) * j;
657 b += (bx >> 5) * j;
658 a += (ax >> 5) * j;
659 }
660
661 *dptr = qRgba(r >> 23, g >> 23, b >> 23, a >> 23);
662 dptr++;
663 }
664 }
665 }
666}
667
668/* scale by area sampling - IGNORE the ALPHA byte*/
669static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
670 int dxx, int dyy, int dx, int dy, int dw,
671 int dh, int dow, int sow)
672{
673 unsigned int *sptr, *dptr;
674 int x, y, end;
675 unsigned int **ypoints = isi->ypoints;
676 int *xpoints = isi->xpoints;
677 int *xapoints = isi->xapoints;
678 int *yapoints = isi->yapoints;
679
680 end = dxx + dw;
681 /* scaling up both ways */
682 if(isi->xup_yup == 3){