4#include <private/qimagescale_p.h>
5#include <private/qdrawhelper_p.h>
6#include <private/qimage_p.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
65 static const unsigned int**
qimageCalcYPoints(
const unsigned int *src,
int sw,
int sh,
int dh);
79 int sw,
int sh,
int dh)
81 const unsigned int **p;
89 p =
new const unsigned int* [dh+1];
91 int up = qAbs(dh) >= sh;
92 val = up ? 0x8000 * sh / dh - 0x8000 : 0;
93 inc = (((qint64)sh) << 16) / dh;
94 for (
int i = 0; i < dh; i++) {
95 p[j++] = src + qMax(0LL, val >> 16) * sw;
99 for (
int i = dh / 2; --i >= 0; ) {
100 const unsigned int *tmp = p[i];
101 p[i] = p[dh - i - 1];
110 int *p, j = 0, rv = 0;
119 int up = qAbs(dw) >= sw;
120 val = up ? 0x8000 * sw / dw - 0x8000 : 0;
121 inc = (((qint64)sw) << 16) / dw;
122 for (
int i = 0; i < dw; i++) {
123 p[j++] = qMax(0LL, val >> 16);
128 for (
int i = dw / 2; --i >= 0; ) {
130 p[i] = p[dw - i - 1];
139 int *p, j = 0, rv = 0;
149 qint64 val = 0x8000 * s / d - 0x8000;
150 qint64 inc = (((qint64)s) << 16) / d;
151 for (
int i = 0; i < d; i++) {
155 else if (pos >= (s - 1))
158 p[j++] = (val >> 8) - ((val >> 8) & 0xffffff00);
164 qint64 inc = (((qint64)s) << 16) / d;
165 int Cp = (((d << 14) + s - 1) / s);
166 for (
int i = 0; i < d; i++) {
167 int ap = ((0x10000 - (val & 0xffff)) * Cp) >> 16;
168 p[j] = ap | (Cp << 16);
175 for (
int i = d / 2; --i >= 0; ) {
187 delete[] isi->xpoints;
188 delete[] isi->ypoints;
189 delete[] isi->xapoints;
190 delete[] isi->yapoints;
198 int dw,
int dh,
char aa)
200 QImageScaleInfo *isi;
203 scw = dw * qlonglong(img.width()) / sw;
204 sch = dh * qlonglong(img.height()) / sh;
206 isi =
new QImageScaleInfo;
212 isi->xup_yup = (qAbs(dw) >= sw) + ((qAbs(dh) >= sh) << 1);
214 isi->xpoints = qimageCalcXPoints(img.width(), scw);
216 return qimageFreeScaleInfo(isi);
217 isi->ypoints = qimageCalcYPoints((
const unsigned int *)img.scanLine(0),
218 img.bytesPerLine() / 4, img.height(), sch);
220 return qimageFreeScaleInfo(isi);
222 isi->xapoints = qimageCalcApoints(img.width(), scw, isi->xup_yup & 1);
224 return qimageFreeScaleInfo(isi);
225 isi->yapoints = qimageCalcApoints(img.height(), sch, isi->xup_yup & 2);
227 return qimageFreeScaleInfo(isi);
234 int dw,
int dh,
int dow,
int sow);
237 int dw,
int dh,
int dow,
int sow);
240 int dw,
int dh,
int dow,
int sow);
242#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
244void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi,
unsigned int *dest,
245 int dw,
int dh,
int dow,
int sow);
247void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi,
unsigned int *dest,
248 int dw,
int dh,
int dow,
int sow);
250void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi,
unsigned int *dest,
251 int dw,
int dh,
int dow,
int sow);
254#if defined(QT_COMPILER_SUPPORTS_LSX)
256void qt_qimageScaleAARGBA_up_x_down_y_lsx(QImageScaleInfo *isi,
unsigned int *dest,
257 int dw,
int dh,
int dow,
int sow);
259void qt_qimageScaleAARGBA_down_x_up_y_lsx(QImageScaleInfo *isi,
unsigned int *dest,
260 int dw,
int dh,
int dow,
int sow);
262void qt_qimageScaleAARGBA_down_xy_lsx(QImageScaleInfo *isi,
unsigned int *dest,
263 int dw,
int dh,
int dow,
int sow);
266#if defined(__ARM_NEON__)
268void qt_qimageScaleAARGBA_up_x_down_y_neon(QImageScaleInfo *isi,
unsigned int *dest,
269 int dw,
int dh,
int dow,
int sow);
271void qt_qimageScaleAARGBA_down_x_up_y_neon(QImageScaleInfo *isi,
unsigned int *dest,
272 int dw,
int dh,
int dow,
int sow);
274void qt_qimageScaleAARGBA_down_xy_neon(QImageScaleInfo *isi,
unsigned int *dest,
275 int dw,
int dh,
int dow,
int sow);
279 int dw,
int dh,
int dow,
int sow)
281 const unsigned int **ypoints = isi->ypoints;
282 int *xpoints = isi->xpoints;
283 int *xapoints = isi->xapoints;
284 int *yapoints = isi->yapoints;
287 auto scaleSection = [&] (
int yStart,
int yEnd) {
288 for (
int y = yStart; y < yEnd; ++y) {
290 const unsigned int *sptr = ypoints[y];
291 unsigned int *dptr = dest + (y * dow);
292 const int yap = yapoints[y];
294 for (
int x = 0; x < dw; x++) {
295 const unsigned int *pix = sptr + xpoints[x];
296 const int xap = xapoints[x];
298 *dptr = interpolate_4_pixels(pix, pix + sow, xap, yap);
300 *dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - yap, pix[sow], yap);
304 for (
int x = 0; x < dw; x++) {
305 const unsigned int *pix = sptr + xpoints[x];
306 const int xap = xapoints[x];
308 *dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - xap, pix[1], xap);
316 multithread_pixels_function(isi, dh, scaleSection);
321 int dw,
int dh,
int dow,
int sow)
324 if (isi->xup_yup == 3) {
325 qt_qimageScaleAARGBA_up_xy(isi, dest, dw, dh, dow, sow);
328 else if (isi->xup_yup == 1) {
329#ifdef QT_COMPILER_SUPPORTS_SSE4_1
330 if (qCpuHasFeature(SSE4_1))
331 qt_qimageScaleAARGBA_up_x_down_y_sse4<
false>(isi, dest, dw, dh, dow, sow);
333#elif defined(QT_COMPILER_SUPPORTS_LSX)
334 if (qCpuHasFeature(LSX))
335 qt_qimageScaleAARGBA_up_x_down_y_lsx<
false>(isi, dest, dw, dh, dow, sow);
337#elif defined(__ARM_NEON__)
338 if (qCpuHasFeature(NEON))
339 qt_qimageScaleAARGBA_up_x_down_y_neon<
false>(isi, dest, dw, dh, dow, sow);
342 qt_qimageScaleAARGBA_up_x_down_y(isi, dest, dw, dh, dow, sow);
345 else if (isi->xup_yup == 2) {
346#ifdef QT_COMPILER_SUPPORTS_SSE4_1
347 if (qCpuHasFeature(SSE4_1))
348 qt_qimageScaleAARGBA_down_x_up_y_sse4<
false>(isi, dest, dw, dh, dow, sow);
350#elif defined(QT_COMPILER_SUPPORTS_LSX)
351 if (qCpuHasFeature(LSX))
352 qt_qimageScaleAARGBA_down_x_up_y_lsx<
false>(isi, dest, dw, dh, dow, sow);
354#elif defined(__ARM_NEON__)
355 if (qCpuHasFeature(NEON))
356 qt_qimageScaleAARGBA_down_x_up_y_neon<
false>(isi, dest, dw, dh, dow, sow);
359 qt_qimageScaleAARGBA_down_x_up_y(isi, dest, dw, dh, dow, sow);
363#ifdef QT_COMPILER_SUPPORTS_SSE4_1
364 if (qCpuHasFeature(SSE4_1))
365 qt_qimageScaleAARGBA_down_xy_sse4<
false>(isi, dest, dw, dh, dow, sow);
367#elif defined(QT_COMPILER_SUPPORTS_LSX)
368 if (qCpuHasFeature(LSX))
369 qt_qimageScaleAARGBA_down_xy_lsx<
false>(isi, dest, dw, dh, dow, sow);
371#elif defined(__ARM_NEON__)
372 if (qCpuHasFeature(NEON))
373 qt_qimageScaleAARGBA_down_xy_neon<
false>(isi, dest, dw, dh, dow, sow);
376 qt_qimageScaleAARGBA_down_xy(isi, dest, dw, dh, dow, sow);
382 r = qRed(*pix) * xyap;
383 g = qGreen(*pix) * xyap;
384 b = qBlue(*pix) * xyap;
385 a = qAlpha(*pix) * xyap;
387 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) {
389 r += qRed(*pix) * Cxy;
390 g += qGreen(*pix) * Cxy;
391 b += qBlue(*pix) * Cxy;
392 a += qAlpha(*pix) * Cxy;
396 g += qGreen(*pix) * j;
397 b += qBlue(*pix) * j;
398 a += qAlpha(*pix) * j;
402 int dw,
int dh,
int dow,
int sow)
404 const unsigned int **ypoints = isi->ypoints;
405 int *xpoints = isi->xpoints;
406 int *xapoints = isi->xapoints;
407 int *yapoints = isi->yapoints;
410 auto scaleSection = [&] (
int yStart,
int yEnd) {
411 for (
int y = yStart; y < yEnd; ++y) {
412 int Cy = yapoints[y] >> 16;
413 int yap = yapoints[y] & 0xffff;
415 unsigned int *dptr = dest + (y * dow);
416 for (
int x = 0; x < dw; x++) {
417 const unsigned int *sptr = ypoints[y] + xpoints[x];
421 int xap = xapoints[x];
430 r = (r + (rr * xap)) >> 8;
431 g = (g + (gg * xap)) >> 8;
432 b = (b + (bb * xap)) >> 8;
433 a = (a + (aa * xap)) >> 8;
435 *dptr++ = qRgba(r >> 14, g >> 14, b >> 14, a >> 14);
439 multithread_pixels_function(isi, dh, scaleSection);
443 int dw,
int dh,
int dow,
int sow)
445 const unsigned int **ypoints = isi->ypoints;
446 int *xpoints = isi->xpoints;
447 int *xapoints = isi->xapoints;
448 int *yapoints = isi->yapoints;
451 auto scaleSection = [&] (
int yStart,
int yEnd) {
452 for (
int y = yStart; y < yEnd; ++y) {
453 unsigned int *dptr = dest + (y * dow);
454 for (
int x = 0; x < dw; x++) {
455 int Cx = xapoints[x] >> 16;
456 int xap = xapoints[x] & 0xffff;
458 const unsigned int *sptr = ypoints[y] + xpoints[x];
462 int yap = yapoints[y];
471 r = (r + (rr * yap)) >> 8;
472 g = (g + (gg * yap)) >> 8;
473 b = (b + (bb * yap)) >> 8;
474 a = (a + (aa * yap)) >> 8;
476 *dptr = qRgba(r >> 14, g >> 14, b >> 14, a >> 14);
481 multithread_pixels_function(isi, dh, scaleSection);
485 int dw,
int dh,
int dow,
int sow)
487 const unsigned int **ypoints = isi->ypoints;
488 int *xpoints = isi->xpoints;
489 int *xapoints = isi->xapoints;
490 int *yapoints = isi->yapoints;
492 auto scaleSection = [&] (
int yStart,
int yEnd) {
493 for (
int y = yStart; y < yEnd; ++y) {
494 int Cy = (yapoints[y]) >> 16;
495 int yap = (yapoints[y]) & 0xffff;
497 unsigned int *dptr = dest + (y * dow);
498 for (
int x = 0; x < dw; x++) {
499 int Cx = xapoints[x] >> 16;
500 int xap = xapoints[x] & 0xffff;
502 const unsigned int *sptr = ypoints[y] + xpoints[x];
506 int r = ((rx>>4) * yap);
507 int g = ((gx>>4) * yap);
508 int b = ((bx>>4) * yap);
509 int a = ((ax>>4) * yap);
512 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
528 *dptr = qRgba(r >> 24, g >> 24, b >> 24, a >> 24);
533 multithread_pixels_function(isi, dh, scaleSection);
536#if QT_CONFIG(raster_64bit)
537static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
538 int dw,
int dh,
int dow,
int sow);
540static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
541 int dw,
int dh,
int dow,
int sow);
543static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
544 int dw,
int dh,
int dow,
int sow);
546static void qt_qimageScaleRgba64_up_xy(QImageScaleInfo *isi, QRgba64 *dest,
547 int dw,
int dh,
int dow,
int sow)
549 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
550 int *xpoints = isi->xpoints;
551 int *xapoints = isi->xapoints;
552 int *yapoints = isi->yapoints;
554 auto scaleSection = [&] (
int yStart,
int yEnd) {
555 for (
int y = yStart; y < yEnd; ++y) {
556 const QRgba64 *sptr = ypoints[y];
557 QRgba64 *dptr = dest + (y * dow);
558 const int yap = yapoints[y];
560 for (
int x = 0; x < dw; x++) {
561 const QRgba64 *pix = sptr + xpoints[x];
562 const int xap = xapoints[x];
564 *dptr = interpolate_4_pixels_rgb64(pix, pix + sow, xap * 256, yap * 256);
566 *dptr = interpolate256(pix[0], 256 - yap, pix[sow], yap);
570 for (
int x = 0; x < dw; x++) {
571 const QRgba64 *pix = sptr + xpoints[x];
572 const int xap = xapoints[x];
574 *dptr = interpolate256(pix[0], 256 - xap, pix[1], xap);
582 multithread_pixels_function(isi, dh, scaleSection);
585void qt_qimageScaleRgba64(QImageScaleInfo *isi, QRgba64 *dest,
586 int dw,
int dh,
int dow,
int sow)
588 if (isi->xup_yup == 3)
589 qt_qimageScaleRgba64_up_xy(isi, dest, dw, dh, dow, sow);
590 else if (isi->xup_yup == 1)
591 qt_qimageScaleRgba64_up_x_down_y(isi, dest, dw, dh, dow, sow);
592 else if (isi->xup_yup == 2)
593 qt_qimageScaleRgba64_down_x_up_y(isi, dest, dw, dh, dow, sow);
595 qt_qimageScaleRgba64_down_xy(isi, dest, dw, dh, dow, sow);
598inline static void qt_qimageScaleRgba64_helper(
const QRgba64 *pix,
int xyap,
int Cxy,
int step, qint64 &r, qint64 &g, qint64 &b, qint64 &a)
600 r = pix->red() * xyap;
601 g = pix->green() * xyap;
602 b = pix->blue() * xyap;
603 a = pix->alpha() * xyap;
605 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy ){
607 r += pix->red() * Cxy;
608 g += pix->green() * Cxy;
609 b += pix->blue() * Cxy;
610 a += pix->alpha() * Cxy;
614 g += pix->green() * j;
615 b += pix->blue() * j;
616 a += pix->alpha() * j;
619static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
620 int dw,
int dh,
int dow,
int sow)
622 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
623 int *xpoints = isi->xpoints;
624 int *xapoints = isi->xapoints;
625 int *yapoints = isi->yapoints;
627 auto scaleSection = [&] (
int yStart,
int yEnd) {
628 for (
int y = yStart; y < yEnd; ++y) {
629 int Cy = (yapoints[y]) >> 16;
630 int yap = (yapoints[y]) & 0xffff;
632 QRgba64 *dptr = dest + (y * dow);
633 for (
int x = 0; x < dw; x++) {
634 const QRgba64 *sptr = ypoints[y] + xpoints[x];
636 qt_qimageScaleRgba64_helper(sptr, yap, Cy, sow, r, g, b, a);
638 int xap = xapoints[x];
640 qint64 rr, gg, bb, aa;
641 qt_qimageScaleRgba64_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa);
647 r = (r + (rr * xap)) >> 8;
648 g = (g + (gg * xap)) >> 8;
649 b = (b + (bb * xap)) >> 8;
650 a = (a + (aa * xap)) >> 8;
652 *dptr++ = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
656 multithread_pixels_function(isi, dh, scaleSection);
659static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
660 int dw,
int dh,
int dow,
int sow)
662 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
663 int *xpoints = isi->xpoints;
664 int *xapoints = isi->xapoints;
665 int *yapoints = isi->yapoints;
667 auto scaleSection = [&] (
int yStart,
int yEnd) {
668 for (
int y = yStart; y < yEnd; ++y) {
669 QRgba64 *dptr = dest + (y * dow);
670 for (
int x = 0; x < dw; x++) {
671 int Cx = xapoints[x] >> 16;
672 int xap = xapoints[x] & 0xffff;
674 const QRgba64 *sptr = ypoints[y] + xpoints[x];
676 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, r, g, b, a);
678 int yap = yapoints[y];
680 qint64 rr, gg, bb, aa;
681 qt_qimageScaleRgba64_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa);
687 r = (r + (rr * yap)) >> 8;
688 g = (g + (gg * yap)) >> 8;
689 b = (b + (bb * yap)) >> 8;
690 a = (a + (aa * yap)) >> 8;
692 *dptr = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
697 multithread_pixels_function(isi, dh, scaleSection);
700static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
701 int dw,
int dh,
int dow,
int sow)
703 const QRgba64 **ypoints = (
const QRgba64 **)isi->ypoints;
704 int *xpoints = isi->xpoints;
705 int *xapoints = isi->xapoints;
706 int *yapoints = isi->yapoints;
708 auto scaleSection = [&] (
int yStart,
int yEnd) {
709 for (
int y = yStart; y < yEnd; ++y) {
710 int Cy = (yapoints[y]) >> 16;
711 int yap = (yapoints[y]) & 0xffff;
713 QRgba64 *dptr = dest + (y * dow);
714 for (
int x = 0; x < dw; x++) {
715 int Cx = xapoints[x] >> 16;
716 int xap = xapoints[x] & 0xffff;
718 const QRgba64 *sptr = ypoints[y] + xpoints[x];
719 qint64 rx, gx, bx, ax;
720 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
727 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
729 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
736 qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
742 *dptr = qRgba64(r >> 28, g >> 28, b >> 28, a >> 28);
747 multithread_pixels_function(isi, dh, scaleSection);
751#if QT_CONFIG(raster_fp)
752static void qt_qimageScaleRgbaFP_up_x_down_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
753 int dw,
int dh,
int dow,
int sow);
755static void qt_qimageScaleRgbaFP_down_x_up_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
756 int dw,
int dh,
int dow,
int sow);
758static void qt_qimageScaleRgbaFP_down_xy(QImageScaleInfo *isi, QRgbaFloat32 *dest,
759 int dw,
int dh,
int dow,
int sow);
761static void qt_qimageScaleRgbaFP_up_xy(QImageScaleInfo *isi, QRgbaFloat32 *dest,
762 int dw,
int dh,
int dow,
int sow)
764 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
765 int *xpoints = isi->xpoints;
766 int *xapoints = isi->xapoints;
767 int *yapoints = isi->yapoints;
769 auto scaleSection = [&] (
int yStart,
int yEnd) {
770 for (
int y = yStart; y < yEnd; ++y) {
771 const QRgbaFloat32 *sptr = ypoints[y];
772 QRgbaFloat32 *dptr = dest + (y * dow);
773 const int yap = yapoints[y];
775 for (
int x = 0; x < dw; x++) {
776 const QRgbaFloat32 *pix = sptr + xpoints[x];
777 const int xap = xapoints[x];
779 *dptr = interpolate_4_pixels_rgba32f(pix, pix + sow, xap * 256, yap * 256);
781 *dptr = interpolate_rgba32f(pix[0], 256 - yap, pix[sow], yap);
785 for (
int x = 0; x < dw; x++) {
786 const QRgbaFloat32 *pix = sptr + xpoints[x];
787 const int xap = xapoints[x];
789 *dptr = interpolate_rgba32f(pix[0], 256 - xap, pix[1], xap);
797 multithread_pixels_function(isi, dh, scaleSection);
800void qt_qimageScaleRgbaFP(QImageScaleInfo *isi, QRgbaFloat32 *dest,
801 int dw,
int dh,
int dow,
int sow)
803 if (isi->xup_yup == 3)
804 qt_qimageScaleRgbaFP_up_xy(isi, dest, dw, dh, dow, sow);
805 else if (isi->xup_yup == 1)
806 qt_qimageScaleRgbaFP_up_x_down_y(isi, dest, dw, dh, dow, sow);
807 else if (isi->xup_yup == 2)
808 qt_qimageScaleRgbaFP_down_x_up_y(isi, dest, dw, dh, dow, sow);
810 qt_qimageScaleRgbaFP_down_xy(isi, dest, dw, dh, dow, sow);
813inline static void qt_qimageScaleRgbaFP_helper(
const QRgbaFloat32 *pix,
int xyap,
int Cxy,
int step,
float &r,
float &g,
float &b,
float &a)
815 constexpr float f = (1.0f /
float(1<<14));
816 const float xyapf = xyap * f;
817 const float Cxyf = Cxy * f;
818 r = pix->red() * xyapf;
819 g = pix->green() * xyapf;
820 b = pix->blue() * xyapf;
821 a = pix->alpha() * xyapf;
823 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy ){
825 r += pix->red() * Cxyf;
826 g += pix->green() * Cxyf;
827 b += pix->blue() * Cxyf;
828 a += pix->alpha() * Cxyf;
831 const float jf = j * f;
832 r += pix->red() * jf;
833 g += pix->green() * jf;
834 b += pix->blue() * jf;
835 a += pix->alpha() * jf;
838static void qt_qimageScaleRgbaFP_up_x_down_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
839 int dw,
int dh,
int dow,
int sow)
841 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
842 int *xpoints = isi->xpoints;
843 int *xapoints = isi->xapoints;
844 int *yapoints = isi->yapoints;
846 auto scaleSection = [&] (
int yStart,
int yEnd) {
847 for (
int y = yStart; y < yEnd; ++y) {
848 int Cy = (yapoints[y]) >> 16;
849 int yap = (yapoints[y]) & 0xffff;
851 QRgbaFloat32 *dptr = dest + (y * dow);
852 for (
int x = 0; x < dw; x++) {
853 const QRgbaFloat32 *sptr = ypoints[y] + xpoints[x];
855 qt_qimageScaleRgbaFP_helper(sptr, yap, Cy, sow, r, g, b, a);
857 int xap = xapoints[x];
858 float xapf = xap * (1.f / 256.f);
860 float rr, gg, bb, aa;
861 qt_qimageScaleRgbaFP_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa);
863 r = (r * (1.0f - xapf) + (rr * xapf));
864 g = (g * (1.0f - xapf) + (gg * xapf));
865 b = (b * (1.0f - xapf) + (bb * xapf));
866 a = (a * (1.0f - xapf) + (aa * xapf));
868 *dptr++ = QRgbaFloat32{r, g, b, a};
872 multithread_pixels_function(isi, dh, scaleSection);
875static void qt_qimageScaleRgbaFP_down_x_up_y(QImageScaleInfo *isi, QRgbaFloat32 *dest,
876 int dw,
int dh,
int dow,
int sow)
878 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
879 int *xpoints = isi->xpoints;
880 int *xapoints = isi->xapoints;
881 int *yapoints = isi->yapoints;
883 auto scaleSection = [&] (
int yStart,
int yEnd) {
884 for (
int y = yStart; y < yEnd; ++y) {
885 QRgbaFloat32 *dptr = dest + (y * dow);
886 for (
int x = 0; x < dw; x++) {
887 int Cx = xapoints[x] >> 16;
888 int xap = xapoints[x] & 0xffff;
890 const QRgbaFloat32 *sptr = ypoints[y] + xpoints[x];
892 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, r, g, b, a);
894 int yap = yapoints[y];
895 float yapf = yap * (1.f / 256.f);
897 float rr, gg, bb, aa;
898 qt_qimageScaleRgbaFP_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa);
900 r = (r * (1.0f - yapf) + (rr * yapf));
901 g = (g * (1.0f - yapf) + (gg * yapf));
902 b = (b * (1.0f - yapf) + (bb * yapf));
903 a = (a * (1.0f - yapf) + (aa * yapf));
905 *dptr++ = QRgbaFloat32{r, g, b, a};
909 multithread_pixels_function(isi, dh, scaleSection);
912static void qt_qimageScaleRgbaFP_down_xy(QImageScaleInfo *isi, QRgbaFloat32 *dest,
913 int dw,
int dh,
int dow,
int sow)
915 const QRgbaFloat32 **ypoints = (
const QRgbaFloat32 **)isi->ypoints;
916 int *xpoints = isi->xpoints;
917 int *xapoints = isi->xapoints;
918 int *yapoints = isi->yapoints;
920 auto scaleSection = [&] (
int yStart,
int yEnd) {
921 constexpr float f = 1.f /
float(1 << 14);
922 for (
int y = yStart; y < yEnd; ++y) {
923 int Cy = (yapoints[y]) >> 16;
924 int yap = (yapoints[y]) & 0xffff;
926 QRgbaFloat32 *dptr = dest + (y * dow);
927 for (
int x = 0; x < dw; x++) {
928 int Cx = xapoints[x] >> 16;
929 int xap = xapoints[x] & 0xffff;
931 const QRgbaFloat32 *sptr = ypoints[y] + xpoints[x];
932 float rx, gx, bx, ax;
933 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
935 const float yapf = yap * f;
936 const float Cyf = Cy * f;
942 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
944 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
951 qt_qimageScaleRgbaFP_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
952 const float jf = j * f;
958 *dptr++ = QRgbaFloat32{r, g, b, a};
962 multithread_pixels_function(isi, dh, scaleSection);
967 int dw,
int dh,
int dow,
int sow);
970 int dw,
int dh,
int dow,
int sow);
973 int dw,
int dh,
int dow,
int sow);
977 int dw,
int dh,
int dow,
int sow)
980 if (isi->xup_yup == 3) {
981 qt_qimageScaleAARGBA_up_xy(isi, dest, dw, dh, dow, sow);
984 else if (isi->xup_yup == 1) {
985#ifdef QT_COMPILER_SUPPORTS_SSE4_1
986 if (qCpuHasFeature(SSE4_1))
987 qt_qimageScaleAARGBA_up_x_down_y_sse4<
true>(isi, dest, dw, dh, dow, sow);
989#elif defined QT_COMPILER_SUPPORTS_LSX
990 if (qCpuHasFeature(LSX))
991 qt_qimageScaleAARGBA_up_x_down_y_lsx<
true>(isi, dest, dw, dh, dow, sow);
993#elif defined(__ARM_NEON__)
994 if (qCpuHasFeature(NEON))
995 qt_qimageScaleAARGBA_up_x_down_y_neon<
true>(isi, dest, dw, dh, dow, sow);
998 qt_qimageScaleAARGB_up_x_down_y(isi, dest, dw, dh, dow, sow);
1001 else if (isi->xup_yup == 2) {
1002#ifdef QT_COMPILER_SUPPORTS_SSE4_1
1003 if (qCpuHasFeature(SSE4_1))
1004 qt_qimageScaleAARGBA_down_x_up_y_sse4<
true>(isi, dest, dw, dh, dow, sow);
1006#elif defined QT_COMPILER_SUPPORTS_LSX
1007 if (qCpuHasFeature(LSX))
1008 qt_qimageScaleAARGBA_down_x_up_y_lsx<
true>(isi, dest, dw, dh, dow, sow);
1010#elif defined(__ARM_NEON__)
1011 if (qCpuHasFeature(NEON))
1012 qt_qimageScaleAARGBA_down_x_up_y_neon<
true>(isi, dest, dw, dh, dow, sow);
1015 qt_qimageScaleAARGB_down_x_up_y(isi, dest, dw, dh, dow, sow);
1019#ifdef QT_COMPILER_SUPPORTS_SSE4_1
1020 if (qCpuHasFeature(SSE4_1))
1021 qt_qimageScaleAARGBA_down_xy_sse4<
true>(isi, dest, dw, dh, dow, sow);
1023#elif defined QT_COMPILER_SUPPORTS_LSX
1024 if (qCpuHasFeature(LSX))
1025 qt_qimageScaleAARGBA_down_xy_lsx<
true>(isi, dest, dw, dh, dow, sow);
1027#elif defined(__ARM_NEON__)
1028 if (qCpuHasFeature(NEON))
1029 qt_qimageScaleAARGBA_down_xy_neon<
true>(isi, dest, dw, dh, dow, sow);
1032 qt_qimageScaleAARGB_down_xy(isi, dest, dw, dh, dow, sow);
1039 r = qRed(*pix) * xyap;
1040 g = qGreen(*pix) * xyap;
1041 b = qBlue(*pix) * xyap;
1043 for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) {
1045 r += qRed(*pix) * Cxy;
1046 g += qGreen(*pix) * Cxy;
1047 b += qBlue(*pix) * Cxy;
1050 r += qRed(*pix) * j;
1051 g += qGreen(*pix) * j;
1052 b += qBlue(*pix) * j;
1056 int dw,
int dh,
int dow,
int sow)
1058 const unsigned int **ypoints = isi->ypoints;
1059 int *xpoints = isi->xpoints;
1060 int *xapoints = isi->xapoints;
1061 int *yapoints = isi->yapoints;
1064 auto scaleSection = [&] (
int yStart,
int yEnd) {
1065 for (
int y = yStart; y < yEnd; ++y) {
1066 int Cy = yapoints[y] >> 16;
1067 int yap = yapoints[y] & 0xffff;
1069 unsigned int *dptr = dest + (y * dow);
1070 for (
int x = 0; x < dw; x++) {
1071 const unsigned int *sptr = ypoints[y] + xpoints[x];
1075 int xap = xapoints[x];
1080 r = r * (256 - xap);
1081 g = g * (256 - xap);
1082 b = b * (256 - xap);
1083 r = (r + (rr * xap)) >> 8;
1084 g = (g + (gg * xap)) >> 8;
1085 b = (b + (bb * xap)) >> 8;
1087 *dptr++ = qRgb(r >> 14, g >> 14, b >> 14);
1091 multithread_pixels_function(isi, dh, scaleSection);
1095 int dw,
int dh,
int dow,
int sow)
1097 const unsigned int **ypoints = isi->ypoints;
1098 int *xpoints = isi->xpoints;
1099 int *xapoints = isi->xapoints;
1100 int *yapoints = isi->yapoints;
1103 auto scaleSection = [&] (
int yStart,
int yEnd) {
1104 for (
int y = yStart; y < yEnd; ++y) {
1105 unsigned int *dptr = dest + (y * dow);
1106 for (
int x = 0; x < dw; x++) {
1107 int Cx = xapoints[x] >> 16;
1108 int xap = xapoints[x] & 0xffff;
1110 const unsigned int *sptr = ypoints[y] + xpoints[x];
1114 int yap = yapoints[y];
1119 r = r * (256 - yap);
1120 g = g * (256 - yap);
1121 b = b * (256 - yap);
1122 r = (r + (rr * yap)) >> 8;
1123 g = (g + (gg * yap)) >> 8;
1124 b = (b + (bb * yap)) >> 8;
1126 *dptr++ = qRgb(r >> 14, g >> 14, b >> 14);
1130 multithread_pixels_function(isi, dh, scaleSection);
1134 int dw,
int dh,
int dow,
int sow)
1136 const unsigned int **ypoints = isi->ypoints;
1137 int *xpoints = isi->xpoints;
1138 int *xapoints = isi->xapoints;
1139 int *yapoints = isi->yapoints;
1141 auto scaleSection = [&] (
int yStart,
int yEnd) {
1142 for (
int y = yStart; y < yEnd; ++y) {
1143 int Cy = yapoints[y] >> 16;
1144 int yap = yapoints[y] & 0xffff;
1146 unsigned int *dptr = dest + (y * dow);
1147 for (
int x = 0; x < dw; x++) {
1148 int Cx = xapoints[x] >> 16;
1149 int xap = xapoints[x] & 0xffff;
1151 const unsigned int *sptr = ypoints[y] + xpoints[x];
1155 int r = (rx >> 4) * yap;
1156 int g = (gx >> 4) * yap;
1157 int b = (bx >> 4) * yap;
1160 for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
1164 r += (rx >> 4) * Cy;
1165 g += (gx >> 4) * Cy;
1166 b += (bx >> 4) * Cy;
1175 *dptr = qRgb(r >> 24, g >> 24, b >> 24);
1180 multithread_pixels_function(isi, dh, scaleSection);
1186 if (src.isNull() || dw <= 0 || dh <= 0)
1189 int w = src.width();
1190 int h = src.height();
1191 QImageScaleInfo *scaleinfo =
1192 qimageCalcScaleInfo(src, w, h, dw, dh,
true);
1196 buffer = QImage(dw, dh, src.format());
1197 if (buffer.isNull()) {
1198 qWarning(
"QImage: out of memory, returning null");
1199 qimageFreeScaleInfo(scaleinfo);
1203#if QT_CONFIG(raster_fp)
1204 if (qt_fpColorPrecision(src.format()))
1205 qt_qimageScaleRgbaFP(scaleinfo, (QRgbaFloat32 *)buffer.scanLine(0),
1206 dw, dh, dw, src.bytesPerLine() / 16);
1209#if QT_CONFIG(raster_64bit)
1210 if (src.depth() > 32)
1211 qt_qimageScaleRgba64(scaleinfo, (QRgba64 *)buffer.scanLine(0),
1212 dw, dh, dw, src.bytesPerLine() / 8);
1215 if (src.hasAlphaChannel() || src.format() == QImage::Format_CMYK8888)
1216 qt_qimageScaleAARGBA(scaleinfo, (
unsigned int *)buffer.scanLine(0),
1217 dw, dh, dw, src.bytesPerLine() / 4);
1219 qt_qimageScaleAARGB(scaleinfo, (
unsigned int *)buffer.scanLine(0),
1220 dw, dh, dw, src.bytesPerLine() / 4);
1222 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)