~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to ksplash/ksplashx/scale.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// This code is Imlib2 code, additionally modified by Mosfet, and with few small
 
2
// modifications for Gwenview. The MMX scaling code also belongs to it.
 
3
 
 
4
// The original license texts follow.
 
5
 
 
6
/**
 
7
 * This is the normal smoothscale method, based on Imlib2's smoothscale.
 
8
 *
 
9
 * Originally I took the algorithm used in NetPBM and Qt and added MMX/3dnow
 
10
 * optimizations. It ran in about 1/2 the time as Qt. Then I ported Imlib's
 
11
 * C algorithm and it ran at about the same speed as my MMX optimized one...
 
12
 * Finally I ported Imlib's MMX version and it ran in less than half the
 
13
 * time as my MMX algorithm, (taking only a quarter of the time Qt does).
 
14
 *
 
15
 * Changes include formatting, namespaces and other C++'ings, removal of old
 
16
 * #ifdef'ed code, and removal of unneeded border calculation code.
 
17
 *
 
18
 * Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code
 
19
 * is by Willem Monsuwe <willem@stack.nl>. All other modifications are
 
20
 * (C) Daniel M. Duley.
 
21
 */
 
22
 
 
23
/*
 
24
    Copyright (C) 2004 Daniel M. Duley <dan.duley@verizon.net>
 
25
 
 
26
Redistribution and use in source and binary forms, with or without
 
27
modification, are permitted provided that the following conditions
 
28
are met:
 
29
 
 
30
1. Redistributions of source code must retain the above copyright
 
31
   notice, this list of conditions and the following disclaimer.
 
32
2. Redistributions in binary form must reproduce the above copyright
 
33
   notice, this list of conditions and the following disclaimer in the
 
34
   documentation and/or other materials provided with the distribution.
 
35
 
 
36
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
37
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
38
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
39
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
40
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
41
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
42
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
43
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
44
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
45
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
46
 
 
47
*/
 
48
 
 
49
/*
 
50
Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS)
 
51
 
 
52
Permission is hereby granted, free of charge, to any person obtaining a copy
 
53
of this software and associated documentation files (the "Software"), to
 
54
deal in the Software without restriction, including without limitation the
 
55
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 
56
sell copies of the Software, and to permit persons to whom the Software is
 
57
furnished to do so, subject to the following conditions:
 
58
 
 
59
The above copyright notice and this permission notice shall be included in
 
60
all copies of the Software and its Copyright notices. In addition publicly
 
61
documented acknowledgment must be given that this software has been used if no
 
62
source code of this software is made available publicly. This includes
 
63
acknowledgments in either Copyright notices, Manuals, Publicity and Marketing
 
64
documents or any documentation provided with any product containing this
 
65
software. This License does not apply to any software that links to the
 
66
libraries provided by this software (statically or dynamically), but only to
 
67
the software provided.
 
68
 
 
69
Please see the COPYING.PLAIN for a plain-english explanation of this notice
 
70
and it's intent.
 
71
 
 
72
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
73
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
74
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
75
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
 
76
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
77
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
78
*/
 
79
 
 
80
#include <config-workspace.h>
 
81
 
 
82
#include "scale.h"
 
83
 
 
84
#include <string.h>
 
85
 
 
86
#include "kcpuinfo.h"
 
87
#include "qcolor.h"
 
88
 
 
89
namespace MImageScale{
 
90
    typedef struct __mimage_scale_info
 
91
    {
 
92
        int *xpoints;
 
93
        unsigned int **ypoints;
 
94
        int *xapoints, *yapoints;
 
95
        int xup_yup;
 
96
    } MImageScaleInfo;
 
97
 
 
98
    unsigned int** mimageCalcYPoints(unsigned int *src, int sw, int sh,
 
99
                                     int dh);
 
100
    int* mimageCalcXPoints(int sw, int dw);
 
101
    int* mimageCalcApoints(int s, int d, int up);
 
102
    MImageScaleInfo* mimageFreeScaleInfo(MImageScaleInfo *isi);
 
103
    MImageScaleInfo *mimageCalcScaleInfo(QImage &img, int sw, int sh,
 
104
                                         int dw, int dh, char aa);
 
105
    void mimageSampleRGBA(MImageScaleInfo *isi, unsigned int *dest, int dxx,
 
106
                          int dyy, int dx, int dy, int dw, int dh, int dow);
 
107
    void mimageScaleAARGBA(MImageScaleInfo *isi, unsigned int *dest, int dxx,
 
108
                           int dyy, int dx, int dy, int dw, int dh, int dow,
 
109
                           int sow);
 
110
    void mimageScaleAARGB(MImageScaleInfo *isi, unsigned int *dest, int dxx,
 
111
                          int dyy, int dx, int dy, int dw, int dh, int dow, int
 
112
                          sow);
 
113
    QImage smoothScale(const QImage& img, int dw, int dh);
 
114
}
 
115
 
 
116
#ifdef HAVE_X86_MMX
 
117
extern "C" {
 
118
    void __mimageScale_mmx_AARGBA(MImageScale::MImageScaleInfo *isi,
 
119
                                  unsigned int *dest, int dxx, int dyy,
 
120
                                  int dx, int dy, int dw, int dh,
 
121
                                  int dow, int sow);
 
122
};
 
123
#endif
 
124
 
 
125
using namespace MImageScale;
 
126
 
 
127
QImage MImageScale::smoothScale(const QImage& image, int dw, int dh)
 
128
{
 
129
    QImage img = image.depth() < 32 ? image.convertDepth( 32 ) : image;
 
130
    int w = img.width();
 
131
    int h = img.height();
 
132
 
 
133
    MImageScaleInfo *scaleinfo =
 
134
        mimageCalcScaleInfo(img, w, h, dw, dh, true);
 
135
    if(!scaleinfo)
 
136
        return QImage();
 
137
 
 
138
    QImage buffer(dw, dh, 32);
 
139
    buffer.setAlphaBuffer(img.hasAlphaBuffer());
 
140
 
 
141
#ifdef HAVE_X86_MMX
 
142
//#warning Using MMX Smoothscale
 
143
    bool haveMMX = KCPUInfo::haveExtension( KCPUInfo::IntelMMX );
 
144
    if(haveMMX){
 
145
        __mimageScale_mmx_AARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0),
 
146
                                 0, 0, 0, 0, dw, dh, dw, w);
 
