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
qpixmap_win.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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// Qt-Security score:critical reason:data-parser
4
5#include "qbitmap.h"
6#include "qpixmap.h"
7#include <private/qpixmap_win_p.h>
8#include <qpa/qplatformpixmap.h>
10
11#include <qdebug.h>
12#include <QScopedArrayPointer>
13#include <qt_windows.h>
14
15#include <algorithm>
16#include <iterator>
17
18QT_BEGIN_NAMESPACE
19
20template <typename Int>
21static inline Int pad4(Int v)
22{
23 return (v + Int(3)) & ~Int(3);
24}
25
26#ifndef QT_NO_DEBUG_STREAM
27QDebug operator<<(QDebug d, const BITMAPINFOHEADER &bih)
28{
29 QDebugStateSaver saver(d);
30 d.nospace();
31 d << "BITMAPINFOHEADER(" << bih.biWidth << 'x' << qAbs(bih.biHeight)
32 << (bih.biHeight < 0 ? ", top-down" : ", bottom-up")
33 << ", planes=" << bih.biPlanes << ", bitCount=" << bih.biBitCount
34 << ", compression=" << bih.biCompression << ", size="
35 << bih.biSizeImage << ')';
36 return d;
37}
38#endif // !QT_NO_DEBUG_STREAM
39
40static inline void initBitMapInfoHeader(int width, int height, bool topToBottom,
41 DWORD compression, DWORD bitCount,
42 BITMAPINFOHEADER *bih)
43{
44 memset(bih, 0, sizeof(BITMAPINFOHEADER));
45 bih->biSize = sizeof(BITMAPINFOHEADER);
46 bih->biWidth = width;
47 bih->biHeight = topToBottom ? -height : height;
48 bih->biPlanes = 1;
49 bih->biBitCount = WORD(bitCount);
50 bih->biCompression = compression;
51 // scan lines are word-aligned (unless RLE)
52 const DWORD bytesPerLine = bitCount == 1 ? pad4(DWORD(qCeil(width / 8.0)))
53 : pad4(DWORD(width) * bitCount / 8);
54 bih->biSizeImage = bytesPerLine * DWORD(height);
55}
56
58
59struct BITMAPINFO_COLORTABLE256 { // BITMAPINFO with 256 entry color table for Indexed 8 format
62};
63
64template <class BITMAPINFO_T> // BITMAPINFO, BITMAPINFO_COLORTABLE256
65static inline void initBitMapInfo(int width, int height, bool topToBottom,
66 DWORD compression, DWORD bitCount,
67 BITMAPINFO_T *bmi)
68{
69 initBitMapInfoHeader(width, height, topToBottom, compression, bitCount, &bmi->bmiHeader);
70 memset(bmi->bmiColors, 0, sizeof(bmi->bmiColors));
71}
72
73static inline uchar *getDiBits(HDC hdc, HBITMAP bitmap, int width, int height, bool topToBottom = true)
74{
75 BITMAPINFO bmi;
76 initBitMapInfo(width, height, topToBottom, BI_RGB, 32u, &bmi);
77 uchar *result = new uchar[bmi.bmiHeader.biSizeImage];
78 if (!GetDIBits(hdc, bitmap, 0, UINT(height), result, &bmi, DIB_RGB_COLORS)) {
79 delete [] result;
80 qErrnoWarning("%s: GetDIBits() failed to get bitmap bits.", __FUNCTION__);
81 return nullptr;
82 }
83 return result;
84}
85
86static inline void copyImageDataCreateAlpha(const uchar *data, QImage *target)
87{
88 const uint mask = target->format() == QImage::Format_RGB32 ? 0xff000000 : 0;
89 const int height = target->height();
90 const int width = target->width();
91 const qsizetype bytesPerLine = width * sizeof(QRgb);
92 for (int y = 0; y < height; ++y) {
93 QRgb *dest = reinterpret_cast<QRgb *>(target->scanLine(y));
94 const QRgb *src = reinterpret_cast<const QRgb *>(data + y * bytesPerLine);
95 for (int x = 0; x < width; ++x) {
96 const uint pixel = src[x];
97 if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
98 dest[x] = pixel | 0xff000000;
99 else
100 dest[x] = pixel | mask;
101 }
102 }
103}
104
105// Flip RGB triplets from DIB to QImage formats. Scan lines are padded to 32bit
106// both in QImage and DIB.
107static inline void flipRgb3(uchar *p, int width, int height)
108{
109 const int lineSize = 3 * width;
110 const int linePad = pad4(lineSize) - lineSize;
111 for (int y = 0; y < height; ++y) {
112 uchar *end = p + lineSize;
113 for ( ; p < end; p += 3)
114 std::swap(*p, *(p + 2));
115 p += linePad;
116 }
117}
118
119static inline RGBQUAD qRgbToRgbQuad(QRgb qrgb)
120{
121 RGBQUAD result = {BYTE(qBlue(qrgb)), BYTE(qGreen(qrgb)), BYTE(qRed(qrgb)), 0};
122 return result;
123}
124
125static inline QRgb rgbQuadToQRgb(RGBQUAD quad)
126{
127 return QRgb(quad.rgbBlue) + (QRgb(quad.rgbGreen) << 8) + (QRgb(quad.rgbRed) << 16)
128 + 0xff000000;
129}
130
131// Helper for imageFromWinHBITMAP_*(), create image in desired format
132static QImage copyImageData(const BITMAPINFOHEADER &header, const RGBQUAD *colorTableIn,
133 const void *data, QImage::Format format)
134{
135 const QSize size = QSize(header.biWidth, qAbs(header.biHeight));
136 QImage image(size, format);
137
138 int colorTableSize = 0;
139 switch (format) {
140 case QImage::Format_Mono:
141 colorTableSize = 2;
142 break;
143 case QImage::Format_Indexed8:
144 colorTableSize = Indexed8ColorTableSize;
145 break;
146 default:
147 break;
148 }
149 if (colorTableSize) {
150 Q_ASSERT(colorTableIn);
151 QList<QRgb> colorTable;
152 colorTable.reserve(colorTableSize);
153 std::transform(colorTableIn, colorTableIn + colorTableSize,
154 std::back_inserter(colorTable), rgbQuadToQRgb);
155 image.setColorTable(colorTable);
156 }
157
158 switch (header.biBitCount) {
159 case 32:
160 copyImageDataCreateAlpha(static_cast<const uchar *>(data), &image);
161 break;
162 case 1:
163 case 8:
164 case 16:
165 case 24:
166 Q_ASSERT(DWORD(image.sizeInBytes()) == header.biSizeImage);
167 memcpy(image.bits(), data, header.biSizeImage);
168 if (format == QImage::Format_RGB888)
169 image = std::move(image).rgbSwapped();
170 break;
171 default:
172 Q_UNREACHABLE();
173 break;
174 }
175 return image;
176}
177
179{
181public:
182 DisplayHdc() : m_displayDc(GetDC(nullptr)) {}
184
185 operator HDC() const { return m_displayDc; }
186
187private:
188 const HDC m_displayDc;
189};
190
197
198static HBITMAP qt_createIconMask(QImage bm)
199{
200 Q_ASSERT(bm.format() == QImage::Format_Mono);
201 const int w = bm.width();
202 const int h = bm.height();
203 const int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment
204 QScopedArrayPointer<uchar> bits(new uchar[size_t(bpl * h)]);
205 bm.invertPixels();
206 for (int y = 0; y < h; ++y)
207 memcpy(bits.data() + y * bpl, bm.constScanLine(y), size_t(bpl));
208 HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits.data());
209 return hbm;
210}
211
212HBITMAP qt_createIconMask(const QBitmap &bitmap)
213{
214 return qt_createIconMask(bitmap.toImage().convertToFormat(QImage::Format_Mono));
215}
216
217static inline QImage::Format format32(int hbitmapFormat)
218{
219 switch (hbitmapFormat) {
220 case HBitmapNoAlpha:
221 return QImage::Format_RGB32;
222 case HBitmapAlpha:
223 return QImage::Format_ARGB32;
224 default:
225 break;
226 }
227 return QImage::Format_ARGB32_Premultiplied;
228}
229
230HBITMAP qt_imageToWinHBITMAP(const QImage &imageIn, int hbitmapFormat)
231{
232 if (imageIn.isNull())
233 return nullptr;
234
235 // Define the header
236 DWORD compression = 0;
237 DWORD bitCount = 0;
238
239 // Copy over the data
240 QImage image = imageIn;
241 switch (image.format()) {
242 case QImage::Format_Mono:
243 bitCount = 1u;
244 break;
245 case QImage::Format_RGB32:
246 case QImage::Format_ARGB32:
247 case QImage::Format_ARGB32_Premultiplied: {
248 compression = BI_RGB;
249 bitCount = 32u;
250 const QImage::Format targetFormat = format32(hbitmapFormat);
251 if (targetFormat != image.format())
252 image = image.convertToFormat(targetFormat);
253 }
254 break;
255 case QImage::Format_RGB888:
256 case QImage::Format_BGR888:
257 compression = BI_RGB;
258 bitCount = 24u;
259 break;
260 case QImage::Format_Indexed8:
261 bitCount = 8u;
262 break;
263 case QImage::Format_RGB555:
264 bitCount = 16u;
265 break;
266 default: {
267 QImage::Format fallbackFormat = QImage::Format_ARGB32_Premultiplied;
268 switch (image.format()) { // Convert to a suitable format.
269 case QImage::Format_MonoLSB:
270 fallbackFormat = QImage::Format_Mono;
271 break;
272 case QImage::Format_RGB16:
273 fallbackFormat = QImage::Format_RGB555;
274 break;
275 case QImage::Format_Grayscale8:
276 fallbackFormat = QImage::Format_Indexed8;
277 break;
278 default:
279 break;
280 } // switch conversion format
281 return qt_imageToWinHBITMAP(imageIn.convertToFormat(fallbackFormat), hbitmapFormat);
282 }
283 }
284
285 const int w = image.width();
286 const int h = image.height();
287
288 BITMAPINFO_COLORTABLE256 bmiColorTable256;
289 initBitMapInfo(w, h, true, compression, bitCount, &bmiColorTable256);
290 BITMAPINFO &bmi = reinterpret_cast<BITMAPINFO &>(bmiColorTable256);
291 switch (image.format()) {
292 case QImage::Format_Mono: // Color table with 2 entries
293 case QImage::Format_Indexed8:
294 std::transform(image.colorTable().constBegin(), image.colorTable().constEnd(),
295 bmiColorTable256.bmiColors, qRgbToRgbQuad);
296 break;
297 default:
298 break;
299 }
300
301 // Create the pixmap
302 uchar *pixels = nullptr;
303 const HBITMAP bitmap = CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS,
304 reinterpret_cast<void **>(&pixels), nullptr, 0);
305 if (!bitmap) {
306 qErrnoWarning("%s, failed to create dibsection", __FUNCTION__);
307 return nullptr;
308 }
309 if (!pixels) {
310 DeleteObject(bitmap);
311 qErrnoWarning("%s, did not allocate pixel data", __FUNCTION__);
312 return nullptr;
313 }
314 memcpy(pixels, image.constBits(), bmi.bmiHeader.biSizeImage);
315 if (image.format() == QImage::Format_RGB888)
316 flipRgb3(pixels, w, h);
317 return bitmap;
318}
319
320/*!
321 \since 6.0
322
323 \brief Creates a \c HBITMAP equivalent of the QImage.
324
325 Returns the \c HBITMAP handle.
326
327 It is the caller's responsibility to free the \c HBITMAP data
328 after use.
329
330 For usage with standard GDI calls, such as \c BitBlt(), the image
331 should have the format QImage::Format_RGB32.
332
333 When using the resulting HBITMAP for the \c AlphaBlend() GDI function,
334 the image should have the format QImage::Format_ARGB32_Premultiplied
335 (use convertToFormat()).
336
337 When using the resulting HBITMAP as application icon or a systray icon,
338 the image should have the format QImage::Format_ARGB32.
339
340 \ingroup platform-type-conversions
341
342 \sa fromHBITMAP(), convertToFormat()
343*/
344HBITMAP QImage::toHBITMAP() const
345{
346 switch (format()) {
347 case QImage::Format_ARGB32:
348 return qt_imageToWinHBITMAP(*this, HBitmapAlpha);
349 case QImage::Format_ARGB32_Premultiplied:
350 return qt_imageToWinHBITMAP(*this, HBitmapPremultipliedAlpha);
351 default:
352 break;
353 }
354 return qt_imageToWinHBITMAP(*this);
355}
356
357HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat)
358{
359 if (p.isNull())
360 return nullptr;
361
362 QPlatformPixmap *platformPixmap = p.handle();
363 if (platformPixmap->classId() != QPlatformPixmap::RasterClass) {
364 QRasterPlatformPixmap *data = new QRasterPlatformPixmap(p.depth() == 1 ?
365 QRasterPlatformPixmap::BitmapType : QRasterPlatformPixmap::PixmapType);
366 data->fromImage(p.toImage(), Qt::AutoColor);
367 return qt_pixmapToWinHBITMAP(QPixmap(data), hbitmapFormat);
368 }
369
370 return qt_imageToWinHBITMAP(*static_cast<QRasterPlatformPixmap*>(platformPixmap)->buffer(), hbitmapFormat);
371}
372
373static QImage::Format imageFromWinHBITMAP_Format(const BITMAPINFOHEADER &header, int hbitmapFormat)
374{
375 QImage::Format result = QImage::Format_Invalid;
376 switch (header.biBitCount) {
377 case 32:
378 result = hbitmapFormat == HBitmapNoAlpha
379 ? QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied;
380 break;
381 case 24:
382 result = QImage::Format_BGR888;
383 break;
384 case 16:
385 result = QImage::Format_RGB555;
386 break;
387 case 8:
388 result = QImage::Format_Indexed8;
389 break;
390 case 1:
391 result = QImage::Format_Mono;
392 break;
393 }
394 return result;
395}
396
397// Fast path for creating a QImage directly from a HBITMAP created by CreateDIBSection(),
398// not requiring memory allocation.
399static QImage imageFromWinHBITMAP_DibSection(HBITMAP bitmap, int hbitmapFormat)
400{
401 DIBSECTION dibSection;
402 memset(&dibSection, 0, sizeof(dibSection));
403 dibSection.dsBmih.biSize = sizeof(dibSection.dsBmih);
404
405 if (!GetObject(bitmap, sizeof(dibSection), &dibSection)
406 || !dibSection.dsBm.bmBits
407 || dibSection.dsBmih.biBitCount <= 8 // Cannot access the color table for Indexed8, Mono
408 || dibSection.dsBmih.biCompression != BI_RGB) {
409 return QImage();
410 }
411
412 const QImage::Format imageFormat = imageFromWinHBITMAP_Format(dibSection.dsBmih, hbitmapFormat);
413 if (imageFormat == QImage::Format_Invalid)
414 return QImage();
415
416 return copyImageData(dibSection.dsBmih, nullptr, dibSection.dsBm.bmBits, imageFormat);
417}
418
419// Create QImage from a HBITMAP using GetDIBits(), potentially with conversion.
420static QImage imageFromWinHBITMAP_GetDiBits(HBITMAP bitmap, bool forceQuads, int hbitmapFormat)
421{
422 BITMAPINFO_COLORTABLE256 bmiColorTable256;
423 BITMAPINFO &info = reinterpret_cast<BITMAPINFO &>(bmiColorTable256);
424 memset(&info, 0, sizeof(info));
425 info.bmiHeader.biSize = sizeof(info.bmiHeader);
426
427 DisplayHdc displayDc;
428 if (!GetDIBits(displayDc, bitmap, 0, 1, 0, &info, DIB_RGB_COLORS)) {
429 qErrnoWarning("%s: GetDIBits() failed to query data.", __FUNCTION__);
430 return QImage();
431 }
432
433 if (info.bmiHeader.biHeight > 0) // Force top-down
434 info.bmiHeader.biHeight = -info.bmiHeader.biHeight;
435 info.bmiHeader.biCompression = BI_RGB; // Extract using no compression (can be BI_BITFIELD)
436 size_t allocSize = info.bmiHeader.biSizeImage;
437 if (forceQuads) {
438 info.bmiHeader.biBitCount = 32;
439 allocSize = info.bmiHeader.biWidth * qAbs(info.bmiHeader.biHeight) * 4;
440 }
441
442 const QImage::Format imageFormat = imageFromWinHBITMAP_Format(info.bmiHeader, hbitmapFormat);
443 if (imageFormat == QImage::Format_Invalid) {
444 qWarning().nospace() << __FUNCTION__ << ": unsupported image format:" << info.bmiHeader;
445 return QImage();
446 }
447
448 QScopedArrayPointer<uchar> data(new uchar[allocSize]);
449 if (!GetDIBits(displayDc, bitmap, 0, qAbs(info.bmiHeader.biHeight), data.data(), &info, DIB_RGB_COLORS)) {
450 qErrnoWarning("%s: GetDIBits() failed to get data.", __FUNCTION__);
451 return QImage();
452 }
453 return copyImageData(info.bmiHeader, bmiColorTable256.bmiColors, data.data(), imageFormat);
454}
455
456QImage qt_imageFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat)
457{
458 QImage result = imageFromWinHBITMAP_DibSection(bitmap, hbitmapFormat);
459 if (result.isNull())
460 result = imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ false, hbitmapFormat);
461 return result;
462}
463
464/*!
465 \since 6.0
466
467 \brief Returns a QImage that is equivalent to the given \a hbitmap.
468
469 HBITMAP does not store information about the alpha channel.
470
471 In the standard case, the alpha channel is ignored and a fully
472 opaque image is created (typically of format QImage::Format_RGB32).
473
474 There are cases where the alpha channel is used, though, for example
475 for application icon or systray icons. In that case,
476 \c reinterpretAsFormat(QImage::Format_ARGB32) should be called
477 on the returned image to ensure the format is correct.
478
479 \ingroup platform-type-conversions
480
481 \sa toHBITMAP(), reinterpretAsFormat()
482*/
483QImage QImage::fromHBITMAP(HBITMAP hbitmap)
484{
485 return qt_imageFromWinHBITMAP(hbitmap);
486}
487
488QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat)
489{
490 return QPixmap::fromImage(imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ true, hbitmapFormat));
491}
492
493/*!
494 \since 6.0
495
496 \brief Creates a \c HICON equivalent of the QPixmap, applying the mask
497 \a mask.
498
499 If \a mask is not null, it needs to be of format QImage::Format_Mono.
500 Returns the \c HICON handle.
501
502 It is the caller's responsibility to free the \c HICON data after use.
503
504 \ingroup platform-type-conversions
505
506 \sa fromHICON()
507*/
508HICON QImage::toHICON(const QImage &mask) const
509{
510 if (!mask.isNull() && mask.format() != QImage::Format_Mono) {
511 qWarning("QImage::toHICON(): Mask must be empty or have format Format_Mono");
512 return nullptr;
513 }
514
515 if (isNull())
516 return nullptr;
517
518 auto effectiveMask = mask;
519 if (effectiveMask.isNull()) {
520 effectiveMask = QImage(size(), QImage::Format_Mono);
521 effectiveMask.fill(Qt::color1);
522 }
523
524 ICONINFO ii;
525 ii.fIcon = true;
526 ii.hbmMask = qt_createIconMask(effectiveMask);
527 ii.hbmColor = qt_imageToWinHBITMAP(*this, HBitmapAlpha);
528 ii.xHotspot = 0;
529 ii.yHotspot = 0;
530
531 HICON hIcon = CreateIconIndirect(&ii);
532
533 DeleteObject(ii.hbmColor);
534 DeleteObject(ii.hbmMask);
535
536 return hIcon;
537}
538
539HICON qt_pixmapToWinHICON(const QPixmap &p)
540{
541 QImage mask;
542 QBitmap maskBitmap = p.mask();
543 if (!maskBitmap.isNull())
544 mask = maskBitmap.toImage().convertToFormat(QImage::Format_Mono);
545 return p.toImage().toHICON(mask);
546}
547
548QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
549{
550 QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
551 if (image.isNull())
552 return image;
553 QScopedArrayPointer<uchar> data(getDiBits(hdc, bitmap, w, h, true));
554 if (data.isNull())
555 return QImage();
556 copyImageDataCreateAlpha(data.data(), &image);
557 return image;
558}
559
560static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
561{
562 QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
563 if (image.isNull())
564 return image;
565 QScopedArrayPointer<uchar> data(getDiBits(hdc, bitmap, w, h, true));
566 if (data.isNull())
567 return QImage();
568 memcpy(image.bits(), data.data(), size_t(image.sizeInBytes()));
569 return image;
570}
571
572static inline bool hasAlpha(const QImage &image)
573{
574 const int w = image.width();
575 const int h = image.height();
576 for (int y = 0; y < h; ++y) {
577 const QRgb *scanLine = reinterpret_cast<const QRgb *>(image.scanLine(y));
578 for (int x = 0; x < w; ++x) {
579 if (qAlpha(scanLine[x]) != 0)
580 return true;
581 }
582 }
583 return false;
584}
585
586/*!
587 \since 6.0
588
589 \brief Returns a QImage that is equivalent to the given \a icon.
590
591 \ingroup platform-type-conversions
592
593 \sa toHICON()
594*/
595QImage QImage::fromHICON(HICON icon)
596{
597 HDC screenDevice = GetDC(nullptr);
598 HDC hdc = CreateCompatibleDC(screenDevice);
599 ReleaseDC(nullptr, screenDevice);
600
601 ICONINFO iconinfo;
602 const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
603 if (!result) {
604 qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
605 DeleteDC(hdc);
606 return {};
607 }
608
609 const int w = int(iconinfo.xHotspot) * 2;
610 const int h = int(iconinfo.yHotspot) * 2;
611
612 BITMAPINFOHEADER bitmapInfo;
613 initBitMapInfoHeader(w, h, false, BI_RGB, 32u, &bitmapInfo);
614 DWORD* bits;
615
616 HBITMAP winBitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bitmapInfo),
617 DIB_RGB_COLORS, reinterpret_cast<VOID **>(&bits),
618 nullptr, 0);
619 HGDIOBJ oldhdc = static_cast<HBITMAP>(SelectObject(hdc, winBitmap));
620 DrawIconEx(hdc, 0, 0, icon, w, h, 0, nullptr, DI_NORMAL);
621 QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
622
623 if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values
624 DrawIconEx( hdc, 0, 0, icon, w, h, 0, nullptr, DI_MASK);
625 const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
626
627 for (int y = 0 ; y < h ; y++){
628 QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y));
629 const QRgb *scanlineMask = mask.isNull() ? nullptr : reinterpret_cast<const QRgb *>(mask.scanLine(y));
630 for (int x = 0; x < w ; x++){
631 if (scanlineMask && qRed(scanlineMask[x]) != 0)
632 scanlineImage[x] = 0; //mask out this pixel
633 else
634 scanlineImage[x] |= 0xff000000; // set the alpha channel to 255
635 }
636 }
637 }
638 //dispose resources created by iconinfo call
639 DeleteObject(iconinfo.hbmMask);
640 DeleteObject(iconinfo.hbmColor);
641
642 SelectObject(hdc, oldhdc); //restore state
643 DeleteObject(winBitmap);
644 DeleteDC(hdc);
645 return image;
646}
647
649{
650 return QPixmap::fromImage(QImage::fromHICON(icon));
651}
652
653QT_END_NAMESPACE
\inmodule QtGui
Definition qbitmap.h:16
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
HBITMAP qt_imageToWinHBITMAP(const QImage &imageIn, int hbitmapFormat)
static void flipRgb3(uchar *p, int width, int height)
static bool hasAlpha(const QImage &image)
@ Indexed8ColorTableSize
static QImage imageFromWinHBITMAP_GetDiBits(HBITMAP bitmap, bool forceQuads, int hbitmapFormat)
static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
static void initBitMapInfoHeader(int width, int height, bool topToBottom, DWORD compression, DWORD bitCount, BITMAPINFOHEADER *bih)
QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat)
static HBITMAP qt_createIconMask(QImage bm)
static RGBQUAD qRgbToRgbQuad(QRgb qrgb)
static QImage::Format format32(int hbitmapFormat)
HBitmapFormat
@ HBitmapPremultipliedAlpha
@ HBitmapNoAlpha
@ HBitmapAlpha
static QImage copyImageData(const BITMAPINFOHEADER &header, const RGBQUAD *colorTableIn, const void *data, QImage::Format format)
static QImage::Format imageFromWinHBITMAP_Format(const BITMAPINFOHEADER &header, int hbitmapFormat)
QImage qt_imageFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat)
QPixmap qt_pixmapFromWinHICON(HICON icon)
HBITMAP qt_createIconMask(const QBitmap &bitmap)
static QImage imageFromWinHBITMAP_DibSection(HBITMAP bitmap, int hbitmapFormat)
HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat)
HICON qt_pixmapToWinHICON(const QPixmap &p)
static uchar * getDiBits(HDC hdc, HBITMAP bitmap, int width, int height, bool topToBottom=true)
static void copyImageDataCreateAlpha(const uchar *data, QImage *target)
static QRgb rgbQuadToQRgb(RGBQUAD quad)
static void initBitMapInfo(int width, int height, bool topToBottom, DWORD compression, DWORD bitCount, BITMAPINFO_T *bmi)
QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
BITMAPINFOHEADER bmiHeader
RGBQUAD bmiColors[Indexed8ColorTableSize]