54 #include <qpa/qplatformintegration.h>
55 #include <private/qguiapplication_p.h>
59 #include <qpa/qplatformpixmap.h>
60 #include <private/qcolortransform_p.h>
61 #include <private/qmemrotate_p.h>
62 #include <private/qimagescale_p.h>
63 #include <private/qpixellayout_p.h>
64 #include <private/qsimd_p.h>
68 #include <private/qpaintengine_raster_p.h>
70 #include <private/qimage_p.h>
71 #include <private/qfont_p.h>
78 #include <qtgui_tracepoints_p.h>
89 #if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
90 #pragma message disable narrowptr
94 #define QIMAGE_SANITYCHECK_MEMORY(image) \
95 if ((image).isNull()) { \
96 qWarning("QImage: out of memory, returning null image"); \
105 static int next_qimage_serial_number()
114 ser_no(next_qimage_serial_number()),
145 auto d = std::make_unique<QImageData>();
150 d->colortable.resize(2);
162 d->has_alpha_clut =
false;
163 d->is_cached =
false;
165 d->bytes_per_line =
params.bytesPerLine;
167 d->data = (
uchar *)malloc(
d->nbytes);
188 #if defined(_M_ARM) && defined(_MSC_VER)
189 #pragma optimize("", off)
194 bool has_alpha_pixels =
false;
204 has_alpha_pixels =
true;
209 for (
int y=0;
y<
height && !has_alpha_pixels; ++
y) {
210 uint alphaAnd = 0xff000000;
212 alphaAnd &=
reinterpret_cast<const uint*
>(
bits)[
x];
213 has_alpha_pixels = (alphaAnd != 0xff000000);
221 for (
int y=0;
y<
height && !has_alpha_pixels; ++
y) {
222 uchar alphaAnd = 0xff;
224 alphaAnd &=
bits[
x * 4+ 3];
225 has_alpha_pixels = (alphaAnd != 0xff);
233 for (
int y=0;
y<
height && !has_alpha_pixels; ++
y) {
234 uint alphaAnd = 0xc0000000;
236 alphaAnd &=
reinterpret_cast<const uint*
>(
bits)[
x];
237 has_alpha_pixels = (alphaAnd != 0xc0000000);
247 for (
int y=0;
y<
height && !has_alpha_pixels; ++
y) {
248 uchar alphaAnd = 0xff;
249 while (
bits < end_bits) {
253 has_alpha_pixels = (alphaAnd != 0xff);
263 for (
int y=0;
y<
height && !has_alpha_pixels; ++
y) {
264 uchar alphaAnd = 0xfc;
265 while (
bits < end_bits) {
269 has_alpha_pixels = (alphaAnd != 0xfc);
277 for (
int y=0;
y<
height && !has_alpha_pixels; ++
y) {
280 alphaAnd &=
reinterpret_cast<const ushort*
>(
bits)[
x];
281 has_alpha_pixels = (alphaAnd != 0xf000);
288 for (
int y=0;
y<
height && !has_alpha_pixels; ++
y) {
298 for (
int y = 0;
y <
height && !has_alpha_pixels; ++
y) {
307 for (
int y = 0;
y <
height && !has_alpha_pixels; ++
y) {
309 has_alpha_pixels |= ((
float *)
bits)[
x * 4 + 3] < 1.0f;
336 return has_alpha_pixels;
338 #if defined(_M_ARM) && defined(_MSC_VER)
339 #pragma optimize("", on)
839 if (bpl < min_bytes_per_line)
843 params.bytesPerLine = bpl;
844 if (mul_overflow<qsizetype>(bpl,
height, &
params.totalSize))
852 d->ro_data = readOnly;
859 d->bytes_per_line =
params.bytesPerLine;
1004 #ifndef QT_NO_IMAGEFORMAT_XPM
1031 qWarning(
"QImage::QImage(), XPM is not supported");
1047 if (
image.paintingActive()) {
1049 image.copy().swap(*
this);
1079 if (
image.paintingActive()) {
1145 dst->devicePixelRatio =
src->devicePixelRatio;
1151 copyPhysicalMetadata(
dst,
src);
1153 dst->colorSpace =
src->colorSpace;
1158 dst->setDotsPerMeterX(
src.dotsPerMeterX());
1159 dst->setDotsPerMeterY(
src.dotsPerMeterY());
1160 dst->setDevicePixelRatio(
src.devicePixelRatio());
1161 const auto textKeys =
src.textKeys();
1162 for (
const auto &
key: textKeys)
1219 copyMetadata(
image.d, d);
1230 if (
w <= 0 ||
h <= 0)
1252 int pixels_to_copy = qMax(
w - dx, 0);
1255 else if (pixels_to_copy > d->
width -
x)
1256 pixels_to_copy = d->
width -
x;
1257 int lines_to_copy = qMax(
h - dy, 0);
1260 else if (lines_to_copy > d->
height -
y)
1261 lines_to_copy = d->
height -
y;
1263 bool byteAligned =
true;
1265 byteAligned = !(dx & 7) && !(
x & 7) && !(pixels_to_copy & 7);
1271 for (
int i = 0;
i < lines_to_copy; ++
i) {
1272 memcpy(dest,
src, bytes_to_copy);
1274 dest +=
image.d->bytes_per_line;
1279 for (
int i = 0;
i < lines_to_copy; ++
i) {
1280 for (
int j = 0;
j < pixels_to_copy; ++
j) {
1281 if (
src[(
x +
j) >> 3] & (0x80 >> ((
x +
j) & 7)))
1282 dest[(dx +
j) >> 3] |= (0x80 >> ((dx +
j) & 7));
1284 dest[(dx +
j) >> 3] &= ~(0x80 >> ((dx +
j) & 7));
1287 dest +=
image.d->bytes_per_line;
1293 for (
int i = 0;
i < lines_to_copy; ++
i) {
1294 for (
int j = 0;
j < pixels_to_copy; ++
j) {
1295 if (
src[(
x +
j) >> 3] & (0x1 << ((
x +
j) & 7)))
1296 dest[(dx +
j) >> 3] |= (0x1 << ((dx +
j) & 7));
1298 dest[(dx +
j) >> 3] &= ~(0x1 << ((dx +
j) & 7));
1301 dest +=
image.d->bytes_per_line;
1305 copyMetadata(
image.d, d);
1333 return d ? d->
width : 0;
1345 return d ? d->
height : 0;
1387 return d ? d->
depth : 0;
1526 return d ? d->
nbytes : 0;
1576 qWarning(
"QImage::setColor: Index out of bound %d",
i);
1697 return d ? d->
data :
nullptr;
1713 return d ? d->
data :
nullptr;
1749 if (d->
depth == 1) {
1758 qt_rectfill<quint8>(d->
data,
pixel, 0, 0,
1761 }
else if (d->
depth == 16) {
1767 }
else if (d->
depth == 24) {
1780 ::memcpy(&cu, &cf,
sizeof(
quint64));
1781 qt_rectfill<quint64>(
reinterpret_cast<quint64*
>(d->
data), cu,
1798 pixel |= 0xff000000;
1800 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
1801 pixel |= 0xff000000;
1803 pixel |= 0x000000ff;
1806 pixel |= 0xc0000000;
1867 fill(ARGB2RGBA(
color.rgba() | 0xff000000));
1903 qt_rectfill<quint64>(
reinterpret_cast<quint64*
>(d->
data), opaque,
1911 qt_rectfill<quint64>(
reinterpret_cast<quint64 *
>(d->
data),
color.rgba64().premultiplied(),
1963 }
else if (
depth() > 32) {
1996 float *
p =
reinterpret_cast<float *
>(
data);
1997 for (
int x = 0;
x < d->
width; ++
x) {
2007 }
else if (
depth() == 64) {
2030 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
2031 xorbits = 0xffffff00;
2034 xorbits = 0x00ffffff;
2042 xorbits = 0x00ffffff;
2046 xorbits = 0x3fffffff;
2057 if (originalFormat != d->
format) {
2092 qWarning(
"QImage::setColorCount: null image");
2165 #if QT_CONFIG(raster_fp)
2167 converter = convert_generic_over_rgba32f;
2180 copyMetadata(
image.d, d);
2215 return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2) + abs(
a1 -
a2);
2220 int current_distance = INT_MAX;
2221 for (
int i=0;
i<clut.
size(); ++
i) {
2222 int dist = pixel_distance(pixel, clut.
at(
i));
2223 if (
dist < current_distance) {
2224 current_distance =
dist;
2234 dest.setColorTable(clut);
2238 int h =
src.height();
2239 int w =
src.width();
2244 for (
int y=0;
y<
h; ++
y) {
2245 const QRgb *src_pixels = (
const QRgb *)
src.scanLine(
y);
2247 for (
int x=0;
x<
w; ++
x) {
2248 int src_pixel = src_pixels[
x];
2251 value = closestMatch(src_pixel, clut);
2260 for (
int y=0;
y<
h; ++
y) {
2261 const QRgb *src_pixels = (
const QRgb *)
src.scanLine(
y);
2262 for (
int x=0;
x<
w; ++
x) {
2263 int src_pixel = src_pixels[
x];
2413 qWarning(
"QImage::pixelIndex: coordinate (%d,%d) out of range",
x,
y);
2419 return (*(
s + (
x >> 3)) >> (7- (
x & 7))) & 1;
2421 return (*(
s + (
x >> 3)) >> (
x & 7)) & 1;
2425 qWarning(
"QImage::pixelIndex: Not applicable for %d-bpp images (no palette)", d->
depth);
2454 qWarning(
"QImage::pixel: coordinate (%d,%d) out of range",
x,
y);
2463 index = (*(
s + (
x >> 3)) >> (~
x & 7)) & 1;
2466 index = (*(
s + (
x >> 3)) >> (
x & 7)) & 1;
2476 qWarning(
"QImage::pixel: color table index %d out of range.",
index);
2484 return 0xff000000 |
reinterpret_cast<const QRgb *
>(
s)[
x];
2487 return reinterpret_cast<const QRgb *
>(
s)[
x];
2491 return RGBA2ARGB(
reinterpret_cast<const quint32 *
>(
s)[
x]);
2503 return reinterpret_cast<const QRgba64 *
>(
s)[
x].toArgb32();
2517 return *
layout->fetchToARGB32PM(&
result,
s,
x, 1,
nullptr,
nullptr);
2549 qWarning(
"QImage::setPixel: coordinate (%d,%d) out of range",
x,
y);
2557 if (index_or_rgb > 1) {
2558 qWarning(
"QImage::setPixel: Index %d out of range", index_or_rgb);
2560 if (index_or_rgb==0)
2561 *(
s + (
x >> 3)) &= ~(1 << (
x & 7));
2563 *(
s + (
x >> 3)) |= (1 << (
x & 7));
2565 if (index_or_rgb==0)
2566 *(
s + (
x >> 3)) &= ~(1 << (7-(
x & 7)));
2568 *(
s + (
x >> 3)) |= (1 << (7-(
x & 7)));
2573 qWarning(
"QImage::setPixel: Index %d out of range", index_or_rgb);
2576 s[
x] = index_or_rgb;
2581 ((
uint *)
s)[
x] = 0xff000000 | index_or_rgb;
2585 ((
uint *)
s)[
x] = index_or_rgb;
2591 ((
uint *)
s)[
x] = ARGB2RGBA(0xff000000 | index_or_rgb);
2595 ((
uint *)
s)[
x] = ARGB2RGBA(index_or_rgb);
2637 layout->storeFromRGB32(
s, &index_or_rgb,
x, 1,
nullptr,
nullptr);
2639 layout->storeFromARGB32PM(
s, &index_or_rgb,
x, 1,
nullptr,
nullptr);
2667 qWarning(
"QImage::pixelColor: coordinate (%d,%d) out of range",
x,
y);
2698 color.setRgbF(
p.red(),
p.green(),
p.blue(),
p.alpha());
2708 color.setRgbF(
p.red(),
p.green(),
p.blue(),
p.alpha());
2717 c =
c.unpremultiplied();
2746 qWarning(
"QImage::setPixelColor: coordinate (%d,%d) out of range",
x,
y);
2750 if (!
color.isValid()) {
2751 qWarning(
"QImage::setPixelColor: color is invalid");
2760 c =
c.premultiplied();
2767 qWarning(
"QImage::setPixelColor: called on monochrome or indexed format");
2795 c16f = c16f.premultiplied();
2808 c32f = c32f.premultiplied();
2849 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
2856 for (
int i = 0;
i < d->
width; ++
i) {
2865 for (
int i = 0;
i < d->
width; ++
i) {
2877 const auto fetch =
layout->fetchToARGB32PM;
2884 for (
int i = 0;
i <
l; ++
i) {
2971 qWarning(
"QImage::scaled: Image is a null image");
2978 newSize.
scale(
s, aspectMode);
2981 if (newSize ==
size())
3008 qWarning(
"QImage::scaleWidth: Image is a null image");
3038 qWarning(
"QImage::scaleHeight: Image is a null image");
3073 if (d->
depth == 1) {
3080 if (!
mask.isNull()) {
3082 copyPhysicalMetadata(
mask.d, d);
3087 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
3117 if (d->
depth != 32) {
3122 #define PIX(x,y) (*((const QRgb*)scanLine(y)+x) & 0x00ffffff)
3134 if (background !=
PIX(
w-1,0) &&
3135 background !=
PIX(0,
h-1) &&
3136 background !=
PIX(
w-1,
h-1)) {
3137 background =
PIX(
w-1,0);
3138 if (background !=
PIX(
w-1,
h-1) &&
3139 background !=
PIX(0,
h-1) &&
3141 background =
PIX(
w-1,
h-1);
3147 uchar *ypp, *ypc, *ypn;
3150 ypn =
m.scanLine(0);
3152 for (
y = 0;
y <
h;
y++) {
3155 ypn = (
y ==
h-1) ?
nullptr :
m.scanLine(
y+1);
3157 for (
x = 0;
x <
w;
x++) {
3160 if ((
x == 0 ||
y == 0 ||
x ==
w-1 ||
y ==
h-1 ||
3161 !(*(ypc + ((
x-1) >> 3)) & (1 << ((
x-1) & 7))) ||
3162 !(*(ypc + ((
x+1) >> 3)) & (1 << ((
x+1) & 7))) ||
3163 !(*(ypp + (
x >> 3)) & (1 << (
x & 7))) ||
3164 !(*(ypn + (
x >> 3)) & (1 << (
x & 7)))) &&
3165 ( (*(ypc + (
x >> 3)) & (1 << (
x & 7)))) &&
3166 ((*
p & 0x00ffffff) == background)) {
3168 *(ypc + (
x >> 3)) &= ~(1 << (
x & 7));
3176 ypn =
m.scanLine(0);
3178 for (
y = 0;
y <
h;
y++) {
3181 ypn = (
y ==
h-1) ?
nullptr :
m.scanLine(
y+1);
3183 for (
x = 0;
x <
w;
x++) {
3184 if ((*
p & 0x00ffffff) != background) {
3186 *(ypc + ((
x-1) >> 3)) |= (1 << ((
x-1) & 7));
3188 *(ypc + ((
x+1) >> 3)) |= (1 << ((
x+1) & 7));
3190 *(ypp + (
x >> 3)) |= (1 << (
x & 7));
3192 *(ypn + (
x >> 3)) |= (1 << (
x & 7));
3201 copyPhysicalMetadata(
m.d, d);
3227 if (
depth() == 32) {
3230 for (
int w = 0;
w < d->
width;
w++) {
3232 *(
s + (
w >> 3)) |= (1 << (
w & 7));
3238 for (
int w = 0;
w < d->
width;
w++) {
3240 *(
s + (
w >> 3)) |= (1 << (
w & 7));
3248 copyPhysicalMetadata(maskImage.d, d);
3277 int dstXIncr,
int dstYIncr,
3284 const int srcYEnd =
dstY0 ?
h / 2 :
h;
3286 T *srcPtr = (
T *) (
src->data +
srcY *
src->bytes_per_line);
3287 T *dstPtr = (
T *) (
dst->data +
dstY *
dst->bytes_per_line);
3294 int srcXEnd2 =
w / 2;
3295 T *srcPtr = (
T *) (
src->data +
srcY *
src->bytes_per_line);
3301 T *srcPtr = (
T *) (
src->data +
srcY *
src->bytes_per_line);
3302 T *dstPtr = (
T *) (
dst->data +
dstY *
dst->bytes_per_line);
3311 const int data_bytes_per_line =
w * (
depth / 8);
3313 uint *srcPtr =
reinterpret_cast<uint *
>(
src->data);
3314 uint *dstPtr =
reinterpret_cast<uint *
>(
dst->data + (
h - 1) *
dst->bytes_per_line);
3316 const int uint_per_line = (data_bytes_per_line + 3) >> 2;
3317 for (
int y = 0;
y <
h; ++
y) {
3319 for (
int x = 0;
x < uint_per_line;
x++) {
3320 const uint d = dstPtr[
x];
3321 const uint s = srcPtr[
x];
3325 srcPtr +=
src->bytes_per_line >> 2;
3326 dstPtr -=
dst->bytes_per_line >> 2;
3331 uchar *dstPtr =
dst->data + (
h - 1) *
dst->bytes_per_line;
3333 memcpy(dstPtr, srcPtr, data_bytes_per_line);
3334 srcPtr +=
src->bytes_per_line;
3335 dstPtr -=
dst->bytes_per_line;
3344 int h =
src->height;
3347 if (
src->depth == 1) {
3352 if (vertical && !horizontal) {
3358 int dstX0 = 0, dstXIncr = 1;
3359 int dstY0 = 0, dstYIncr = 1;
3397 if (horizontal &&
dst->depth == 1) {
3399 const int shift = 8 - (
dst->width % 8);
3401 for (
int y = 0;
y <
h; ++
y) {
3412 p[-1] |= (*
p & (128 >>
i)) >> (7 -
i);
3417 p[-1] |= (*
p & (1 <<
i)) << (7 -
i);
3440 if ((d->
width <= 1 && d->
height <= 1) || (!horizontal && !vertical))
3453 copyMetadata(
result.d, d);
3465 if (!d || (d->
width <= 1 && d->
height <= 1) || (!horizontal && !vertical))
3504 qWarning(
"Trying to rb-swap an image format where it doesn't make sense");
3542 for (
int i = 0;
i <
res.d->colortable.size();
i++) {
3544 res.d->colortable[
i] =
QRgb(((
c << 16) & 0xff0000) | ((
c >> 16) & 0xff) | (
c & 0xff00ff00));
3550 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
3559 *
q = ((
c << 16) & 0xff000000) | ((
c >> 16) & 0xff00) | (
c & 0x00ff00ff);
3580 *
q = ((
c << 16) & 0xff0000) | ((
c >> 16) & 0xff) | (
c & 0xff00ff00);
3595 *
q = ((
c << 11) & 0xf800) | ((
c >> 11) & 0x1f) | (
c & 0x07e0);
3607 copyMetadata(
res.d, d);
3639 d->
colortable[
i] =
QRgb(((
c << 16) & 0xff0000) | ((
c >> 16) & 0xff) | (
c & 0xff00ff00));
3645 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
3651 *
p = ((
c << 16) & 0xff000000) | ((
c >> 16) & 0xff00) | (
c & 0x00ff00ff);
3668 *
p = ((
c << 16) & 0xff0000) | ((
c >> 16) & 0xff) | (
c & 0xff00ff00);
3679 *
p = ((
c << 11) & 0xf800) | ((
c >> 11) & 0x1f) | (
c & 0x07e0);
3876 qWarning(
"QPixmap::save: Quality out of range [-1, 100]");
3885 #if !defined(QT_NO_DATASTREAM)
3899 if (
s.version() >= 5) {
3900 if (
image.isNull()) {
3908 QImageWriter writer(
s.device(),
s.version() == 1 ?
"bmp" :
"png");
3925 if (
s.version() >= 5) {
3934 if (
image.isNull() &&
s.version() >= 5)
3984 for (
int y=0;
y<
h; ++
y) {
3985 for (
int x=0;
x<
w; ++
x) {
3996 const uint *
p2 =
reinterpret_cast<const uint*
>(
i.scanLine(
l));
3998 if ((*
p1++ & 0x00ffffff) != (*
p2++ & 0x00ffffff))
4022 return !(*
this ==
i);
4213 if (platformIntegration)
4309 #define IWX_MSB(b) if (trigx < maxws && trigy < maxhs) { \
4310 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4311 (1 << (7-((trigx>>12)&7)))) \
4318 #define IWX_LSB(b) if (trigx < maxws && trigy < maxhs) { \
4319 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4320 (1 << ((trigx>>12)&7))) \
4327 #define IWX_PIX(b) if (trigx < maxws && trigy < maxhs) { \
4328 if ((*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4329 (1 << (7-((trigx>>12)&7)))) == 0) \
4339 int m11 = int(trueMat.
m11()*4096.0);
4340 int m12 = int(trueMat.
m12()*4096.0);
4341 int m21 = int(trueMat.
m21()*4096.0);
4342 int m22 = int(trueMat.
m22()*4096.0);
4343 int dx =
qRound(trueMat.
dx()*4096.0);
4344 int dy =
qRound(trueMat.
dy()*4096.0);
4346 int m21ydx = dx + (
xoffset<<16) + (m11 + m21) / 2;
4347 int m22ydy = dy + (m12 + m22) / 2;
4350 uint maxws = sWidth<<12;
4351 uint maxhs = sHeight<<12;
4353 for (
int y=0;
y<dHeight;
y++) {
4356 uchar *maxp = dptr + dbpl;
4360 while (dptr < maxp) {
4361 if (trigx < maxws && trigy < maxhs)
4362 *dptr = *(sptr+sbpl*(trigy>>12)+(trigx>>12));
4370 while (dptr < maxp) {
4371 if (trigx < maxws && trigy < maxhs)
4372 *((
ushort*)dptr) = *((
const ushort *)(sptr+sbpl*(trigy>>12) +
4382 while (dptr < maxp) {
4383 if (trigx < maxws && trigy < maxhs) {
4384 const uchar *
p2 = sptr+sbpl*(trigy>>12) + ((trigx>>12)*3);
4396 while (dptr < maxp) {
4397 if (trigx < maxws && trigy < maxhs)
4398 *((
uint*)dptr) = *((
const uint *)(sptr+sbpl*(trigy>>12) +
4413 while (dptr < maxp) {
4426 while (dptr < maxp) {
4500 if (!d || alphaChannel.
isNull())
4504 qWarning(
"QImage::setAlphaChannel: "
4505 "Unable to set alpha channel while image is being painted on");
4510 if (d->
format == alphaFormat)
4520 sourceImage = alphaChannel;
4618 switch (
src.format()) {
4621 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
4625 #if QT_CONFIG(raster_64bit)
4634 #if QT_CONFIG(raster_fp)
4648 if (
src.hasAlphaChannel())
4655 copyMetadata(
src.d, d);
4663 if (
image.colorCount() > 0)
4664 out.setColorTable(
image.colorTable());
4669 memrotate(
image.constBits(),
w,
h,
image.bytesPerLine(),
out.bits(),
out.bytesPerLine());
4671 for (
int y=0;
y<
h; ++
y) {
4672 if (
image.colorCount())
4673 for (
int x=0;
x<
w; ++
x)
4676 for (
int x=0;
x<
w; ++
x)
4687 return image.mirrored(
true,
true);
4691 if (
image.colorCount() > 0)
4692 out.setColorTable(
image.colorTable());
4695 memrotate(
image.constBits(),
w,
h,
image.bytesPerLine(),
out.bits(),
out.bytesPerLine());
4703 if (
image.colorCount() > 0)
4704 out.setColorTable(
image.colorTable());
4709 memrotate(
image.constBits(),
w,
h,
image.bytesPerLine(),
out.bits(),
out.bytesPerLine());
4711 for (
int y=0;
y<
h; ++
y) {
4712 if (
image.colorCount())
4713 for (
int x=0;
x<
w; ++
x)
4716 for (
int x=0;
x<
w; ++
x)
4764 bool complex_xform =
false;
4765 bool scale_xform =
false;
4766 bool nonpaintable_scale_xform =
false;
4770 else if (mat.
m11() == -1. && mat.
m22() == -1.)
4771 return rotated180(*
this);
4777 hd = int(
qAbs(mat.
m22()) * hs + 0.9999);
4778 wd = int(
qAbs(mat.
m11()) *
ws + 0.9999);
4783 if (hd * 2 < hs || wd * 2 <
ws)
4784 nonpaintable_scale_xform =
true;
4787 if (mat.
m12() == 1. && mat.
m21() == -1.)
4788 return rotated90(*
this);
4789 else if (mat.
m12() == -1. && mat.
m21() == 1.)
4790 return rotated270(*
this);
4795 QRect r =
a.boundingRect().toAlignedRect();
4798 complex_xform =
true;
4801 if (wd == 0 || hd == 0)
4808 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
4812 #if QT_CONFIG(raster_64bit)
4817 if (mat.
m11() > 0.0F && mat.
m22() > 0.0F)
4824 if (nonpaintable_scale_xform
4825 #
if QT_CONFIG(thread) && !defined(Q_OS_WASM)
4826 || (
ws * hs) >= (1<<20)
4829 if (mat.
m11() < 0.0F && mat.
m22() < 0.0F) {
4831 }
else if (mat.
m11() < 0.0F) {
4833 }
else if (mat.
m22() < 0.0F) {
4854 QImage dImage(wd, hd, target_format);
4874 memset(dImage.
bits(), 0x00, dImage.d->
nbytes);
4888 p.setTransform(mat);
4889 p.drawImage(
QPoint(0, 0), sImage);
4899 qt_xForm_helper(mat, 0,
type,
bpp, dImage.
bits(), dbpl, 0, hd, sptr, sbpl,
ws, hs);
4901 copyMetadata(dImage.d, d);
4969 qWarning() <<
"QImage::convertToColorSpace: Output colorspace is not valid";
5056 transformSegment = [&](
int yStart,
int yEnd) {
5057 for (
int y = yStart;
y < yEnd; ++
y) {
5063 transformSegment = [&](
int yStart,
int yEnd) {
5064 for (
int y = yStart;
y < yEnd; ++
y) {
5071 #if QT_CONFIG(thread) && !defined(Q_OS_WASM)
5080 threadPool->
start([&,
y, yn]() {
5081 transformSegment(
y,
y + yn);
5089 transformSegment(0,
height());
5091 if (oldFormat !=
format())
5092 *
this = std::move(*this).convertToFormat(oldFormat);
5107 return converter(
this,
flags);
5113 #if QT_CONFIG(raster_fp)
5115 return convert_generic_inplace_over_rgba32f(
this, newFormat,
flags);
5134 #ifndef QT_NO_DEBUG_STREAM
5144 dbg <<
i.size() <<
",format=" <<
i.format() <<
",depth=" <<
i.depth();
5146 dbg <<
",colorCount=" <<
i.colorCount();
5147 const int bytesPerLine =
i.bytesPerLine();
5148 dbg <<
",devicePixelRatio=" <<
i.devicePixelRatio()
5149 <<
",bytesPerLine=" << bytesPerLine <<
",sizeInBytes=" <<
i.sizeInBytes();
5151 const int outputLength = qMin(bytesPerLine, 24);
5153 <<
QByteArray(
reinterpret_cast<const char *
>(
i.scanLine(0)), outputLength).toHex()
5637 return pixelformats[
format];
5645 for (
int i = 0;
i < NImageFormats;
i++) {
5646 if (
format == pixelformats[
i])
5649 return Format_Invalid;
5669 const auto textKeys =
image.textKeys();
5681 for (
const auto &pair : pairs) {
5684 if (!pair.trimmed().isEmpty())
5688 if (!
key.trimmed().isEmpty())
5697 #include "moc_qimage.cpp"
small capitals from c petite p scientific f u
small capitals from c petite p scientific i
[1]
T fetchAndAddRelaxed(T valueToAdd) noexcept
T loadRelaxed() const noexcept
The QBuffer class provides a QIODevice interface for a QByteArray.
The QByteArray class provides an array of bytes.
static QByteArray fromRawData(const char *data, qsizetype size)
The QColor class provides colors based on RGB, HSV or CMYK values.
QRgb rgba() const noexcept
The QColorSpace class provides a color space abstraction.
QColorTransform transformationToColorSpace(const QColorSpace &colorspace) const
bool isValid() const noexcept
The QDataStream class provides serialization of binary data to a QIODevice.
operator>>(QDataStream &ds, qfloat16 &f)
operator<<(QDataStream &ds, qfloat16 f)
The QDebug class provides an output stream for debugging information.
QDebug & verbosity(int verbosityLevel)
Convenience class for custom QDebug operators.
static QPlatformIntegration * platformIntegration()
The QHash class is a template class that provides a hash-table-based dictionary.
The QIODevice class is the base interface class of all I/O devices in Qt.
The QImage class provides a hardware-independent image representation that allows direct access to th...
void setDotsPerMeterY(int)
bool loadFromData(QByteArrayView data, const char *format=nullptr)
int dotsPerMeterX() const
int bitPlaneCount() const
bool hasAlphaChannel() const
void convertToColorSpace(const QColorSpace &)
bool valid(int x, int y) const
QImage createAlphaMask(Qt::ImageConversionFlags flags=Qt::AutoColor) const
QImage scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
void setAlphaChannel(const QImage &alphaChannel)
QColorSpace colorSpace() const
void setText(const QString &key, const QString &value)
static QPixelFormat toPixelFormat(QImage::Format format) noexcept
qsizetype bytesPerLine() const
void setPixel(int x, int y, uint index_or_rgb)
QImage scaledToWidth(int w, Qt::TransformationMode mode=Qt::FastTransformation) const
[9]
void setPixelColor(int x, int y, const QColor &c)
QList< QRgb > colorTable() const
QRgb pixel(int x, int y) const
QImage transformed(const QTransform &matrix, Qt::TransformationMode mode=Qt::FastTransformation) const
QImage copy(const QRect &rect=QRect()) const
QImage createHeuristicMask(bool clipTight=true) const
qsizetype sizeInBytes() const
QImage smoothScaled(int w, int h) const
void rgbSwapped_inplace()
void convertTo(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor)
QImage convertedToColorSpace(const QColorSpace &) const
bool operator==(const QImage &) const
bool save(const QString &fileName, const char *format=nullptr, int quality=-1) const
void applyColorTransform(const QColorTransform &transform)
void setColorTable(const QList< QRgb > &colors)
QImage createMaskFromColor(QRgb color, Qt::MaskMode mode=Qt::MaskInColor) const
QPaintEngine * paintEngine() const override
bool convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags)
@ Format_RGBA32FPx4_Premultiplied
@ Format_RGBA64_Premultiplied
@ Format_ARGB6666_Premultiplied
@ Format_ARGB8555_Premultiplied
@ Format_RGBA8888_Premultiplied
@ Format_ARGB8565_Premultiplied
@ Format_RGBA16FPx4_Premultiplied
@ Format_A2BGR30_Premultiplied
@ Format_ARGB32_Premultiplied
@ Format_A2RGB30_Premultiplied
@ Format_ARGB4444_Premultiplied
virtual int metric(PaintDeviceMetric metric) const override
QImage mirrored(bool horizontally=false, bool vertically=true) const &
QPixelFormat pixelFormat() const noexcept
QColor pixelColor(int x, int y) const
QImage scaledToHeight(int h, Qt::TransformationMode mode=Qt::FastTransformation) const
static QTransform trueMatrix(const QTransform &, int w, int h)
bool operator!=(const QImage &) const
static QImage fromData(QByteArrayView data, const char *format=nullptr)
bool load(QIODevice *device, const char *format)
const uchar * constScanLine(int) const
QStringList textKeys() const
void setColor(int i, QRgb c)
void setDevicePixelRatio(qreal scaleFactor)
void mirrored_inplace(bool horizontal, bool vertical)
qreal devicePixelRatio() const
void setDotsPerMeterX(int)
QImage rgbSwapped_helper() const
int dotsPerMeterY() const
static QImage::Format toImageFormat(QPixelFormat format) noexcept
const uchar * constBits() const
QSizeF deviceIndependentSize() const
QImage mirrored_helper(bool horizontal, bool vertical) const
QString text(const QString &key=QString()) const
QImage & operator=(const QImage &)
int pixelIndex(int x, int y) const
QImage convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const
void setColorSpace(const QColorSpace &)
bool reinterpretAsFormat(Format f)
void setOffset(const QPoint &)
int devType() const override
void invertPixels(InvertMode=InvertRgb)
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const &
@ TransformationRotate270
static void executeImageHooks(qint64 key)
The QImageReader class provides a format independent interface for reading images from files or other...
The QImageWriter class provides a format independent interface for writing images to files or other d...
bool write(const QImage &image)
void setQuality(int quality)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void resize(qsizetype size)
void append(parameter_type t)
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue=T()) const
QList< Key > keys() const
@ PdmDevicePixelRatioScaled
static qreal devicePixelRatioFScale()
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
The QPainter class performs low-level painting on widgets and other paint devices.
void setCompositionMode(CompositionMode mode)
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags=Qt::AutoColor)
@ CompositionMode_DestinationIn
void setRenderHint(RenderHint hint, bool on=true)
The QPoint class defines a point in the plane using integer precision.
constexpr int x() const noexcept
constexpr int y() const noexcept
The QPolygonF class provides a list of points using floating point precision. \inmodule QtGui.
The QRasterPaintEngine class enables hardware acceleration of painting operations in Qt for Embedded ...
The QRectF class defines a finite rectangle in the plane using floating point precision.
The QRect class defines a rectangle in the plane using integer precision.
constexpr int width() const noexcept
constexpr static QRgba64 fromArgb32(uint rgb)
void setAlpha(quint16 _alpha)
static constexpr QRgbaFloat fromArgb32(uint rgb)
constexpr Q_ALWAYS_INLINE QRgbaFloat unpremultiplied() const
The QSemaphore class provides a general counting semaphore.
The QSizeF class defines the size of a two-dimensional object using floating point precision.
The QSize class defines the size of a two-dimensional object using integer point precision.
constexpr int height() const noexcept
constexpr int width() const noexcept
constexpr int & rheight() noexcept
void scale(int w, int h, Qt::AspectRatioMode mode) noexcept
constexpr int & rwidth() noexcept
The QString class provides a Unicode character string.
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString simplified() const &
QString & insert(qsizetype i, QChar c)
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString left(qsizetype n) const
The QStringList class provides a list of strings.
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
static QThread * currentThread()
The QThreadPool class manages a collection of QThreads.
void start(QRunnable *runnable, int priority=0)
static QThreadPool * globalInstance()
bool contains(const QThread *thread) const
The QVariant class acts like a union for the most common Qt data types.
static auto fromValue(const T &value) -> std::enable_if_t< std::is_copy_constructible_v< T >, QVariant >
Provides 16-bit floating point support.
QCache< int, Employee > cache
[0]
for(n=0;n< outline->n_points;n++)
auto it unsigned count const
QFuture< QtPrivate::MapResultType< Sequence, MapFunctor > > mapped(QThreadPool *pool, Sequence &&sequence, MapFunctor &&map)
void swap(SimpleVector< T > &v1, SimpleVector< T > &v2)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp
#define Q_BASIC_ATOMIC_INITIALIZER(a)
#define QT_WARNING_DISABLE_MSVC(number)
QList< QString > QStringList
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
ushort qConvertRgb32To16(uint c)
QRgb qConvertRgb16To32(uint c)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
QT_BEGIN_NAMESPACE bool done
int qRound(qfloat16 d) noexcept
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
QT_END_INCLUDE_NAMESPACE typedef double qreal
unsigned long long quint64
#define QT_CONFIG(feature)
bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth, uchar *dptr, qsizetype dbpl, int p_inc, int dHeight, const uchar *sptr, qsizetype sbpl, int sWidth, int sHeight)
bool qt_read_xpm_image_or_array(QIODevice *device, const char *const *source, QImage &image)
#define QIMAGE_SANITYCHECK_MEMORY(image)
void do_flip(QImageData *dst, QImageData *src, int w, int h, int depth)
Q_GUI_EXPORT void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient)
void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
QMap< QString, QString > qt_getImageTextFromDescription(const QString &description)
void do_mirror_data(QImageData *dst, QImageData *src, int dstX0, int dstY0, int dstXIncr, int dstYIncr, int w, int h)
QMap< QString, QString > qt_getImageText(const QImage &image, const QString &description)
bool convert_generic_inplace_over_rgb64(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags)
Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats]
InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats]
void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha)
void convert_generic_over_rgb64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
const uchar * qt_get_bitflip_array()
void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags flags)
int qt_depthForFormat(QImage::Format format)
bool qt_fpColorPrecision(QImage::Format format)
bool(* InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags)
QImage::Format qt_alphaVersion(QImage::Format format)
bool qt_highColorPrecision(QImage::Format format, bool opaque=false)
void(* Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
QImage::Format qt_alphaVersionForPainting(QImage::Format format)
QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3]
GLint GLint GLint GLint dstX0
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint GLint dstY
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLint GLint GLint srcY
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint dstX
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLint GLint GLint GLint GLint dstY0
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLuint GLenum GLenum transform
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLdouble GLdouble GLdouble GLdouble q
GLenum GLenum GLsizei void * table
QPixelLayout qPixelLayouts[QImage::NImageFormats]
QRgba64 qConvertA2rgb30ToRgb64< PixelOrderBGR >(uint rgb)
unsigned int qConvertRgb64ToRgb30< PixelOrderBGR >(QRgba64 c)
QRgb qConvertA2rgb30ToArgb32< PixelOrderBGR >(uint c)
void(QT_FASTCALL * RbSwapFunc)(uchar *dst, const uchar *src, int count)
uint qConvertRgb32ToRgb30< PixelOrderRGB >(QRgb c)
QRgba64 qConvertA2rgb30ToRgb64< PixelOrderRGB >(uint rgb)
uint qConvertArgb32ToA2rgb30< PixelOrderBGR >(QRgb c)
uint qConvertRgb32ToRgb30< PixelOrderBGR >(QRgb c)
QRgb qConvertA2rgb30ToArgb32< PixelOrderRGB >(uint c)
unsigned int qConvertRgb64ToRgb30< PixelOrderRGB >(QRgba64 c)
void(* MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
uint qConvertArgb32ToA2rgb30< PixelOrderRGB >(QRgb c)
uint qRgbSwapRgb30(uint c)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
constexpr bool qIsGray(QRgb rgb)
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
constexpr QRgb qRgb(int r, int g, int b)
constexpr QRgb qPremultiply(QRgb x)
constexpr int qAlpha(QRgb rgb)
constexpr QRgba64 qRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
#define Q_TRACE_SCOPE(x,...)
std::uniform_real_distribution dist(1, 2.5)
[2]
QTextStream out(stdout)
[7]
bool checkForAlphaPixels() const
bool doImageIO(const QImage *image, QImageWriter *io, int quality) const
static ImageSizeParameters calculateImageParameters(qsizetype width, qsizetype height, qsizetype depth)
static QImageData * get(QImage &img) noexcept
bool convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags)
static QImageData * create(const QSize &size, QImage::Format format)
QPaintEngine * paintEngine
QMap< QString, QString > text
QImageCleanupFunction cleanupFunction
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.