147
    }
 
148
    else
 
149
#endif
 
150
    {
 
151
        if(img.hasAlphaBuffer())
 
152
            mimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0,
 
153
                              0, 0, dw, dh, dw, w);
 
154
        else
 
155
            mimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0,
 
156
                             0, 0, dw, dh, dw, w);
 
157
    }
 
158
    mimageFreeScaleInfo(scaleinfo);
 
159
    return(buffer);
 
160
}
 
161
 
 
162
//
 
163
// Code ported from Imlib...
 
164
//
 
165
 
 
166
// FIXME: replace with mRed, etc... These work on pointers to pixels, not
 
167
// pixel values
 
168
#if BYTE_ORDER == BIG_ENDIAN
 
169
#define A_VAL(p) ((unsigned char *)(p))[0]
 
170
#define R_VAL(p) ((unsigned char *)(p))[1]
 
171
#define G_VAL(p) ((unsigned char *)(p))[2]
 
172
#define B_VAL(p) ((unsigned char *)(p))[3]
 
173
#elif BYTE_ORDER == LITTLE_ENDIAN
 
174
#define A_VAL(p) ((unsigned char *)(p))[3]
 
175
#define R_VAL(p) ((unsigned char *)(p))[2]
 
176
#define G_VAL(p) ((unsigned char *)(p))[1]
 
177
#define B_VAL(p) ((unsigned char *)(p))[0]
 
178
#else
 
179
#error "BYTE_ORDER is not defined"
 
180
#endif
 
181
 
 
182
#define INV_XAP                   (256 - xapoints[x])
 
183
#define XAP                       (xapoints[x])
 
184
#define INV_YAP                   (256 - yapoints[dyy + y])
 
185
#define YAP                       (yapoints[dyy + y])
 
186
 
 
187
unsigned int** MImageScale::mimageCalcYPoints(unsigned int *src,
 
188
                                              int sw, int sh, int dh)
 
189
{
 
190
    unsigned int **p;
 
191
    int i, j = 0;
 
192
    int val, inc, rv = 0;
 
193
 
 
194
    if(dh < 0){
 
195
        dh = -dh;
 
196
        rv = 1;
 
197
    }
 
198
    p = new unsigned int* [dh+1];
 
199
 
 
200
    val = 0;
 
201
    inc = (sh << 16) / dh;
 
202
    for(i = 0; i < dh; i++){
 
203
        p[j++] = src + ((val >> 16) * sw);
 
204
        val += inc;
 
205
    }
 
206
    if(rv){
 
207
        for(i = dh / 2; --i >= 0; ){
 
208
            unsigned int *tmp = p[i];
 
209
            p[i] = p[dh - i - 1];
 
210
            p[dh - i - 1] = tmp;
 
211
        }
 
212
    }
 
213
    return(p);
 
214
}
 
215
 
 
216
int* MImageScale::mimageCalcXPoints(int sw, int dw)
 
217
{
 
218
    int *p, i, j = 0;
 
219
    int val, inc, rv = 0;
 
220
 
 
221
    if(dw < 0){
 
222
        dw = -dw;
 
223
        rv = 1;
 
224
    }
 
225
    p = new int[dw+1];
 
226
 
 
227
    val = 0;
 
228
    inc = (sw << 16) / dw;
 
229
    for(i = 0; i < dw; i++){
 
230
        p[j++] = (val >> 16);
 
231
        val += inc;
 
232
    }
 
233
 
 
234
    if(rv){
 
235
        for(i = dw / 2; --i >= 0; ){
 
236
            int tmp = p[i];
 
237
            p[i] = p[dw - i - 1];
 
238
            p[dw - i - 1] = tmp;
 
239
        }
 
240
    }
 
241
   return(p);
 
242
}
 
243
 
 
244
int* MImageScale::mimageCalcApoints(int s, int d, int up)
 
245
{
 
246
    int *p, i, j = 0, rv = 0;
 
247
 
 
248
    if(d < 0){
 
249
        rv = 1;
 
250
        d = -d;
 
251
    }
 
252
    p = new int[d];
 
253
 
 
254
    /* scaling up */
 
255
    if(up){
 
256
        int val, inc;
 
257
 
 
258
        val = 0;
 
259
        inc = (s << 16) / d;
 
260
        for(i = 0; i < d; i++){
 
261
            p[j++] = (val >> 8) - ((val >> 8) & 0xffffff00);
 
262
            if((val >> 16) >= (s - 1))
 
263
                p[j - 1] = 0;
 
264
            val += inc;
 
265
        }
 
266
    }
 
267
    /* scaling down */
 
268
    else{
 
269
        int val, inc, ap, Cp;
 
270
        val = 0;
 
271
        inc = (s << 16) / d;
 
272
        Cp = ((d << 14) / s) + 1;
 
273
        for(i = 0; i < d; i++){
 
274
            ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8;
 
275
            p[j] = ap | (Cp << 16);
 
276
            j++;
 
277
            val += inc;
 
278
        }
 
279
    }
 
280
    if(rv){
 
281
        int tmp;
 
282
        for(i = d / 2; --i >= 0; ){
 
283
            tmp = p[i];
 
284
            p[i] = p[d - i - 1];
 
285
            p[d - i - 1] = tmp;
 
286
        }
 
287
    }
 
288
    return(p);
 
289
}
 
290
 
 
291
MImageScaleInfo* MImageScale::mimageFreeScaleInfo(MImageScaleInfo *isi)
 
292
{
 
293
    if(isi){
 
294
        delete[] isi->xpoints;
 
295
        delete[] isi->ypoints;
 
296
        delete[] isi->xapoints;
 
297
        delete[] isi->yapoints;
 
298
        delete isi;
 
299
    }
 
300
    return(NULL);
 
301
}
 
302
 
 
303
MImageScaleInfo* MImageScale::mimageCalcScaleInfo(QImage &img, int sw, int sh,
 
304
                                                  int dw, int dh, char aa)
 
