summaryrefslogtreecommitdiffstats
path: root/src/gui/image
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image')
-rw-r--r--src/gui/image/image.pri3
-rw-r--r--src/gui/image/qbitmap.cpp11
-rw-r--r--src/gui/image/qimage.cpp71
-rw-r--r--src/gui/image/qimageiohandler.cpp1
-rw-r--r--src/gui/image/qimageiohandler.h3
-rw-r--r--src/gui/image/qpicture.cpp29
-rw-r--r--src/gui/image/qpicture.h4
-rw-r--r--src/gui/image/qpicture_p.h4
-rw-r--r--src/gui/image/qpixmap.cpp41
-rw-r--r--src/gui/image/qpixmap.h10
-rw-r--r--src/gui/image/qpixmap_raster.cpp10
-rw-r--r--src/gui/image/qpixmap_s60.cpp236
-rw-r--r--src/gui/image/qpixmapcache.cpp14
-rw-r--r--src/gui/image/qpixmapdatafactory.cpp4
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);