1 /****************************************************************************
2 **
3 ** DQt - D bindings for the Qt Toolkit
4 **
5 ** GNU Lesser General Public License Usage
6 ** This file may be used under the terms of the GNU Lesser
7 ** General Public License version 3 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
9 ** packaging of this file. Please review the following information to
10 ** ensure the GNU Lesser General Public License version 3 requirements
11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
12 **
13 ****************************************************************************/
14 module qt.gui.image;
15 extern(C++):
16 
17 import qt.config;
18 import qt.core.bytearray;
19 import qt.core.global;
20 import qt.core.iodevice;
21 import qt.core.metatype;
22 import qt.core.namespace;
23 import qt.core.objectdefs;
24 import qt.core.point;
25 import qt.core.rect;
26 import qt.core.size;
27 import qt.core.string;
28 import qt.core.stringlist;
29 import qt.core.typeinfo;
30 import qt.core.variant;
31 import qt.core.vector;
32 import qt.gui.color;
33 import qt.gui.colorspace;
34 import qt.gui.colortransform;
35 import qt.gui.matrix;
36 import qt.gui.paintdevice;
37 import qt.gui.paintengine;
38 import qt.gui.pixelformat;
39 import qt.gui.rgb;
40 import qt.gui.transform;
41 import qt.helpers;
42 
43 /+ #if QT_DEPRECATED_SINCE(5, 0)
44 #endif
45 
46 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
47 Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(CGImage);
48 #endif
49 
50 
51 
52 class QColorSpace;
53 class QColorTransform;
54 class QIODevice;
55 class QMatrix;
56 class QStringList;
57 class QTransform;
58 class QVariant;
59 template <class T> class QList;
60 template <class T> class QVector; +/
61 
62 struct QImageData;
63 extern(C++, class) struct QImageDataMisc; // internal
64 /+ #if QT_DEPRECATED_SINCE(5, 0)
65 class QImageTextKeyLang {
66 public:
67     QT_DEPRECATED QImageTextKeyLang(const char* k, const char* l) : key(k), lang(l) { }
68     QT_DEPRECATED QImageTextKeyLang() { }
69 
70     QByteArray key;
71     QByteArray lang;
72 
73     bool operator< (const QImageTextKeyLang& other) const
74         { return key < other.key || (key==other.key && lang < other.lang); }
75     bool operator== (const QImageTextKeyLang& other) const
76         { return key==other.key && lang==other.lang; }
77     inline bool operator!= (const QImageTextKeyLang &other) const
78         { return !operator==(other); }
79 private:
80     friend class QImage;
81     QImageTextKeyLang(bool /*dummy*/) {}
82 };
83 #endif +/
84 
85 alias QImageCleanupFunction = ExternCPPFunc!(void function(void*));
86 
87 @(QMetaType.Type.QImage) @Q_MOVABLE_TYPE extern(C++, class) struct /+ Q_GUI_EXPORT +/ QImage
88 {
89 private:
90     immutable void *vtbl;
91     QPaintDeviceFakeInheritance baseQPaintDeviceInterface;
92 
93     public QPaintDevice paintDevice() return
94     {
95         return cast(QPaintDevice)&this;
96     }
97 
98     alias PaintDeviceMetric = QPaintDevice.PaintDeviceMetric;
99 
100     mixin(Q_GADGET);
101 public:
102     enum InvertMode { InvertRgb, InvertRgba }
103     enum Format {
104         Format_Invalid,
105         Format_Mono,
106         Format_MonoLSB,
107         Format_Indexed8,
108         Format_RGB32,
109         Format_ARGB32,
110         Format_ARGB32_Premultiplied,
111         Format_RGB16,
112         Format_ARGB8565_Premultiplied,
113         Format_RGB666,
114         Format_ARGB6666_Premultiplied,
115         Format_RGB555,
116         Format_ARGB8555_Premultiplied,
117         Format_RGB888,
118         Format_RGB444,
119         Format_ARGB4444_Premultiplied,
120         Format_RGBX8888,
121         Format_RGBA8888,
122         Format_RGBA8888_Premultiplied,
123         Format_BGR30,
124         Format_A2BGR30_Premultiplied,
125         Format_RGB30,
126         Format_A2RGB30_Premultiplied,
127         Format_Alpha8,
128         Format_Grayscale8,
129         Format_RGBX64,
130         Format_RGBA64,
131         Format_RGBA64_Premultiplied,
132         Format_Grayscale16,
133         Format_BGR888,
134 /+ #ifndef Q_QDOC +/
135         NImageFormats
136 /+ #endif +/
137     }
138     /+ Q_ENUM(Format) +/
139 
140     @disable this();
141     pragma(mangle, defaultConstructorMangling(__traits(identifier, typeof(this))))
142     ref typeof(this) rawConstructor()/+ noexcept+/;
143     static typeof(this) create()
144     {
145         typeof(this) r = typeof(this).init;
146         r.rawConstructor();
147         return r;
148     }
149 
150     this(ref const(QSize) size, Format format);
151     this(int width, int height, Format format);
152     this(uchar* data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = null, void* cleanupInfo = null);
153     this(const(uchar)* data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = null, void* cleanupInfo = null);
154     this(uchar* data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = null, void* cleanupInfo = null);
155     this(const(uchar)* data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = null, void* cleanupInfo = null);
156 
157     version(QT_NO_IMAGEFORMAT_XPM){}else
158     {
159         /+ explicit +/this(const(char)* /+ const +/ /+[0]+/* xpm);
160     }
161     /+ explicit +/this(ref const(QString) fileName, const(char)* format = null);
162 
163     @disable this(this);
164     this(ref const(QImage) );
165     /+ inline QImage(QImage &&other) noexcept
166         : QPaintDevice(), d(nullptr)
167     { qSwap(d, other.d); } +/
168     mixin(mangleWindows("??1QImage@@UEAA@XZ", q{
169     ~this();
170     }));
171 
172     /+ref QImage operator =(ref const(QImage) );+/
173     /+ inline QImage &operator=(QImage &&other) noexcept
174     { qSwap(d, other.d); return *this; } +/
175     /+ inline void swap(QImage &other) noexcept
176     { qSwap(d, other.d); } +/
177 
178     bool isNull() const;
179 
180     int devType() const;
181 
182     /+bool operator ==(ref const(QImage) ) const;+/
183     /+bool operator !=(ref const(QImage) ) const;+/
184     /+auto opCast(T : QVariant)() const;+/
185     void detach();
186     bool isDetached() const;
187 
188     /+ QImage copy(const QRect &rect = QRect()) const; +/
189     /+ inline QImage copy(int x, int y, int w, int h) const
190         { return copy(QRect(x, y, w, h)); } +/
191 
192     Format format() const;
193 
194 /+    static if((!versionIsSet!("QT_COMPILING_QIMAGE_COMPAT_CPP") && defined!"Q_COMPILER_REF_QUALIFIERS"))
195     {
196         /+ Q_REQUIRED_RESULT +/ /+ Q_ALWAYS_INLINE +/ pragma(inline, true) QImage convertToFormat(Format f, /+ Qt:: +/qt.core.namespace.ImageConversionFlags flags = /+ Qt:: +/qt.core.namespace.ImageConversionFlag.AutoColor) const/+ &+/
197         { return convertToFormat_helper(f, flags); }
198         /+ Q_REQUIRED_RESULT +/ /+ Q_ALWAYS_INLINE +/ pragma(inline, true) QImage convertToFormat(Format f, /+ Qt:: +/qt.core.namespace.ImageConversionFlags flags = /+ Qt:: +/qt.core.namespace.ImageConversionFlag.AutoColor)/+ &&+/
199         {
200             if (convertToFormat_inplace(f, flags))
201                 return cast(QImage)(/+ std:: +/move(this));
202             else
203                 return convertToFormat_helper(f, flags);
204         }
205     }
206     else
207     {
208         /+ Q_REQUIRED_RESULT +/ QImage convertToFormat(Format f, /+ Qt:: +/qt.core.namespace.ImageConversionFlags flags = /+ Qt:: +/qt.core.namespace.ImageConversionFlag.AutoColor) const;
209     }
210 +/
211     /+ Q_REQUIRED_RESULT +/ QImage convertToFormat(Format f, ref const(QVector!(QRgb)) colorTable, /+ Qt:: +/qt.core.namespace.ImageConversionFlags flags = /+ Qt:: +/qt.core.namespace.ImageConversionFlag.AutoColor) const;
212     bool reinterpretAsFormat(Format f);
213 
214     void convertTo(Format f, /+ Qt:: +/qt.core.namespace.ImageConversionFlags flags = /+ Qt:: +/qt.core.namespace.ImageConversionFlag.AutoColor);
215 
216     int width() const;
217     int height() const;
218     QSize size() const;
219     QRect rect() const;
220 
221     int depth() const;
222     int colorCount() const;
223     int bitPlaneCount() const;
224 
225     QRgb color(int i) const;
226     void setColor(int i, QRgb c);
227     void setColorCount(int);
228 
229     bool allGray() const;
230     bool isGrayscale() const;
231 
232     uchar* bits();
233     const(uchar)* bits() const;
234     const(uchar)* constBits() const;
235 
236 /+ #if QT_DEPRECATED_SINCE(5, 10) +/
237     /+ QT_DEPRECATED_X("Use sizeInBytes") +/ int byteCount() const;
238 /+ #endif +/
239     qsizetype sizeInBytes() const;
240 
241     uchar* scanLine(int);
242     const(uchar)* scanLine(int) const;
243     const(uchar)* constScanLine(int) const;
244 /+ #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
245     qsizetype bytesPerLine() const;
246 #else +/
247     int bytesPerLine() const;
248 /+ #endif +/
249 
250     bool valid(int x, int y) const;
251     pragma(inline, true) bool valid(ref const(QPoint) pt) const { return valid(pt.x(), pt.y()); }
252 
253     int pixelIndex(int x, int y) const;
254     pragma(inline, true) int pixelIndex(ref const(QPoint) pt) const { return pixelIndex(pt.x(), pt.y());}
255 
256     QRgb pixel(int x, int y) const;
257     pragma(inline, true) QRgb pixel(ref const(QPoint) pt) const { return pixel(pt.x(), pt.y()); }
258 
259     void setPixel(int x, int y, uint index_or_rgb);
260     pragma(inline, true) void setPixel(ref const(QPoint) pt, uint index_or_rgb) { setPixel(pt.x(), pt.y(), index_or_rgb); }
261 
262     QColor pixelColor(int x, int y) const;
263     pragma(inline, true) QColor pixelColor(ref const(QPoint) pt) const { return pixelColor(pt.x(), pt.y()); }
264 
265     void setPixelColor(int x, int y, ref const(QColor) c);
266     pragma(inline, true) void setPixelColor(ref const(QPoint) pt, ref const(QColor) c) { setPixelColor(pt.x(), pt.y(), c); }
267 
268     QVector!(QRgb) colorTable() const;
269 /+ #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
270     void setColorTable(const QVector<QRgb> &colors);
271 #else +/
272     void setColorTable(const(QVector!(QRgb)) colors);
273 /+ #endif +/
274 
275     qreal devicePixelRatio() const;
276     void setDevicePixelRatio(qreal scaleFactor);
277 
278     void fill(uint pixel);
279     void fill(ref const(QColor) color);
280     void fill(/+ Qt:: +/qt.core.namespace.GlobalColor color);
281 
282 
283     bool hasAlphaChannel() const;
284     void setAlphaChannel(ref const(QImage) alphaChannel);
285 /+ #if QT_DEPRECATED_SINCE(5, 15) +/
286     /+ QT_DEPRECATED_X("Use convertToFormat(QImage::Format_Alpha8)") +/
287         QImage alphaChannel() const;
288 /+ #endif +/
289     QImage createAlphaMask(/+ Qt:: +/qt.core.namespace.ImageConversionFlags flags = /+ Qt:: +/qt.core.namespace.ImageConversionFlag.AutoColor) const;
290     version(QT_NO_IMAGE_HEURISTIC_MASK){}else
291     {
292         QImage createHeuristicMask(bool clipTight = true) const;
293     }
294     QImage createMaskFromColor(QRgb color, /+ Qt:: +/qt.core.namespace.MaskMode mode = /+ Qt:: +/qt.core.namespace.MaskMode.MaskInColor) const;
295 
296     pragma(inline, true) QImage scaled(int w, int h, /+ Qt:: +/qt.core.namespace.AspectRatioMode aspectMode = /+ Qt:: +/qt.core.namespace.AspectRatioMode.IgnoreAspectRatio,
297                             /+ Qt:: +/qt.core.namespace.TransformationMode mode = /+ Qt:: +/qt.core.namespace.TransformationMode.FastTransformation) const
298         { auto tmp = QSize(w, h); return scaled(tmp, aspectMode, mode); }
299     QImage scaled(ref const(QSize) s, /+ Qt:: +/qt.core.namespace.AspectRatioMode aspectMode = /+ Qt:: +/qt.core.namespace.AspectRatioMode.IgnoreAspectRatio,
300                      /+ Qt:: +/qt.core.namespace.TransformationMode mode = /+ Qt:: +/qt.core.namespace.TransformationMode.FastTransformation) const;
301     QImage scaledToWidth(int w, /+ Qt:: +/qt.core.namespace.TransformationMode mode = /+ Qt:: +/qt.core.namespace.TransformationMode.FastTransformation) const;
302     QImage scaledToHeight(int h, /+ Qt:: +/qt.core.namespace.TransformationMode mode = /+ Qt:: +/qt.core.namespace.TransformationMode.FastTransformation) const;
303 /+ #if QT_DEPRECATED_SINCE(5, 15) +/
304     /+ QT_DEPRECATED_X("Use transformed(const QTransform &matrix, Qt::TransformationMode mode)") +/
305         QImage transformed(ref const(QMatrix) matrix, /+ Qt:: +/qt.core.namespace.TransformationMode mode = /+ Qt:: +/qt.core.namespace.TransformationMode.FastTransformation) const;
306     /+ QT_DEPRECATED_X("trueMatrix(const QTransform &, int w, int h)") +/
307         static QMatrix trueMatrix(ref const(QMatrix) , int w, int h);
308 /+ #endif +/ // QT_DEPRECATED_SINCE(5, 15)
309     QImage transformed(ref const(QTransform) matrix, /+ Qt:: +/qt.core.namespace.TransformationMode mode = /+ Qt:: +/qt.core.namespace.TransformationMode.FastTransformation) const;
310     static QTransform trueMatrix(ref const(QTransform) , int w, int h);
311     static if((!versionIsSet!("QT_COMPILING_QIMAGE_COMPAT_CPP") && defined!"Q_COMPILER_REF_QUALIFIERS"))
312     {
313         QImage mirrored(bool horizontally = false, bool vertically = true) const/+ &+/
314             { return mirrored_helper(horizontally, vertically); }
315         /+ QImage &&mirrored(bool horizontally = false, bool vertically = true) &&
316             { mirrored_inplace(horizontally, vertically); return std::move(*this); } +/
317         QImage rgbSwapped() const/+ &+/
318             { return rgbSwapped_helper(); }
319         /+ QImage &&rgbSwapped() &&
320             { rgbSwapped_inplace(); return std::move(*this); } +/
321     }
322     else
323     {
324         QImage mirrored(bool horizontally = false, bool vertically = true) const;
325         QImage rgbSwapped() const;
326     }
327     void invertPixels(InvertMode /+ = InvertRgb +/);
328 
329     QColorSpace colorSpace() const;
330     QImage convertedToColorSpace(ref const(QColorSpace) ) const;
331     void convertToColorSpace(ref const(QColorSpace) );
332     void setColorSpace(ref const(QColorSpace) );
333 
334     void applyColorTransform(ref const(QColorTransform) transform);
335 
336     bool load(QIODevice device, const(char)* format);
337     bool load(ref const(QString) fileName, const(char)* format = null);
338     bool loadFromData(const(uchar)* buf, int len, const(char)* format = null);
339     pragma(inline, true) bool loadFromData(ref const(QByteArray) data, const(char)* aformat = null)
340         { return loadFromData(reinterpret_cast!(const(uchar)*)(data.constData()), data.size(), aformat); }
341 
342     bool save(ref const(QString) fileName, const(char)* format = null, int quality = -1) const;
343     bool save(QIODevice device, const(char)* format = null, int quality = -1) const;
344 
345     static QImage fromData(const(uchar)* data, int size, const(char)* format = null);
346     pragma(inline, true) static QImage fromData(ref const(QByteArray) data, const(char)* format = null)
347         { return fromData(reinterpret_cast!(const(uchar)*)(data.constData()), data.size(), format); }
348 
349 /+ #if QT_DEPRECATED_SINCE(5, 0)
350     QT_DEPRECATED inline int serialNumber() const { return cacheKey() >> 32; }
351 #endif +/
352     qint64 cacheKey() const;
353 
354     QPaintEngine paintEngine() const;
355 
356     // Auxiliary data
357     int dotsPerMeterX() const;
358     int dotsPerMeterY() const;
359     void setDotsPerMeterX(int);
360     void setDotsPerMeterY(int);
361     QPoint offset() const;
362     void setOffset(ref const(QPoint));
363 
364     QStringList textKeys() const;
365     QString text(ref const(QString) key = globalInitVar!QString) const;
366     void setText(ref const(QString) key, ref const(QString) value);
367 
368     QPixelFormat pixelFormat() const/+ noexcept+/;
369     static QPixelFormat toPixelFormat(QImage.Format format)/+ noexcept+/;
370     static QImage.Format toImageFormat(QPixelFormat format)/+ noexcept+/;
371 
372     // Platform specific conversion functions
373 /+ #if defined(Q_OS_DARWIN) || defined(Q_QDOC) +/
374     static if((versionIsSet!("OSX") || versionIsSet!("iOS") || versionIsSet!("TVOS") || versionIsSet!("WatchOS")))
375     {
376         /+ CGImageRef toCGImage() const Q_DECL_CF_RETURNS_RETAINED; +/
377     }
378 /+ #endif
379 
380 #if QT_DEPRECATED_SINCE(5, 0)
381     QT_DEPRECATED inline QString text(const char *key, const char *lang = nullptr) const;
382     QT_DEPRECATED inline QList<QImageTextKeyLang> textList() const;
383     QT_DEPRECATED inline QStringList textLanguages() const;
384     QT_DEPRECATED inline QString text(const QImageTextKeyLang&) const;
385     QT_DEPRECATED inline void setText(const char* key, const char* lang, const QString&);
386 #endif
387 
388 #if QT_DEPRECATED_SINCE(5, 0)
389     QT_DEPRECATED inline int numColors() const;
390     QT_DEPRECATED inline void setNumColors(int);
391     QT_DEPRECATED inline int numBytes() const;
392 #endif +/
393 
394 protected:
395     /+ virtual +/ int metric(PaintDeviceMetric metric) const;
396     QImage mirrored_helper(bool horizontal, bool vertical) const;
397     QImage rgbSwapped_helper() const;
398     void mirrored_inplace(bool horizontal, bool vertical);
399     void rgbSwapped_inplace();
400     QImage convertToFormat_helper(Format format, /+ Qt:: +/qt.core.namespace.ImageConversionFlags flags) const;
401     bool convertToFormat_inplace(Format format, /+ Qt:: +/qt.core.namespace.ImageConversionFlags flags);
402     QImage smoothScaled(int w, int h) const;
403 
404 private:
405     /+ friend class QWSOnScreenSurface; +/
406     QImageData* d;
407 
408     /+ friend class QRasterPlatformPixmap; +/
409     /+ friend class QBlittablePlatformPixmap; +/
410     /+ friend class QPixmapCacheEntry; +/
411     /+ friend struct QImageData; +/
412 
413 public:
414     alias DataPtr = QImageData*;
415     pragma(inline, true) ref DataPtr data_ptr() return { return d; }
416 }
417 
418 /+ Q_DECLARE_SHARED(QImage)
419 
420 // Inline functions...
421 
422 #if QT_DEPRECATED_SINCE(5, 0)
423 
424 QT_WARNING_PUSH
425 QT_WARNING_DISABLE_DEPRECATED
426 
427 inline QString QImage::text(const char* key, const char* lang) const
428 {
429     if (!d)
430         return QString();
431     QString k = QString::fromLatin1(key);
432     if (lang && *lang)
433         k += QLatin1Char('/') + QString::fromLatin1(lang);
434     return text(k);
435 }
436 
437 inline QList<QImageTextKeyLang> QImage::textList() const
438 {
439     QList<QImageTextKeyLang> imageTextKeys;
440     if (!d)
441         return imageTextKeys;
442     QStringList keys = textKeys();
443     for (int i = 0; i < keys.size(); ++i) {
444         int index = keys.at(i).indexOf(QLatin1Char('/'));
445         if (index > 0) {
446             QImageTextKeyLang tkl(true);
447             tkl.key = keys.at(i).left(index).toLatin1();
448             tkl.lang = keys.at(i).mid(index+1).toLatin1();
449             imageTextKeys += tkl;
450         }
451     }
452 
453     return imageTextKeys;
454 }
455 
456 inline QStringList QImage::textLanguages() const
457 {
458     if (!d)
459         return QStringList();
460     QStringList keys = textKeys();
461     QStringList languages;
462     for (int i = 0; i < keys.size(); ++i) {
463         int index = keys.at(i).indexOf(QLatin1Char('/'));
464         if (index > 0)
465             languages += keys.at(i).mid(index+1);
466     }
467 
468     return languages;
469 }
470 
471 inline QString QImage::text(const QImageTextKeyLang&kl) const
472 {
473     if (!d)
474         return QString();
475     QString k = QString::fromLatin1(kl.key.constData());
476     if (!kl.lang.isEmpty())
477         k += QLatin1Char('/') + QString::fromLatin1(kl.lang.constData());
478     return text(k);
479 }
480 
481 inline void QImage::setText(const char* key, const char* lang, const QString &s)
482 {
483     if (!d)
484         return;
485     detach();
486 
487     // In case detach() ran out of memory
488     if (!d)
489         return;
490 
491     QString k = QString::fromLatin1(key);
492     if (lang && *lang)
493         k += QLatin1Char('/') + QString::fromLatin1(lang);
494     setText(k, s);
495 }
496 
497 QT_WARNING_POP
498 
499 inline int QImage::numColors() const
500 {
501     return colorCount();
502 }
503 
504 inline void QImage::setNumColors(int n)
505 {
506     setColorCount(n);
507 }
508 
509 inline int QImage::numBytes() const
510 {
511     return int(sizeInBytes());
512 }
513 #endif
514 
515 // QImage stream functions
516 
517 #if !defined(QT_NO_DATASTREAM)
518 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QImage &);
519 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QImage &);
520 #endif
521 
522 #ifndef QT_NO_DEBUG_STREAM
523 Q_GUI_EXPORT QDebug operator<<(QDebug, const QImage &);
524 #endif +/
525