305
{
 
306
    MImageScaleInfo *isi;
 
307
    int scw, sch;
 
308
 
 
309
    scw = dw * img.width() / sw;
 
310
    sch = dh * img.height() / sh;
 
311
 
 
312
    isi = new MImageScaleInfo;
 
313
    if(!isi)
 
314
        return(NULL);
 
315
    memset(isi, 0, sizeof(MImageScaleInfo));
 
316
 
 
317
    isi->xup_yup = (abs(dw) >= sw) + ((abs(dh) >= sh) << 1);
 
318
 
 
319
    isi->xpoints = mimageCalcXPoints(img.width(), scw);
 
320
    if(!isi->xpoints)
 
321
        return(mimageFreeScaleInfo(isi));
 
322
    isi->ypoints = mimageCalcYPoints((unsigned int *)img.scanLine(0),
 
323
                                     img.width(), img.height(), sch);
 
324
    if (!isi->ypoints)
 
325
        return(mimageFreeScaleInfo(isi));
 
326
    if(aa){
 
327
        isi->xapoints = mimageCalcApoints(img.width(), scw, isi->xup_yup & 1);
 
328
        if(!isi->xapoints)
 
329
            return(mimageFreeScaleInfo(isi));
 
330
        isi->yapoints = mimageCalcApoints(img.height(), sch, isi->xup_yup & 2);
 
331
        if(!isi->yapoints)
 
332
            return(mimageFreeScaleInfo(isi));
 
333
    }
 
334
    return(isi);
 
335
}
 
336
 
 
337
/* scale by pixel sampling only */
 
338
void MImageScale::mimageSampleRGBA(MImageScaleInfo *isi, unsigned int *dest,
 
339
                                   int dxx, int dyy, int dx, int dy, int dw,
 
340
                                   int dh, int dow)
 
341
{
 
342
    unsigned int *sptr, *dptr;
 
343
    int x, y, end;
 
344
    unsigned int **ypoints = isi->ypoints;
 
345
    int *xpoints = isi->xpoints;
 
346
 
 
347
    /* whats the last pixel ont he line so we stop there */
 
348
    end = dxx + dw;
 
349
    /* go through every scanline in the output buffer */
 
350
    for(y = 0; y < dh; y++){
 
351
        /* get the pointer to the start of the destination scanline */
 
352
        dptr = dest + dx + ((y + dy) * dow);
 
353
        /* calculate the source line we'll scan from */
 
354
        sptr = ypoints[dyy + y];
 
355
        /* go thru the scanline and copy across */
 
356
        for(x = dxx; x < end; x++)
 
357
            *dptr++ = sptr[xpoints[x]];
 
358
    }
 
359
}
 
360
 
 
361
/* FIXME: NEED to optimise ScaleAARGBA - currently it is "ok" but needs work*/
 
362
 
 
363
/* scale by area sampling */
 
364
void MImageScale::mimageScaleAARGBA(MImageScaleInfo *isi, unsigned int *dest,
 
365
                                    int dxx, int dyy, int dx, int dy, int dw,
 
366
                                    int dh, int dow, int sow)
 
