diff options
Diffstat (limited to 'src/gui/image')
-rw-r--r-- | src/gui/image/image.pri | 3 | ||||
-rw-r--r-- | src/gui/image/qbitmap.cpp | 11 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 71 | ||||
-rw-r--r-- | src/gui/image/qimageiohandler.cpp | 1 | ||||
-rw-r--r-- | src/gui/image/qimageiohandler.h | 3 | ||||
-rw-r--r-- | src/gui/image/qpicture.cpp | 29 | ||||
-rw-r--r-- | src/gui/image/qpicture.h | 4 | ||||
-rw-r--r-- | src/gui/image/qpicture_p.h | 4 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 41 | ||||
-rw-r--r-- | src/gui/image/qpixmap.h | 10 | ||||
-rw-r--r-- | src/gui/image/qpixmap_raster.cpp | 10 | ||||
-rw-r--r-- | src/gui/image/qpixmap_s60.cpp | 236 | ||||
-rw-r--r-- | src/gui/image/qpixmapcache.cpp | 14 | ||||
-rw-r--r-- | src/gui/image/qpixmapdatafactory.cpp | 4 |
14 files changed, 357 insertions, 84 deletions
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index 5507d25..0970385 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -69,6 +69,9 @@ mac { HEADERS += image/qpixmap_mac_p.h SOURCES += image/qpixmap_mac.cpp } +symbian { + SOURCES += image/qpixmap_s60.cpp +} # Built-in image format support HEADERS += \ diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp index bef1738..e239022 100644 --- a/src/gui/image/qbitmap.cpp +++ b/src/gui/image/qbitmap.cpp @@ -265,15 +265,12 @@ QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) img.setColor(1, c0); } - QPixmapData *d; QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem(); - if (gs) - d = gs->createPixmapData(QPixmapData::BitmapType); - else - d = QGraphicsSystem::createDefaultPixmapData(QPixmapData::BitmapType); + QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::BitmapType) + : QGraphicsSystem::createDefaultPixmapData(QPixmapData::BitmapType)); - d->fromImage(img, flags | Qt::MonoOnly); - return QPixmap(d); + data->fromImage(img, flags | Qt::MonoOnly); + return QPixmap(data.take()); } /*! diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 3faca46..86e27bd 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -174,6 +174,13 @@ static int depthForFormat(QImage::Format format) return depth; } +/*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) + + \internal + + Creates a new image data. + Returns 0 if invalid parameters are give or anything else failed. +*/ QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) { if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid) @@ -212,7 +219,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu || INT_MAX/sizeof(uchar *) < uint(height)) return 0; - QImageData *d = new QImageData; + QScopedPointer<QImageData> d(new QImageData); d->colortable.resize(numColors); if (depth == 1) { d->colortable[0] = QColor(Qt::black).rgba(); @@ -235,12 +242,11 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu d->data = (uchar *)malloc(d->nbytes); if (!d->data) { - delete d; return 0; } d->ref.ref(); - return d; + return d.take(); } @@ -1606,6 +1612,7 @@ int QImage::numColors() const /*! Returns a pointer to the scanline pointer table. This is the beginning of the data block for the image. + Returns 0 in case of an error. Use the bits() or scanLine() function instead. */ @@ -1621,6 +1628,8 @@ uchar **QImage::jumpTable() if (!d->jumptable) { d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *)); + if (!d->jumptable) + return 0; uchar *data = d->data; int height = d->height; uchar **p = d->jumptable; @@ -1641,6 +1650,8 @@ const uchar * const *QImage::jumpTable() const return 0; if (!d->jumptable) { d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *)); + if (!d->jumptable) + return 0; uchar *data = d->data; int height = d->height; uchar **p = d->jumptable; @@ -2359,8 +2370,9 @@ static void dither_to_Mono(QImageData *dst, const QImageData *src, switch (dithermode) { case Diffuse: { - int *line1 = new int[w]; - int *line2 = new int[w]; + QScopedArrayPointer<int> lineBuffer(new int[w * 2]); + int *line1 = lineBuffer.data(); + int *line2 = lineBuffer.data() + w; int bmwidth = (w+7)/8; int *b1, *b2; @@ -2440,8 +2452,6 @@ static void dither_to_Mono(QImageData *dst, const QImageData *src, b2++; } } - delete [] line1; - delete [] line2; } break; case Ordered: { @@ -2582,10 +2592,9 @@ static void convert_X_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageC static void convert_ARGB_PM_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags) { - QImageData *tmp = QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32); - convert_ARGB_PM_to_ARGB(tmp, src, flags); - dither_to_Mono(dst, tmp, flags, false); - delete tmp; + QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32)); + convert_ARGB_PM_to_ARGB(tmp.data(), src, flags); + dither_to_Mono(dst, tmp.data(), flags, false); } // @@ -2734,15 +2743,16 @@ static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt:: int* line1[3]; int* line2[3]; int* pv[3]; - line1[0] = new int[src->width]; - line2[0] = new int[src->width]; - line1[1] = new int[src->width]; - line2[1] = new int[src->width]; - line1[2] = new int[src->width]; - line2[2] = new int[src->width]; - pv[0] = new int[src->width]; - pv[1] = new int[src->width]; - pv[2] = new int[src->width]; + QScopedArrayPointer<int> lineBuffer(new int[src->width * 9]); + line1[0] = lineBuffer.data(); + line2[0] = lineBuffer.data() + src->width; + line1[1] = lineBuffer.data() + src->width * 2; + line2[1] = lineBuffer.data() + src->width * 3; + line1[2] = lineBuffer.data() + src->width * 4; + line2[2] = lineBuffer.data() + src->width * 5; + pv[0] = lineBuffer.data() + src->width * 6; + pv[1] = lineBuffer.data() + src->width * 7; + pv[2] = lineBuffer.data() + src->width * 8; int endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian); for (int y = 0; y < src->height; y++) { @@ -2805,15 +2815,6 @@ static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt:: src_data += src->bytes_per_line; dest_data += dst->bytes_per_line; } - delete [] line1[0]; - delete [] line2[0]; - delete [] line1[1]; - delete [] line2[1]; - delete [] line1[2]; - delete [] line2[2]; - delete [] pv[0]; - delete [] pv[1]; - delete [] pv[2]; } else { // OrderedDither for (int y = 0; y < src->height; y++) { const QRgb *p = (const QRgb *)src_data; @@ -2846,8 +2847,8 @@ static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt:: const int trans = 216; Q_ASSERT(dst->colortable.size() > trans); dst->colortable[trans] = 0; - QImageData *mask = QImageData::create(QSize(src->width, src->height), QImage::Format_Mono); - dither_to_Mono(mask, src, flags, true); + QScopedPointer<QImageData> mask(QImageData::create(QSize(src->width, src->height), QImage::Format_Mono)); + dither_to_Mono(mask.data(), src, flags, true); uchar *dst_data = dst->data; const uchar *mask_data = mask->data; for (int y = 0; y < src->height; y++) { @@ -2859,7 +2860,6 @@ static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt:: dst_data += dst->bytes_per_line; } dst->has_alpha_clut = true; - delete mask; } #undef MAX_R @@ -2872,10 +2872,9 @@ static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt:: static void convert_ARGB_PM_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags) { - QImageData *tmp = QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32); - convert_ARGB_PM_to_ARGB(tmp, src, flags); - convert_RGB_to_Indexed8(dst, tmp, flags); - delete tmp; + QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32)); + convert_ARGB_PM_to_ARGB(tmp.data(), src, flags); + convert_RGB_to_Indexed8(dst, tmp.data(), flags); } static void convert_ARGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags) diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp index cae6922..0b07f5c 100644 --- a/src/gui/image/qimageiohandler.cpp +++ b/src/gui/image/qimageiohandler.cpp @@ -272,7 +272,6 @@ QImageIOHandler::QImageIOHandler(QImageIOHandlerPrivate &dd) */ QImageIOHandler::~QImageIOHandler() { - delete d_ptr; } /*! diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h index 02afbb8..83a605b 100644 --- a/src/gui/image/qimageiohandler.h +++ b/src/gui/image/qimageiohandler.h @@ -44,6 +44,7 @@ #include <QtCore/qplugin.h> #include <QtCore/qfactoryinterface.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -109,7 +110,7 @@ public: protected: QImageIOHandler(QImageIOHandlerPrivate &dd); - QImageIOHandlerPrivate *d_ptr; + QScopedPointer<QImageIOHandlerPrivate> d_ptr; private: Q_DISABLE_COPY(QImageIOHandler) }; diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 7b02dca..1136a97 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -132,7 +132,6 @@ QPicture::QPicture(int formatVersion) { Q_D(QPicture); d_ptr->q_ptr = this; - d->paintEngine = 0; if (formatVersion == 0) qWarning("QPicture: invalid format version 0"); @@ -155,7 +154,7 @@ QPicture::QPicture(int formatVersion) */ QPicture::QPicture(const QPicture &pic) - : QPaintDevice(), d_ptr(pic.d_ptr) + : QPaintDevice(), d_ptr(pic.d_ptr.data()) { d_func()->ref.ref(); } @@ -173,10 +172,6 @@ QPicture::QPicture(QPicturePrivate &dptr) */ QPicture::~QPicture() { - if (!d_func()->ref.deref()) { - delete d_func()->paintEngine; - delete d_func(); - } } /*! @@ -1032,9 +1027,7 @@ void QPicture::detach_helper() x->formatMinor = d->formatMinor; x->brect = d->brect; x->override_rect = d->override_rect; - if (!d->ref.deref()) - delete d; - d_ptr = x; + d_ptr.reset(x); } /*! @@ -1043,13 +1036,25 @@ void QPicture::detach_helper() */ QPicture& QPicture::operator=(const QPicture &p) { - qAtomicAssign<QPicturePrivate>(d_ptr, p.d_ptr); + d_ptr.assign(p.d_ptr.data()); return *this; } /*! \internal + Constructs a QPicturePrivate +*/ +QPicturePrivate::QPicturePrivate() + : in_memory_only(false), + q_ptr(0) +{ + ref = 1; +} + +/*! + \internal + Sets formatOk to false and resets the format version numbers to default */ @@ -1137,8 +1142,8 @@ bool QPicturePrivate::checkFormat() QPaintEngine *QPicture::paintEngine() const { if (!d_func()->paintEngine) - const_cast<QPicture*>(this)->d_func()->paintEngine = new QPicturePaintEngine; - return d_func()->paintEngine; + const_cast<QPicture*>(this)->d_func()->paintEngine.reset(new QPicturePaintEngine); + return d_func()->paintEngine.data(); } /***************************************************************************** diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h index fa770e0..1e80ab7 100644 --- a/src/gui/image/qpicture.h +++ b/src/gui/image/qpicture.h @@ -106,7 +106,7 @@ private: bool exec(QPainter *p, QDataStream &ds, int i); void detach_helper(); - QPicturePrivate *d_ptr; + QScopedSharedPointer<QPicturePrivate> d_ptr; friend class QPicturePaintEngine; friend class Q3Picture; friend class QAlphaPaintEngine; @@ -114,7 +114,7 @@ private: public: typedef QPicturePrivate* DataPtr; - inline DataPtr &data_ptr() { return d_ptr; } + inline DataPtr &data_ptr() { return d_ptr.data_ptr(); } }; Q_DECLARE_SHARED(QPicture) diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h index 0d08e65..f405d7f 100644 --- a/src/gui/image/qpicture_p.h +++ b/src/gui/image/qpicture_p.h @@ -143,7 +143,7 @@ public: PdcReservedStop = 199 // for Qt }; - inline QPicturePrivate() : in_memory_only(false), q_ptr(0) { ref = 1; } + QPicturePrivate(); QAtomicInt ref; bool checkFormat(); @@ -156,7 +156,7 @@ public: int formatMinor; QRect brect; QRect override_rect; - QPaintEngine *paintEngine; + QScopedPointer<QPaintEngine> paintEngine; bool in_memory_only; QList<QImage> image_list; QList<QPixmap> pixmap_list; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 0fad1c7..79b1f17 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -77,6 +77,10 @@ # include <private/qpixmap_x11_p.h> #endif +#if defined(Q_OS_SYMBIAN) +# include <private/qt_s60_p.h> +#endif + #include "qpixmap_raster_p.h" QT_BEGIN_NAMESPACE @@ -257,7 +261,12 @@ QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversio if (!qt_pixmap_thread_test()) return; - load(fileName, format, flags); + QT_TRY { + load(fileName, format, flags); + } QT_CATCH(...) { + deref(); + QT_RETHROW; + } } /*! @@ -305,12 +314,17 @@ QPixmap::QPixmap(const char * const xpm[]) if (!xpm) return; - QImage image(xpm); - if (!image.isNull()) { - if (data->pixelType() == QPixmapData::BitmapType) - *this = QBitmap::fromImage(image); - else - *this = fromImage(image); + QT_TRY { + QImage image(xpm); + if (!image.isNull()) { + if (data->pixelType() == QPixmapData::BitmapType) + *this = QBitmap::fromImage(image); + else + *this = fromImage(image); + } + } QT_CATCH(...) { + deref(); + QT_RETHROW; } } #endif @@ -838,6 +852,7 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers QImage image = QImageReader(fileName, format).read(); if (image.isNull()) return false; + QPixmap pm; if (data->pixelType() == QPixmapData::BitmapType) pm = QBitmap::fromImage(image, flags); @@ -1887,6 +1902,8 @@ int QPixmap::defaultDepth() return 32; // XXX #elif defined(Q_WS_MAC) return 32; +#elif defined(Q_OS_SYMBIAN) + return S60->screenDepth; #endif } @@ -1972,15 +1989,11 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) if (image.isNull()) return QPixmap(); - QPixmapData *data; QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem(); - if (gs) - data = gs->createPixmapData(QPixmapData::PixmapType); - else - data = QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType); - + QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::PixmapType) + : QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType)); data->fromImage(image, flags); - return QPixmap(data); + return QPixmap(data.take()); } /*! diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index db50ffd..bce1f5e 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -51,6 +51,10 @@ QT_BEGIN_HEADER +#if defined(Q_OS_SYMBIAN) +class CFbsBitmap; +#endif + QT_BEGIN_NAMESPACE QT_MODULE(Gui) @@ -59,7 +63,6 @@ class QImageWriter; class QColor; class QVariant; class QX11Info; - class QPixmapData; class Q_GUI_EXPORT QPixmap : public QPaintDevice @@ -152,6 +155,11 @@ public: static QPixmap fromMacCGImageRef(CGImageRef image); #endif +#if defined(Q_OS_SYMBIAN) + CFbsBitmap *toSymbianCFbsBitmap() const; + static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap); +#endif + inline QPixmap copy(int x, int y, int width, int height) const; QPixmap copy(const QRect &rect = QRect()) const; diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index f6049be..c0b2c58 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -172,9 +172,13 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage, } } #endif - w = image.d->width; - h = image.d->height; - d = image.d->depth; + if (image.d) { + w = image.d->width; + h = image.d->height; + d = image.d->depth; + } else { + w = h = d = 0; + } is_null = (w <= 0 || h <= 0); setSerialNumber(image.serialNumber()); diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp new file mode 100644 index 0000000..ab19924 --- /dev/null +++ b/src/gui/image/qpixmap_s60.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <exception> +#include <w32std.h> +#include <fbs.h> + +#include <private/qt_s60_p.h> +#include "qpixmap.h" +#include "qpixmap_raster_p.h" +#include <qwidget.h> + +QT_BEGIN_NAMESPACE + +QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) +{ + CWsScreenDevice* screenDevice = S60->screenDevice(); + TSize screenSize = screenDevice->SizeInPixels(); + + TSize srcSize; + // Find out if this is one of our windows. + QSymbianControl *sControl; + sControl = winId->MopGetObject(sControl); + if (sControl && sControl->widget()->windowType() == Qt::Desktop) { + // Grabbing desktop widget + srcSize = screenSize; + } else { + TPoint relativePos = winId->PositionRelativeToScreen(); + x += relativePos.iX; + y += relativePos.iY; + srcSize = winId->Size(); + } + + TRect srcRect(TPoint(x, y), srcSize); + // Clip to the screen + srcRect.Intersection(TRect(screenSize)); + + if (w > 0 && h > 0) { + TRect subRect(TPoint(x, y), TSize(w, h)); + // Clip to the subRect + srcRect.Intersection(subRect); + } + + if (srcRect.IsEmpty()) + return QPixmap(); + + TDisplayMode displayMode = screenDevice->DisplayMode(); + CFbsBitmap* temporary = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new + TInt error = temporary->Create(srcRect.Size(), displayMode); + if (error == KErrNone) + error = screenDevice->CopyScreenToBitmap(temporary, srcRect); + + if (error != KErrNone) { + CBase::Delete(temporary); + return QPixmap(); + } + + QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(temporary); + CBase::Delete(temporary); + return pixmap; +} + +/*! +\since 4.6 + +Returns a \c CFbsBitmap that is equivalent to the QPixmap by copying the data. + +It is the caller's responsibility to delete the \c CFbsBitmap after use. + +\warning This function is only available on Symbian OS. + +\sa fromSymbianCFbsBitmap() +*/ + +CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const +{ + if (isNull()) + return 0; + + TDisplayMode mode; + const QImage img = toImage(); + QImage::Format destFormat = img.format(); + switch (img.format()) { + case QImage::Format_Mono: + destFormat = QImage::Format_MonoLSB; + // Fall through intended + case QImage::Format_MonoLSB: + mode = EGray2; + break; + case QImage::Format_Indexed8: + if (img.isGrayscale()) + mode = EGray256; + else + mode = EColor256; + break; + case QImage::Format_RGB32: + mode = EColor16MU; + break; + case QImage::Format_ARGB6666_Premultiplied: + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_ARGB8555_Premultiplied: + destFormat = QImage::Format_ARGB32_Premultiplied; + // Fall through intended + case QImage::Format_ARGB32_Premultiplied: +#if !defined(__SERIES60_31__) && !defined(__S60_32__) + // ### TODO: Add runtime detection as well? + mode = EColor16MAP; + break; +#endif + destFormat = QImage::Format_ARGB32; + // Fall through intended + case QImage::Format_ARGB32: + mode = EColor16MA; + break; + case QImage::Format_RGB555: + destFormat = QImage::Format_RGB16; + // Fall through intended + case QImage::Format_RGB16: + mode = EColor64K; + break; + case QImage::Format_RGB666: + destFormat = QImage::Format_RGB888; + // Fall through intended + case QImage::Format_RGB888: + mode = EColor16M; + break; + case QImage::Format_RGB444: + mode = EColor4K; + break; + case QImage::Format_Invalid: + return 0; + default: + qWarning("Image format not supported: %d", img.format()); + return 0; + } + + CFbsBitmap* bitmap = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new + TSize size(width(), height()); + if (bitmap->Create(size, mode) != KErrNone) { + CBase::Delete(bitmap); + return 0; + } + + const QImage converted = img.convertToFormat(destFormat); + + bitmap->LockHeap(); + const uchar *sptr = converted.bits(); + uchar *dptr = (uchar*)bitmap->DataAddress(); + Mem::Copy(dptr, sptr, converted.numBytes()); + bitmap->UnlockHeap(); + return bitmap; +} + +/*! +\since 4.6 + +Returns a QPixmap that is equivalent to the \c CFbsBitmap by copying the data. +If the CFbsBitmap is not valid or is compressed in memory, this function will +return a null QPixmap. + +\warning This function is only available on Symbian OS. + +\sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} +*/ + +QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) +{ + if (!bitmap) + return QPixmap(); + + int width = bitmap->SizeInPixels().iWidth; + int height = bitmap->SizeInPixels().iHeight; + + if (width <= 0 || height <= 0 || bitmap->IsCompressedInRAM()) + return QPixmap(); + + TDisplayMode displayMode = bitmap->DisplayMode(); + QImage::Format format = qt_TDisplayMode2Format(displayMode); + int bytesPerLine = CFbsBitmap::ScanLineLength(width, displayMode); + bitmap->LockHeap(); + QImage image = QImage((const uchar*)bitmap->DataAddress(), width, height, bytesPerLine, format); + if (displayMode == EGray2) { + image.setNumColors(2); + image.setColor(0, QColor(Qt::color0).rgba()); + image.setColor(1, QColor(Qt::color1).rgba()); + } else if (displayMode == EGray256) { + for (int i=0; i < 256; ++i) + image.setColor(i, qRgb(i, i, i)); + }else if (displayMode == EColor256) { + const TColor256Util *palette = TColor256Util::Default(); + for (int i=0; i < 256; ++i) + image.setColor(i, (QRgb)(palette->Color256(i).Value())); + } + QPixmap pixmap = QPixmap::fromImage(image.copy()); + bitmap->UnlockHeap(); + return pixmap; +} + +QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index cef5c49..b8d6ac1 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -85,7 +85,9 @@ QT_BEGIN_NAMESPACE \sa QCache, QPixmap */ -#if defined(Q_WS_QWS) || defined(Q_WS_WINCE) +#if defined(Q_OS_SYMBIAN) +static int cache_limit = 1024; // 1048 KB cache limit for symbian +#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE) static int cache_limit = 2048; // 2048 KB cache limit for embedded #else static int cache_limit = 10240; // 10 MB cache limit for desktop @@ -365,7 +367,8 @@ void QPMCache::resizeKeyArray(int size) { if (size <= keyArraySize || size == 0) return; - keyArray = reinterpret_cast<int *>(realloc(keyArray, size * sizeof(int))); + keyArray = q_check_ptr(reinterpret_cast<int *>(realloc(keyArray, + size * sizeof(int)))); for (int i = keyArraySize; i != size; ++i) keyArray[i] = i + 1; keyArraySize = size; @@ -607,7 +610,12 @@ void QPixmapCache::remove(const Key &key) void QPixmapCache::clear() { - pm_cache()->clear(); + QT_TRY { + pm_cache()->clear(); + } QT_CATCH(const std::bad_alloc &) { + // if we ran out of memory during pm_cache(), it's no leak, + // so just ignore it. + } } QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdatafactory.cpp b/src/gui/image/qpixmapdatafactory.cpp index 2af68c2..2e36b2c 100644 --- a/src/gui/image/qpixmapdatafactory.cpp +++ b/src/gui/image/qpixmapdatafactory.cpp @@ -47,7 +47,7 @@ #ifdef Q_WS_X11 # include <private/qpixmap_x11_p.h> #endif -#ifdef Q_WS_WIN +#if defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) # include <private/qpixmap_raster_p.h> #endif #ifdef Q_WS_MAC @@ -75,7 +75,7 @@ QPixmapData* QSimplePixmapDataFactory::create(QPixmapData::PixelType type) #if defined(Q_WS_X11) return new QX11PixmapData(type); -#elif defined(Q_WS_WIN) +#elif defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) return new QRasterPixmapData(type); #elif defined(Q_WS_MAC) return new QMacPixmapData(type); |