Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qa8image.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qa8image_p.h"
5#include <QtCore/qalloc.h>
6#include <private/qimage_p.h>
7
9
10QA8ImageData::QA8ImageData(const QA8ImageData &other)
11 : QSharedData(other)
12 , width(other.width)
13 , height(other.height)
14 , nbytes(other.nbytes)
15{
16 if (nbytes && other.data)
17 data = static_cast<uchar *>(malloc(nbytes));
18 else
19 data = nullptr;
20
21 if (data) {
22 memcpy(data, other.data, nbytes);
23 } else {
24 width = 0;
25 height = 0;
26 nbytes = 0;
27 }
28}
29
30QA8ImageData::~QA8ImageData()
31{
32 QtPrivate::sizedFree(data, nbytes);
33}
34
35QA8ImageData *QA8ImageData::create(QSize size)
36{
37 QA8ImageData *data = new QA8ImageData;
38 if (size.isEmpty())
39 return data;
40
41 // pixel data stored as a 1-byte alpha value, tightly packed
42 const quint64 nbytes = quint64(size.width()) * quint64(size.height());
43 if (nbytes > INT_MAX) { // int used for bytes internally
44 qWarning("QA8Image: Rejecting image as size exceeds the upper limit of %i bytes",
45 INT_MAX);
46 return data;
47 }
48
49 data->data = static_cast<uchar *>(malloc(nbytes));
50 if (data->data) {
51 data->width = size.width();
52 data->height = size.height();
53 data->nbytes = int(nbytes);
54 }
55
56 return data;
57}
58
59QA8Image::QA8Image()
60 : d(new QA8ImageData)
61{
62}
63
64QA8Image::QA8Image(int width, int height)
65 : QA8Image(QSize(width, height))
66{
67}
68
69QA8Image::QA8Image(QSize size)
70 : d(QA8ImageData::create(size))
71{
72}
73
74QA8Image::QA8Image(QA8ImageData *data)
75 : d(data)
76{
77}
78
79bool QA8Image::isNull() const
80{
81 return !d->data;
82}
83
84int QA8Image::width() const
85{
86 return d->width;
87}
88
89int QA8Image::height() const
90{
91 return d->height;
92}
93
94QSize QA8Image::size() const
95{
96 return QSize(d->width, d->height);
97}
98
99qsizetype QA8Image::sizeInBytes() const
100{
101 return d->nbytes;
102}
103
104void QA8Image::fill(uchar value)
105{
106 if (isNull())
107 return;
108
109 memset(d->data, value, d->nbytes);
110}
111
112QA8Image QA8Image::copy(const QRect &r) const
113{
114 if (isNull())
115 return QA8Image();
116
117 if (r.isNull())
118 return QA8Image(new QA8ImageData(*d));
119
120 int x = r.x();
121 int y = r.y();
122 int w = r.width();
123 int h = r.height();
124
125 int dx = 0;
126 int dy = 0;
127 if (w <= 0 || h <= 0)
128 return QA8Image();
129
130 QA8Image image(w, h);
131 if (image.isNull())
132 return image;
133
134 if (x < 0 || y < 0 || x + w > d->width || y + h > d->height) {
135 image.fill(0);
136 if (x < 0) {
137 dx = -x;
138 x = 0;
139 }
140 if (y < 0) {
141 dy = -y;
142 y = 0;
143 }
144 }
145
146 int pixels_to_copy = qMax(w - dx, 0);
147 if (x > d->width)
148 pixels_to_copy = 0;
149 else if (pixels_to_copy > d->width - x)
150 pixels_to_copy = d->width - x;
151 int lines_to_copy = qMax(h - dy, 0);
152 if (y > d->height)
153 lines_to_copy = 0;
154 else if (lines_to_copy > d->height - y)
155 lines_to_copy = d->height - y;
156
157 const uchar *src = d->data + x + y * d->width;
158 uchar *dest = image.d->data + dx + dy * image.d->width;
159 for (int i = 0; i < lines_to_copy; ++i) {
160 memcpy(dest, src, pixels_to_copy);
161 src += d->width;
162 dest += image.d->width;
163 }
164
165 return image;
166}
167
168uchar *QA8Image::bits()
169{
170 return d->data;
171}
172
173const uchar *QA8Image::bits() const
174{
175 return d->data;
176}
177
178const uchar *QA8Image::constBits() const
179{
180 return d->data;
181}
182
183uchar *QA8Image::scanLine(int i)
184{
185 if (isNull())
186 return nullptr;
187
188 Q_ASSERT(i >= 0 && i < d->height);
189 return d->data + i * d->width;
190}
191
192const uchar *QA8Image::scanLine(int i) const
193{
194 if (isNull())
195 return nullptr;
196
197 Q_ASSERT(i >= 0 && i < d->height);
198 return d->data + i * d->width;
199}
200
201const uchar *QA8Image::constScanLine(int i) const
202{
203 if (isNull())
204 return nullptr;
205
206 Q_ASSERT(i >= 0 && i < d->height);
207 return d->data + i * d->width;
208}
209
210QImage QA8Image::toImage(QImage::Format format) const
211{
212 if (isNull())
213 return QImage();
214
215 QImage image(d->width, d->height, qt_depthForFormat(format) == 8 ?
216 format : QImage::Format_ARGB32_Premultiplied);
217 if (image.isNull())
218 return image;
219
220 if (image.depth() == 8) {
221 for (int y = 0; y < d->height; ++y)
222 memcpy(image.scanLine(y), constScanLine(y), d->width);
223 } else {
224 for (int y = 0; y < d->height; ++y) {
225 for (int x = 0; x < d->width; ++x) {
226 uint alpha = *(d->data + x + y * d->width);
227 image.setPixel(x, y, alpha << 24);
228 }
229 }
230
231 if (image.format() != format)
232 image = std::move(image).convertToFormat(format);
233 }
234
235 return image;
236}
237
238QT_END_NAMESPACE
Combined button and popup list for selecting options.