Changeset 846 for trunk/src/gui/image
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 66 edited
- 16 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/image/image.pri
r561 r846 29 29 image/qpixmapdatafactory_p.h \ 30 30 image/qpixmapfilter_p.h \ 31 image/qimagepixmapcleanuphooks_p.h \ 32 31 image/qimagepixmapcleanuphooks_p.h 33 32 34 33 SOURCES += \ … … 53 52 image/qpixmap_raster.cpp \ 54 53 image/qnativeimage.cpp \ 55 image/qimagepixmapcleanuphooks.cpp \ 56 54 image/qimagepixmapcleanuphooks.cpp 57 55 58 56 win32 { 59 57 SOURCES += image/qpixmap_win.cpp 60 58 } 61 os2 {59 else:os2 { 62 60 SOURCES += image/qpixmap_pm.cpp 63 61 } 64 e mbedded {62 else:embedded { 65 63 SOURCES += image/qpixmap_qws.cpp 66 64 } 67 x11 {65 else:x11 { 68 66 HEADERS += image/qpixmap_x11_p.h 69 SOURCES += image/qpixmap_x11.cpp 67 SOURCES += image/qpixmap_x11.cpp 70 68 } 71 mac {69 else:mac { 72 70 HEADERS += image/qpixmap_mac_p.h 73 71 SOURCES += image/qpixmap_mac.cpp 74 72 } 75 symbian {73 else:symbian { 76 74 HEADERS += image/qpixmap_s60_p.h 77 75 SOURCES += image/qpixmap_s60.cpp … … 91 89 image/qxpmhandler.cpp 92 90 93 # 3rd party / system PNG support 94 !contains(QT_CONFIG, no-png) { 95 HEADERS += image/qpnghandler_p.h 96 SOURCES += image/qpnghandler.cpp 91 !contains(QT_CONFIG, no-png):include($$PWD/qpnghandler.pri) 92 else:DEFINES *= QT_NO_IMAGEFORMAT_PNG 97 93 98 contains(QT_CONFIG, system-png) { 99 unix:LIBS_PRIVATE += -lpng 100 win32:LIBS += libpng.lib 101 } else { 102 !isEqual(QT_ARCH, i386):!isEqual(QT_ARCH, x86_64):DEFINES += PNG_NO_ASSEMBLER_CODE 103 INCLUDEPATH += ../3rdparty/libpng ../3rdparty/zlib 104 SOURCES += ../3rdparty/libpng/png.c \ 105 ../3rdparty/libpng/pngerror.c \ 106 ../3rdparty/libpng/pngget.c \ 107 ../3rdparty/libpng/pngmem.c \ 108 ../3rdparty/libpng/pngpread.c \ 109 ../3rdparty/libpng/pngread.c \ 110 ../3rdparty/libpng/pngrio.c \ 111 ../3rdparty/libpng/pngrtran.c \ 112 ../3rdparty/libpng/pngrutil.c \ 113 ../3rdparty/libpng/pngset.c \ 114 ../3rdparty/libpng/pngtrans.c \ 115 ../3rdparty/libpng/pngwio.c \ 116 ../3rdparty/libpng/pngwrite.c \ 117 ../3rdparty/libpng/pngwtran.c \ 118 ../3rdparty/libpng/pngwutil.c \ 119 ../3rdparty/libpng/pnggccrd.c 120 } 121 } else { 122 DEFINES *= QT_NO_IMAGEFORMAT_PNG 123 } 94 contains(QT_CONFIG, jpeg):include($$PWD/qjpeghandler.pri) 95 contains(QT_CONFIG, mng):include($$PWD/qmnghandler.pri) 96 contains(QT_CONFIG, tiff):include($$PWD/qtiffhandler.pri) 97 contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri) 98 99 # SIMD 100 NEON_SOURCES += image/qimage_neon.cpp 101 SSE2_SOURCES += image/qimage_sse2.cpp 102 SSSE3_SOURCES += image/qimage_ssse3.cpp -
trunk/src/gui/image/qbitmap.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qbitmap.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qbmphandler.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 247 247 if (depth != 32) { 248 248 ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; 249 if (ncols > 256) // sanity check - don't run out of mem if color table is broken 250 return false; 249 251 image.setColorCount(ncols); 250 252 } … … 675 677 bool QBmpHandler::canRead() const 676 678 { 677 if (state == Ready) { 678 if (!canRead(device())) 679 return false; 679 if (state == Ready && !canRead(device())) 680 return false; 681 682 if (state != Error) { 680 683 setFormat("bmp"); 681 684 return true; 682 685 } 683 return state != Error; 686 687 return false; 684 688 } 685 689 -
trunk/src/gui/image/qbmphandler_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qicon.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 67 67 #endif 68 68 69 #include "private/qstylehelper_p.h" 70 69 71 #ifndef QT_NO_ICON 70 72 QT_BEGIN_NAMESPACE … … 262 264 actualSize.scale(size, Qt::KeepAspectRatio); 263 265 264 QString key = QLatin1String("$qt_icon_") 265 + QString::number(pm.cacheKey()) 266 + QString::number(pe->mode) 267 + QString::number(QApplication::palette().cacheKey()) 268 + QLatin1Char('_') 269 + QString::number(actualSize.width()) 270 + QLatin1Char('_') 271 + QString::number(actualSize.height()) 272 + QLatin1Char('_'); 273 266 QString key = QLatin1Literal("qt_") 267 % HexString<quint64>(pm.cacheKey()) 268 % HexString<uint>(pe->mode) 269 % HexString<quint64>(QApplication::palette().cacheKey()) 270 % HexString<uint>(actualSize.width()) 271 % HexString<uint>(actualSize.height()); 274 272 275 273 if (mode == QIcon::Active) { 276 if (QPixmapCache::find(key + QString::number(mode), pm))274 if (QPixmapCache::find(key % HexString<uint>(mode), pm)) 277 275 return pm; // horray 278 if (QPixmapCache::find(key + QString::number(QIcon::Normal), pm)) {276 if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), pm)) { 279 277 QStyleOption opt(0); 280 278 opt.palette = QApplication::palette(); … … 285 283 } 286 284 287 if (!QPixmapCache::find(key + QString::number(mode), pm)) {285 if (!QPixmapCache::find(key % HexString<uint>(mode), pm)) { 288 286 if (pm.size() != actualSize) 289 287 pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); … … 295 293 pm = generated; 296 294 } 297 QPixmapCache::insert(key + QString::number(mode), pm);295 QPixmapCache::insert(key % HexString<uint>(mode), pm); 298 296 } 299 297 return pm; … … 442 440 } 443 441 444 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)442 #ifndef QT_NO_LIBRARY 445 443 Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, 446 444 (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive)) … … 880 878 881 879 /*! 880 \since 4.7 881 882 Returns the name used to create the icon, if available. 883 884 Depending on the way the icon was created, it may have an associated 885 name. This is the case for icons created with fromTheme() or icons 886 using a QIconEngine which supports the QIconEngineV2::IconNameHook. 887 888 \sa fromTheme(), QIconEngine 889 */ 890 QString QIcon::name() const 891 { 892 if (!d || !d->engine || d->engine_version < 2) 893 return QString(); 894 QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine); 895 return engine->iconName(); 896 } 897 898 /*! 882 899 \since 4.6 883 900 -
trunk/src/gui/image/qicon.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 82 82 QSize actualSize(const QSize &size, Mode mode = Normal, State state = Off) const; 83 83 84 QString name() const; 85 84 86 void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const; 85 87 inline void paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const -
trunk/src/gui/image/qicon_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qiconengine.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 183 183 that should be filled with icon sizes. Engines that work in terms 184 184 of a scalable, vectorial format normally return an empty list. 185 186 \value IconNameHook Allows to query the name used to create the 187 icon, for example when instantiating an icon using 188 QIcon::fromTheme(). 185 189 186 190 \sa virtual_hook() … … 302 306 } 303 307 308 /*! 309 \since 4.7 310 311 Returns the name used to create the engine, if available. 312 313 \note This is a helper method and the actual work is done by 314 virtual_hook() method, hence this method depends on icon engine support 315 and may not work with all icon engines. 316 */ 317 QString QIconEngineV2::iconName() 318 { 319 QString name; 320 virtual_hook(QIconEngineV2::IconNameHook, reinterpret_cast<void*>(&name)); 321 return name; 322 } 323 304 324 QT_END_NAMESPACE -
trunk/src/gui/image/qiconengine.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 81 81 82 82 public: 83 enum IconEngineHook { AvailableSizesHook = 1 };83 enum IconEngineHook { AvailableSizesHook = 1, IconNameHook }; 84 84 85 85 struct AvailableSizesArgument … … 93 93 QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal, 94 94 QIcon::State state = QIcon::Off); 95 96 // ### Qt 5: make this function const and virtual. 97 QString iconName(); 95 98 }; 96 99 -
trunk/src/gui/image/qiconengineplugin.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qiconengineplugin.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qiconloader.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 63 63 #include <private/qt_x11_p.h> 64 64 #endif 65 66 #include <private/qstylehelper_p.h> 65 67 66 68 QT_BEGIN_NAMESPACE … … 150 152 if (m_iconDirs.isEmpty()) { 151 153 m_iconDirs = qt_guiPlatformPlugin()->iconThemeSearchPaths(); 152 // Al lways add resource directory as search path154 // Always add resource directory as search path 153 155 m_iconDirs.append(QLatin1String(":/icons")); 154 156 } … … 265 267 iconEntry->dir = dirInfo; 266 268 iconEntry->filename = currentDir.filePath(iconName + pngext); 267 // Notice we ensure that pixmap entries al lways come before269 // Notice we ensure that pixmap entries always come before 268 270 // scalable to preserve search order afterwards 269 271 entries.prepend(iconEntry); … … 489 491 490 492 int actualSize = qMin(size.width(), size.height()); 491 QString key = QLatin1String("$qt_theme_") 492 + QString::number(basePixmap.cacheKey(), 16) 493 + QLatin1Char('_') 494 + QString::number(mode) 495 + QLatin1Char('_') 496 + QString::number(qApp->palette().cacheKey(), 16) 497 + QLatin1Char('_') 498 + QString::number(actualSize); 493 494 QString key = QLatin1Literal("$qt_theme_") 495 % HexString<qint64>(basePixmap.cacheKey()) 496 % HexString<int>(mode) 497 % HexString<qint64>(qApp->palette().cacheKey()) 498 % HexString<int>(actualSize); 499 499 500 500 QPixmap cachedPixmap; … … 555 555 } 556 556 break; 557 case QIconEngineV2::IconNameHook: 558 { 559 QString &name = *reinterpret_cast<QString*>(data); 560 name = m_iconName; 561 } 562 break; 557 563 default: 558 564 QIconEngineV2::virtual_hook(id, data); -
trunk/src/gui/image/qiconloader_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qimage.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 59 59 #include <private/qpixmapdata_p.h> 60 60 #include <private/qimagescale_p.h> 61 #include <private/qsimd_p.h> 61 62 62 63 #include <qhash.h> … … 210 211 } 211 212 212 const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 8)213 const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4) 213 214 214 215 // sanity check for potential overflows … … 273 274 switch (format) { 274 275 276 case QImage::Format_Mono: 277 case QImage::Format_MonoLSB: 275 278 case QImage::Format_Indexed8: 276 279 has_alpha_pixels = has_alpha_clut; … … 481 484 \o Low-level information 482 485 \o 486 483 487 The depth() function returns the depth of the image. The supported 484 depths are 1 (monochrome), 8 and 32 (for more information see the 485 \l {QImage#Image Formats}{Image Formats} section). 488 depths are 1 (monochrome), 8, 16, 24 and 32 bits. The 489 bitPlaneCount() function tells how many of those bits that are 490 used. For more information see the 491 \l {QImage#Image Formats}{Image Formats} section. 486 492 487 493 The format(), bytesPerLine(), and byteCount() functions provide … … 708 714 709 715 \value Format_Indexed8 The image is stored using 8-bit indexes 710 into a colormap. 716 into a colormap. 711 717 712 718 \value Format_RGB32 The image is stored using a 32-bit RGB format (0xffRRGGBB). … … 1116 1122 : QPaintDevice() 1117 1123 { 1118 d = image.d; 1119 if (d) 1120 d->ref.ref(); 1124 if (image.paintingActive()) { 1125 d = 0; 1126 operator=(image.copy()); 1127 } else { 1128 d = image.d; 1129 if (d) 1130 d->ref.ref(); 1131 } 1121 1132 } 1122 1133 … … 1315 1326 QImage &QImage::operator=(const QImage &image) 1316 1327 { 1317 if (image.d) 1318 image.d->ref.ref(); 1319 if (d && !d->ref.deref()) 1320 delete d; 1321 d = image.d; 1328 if (image.paintingActive()) { 1329 operator=(image.copy()); 1330 } else { 1331 if (image.d) 1332 image.d->ref.ref(); 1333 if (d && !d->ref.deref()) 1334 delete d; 1335 d = image.d; 1336 } 1322 1337 return *this; 1323 1338 } … … 1581 1596 Returns the depth of the image. 1582 1597 1583 The image depth is the number of bits used to encode a single1598 The image depth is the number of bits used to store a single 1584 1599 pixel, also called bits per pixel (bpp). 1585 1600 1586 1601 The supported depths are 1, 8, 16, 24 and 32. 1587 1602 1588 \sa convertToFormat(), {QImage#Image Formats}{Image Formats},1603 \sa bitPlaneCount(), convertToFormat(), {QImage#Image Formats}{Image Formats}, 1589 1604 {QImage#Image Information}{Image Information} 1590 1605 … … 1836 1851 1837 1852 \sa bytesPerLine(), bits(), {QImage#Pixel Manipulation}{Pixel 1838 Manipulation} 1853 Manipulation}, constScanLine() 1839 1854 */ 1840 1855 uchar *QImage::scanLine(int i) … … 1864 1879 } 1865 1880 1881 1882 /*! 1883 Returns a pointer to the pixel data at the scanline with index \a 1884 i. The first scanline is at index 0. 1885 1886 The scanline data is aligned on a 32-bit boundary. 1887 1888 Note that QImage uses \l{Implicit Data Sharing} {implicit data 1889 sharing}, but this function does \e not perform a deep copy of the 1890 shared pixel data, because the returned data is const. 1891 1892 \sa scanLine(), constBits() 1893 \since 4.7 1894 */ 1895 const uchar *QImage::constScanLine(int i) const 1896 { 1897 if (!d) 1898 return 0; 1899 1900 Q_ASSERT(i >= 0 && i < height()); 1901 return d->data + i * d->bytes_per_line; 1902 } 1866 1903 1867 1904 /*! … … 1874 1911 current return value. 1875 1912 1876 \sa scanLine(), byteCount() 1913 \sa scanLine(), byteCount(), constBits() 1877 1914 */ 1878 1915 uchar *QImage::bits() … … 1902 1939 1903 1940 1941 /*! 1942 Returns a pointer to the first pixel data. 1943 1944 Note that QImage uses \l{Implicit Data Sharing} {implicit data 1945 sharing}, but this function does \e not perform a deep copy of the 1946 shared pixel data, because the returned data is const. 1947 1948 \sa bits(), constScanLine() 1949 \since 4.7 1950 */ 1951 const uchar *QImage::constBits() const 1952 { 1953 return d ? d->data : 0; 1954 } 1904 1955 1905 1956 /*! … … 2234 2285 typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); 2235 2286 2287 typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags); 2288 2236 2289 static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) 2237 2290 { … … 2255 2308 src_data += src_pad; 2256 2309 dest_data += dest_pad; 2310 } 2311 } 2312 2313 static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) 2314 { 2315 Q_ASSERT(data->format == QImage::Format_ARGB32); 2316 2317 const int pad = (data->bytes_per_line >> 2) - data->width; 2318 QRgb *rgb_data = (QRgb *) data->data; 2319 2320 for (int i = 0; i < data->height; ++i) { 2321 const QRgb *end = rgb_data + data->width; 2322 while (rgb_data < end) { 2323 *rgb_data = PREMUL(*rgb_data); 2324 ++rgb_data; 2325 } 2326 rgb_data += pad; 2327 } 2328 data->format = QImage::Format_ARGB32_Premultiplied; 2329 return true; 2330 } 2331 2332 static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) 2333 { 2334 Q_ASSERT(data->format == QImage::Format_Indexed8); 2335 const int depth = 32; 2336 2337 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; 2338 const int nbytes = dst_bytes_per_line * data->height; 2339 uchar *const newData = (uchar *)realloc(data->data, nbytes); 2340 if (!newData) 2341 return false; 2342 2343 data->data = newData; 2344 2345 // start converting from the end because the end image is bigger than the source 2346 uchar *src_data = newData + data->nbytes; // end of src 2347 quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src 2348 const int width = data->width; 2349 const int src_pad = data->bytes_per_line - width; 2350 const int dest_pad = (dst_bytes_per_line >> 2) - width; 2351 if (data->colortable.size() == 0) { 2352 data->colortable.resize(256); 2353 for (int i = 0; i < 256; ++i) 2354 data->colortable[i] = qRgb(i, i, i); 2355 } else { 2356 for (int i = 0; i < data->colortable.size(); ++i) 2357 data->colortable[i] = PREMUL(data->colortable.at(i)); 2358 2359 // Fill the rest of the table in case src_data > colortable.size() 2360 const int oldSize = data->colortable.size(); 2361 const QRgb lastColor = data->colortable.at(oldSize - 1); 2362 data->colortable.insert(oldSize, 256 - oldSize, lastColor); 2363 } 2364 2365 for (int i = 0; i < data->height; ++i) { 2366 src_data -= src_pad; 2367 dest_data -= dest_pad; 2368 for (int pixI = 0; pixI < width; ++pixI) { 2369 --src_data; 2370 --dest_data; 2371 *dest_data = data->colortable.at(*src_data); 2372 } 2373 } 2374 2375 data->colortable = QVector<QRgb>(); 2376 data->format = QImage::Format_ARGB32_Premultiplied; 2377 data->bytes_per_line = dst_bytes_per_line; 2378 data->depth = depth; 2379 data->nbytes = nbytes; 2380 2381 return true; 2382 } 2383 2384 static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags) 2385 { 2386 Q_ASSERT(data->format == QImage::Format_Indexed8); 2387 const int depth = 32; 2388 2389 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; 2390 const int nbytes = dst_bytes_per_line * data->height; 2391 uchar *const newData = (uchar *)realloc(data->data, nbytes); 2392 if (!newData) 2393 return false; 2394 2395 data->data = newData; 2396 2397 // start converting from the end because the end image is bigger than the source 2398 uchar *src_data = newData + data->nbytes; 2399 quint32 *dest_data = (quint32 *) (newData + nbytes); 2400 const int width = data->width; 2401 const int src_pad = data->bytes_per_line - width; 2402 const int dest_pad = (dst_bytes_per_line >> 2) - width; 2403 if (data->colortable.size() == 0) { 2404 data->colortable.resize(256); 2405 for (int i = 0; i < 256; ++i) 2406 data->colortable[i] = qRgb(i, i, i); 2407 } else { 2408 // Fill the rest of the table in case src_data > colortable.size() 2409 const int oldSize = data->colortable.size(); 2410 const QRgb lastColor = data->colortable.at(oldSize - 1); 2411 data->colortable.insert(oldSize, 256 - oldSize, lastColor); 2412 } 2413 2414 for (int i = 0; i < data->height; ++i) { 2415 src_data -= src_pad; 2416 dest_data -= dest_pad; 2417 for (int pixI = 0; pixI < width; ++pixI) { 2418 --src_data; 2419 --dest_data; 2420 *dest_data = (quint32) data->colortable.at(*src_data); 2421 } 2422 } 2423 2424 data->colortable = QVector<QRgb>(); 2425 data->format = QImage::Format_RGB32; 2426 data->bytes_per_line = dst_bytes_per_line; 2427 data->depth = depth; 2428 data->nbytes = nbytes; 2429 2430 return true; 2431 } 2432 2433 static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags) 2434 { 2435 Q_ASSERT(data->format == QImage::Format_Indexed8); 2436 const int depth = 16; 2437 2438 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; 2439 const int nbytes = dst_bytes_per_line * data->height; 2440 uchar *const newData = (uchar *)realloc(data->data, nbytes); 2441 if (!newData) 2442 return false; 2443 2444 data->data = newData; 2445 2446 // start converting from the end because the end image is bigger than the source 2447 uchar *src_data = newData + data->nbytes; 2448 quint16 *dest_data = (quint16 *) (newData + nbytes); 2449 const int width = data->width; 2450 const int src_pad = data->bytes_per_line - width; 2451 const int dest_pad = (dst_bytes_per_line >> 1) - width; 2452 2453 quint16 colorTableRGB16[256]; 2454 if (data->colortable.isEmpty()) { 2455 for (int i = 0; i < 256; ++i) 2456 colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(qRgb(i, i, i), 0); 2457 } else { 2458 // 1) convert the existing colors to RGB16 2459 const int tableSize = data->colortable.size(); 2460 for (int i = 0; i < tableSize; ++i) 2461 colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(data->colortable.at(i), 0); 2462 data->colortable = QVector<QRgb>(); 2463 2464 // 2) fill the rest of the table in case src_data > colortable.size() 2465 const quint16 lastColor = colorTableRGB16[tableSize - 1]; 2466 for (int i = tableSize; i < 256; ++i) 2467 colorTableRGB16[i] = lastColor; 2468 } 2469 2470 for (int i = 0; i < data->height; ++i) { 2471 src_data -= src_pad; 2472 dest_data -= dest_pad; 2473 for (int pixI = 0; pixI < width; ++pixI) { 2474 --src_data; 2475 --dest_data; 2476 *dest_data = colorTableRGB16[*src_data]; 2477 } 2478 } 2479 2480 data->format = QImage::Format_RGB16; 2481 data->bytes_per_line = dst_bytes_per_line; 2482 data->depth = depth; 2483 data->nbytes = nbytes; 2484 2485 return true; 2486 } 2487 2488 static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags) 2489 { 2490 Q_ASSERT(data->format == QImage::Format_RGB32); 2491 const int depth = 16; 2492 2493 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; 2494 const int src_bytes_per_line = data->bytes_per_line; 2495 quint32 *src_data = (quint32 *) data->data; 2496 quint16 *dst_data = (quint16 *) data->data; 2497 2498 for (int i = 0; i < data->height; ++i) { 2499 qt_memconvert(dst_data, src_data, data->width); 2500 src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line); 2501 dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line); 2502 } 2503 data->format = QImage::Format_RGB16; 2504 data->bytes_per_line = dst_bytes_per_line; 2505 data->depth = depth; 2506 data->nbytes = dst_bytes_per_line * data->height; 2507 uchar *const newData = (uchar *)realloc(data->data, data->nbytes); 2508 if (newData) { 2509 data->data = newData; 2510 return true; 2511 } else { 2512 return false; 2257 2513 } 2258 2514 } … … 2950 3206 for (int i=0; i<256; ++i) 2951 3207 colorTable[i] = qRgb(i, i, i); 2952 2953 3208 } 2954 3209 … … 2956 3211 const uchar *src_data = src->data; 2957 3212 uchar *dest_data = dest->data; 3213 int tableSize = colorTable.size() - 1; 2958 3214 for (int y = 0; y < src->height; y++) { 2959 3215 uint *p = (uint *)dest_data; … … 2962 3218 2963 3219 while (p < end) 2964 *p++ = colorTable.at( *b++);3220 *p++ = colorTable.at(qMin<int>(tableSize, *b++)); 2965 3221 2966 3222 src_data += src->bytes_per_line; … … 3108 3364 3109 3365 // first index source, second dest 3110 static constImage_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] =3366 static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] = 3111 3367 { 3112 3368 { … … 3406 3662 } // Format_ARGB4444_Premultiplied 3407 3663 }; 3664 3665 static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] = 3666 { 3667 { 3668 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3669 }, 3670 { 3671 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3672 }, // Format_Mono 3673 { 3674 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3675 }, // Format_MonoLSB 3676 { 3677 0, 3678 0, 3679 0, 3680 0, 3681 0, 3682 convert_indexed8_to_RGB_inplace, 3683 convert_indexed8_to_ARGB_PM_inplace, 3684 convert_indexed8_to_RGB16_inplace, 3685 0, 3686 0, 3687 0, 3688 0, 3689 0, 3690 0, 3691 0, 3692 0, 3693 }, // Format_Indexed8 3694 { 3695 0, 3696 0, 3697 0, 3698 0, 3699 0, 3700 0, 3701 0, 3702 convert_RGB_to_RGB16_inplace, 3703 0, 3704 0, 3705 0, 3706 0, 3707 0, 3708 0, 3709 0, 3710 0, 3711 }, // Format_ARGB32 3712 { 3713 0, 3714 0, 3715 0, 3716 0, 3717 0, 3718 0, 3719 convert_ARGB_to_ARGB_PM_inplace, 3720 0, 3721 0, 3722 0, 3723 0, 3724 0, 3725 0, 3726 0, 3727 0, 3728 0, 3729 }, // Format_ARGB32 3730 { 3731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3732 }, // Format_ARGB32_Premultiplied 3733 { 3734 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3735 }, // Format_RGB16 3736 { 3737 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3738 }, // Format_ARGB8565_Premultiplied 3739 { 3740 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3741 }, // Format_RGB666 3742 { 3743 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3744 }, // Format_ARGB6666_Premultiplied 3745 { 3746 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3747 }, // Format_RGB555 3748 { 3749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3750 }, // Format_ARGB8555_Premultiplied 3751 { 3752 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3753 }, // Format_RGB888 3754 { 3755 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3756 }, // Format_RGB444 3757 { 3758 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 3759 } // Format_ARGB4444_Premultiplied 3760 }; 3761 3762 void qInitImageConversions() 3763 { 3764 const uint features = qDetectCPUFeatures(); 3765 Q_UNUSED(features); 3766 3767 #ifdef QT_HAVE_SSE2 3768 if (features & SSE2) { 3769 extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags); 3770 inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2; 3771 } 3772 #endif 3773 #ifdef QT_HAVE_SSSE3 3774 if (features & SSSE3) { 3775 extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); 3776 converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3; 3777 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3; 3778 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3; 3779 } 3780 #endif 3781 #ifdef QT_HAVE_NEON 3782 if (features & NEON) { 3783 extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); 3784 converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon; 3785 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon; 3786 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon; 3787 } 3788 #endif 3789 } 3408 3790 3409 3791 /*! … … 3759 4141 break; 3760 4142 case Format_Indexed8: 3761 if (index_or_rgb > (uint)d->colortable.size()) {4143 if (index_or_rgb >= (uint)d->colortable.size()) { 3762 4144 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb); 3763 4145 return; … … 4170 4552 int h = height(); 4171 4553 QImage m(w, h, Format_MonoLSB); 4554 QIMAGE_SANITYCHECK_MEMORY(m); 4172 4555 m.setColorCount(2); 4173 4556 m.setColor(0, QColor(Qt::color0).rgba()); … … 4262 4645 return QImage(); 4263 4646 QImage maskImage(size(), QImage::Format_MonoLSB); 4647 QIMAGE_SANITYCHECK_MEMORY(maskImage); 4264 4648 maskImage.fill(0); 4265 4649 uchar *s = maskImage.bits(); … … 4322 4706 // Create result image, copy colormap 4323 4707 QImage result(d->width, d->height, d->format); 4708 QIMAGE_SANITYCHECK_MEMORY(result); 4324 4709 4325 4710 // check if we ran out of of memory.. … … 4459 4844 case Format_ARGB32_Premultiplied: 4460 4845 res = QImage(d->width, d->height, d->format); 4846 QIMAGE_SANITYCHECK_MEMORY(res); 4461 4847 for (int i = 0; i < d->height; i++) { 4462 4848 uint *q = (uint*)res.scanLine(i); 4463 uint *p = (uint*) scanLine(i);4849 uint *p = (uint*)constScanLine(i); 4464 4850 uint *end = p + d->width; 4465 4851 while (p < end) { … … 4472 4858 case Format_RGB16: 4473 4859 res = QImage(d->width, d->height, d->format); 4860 QIMAGE_SANITYCHECK_MEMORY(res); 4474 4861 for (int i = 0; i < d->height; i++) { 4475 4862 ushort *q = (ushort*)res.scanLine(i); 4476 const ushort *p = (const ushort*) scanLine(i);4863 const ushort *p = (const ushort*)constScanLine(i); 4477 4864 const ushort *end = p + d->width; 4478 4865 while (p < end) { … … 4485 4872 case Format_ARGB8565_Premultiplied: 4486 4873 res = QImage(d->width, d->height, d->format); 4874 QIMAGE_SANITYCHECK_MEMORY(res); 4487 4875 for (int i = 0; i < d->height; i++) { 4488 quint8 *p = (quint8*)scanLine(i); 4876 const quint8 *p = constScanLine(i); 4877 quint8 *q = res.scanLine(i); 4489 4878 const quint8 *end = p + d->width * sizeof(qargb8565); 4490 4879 while (p < end) { 4491 quint16 *q = reinterpret_cast<quint16*>(p + 1); 4492 *q = ((*q << 11) & 0xf800) | ((*q >> 11) & 0x1f) | (*q & 0x07e0); 4880 q[0] = p[0]; 4881 q[1] = (p[1] & 0xe0) | (p[2] >> 3); 4882 q[2] = (p[2] & 0x07) | (p[1] << 3); 4493 4883 p += sizeof(qargb8565); 4884 q += sizeof(qargb8565); 4494 4885 } 4495 4886 } … … 4497 4888 case Format_RGB666: 4498 4889 res = QImage(d->width, d->height, d->format); 4890 QIMAGE_SANITYCHECK_MEMORY(res); 4499 4891 for (int i = 0; i < d->height; i++) { 4500 4892 qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i)); 4501 const qrgb666 *p = reinterpret_cast<const qrgb666*>( scanLine(i));4893 const qrgb666 *p = reinterpret_cast<const qrgb666*>(constScanLine(i)); 4502 4894 const qrgb666 *end = p + d->width; 4503 4895 while (p < end) { … … 4509 4901 case Format_ARGB6666_Premultiplied: 4510 4902 res = QImage(d->width, d->height, d->format); 4903 QIMAGE_SANITYCHECK_MEMORY(res); 4511 4904 for (int i = 0; i < d->height; i++) { 4512 qargb6666 *q = reinterpret_cast<qargb6666*>(res.scanLine(i));4513 const q argb6666 *p = reinterpret_cast<const qargb6666*>(scanLine(i));4514 const qargb6666 *end = p + d->width;4905 const quint8 *p = constScanLine(i); 4906 const quint8 *end = p + d->width * sizeof(qargb6666); 4907 quint8 *q = res.scanLine(i); 4515 4908 while (p < end) { 4516 const QRgb rgb = quint32(*p++); 4517 *q++ = qRgba(qBlue(rgb), qGreen(rgb), qRed(rgb), qAlpha(rgb)); 4909 q[0] = (p[1] >> 4) | ((p[2] & 0x3) << 4) | (p[0] & 0xc0); 4910 q[1] = (p[1] & 0xf) | (p[0] << 4); 4911 q[2] = (p[2] & 0xfc) | ((p[0] >> 4) & 0x3); 4912 p += sizeof(qargb6666); 4913 q += sizeof(qargb6666); 4518 4914 } 4519 4915 } … … 4521 4917 case Format_RGB555: 4522 4918 res = QImage(d->width, d->height, d->format); 4919 QIMAGE_SANITYCHECK_MEMORY(res); 4523 4920 for (int i = 0; i < d->height; i++) { 4524 ushort *q = (ushort*)res.scanLine(i);4525 const ushort *p = (const ushort*)scanLine(i);4526 const ushort*end = p + d->width;4921 quint16 *q = (quint16*)res.scanLine(i); 4922 const quint16 *p = (const quint16*)constScanLine(i); 4923 const quint16 *end = p + d->width; 4527 4924 while (p < end) { 4528 *q = ((*p << 10) & 0x7 800) | ((*p >> 10) & 0x1f) | (*p & 0x83e0);4925 *q = ((*p << 10) & 0x7c00) | ((*p >> 10) & 0x1f) | (*p & 0x3e0); 4529 4926 p++; 4530 4927 q++; … … 4534 4931 case Format_ARGB8555_Premultiplied: 4535 4932 res = QImage(d->width, d->height, d->format); 4933 QIMAGE_SANITYCHECK_MEMORY(res); 4536 4934 for (int i = 0; i < d->height; i++) { 4537 quint8 *p = (quint8*)scanLine(i); 4935 const quint8 *p = constScanLine(i); 4936 quint8 *q = res.scanLine(i); 4538 4937 const quint8 *end = p + d->width * sizeof(qargb8555); 4539 4938 while (p < end) { 4540 quint16 *q = reinterpret_cast<quint16*>(p + 1); 4541 *q = ((*q << 10) & 0x7800) | ((*q >> 10) & 0x1f) | (*q & 0x83e0); 4939 q[0] = p[0]; 4940 q[1] = (p[1] & 0xe0) | (p[2] >> 2); 4941 q[2] = (p[2] & 0x03) | ((p[1] << 2) & 0x7f); 4542 4942 p += sizeof(qargb8555); 4943 q += sizeof(qargb8555); 4543 4944 } 4544 4945 } … … 4546 4947 case Format_RGB888: 4547 4948 res = QImage(d->width, d->height, d->format); 4949 QIMAGE_SANITYCHECK_MEMORY(res); 4548 4950 for (int i = 0; i < d->height; i++) { 4549 quint8 *q = re interpret_cast<quint8*>(res.scanLine(i));4550 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));4951 quint8 *q = res.scanLine(i); 4952 const quint8 *p = constScanLine(i); 4551 4953 const quint8 *end = p + d->width * sizeof(qrgb888); 4552 4954 while (p < end) { … … 4560 4962 break; 4561 4963 case Format_RGB444: 4562 res = QImage(d->width, d->height, d->format);4563 for (int i = 0; i < d->height; i++) {4564 quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i));4565 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));4566 const quint8 *end = p + d->width * sizeof(qrgb444);4567 while (p < end) {4568 q[0] = (p[0] & 0xf0) | ((p[1] & 0x0f) << 8);4569 q[1] = ((p[0] & 0x0f) >> 8) | (p[1] & 0xf0);4570 q += sizeof(qrgb444);4571 p += sizeof(qrgb444);4572 }4573 }4574 break;4575 4964 case Format_ARGB4444_Premultiplied: 4576 4965 res = QImage(d->width, d->height, d->format); 4966 QIMAGE_SANITYCHECK_MEMORY(res); 4577 4967 for (int i = 0; i < d->height; i++) { 4578 quint 8 *q = reinterpret_cast<quint8*>(res.scanLine(i));4579 const quint 8 *p = reinterpret_cast<const quint8*>(scanLine(i));4580 const quint 8 *end = p + d->width * sizeof(qargb4444);4968 quint16 *q = reinterpret_cast<quint16*>(res.scanLine(i)); 4969 const quint16 *p = reinterpret_cast<const quint16*>(constScanLine(i)); 4970 const quint16 *end = p + d->width; 4581 4971 while (p < end) { 4582 q[0] = (p[0] & 0xf0) | ((p[1] & 0x0f) << 8); 4583 q[1] = ((p[0] & 0x0f) >> 8) | (p[1] & 0xf0); 4584 q += sizeof(qargb4444); 4585 p += sizeof(qargb4444); 4972 *q = (*p & 0xf0f0) | ((*p & 0x0f) << 8) | ((*p & 0xf00) >> 8); 4973 p++; 4974 q++; 4586 4975 } 4587 4976 } … … 4774 5163 the stream to a file will not produce a valid image file. 4775 5164 4776 \sa QImage::save(), { Format of the QDataStream Operators}5165 \sa QImage::save(), {Serializing Qt Data Types} 4777 5166 */ 4778 5167 … … 4800 5189 \a image. 4801 5190 4802 \sa QImage::load(), { Format of the QDataStream Operators}5191 \sa QImage::load(), {Serializing Qt Data Types} 4803 5192 */ 4804 5193 … … 5666 6055 } 5667 6056 5668 detach(); 5669 5670 QImage converted = convertToFormat(QImage::Format_ARGB32_Premultiplied); 5671 if (!converted.isNull()) 5672 *this = converted; 6057 if (d->format == QImage::Format_ARGB32_Premultiplied) 6058 detach(); 5673 6059 else 6060 *this = convertToFormat(QImage::Format_ARGB32_Premultiplied); 6061 6062 if (isNull()) 5674 6063 return; 5675 6064 … … 5814 6203 || d->format == Format_Mono 5815 6204 || d->format == Format_MonoLSB))); 6205 } 6206 6207 6208 /*! 6209 \since 4.7 6210 Returns the number of bit planes in the image. 6211 6212 The number of bit planes is the number of bits of color and 6213 transparency information for each pixel. This is different from 6214 (i.e. smaller than) the depth when the image format contains 6215 unused bits. 6216 6217 \sa depth(), format(), {QImage#Image Formats}{Image Formats} 6218 */ 6219 int QImage::bitPlaneCount() const 6220 { 6221 if (!d) 6222 return 0; 6223 int bpc = 0; 6224 switch (d->format) { 6225 case QImage::Format_Invalid: 6226 break; 6227 case QImage::Format_RGB32: 6228 bpc = 24; 6229 break; 6230 case QImage::Format_RGB666: 6231 bpc = 18; 6232 break; 6233 case QImage::Format_RGB555: 6234 bpc = 15; 6235 break; 6236 case QImage::Format_ARGB8555_Premultiplied: 6237 bpc = 23; 6238 break; 6239 case QImage::Format_RGB444: 6240 bpc = 12; 6241 break; 6242 default: 6243 bpc = depthForFormat(d->format); 6244 break; 6245 } 6246 return bpc; 5816 6247 } 5817 6248 … … 6181 6612 } 6182 6613 6614 bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags) 6615 { 6616 if (format == newFormat) 6617 return true; 6618 6619 // No in-place conversion if we have to detach 6620 if (ref > 1) 6621 return false; 6622 6623 const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat]; 6624 InPlace_Image_Converter converter = *converterPtr; 6625 if (converter) 6626 return converter(this, flags); 6627 else 6628 return false; 6629 } 6183 6630 6184 6631 /*! -
trunk/src/gui/image/qimage.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 170 170 #endif 171 171 int colorCount() const; 172 int bitPlaneCount() const; 172 173 173 174 QRgb color(int i) const; … … 183 184 uchar *bits(); 184 185 const uchar *bits() const; 186 const uchar *constBits() const; 185 187 #ifdef QT_DEPRECATED 186 188 QT_DEPRECATED int numBytes() const; … … 190 192 uchar *scanLine(int); 191 193 const uchar *scanLine(int) const; 194 const uchar *constScanLine(int) const; 192 195 int bytesPerLine() const; 193 196 -
trunk/src/gui/image/qimage_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 64 64 QT_BEGIN_NAMESPACE 65 65 66 class QImageWriter; 67 66 68 struct Q_GUI_EXPORT QImageData { // internal image data 67 69 QImageData(); … … 97 99 bool checkForAlphaPixels() const; 98 100 101 // Convert the image in-place, minimizing memory reallocation 102 // Return false if the conversion cannot be done in-place. 103 bool convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags); 99 104 100 105 #ifndef QT_NO_IMAGE_TEXT … … 106 111 }; 107 112 113 void qInitImageConversions(); 114 108 115 QT_END_NAMESPACE 109 116 -
trunk/src/gui/image/qimageiohandler.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qimageiohandler.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qimagepixmapcleanuphooks.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qimagepixmapcleanuphooks_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qimagereader.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 142 142 #include <private/qpnghandler_p.h> 143 143 #endif 144 #ifndef QT_NO_IMAGEFORMAT_JPEG 145 #include <private/qjpeghandler_p.h> 146 #endif 147 #ifndef QT_NO_IMAGEFORMAT_MNG 148 #include <private/qmnghandler_p.h> 149 #endif 150 #ifndef QT_NO_IMAGEFORMAT_TIFF 151 #include <private/qtiffhandler_p.h> 152 #endif 153 #ifdef QT_BUILTIN_GIF_READER 154 #include <private/qgifhandler_p.h> 155 #endif 144 156 145 157 QT_BEGIN_NAMESPACE 146 158 147 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)159 #ifndef QT_NO_LIBRARY 148 160 Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, 149 161 (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) … … 153 165 #ifndef QT_NO_IMAGEFORMAT_PNG 154 166 _qt_PngFormat, 167 #endif 168 #ifndef QT_NO_IMAGEFORMAT_JPEG 169 _qt_JpgFormat, 170 #endif 171 #ifndef QT_NO_IMAGEFORMAT_MNG 172 _qt_MngFormat, 173 #endif 174 #ifndef QT_NO_IMAGEFORMAT_TIFF 175 _qt_TifFormat, 176 #endif 177 #ifdef QT_BUILTIN_GIF_READER 178 _qt_GifFormat, 155 179 #endif 156 180 _qt_BmpFormat, … … 180 204 {_qt_PngFormat, "png"}, 181 205 #endif 206 #ifndef QT_NO_IMAGEFORMAT_JPEG 207 {_qt_JpgFormat, "jpg"}, 208 #endif 209 #ifndef QT_NO_IMAGEFORMAT_MNG 210 {_qt_MngFormat, "mng"}, 211 #endif 212 #ifndef QT_NO_IMAGEFORMAT_TIFF 213 {_qt_TifFormat, "tif"}, 214 #endif 215 #ifdef QT_BUILTIN_GIF_READER 216 {_qt_GifFormat, "gif"}, 217 #endif 182 218 {_qt_BmpFormat, "bmp"}, 183 219 #ifndef QT_NO_IMAGEFORMAT_PPM … … 206 242 QImageIOHandler *handler = 0; 207 243 208 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)244 #ifndef QT_NO_LIBRARY 209 245 // check if we have plugins that support the image format 210 246 QFactoryLoader *l = loader(); … … 218 254 #endif 219 255 220 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)256 #ifndef QT_NO_LIBRARY 221 257 int suffixPluginIndex = -1; 222 258 if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) { … … 247 283 testFormat = QByteArray(); 248 284 249 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)285 #ifndef QT_NO_LIBRARY 250 286 if (suffixPluginIndex != -1) { 251 287 // check if the plugin that claims support for this format can load … … 302 338 if (false) { 303 339 #ifndef QT_NO_IMAGEFORMAT_PNG 304 340 } else if (testFormat == "png") { 305 341 handler = new QPngHandler; 342 #endif 343 #ifndef QT_NO_IMAGEFORMAT_JPEG 344 } else if (testFormat == "jpg" || testFormat == "jpeg") { 345 handler = new QJpegHandler; 346 #endif 347 #ifndef QT_NO_IMAGEFORMAT_MNG 348 } else if (testFormat == "mng") { 349 handler = new QMngHandler; 350 #endif 351 #ifndef QT_NO_IMAGEFORMAT_TIFF 352 } else if (testFormat == "tif" || testFormat == "tiff") { 353 handler = new QTiffHandler; 354 #endif 355 #ifdef QT_BUILTIN_GIF_READER 356 } else if (testFormat == "gif") { 357 handler = new QGifHandler; 306 358 #endif 307 359 #ifndef QT_NO_IMAGEFORMAT_BMP … … 332 384 } 333 385 334 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)386 #ifndef QT_NO_LIBRARY 335 387 if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { 336 388 // check if any of our plugins recognize the file from its contents. … … 351 403 device->seek(pos); 352 404 } 353 #endif 405 #endif // QT_NO_LIBRARY 354 406 355 407 if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { … … 381 433 break; 382 434 #endif 435 #ifndef QT_NO_IMAGEFORMAT_JPEG 436 case _qt_JpgFormat: 437 if (QJpegHandler::canRead(device)) 438 handler = new QJpegHandler; 439 break; 440 #endif 441 #ifndef QT_NO_IMAGEFORMAT_MNG 442 case _qt_MngFormat: 443 if (QMngHandler::canRead(device)) 444 handler = new QMngHandler; 445 break; 446 #endif 447 #ifndef QT_NO_IMAGEFORMAT_TIFF 448 case _qt_TifFormat: 449 if (QTiffHandler::canRead(device)) 450 handler = new QTiffHandler; 451 break; 452 #endif 453 #ifdef QT_BUILTIN_GIF_READER 454 case _qt_GifFormat: 455 if (QGifHandler::canRead(device)) 456 handler = new QGifHandler; 457 break; 458 #endif 383 459 #ifndef QT_NO_IMAGEFORMAT_BMP 384 460 case _qt_BmpFormat: … … 504 580 { 505 581 // check some preconditions 506 if (!device || (!deleteDevice && !device->isOpen() )) {582 if (!device || (!deleteDevice && !device->isOpen() && !device->open(QIODevice::ReadOnly))) { 507 583 imageReaderError = QImageReader::DeviceError; 508 584 errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Invalid device")); … … 1415 1491 formats << _qt_BuiltInFormats[i].extension; 1416 1492 1417 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)1493 #ifndef QT_NO_LIBRARY 1418 1494 QFactoryLoader *l = loader(); 1419 1495 QStringList keys = l->keys(); -
trunk/src/gui/image/qimagereader.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qimagewriter.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 115 115 #include <private/qpnghandler_p.h> 116 116 #endif 117 #ifndef QT_NO_IMAGEFORMAT_JPEG 118 #include <private/qjpeghandler_p.h> 119 #endif 120 #ifndef QT_NO_IMAGEFORMAT_MNG 121 #include <private/qmnghandler_p.h> 122 #endif 123 #ifndef QT_NO_IMAGEFORMAT_TIFF 124 #include <private/qtiffhandler_p.h> 125 #endif 126 #ifdef QT_BUILTIN_GIF_READER 127 #include <private/qgifhandler_p.h> 128 #endif 117 129 118 130 QT_BEGIN_NAMESPACE 119 131 120 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)132 #ifndef QT_NO_LIBRARY 121 133 Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, 122 134 (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) … … 130 142 QImageIOHandler *handler = 0; 131 143 132 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)144 #ifndef QT_NO_LIBRARY 133 145 // check if any plugins can write the image 134 146 QFactoryLoader *l = loader(); … … 143 155 if (QFile *file = qobject_cast<QFile *>(device)) { 144 156 if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) { 145 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)157 #ifndef QT_NO_LIBRARY 146 158 int index = keys.indexOf(QString::fromLatin1(suffix)); 147 159 if (index != -1) … … 154 166 QByteArray testFormat = !form.isEmpty() ? form : suffix; 155 167 156 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)168 #ifndef QT_NO_LIBRARY 157 169 if (suffixPluginIndex != -1) { 158 170 // when format is missing, check if we can find a plugin for the … … 162 174 handler = plugin->create(device, suffix); 163 175 } 164 #endif // Q _NO_LIBRARY176 #endif // QT_NO_LIBRARY 165 177 166 178 // check if any built-in handlers can write the image … … 171 183 handler = new QPngHandler; 172 184 #endif 185 #ifndef QT_NO_IMAGEFORMAT_JPEG 186 } else if (testFormat == "jpg" || testFormat == "jpeg") { 187 handler = new QJpegHandler; 188 #endif 189 #ifndef QT_NO_IMAGEFORMAT_MNG 190 } else if (testFormat == "mng") { 191 handler = new QMngHandler; 192 #endif 193 #ifndef QT_NO_IMAGEFORMAT_TIFF 194 } else if (testFormat == "tif" || testFormat == "tiff") { 195 handler = new QTiffHandler; 196 #endif 197 #ifdef QT_BUILTIN_GIF_READER 198 } else if (testFormat == "gif") { 199 handler = new QGifHandler; 200 #endif 173 201 #ifndef QT_NO_IMAGEFORMAT_BMP 174 202 } else if (testFormat == "bmp") { … … 193 221 } 194 222 195 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)223 #ifndef QT_NO_LIBRARY 196 224 if (!testFormat.isEmpty()) { 197 225 for (int i = 0; i < keys.size(); ++i) { … … 204 232 } 205 233 } 206 #endif 234 #endif // QT_NO_LIBRARY 207 235 208 236 if (!handler) … … 670 698 formats << "png"; 671 699 #endif 672 673 #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) 700 #ifndef QT_NO_IMAGEFORMAT_JPEG 701 formats << "jpg" << "jpeg"; 702 #endif 703 #ifndef QT_NO_IMAGEFORMAT_MNG 704 formats << "mng"; 705 #endif 706 #ifndef QT_NO_IMAGEFORMAT_TIFF 707 formats << "tif" << "tiff"; 708 #endif 709 #ifdef QT_BUILTIN_GIF_READER 710 formats << "gif"; 711 #endif 712 713 #ifndef QT_NO_LIBRARY 674 714 QFactoryLoader *l = loader(); 675 715 QStringList keys = l->keys(); -
trunk/src/gui/image/qimagewriter.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qmovie.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qmovie.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qnativeimage.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qnativeimage_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpaintengine_pic.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 487 487 #endif 488 488 489 const QTextItemInt &si = static_cast<const QTextItemInt &>(ti); 490 if (si.chars == 0) 491 QPaintEngine::drawTextItem(p, ti); // Draw as path 492 489 493 if (d->pic_d->formatMajor >= 9) { 490 const QTextItemInt &si = static_cast<const QTextItemInt &>(ti);491 494 int pos; 492 495 SERIALIZE_CMD(QPicturePrivate::PdcDrawTextItem); -
trunk/src/gui/image/qpaintengine_pic_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpicture.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpicture.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpicture_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpictureformatplugin.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpictureformatplugin.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpixmap.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 83 83 84 84 #include "qpixmap_raster_p.h" 85 #include "private/qstylehelper_p.h" 85 86 86 87 QT_BEGIN_NAMESPACE … … 579 580 QSize QPixmap::size() const 580 581 { 581 return data ? QSize(data->width(), data->height()) : QSize( );582 return data ? QSize(data->width(), data->height()) : QSize(0, 0); 582 583 } 583 584 … … 636 637 return; 637 638 639 // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get 640 // the actual underlaying runtime pixmap data. 641 QPixmapData *pd = pixmapData(); 642 638 643 // Create new pixmap 639 QPixmap pm(QSize(w, h), data ? data->type : QPixmapData::PixmapType);644 QPixmap pm(QSize(w, h), pd ? pd->type : QPixmapData::PixmapType); 640 645 bool uninit = false; 641 646 #if defined(Q_WS_X11) 642 QX11PixmapData *x11Data = data && data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;647 QX11PixmapData *x11Data = pd && pd->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(pd) : 0; 643 648 if (x11Data) { 644 649 pm.x11SetScreen(x11Data->xinfo.screen()); … … 646 651 } 647 652 #elif defined(Q_WS_MAC) 648 QMacPixmapData *macData = data && data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;653 QMacPixmapData *macData = pd && pd->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0; 649 654 if (macData) 650 655 uninit = macData->uninit; … … 660 665 #if defined(Q_WS_X11) 661 666 if (x11Data && x11Data->x11_mask) { 662 QX11PixmapData *pmData = static_cast<QX11PixmapData*>(pm.data.data()); 663 pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display, 664 RootWindow(x11Data->xinfo.display(), 665 x11Data->xinfo.screen()), 666 w, h, 1); 667 GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0); 668 XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0, qMin(width(), w), qMin(height(), h), 0, 0); 669 XFreeGC(X11->display, gc); 667 QPixmapData *newPd = pm.pixmapData(); 668 QX11PixmapData *pmData = (newPd && newPd->classId() == QPixmapData::X11Class) 669 ? static_cast<QX11PixmapData*>(newPd) : 0; 670 if (pmData) { 671 pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display, 672 RootWindow(x11Data->xinfo.display(), 673 x11Data->xinfo.screen()), 674 w, h, 1); 675 GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0); 676 XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0, 677 qMin(width(), w), qMin(height(), h), 0, 0); 678 XFreeGC(X11->display, gc); 679 } 670 680 } 671 681 #endif … … 766 776 Creates and returns a mask for this pixmap based on the given \a 767 777 maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the 768 maskColor will be opaque. If \a mode is Qt::MaskOutColor, all pixels769 matching the maskColor will be transparent.778 maskColor will be transparent. If \a mode is Qt::MaskOutColor, all pixels 779 matching the maskColor will be opaque. 770 780 771 781 This function is slow because it involves converting to/from a … … 826 836 827 837 QFileInfo info(fileName); 828 QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') + 829 QString::number(info.size()) + QLatin1Char('_') + QString::number(data ? data->pixelType() : QPixmapData::PixmapType); 838 QString key = QLatin1Literal("qt_pixmap") 839 % info.absoluteFilePath() 840 % HexString<uint>(info.lastModified().toTime_t()) 841 % HexString<quint64>(info.size()) 842 % HexString<uint>(data ? data->pixelType() : QPixmapData::PixmapType); 843 844 // Note: If no extension is provided, we try to match the 845 // file against known plugin extensions 846 if (!info.completeSuffix().isEmpty() && !info.exists()) 847 return false; 830 848 831 849 if (QPixmapCache::find(key, *this)) … … 1072 1090 sendResizeEvents(widget); 1073 1091 1092 widget->d_func()->prepareToRender(QRegion(), 1093 QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask); 1094 1074 1095 QRect r(rect); 1075 1096 if (r.width() < 0) … … 1082 1103 1083 1104 QPixmap res(r.size()); 1084 widget->render(&res, QPoint(), r, 1085 QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask); 1105 if (!qt_widget_private(widget)->isOpaque) 1106 res.fill(Qt::transparent); 1107 1108 widget->d_func()->render(&res, QPoint(), r, QWidget::DrawWindowBackground 1109 | QWidget::DrawChildren | QWidget::IgnoreMask, true); 1086 1110 return res; 1087 1111 } … … 1161 1185 { 1162 1186 #if defined(Q_WS_X11) 1163 if (data && data->classId() == QPixmapData::X11Class) 1164 return static_cast<const QX11PixmapData*>(data.constData())->handle(); 1187 const QPixmapData *pd = pixmapData(); 1188 if (pd) { 1189 if (pd->classId() == QPixmapData::X11Class) 1190 return static_cast<const QX11PixmapData*>(pd)->handle(); 1191 else 1192 qWarning("QPixmap::handle(): Pixmap is not an X11 class pixmap"); 1193 } 1165 1194 #endif 1166 1195 return 0; … … 1279 1308 valid image file. 1280 1309 1281 \sa QPixmap::save(), { Format of the QDataStream Operators}1310 \sa QPixmap::save(), {Serializing Qt Data Types} 1282 1311 */ 1283 1312 … … 1292 1321 Reads an image from the given \a stream into the given \a pixmap. 1293 1322 1294 \sa QPixmap::load(), { Format of the QDataStream Operators}1323 \sa QPixmap::load(), {Serializing Qt Data Types} 1295 1324 */ 1296 1325 … … 1364 1393 1365 1394 /*! 1366 \fn bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags) 1367 1368 Use the static fromImage() function instead. 1369 */ 1395 Replaces this pixmap's data with the given \a image using the 1396 specified \a flags to control the conversion. The \a flags 1397 argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}. 1398 Passing 0 for \a flags sets all the default options. Returns true 1399 if the result is that this pixmap is not null. 1400 1401 Note: this function was part of Qt 3 support in Qt 4.6 and earlier. 1402 It has been promoted to official API status in 4.7 to support updating 1403 the pixmap's image without creating a new QPixmap as fromImage() would. 1404 1405 \sa fromImage() 1406 \since 4.7 1407 */ 1408 bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags) 1409 { 1410 if (image.isNull() || !data) 1411 *this = QPixmap::fromImage(image, flags); 1412 else 1413 data->fromImage(image, flags); 1414 return !isNull(); 1415 } 1370 1416 1371 1417 /*! … … 1735 1781 pixmap. 1736 1782 1783 \note When using the native X11 graphics system, the pixmap 1784 becomes invalid when the QApplication instance is destroyed. 1785 1737 1786 \sa QBitmap, QImage, QImageReader, QImageWriter 1738 1787 */ … … 1753 1802 mask, otherwise returns false. 1754 1803 1755 \warning This is potentially an expensive operation.1756 1757 1804 \sa hasAlphaChannel(), mask() 1758 1805 */ 1759 1806 bool QPixmap::hasAlpha() const 1760 1807 { 1761 return data && (data->hasAlphaChannel() || !data->mask().isNull()); 1808 #if defined(Q_WS_X11) 1809 if (data && data->hasAlphaChannel()) 1810 return true; 1811 QPixmapData *pd = pixmapData(); 1812 if (pd && pd->classId() == QPixmapData::X11Class) { 1813 QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pd); 1814 #ifndef QT_NO_XRENDER 1815 if (x11Data->picture && x11Data->d == 32) 1816 return true; 1817 #endif 1818 if (x11Data->d == 1 || x11Data->x11_mask) 1819 return true; 1820 } 1821 return false; 1822 #else 1823 return data && data->hasAlphaChannel(); 1824 #endif 1762 1825 } 1763 1826 … … 1927 1990 return; 1928 1991 1929 QPixmapData::ClassId id = data->classId(); 1992 // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get 1993 // the actual underlaying runtime pixmap data. 1994 QPixmapData *pd = pixmapData(); 1995 QPixmapData::ClassId id = pd->classId(); 1930 1996 if (id == QPixmapData::RasterClass) { 1931 QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>( data.data());1997 QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(pd); 1932 1998 rasterData->image.detach(); 1933 1999 } 1934 2000 1935 2001 if (data->is_cached && data->ref == 1) 1936 QImagePixmapCleanupHooks::executePixmapDataModificationHooks( data.data());2002 QImagePixmapCleanupHooks::executePixmapDataModificationHooks(pd); 1937 2003 1938 2004 #if defined(Q_WS_MAC) 1939 QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>( data.data()) : 0;2005 QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0; 1940 2006 if (macData) { 1941 2007 if (macData->cg_mask) { … … 1952 2018 1953 2019 #if defined(Q_WS_X11) 1954 if ( data->classId() == QPixmapData::X11Class) {1955 QX11PixmapData *d = static_cast<QX11PixmapData*>( data.data());2020 if (pd->classId() == QPixmapData::X11Class) { 2021 QX11PixmapData *d = static_cast<QX11PixmapData*>(pd); 1956 2022 d->flags &= ~QX11PixmapData::Uninitialized; 1957 2023 … … 1983 2049 use QBitmap::fromImage() instead. 1984 2050 1985 \sa toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}2051 \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} 1986 2052 */ 1987 2053 QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) … … 1998 2064 1999 2065 /*! 2066 \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags) 2067 2068 Create a QPixmap from an image read directly from an \a imageReader. 2069 The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}. 2070 Passing 0 for \a flags sets all the default options. 2071 2072 On some systems, reading an image directly to QPixmap can use less memory than 2073 reading a QImage to convert it to QPixmap. 2074 2075 \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} 2076 */ 2077 QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags) 2078 { 2079 QGraphicsSystem *gs = QApplicationPrivate::graphicsSystem(); 2080 QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::PixmapType) 2081 : QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType)); 2082 data->fromImageReader(imageReader, flags); 2083 return QPixmap(data.take()); 2084 } 2085 2086 /*! 2000 2087 \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int 2001 2088 width, int height) … … 2043 2130 QPixmapData* QPixmap::pixmapData() const 2044 2131 { 2045 return data.data(); 2046 } 2132 if (data) { 2133 QPixmapData* pm = data.data(); 2134 return pm->runtimeData() ? pm->runtimeData() : pm; 2135 } 2136 2137 return 0; 2138 } 2139 2047 2140 2048 2141 /*! -
trunk/src/gui/image/qpixmap.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 63 63 64 64 class QImageWriter; 65 class QImageReader; 65 66 class QColor; 66 67 class QVariant; … … 140 141 QImage toImage() const; 141 142 static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor); 143 static QPixmap fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags = Qt::AutoColor); 142 144 143 145 bool load(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor); … … 146 148 bool save(const QString& fileName, const char* format = 0, int quality = -1) const; 147 149 bool save(QIODevice* device, const char* format = 0, int quality = -1) const; 150 151 bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor); 148 152 149 153 #if defined(Q_WS_WIN) … … 240 244 inline QT3_SUPPORT QImage convertToImage() const { return toImage(); } 241 245 QT3_SUPPORT bool convertFromImage(const QImage &, ColorMode mode); 242 QT3_SUPPORT bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor)243 { (*this) = fromImage(img, flags); return !isNull(); }244 246 inline QT3_SUPPORT operator QImage() const { return toImage(); } 245 247 inline QT3_SUPPORT QPixmap xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); } … … 287 289 friend class QCoreGraphicsPaintEngine; 288 290 friend class QWidgetPrivate; 289 friend class QRasterPaintEngine;290 291 friend class QRasterBuffer; 291 friend class QPixmapCacheEntry;292 292 #if !defined(QT_NO_DATASTREAM) 293 293 friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPixmap &); -
trunk/src/gui/image/qpixmap_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpixmap_mac_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpixmap_qws.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpixmap_raster.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 45 45 #include "qnativeimage_p.h" 46 46 #include "qimage_p.h" 47 #include "qpaintengine.h" 47 48 48 49 #include "qbitmap.h" 49 50 #include "qimage.h" 51 #include <QBuffer> 52 #include <QImageReader> 53 #include <private/qimage_p.h> 54 #include <private/qsimd_p.h> 50 55 #include <private/qwidget_p.h> 51 56 #include <private/qdrawhelper_p.h> … … 128 133 } 129 134 135 bool QRasterPixmapData::fromData(const uchar *buffer, uint len, const char *format, 136 Qt::ImageConversionFlags flags) 137 { 138 QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len); 139 QBuffer b(&a); 140 b.open(QIODevice::ReadOnly); 141 QImage image = QImageReader(&b, format).read(); 142 if (image.isNull()) 143 return false; 144 145 createPixmapForImage(image, flags, /* inplace = */true); 146 return !isNull(); 147 } 148 130 149 void QRasterPixmapData::fromImage(const QImage &sourceImage, 131 150 Qt::ImageConversionFlags flags) 132 151 { 133 152 Q_UNUSED(flags); 134 135 #ifdef Q_WS_QWS 136 QImage::Format format; 137 if (pixelType() == BitmapType) { 138 format = QImage::Format_Mono; 139 } else { 140 format = QScreen::instance()->pixelFormat(); 141 if (format == QImage::Format_Invalid) 142 format = QImage::Format_ARGB32_Premultiplied; 143 else if (format == QImage::Format_Indexed8) // currently not supported 144 format = QImage::Format_RGB444; 145 } 146 147 if (sourceImage.hasAlphaChannel() 148 && ((flags & Qt::NoOpaqueDetection) 149 || const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) { 150 switch (format) { 151 case QImage::Format_RGB16: 152 format = QImage::Format_ARGB8565_Premultiplied; 153 break; 154 case QImage::Format_RGB666: 155 format = QImage::Format_ARGB6666_Premultiplied; 156 break; 157 case QImage::Format_RGB555: 158 format = QImage::Format_ARGB8555_Premultiplied; 159 break; 160 case QImage::Format_RGB444: 161 format = QImage::Format_ARGB4444_Premultiplied; 162 break; 163 default: 164 format = QImage::Format_ARGB32_Premultiplied; 165 break; 166 } 167 } else if (format == QImage::Format_Invalid) { 168 format = QImage::Format_ARGB32_Premultiplied; 169 } 170 171 image = sourceImage.convertToFormat(format); 172 #else 173 if (pixelType() == BitmapType) { 174 image = sourceImage.convertToFormat(QImage::Format_MonoLSB); 175 } else { 176 if (sourceImage.depth() == 1) { 177 image = sourceImage.hasAlphaChannel() 178 ? sourceImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) 179 : sourceImage.convertToFormat(QImage::Format_RGB32); 180 } else { 181 182 QImage::Format opaqueFormat = QNativeImage::systemFormat(); 183 QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; 184 185 switch (opaqueFormat) { 186 case QImage::Format_RGB16: 187 alphaFormat = QImage::Format_ARGB8565_Premultiplied; 188 break; 189 default: // We don't care about the others... 190 break; 191 } 192 193 if (!sourceImage.hasAlphaChannel() 194 || ((flags & Qt::NoOpaqueDetection) == 0 195 && !const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) { 196 image = sourceImage.convertToFormat(opaqueFormat); 197 } else { 198 image = sourceImage.convertToFormat(alphaFormat); 199 } 200 } 201 } 202 #endif 203 if (image.d) { 204 w = image.d->width; 205 h = image.d->height; 206 d = image.d->depth; 207 } else { 208 w = h = d = 0; 209 } 210 is_null = (w <= 0 || h <= 0); 211 212 setSerialNumber(image.serialNumber()); 153 QImage image = sourceImage; 154 createPixmapForImage(image, flags, /* inplace = */false); 155 } 156 157 void QRasterPixmapData::fromImageReader(QImageReader *imageReader, 158 Qt::ImageConversionFlags flags) 159 { 160 Q_UNUSED(flags); 161 QImage image = imageReader->read(); 162 if (image.isNull()) 163 return; 164 165 createPixmapForImage(image, flags, /* inplace = */true); 213 166 } 214 167 215 168 // from qwindowsurface.cpp 216 169 extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); 170 171 void QRasterPixmapData::copy(const QPixmapData *data, const QRect &rect) 172 { 173 fromImage(data->toImage(rect).copy(), Qt::NoOpaqueDetection); 174 } 217 175 218 176 bool QRasterPixmapData::scroll(int dx, int dy, const QRect &rect) … … 239 197 if (!image.hasAlphaChannel()) { 240 198 QImage::Format toFormat; 199 #if !(defined(QT_HAVE_NEON) || defined(QT_ALWAYS_HAVE_SSE2)) 241 200 if (image.format() == QImage::Format_RGB16) 242 201 toFormat = QImage::Format_ARGB8565_Premultiplied; … … 248 207 toFormat = QImage::Format_ARGB4444_Premultiplied; 249 208 else 209 #endif 250 210 toFormat = QImage::Format_ARGB32_Premultiplied; 251 211 image = QImage(image.width(), image.height(), toFormat); … … 345 305 QImage QRasterPixmapData::toImage() const 346 306 { 307 if (!image.isNull()) { 308 QImageData *data = const_cast<QImage &>(image).data_ptr(); 309 if (data->paintEngine && data->paintEngine->isActive() 310 && data->paintEngine->paintDevice() == &image) 311 { 312 return image.copy(); 313 } 314 } 315 347 316 return image; 317 } 318 319 QImage QRasterPixmapData::toImage(const QRect &rect) const 320 { 321 if (rect.isNull()) 322 return image; 323 324 QRect clipped = rect.intersected(QRect(0, 0, w, h)); 325 if (d % 8 == 0) 326 return QImage(image.scanLine(clipped.y()) + clipped.x() * (d / 8), 327 clipped.width(), clipped.height(), 328 image.bytesPerLine(), image.format()); 329 else 330 return image.copy(clipped); 348 331 } 349 332 … … 395 378 } 396 379 380 void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace) 381 { 382 QImage::Format format; 383 #ifdef Q_WS_QWS 384 if (pixelType() == BitmapType) { 385 format = QImage::Format_Mono; 386 } else { 387 format = QScreen::instance()->pixelFormat(); 388 if (format == QImage::Format_Invalid) 389 format = QImage::Format_ARGB32_Premultiplied; 390 else if (format == QImage::Format_Indexed8) // currently not supported 391 format = QImage::Format_RGB444; 392 } 393 394 if (sourceImage.hasAlphaChannel() 395 && ((flags & Qt::NoOpaqueDetection) 396 || const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) { 397 switch (format) { 398 case QImage::Format_RGB16: 399 format = QImage::Format_ARGB8565_Premultiplied; 400 break; 401 case QImage::Format_RGB666: 402 format = QImage::Format_ARGB6666_Premultiplied; 403 break; 404 case QImage::Format_RGB555: 405 format = QImage::Format_ARGB8555_Premultiplied; 406 break; 407 case QImage::Format_RGB444: 408 format = QImage::Format_ARGB4444_Premultiplied; 409 break; 410 default: 411 format = QImage::Format_ARGB32_Premultiplied; 412 break; 413 } 414 } else if (format == QImage::Format_Invalid) { 415 format = QImage::Format_ARGB32_Premultiplied; 416 } 417 #else 418 if (pixelType() == BitmapType) { 419 format = QImage::Format_MonoLSB; 420 } else { 421 if (sourceImage.depth() == 1) { 422 format = sourceImage.hasAlphaChannel() 423 ? QImage::Format_ARGB32_Premultiplied 424 : QImage::Format_RGB32; 425 } else { 426 QImage::Format opaqueFormat = QNativeImage::systemFormat(); 427 QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; 428 429 #if !defined(QT_HAVE_NEON) && !defined(QT_ALWAYS_HAVE_SSE2) 430 switch (opaqueFormat) { 431 case QImage::Format_RGB16: 432 alphaFormat = QImage::Format_ARGB8565_Premultiplied; 433 break; 434 default: // We don't care about the others... 435 break; 436 } 437 #endif 438 439 if (!sourceImage.hasAlphaChannel()) { 440 format = opaqueFormat; 441 } else if ((flags & Qt::NoOpaqueDetection) == 0 442 && !const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels()) 443 { 444 // image has alpha format but is really opaque, so try to do a 445 // more efficient conversion 446 if (sourceImage.format() == QImage::Format_ARGB32 447 || sourceImage.format() == QImage::Format_ARGB32_Premultiplied) 448 { 449 if (!inPlace) 450 sourceImage.detach(); 451 sourceImage.d->format = QImage::Format_RGB32; 452 } 453 format = opaqueFormat; 454 } else { 455 format = alphaFormat; 456 } 457 } 458 } 459 #endif 460 461 if (inPlace && sourceImage.d->convertInPlace(format, flags)) { 462 image = sourceImage; 463 } else { 464 image = sourceImage.convertToFormat(format); 465 } 466 467 if (image.d) { 468 w = image.d->width; 469 h = image.d->height; 470 d = image.d->depth; 471 } else { 472 w = h = d = 0; 473 } 474 is_null = (w <= 0 || h <= 0); 475 476 setSerialNumber(image.serialNumber()); 477 } 478 397 479 QImage* QRasterPixmapData::buffer() 398 480 { -
trunk/src/gui/image/qpixmap_raster_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 73 73 void resize(int width, int height); 74 74 void fromFile(const QString &filename, Qt::ImageConversionFlags flags); 75 bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags); 75 76 void fromImage(const QImage &image, Qt::ImageConversionFlags flags); 77 void fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags); 76 78 79 void copy(const QPixmapData *data, const QRect &rect); 77 80 bool scroll(int dx, int dy, const QRect &rect); 78 81 void fill(const QColor &color); … … 81 84 void setAlphaChannel(const QPixmap &alphaChannel); 82 85 QImage toImage() const; 86 QImage toImage(const QRect &rect) const; 83 87 QPaintEngine* paintEngine() const; 84 88 QImage* buffer(); … … 86 90 protected: 87 91 int metric(QPaintDevice::PaintDeviceMetric metric) const; 92 void createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace); 93 void setImage(const QImage &image); 88 94 QImage image; 89 95 -
trunk/src/gui/image/qpixmap_s60.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 64 64 0x10, 0x20, 0x40, 0x80 }; 65 65 66 static bool cleanup_function_registered = false; 67 static QS60PixmapData *firstPixmap = 0; 68 69 // static 70 void QS60PixmapData::qt_symbian_register_pixmap(QS60PixmapData *pd) 71 { 72 if (!cleanup_function_registered) { 73 qAddPostRoutine(qt_symbian_release_pixmaps); 74 cleanup_function_registered = true; 75 } 76 77 pd->next = firstPixmap; 78 pd->prev = 0; 79 if (firstPixmap) 80 firstPixmap->prev = pd; 81 firstPixmap = pd; 82 } 83 84 // static 85 void QS60PixmapData::qt_symbian_unregister_pixmap(QS60PixmapData *pd) 86 { 87 if (pd->next) 88 pd->next->prev = pd->prev; 89 if (pd->prev) 90 pd->prev->next = pd->next; 91 else 92 firstPixmap = pd->next; 93 } 94 95 // static 96 void QS60PixmapData::qt_symbian_release_pixmaps() 97 { 98 // Scan all QS60PixmapData objects in the system and destroy them. 99 QS60PixmapData *pd = firstPixmap; 100 while (pd != 0) { 101 pd->release(); 102 pd = pd->next; 103 } 104 } 66 105 67 106 /* … … 158 197 public: 159 198 160 bool heapWasLocked;199 static int heapRefCount; 161 200 QSysInfo::SymbianVersion symbianVersion; 162 201 163 explicit QSymbianBitmapDataAccess() : heapWasLocked(false)202 explicit QSymbianBitmapDataAccess() 164 203 { 165 204 symbianVersion = QSysInfo::symbianVersion(); … … 170 209 inline void beginDataAccess(CFbsBitmap *bitmap) 171 210 { 172 if (symbianVersion == QSysInfo::SV_9_2) 173 heapWasLocked = qt_symbianFbsClient()->lockHeap(); 174 else 211 if (symbianVersion == QSysInfo::SV_9_2) { 212 if (heapRefCount == 0) 213 qt_symbianFbsClient()->lockHeap(); 214 } else { 175 215 bitmap->LockHeap(ETrue); 216 } 217 218 heapRefCount++; 176 219 } 177 220 178 221 inline void endDataAccess(CFbsBitmap *bitmap) 179 222 { 223 heapRefCount--; 224 180 225 if (symbianVersion == QSysInfo::SV_9_2) { 181 if ( !heapWasLocked)226 if (heapRefCount == 0) 182 227 qt_symbianFbsClient()->unlockHeap(); 183 228 } else { … … 186 231 } 187 232 }; 233 234 int QSymbianBitmapDataAccess::heapRefCount = 0; 188 235 189 236 … … 349 396 pengine(0), 350 397 bytes(0), 351 formatLocked(false) 352 { 353 398 formatLocked(false), 399 next(0), 400 prev(0) 401 { 402 qt_symbian_register_pixmap(this); 354 403 } 355 404 … … 358 407 release(); 359 408 delete symbianBitmapDataAccess; 409 qt_symbian_unregister_pixmap(this); 360 410 } 361 411 … … 782 832 bool needsCopy = false; 783 833 784 QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();785 834 if (!(S60->supportsPremultipliedAlpha)) { 786 835 // Convert argb32_premultiplied to argb32 since Symbian 9.2 does … … 920 969 921 970 TSize size = sourceBitmap->SizeInPixels(); 971 int bytesPerLine = sourceBitmap->ScanLineLength(size.iWidth, displayMode); 922 972 923 973 QSymbianBitmapDataAccess da; 924 974 da.beginDataAccess(sourceBitmap); 925 975 uchar *bytes = (uchar*)sourceBitmap->DataAddress(); 926 QImage img = QImage(bytes, size.iWidth, size.iHeight, format);976 QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format); 927 977 img = img.copy(); 928 978 da.endDataAccess(sourceBitmap); … … 963 1013 } 964 1014 1015 void QS60PixmapData::convertToDisplayMode(int mode) 1016 { 1017 const TDisplayMode displayMode = static_cast<TDisplayMode>(mode); 1018 if (!cfbsBitmap || cfbsBitmap->DisplayMode() == displayMode) 1019 return; 1020 if (image.depth() != TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)) { 1021 qWarning("Cannot convert display mode due to depth mismatch"); 1022 return; 1023 } 1024 1025 const TSize size = cfbsBitmap->SizeInPixels(); 1026 QScopedPointer<CFbsBitmap> newBitmap(createSymbianCFbsBitmap(size, displayMode)); 1027 1028 const uchar *sptr = const_cast<const QImage &>(image).bits(); 1029 symbianBitmapDataAccess->beginDataAccess(newBitmap.data()); 1030 uchar *dptr = (uchar*)newBitmap->DataAddress(); 1031 Mem::Copy(dptr, sptr, image.byteCount()); 1032 symbianBitmapDataAccess->endDataAccess(newBitmap.data()); 1033 1034 QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); 1035 delete cfbsBitmap; 1036 lock.relock(); 1037 cfbsBitmap = newBitmap.take(); 1038 setSerialNumber(cfbsBitmap->Handle()); 1039 UPDATE_BUFFER(); 1040 } 1041 965 1042 QPixmapData *QS60PixmapData::createCompatiblePixmapData() const 966 1043 { -
trunk/src/gui/image/qpixmap_s60_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 108 108 void fromNativeType(void* pixmap, NativeType type); 109 109 110 void convertToDisplayMode(int mode); 111 110 112 private: 111 113 void release(); … … 121 123 bool formatLocked; 122 124 125 QS60PixmapData *next; 126 QS60PixmapData *prev; 127 128 static void qt_symbian_register_pixmap(QS60PixmapData *pd); 129 static void qt_symbian_unregister_pixmap(QS60PixmapData *pd); 130 static void qt_symbian_release_pixmaps(); 131 123 132 friend class QPixmap; 124 133 friend class QS60WindowSurface; -
trunk/src/gui/image/qpixmap_win.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpixmap_x11.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 315 315 316 316 QX11PixmapData::QX11PixmapData(PixelType type) 317 : QPixmapData(type, X11Class), hd(0),318 flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), gl_surface(0),317 : QPixmapData(type, X11Class), gl_surface(0), hd(0), 318 flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), 319 319 share_mode(QPixmap::ImplicitlyShared), pengine(0) 320 320 { … … 1143 1143 } 1144 1144 1145 void QX11PixmapData::bitmapFromImage(const QImage &image)1145 Qt::HANDLE QX11PixmapData::createBitmapFromImage(const QImage &image) 1146 1146 { 1147 1147 QImage img = image.convertToFormat(QImage::Format_MonoLSB); … … 1156 1156 char *bits; 1157 1157 uchar *tmp_bits; 1158 w = img.width(); 1159 h = img.height(); 1160 d = 1; 1161 is_null = (w <= 0 || h <= 0); 1158 int w = img.width(); 1159 int h = img.height(); 1162 1160 int bpl = (w + 7) / 8; 1163 1161 int ibpl = img.bytesPerLine(); … … 1178 1176 tmp_bits = 0; 1179 1177 } 1180 hd = (Qt::HANDLE)XCreateBitmapFromData(xinfo.display(),1181 RootWindow(xinfo.display(), xinfo.screen()),1178 Qt::HANDLE hd = (Qt::HANDLE)XCreateBitmapFromData(X11->display, 1179 QX11Info::appRootWindow(), 1182 1180 bits, w, h); 1183 1181 if (tmp_bits) // Avoid purify complaint 1182 delete [] tmp_bits; 1183 return hd; 1184 } 1185 1186 void QX11PixmapData::bitmapFromImage(const QImage &image) 1187 { 1188 w = image.width(); 1189 h = image.height(); 1190 d = 1; 1191 is_null = (w <= 0 || h <= 0); 1192 hd = createBitmapFromImage(image); 1184 1193 #ifndef QT_NO_XRENDER 1185 1194 if (X11->use_xrender) … … 1187 1196 XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0); 1188 1197 #endif // QT_NO_XRENDER 1189 1190 if (tmp_bits) // Avoid purify complaint1191 delete [] tmp_bits;1192 1198 } 1193 1199 … … 1245 1251 1246 1252 if (!X11) { 1247 #ifndef QT_NO_DEBUG 1248 qWarning("~QX11PixmapData(): QPixmap objects must be destroyed before the QApplication" 1249 " object, otherwise the native pixmap object will be leaked."); 1250 #endif 1253 // At this point, the X server will already have freed our resources, 1254 // so there is nothing to do. 1251 1255 return; 1252 1256 } … … 1317 1321 return mask; 1318 1322 } 1319 1320 1323 1321 1324 /*! … … 1455 1458 } 1456 1459 1460 struct QXImageWrapper 1461 { 1462 XImage *xi; 1463 }; 1464 1465 bool QX11PixmapData::canTakeQImageFromXImage(const QXImageWrapper &xiWrapper) const 1466 { 1467 XImage *xi = xiWrapper.xi; 1468 1469 // ARGB32_Premultiplied 1470 if (picture && depth() == 32) 1471 return true; 1472 1473 Visual *visual = (Visual *)xinfo.visual(); 1474 1475 // RGB32 1476 if (depth() == 24 && xi->bits_per_pixel == 32 && visual->red_mask == 0xff0000 1477 && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) 1478 return true; 1479 1480 // RGB16 1481 if (depth() == 16 && xi->bits_per_pixel == 16 && visual->red_mask == 0xf800 1482 && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f) 1483 return true; 1484 1485 return false; 1486 } 1487 1488 QImage QX11PixmapData::takeQImageFromXImage(const QXImageWrapper &xiWrapper) const 1489 { 1490 XImage *xi = xiWrapper.xi; 1491 1492 QImage::Format format = QImage::Format_ARGB32_Premultiplied; 1493 if (depth() == 24) 1494 format = QImage::Format_RGB32; 1495 else if (depth() == 16) 1496 format = QImage::Format_RGB16; 1497 1498 QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format); 1499 // take ownership 1500 image.data_ptr()->own_data = true; 1501 xi->data = 0; 1502 1503 // we may have to swap the byte order 1504 if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst) 1505 || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst)) 1506 { 1507 for (int i=0; i < image.height(); i++) { 1508 if (depth() == 16) { 1509 ushort *p = (ushort*)image.scanLine(i); 1510 ushort *end = p + image.width(); 1511 while (p < end) { 1512 *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff); 1513 p++; 1514 } 1515 } else { 1516 uint *p = (uint*)image.scanLine(i); 1517 uint *end = p + image.width(); 1518 while (p < end) { 1519 *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000) 1520 | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff); 1521 p++; 1522 } 1523 } 1524 } 1525 } 1526 1527 // fix-up alpha channel 1528 if (format == QImage::Format_RGB32) { 1529 QRgb *p = (QRgb *)image.bits(); 1530 for (int y = 0; y < xi->height; ++y) { 1531 for (int x = 0; x < xi->width; ++x) 1532 p[x] |= 0xff000000; 1533 p += xi->bytes_per_line / 4; 1534 } 1535 } 1536 1537 XDestroyImage(xi); 1538 return image; 1539 } 1540 1541 QImage QX11PixmapData::toImage(const QRect &rect) const 1542 { 1543 QXImageWrapper xiWrapper; 1544 xiWrapper.xi = XGetImage(X11->display, hd, rect.x(), rect.y(), rect.width(), rect.height(), 1545 AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap); 1546 1547 Q_CHECK_PTR(xiWrapper.xi); 1548 if (!xiWrapper.xi) 1549 return QImage(); 1550 1551 if (!x11_mask && canTakeQImageFromXImage(xiWrapper)) 1552 return takeQImageFromXImage(xiWrapper); 1553 1554 QImage image = toImage(xiWrapper, rect); 1555 qSafeXDestroyImage(xiWrapper.xi); 1556 return image; 1557 } 1558 1457 1559 /*! 1458 1560 Converts the pixmap to a QImage. Returns a null image if the … … 1472 1574 QImage QX11PixmapData::toImage() const 1473 1575 { 1576 return toImage(QRect(0, 0, w, h)); 1577 } 1578 1579 QImage QX11PixmapData::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const 1580 { 1581 XImage *xi = xiWrapper.xi; 1582 1474 1583 int d = depth(); 1475 1584 Visual *visual = (Visual *)xinfo.visual(); … … 1489 1598 } 1490 1599 1491 XImage *xi = XGetImage(X11->display, hd, 0, 0, w, h, AllPlanes,1492 (d == 1) ? XYPixmap : ZPixmap);1493 1494 Q_CHECK_PTR(xi);1495 if (!xi)1496 return QImage();1497 1498 if (picture && depth() == 32) {1499 QImage image(w, h, QImage::Format_ARGB32_Premultiplied);1500 memcpy(image.bits(), xi->data, xi->bytes_per_line * xi->height);1501 1502 // we may have to swap the byte order1503 if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)1504 || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))1505 {1506 for (int i=0; i < image.height(); i++) {1507 uint *p = (uint*)image.scanLine(i);1508 uint *end = p + image.width();1509 if ((xi->byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)1510 || (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {1511 while (p < end) {1512 *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)1513 | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);1514 p++;1515 }1516 } else if (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian) {1517 while (p < end) {1518 *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)1519 | ((*p ) & 0xff00ff00);1520 p++;1521 }1522 }1523 }1524 }1525 1526 // throw away image data1527 qSafeXDestroyImage(xi);1528 1529 return image;1530 }1531 1532 1600 if (d == 1 && xi->bitmap_bit_order == LSBFirst) 1533 1601 format = QImage::Format_MonoLSB; … … 1535 1603 format = QImage::Format_ARGB32; 1536 1604 1537 QImage image( w, h, format);1605 QImage image(xi->width, xi->height, format); 1538 1606 if (image.isNull()) // could not create image 1539 1607 return image; … … 1541 1609 QImage alpha; 1542 1610 if (x11_mask) { 1543 alpha = mask().toImage(); 1611 if (rect.contains(QRect(0, 0, w, h))) 1612 alpha = mask().toImage(); 1613 else 1614 alpha = mask().toImage().copy(rect); 1544 1615 } 1545 1616 bool ale = alpha.format() == QImage::Format_MonoLSB; … … 1584 1655 bppc++; 1585 1656 1586 for (int y = 0; y < h; ++y) {1657 for (int y = 0; y < xi->height; ++y) { 1587 1658 uchar* asrc = x11_mask ? alpha.scanLine(y) : 0; 1588 1659 dst = (QRgb *)image.scanLine(y); 1589 1660 src = (uchar *)xi->data + xi->bytes_per_line*y; 1590 for (int x = 0; x < w; x++) {1661 for (int x = 0; x < xi->width; x++) { 1591 1662 switch (bppc) { 1592 1663 case 8: … … 1618 1689 break; 1619 1690 default: // should not really happen 1620 x = w; // leave loop1621 y = h;1691 x = xi->width; // leave loop 1692 y = xi->height; 1622 1693 pixel = 0; // eliminate compiler warning 1623 1694 qWarning("QPixmap::convertToImage: Invalid depth %d", bppc); … … 1657 1728 char *xidata = xi->data; // copy each scanline 1658 1729 int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line); 1659 for (int y=0; y< h; y++) {1730 for (int y=0; y<xi->height; y++) { 1660 1731 memcpy(image.scanLine(y), xidata, bpl); 1661 1732 xidata += xi->bytes_per_line; … … 1683 1754 1684 1755 if (x11_mask) { // which pixels are used? 1685 for (int i = 0; i < h; i++) {1756 for (int i = 0; i < xi->height; i++) { 1686 1757 uchar* asrc = alpha.scanLine(i); 1687 1758 p = image.scanLine(i); 1688 1759 if (ale) { 1689 for (int x = 0; x < w; x++) {1760 for (int x = 0; x < xi->width; x++) { 1690 1761 if (asrc[x >> 3] & (1 << (x & 7))) 1691 1762 use[*p] = 1; … … 1693 1764 } 1694 1765 } else { 1695 for (int x = 0; x < w; x++) {1766 for (int x = 0; x < xi->width; x++) { 1696 1767 if (asrc[x >> 3] & (0x80 >> (x & 7))) 1697 1768 use[*p] = 1; … … 1701 1772 } 1702 1773 } else { 1703 for (int i = 0; i < h; i++) {1774 for (int i = 0; i < xi->height; i++) { 1704 1775 p = image.scanLine(i); 1705 1776 end = p + bpl; … … 1713 1784 pix[i] = ncols++; 1714 1785 } 1715 for (int i = 0; i < h; i++) { // translate pixels1786 for (int i = 0; i < xi->height; i++) { // translate pixels 1716 1787 p = image.scanLine(i); 1717 1788 end = p + bpl; … … 1733 1804 trans = image.scanLine(0)[0]; 1734 1805 } 1735 for (int i = 0; i < h; i++) {1806 for (int i = 0; i < xi->height; i++) { 1736 1807 uchar* asrc = alpha.scanLine(i); 1737 1808 p = image.scanLine(i); 1738 1809 if (ale) { 1739 for (int x = 0; x < w; x++) {1810 for (int x = 0; x < xi->width; x++) { 1740 1811 if (!(asrc[x >> 3] & (1 << (x & 7)))) 1741 1812 *p = trans; … … 1743 1814 } 1744 1815 } else { 1745 for (int x = 0; x < w; x++) {1816 for (int x = 0; x < xi->width; x++) { 1746 1817 if (!(asrc[x >> 3] & (1 << (7 -(x & 7))))) 1747 1818 *p = trans; … … 1760 1831 } 1761 1832 } 1762 1763 qSafeXDestroyImage(xi);1764 1833 1765 1834 return image; -
trunk/src/gui/image/qpixmap_x11_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 63 63 class QX11PaintEngine; 64 64 65 struct QXImageWrapper; 66 65 67 class Q_GUI_EXPORT QX11PixmapData : public QPixmapData 66 68 { … … 88 90 Qt::TransformationMode mode) const; 89 91 QImage toImage() const; 92 QImage toImage(const QRect &rect) const; 90 93 QPaintEngine* paintEngine() const; 91 94 92 95 Qt::HANDLE handle() const { return hd; } 93 96 Qt::HANDLE x11ConvertToDefaultDepth(); 97 98 static Qt::HANDLE createBitmapFromImage(const QImage &image); 99 100 void* gl_surface; 101 #ifndef QT_NO_XRENDER 102 void convertToARGB32(bool preserveContents = true); 103 #endif 94 104 95 105 protected: … … 104 114 friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags 105 115 friend class QEglContext; // Needs gl_surface 116 friend class QGLContext; // Needs gl_surface 106 117 friend class QX11GLPixmapData; // Needs gl_surface 118 friend class QMeeGoLivePixmapData; // Needs gl_surface and flags 107 119 friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface 108 120 109 121 void release(); 110 122 123 QImage toImage(const QXImageWrapper &xi, const QRect &rect) const; 124 111 125 QBitmap mask_to_bitmap(int screen) const; 112 126 static Qt::HANDLE bitmap_to_mask(const QBitmap &, int screen); 113 127 void bitmapFromImage(const QImage &image); 128 129 bool canTakeQImageFromXImage(const QXImageWrapper &xi) const; 130 QImage takeQImageFromXImage(const QXImageWrapper &xi) const; 114 131 115 132 Qt::HANDLE hd; … … 129 146 Qt::HANDLE mask_picture; 130 147 Qt::HANDLE hd2; // sorted in the default display depth 131 Qt::HANDLE gl_surface;132 #ifndef QT_NO_XRENDER133 void convertToARGB32(bool preserveContents = true);134 #endif135 148 QPixmap::ShareMode share_mode; 136 149 -
trunk/src/gui/image/qpixmapcache.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 40 40 ****************************************************************************/ 41 41 42 #define Q_TEST_QPIXMAPCACHE 42 43 #include "qpixmapcache.h" 43 44 #include "qobject.h" … … 195 196 static QPixmapCache::KeyData* getKeyData(QPixmapCache::Key *key); 196 197 198 QList< QPair<QString,QPixmap> > allPixmaps() const; 199 bool flushDetachedPixmaps(bool nt); 200 197 201 private: 202 enum { soon_time = 10000, flush_time = 30000 }; 198 203 int *keyArray; 199 204 int theid; … … 233 238 cache is in active use. 234 239 235 When the last pixmap has been deleted from the cache, kill the 236 timer so Qt won't keep the CPU from going into sleep mode. 237 */ 238 void QPMCache::timerEvent(QTimerEvent *) 240 When the last detached pixmap has been deleted from the cache, kill the 241 timer so Qt won't keep the CPU from going into sleep mode. Currently 242 the timer is not restarted when the pixmap becomes unused, but it does 243 restart once something else is added (i.e. the cache space is actually needed). 244 245 Returns true if any were removed. 246 */ 247 bool QPMCache::flushDetachedPixmaps(bool nt) 239 248 { 240 249 int mc = maxCost(); 241 bool nt = totalCost() == ps;242 250 setMaxCost(nt ? totalCost() * 3 / 4 : totalCost() -1); 243 251 setMaxCost(mc); 244 252 ps = totalCost(); 245 253 254 bool any = false; 246 255 QHash<QString, QPixmapCache::Key>::iterator it = cacheKeys.begin(); 247 256 while (it != cacheKeys.end()) { … … 249 258 releaseKey(it.value()); 250 259 it = cacheKeys.erase(it); 260 any = true; 251 261 } else { 252 262 ++it; … … 254 264 } 255 265 256 if (!size()) { 266 return any; 267 } 268 269 void QPMCache::timerEvent(QTimerEvent *) 270 { 271 bool nt = totalCost() == ps; 272 if (!flushDetachedPixmaps(nt)) { 257 273 killTimer(theid); 258 274 theid = 0; 259 275 } else if (nt != t) { 260 276 killTimer(theid); 261 theid = startTimer(nt ? 10000 : 30000);277 theid = startTimer(nt ? soon_time : flush_time); 262 278 t = nt; 263 279 } 264 280 } 281 265 282 266 283 QPixmap *QPMCache::object(const QString &key) const … … 306 323 cacheKeys.insert(key, cacheKey); 307 324 if (!theid) { 308 theid = startTimer( 30000);325 theid = startTimer(flush_time); 309 326 t = false; 310 327 } … … 322 339 if (success) { 323 340 if (!theid) { 324 theid = startTimer( 30000);341 theid = startTimer(flush_time); 325 342 t = false; 326 343 } … … 343 360 if (success) { 344 361 if(!theid) { 345 theid = startTimer( 30000);362 theid = startTimer(flush_time); 346 363 t = false; 347 364 } … … 423 440 } 424 441 442 QList< QPair<QString,QPixmap> > QPMCache::allPixmaps() const 443 { 444 QList< QPair<QString,QPixmap> > r; 445 QHash<QString, QPixmapCache::Key>::const_iterator it = cacheKeys.begin(); 446 while (it != cacheKeys.end()) { 447 QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(it.value()); 448 if (ptr) 449 r.append(QPair<QString,QPixmap>(it.key(),*ptr)); 450 ++it; 451 } 452 return r; 453 } 454 455 425 456 Q_GLOBAL_STATIC(QPMCache, pm_cache) 426 457 … … 634 665 } 635 666 667 void QPixmapCache::flushDetachedPixmaps() 668 { 669 pm_cache()->flushDetachedPixmaps(true); 670 } 671 672 int QPixmapCache::totalUsed() 673 { 674 return (pm_cache()->totalCost()+1023) / 1024; 675 } 676 677 QList< QPair<QString,QPixmap> > QPixmapCache::allPixmaps() 678 { 679 return pm_cache()->allPixmaps(); 680 } 681 636 682 QT_END_NAMESPACE -
trunk/src/gui/image/qpixmapcache.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 45 45 #include <QtGui/qpixmap.h> 46 46 47 #ifdef Q_TEST_QPIXMAPCACHE 48 #include <QtCore/qpair.h> 49 #endif 50 47 51 QT_BEGIN_HEADER 48 52 … … 84 88 static void remove(const Key &key); 85 89 static void clear(); 90 91 #ifdef Q_TEST_QPIXMAPCACHE 92 static void flushDetachedPixmaps(); 93 static int totalUsed(); 94 static QList< QPair<QString,QPixmap> > allPixmaps(); 95 #endif 86 96 }; 87 97 -
trunk/src/gui/image/qpixmapcache_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 82 82 QPixmapCacheEntry(const QPixmapCache::Key &key, const QPixmap &pix) : QPixmap(pix), key(key) 83 83 { 84 if (data && data->classId() == QPixmapData::RasterClass) { 85 QRasterPixmapData *d = static_cast<QRasterPixmapData*>(data.data()); 84 QPixmapData *pd = pixmapData(); 85 if (pd && pd->classId() == QPixmapData::RasterClass) { 86 QRasterPixmapData *d = static_cast<QRasterPixmapData*>(pd); 86 87 if (!d->image.isNull() && d->image.d->paintEngine 87 88 && !d->image.d->paintEngine->isActive()) … … 96 97 }; 97 98 99 inline bool qIsDetached(QPixmapCacheEntry &t) { return t.isDetached(); } 100 98 101 QT_END_NAMESPACE 99 102 -
trunk/src/gui/image/qpixmapdata.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 125 125 } 126 126 127 void QPixmapData::fromImageReader(QImageReader *imageReader, 128 Qt::ImageConversionFlags flags) 129 { 130 const QImage image = imageReader->read(); 131 fromImage(image, flags); 132 } 133 127 134 bool QPixmapData::fromFile(const QString &fileName, const char *format, 128 135 Qt::ImageConversionFlags flags) … … 147 154 void QPixmapData::copy(const QPixmapData *data, const QRect &rect) 148 155 { 149 fromImage(data->toImage( ).copy(rect), Qt::AutoColor);156 fromImage(data->toImage(rect), Qt::NoOpaqueDetection); 150 157 } 151 158 … … 256 263 } 257 264 265 QImage QPixmapData::toImage(const QRect &rect) const 266 { 267 if (rect.contains(QRect(0, 0, w, h))) 268 return toImage(); 269 else 270 return toImage().copy(rect); 271 } 272 258 273 QImage* QPixmapData::buffer() 259 274 { -
trunk/src/gui/image/qpixmapdata_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 59 59 QT_BEGIN_NAMESPACE 60 60 61 class QImageReader; 62 61 63 class Q_GUI_EXPORT QPixmapData 62 64 { … … 74 76 #endif 75 77 enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass, 76 OpenGLClass, OpenVGClass, CustomClass = 1024 };78 OpenGLClass, OpenVGClass, RuntimeClass, CustomClass = 1024 }; 77 79 78 80 QPixmapData(PixelType pixelType, int classId); … … 84 86 virtual void fromImage(const QImage &image, 85 87 Qt::ImageConversionFlags flags) = 0; 88 virtual void fromImageReader(QImageReader *imageReader, 89 Qt::ImageConversionFlags flags); 86 90 87 91 virtual bool fromFile(const QString &filename, const char *format, … … 103 107 virtual QPixmap alphaChannel() const; 104 108 virtual QImage toImage() const = 0; 109 virtual QImage toImage(const QRect &rect) const; 105 110 virtual QPaintEngine* paintEngine() const = 0; 106 111 … … 134 139 static QPixmapData *create(int w, int h, PixelType type); 135 140 141 virtual QPixmapData *runtimeData() const { return 0; } 142 136 143 protected: 144 137 145 void setSerialNumber(int serNo); 138 146 int w; -
trunk/src/gui/image/qpixmapdatafactory.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 57 57 # include <private/qpixmap_mac_p.h> 58 58 #endif 59 #ifdef Q_ WS_S6059 #ifdef Q_OS_SYMBIAN 60 60 # include <private/qpixmap_s60_p.h> 61 61 #endif … … 88 88 #elif defined(Q_WS_MAC) 89 89 return new QMacPixmapData(type); 90 #elif defined(Q_ WS_S60)90 #elif defined(Q_OS_SYMBIAN) 91 91 return new QS60PixmapData(type); 92 92 #else -
trunk/src/gui/image/qpixmapdatafactory_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpixmapfilter.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 727 727 int img_height = img.height(); 728 728 for (int row = 0; row < img_height; ++row) { 729 for (int i = 0; i <= i mprovedQuality; ++i)729 for (int i = 0; i <= int(improvedQuality); ++i) 730 730 qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha); 731 731 } … … 760 760 img_height = temp.height(); 761 761 for (int row = 0; row < img_height; ++row) { 762 for (int i = 0; i <= i mprovedQuality; ++i)762 for (int i = 0; i <= int(improvedQuality); ++i) 763 763 qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha); 764 764 } 765 765 766 766 if (transposed == 0) { 767 qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()), 768 temp.width(), temp.height(), temp.bytesPerLine(), 769 reinterpret_cast<quint32*>(img.bits()), 770 img.bytesPerLine()); 767 if (img.depth() == 8) { 768 qt_memrotate90(reinterpret_cast<const quint8*>(temp.bits()), 769 temp.width(), temp.height(), temp.bytesPerLine(), 770 reinterpret_cast<quint8*>(img.bits()), 771 img.bytesPerLine()); 772 } else { 773 qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()), 774 temp.width(), temp.height(), temp.bytesPerLine(), 775 reinterpret_cast<quint32*>(img.bits()), 776 img.bytesPerLine()); 777 } 771 778 } else { 772 779 img = temp; -
trunk/src/gui/image/qpixmapfilter_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qpnghandler.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 51 51 #include <qvector.h> 52 52 53 #ifdef QT_USE_BUNDLED_LIBPNG 54 #include <../../3rdparty/libpng/png.h> 55 #include <../../3rdparty/libpng/pngconf.h> 56 #else 53 57 #include <png.h> 54 58 #include <pngconf.h> 59 #endif 55 60 56 61 #ifdef Q_OS_WINCE … … 77 82 Never to grayscale. 78 83 */ 84 85 class QPngHandlerPrivate 86 { 87 public: 88 enum State { 89 Ready, 90 ReadHeader, 91 ReadingEnd, 92 Error 93 }; 94 95 QPngHandlerPrivate(QPngHandler *qq) 96 : gamma(0.0), quality(2), png_ptr(0), info_ptr(0), 97 end_info(0), row_pointers(0), state(Ready), q(qq) 98 { } 99 100 float gamma; 101 int quality; 102 QString description; 103 104 png_struct *png_ptr; 105 png_info *info_ptr; 106 png_info *end_info; 107 png_byte **row_pointers; 108 109 bool readPngHeader(); 110 bool readPngImage(QImage *image); 111 112 QImage::Format readImageFormat(); 113 114 State state; 115 116 QPngHandler *q; 117 }; 118 79 119 80 120 #if defined(Q_C_CALLBACKS) … … 114 154 void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) 115 155 { 116 QIODevice *in = (QIODevice *)png_get_io_ptr(png_ptr); 156 QPngHandlerPrivate *d = (QPngHandlerPrivate *)png_get_io_ptr(png_ptr); 157 QIODevice *in = d->q->device(); 158 159 if (d->state == QPngHandlerPrivate::ReadingEnd && !in->isSequential() && (in->size() - in->pos()) < 4 && length == 4) { 160 // Workaround for certain malformed PNGs that lack the final crc bytes 161 uchar endcrc[4] = { 0xae, 0x42, 0x60, 0x82 }; 162 qMemCopy(data, endcrc, 4); 163 in->seek(in->size()); 164 return; 165 } 117 166 118 167 while (length) { … … 163 212 int bit_depth; 164 213 int color_type; 214 png_bytep trans_alpha = 0; 215 png_color_16p trans_color_p = 0; 216 int num_trans; 217 png_colorp palette = 0; 218 int num_palette; 165 219 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); 166 220 167 221 if (color_type == PNG_COLOR_TYPE_GRAY) { 168 222 // Black & White or 8-bit grayscale 169 if (bit_depth == 1 && info_ptr->channels== 1) {223 if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) { 170 224 png_set_invert_mono(png_ptr); 171 225 png_read_update_info(png_ptr, info_ptr); … … 208 262 image.setColor(i, qRgba(c,c,c,0xff)); 209 263 } 210 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 211 #if PNG_LIBPNG_VER_MAJOR < 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR < 4) 212 const int g = info_ptr->trans_values.gray; 213 #else 214 const int g = info_ptr->trans_color.gray; 215 #endif 264 if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) { 265 const int g = trans_color_p->gray; 216 266 if (g < ncols) { 217 267 image.setColor(g, 0); … … 220 270 } 221 271 } else if (color_type == PNG_COLOR_TYPE_PALETTE 222 && png_get_ valid(png_ptr, info_ptr, PNG_INFO_PLTE)223 && info_ptr->num_palette <= 256)272 && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) 273 && num_palette <= 256) 224 274 { 225 275 // 1-bit and 8-bit color … … 234 284 return; 235 285 } 236 image.setColorCount(info_ptr->num_palette); 286 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); 287 image.setColorCount(num_palette); 237 288 int i = 0; 238 if (png_get_ valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {239 while (i < info_ptr->num_trans) {289 if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) { 290 while (i < num_trans) { 240 291 image.setColor(i, qRgba( 241 info_ptr->palette[i].red, 242 info_ptr->palette[i].green, 243 info_ptr->palette[i].blue, 244 #if PNG_LIBPNG_VER_MAJOR < 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR < 4) 245 info_ptr->trans[i] 246 #else 247 info_ptr->trans_alpha[i] 248 #endif 292 palette[i].red, 293 palette[i].green, 294 palette[i].blue, 295 trans_alpha[i] 249 296 ) 250 297 ); … … 252 299 } 253 300 } 254 while (i < info_ptr->num_palette) {301 while (i < num_palette) { 255 302 image.setColor(i, qRgba( 256 info_ptr->palette[i].red,257 info_ptr->palette[i].green,258 info_ptr->palette[i].blue,303 palette[i].red, 304 palette[i].green, 305 palette[i].blue, 259 306 0xff 260 307 ) … … 312 359 #endif 313 360 314 class QPngHandlerPrivate315 {316 public:317 enum State {318 Ready,319 ReadHeader,320 Error321 };322 323 QPngHandlerPrivate(QPngHandler *qq)324 : gamma(0.0), quality(2), png_ptr(0), info_ptr(0),325 end_info(0), row_pointers(0), state(Ready), q(qq)326 { }327 328 float gamma;329 int quality;330 QString description;331 332 png_struct *png_ptr;333 png_info *info_ptr;334 png_info *end_info;335 png_byte **row_pointers;336 337 bool readPngHeader();338 bool readPngImage(QImage *image);339 340 QImage::Format readImageFormat();341 342 State state;343 344 QPngHandler *q;345 };346 361 347 362 /*! … … 377 392 } 378 393 379 png_set_read_fn(png_ptr, q->device(), iod_read_fn);394 png_set_read_fn(png_ptr, this, iod_read_fn); 380 395 png_read_info(png_ptr, info_ptr); 381 396 … … 387 402 while (num_text--) { 388 403 QString key, value; 389 #if defined(PNG_iTXt_SUPPORTED) 404 #if defined(PNG_iTXt_SUPPORTED) && !defined(QT_NO_TEXTCODEC) 390 405 if (text_ptr->lang) { 391 406 QTextCodec *codec = QTextCodec::codecForName(text_ptr->lang); … … 503 518 #endif 504 519 520 state = ReadingEnd; 505 521 png_read_end(png_ptr, end_info); 506 522 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); … … 532 548 png_uint_32 width, height; 533 549 int bit_depth, color_type; 534 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) { 550 png_colorp palette; 551 int num_palette; 552 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); 553 if (color_type == PNG_COLOR_TYPE_GRAY) { 535 554 // Black & White or 8-bit grayscale 536 if ( info_ptr->bit_depth == 1 && info_ptr->channels== 1) {555 if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) { 537 556 format = QImage::Format_Mono; 538 } else if ( info_ptr->bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {557 } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 539 558 format = QImage::Format_ARGB32; 540 559 } else { 541 560 format = QImage::Format_Indexed8; 542 561 } 543 } else if ( info_ptr->color_type == PNG_COLOR_TYPE_PALETTE544 && png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)545 && info_ptr->num_palette <= 256)562 } else if (color_type == PNG_COLOR_TYPE_PALETTE 563 && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) 564 && num_palette <= 256) 546 565 { 547 566 // 1-bit and 8-bit color 548 if ( info_ptr->bit_depth != 1)567 if (bit_depth != 1) 549 568 png_set_packing(png_ptr); 550 569 png_read_update_info(png_ptr, info_ptr); … … 553 572 } else { 554 573 // 32-bit 555 if ( info_ptr->bit_depth == 16)574 if (bit_depth == 16) 556 575 png_set_strip_16(png_ptr); 557 576 558 577 format = QImage::Format_ARGB32; 559 578 // Only add filler if no alpha, or we can get 5 channel data. 560 if (!( info_ptr->color_type & PNG_COLOR_MASK_ALPHA)579 if (!(color_type & PNG_COLOR_MASK_ALPHA) 561 580 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 562 581 // We want 4 bytes, but it isn't an alpha channel … … 649 668 text_ptr[i].text_length = 0; 650 669 text_ptr[i].itxt_length = value.size(); 651 text_ptr[i].lang = "UTF-8";670 text_ptr[i].lang = const_cast<char*>("UTF-8"); 652 671 text_ptr[i].lang_key = qstrdup(it.key().toUtf8().constData()); 653 672 #endif … … 673 692 } 674 693 675 bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image _in, int quality_in, const QString &description,694 bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, int quality_in, const QString &description, 676 695 int off_x_in, int off_y_in) 677 696 { … … 679 698 Q_UNUSED(description); 680 699 #endif 681 682 QImage image;683 switch (image_in.format()) {684 case QImage::Format_ARGB32_Premultiplied:685 case QImage::Format_ARGB4444_Premultiplied:686 case QImage::Format_ARGB8555_Premultiplied:687 case QImage::Format_ARGB8565_Premultiplied:688 case QImage::Format_ARGB6666_Premultiplied:689 image = image_in.convertToFormat(QImage::Format_ARGB32);690 break;691 case QImage::Format_RGB16:692 case QImage::Format_RGB444:693 case QImage::Format_RGB555:694 case QImage::Format_RGB666:695 case QImage::Format_RGB888:696 image = image_in.convertToFormat(QImage::Format_RGB32);697 break;698 default:699 image = image_in;700 break;701 }702 700 703 701 QPoint offset = image.offset(); … … 707 705 png_structp png_ptr; 708 706 png_infop info_ptr; 709 png_bytep* row_pointers;710 707 711 708 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); … … 736 733 } 737 734 735 png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); 736 737 738 int color_type = 0; 739 if (image.colorCount()) 740 color_type = PNG_COLOR_TYPE_PALETTE; 741 else if (image.hasAlphaChannel()) 742 color_type = PNG_COLOR_TYPE_RGB_ALPHA; 743 else 744 color_type = PNG_COLOR_TYPE_RGB; 745 746 png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), 747 image.depth() == 1 ? 1 : 8, // per channel 748 color_type, 0, 0, 0); // sets #channels 749 738 750 if (gamma != 0.0) { 739 751 png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); 740 752 } 741 753 742 png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); 743 744 info_ptr->channels = 745 (image.depth() == 32) 746 ? (image.format() == QImage::Format_RGB32 ? 3 : 4) 747 : 1; 748 749 png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), 750 image.depth() == 1 ? 1 : 8 /* per channel */, 751 image.depth() == 32 752 ? image.format() == QImage::Format_RGB32 753 ? PNG_COLOR_TYPE_RGB 754 : PNG_COLOR_TYPE_RGB_ALPHA 755 : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); 756 757 758 //png_set_sBIT(png_ptr, info_ptr, 8); 759 info_ptr->sig_bit.red = 8; 760 info_ptr->sig_bit.green = 8; 761 info_ptr->sig_bit.blue = 8; 754 png_color_8 sig_bit; 755 sig_bit.red = 8; 756 sig_bit.green = 8; 757 sig_bit.blue = 8; 758 sig_bit.alpha = image.hasAlphaChannel() ? 8 : 0; 759 png_set_sBIT(png_ptr, info_ptr, &sig_bit); 762 760 763 761 if (image.format() == QImage::Format_MonoLSB) 764 762 png_set_packswap(png_ptr); 765 763 766 png_colorp palette = 0;767 png_bytep copy_trans = 0;768 764 if (image.colorCount()) { 769 765 // Paletted 770 int num_palette = image.colorCount(); 771 palette = new png_color[num_palette]; 772 png_set_PLTE(png_ptr, info_ptr, palette, num_palette); 773 int* trans = new int[num_palette]; 766 int num_palette = qMin(256, image.colorCount()); 767 png_color palette[256]; 768 png_byte trans[256]; 774 769 int num_trans = 0; 775 770 for (int i=0; i<num_palette; i++) { 776 QRgb rgb =image.color(i);777 info_ptr->palette[i].red = qRed(rgb);778 info_ptr->palette[i].green = qGreen(rgb);779 info_ptr->palette[i].blue = qBlue(rgb);780 trans[i] = rgb >> 24;771 QRgb rgba=image.color(i); 772 palette[i].red = qRed(rgba); 773 palette[i].green = qGreen(rgba); 774 palette[i].blue = qBlue(rgba); 775 trans[i] = qAlpha(rgba); 781 776 if (trans[i] < 255) { 782 777 num_trans = i+1; 783 778 } 784 779 } 780 png_set_PLTE(png_ptr, info_ptr, palette, num_palette); 781 785 782 if (num_trans) { 786 copy_trans = new png_byte[num_trans]; 787 for (int i=0; i<num_trans; i++) 788 copy_trans[i] = trans[i]; 789 png_set_tRNS(png_ptr, info_ptr, copy_trans, num_trans, 0); 790 } 791 delete [] trans; 792 } 793 794 if (image.format() != QImage::Format_RGB32) { 795 info_ptr->sig_bit.alpha = 8; 783 png_set_tRNS(png_ptr, info_ptr, trans, num_trans, 0); 784 } 796 785 } 797 786 … … 802 791 } 803 792 804 // Qt==ARGB==Big(ARGB)==Little(BGRA) 805 if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { 793 // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless 794 if (QSysInfo::ByteOrder == QSysInfo::LittleEndian 795 && image.format() != QImage::Format_RGB888) { 806 796 png_set_bgr(png_ptr); 807 797 } … … 828 818 png_set_packing(png_ptr); 829 819 830 if ( image.format() == QImage::Format_RGB32)820 if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888) 831 821 png_set_filler(png_ptr, 0, 832 822 QSysInfo::ByteOrder == QSysInfo::BigEndian ? … … 849 839 } 850 840 851 png_uint_32 width; 852 png_uint_32 height; 853 int bit_depth; 854 int color_type; 855 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 856 0, 0, 0); 857 858 const uchar *data = (static_cast<const QImage *>(&image))->bits(); 859 int bpl = image.bytesPerLine(); 860 row_pointers = new png_bytep[height]; 861 uint y; 862 for (y=0; y<height; y++) { 863 row_pointers[y] = (png_bytep)(data + y * bpl); 864 } 865 png_write_image(png_ptr, row_pointers); 866 delete [] row_pointers; 841 int height = image.height(); 842 int width = image.width(); 843 switch (image.format()) { 844 case QImage::Format_Mono: 845 case QImage::Format_MonoLSB: 846 case QImage::Format_Indexed8: 847 case QImage::Format_RGB32: 848 case QImage::Format_ARGB32: 849 case QImage::Format_RGB888: 850 { 851 png_bytep* row_pointers = new png_bytep[height]; 852 for (int y=0; y<height; y++) 853 row_pointers[y] = (png_bytep)image.constScanLine(y); 854 png_write_image(png_ptr, row_pointers); 855 delete [] row_pointers; 856 } 857 break; 858 default: 859 { 860 QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32; 861 QImage row; 862 png_bytep row_pointers[1]; 863 for (int y=0; y<height; y++) { 864 row = image.copy(0, y, width, 1).convertToFormat(fmt); 865 row_pointers[0] = png_bytep(row.constScanLine(0)); 866 png_write_rows(png_ptr, row_pointers, 1); 867 } 868 } 869 break; 870 } 867 871 868 872 png_write_end(png_ptr, info_ptr); 869 873 frames_written++; 870 871 if (palette)872 delete [] palette;873 if (copy_trans)874 delete [] copy_trans;875 874 876 875 png_destroy_write_struct(&png_ptr, &info_ptr); … … 905 904 bool QPngHandler::canRead() const 906 905 { 907 if (d->state == QPngHandlerPrivate::Ready) { 908 if (!canRead(device())) 909 return false; 906 if (d->state == QPngHandlerPrivate::Ready && !canRead(device())) 907 return false; 908 909 if (d->state != QPngHandlerPrivate::Error) { 910 910 setFormat("png"); 911 911 return true; 912 912 } 913 return d->state != QPngHandlerPrivate::Error; 913 914 return false; 914 915 } 915 916 … … 959 960 return d->description; 960 961 else if (option == Size) 961 return QSize(d->info_ptr->width, d->info_ptr->height); 962 return QSize(png_get_image_width(d->png_ptr, d->info_ptr), 963 png_get_image_height(d->png_ptr, d->info_ptr)); 962 964 else if (option == ImageFormat) 963 965 return d->readImageFormat(); -
trunk/src/gui/image/qpnghandler_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qppmhandler.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 410 410 bool QPpmHandler::canRead() const 411 411 { 412 if (state == Ready) { 413 if (!canRead(device(), &subType)) 414 return false; 412 if (state == Ready && !canRead(device(), &subType)) 413 return false; 414 415 if (state != Error) { 415 416 setFormat(subType); 416 417 return true; 417 418 } 418 return state != Error; 419 420 return false; 419 421 } 420 422 -
trunk/src/gui/image/qppmhandler_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qxbmhandler.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 67 67 { 68 68 const int buflen = 300; 69 const int maxlen = 4096; 69 70 char buf[buflen + 1]; 70 71 QRegExp r1(QLatin1String("^#define[ \t]+[a-zA-Z0-9._]+[ \t]+")); … … 72 73 73 74 qint64 readBytes = 0; 74 75 // "#define .._width <num>" 76 readBytes = device->readLine(buf, buflen); 77 if (readBytes <= 0) 78 return false; 79 buf[readBytes - 1] = '\0'; 75 qint64 totalReadBytes = 0; 76 77 buf[0] = '\0'; 80 78 81 79 // skip initial comment, if any 82 while (buf[0] != '#' && (readBytes = device->readLine( buf, buflen )) > 0) {} 83 84 if (readBytes <= 0) 85 return false; 80 while (buf[0] != '#') { 81 readBytes = device->readLine(buf, buflen); 82 83 // if readBytes >= buflen, it's very probably not a C file 84 if (readBytes <= 0 || readBytes >= buflen -1) 85 return false; 86 87 // limit xbm headers to the first 4k in the file to prevent 88 // excessive reads on non-xbm files 89 totalReadBytes += readBytes; 90 if (totalReadBytes >= maxlen) 91 return false; 92 } 93 86 94 buf[readBytes - 1] = '\0'; 87 95 QString sbuf; 88 96 sbuf = QString::fromLatin1(buf); 89 97 98 // "#define .._width <num>" 90 99 if (r1.indexIn(sbuf) == 0 && 91 100 r2.indexIn(sbuf, r1.matchedLength()) == r1.matchedLength()) … … 262 271 bool QXbmHandler::canRead() const 263 272 { 264 if (state == Ready) { 265 if (!canRead(device())) 266 return false; 273 if (state == Ready && !canRead(device())) 274 return false; 275 276 if (state != Error) { 267 277 setFormat("xbm"); 268 278 return true; 269 279 } 270 return state != Error; 280 281 return false; 271 282 } 272 283 -
trunk/src/gui/image/qxbmhandler_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/image/qxpmhandler.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 767 767 XPMRGBData x; 768 768 x.name = name_no_space; 769 // Fun tion bsearch() is supposed to be769 // Function bsearch() is supposed to be 770 770 // void *bsearch(const void *key, const void *base, ... 771 771 // So why (char*)? Are there broken bsearch() declarations out there? … … 1226 1226 bool QXpmHandler::canRead() const 1227 1227 { 1228 if (state == Ready && canRead(device())) { 1228 if (state == Ready && !canRead(device())) 1229 return false; 1230 1231 if (state != Error) { 1229 1232 setFormat("xpm"); 1230 1233 return true; 1231 1234 } 1232 return state != Error; 1235 1236 return false; 1233 1237 } 1234 1238 -
trunk/src/gui/image/qxpmhandler_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
Note:
See TracChangeset
for help on using the changeset viewer.