5#include <private/qimagescale_p.h>
6#include <private/qdrawhelper_p.h>
7#include <private/qimage_p.h>
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
66 static const unsigned int**
qimageCalcYPoints(
const unsigned int *src,
int sw,
int sh,
int dh);
80 int sw,
int sh,
int dh)
82 const unsigned int **p;
90 p =
new const unsigned int* [dh+1];
92 int up = qAbs(dh) >= sh;
93 val = up ? 0x8000 * sh / dh - 0x8000 : 0;
94 inc = (((qint64)sh) << 16) / dh;
95 for (
int i = 0; i < dh; i++) {
96 p[j++] = src + qMax(0LL, val >> 16) * sw;
100 for (
int i = dh / 2; --i >= 0; ) {
101 const unsigned int *tmp = p[i];
102 p[i] = p[dh - i - 1];
111 int *p, j = 0, rv = 0;
120 int up = qAbs(dw) >= sw;
121 val = up ? 0x8000 * sw / dw - 0x8000 : 0;
122 inc = (((qint64)sw) << 16) / dw;
123 for (
int i = 0; i < dw; i++) {
124 p[j++] = qMax(0LL, val >> 16);
129 for (
int i = dw / 2; --i >= 0; ) {
131 p[i] = p[dw - i - 1];
140 int *p, j = 0, rv = 0;
150 qint64 val = 0x8000 * s / d - 0x8000;
151 qint64 inc = (((qint64)s) << 16) / d;
152 for (
int i = 0; i < d; i++) {
156 else if (pos >= (s - 1))
159 p[j++] = (val >> 8) - ((val >> 8) & 0xffffff00);
165 qint64 inc = (((qint64)s) << 16) / d;
166 int Cp = (((d << 14) + s - 1) / s);
167 for (
int i = 0; i < d; i++) {
168 int ap = ((0x10000 - (val & 0xffff)) * Cp) >> 16;
169 p[j] = ap | (Cp << 16);
176 for (
int i = d / 2; --i >= 0; ) {
188 delete[] isi->xpoints;
189 delete[] isi->ypoints;
190 delete[] isi->xapoints;
191 delete[] isi->yapoints;
199 int dw,
int dh,
char aa)
201 QImageScaleInfo *isi;
204 scw = dw * qlonglong(img.width()) / sw;
205 sch = dh * qlonglong(img.height()) / sh;
207 isi =
new QImageScaleInfo;
213 isi->xup_yup = (qAbs(dw) >= sw) + ((qAbs(dh) >= sh) << 1);
215 isi->xpoints = qimageCalcXPoints(img.width(), scw);
217 return qimageFreeScaleInfo(isi);
218 isi->ypoints = qimageCalcYPoints((
const unsigned int *)img.scanLine(0),
219 img.bytesPerLine() / 4, img.height(), sch);
221 return qimageFreeScaleInfo(isi);
223 isi->xapoints = qimageCalcApoints(img.width(), scw, isi->xup_yup & 1);
225 return qimageFreeScaleInfo(isi);
226 isi->yapoints = qimageCalcApoints(img.height(), sch, isi->xup_yup & 2);
228 return qimageFreeScaleInfo(isi);
235 int dw,
int dh,
int dow,
int sow);
238 int dw,
int dh,
int dow,
int sow);
241 int dw,
int dh,
int dow,
int sow);
243#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
245void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi,
unsigned int *dest,
246 int dw,
int dh,
int dow,
int sow);
248void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi,
unsigned int *dest,
249 int dw,
int dh,
int dow,
int sow);
251void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi,
unsigned int *dest,
252 int dw,
int dh,
int dow,
int sow);
255#if defined(QT_COMPILER_SUPPORTS_LSX)
257void qt_qimageScaleAARGBA_up_x_down_y_lsx(QImageScaleInfo *isi,
unsigned int *dest,
258 int dw,
int dh,
int dow,
int sow);
260void qt_qimageScaleAARGBA_down_x_up_y_lsx(QImageScaleInfo *isi,
unsigned int *dest,
261 int dw,
int dh,
int dow,
int sow);
263void qt_qimageScaleAARGBA_down_xy_lsx(QImageScaleInfo *isi,
unsigned int *dest,
264 int dw,
int dh,
int dow,
int sow);
267#if defined(__ARM_NEON__)
269void qt_qimageScaleAARGBA_up_x_down_y_neon(QImageScaleInfo *isi,
unsigned int *dest,
270 int dw,
int dh,
int dow,
int sow);
272void qt_qimageScaleAARGBA_down_x_up_y_neon(QImageScaleInfo *isi,
unsigned int *dest,
273 int dw,
int dh,
int dow,
int sow);
275void qt_qimageScaleAARGBA_down_xy_neon(QImageScaleInfo *isi,
unsigned int *dest,
276 int dw,
int dh,
int dow,
int sow);
280 int dw,
int dh,
int dow,
int sow)
282 const unsigned int **ypoints = isi->ypoints;
283 int *xpoints = isi->xpoints;
284 int *xapoints = isi->xapoints;
285 int *yapoints = isi->yapoints;
288 auto scaleSection = [&] (
int yStart,
int yEnd) {
289 for (
int y = yStart; y < yEnd; ++y) {
291 const unsigned int *sptr = ypoints[y];
292 unsigned int *dptr = dest + (y * dow);
293 const int yap = yapoints[y];
295 for (
int x = 0; x < dw; x++) {
296 const unsigned int *pix = sptr + xpoints[x];
297 const int xap = xapoints[x];
299 *dptr = interpolate_4_pixels(pix, pix + sow, xap, yap);
301 *dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - yap, pix[sow], yap);
305 for (
int x = 0; x < dw; x++) {
306 const unsigned int *pix = sptr + xpoints[x];
307 const int xap = xapoints[x];
309 *dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - xap, pix[1], xap);
317 multithread_pixels_function(isi, dh, scaleSection);
322 int dw,
int dh,
int dow,
int sow)
325 if (isi->xup_yup == 3) {
326 qt_qimageScaleAARGBA_up_xy(isi, dest, dw, dh, dow, sow);
329 else if (isi->xup_yup == 1) {
330#ifdef QT_COMPILER_SUPPORTS_SSE4_1
331 if (qCpuHasFeature(SSE4_1))
332 qt_qimageScaleAARGBA_up_x_down_y_sse4<
false>(isi, dest, dw, dh, dow, sow);
334#elif defined(QT_COMPILER_SUPPORTS_LSX)
335 if (qCpuHasFeature(LSX))
336 qt_qimageScaleAARGBA_up_x_down_y_lsx<
false>(isi, dest, dw, dh, dow, sow);
338#elif defined(__ARM_NEON__)
339 if (qCpuHasFeature(NEON))
340 qt_qimageScaleAARGBA_up_x_down_y_neon<
false>(isi, dest, dw, dh, dow, sow);
343 qt_qimageScaleAARGBA_up_x_down_y(isi, dest, dw, dh, dow, sow);
346 else if (isi->xup_yup == 2) {
347#ifdef QT_COMPILER_SUPPORTS_SSE4_1
348 if (qCpuHasFeature(SSE4_1))
349 qt_qimageScaleAARGBA_down_x_up_y_sse4<
false>(isi, dest, dw, dh, dow, sow);
351#elif defined(QT_COMPILER_SUPPORTS_LSX)
352 if (qCpuHasFeature(LSX))
353 qt_qimageScaleAARGBA_down_x_up_y_lsx<
false>(isi, dest, dw, dh, dow, sow);
355#elif defined(__ARM_NEON__)
356 if (qCpuHasFeature(NEON))
357 qt_qimageScaleAARGBA_down_x_up_y_neon<
false>(isi, dest, dw, dh, dow, sow);
360 qt_qimageScaleAARGBA_down_x_up_y(isi, dest, dw, dh, dow, sow);
364#ifdef QT_COMPILER_SUPPORTS_SSE4_1
365 if (qCpuHasFeature(SSE4_1))
366 qt_qimageScaleAARGBA_down_xy_sse4<
false>(isi, dest, dw, dh, dow, sow);
368#elif defined(QT_COMPILER_SUPPORTS_LSX)
369 if (qCpuHasFeature(LSX))
370 qt_qimageScaleAARGBA_down_xy_lsx<
false>(isi, dest, dw, dh, dow, sow);
372#elif defined(__ARM_NEON__)
373 if (qCpuHasFeature(NEON))
374 qt_qimageScaleAARGBA_down_xy_neon<
false>(isi, dest, dw, dh, dow, sow);
377 qt_qimageScaleAARGBA_down_xy(isi, dest, dw, dh, dow, sow);
383 r = qRed(*pix) * xyap;
384 g = qGreen(*pix) * xyap;
385 b = qBlue(*pix) * xyap;
386 a = qAlpha(*pix) * xyap;
388 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) {
390 r += qRed(*pix) * Cxy;
391 g += qGreen(*pix) * Cxy;
392 b += qBlue(*pix) * Cxy;
393 a += qAlpha(*pix) * Cxy;
397 g += qGreen(*pix) * j;
398 b += qBlue(*pix) * j;
399 a += qAlpha(*pix) * j;
403 int dw,
int dh,
int dow,
int sow)
405 const unsigned int **ypoints = isi->ypoints;
406 int *xpoints = isi->xpoints;
407 int *xapoints = isi->xapoints;
408 int *yapoints = isi->yapoints;
411 auto scaleSection = [&] (
int yStart,
int yEnd) {
412 for (
int y = yStart; y < yEnd; ++y) {
413 int Cy = yapoints[y] >> 16;
414 int yap = yapoints[y] & 0xffff;
416 unsigned int *dptr = dest + (y * dow);
417 for (
int x = 0; x < dw; x++) {
418 const unsigned int *sptr = ypoints[y] + xpoints[x];
422 int xap = xapoints[x];
431 r = (r + (rr * xap)) >> 8;
432 g = (g + (gg * xap)) >> 8;
433 b = (b + (bb * xap)) >> 8;
434 a = (a + (aa * xap)) >> 8;
436 *dptr++ = qRgba(r >> 14, g >> 14, b >> 14, a >> 14);
440 multithread_pixels_function(isi, dh, scaleSection);
444 int dw,
int dh,
int dow,
int sow)
446 const unsigned int **ypoints = isi->ypoints;
447 int *xpoints = isi->xpoints;
448 int *xapoints = isi->xapoints;
449 int *yapoints = isi->yapoints;
452 auto scaleSection = [&] (
int yStart,
int yEnd) {
453 for (
int y = yStart; y < yEnd; ++y) {
454 unsigned int *dptr = dest + (y * dow);
455 for (
int x = 0; x < dw; x++) {
456 int Cx = xapoints[x] >> 16;
457 int xap = xapoints[x] & 0xffff;
459 const unsigned int *sptr = ypoints[y] + xpoints[x];
463 int yap = yapoints[y];
472 r = (r + (rr * yap)) >> 8;
473 g = (g + (gg * yap)) >> 8;
474 b = (b + (bb * yap)) >> 8;
475 a = (a + (aa * yap)) >> 8;
477 *dptr = qRgba(r >> 14, g >> 14, b >> 14, a >> 14);
482 multithread_pixels_function(isi, dh, scaleSection);
486 int dw,
int dh,
int dow,
int sow)
488 const unsigned int **ypoints = isi->ypoints;
489 int *xpoints = isi->xpoints;
490 int *xapoints = isi->xapoints;
491 int *yapoints = isi->yapoints;
493 auto scaleSection = [&] (
int yStart,
int yEnd) {
494 for (
int y = yStart; y < yEnd; ++y) {
495 int Cy = (yapoints[y]) >> 16;
496 int yap = (yapoints[y]) & 0xffff;
498 unsigned int *dptr = dest + (y * dow);
499 for (
int x = 0; x < dw; x++) {
500 int Cx = xapoints[x] >> 16;
501 int xap = xapoints[x] & 0xffff;
503 const unsigned int *sptr = ypoints[y] + xpoints[x];
507 int r = ((rx>>4) * yap);
508 int g = ((gx>>4) * yap);
509 int b = ((bx>>4) * yap);
510 int a = ((ax>>4) * yap);
513 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
529 *dptr = qRgba(r >> 24, g >> 24, b >> 24, a >> 24);
534 multithread_pixels_function(isi, dh, scaleSection);
537#if QT_CONFIG(raster_64bit)
538static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
539 int dw,
int dh,
int dow,
int sow);
541static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
542 int dw,
int dh,
int dow,
int sow);
544static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
545 int dw,
int dh,
int dow,
int sow);
547static void qt_qimageScaleRgba64_up_xy(QImageScaleInfo *isi, QRgba64 *dest,
548 int dw,
int dh,
int dow,
int sow)
550 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
551 int *xpoints = isi->xpoints;
552 int *xapoints = isi->xapoints;
553 int *yapoints = isi->yapoints;
555 auto scaleSection = [&] (
int yStart,
int yEnd) {
556 for (
int y = yStart; y < yEnd; ++y) {
557 const QRgba64 *sptr = ypoints[y];
558 QRgba64 *dptr = dest + (y * dow);
559 const int yap = yapoints[y];
561 for (
int x = 0; x < dw; x++) {
562 const QRgba64 *pix = sptr + xpoints[x];
563 const int xap = xapoints[x];
565 *dptr = interpolate_4_pixels_rgb64(pix, pix + sow, xap * 256, yap * 256);
567 *dptr = interpolate256(pix[0], 256 - yap, pix[sow], yap);
571 for (
int x = 0; x < dw; x++) {
572 const QRgba64 *pix = sptr + xpoints[x];
573 const int xap = xapoints[x];
575 *dptr = interpolate256(pix[0], 256 - xap, pix[1], xap);
583 multithread_pixels_function(isi, dh, scaleSection);
586void qt_qimageScaleRgba64(QImageScaleInfo *isi, QRgba64 *dest,
587 int dw,
int dh,
int dow,
int sow)
589 if (isi->xup_yup == 3)
590 qt_qimageScaleRgba64_up_xy(isi, dest, dw, dh, dow, sow);
591 else if (isi->xup_yup == 1)
592 qt_qimageScaleRgba64_up_x_down_y(isi, dest, dw, dh, dow, sow);
593 else if (isi->xup_yup == 2)
594 qt_qimageScaleRgba64_down_x_up_y(isi, dest, dw, dh, dow, sow);
596 qt_qimageScaleRgba64_down_xy(isi, dest, dw, dh, dow, sow);
599inline static void qt_qimageScaleRgba64_helper(
const QRgba64 *pix,
int xyap,
int Cxy,
int step, qint64 &r, qint64 &g, qint64 &b, qint64 &a)
601 r = pix->red() * xyap;
602 g = pix->green() * xyap;
603 b = pix->blue() * xyap;
604 a = pix->alpha() * xyap;
606 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy ){
608 r += pix->red() * Cxy;
609 g += pix->green() * Cxy;
610 b += pix->blue() * Cxy;
611 a += pix->alpha() * Cxy;
615 g += pix->green() * j;
616 b += pix->blue() * j;
617 a += pix->alpha() * j;
620static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
621 int dw,
int dh,
int dow,
int sow)
623 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
624 int *xpoints = isi->xpoints;
625 int *xapoints = isi->xapoints;
626 int *yapoints = isi->yapoints;
628 auto scaleSection = [&] (
int yStart,
int yEnd) {
629 for (
int y = yStart; y < yEnd; ++y) {
630 int Cy = (yapoints[y]) >> 16;
631 int yap = (yapoints[y]) & 0xffff;
633 QRgba64 *dptr = dest + (y * dow);
634 for (
int x = 0; x < dw; x++) {
635 const QRgba64 *sptr = ypoints[y] + xpoints[x];
637 qt_qimageScaleRgba64_helper(sptr, yap, Cy, sow, r, g, b, a);
639 int xap = xapoints[x];
641 qint64 rr, gg, bb, aa;
642 qt_qimageScaleRgba64_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa);
648 r = (r + (rr * xap)) >> 8;
649 g = (g + (gg * xap)) >> 8;
650 b = (b + (bb * xap)) >> 8;
651 a = (a + (aa * xap)) >> 8;
653 *dptr++ = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
657 multithread_pixels_function(isi, dh, scaleSection);
660static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
661 int dw,
int dh,
int dow,
int sow)
663 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
664 int *xpoints = isi->xpoints;
665 int *xapoints = isi->xapoints;
666 int *yapoints = isi->yapoints;
668 auto scaleSection = [&] (
int yStart,
int yEnd) {
669 for (
int y = yStart; y < yEnd; ++y) {
670 QRgba64 *dptr = dest + (y * dow);
671 for (
int x = 0; x < dw; x++) {
672 int Cx = xapoints[x] >> 16;
673 int xap = xapoints[x] & 0xffff;
675 const QRgba64 *sptr = ypoints[y] + xpoints[x];
677 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, r, g, b, a);
679 int yap = yapoints[y];
681 qint64 rr, gg, bb, aa;
682 qt_qimageScaleRgba64_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa);
688 r = (r + (rr * yap)) >> 8;
689 g = (g + (gg * yap)) >> 8;
690 b = (b + (bb * yap)) >> 8;
691 a = (a + (aa * yap)) >> 8;
693 *dptr = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
698 multithread_pixels_function(isi, dh, scaleSection);
701static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
702 int dw,
int dh,
int dow,
int sow)
704 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
705 int *xpoints = isi->xpoints;
706 int *xapoints = isi->xapoints;
707 int *yapoints = isi->yapoints;
709 auto scaleSection = [&] (
int yStart,
int yEnd) {
710 for (
int y = yStart; y < yEnd; ++y) {
711 int Cy = (yapoints[y]) >> 16;
712 int yap = (yapoints[y]) & 0xffff;
714 QRgba64 *dptr = dest + (y * dow);
715 for (
int x = 0; x < dw; x++) {
716 int Cx = xapoints[x] >> 16;
717 int xap = xapoints[x] & 0xffff;
719 const QRgba64 *sptr = ypoints[y] + xpoints[x];
720 qint64 rx, gx, bx, ax;
721 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
728 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
730 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
737 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
743 *dptr = qRgba64(r >> 28, g >> 28, b >> 28, a >> 28);
748 multithread_pixels_function(isi, dh, scaleSection);
752#if QT_CONFIG(raster_fp)
753static void qt_qimageScaleRgbaFP_up_x_down_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
754 int dw,
int dh,
int dow,
int sow);
756static void qt_qimageScaleRgbaFP_down_x_up_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
757 int dw,
int dh,
int dow,
int sow);
759static void qt_qimageScaleRgbaFP_down_xy(QImageScaleInfo *isi, QRgbaFloat32 *dest,
760 int dw,
int dh,
int dow,
int sow);
762static void qt_qimageScaleRgbaFP_up_xy(QImageScaleInfo *isi, QRgbaFloat32 *dest,
763 int dw,
int dh,
int dow,
int sow)
765 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
766 int *xpoints = isi->xpoints;
767 int *xapoints = isi->xapoints;
768 int *yapoints = isi->yapoints;
770 auto scaleSection = [&] (
int yStart,
int yEnd) {
771 for (
int y = yStart; y < yEnd; ++y) {
772 const QRgbaFloat32 *sptr = ypoints[y];
773 QRgbaFloat32 *dptr = dest + (y * dow);
774 const int yap = yapoints[y];
776 for (
int x = 0; x < dw; x++) {
777 const QRgbaFloat32 *pix = sptr + xpoints[x];
778 const int xap = xapoints[x];
780 *dptr = interpolate_4_pixels_rgba32f(pix, pix + sow, xap * 256, yap * 256);
782 *dptr = interpolate_rgba32f(pix[0], 256 - yap, pix[sow], yap);
786 for (
int x = 0; x < dw; x++) {
787 const QRgbaFloat32 *pix = sptr + xpoints[x];
788 const int xap = xapoints[x];
790 *dptr = interpolate_rgba32f(pix[0], 256 - xap, pix[1], xap);
798 multithread_pixels_function(isi, dh, scaleSection);
801void qt_qimageScaleRgbaFP(QImageScaleInfo *isi, QRgbaFloat32 *dest,
802 int dw,
int dh,
int dow,
int sow)
804 if (isi->xup_yup == 3)
805 qt_qimageScaleRgbaFP_up_xy(isi, dest, dw, dh, dow, sow);
806 else if (isi->xup_yup == 1)
807 qt_qimageScaleRgbaFP_up_x_down_y(isi, dest, dw, dh, dow, sow);
808 else if (isi->xup_yup == 2)
809 qt_qimageScaleRgbaFP_down_x_up_y(isi, dest, dw, dh, dow, sow);
811 qt_qimageScaleRgbaFP_down_xy(isi, dest, dw, dh, dow, sow);
814inline static void qt_qimageScaleRgbaFP_helper(
const QRgbaFloat32 *pix,
int xyap,
int Cxy,
int step,
float &r,
float &g,
float &b,
float &a)
816 constexpr float f = (1.0f /
float(1<<14));
817 const float xyapf = xyap * f;
818 const float Cxyf = Cxy * f;
819 r = pix->red() * xyapf;
820 g = pix->green() * xyapf;
821 b = pix->blue() * xyapf;
822 a = pix->alpha() * xyapf;
824 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy ){
826 r += pix->red() * Cxyf;
827 g += pix->green() * Cxyf;
828 b += pix->blue() * Cxyf;
829 a += pix->alpha() * Cxyf;
832 const float jf = j * f;
833 r += pix->red() * jf;
834 g += pix->green() * jf;
835 b += pix->blue() * jf;
836 a += pix->alpha() * jf;
839static void qt_qimageScaleRgbaFP_up_x_down_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
840 int dw,
int dh,
int dow,
int sow)
842 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
843 int *xpoints = isi->xpoints;
844 int *xapoints = isi->xapoints;
845 int *yapoints = isi->yapoints;
847 auto scaleSection = [&] (
int yStart,
int yEnd) {
848 for (
int y = yStart; y < yEnd; ++y) {
849 int Cy = (yapoints[y]) >> 16;
850 int yap = (yapoints[y]) & 0xffff;
852 QRgbaFloat32 *dptr = dest + (y * dow);
853 for (
int x = 0; x < dw; x++) {
854 const QRgbaFloat32 *sptr = ypoints[y] + xpoints[x];
856 qt_qimageScaleRgbaFP_helper(sptr, yap, Cy, sow, r, g, b, a);
858 int xap = xapoints[x];
859 float xapf = xap * (1.f / 256.f);
861 float rr, gg, bb, aa;
862 qt_qimageScaleRgbaFP_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa);
864 r = (r * (1.0f - xapf) + (rr * xapf));
865 g = (g * (1.0f - xapf) + (gg * xapf));
866 b = (b * (1.0f - xapf) + (bb * xapf));
867 a = (a * (1.0f - xapf) + (aa * xapf));
869 *dptr++ = QRgbaFloat32{r, g, b, a};
873 multithread_pixels_function(isi, dh, scaleSection);
876static void qt_qimageScaleRgbaFP_down_x_up_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
877 int dw,
int dh,
int dow,
int sow)
879 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
880 int *xpoints = isi->xpoints;
881 int *xapoints = isi->xapoints;
882 int *yapoints = isi->yapoints;
884 auto scaleSection = [&] (
int yStart,
int yEnd) {
885 for (
int y = yStart; y < yEnd; ++y) {
886 QRgbaFloat32 *dptr = dest + (y * dow);
887 for (
int x = 0; x < dw; x++) {
888 int Cx = xapoints[x] >> 16;
889 int xap = xapoints[x] & 0xffff;
891 const QRgbaFloat32 *sptr = ypoints[y] + xpoints[x];
893 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, r, g, b, a);
895 int yap = yapoints[y];
896 float yapf = yap * (1.f / 256.f);
898 float rr, gg, bb, aa;
899 qt_qimageScaleRgbaFP_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa);
901 r = (r * (1.0f - yapf) + (rr * yapf));
902 g = (g * (1.0f - yapf) + (gg * yapf));
903 b = (b * (1.0f - yapf) + (bb * yapf));
904 a = (a * (1.0f - yapf) + (aa * yapf));
906 *dptr++ = QRgbaFloat32{r, g, b, a};
910 multithread_pixels_function(isi, dh, scaleSection);
913static void qt_qimageScaleRgbaFP_down_xy(QImageScaleInfo *isi, QRgbaFloat32 *dest,
914 int dw,
int dh,
int dow,
int sow)
916 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
917 int *xpoints = isi->xpoints;
918 int *xapoints = isi->xapoints;
919 int *yapoints = isi->yapoints;
921 auto scaleSection = [&] (
int yStart,
int yEnd) {
922 constexpr float f = 1.f /
float(1 << 14);
923 for (
int y = yStart; y < yEnd; ++y) {
924 int Cy = (yapoints[y]) >> 16;
925 int yap = (yapoints[y]) & 0xffff;
927 QRgbaFloat32 *dptr = dest + (y * dow);
928 for (
int x = 0; x < dw; x++) {
929 int Cx = xapoints[x] >> 16;
930 int xap = xapoints[x] & 0xffff;
932 const QRgbaFloat32 *sptr = ypoints[y] + xpoints[x];
933 float rx, gx, bx, ax;
934 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
936 const float yapf = yap * f;
937 const float Cyf = Cy * f;
943 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
945 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
952 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
953 const float jf = j * f;
959 *dptr++ = QRgbaFloat32{r, g, b, a};
963 multithread_pixels_function(isi, dh, scaleSection);
968 int dw,
int dh,
int dow,
int sow);
971 int dw,
int dh,
int dow,
int sow);
974 int dw,
int dh,
int dow,
int sow);
978 int dw,
int dh,
int dow,
int sow)
981 if (isi->xup_yup == 3) {
982 qt_qimageScaleAARGBA_up_xy(isi, dest, dw, dh, dow, sow);
985 else if (isi->xup_yup == 1) {
986#ifdef QT_COMPILER_SUPPORTS_SSE4_1
987 if (qCpuHasFeature(SSE4_1))
988 qt_qimageScaleAARGBA_up_x_down_y_sse4<
true>(isi, dest, dw, dh, dow, sow);
990#elif defined QT_COMPILER_SUPPORTS_LSX
991 if (qCpuHasFeature(LSX))
992 qt_qimageScaleAARGBA_up_x_down_y_lsx<
true>(isi, dest, dw, dh, dow, sow);
994#elif defined(__ARM_NEON__)
995 if (qCpuHasFeature(NEON))
996 qt_qimageScaleAARGBA_up_x_down_y_neon<
true>(isi, dest, dw, dh, dow, sow);
999 qt_qimageScaleAARGB_up_x_down_y(isi, dest, dw, dh, dow, sow);
1002 else if (isi->xup_yup == 2) {
1003#ifdef QT_COMPILER_SUPPORTS_SSE4_1
1004 if (qCpuHasFeature(SSE4_1))
1005 qt_qimageScaleAARGBA_down_x_up_y_sse4<
true>(isi, dest, dw, dh, dow, sow);
1007#elif defined QT_COMPILER_SUPPORTS_LSX
1008 if (qCpuHasFeature(LSX))
1009 qt_qimageScaleAARGBA_down_x_up_y_lsx<
true>(isi, dest, dw, dh, dow, sow);
1011#elif defined(__ARM_NEON__)
1012 if (qCpuHasFeature(NEON))
1013 qt_qimageScaleAARGBA_down_x_up_y_neon<
true>(isi, dest, dw, dh, dow, sow);
1016 qt_qimageScaleAARGB_down_x_up_y(isi, dest, dw, dh, dow, sow);
1020#ifdef QT_COMPILER_SUPPORTS_SSE4_1
1021 if (qCpuHasFeature(SSE4_1))
1022 qt_qimageScaleAARGBA_down_xy_sse4<
true>(isi, dest, dw, dh, dow, sow);
1024#elif defined QT_COMPILER_SUPPORTS_LSX
1025 if (qCpuHasFeature(LSX))
1026 qt_qimageScaleAARGBA_down_xy_lsx<
true>(isi, dest, dw, dh, dow, sow);
1028#elif defined(__ARM_NEON__)
1029 if (qCpuHasFeature(NEON))
1030 qt_qimageScaleAARGBA_down_xy_neon<
true>(isi, dest, dw, dh, dow, sow);
1033 qt_qimageScaleAARGB_down_xy(isi, dest, dw, dh, dow, sow);
1040 r = qRed(*pix) * xyap;
1041 g = qGreen(*pix) * xyap;
1042 b = qBlue(*pix) * xyap;
1044 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) {
1046 r += qRed(*pix) * Cxy;
1047 g += qGreen(*pix) * Cxy;
1048 b += qBlue(*pix) * Cxy;
1051 r += qRed(*pix) * j;
1052 g += qGreen(*pix) * j;
1053 b += qBlue(*pix) * j;
1057 int dw,
int dh,
int dow,
int sow)
1059 const unsigned int **ypoints = isi->ypoints;
1060 int *xpoints = isi->xpoints;
1061 int *xapoints = isi->xapoints;
1062 int *yapoints = isi->yapoints;
1065 auto scaleSection = [&] (
int yStart,
int yEnd) {
1066 for (
int y = yStart; y < yEnd; ++y) {
1067 int Cy = yapoints[y] >> 16;
1068 int yap = yapoints[y] & 0xffff;
1070 unsigned int *dptr = dest + (y * dow);
1071 for (
int x = 0; x < dw; x++) {
1072 const unsigned int *sptr = ypoints[y] + xpoints[x];
1076 int xap = xapoints[x];
1081 r = r * (256 - xap);
1082 g = g * (256 - xap);
1083 b = b * (256 - xap);
1084 r = (r + (rr * xap)) >> 8;
1085 g = (g + (gg * xap)) >> 8;
1086 b = (b + (bb * xap)) >> 8;
1088 *dptr++ = qRgb(r >> 14, g >> 14, b >> 14);
1092 multithread_pixels_function(isi, dh, scaleSection);
1096 int dw,
int dh,
int dow,
int sow)
1098 const unsigned int **ypoints = isi->ypoints;
1099 int *xpoints = isi->xpoints;
1100 int *xapoints = isi->xapoints;
1101 int *yapoints = isi->yapoints;
1104 auto scaleSection = [&] (
int yStart,
int yEnd) {
1105 for (
int y = yStart; y < yEnd; ++y) {
1106 unsigned int *dptr = dest + (y * dow);
1107 for (
int x = 0; x < dw; x++) {
1108 int Cx = xapoints[x] >> 16;
1109 int xap = xapoints[x] & 0xffff;
1111 const unsigned int *sptr = ypoints[y] + xpoints[x];
1115 int yap = yapoints[y];
1120 r = r * (256 - yap);
1121 g = g * (256 - yap);
1122 b = b * (256 - yap);
1123 r = (r + (rr * yap)) >> 8;
1124 g = (g + (gg * yap)) >> 8;
1125 b = (b + (bb * yap)) >> 8;
1127 *dptr++ = qRgb(r >> 14, g >> 14, b >> 14);
1131 multithread_pixels_function(isi, dh, scaleSection);
1135 int dw,
int dh,
int dow,
int sow)
1137 const unsigned int **ypoints = isi->ypoints;
1138 int *xpoints = isi->xpoints;
1139 int *xapoints = isi->xapoints;
1140 int *yapoints = isi->yapoints;
1142 auto scaleSection = [&] (
int yStart,
int yEnd) {
1143 for (
int y = yStart; y < yEnd; ++y) {
1144 int Cy = yapoints[y] >> 16;
1145 int yap = yapoints[y] & 0xffff;
1147 unsigned int *dptr = dest + (y * dow);
1148 for (
int x = 0; x < dw; x++) {
1149 int Cx = xapoints[x] >> 16;
1150 int xap = xapoints[x] & 0xffff;
1152 const unsigned int *sptr = ypoints[y] + xpoints[x];
1156 int r = (rx >> 4) * yap;
1157 int g = (gx >> 4) * yap;
1158 int b = (bx >> 4) * yap;
1161 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
1165 r += (rx >> 4) * Cy;
1166 g += (gx >> 4) * Cy;
1167 b += (bx >> 4) * Cy;
1176 *dptr = qRgb(r >> 24, g >> 24, b >> 24);
1181 multithread_pixels_function(isi, dh, scaleSection);
1187 if (src.isNull() || dw <= 0 || dh <= 0)
1190 int w = src.width();
1191 int h = src.height();
1192 QImageScaleInfo *scaleinfo =
1193 qimageCalcScaleInfo(src, w, h, dw, dh,
true);
1197 buffer = QImage(dw, dh, src.format());
1198 if (buffer.isNull()) {
1199 qWarning(
"QImage: out of memory, returning null");
1200 qimageFreeScaleInfo(scaleinfo);
1204#if QT_CONFIG(raster_fp)
1205 if (qt_fpColorPrecision(src.format()))
1206 qt_qimageScaleRgbaFP(scaleinfo, (QRgbaFloat32 *)buffer.scanLine(0),
1207 dw, dh, dw, src.bytesPerLine() / 16);
1210#if QT_CONFIG(raster_64bit)
1211 if (src.depth() > 32)
1212 qt_qimageScaleRgba64(scaleinfo, (QRgba64 *)buffer.scanLine(0),
1213 dw, dh, dw, src.bytesPerLine() / 8);
1216 if (src.hasAlphaChannel() || src.format() == QImage::Format_CMYK8888)
1217 qt_qimageScaleAARGBA(scaleinfo, (
unsigned int *)buffer.scanLine(0),
1218 dw, dh, dw, src.bytesPerLine() / 4);
1220 qt_qimageScaleAARGB(scaleinfo, (
unsigned int *)buffer.scanLine(0),
1221 dw, dh, dw, src.bytesPerLine() / 4);
1223 qimageFreeScaleInfo(scaleinfo);
static QImageScaleInfo * qimageCalcScaleInfo(const QImage &img, int sw, int sh, int dw, int dh, char aa)
static int * qimageCalcXPoints(int sw, int dw)
static QImageScaleInfo * qimageFreeScaleInfo(QImageScaleInfo *isi)
static int * qimageCalcApoints(int s, int d, int up)
static const unsigned int ** qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh)
Combined button and popup list for selecting options.
static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b, int &a)
static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGB_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b)
QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)
static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, int dw, int dh, int dow, int sow)