367
{
 
368
    unsigned int *sptr, *dptr;
 
369
    int x, y, end;
 
370
    unsigned int **ypoints = isi->ypoints;
 
371
    int *xpoints = isi->xpoints;
 
372
    int *xapoints = isi->xapoints;
 
373
    int *yapoints = isi->yapoints;
 
374
 
 
375
    end = dxx + dw;
 
376
    /* scaling up both ways */
 
377
    if(isi->xup_yup == 3){
 
378
        /* go through every scanline in the output buffer */
 
379
        for(y = 0; y < dh; y++){
 
380
            /* calculate the source line we'll scan from */
 
381
            dptr = dest + dx + ((y + dy) * dow);
 
382
            sptr = ypoints[dyy + y];
 
383
            if(YAP > 0){
 
384
                for(x = dxx; x < end; x++){
 
385
                    int r, g, b, a;
 
386
                    int rr, gg, bb, aa;
 
387
                    unsigned int *pix;
 
388
 
 
389
                    if(XAP > 0){
 
390
                        pix = ypoints[dyy + y] + xpoints[x];
 
391
                        r = R_VAL(pix) * INV_XAP;
 
392
                        g = G_VAL(pix) * INV_XAP;
 
393
                        b = B_VAL(pix) * INV_XAP;
 
394
                        a = A_VAL(pix) * INV_XAP;
 
395
                        pix++;
 
396
                        r += R_VAL(pix) * XAP;
 
397
                        g += G_VAL(pix) * XAP;
 
398
                        b += B_VAL(pix) * XAP;
 
399
                        a += A_VAL(pix) * XAP;
 
400
                        pix += sow;
 
401
                        rr = R_VAL(pix) * XAP;
 
402
                        gg = G_VAL(pix) * XAP;
 
403
                        bb = B_VAL(pix) * XAP;
 
404
                        aa = A_VAL(pix) * XAP;
 
405
                        pix--;
 
406
                        rr += R_VAL(pix) * INV_XAP;
 
407
                        gg += G_VAL(pix) * INV_XAP;
 
408
                        bb += B_VAL(pix) * INV_XAP;
 
409
                        aa += A_VAL(pix) * INV_XAP;
 
410
                        r = ((rr * YAP) + (r * INV_YAP)) >> 16;
 
411
                        g = ((gg * YAP) + (g * INV_YAP)) >> 16;
 
412
                        b = ((bb * YAP) + (b * INV_YAP)) >> 16;
 
413
                        a = ((aa * YAP) + (a * INV_YAP)) >> 16;
 
414
                        *dptr++ = qRgba(r, g, b, a);
 
415
                    }
 
416
                    else{
 
417
                        pix = ypoints[dyy + y] + xpoints[x];
 
418
                        r = R_VAL(pix) * INV_YAP;
 
419
                        g = G_VAL(pix) * INV_YAP;
 
420
                        b = B_VAL(pix) * INV_YAP;
 
421
                        a = A_VAL(pix) * INV_YAP;
 
422
                        pix += sow;
 
423
                        r += R_VAL(pix) * YAP;
 
424
                        g += G_VAL(pix) * YAP;
 
425
                        b += B_VAL(pix) * YAP;
 
426
                        a += A_VAL(pix) * YAP;
 
427
                        r >>= 8;
 
428
                        g >>= 8;
 
429
                        b >>= 8;
 
430
                        a >>= 8;
 
431
                        *dptr++ = qRgba(r, g, b, a);
 
432
                    }
 
433
                }
 
434
            }
 
435
            else{
 
436
                for(x = dxx; x < end; x++){
 
437
                    int r, g, b, a;
 
438
                    unsigned int *pix;
 
439
 
 
440
                    if(XAP > 0){
 
441
                        pix = ypoints[dyy + y] + xpoints[x];
 
442
                        r = R_VAL(pix) * INV_XAP;
 
443
                        g = G_VAL(pix) * INV_XAP;
 
444
                        b = B_VAL(pix) * INV_XAP;
 
445
                        a = A_VAL(pix) * INV_XAP;
 
446
                        pix++;
 
447
                        r += R_VAL(pix) * XAP;
 
448
                        g += G_VAL(pix) * XAP;
 
449
                        b += B_VAL(pix) * XAP;
 
450
                        a += A_VAL(pix) * XAP;
 
451
                        r >>= 8;
 
452
                        g >>= 8;
 
453
                        b >>= 8;
 
454
                        a >>= 8;
 
455
                        *dptr++ = qRgba(r, g, b, a);
 
456
                    }
 
457
                    else
 
458
                        *dptr++ = sptr[xpoints[x] ];
 
459
                }
 
460
            }
 
461
        }
 
462
    }
 
463
    /* if we're scaling down vertically */
 
464
    else if(isi->xup_yup == 1){
 
465
        /*\ 'Correct' version, with math units prepared for MMXification \*/
 
466
        int Cy, j;
 
467
        unsigned int *pix;
 
468
        int r, g, b, a, rr, gg, bb, aa;
 
469
        int yap;
 
470
                 
 
471
        /* go through every scanline in the output buffer */
 
472
        for(y = 0; y < dh; y++){
 
473
            Cy = YAP >> 16;
 
474
            yap = YAP & 0xffff;
 
475
 
 
476
            dptr = dest + dx + ((y + dy) * dow);
 
477
            for(x = dxx; x < end; x++){
 
478
                pix = ypoints[dyy + y] + xpoints[x];
 
479
                r = (R_VAL(pix) * yap) >> 10;
 
480
                g = (G_VAL(pix) * yap) >> 10;
 
481
                b = (B_VAL(pix) * yap) >> 10;
 
482
                a = (A_VAL(pix) * yap) >> 10;
 
483
                for(j = (1 << 14) - yap; j > Cy; j -= Cy){
 
484
                    pix += sow;
 
485
                    r += (R_VAL(pix) * Cy) >> 10;
 
486
                    g += (G_VAL(pix) * Cy) >> 10;
 
487
                    b += (B_VAL(pix) * Cy) >> 10;
 
488
                    a += (A_VAL(pix) * Cy) >> 10;
 
489
                }
 
490
                if(j > 0){
 
491
                    pix += sow;
 
492
                    r += (R_VAL(pix) * j) >> 10;
 
493
                    g += (G_VAL(pix) * j) >> 10;
 
494
                    b += (B_VAL(pix) * j) >> 10;
 
495
                    a += (A_VAL(pix) * j) >> 10;
 
496
                }
 
497
                if(XAP > 0){
 
498
                    pix = ypoints[dyy + y] + xpoints[x] + 1;
 
499
                    rr = (R_VAL(pix) * yap) >> 10;
 
500
                    gg = (G_VAL(pix) * yap) >> 10;
 
501
                    bb = (B_VAL(pix) * yap) >> 10;
 
502
                    aa = (A_VAL(pix) * yap) >> 10;
 
503
                    for(j = (1 << 14) - yap; j > Cy; j -= Cy){
 
504
                        pix += sow;
 
505
                        rr += (R_VAL(pix) * Cy) >> 10;
 
506
                        gg += (G_VAL(pix) * Cy) >> 10;
 
507
                        bb += (B_VAL(pix) * Cy) >> 10;
 
508
                        aa += (A_VAL(pix) * Cy) >> 10;
 
509
                    }
 
510
                    if(j > 0){
 
511
                        pix += sow;
 
512
                        rr += (R_VAL(pix) * j) >> 10;
 
513
                        gg += (G_VAL(pix) * j) >> 10;
 
514
                        bb += (B_VAL(pix) * j) >> 10;
 
515
                        aa += (A_VAL(pix) * j) >> 10;
 
516
                    }
 
517
                    r = r * INV_XAP;
 
518
                    g = g * INV_XAP;
 
519
                    b = b * INV_XAP;
 
520
                    a = a * INV_XAP;
 
521
                    r = (r + ((rr * XAP))) >> 12;
 
522
                    g = (g + ((gg * XAP))) >> 12;
 
523
                    b = (b + ((bb * XAP))) >> 12;
 
524
                    a = (a + ((aa * XAP))) >> 12;
 
525
                }
 
526
                else{
 
527
                    r >>= 4;
 
528
                    g >>= 4;
 
529
                    b >>= 4;
 
530
                    a >>= 4;
 
531
                }
 
532
                *dptr = qRgba(r, g, b, a);
 
533
                dptr++;
 
534
            }
 
535
        }
 
536
    }
 
537
    /* if we're scaling down horizontally */
 
538
    else if(isi->xup_yup == 2){
 
539
        /*\ 'Correct' version, with math units prepared for MMXification \*/
 
540
        int Cx, j;
 
541
        unsigned int *pix;
 
542
        int r, g, b, a, rr, gg, bb, aa;
 
543
        int xap;
 
544
 
 
545
        /* go through every scanline in the output buffer */
 
546
        for(y = 0; y < dh; y++){
 
547
            dptr = dest + dx + ((y + dy) * dow);
 
548
            for(x = dxx; x < end; x++){
 
549
                Cx = XAP >> 16;
 
550
                xap = XAP & 0xffff;
 
551
 
 
552
                pix = ypoints[dyy + y] + xpoints[x];
 
553
                r = (R_VAL(pix) * xap) >> 10;
 
554
                g = (G_VAL(pix) * xap) >> 10;
 
555
                b = (B_VAL(pix) * xap) >> 10;
 
556
                a = (A_VAL(pix) * xap) >> 10;
 
557
                for(j = (1 << 14) - xap; j > Cx; j -= Cx){
 
558
                    pix++;
 
559
                    r += (R_VAL(pix) * Cx) >> 10;
 
560
                    g += (G_VAL(pix) * Cx) >> 10;
 
561
                    b += (B_VAL(pix) * Cx) >> 10;
 
562
                    a += (A_VAL(pix) * Cx) >> 10;
 
563
                }
 
564
                if(j > 0){
 
565
                    pix++;
 
566
                    r += (R_VAL(pix) * j) >> 10;
 
567
                    g += (G_VAL(pix) * j) >> 10;
 
568
                    b += (B_VAL(pix) * j) >> 10;
 
569
                    a += (A_VAL(pix) * j) >> 10;
 
570
                }
 
571
                if(YAP > 0){
 
572
                    pix = ypoints[dyy + y] + xpoints[x] + sow;
 
573
                    rr = (R_VAL(pix) * xap) >> 10;
 
574
                    gg = (G_VAL(pix) * xap) >> 10;
 
575
                    bb = (B_VAL(pix) * xap) >> 10;
 
576
                    aa = (A_VAL(pix) * xap) >> 10;
 
577
                    for(j = (1 << 14) - xap; j > Cx; j -= Cx){
 
578
                        pix++;
 
579
                        rr += (R_VAL(pix) * Cx) >> 10;
 
580
                        gg += (G_VAL(pix) * Cx) >> 10;
 
581
                        bb += (B_VAL(pix) * Cx) >> 10;
 
582
                        aa += (A_VAL(pix) * Cx) >> 10;
 
583
                    }
 
584
                    if(j > 0){
 
585
                        pix++;
 
586
                        rr += (R_VAL(pix) * j) >> 10;
 
587
                        gg += (G_VAL(pix) * j) >> 10;
 
588
                        bb += (B_VAL(pix) * j) >> 10;
 
589
                        aa += (A_VAL(pix) * j) >> 10;
 
590
                    }
 
591
                    r = r * INV_YAP;
 
592
                    g = g * INV_YAP;
 
593
                    b = b * INV_YAP;
 
594
                    a = a * INV_YAP;
 
595
                    r = (r + ((rr * YAP))) >> 12;
 
596
                    g = (g + ((gg * YAP))) >> 12;
 
597
                    b = (b + ((bb * YAP))) >> 12;
 
598
                    a = (a + ((aa * YAP))) >> 12;
 
599
                }
 
600
                else{
 
601
                    r >>= 4;
 
602
                    g >>= 4;
 
603
                    b >>= 4;
 
604
                    a >>= 4;
 
605
                }
 
606
                *dptr = qRgba(r, g, b, a);
 
607
                dptr++;
 
608
            }
 
609
        }
 
610
    }
 
611
    /* if we're scaling down horizontally & vertically */
 
612
    else{
 
613
        /*\ 'Correct' version, with math units prepared for MMXification:
 
614
         |*|  The operation 'b = (b * c) >> 16' translates to pmulhw,
 
615
         |*|  so the operation 'b = (b * c) >> d' would translate to
 
616
         |*|  psllw (16 - d), %mmb; pmulh %mmc, %mmb
 
617
         \*/
 
618
        int Cx, Cy, i, j;
 
619
        unsigned int *pix;
 
620
        int a, r, g, b, ax, rx, gx, bx;
 
621
        int xap, yap;
 
622
 
 
623
        for(y = 0; y < dh; y++){
 
624
            Cy = YAP >> 16;
 
625
            yap = YAP & 0xffff;
 
626
 
 
627
            dptr = dest + dx + ((y + dy) * dow);
 
628
            for(x = dxx; x < end; x++){
 
629
                Cx = XAP >> 16;
 
630
                xap = XAP & 0xffff;
 
631
 
 
632
                sptr = ypoints[dyy + y] + xpoints[x];
 
633
                pix = sptr;
 
634
                sptr += sow;
 
635
                rx = (R_VAL(pix) * xap) >> 9;
 
636
                gx = (G_VAL(pix) * xap) >> 9;
 
637
                bx = (B_VAL(pix) * xap) >> 9;
 
638
                ax = (A_VAL(pix) * xap) >> 9;
 
639
                pix++;
 
640
                for(i = (1 << 14) - xap; i > Cx; i -= Cx){
 
641
                    rx += (R_VAL(pix) * Cx) >> 9;
 
642
                    gx += (G_VAL(pix) * Cx) >> 9;
 
643
                    bx += (B_VAL(pix) * Cx) >> 9;
 
644
                    ax += (A_VAL(pix) * Cx) >> 9;
 
645
                    pix++;
 
646
                }
 
647
                if(i > 0){
 
648
                    rx += (R_VAL(pix) * i) >> 9;
 
649
                    gx += (G_VAL(pix) * i) >> 9;
 
650
                    bx += (B_VAL(pix) * i) >> 9;
 
651
                    ax += (A_VAL(pix) * i) >> 9;
 
652
                }
 
653
 
 
654
                r = (rx * yap) >> 14;
 
655
                g = (gx * yap) >> 14;
 
656
                b = (bx * yap) >> 14;
 
657
                a = (ax * yap) >> 14;
 
658
 
 
659
                for(j = (1 << 14) - yap; j > Cy; j -= Cy){
 
660
                    pix = sptr;
 
661
                    sptr += sow;
 
662
                    rx = (R_VAL(pix) * xap) >> 9;
 
663
                    gx = (G_VAL(pix) * xap) >> 9;
 
664
                    bx = (B_VAL(pix) * xap) >> 9;
 
665
                    ax = (A_VAL(pix) * xap) >> 9;
 
666
                    pix++;
 
667
                    for(i = (1 << 14) - xap; i > Cx; i -= Cx){
 
668
                        rx += (R_VAL(pix) * Cx) >> 9;
 
669
                        gx += (G_VAL(pix) * Cx) >> 9;
 
670
                        bx += (B_VAL(pix) * Cx) >> 9;
 
671
                        ax += (A_VAL(pix) * Cx) >> 9;
 
672
                        pix++;
 
673
                    }
 
674
                    if(i > 0){
 
675
                        rx += (R_VAL(pix) * i) >> 9;
 
676
                        gx += (G_VAL(pix) * i) >> 9;
 
677
                        bx += (B_VAL(pix) * i) >> 9;
 
678
                        ax += (A_VAL(pix) * i) >> 9;
 
679
                    }
 
680
 
 
681
                    r += (rx * Cy) >> 14;
 
682
                    g += (gx * Cy) >> 14;
 
683
                    b += (bx * Cy) >> 14;
 
684
                    a += (ax * Cy) >> 14;
 
685
                }
 
686
                if(j > 0){
 
687
                    pix = sptr;
 
688
                    sptr += sow;
 
689
                    rx = (R_VAL(pix) * xap) >> 9;
 
690
                    gx = (G_VAL(pix) * xap) >> 9;
 
691
                    bx = (B_VAL(pix) * xap) >> 9;
 
692
                    ax = (A_VAL(pix) * xap) >> 9;
 
693
                    pix++;
 
694
                    for(i = (1 << 14) - xap; i > Cx; i -= Cx){
 
695
                        rx += (R_VAL(pix) * Cx) >> 9;
 
696
                        gx += (G_VAL(pix) * Cx) >> 9;
 
697
                        bx += (B_VAL(pix) * Cx) >> 9;
 
698
                        ax += (A_VAL(pix) * Cx) >> 9;
 
699
                        pix++;
 
700
                    }
 
701
                    if(i > 0){
 
702
                        rx += (R_VAL(pix) * i) >> 9;
 
703
                        gx += (G_VAL(pix) * i) >> 9;
 
704
                        bx += (B_VAL(pix) * i) >> 9;
 
705
                        ax += (A_VAL(pix) * i) >> 9;
 
706
                    }
 
707
 
 
708
                    r += (rx * j) >> 14;
 
709
                    g += (gx * j) >> 14;
 
710
                    b += (bx * j) >> 14;
 
711
                    a += (ax * j) >> 14;
 
712
                }
 
713
 
 
714
                R_VAL(dptr) = r >> 5;
 
715
                G_VAL(dptr) = g >> 5;
 
716
                B_VAL(dptr) = b >> 5;
 
717
                A_VAL(dptr) = a >> 5;
 
718
                dptr++;
 
719
            }
 
720
        }
 
721
    }
 
722
}
 
723
 
 
724
/* scale by area sampling - IGNORE the ALPHA byte*/
 
725
void MImageScale::mimageScaleAARGB(MImageScaleInfo *isi, unsigned int *dest,
 
726
                                   int dxx, int dyy, int dx, int dy, int dw,
 
727
                                   int dh, int dow, int sow)
 
728
{
 
729
    unsigned int *sptr, *dptr;
 
730
    int x, y, end;
 
731
    unsigned int **ypoints = isi->ypoints;
 
732
    int *xpoints = isi->xpoints;
 
733
    int *xapoints = isi->xapoints;
 
734
    int *yapoints = isi->yapoints;
 
735
 
 
736
    end = dxx + dw;
 
737
    /* scaling up both ways */
 
738
    if(isi->xup_yup == 3){
 
739
        /* go through every scanline in the output buffer */
 
740
        for(y = 0; y < dh; y++){
 
741
            /* calculate the source line we'll scan from */
 
742
            dptr = dest + dx + ((y + dy) * dow);
 
743
            sptr = ypoints[dyy + y];
 
744
            if(YAP > 0){
 
745
                for(x = dxx; x < end; x++){
 
746
                    int r = 0, g = 0, b = 0;
 
747
                    int rr = 0, gg = 0, bb = 0;
 
748
                    unsigned int *pix;
 
749
 
 
750
                    if(XAP > 0){
 
751
                        pix = ypoints[dyy + y] + xpoints[x];
 
752
                        r = R_VAL(pix) * INV_XAP;
 
753
                        g = G_VAL(pix) * INV_XAP;
 
754
                        b = B_VAL(pix) * INV_XAP;
 
755
                        pix++;
 
756
                        r += R_VAL(pix) * XAP;
 
757
                        g += G_VAL(pix) * XAP;
 
758
                        b += B_VAL(pix) * XAP;
 
759
                        pix += sow;
 
760
                        rr = R_VAL(pix) * XAP;
 
761
                        gg = G_VAL(pix) * XAP;
 
762
                        bb = B_VAL(pix) * XAP;
 
763
                        pix --;
 
764
                        rr += R_VAL(pix) * INV_XAP;
 
765
                        gg += G_VAL(pix) * INV_XAP;
 
766
                        bb += B_VAL(pix) * INV_XAP;
 
767
                        r = ((rr * YAP) + (r * INV_YAP)) >> 16;
 
768
                        g = ((gg * YAP) + (g * INV_YAP)) >> 16;
 
769
                        b = ((bb * YAP) + (b * INV_YAP)) >> 16;
 
770
                        *dptr++ = qRgba(r, g, b, 0xff);
 
771
                    }
 
772
                    else{
 
773
                        pix = ypoints[dyy + y] + xpoints[x];
 
774
                        r = R_VAL(pix) * INV_YAP;
 
775
                        g = G_VAL(pix) * INV_YAP;
 
776
                        b = B_VAL(pix) * INV_YAP;
 
777
                        pix += sow;
 
778
                        r += R_VAL(pix) * YAP;
 
779
                        g += G_VAL(pix) * YAP;
 
780
                        b += B_VAL(pix) * YAP;
 
781
                        r >>= 8;
 
782
                        g >>= 8;
 
783
                        b >>= 8;
 
784
                        *dptr++ = qRgba(r, g, b, 0xff);
 
785
                    }
 
786
                }
 
787
            }
 
788
            else{
 
789
                for(x = dxx; x < end; x++){
 
790
                    int r = 0, g = 0, b = 0;
 
791
                    unsigned int *pix;
 
792
 
 
793
                    if(XAP > 0){
 
794
                        pix = ypoints[dyy + y] + xpoints[x];
 
795
                        r = R_VAL(pix) * INV_XAP;
 
796
                        g = G_VAL(pix) * INV_XAP;
 
797
                        b = B_VAL(pix) * INV_XAP;
 
798
                        pix++;
 
799
                        r += R_VAL(pix) * XAP;
 
800
                        g += G_VAL(pix) * XAP;
 
801
                        b += B_VAL(pix) * XAP;
 
802
                        r >>= 8;
 
803
                        g >>= 8;
 
804
                        b >>= 8;
 
805
                        *dptr++ = qRgba(r, g, b, 0xff);
 
806
                    }
 
807
                    else
 
808
                        *dptr++ = sptr[xpoints[x] ];
 
809
                }
 
810
            }
 
811
        }
 
812
    }
 
813
    /* if we're scaling down vertically */
 
814
    else if(isi->xup_yup == 1){
 
815
        /*\ 'Correct' version, with math units prepared for MMXification \*/
 
816
        int Cy, j;
 
817
        unsigned int *pix;
 
818
        int r, g, b, rr, gg, bb;
 
819
        int yap;
 
820
 
 
821
        /* go through every scanline in the output buffer */
 
822
        for(y = 0; y < dh; y++){
 
823
            Cy = YAP >> 16;
 
824
            yap = YAP & 0xffff;
 
825
 
 
826
            dptr = dest + dx + ((y + dy) * dow);
 
827
            for(x = dxx; x < end; x++){
 
828
                pix = ypoints[dyy + y] + xpoints[x];
 
829
                r = (R_VAL(pix) * yap) >> 10;
 
830
                g = (G_VAL(pix) * yap) >> 10;
 
831
                b = (B_VAL(pix) * yap) >> 10;
 
832
                pix += sow;
 
833
                for(j = (1 << 14) - yap; j > Cy; j -= Cy){
 
834
                    r += (R_VAL(pix) * Cy) >> 10;
 
835
                    g += (G_VAL(pix) * Cy) >> 10;
 
836
                    b += (B_VAL(pix) * Cy) >> 10;
 
837
                    pix += sow;
 
838
                }
 
839
                if(j > 0){
 
840
                    r += (R_VAL(pix) * j) >> 10;
 
841
                    g += (G_VAL(pix) * j) >> 10;
 
842
                    b += (B_VAL(pix) * j) >> 10;
 
843
                }
 
844
                if(XAP > 0){
 
845
                    pix = ypoints[dyy + y] + xpoints[x] + 1;
 
846
                    rr = (R_VAL(pix) * yap) >> 10;
 
847
                    gg = (G_VAL(pix) * yap) >> 10;
 
848
                    bb = (B_VAL(pix) * yap) >> 10;
 
849
                    pix += sow;
 
850
                    for(j = (1 << 14) - yap; j > Cy; j -= Cy){
 
851
                        rr += (R_VAL(pix) * Cy) >> 10;
 
852
                        gg += (G_VAL(pix) * Cy) >> 10;
 
853
                        bb += (B_VAL(pix) * Cy) >> 10;
 
854
                        pix += sow;
 
855
                    }
 
856
                    if(j > 0){
 
857
                        rr += (R_VAL(pix) * j) >> 10;
 
858
                        gg += (G_VAL(pix) * j) >> 10;
 
859
                        bb += (B_VAL(pix) * j) >> 10;
 
860
                    }
 
861
                    r = r * INV_XAP;
 
862
                    g = g * INV_XAP;
 
863
                    b = b * INV_XAP;
 
864
                    r = (r + ((rr * XAP))) >> 12;
 
865
                    g = (g + ((gg * XAP))) >> 12;
 
866
                    b = (b + ((bb * XAP))) >> 12;
 
867
                }
 
868
                else{
 
869
                    r >>= 4;
 
870
                    g >>= 4;
 
871
                    b >>= 4;
 
872
                }
 
873
                *dptr = qRgba(r, g, b, 0xff);
 
874
                dptr++;
 
875
            }
 
876
        }
 
877
    }
 
878
    /* if we're scaling down horizontally */
 
879
    else if(isi->xup_yup == 2){
 
880
        /*\ 'Correct' version, with math units prepared for MMXification \*/
 
881
        int Cx, j;
 
882
        unsigned int *pix;
 
883
        int r, g, b, rr, gg, bb;
 
884
        int xap;
 
885
 
 
886
        /* go through every scanline in the output buffer */
 
887
        for(y = 0; y < dh; y++){
 
888
            dptr = dest + dx + ((y + dy) * dow);
 
889
            for(x = dxx; x < end; x++){
 
890
                Cx = XAP >> 16;
 
891
                xap = XAP & 0xffff;
 
892
 
 
893
                pix = ypoints[dyy + y] + xpoints[x];
 
894
                r = (R_VAL(pix) * xap) >> 10;
 
895
                g = (G_VAL(pix) * xap) >> 10;
 
896
                b = (B_VAL(pix) * xap) >> 10;
 
897
                pix++;
 
898
                for(j = (1 << 14) - xap; j > Cx; j -= Cx){
 
899
                    r += (R_VAL(pix) * Cx) >> 10;
 
900
                    g += (G_VAL(pix) * Cx) >> 10;
 
901
                    b += (B_VAL(pix) * Cx) >> 10;
 
902
                    pix++;
 
903
                }
 
904
                if(j > 0){
 
905
                    r += (R_VAL(pix) * j) >> 10;
 
906
                    g += (G_VAL(pix) * j) >> 10;
 
907
                    b += (B_VAL(pix) * j) >> 10;
 
908
                }
 
909
                if(YAP > 0){
 
910
                    pix = ypoints[dyy + y] + xpoints[x] + sow;
 
911
                    rr = (R_VAL(pix) * xap) >> 10;
 
912
                    gg = (G_VAL(pix) * xap) >> 10;
 
913
                    bb = (B_VAL(pix) * xap) >> 10;
 
914
                    pix++;
 
915
                    for(j = (1 << 14) - xap; j > Cx; j -= Cx){
 
916
                        rr += (R_VAL(pix) * Cx) >> 10;
 
917
                        gg += (G_VAL(pix) * Cx) >> 10;
 
918
                        bb += (B_VAL(pix) * Cx) >> 10;
 
919
                        pix++;
 
920
                    }
 
921
                    if(j > 0){
 
922
                        rr += (R_VAL(pix) * j) >> 10;
 
923
                        gg += (G_VAL(pix) * j) >> 10;
 
924
                        bb += (B_VAL(pix) * j) >> 10;
 
925
                    }
 
926
                    r = r * INV_YAP;
 
927
                    g = g * INV_YAP;
 
928
                    b = b * INV_YAP;
 
929
                    r = (r + ((rr * YAP))) >> 12;
 
930
                    g = (g + ((gg * YAP))) >> 12;
 
931
                    b = (b + ((bb * YAP))) >> 12;
 
932
                }
 
933
                else{
 
934
                    r >>= 4;
 
935
                    g >>= 4;
 
936
                    b >>= 4;
 
937
                }
 
938
                *dptr = qRgba(r, g, b, 0xff);
 
939
                dptr++;
 
940
            }
 
941
        }
 
942
    }
 
943
    /* fully optimized (i think) - onyl change of algorithm can help */
 
944
    /* if we're scaling down horizontally & vertically */
 
945
    else{
 
946
        /*\ 'Correct' version, with math units prepared for MMXification \*/
 
947
        int Cx, Cy, i, j;
 
948
        unsigned int *pix;
 
949
        int r, g, b, rx, gx, bx;
 
950
        int xap, yap;
 
951
 
 
952
        for(y = 0; y < dh; y++){
 
953
            Cy = YAP >> 16;
 
954
            yap = YAP & 0xffff;
 
955
 
 
956
            dptr = dest + dx + ((y + dy) * dow);
 
957
            for(x = dxx; x < end; x++){
 
958
                Cx = XAP >> 16;
 
959
                xap = XAP & 0xffff;
 
960
 
 
961
                sptr = ypoints[dyy + y] + xpoints[x];
 
962
                pix = sptr;
 
963
                sptr += sow;
 
964
                rx = (R_VAL(pix) * xap) >> 9;
 
965
                gx = (G_VAL(pix) * xap) >> 9;
 
966
                bx = (B_VAL(pix) * xap) >> 9;
 
967
                pix++;
 
968
                for(i = (1 << 14) - xap; i > Cx; i -= Cx){
 
969
                    rx += (R_VAL(pix) * Cx) >> 9;
 
970
                    gx += (G_VAL(pix) * Cx) >> 9;
 
971
                    bx += (B_VAL(pix) * Cx) >> 9;
 
972
                    pix++;
 
973
                }
 
974
                if(i > 0){
 
975
                    rx += (R_VAL(pix) * i) >> 9;
 
976
                    gx += (G_VAL(pix) * i) >> 9;
 
977
                    bx += (B_VAL(pix) * i) >> 9;
 
978
                }
 
979
 
 
980
                r = (rx * yap) >> 14;
 
981
                g = (gx * yap) >> 14;
 
982
                b = (bx * yap) >> 14;
 
983
 
 
984
                for(j = (1 << 14) - yap; j > Cy; j -= Cy){
 
985
                    pix = sptr;
 
986
                    sptr += sow;
 
987
                    rx = (R_VAL(pix) * xap) >> 9;
 
988
                    gx = (G_VAL(pix) * xap) >> 9;
 
989
                    bx = (B_VAL(pix) * xap) >> 9;
 
990
                    pix++;
 
991
                    for(i = (1 << 14) - xap; i > Cx; i -= Cx){
 
992
                        rx += (R_VAL(pix) * Cx) >> 9;
 
993
                        gx += (G_VAL(pix) * Cx) >> 9;
 
994
                        bx += (B_VAL(pix) * Cx) >> 9;
 
995
                        pix++;
 
996
                    }
 
997
                    if(i > 0){
 
998
                        rx += (R_VAL(pix) * i) >> 9;
 
999
                        gx += (G_VAL(pix) * i) >> 9;
 
1000
                        bx += (B_VAL(pix) * i) >> 9;
 
1001
                    }
 
1002
 
 
1003
                    r += (rx * Cy) >> 14;
 
1004
                    g += (gx * Cy) >> 14;
 
1005
                    b += (bx * Cy) >> 14;
 
1006
                }
 
1007
                if(j > 0){
 
1008
                    pix = sptr;
 
1009
                    sptr += sow;
 
1010
                    rx = (R_VAL(pix) * xap) >> 9;
 
1011
                    gx = (G_VAL(pix) * xap) >> 9;
 
1012
                    bx = (B_VAL(pix) * xap) >> 9;
 
1013
                    pix++;
 
1014
                    for(i = (1 << 14) - xap; i > Cx; i -= Cx){
 
1015
                        rx += (R_VAL(pix) * Cx) >> 9;
 
1016
                        gx += (G_VAL(pix) * Cx) >> 9;
 
1017
                        bx += (B_VAL(pix) * Cx) >> 9;
 
1018
                        pix++;
 
1019
                    }
 
1020
                    if(i > 0){
 
1021
                        rx += (R_VAL(pix) * i) >> 9;
 
1022
                        gx += (G_VAL(pix) * i) >> 9;
 
1023
                        bx += (B_VAL(pix) * i) >> 9;
 
1024
                    }
 
1025
 
 
1026
                    r += (rx * j) >> 14;
 
1027
                    g += (gx * j) >> 14;
 
1028
                    b += (bx * j) >> 14;
 
1029
                }
 
1030
 
 
1031
                R_VAL(dptr) = r >> 5;
 
1032
                G_VAL(dptr) = g >> 5;
 
1033
                B_VAL(dptr) = b >> 5;
 
1034
                dptr++;
 
1035
            }
 
1036
        }
 
1037
    }
 
1038
}
 
1039
 
 
1040
 
 
1041
QImage scale(const QImage& image, int width, int height)
 
1042
{
 
1043
        if( image.isNull()) return image.copy();
 
1044
        
 
1045
        QSize newSize( width, height );
 
1046
        newSize = newSize.expandedTo( QSize( 1, 1 )); // make sure it doesn't become null
 
1047
 
 
1048
        if ( newSize == image.size() ) return image.copy();
 
1049
        
 
1050
        width = newSize.width();
 
1051
        height = newSize.height();
 
1052
//        return image.smoothScale( width, height );
 
1053
        return MImageScale::smoothScale( image, width, height );
 
1054
}