summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-02-08 22:31:15 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-02-08 22:31:15 (GMT)
commit0d62d8e14433f1f0feebb7d151e9a397589be35a (patch)
tree4e33569d2d4273a1dbf93123f45e8ed815e92a44 /src
parent0f4103703ef772cd4ed357378473f7d416a79899 (diff)
parente30d5a56506c4f677d18f9cb867f0bd50615b197 (diff)
downloadQt-0d62d8e14433f1f0feebb7d151e9a397589be35a.zip
Qt-0d62d8e14433f1f0feebb7d151e9a397589be35a.tar.gz
Qt-0d62d8e14433f1f0feebb7d151e9a397589be35a.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-qml
Diffstat (limited to 'src')
-rw-r--r--src/declarative/graphicsitems/qmlgraphicstextinput.cpp21
-rw-r--r--src/declarative/graphicsitems/qmlgraphicstextinput_p.h2
-rw-r--r--src/declarative/qml/parser/qmljsglobal_p.h4
-rw-r--r--src/declarative/qml/parser/qmljsgrammar_p.h2
-rw-r--r--src/declarative/qml/qmlengine.cpp19
-rw-r--r--src/declarative/qml/qmlxmlhttprequest.cpp90
-rw-r--r--src/declarative/util/qmlopenmetaobject.cpp17
-rw-r--r--src/declarative/util/qmlopenmetaobject_p.h7
-rw-r--r--src/gui/widgets/qvalidator.h5
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp574
10 files changed, 183 insertions, 558 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp
index 427f9ff..6d79c7a 100644
--- a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp
@@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE
QML_DEFINE_TYPE(Qt,4,6,TextInput,QmlGraphicsTextInput);
QML_DEFINE_NOCREATE_TYPE(QValidator);
QML_DEFINE_TYPE(Qt,4,6,QIntValidator,QIntValidator);
+QML_DEFINE_TYPE(Qt,4,6,QDoubleValidator,QDoubleValidator);
+QML_DEFINE_TYPE(Qt,4,6,QRegExpValidator,QRegExpValidator);
/*!
\qmlclass TextInput QmlGraphicsTextInput
@@ -437,6 +439,25 @@ void QmlGraphicsTextInput::setFocusOnPress(bool b)
an acceptable or intermediate state. The accepted signal will only be sent
if the text is in an acceptable state when enter is pressed.
+ Currently supported validators are QIntValidator, QDoubleValidator and
+ QRegExpValidator. For details, refer to their C++ documentation and remember
+ that all Q_PROPERTIES are accessible from Qml. A brief usage guide follows:
+
+ QIntValidator and QDoubleValidator both are controllable through two properties,
+ top and bottom. The difference is that for QIntValidator the top and bottom properties
+ should be integers, and for QDoubleValidator they should be doubles. QRegExpValidator
+ has a single string property, regExp, which should be set to the regular expression to
+ be used for validation. An example of using validators is shown below, which allows
+ input of integers between 11 and 31 into the text input:
+
+ \code
+ import Qt 4.6
+ TextInput{
+ validator: QIntValidator{bottom: 11; top: 31;}
+ focus: true
+ }
+ \endcode
+
\sa acceptableInput, inputMask
*/
QValidator* QmlGraphicsTextInput::validator() const
diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput_p.h b/src/declarative/graphicsitems/qmlgraphicstextinput_p.h
index 56f16a5..68f28f8 100644
--- a/src/declarative/graphicsitems/qmlgraphicstextinput_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicstextinput_p.h
@@ -220,6 +220,8 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QmlGraphicsTextInput)
QML_DECLARE_TYPE(QValidator)
QML_DECLARE_TYPE(QIntValidator)
+QML_DECLARE_TYPE(QDoubleValidator)
+QML_DECLARE_TYPE(QRegExpValidator)
QT_END_HEADER
diff --git a/src/declarative/qml/parser/qmljsglobal_p.h b/src/declarative/qml/parser/qmljsglobal_p.h
index 59762ff..49e50cf 100644
--- a/src/declarative/qml/parser/qmljsglobal_p.h
+++ b/src/declarative/qml/parser/qmljsglobal_p.h
@@ -47,13 +47,13 @@
# define QT_QML_BEGIN_NAMESPACE
# define QT_QML_END_NAMESPACE
-# ifdef QML_BUILD_LIB
+# ifdef QMLJS_BUILD_DIR
# define QML_PARSER_EXPORT Q_DECL_EXPORT
# elif QML_BUILD_STATIC_LIB
# define QML_PARSER_EXPORT
# else
# define QML_PARSER_EXPORT Q_DECL_IMPORT
-# endif // QML_BUILD_LIB
+# endif // QMLJS_BUILD_DIR
#else // !QT_CREATOR
# define QT_QML_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/parser/qmljsgrammar_p.h b/src/declarative/qml/parser/qmljsgrammar_p.h
index 903e2c4..c2e2693 100644
--- a/src/declarative/qml/parser/qmljsgrammar_p.h
+++ b/src/declarative/qml/parser/qmljsgrammar_p.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QmlJSGrammar
{
public:
- enum {
+ enum VariousConstants {
EOF_SYMBOL = 0,
REDUCE_HERE = 99,
SHIFT_THERE = 98,
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 5624da1..bb26d30 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -110,6 +110,25 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
QML_DEFINE_TYPE(Qt,4,6,QtObject,QObject)
+/*!
+ \qmlclass QtObject QObject
+ \brief The QtObject element is the most basic element in QML
+
+ The QtObject element is a non-visual element which contains only
+ the objectName property. It is useful for when you need an extremely
+ lightweight element to place your own custom properties in.
+
+ It can also be useful for C++ integration, as it is just a plain QObject. See
+ the QObject documentation for further details.
+*/
+/*!
+ \qmlproperty string QtObject::objectName
+ This property allows you to give a name to this specific object instance.
+
+ See \l{scripting.html#accessing-child-qobjects}{Accessing Child QObjects}
+ in the scripting documentation for details how objectName can be used from
+ scripts.
+*/
struct StaticQtMetaObject : public QObject
{
diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp
index 86bec20..1883d1b 100644
--- a/src/declarative/qml/qmlxmlhttprequest.cpp
+++ b/src/declarative/qml/qmlxmlhttprequest.cpp
@@ -943,21 +943,19 @@ public:
QmlXMLHttpRequest(QNetworkAccessManager *manager);
virtual ~QmlXMLHttpRequest();
- QScriptValue callback() const;
- void setCallback(const QScriptValue &);
-
bool sendFlag() const;
bool errorFlag() const;
quint32 readyState() const;
int replyStatus() const;
QString replyStatusText() const;
- QScriptValue open(const QString &, const QUrl &);
+ QScriptValue open(QScriptValue *me, const QString &, const QUrl &);
+
void addHeader(const QString &, const QString &);
QString header(const QString &name);
QString headers();
- QScriptValue send(const QByteArray &);
- QScriptValue abort();
+ QScriptValue send(QScriptValue *me, const QByteArray &);
+ QScriptValue abort(QScriptValue *me);
QString responseBody() const;
private slots:
@@ -982,8 +980,9 @@ private:
HeadersList m_headersList;
void fillHeadersList();
- QScriptValue dispatchCallback();
- QScriptValue m_callback;
+ QScriptValue m_me; // Set to the data object while a send() is ongoing (to access the callback)
+
+ QScriptValue dispatchCallback(QScriptValue *me);
void printError(const QScriptValue&);
int m_status;
@@ -1007,16 +1006,6 @@ QmlXMLHttpRequest::~QmlXMLHttpRequest()
destroyNetwork();
}
-QScriptValue QmlXMLHttpRequest::callback() const
-{
- return m_callback;
-}
-
-void QmlXMLHttpRequest::setCallback(const QScriptValue &c)
-{
- m_callback = c;
-}
-
bool QmlXMLHttpRequest::sendFlag() const
{
return m_sendFlag;
@@ -1042,7 +1031,7 @@ QString QmlXMLHttpRequest::replyStatusText() const
return m_statusText;
}
-QScriptValue QmlXMLHttpRequest::open(const QString &method, const QUrl &url)
+QScriptValue QmlXMLHttpRequest::open(QScriptValue *me, const QString &method, const QUrl &url)
{
destroyNetwork();
m_sendFlag = false;
@@ -1051,7 +1040,7 @@ QScriptValue QmlXMLHttpRequest::open(const QString &method, const QUrl &url)
m_method = method;
m_url = url;
m_state = Opened;
- return dispatchCallback();
+ return dispatchCallback(me);
}
void QmlXMLHttpRequest::addHeader(const QString &name, const QString &value)
@@ -1155,19 +1144,20 @@ void QmlXMLHttpRequest::requestFromUrl(const QUrl &url)
this, SLOT(finished()));
}
-QScriptValue QmlXMLHttpRequest::send(const QByteArray &data)
+QScriptValue QmlXMLHttpRequest::send(QScriptValue *me, const QByteArray &data)
{
m_errorFlag = false;
m_sendFlag = true;
m_redirectCount = 0;
m_data = data;
+ m_me = *me;
requestFromUrl(m_url);
return QScriptValue();
}
-QScriptValue QmlXMLHttpRequest::abort()
+QScriptValue QmlXMLHttpRequest::abort(QScriptValue *me)
{
destroyNetwork();
m_responseEntityBody = QByteArray();
@@ -1180,7 +1170,7 @@ QScriptValue QmlXMLHttpRequest::abort()
m_state = Done;
m_sendFlag = false;
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(me);
if (cbv.isError()) return cbv;
}
@@ -1200,7 +1190,7 @@ void QmlXMLHttpRequest::downloadProgress(qint64 bytes)
if (m_state < HeadersReceived) {
m_state = HeadersReceived;
fillHeadersList ();
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(&m_me);
if (cbv.isError()) printError(cbv);
}
@@ -1208,7 +1198,7 @@ void QmlXMLHttpRequest::downloadProgress(qint64 bytes)
m_responseEntityBody.append(m_network->readAll());
if (wasEmpty && !m_responseEntityBody.isEmpty()) {
m_state = Loading;
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(&m_me);
if (cbv.isError()) printError(cbv);
}
}
@@ -1233,14 +1223,14 @@ void QmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
error == QNetworkReply::AuthenticationRequiredError ||
error == QNetworkReply::ContentReSendError) {
m_state = Loading;
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(&m_me);
if (cbv.isError()) printError(cbv);
} else {
m_errorFlag = true;
}
m_state = Done;
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(&m_me);
if (cbv.isError()) printError(cbv);
}
@@ -1266,7 +1256,7 @@ void QmlXMLHttpRequest::finished()
if (m_state < HeadersReceived) {
m_state = HeadersReceived;
fillHeadersList ();
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(&m_me);
if (cbv.isError()) printError(cbv);
}
m_responseEntityBody.append(m_network->readAll());
@@ -1274,12 +1264,14 @@ void QmlXMLHttpRequest::finished()
destroyNetwork();
if (m_state < Loading) {
m_state = Loading;
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(&m_me);
if (cbv.isError()) printError(cbv);
}
m_state = Done;
- QScriptValue cbv = dispatchCallback();
+ QScriptValue cbv = dispatchCallback(&m_me);
if (cbv.isError()) printError(cbv);
+
+ m_me = QScriptValue();
}
@@ -1288,9 +1280,10 @@ QString QmlXMLHttpRequest::responseBody() const
return QString::fromUtf8(m_responseEntityBody);
}
-QScriptValue QmlXMLHttpRequest::dispatchCallback()
+QScriptValue QmlXMLHttpRequest::dispatchCallback(QScriptValue *me)
{
- return m_callback.call();
+ QScriptValue v = me->property(QLatin1String("callback"));
+ return v.call();
}
void QmlXMLHttpRequest::printError(const QScriptValue& sv)
@@ -1312,7 +1305,8 @@ void QmlXMLHttpRequest::destroyNetwork()
// XMLHttpRequest methods
static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngine *engine)
{
- QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ QScriptValue dataObject = context->thisObject().data();
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject());
if (!request)
THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1354,7 +1348,7 @@ static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngin
if (!username.isNull()) url.setUserName(username);
if (!password.isNull()) url.setPassword(password);
- return request->open(method, url);
+ return request->open(&dataObject, method, url);
}
static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context, QScriptEngine *engine)
@@ -1405,9 +1399,10 @@ static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context,
return engine->undefinedValue();
}
-static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngine *engine)
+static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngine *)
{
- QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ QScriptValue dataObject = context->thisObject().data();
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject());
if (!request)
THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1421,16 +1416,17 @@ static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngin
if (context->argumentCount() > 0)
data = context->argument(0).toString().toUtf8();
- return request->send(data);
+ return request->send(&dataObject, data);
}
static QScriptValue qmlxmlhttprequest_abort(QScriptContext *context, QScriptEngine *)
{
- QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ QScriptValue dataObject = context->thisObject().data();
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject());
if (!request)
THROW_REFERENCE("Not an XMLHttpRequest object");
- return request->abort();
+ return request->abort(&dataObject);
}
static QScriptValue qmlxmlhttprequest_getResponseHeader(QScriptContext *context, QScriptEngine *engine)
@@ -1545,15 +1541,19 @@ static QScriptValue qmlxmlhttprequest_responseXML(QScriptContext *context, QScri
static QScriptValue qmlxmlhttprequest_onreadystatechange(QScriptContext *context, QScriptEngine *engine)
{
- Q_UNUSED(engine)
- QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ Q_UNUSED(engine);
+ QScriptValue dataObject = context->thisObject().data();
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(dataObject.toQObject());
if (!request)
THROW_REFERENCE("Not an XMLHttpRequest object");
- if (context->argumentCount())
- request->setCallback(context->argument(0));
-
- return request->callback();
+ if (context->argumentCount()) {
+ QScriptValue v = context->argument(0);
+ dataObject.setProperty(QLatin1String("callback"), v);
+ return v;
+ } else {
+ return dataObject.property(QLatin1String("callback"));
+ }
}
// Constructor
diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp
index 373be2d..1be81de 100644
--- a/src/declarative/util/qmlopenmetaobject.cpp
+++ b/src/declarative/util/qmlopenmetaobject.cpp
@@ -81,6 +81,17 @@ QmlOpenMetaObjectType::~QmlOpenMetaObjectType()
delete d;
}
+
+int QmlOpenMetaObjectType::propertyOffset() const
+{
+ return d->propertyOffset;
+}
+
+int QmlOpenMetaObjectType::signalOffset() const
+{
+ return d->signalOffset;
+}
+
int QmlOpenMetaObjectType::createProperty(const QByteArray &name)
{
int id = d->mob.propertyCount();
@@ -226,6 +237,11 @@ int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
}
}
+QAbstractDynamicMetaObject *QmlOpenMetaObject::parent() const
+{
+ return d->parent;
+}
+
QVariant QmlOpenMetaObject::value(int id) const
{
return d->getData(id);
@@ -293,6 +309,7 @@ void QmlOpenMetaObject::setCached(bool c)
}
}
+
int QmlOpenMetaObject::createProperty(const char *name, const char *)
{
if (d->autoCreate)
diff --git a/src/declarative/util/qmlopenmetaobject_p.h b/src/declarative/util/qmlopenmetaobject_p.h
index 450f258..c6da71a 100644
--- a/src/declarative/util/qmlopenmetaobject_p.h
+++ b/src/declarative/util/qmlopenmetaobject_p.h
@@ -57,7 +57,7 @@ QT_MODULE(Declarative)
class QmlEngine;
class QMetaPropertyBuilder;
class QmlOpenMetaObjectTypePrivate;
-class QmlOpenMetaObjectType : public QmlRefCount
+class Q_DECLARATIVE_EXPORT QmlOpenMetaObjectType : public QmlRefCount
{
public:
QmlOpenMetaObjectType(const QMetaObject *base, QmlEngine *engine);
@@ -65,6 +65,9 @@ public:
int createProperty(const QByteArray &name);
+ int propertyOffset() const;
+ int signalOffset() const;
+
protected:
virtual void propertyCreated(int, QMetaPropertyBuilder &);
@@ -108,6 +111,8 @@ protected:
virtual void propertyWrite(int);
virtual void propertyCreated(int, QMetaPropertyBuilder &);
+ QAbstractDynamicMetaObject *parent() const;
+
private:
QmlOpenMetaObjectPrivate *d;
friend class QmlOpenMetaObjectType;
diff --git a/src/gui/widgets/qvalidator.h b/src/gui/widgets/qvalidator.h
index e996a01..63734ca 100644
--- a/src/gui/widgets/qvalidator.h
+++ b/src/gui/widgets/qvalidator.h
@@ -137,10 +137,11 @@ class Q_GUI_EXPORT QDoubleValidator : public QValidator
Q_PROPERTY(double bottom READ bottom WRITE setBottom)
Q_PROPERTY(double top READ top WRITE setTop)
Q_PROPERTY(int decimals READ decimals WRITE setDecimals)
+ Q_ENUMS(Notation)
Q_PROPERTY(Notation notation READ notation WRITE setNotation)
public:
- explicit QDoubleValidator(QObject * parent);
+ explicit QDoubleValidator(QObject * parent = 0);
QDoubleValidator(double bottom, double top, int decimals, QObject * parent);
~QDoubleValidator();
@@ -184,7 +185,7 @@ class Q_GUI_EXPORT QRegExpValidator : public QValidator
Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp)
public:
- explicit QRegExpValidator(QObject *parent);
+ explicit QRegExpValidator(QObject *parent = 0);
QRegExpValidator(const QRegExp& rx, QObject *parent);
~QRegExpValidator();
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 6cb93ad..4b4712c 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -52,8 +52,6 @@
#undef FAR
#endif
-// hw: optimize smoothscaler for returning 24-bit images
-
// including jpeglib.h seems to be a little messy
extern "C" {
// mingw includes rpcndr.h but does not define boolean
@@ -76,433 +74,6 @@ extern "C" {
QT_BEGIN_NAMESPACE
-//#define QT_NO_IMAGE_SMOOTHSCALE
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
-class QImageSmoothScalerPrivate;
-class QImageSmoothScaler
-{
-public:
- QImageSmoothScaler(const int w, const int h, const QImage &src);
- QImageSmoothScaler(const int srcWidth, const int srcHeight,
- const int dstWidth, const int dstHeight);
-
- virtual ~QImageSmoothScaler(void);
-
- QImage scale();
-
-private:
- QImageSmoothScalerPrivate *d;
- virtual QRgb *scanLine(const int line = 0, const QImage *src = 0);
-};
-
-class QImageSmoothScalerPrivate
-{
-public:
- int cols;
- int newcols;
- int rows;
- int newrows;
- bool hasAlpha;
-
- const QImage *src;
-
- void setup(const int srcWidth, const int srcHeight, const int dstWidth,
- const int dstHeight, bool hasAlphaChannel);
-};
-
-QImageSmoothScaler::QImageSmoothScaler(const int w, const int h,
- const QImage &src)
-{
- d = new QImageSmoothScalerPrivate;
-
- d->setup(src.width(), src.height(), w, h, src.hasAlphaChannel() );
- this->d->src = &src;
-}
-
-QImageSmoothScaler::QImageSmoothScaler(const int srcWidth, const int srcHeight,
- const int dstWidth, const int dstHeight)
-{
- d = new QImageSmoothScalerPrivate;
- d->setup(srcWidth, srcHeight, dstWidth, dstHeight, 0);
-}
-
-void QImageSmoothScalerPrivate::setup(const int srcWidth, const int srcHeight,
- const int dstWidth, const int dstHeight,
- bool hasAlphaChannel)
-{
- cols = srcWidth;
- rows = srcHeight;
- newcols = dstWidth;
- newrows = dstHeight;
- hasAlpha = hasAlphaChannel;
-}
-
-QImageSmoothScaler::~QImageSmoothScaler()
-{
- delete d;
-}
-
-inline QRgb *QImageSmoothScaler::scanLine(const int line, const QImage *src)
-{
- return (QRgb*)src->scanLine(line);
-}
-
-/*
- This function uses code based on pnmscale.c by Jef Poskanzer.
-
- pnmscale.c - read a portable anymap and scale it
-
- Copyright (C) 1989, 1991 by Jef Poskanzer.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation. This software is provided "as is" without express or
- implied warranty.
-*/
-
-QImage QImageSmoothScaler::scale()
-{
- long SCALE;
- long HALFSCALE;
- QRgb *xelrow = 0;
- QRgb *tempxelrow = 0;
- QRgb *xP;
- QRgb *nxP;
- int row, rowsread;
- int col, needtoreadrow;
- uchar maxval = 255;
- qreal xscale, yscale;
- long sxscale, syscale;
- long fracrowtofill, fracrowleft;
- long *as;
- long *rs;
- long *gs;
- long *bs;
- int rowswritten = 0;
- QImage dst;
-
- if (d->cols > 4096) {
- SCALE = 4096;
- HALFSCALE = 2048;
- } else {
- int fac = 4096;
- while (d->cols * fac > 4096)
- fac /= 2;
-
- SCALE = fac * d->cols;
- HALFSCALE = fac * d->cols / 2;
- }
-
- xscale = (qreal)d->newcols / (qreal)d->cols;
- yscale = (qreal)d->newrows / (qreal)d->rows;
- sxscale = (long)(xscale * SCALE);
- syscale = (long)(yscale * SCALE);
-
- // shortcut Y scaling if possible
- if (d->newrows != d->rows)
- tempxelrow = new QRgb[d->cols];
-
- if (d->hasAlpha) {
- as = new long[d->cols];
- for (col = 0; col < d->cols; ++col)
- as[col] = HALFSCALE;
- } else {
- as = 0;
- }
- rs = new long[d->cols];
- gs = new long[d->cols];
- bs = new long[d->cols];
- rowsread = 0;
- fracrowleft = syscale;
- needtoreadrow = 1;
- for (col = 0; col < d->cols; ++col)
- rs[col] = gs[col] = bs[col] = HALFSCALE;
- fracrowtofill = SCALE;
-
- dst = QImage(d->newcols, d->newrows, d->hasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32);
-
- for (row = 0; row < d->newrows; ++row) {
- // First scale Y from xelrow into tempxelrow.
- if (d->newrows == d->rows) {
- // shortcut Y scaling if possible
- tempxelrow = xelrow = scanLine(rowsread++, d->src);
- } else {
- while (fracrowleft < fracrowtofill) {
- if (needtoreadrow && rowsread < d->rows)
- xelrow = scanLine(rowsread++, d->src);
- for (col = 0, xP = xelrow; col < d->cols; ++col, ++xP) {
- if (as) {
- as[col] += fracrowleft * qAlpha(*xP);
- rs[col] += fracrowleft * qRed(*xP) * qAlpha(*xP) / 255;
- gs[col] += fracrowleft * qGreen(*xP) * qAlpha(*xP) / 255;
- bs[col] += fracrowleft * qBlue(*xP) * qAlpha(*xP) / 255;
- } else {
- rs[col] += fracrowleft * qRed(*xP);
- gs[col] += fracrowleft * qGreen(*xP);
- bs[col] += fracrowleft * qBlue(*xP);
- }
- }
- fracrowtofill -= fracrowleft;
- fracrowleft = syscale;
- needtoreadrow = 1;
- }
- // Now fracrowleft is >= fracrowtofill, so we can produce a row.
- if (needtoreadrow && rowsread < d->rows) {
- xelrow = scanLine(rowsread++, d->src);
- needtoreadrow = 0;
- }
- for (col = 0, xP = xelrow, nxP = tempxelrow; col < d->cols; ++col, ++xP, ++nxP) {
- register long a, r, g, b;
-
- if (as) {
- r = rs[col] + fracrowtofill * qRed(*xP) * qAlpha(*xP) / 255;
- g = gs[col] + fracrowtofill * qGreen(*xP) * qAlpha(*xP) / 255;
- b = bs[col] + fracrowtofill * qBlue(*xP) * qAlpha(*xP) / 255;
- a = as[col] + fracrowtofill * qAlpha(*xP);
- if (a) {
- r = r * 255 / a * SCALE;
- g = g * 255 / a * SCALE;
- b = b * 255 / a * SCALE;
- }
- } else {
- r = rs[col] + fracrowtofill * qRed(*xP);
- g = gs[col] + fracrowtofill * qGreen(*xP);
- b = bs[col] + fracrowtofill * qBlue(*xP);
- a = 0; // unwarn
- }
- r /= SCALE;
- if (r > maxval)
- r = maxval;
- g /= SCALE;
- if (g > maxval)
- g = maxval;
- b /= SCALE;
- if (b > maxval)
- b = maxval;
- if (as) {
- a /= SCALE;
- if (a > maxval)
- a = maxval;
- *nxP = qRgba((int)r, (int)g, (int)b, (int)a);
- as[col] = HALFSCALE;
- } else {
- *nxP = qRgb((int)r, (int)g, (int)b);
- }
- rs[col] = gs[col] = bs[col] = HALFSCALE;
- }
- fracrowleft -= fracrowtofill;
- if (fracrowleft == 0) {
- fracrowleft = syscale;
- needtoreadrow = 1;
- }
- fracrowtofill = SCALE;
- }
-
- // Now scale X from tempxelrow into dst and write it out.
- if (d->newcols == d->cols) {
- // shortcut X scaling if possible
- memcpy(dst.scanLine(rowswritten++), tempxelrow, d->newcols * 4);
- } else {
- register long a, r, g, b;
- register long fraccoltofill, fraccolleft = 0;
- register int needcol;
-
- nxP = (QRgb *)dst.scanLine(rowswritten++);
- QRgb *nxPEnd = nxP + d->newcols;
- fraccoltofill = SCALE;
- a = r = g = b = HALFSCALE;
- needcol = 0;
- for (col = 0, xP = tempxelrow; col < d->cols; ++col, ++xP) {
- fraccolleft = sxscale;
- while (fraccolleft >= fraccoltofill) {
- if (needcol) {
- ++nxP;
- a = r = g = b = HALFSCALE;
- }
- if (as) {
- r += fraccoltofill * qRed(*xP) * qAlpha(*xP) / 255;
- g += fraccoltofill * qGreen(*xP) * qAlpha(*xP) / 255;
- b += fraccoltofill * qBlue(*xP) * qAlpha(*xP) / 255;
- a += fraccoltofill * qAlpha(*xP);
- if (a) {
- r = r * 255 / a * SCALE;
- g = g * 255 / a * SCALE;
- b = b * 255 / a * SCALE;
- }
- } else {
- r += fraccoltofill * qRed(*xP);
- g += fraccoltofill * qGreen(*xP);
- b += fraccoltofill * qBlue(*xP);
- }
- r /= SCALE;
- if (r > maxval)
- r = maxval;
- g /= SCALE;
- if (g > maxval)
- g = maxval;
- b /= SCALE;
- if (b > maxval)
- b = maxval;
- if (as) {
- a /= SCALE;
- if (a > maxval)
- a = maxval;
- *nxP = qRgba((int)r, (int)g, (int)b, (int)a);
- } else {
- *nxP = qRgb((int)r, (int)g, (int)b);
- }
- fraccolleft -= fraccoltofill;
- fraccoltofill = SCALE;
- needcol = 1;
- }
- if (fraccolleft > 0) {
- if (needcol) {
- ++nxP;
- a = r = g = b = HALFSCALE;
- needcol = 0;
- }
- if (as) {
- a += fraccolleft * qAlpha(*xP);
- r += fraccolleft * qRed(*xP) * qAlpha(*xP) / 255;
- g += fraccolleft * qGreen(*xP) * qAlpha(*xP) / 255;
- b += fraccolleft * qBlue(*xP) * qAlpha(*xP) / 255;
- } else {
- r += fraccolleft * qRed(*xP);
- g += fraccolleft * qGreen(*xP);
- b += fraccolleft * qBlue(*xP);
- }
- fraccoltofill -= fraccolleft;
- }
- }
- if (fraccoltofill > 0) {
- --xP;
- if (as) {
- a += fraccolleft * qAlpha(*xP);
- r += fraccoltofill * qRed(*xP) * qAlpha(*xP) / 255;
- g += fraccoltofill * qGreen(*xP) * qAlpha(*xP) / 255;
- b += fraccoltofill * qBlue(*xP) * qAlpha(*xP) / 255;
- if (a) {
- r = r * 255 / a * SCALE;
- g = g * 255 / a * SCALE;
- b = b * 255 / a * SCALE;
- }
- } else {
- r += fraccoltofill * qRed(*xP);
- g += fraccoltofill * qGreen(*xP);
- b += fraccoltofill * qBlue(*xP);
- }
- }
- if (nxP < nxPEnd) {
- r /= SCALE;
- if (r > maxval)
- r = maxval;
- g /= SCALE;
- if (g > maxval)
- g = maxval;
- b /= SCALE;
- if (b > maxval)
- b = maxval;
- if (as) {
- a /= SCALE;
- if (a > maxval)
- a = maxval;
- *nxP = qRgba((int)r, (int)g, (int)b, (int)a);
- } else {
- *nxP = qRgb((int)r, (int)g, (int)b);
- }
- while (++nxP != nxPEnd)
- nxP[0] = nxP[-1];
- }
- }
- }
-
- if (d->newrows != d->rows && tempxelrow)// Robust, tempxelrow might be 0 1 day
- delete [] tempxelrow;
- if (as) // Avoid purify complaint
- delete [] as;
- if (rs) // Robust, rs might be 0 one day
- delete [] rs;
- if (gs) // Robust, gs might be 0 one day
- delete [] gs;
- if (bs) // Robust, bs might be 0 one day
- delete [] bs;
-
- return dst;
-}
-
-class jpegSmoothScaler : public QImageSmoothScaler
-{
-public:
- jpegSmoothScaler(struct jpeg_decompress_struct *info, const QSize& dstSize, const QRect& clipRect)
- : QImageSmoothScaler(clipRect.width(), clipRect.height(),
- dstSize.width(), dstSize.height())
- {
- cinfo = info;
- clip = clipRect;
- imageCache = QImage(info->output_width, 1, QImage::Format_RGB32);
- }
-
-private:
- QRect clip;
- QImage imageCache;
- struct jpeg_decompress_struct *cinfo;
-
- QRgb *scanLine(const int line = 0, const QImage *src = 0)
- {
- QRgb *out;
- uchar *in;
-
- Q_UNUSED(line);
- Q_UNUSED(src);
-
- uchar* data = imageCache.bits();
-
- // Read ahead if we haven't reached the first clipped scanline yet.
- while (int(cinfo->output_scanline) < clip.y() &&
- cinfo->output_scanline < cinfo->output_height)
- jpeg_read_scanlines(cinfo, &data, 1);
-
- // Read the next scanline. We assume that "line"
- // will never be >= clip.height().
- jpeg_read_scanlines(cinfo, &data, 1);
- if (cinfo->output_scanline == cinfo->output_height)
- jpeg_finish_decompress(cinfo);
-
- out = ((QRgb*)data) + clip.x();
-
- //
- // The smooth scale algorithm only works on 32-bit images;
- // convert from (8|24) bits to 32.
- //
- if (cinfo->output_components == 1) {
- in = data + clip.right();
- for (int i = clip.width(); i--; ) {
- out[i] = qRgb(*in, *in, *in);
- in--;
- }
- } else if (cinfo->out_color_space == JCS_CMYK) {
- in = data + clip.right() * 4;
- for (int i = clip.width(); i--; ) {
- int k = in[3];
- out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255);
- in -= 4;
- }
- } else {
- in = data + clip.right() * 3;
- for (int i = clip.width(); i--; ) {
- out[i] = qRgb(in[0], in[1], in[2]);
- in -= 3;
- }
- }
-
- return out;
- }
-
-};
-#endif
-
struct my_error_mgr : public jpeg_error_mgr {
jmp_buf setjmp_buffer;
};
@@ -844,93 +415,82 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
clip = clip.intersected(imageRect);
}
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
- if (scaledSize.isValid() && scaledSize != clip.size()
- && quality >= HIGH_QUALITY_THRESHOLD) {
+ // Allocate memory for the clipped QImage.
+ if (!ensureValidImage(outImage, &cinfo, clip.size()))
+ longjmp(jerr.setjmp_buffer, 1);
+
+ // Avoid memcpy() overhead if grayscale with no clipping.
+ bool quickGray = (cinfo.output_components == 1 &&
+ clip == imageRect);
+ if (!quickGray) {
+ // Ask the jpeg library to allocate a temporary row.
+ // The library will automatically delete it for us later.
+ // The libjpeg docs say we should do this before calling
+ // jpeg_start_decompress(). We can't use "new" here
+ // because we are inside the setjmp() block and an error
+ // in the jpeg input stream would cause a memory leak.
+ JSAMPARRAY rows = (cinfo.mem->alloc_sarray)
+ ((j_common_ptr)&cinfo, JPOOL_IMAGE,
+ cinfo.output_width * cinfo.output_components, 1);
(void) jpeg_start_decompress(&cinfo);
- jpegSmoothScaler scaler(&cinfo, scaledSize, clip);
- *outImage = scaler.scale();
- } else
-#endif
- {
- // Allocate memory for the clipped QImage.
- if (!ensureValidImage(outImage, &cinfo, clip.size()))
- longjmp(jerr.setjmp_buffer, 1);
-
- // Avoid memcpy() overhead if grayscale with no clipping.
- bool quickGray = (cinfo.output_components == 1 &&
- clip == imageRect);
- if (!quickGray) {
- // Ask the jpeg library to allocate a temporary row.
- // The library will automatically delete it for us later.
- // The libjpeg docs say we should do this before calling
- // jpeg_start_decompress(). We can't use "new" here
- // because we are inside the setjmp() block and an error
- // in the jpeg input stream would cause a memory leak.
- JSAMPARRAY rows = (cinfo.mem->alloc_sarray)
- ((j_common_ptr)&cinfo, JPOOL_IMAGE,
- cinfo.output_width * cinfo.output_components, 1);
-
- (void) jpeg_start_decompress(&cinfo);
-
- while (cinfo.output_scanline < cinfo.output_height) {
- int y = int(cinfo.output_scanline) - clip.y();
- if (y >= clip.height())
- break; // We've read the entire clip region, so abort.
-
- (void) jpeg_read_scanlines(&cinfo, rows, 1);
-
- if (y < 0)
- continue; // Haven't reached the starting line yet.
-
- if (cinfo.output_components == 3) {
- // Expand 24->32 bpp.
- uchar *in = rows[0] + clip.x() * 3;
- QRgb *out = (QRgb*)outImage->scanLine(y);
- for (int i = 0; i < clip.width(); ++i) {
- *out++ = qRgb(in[0], in[1], in[2]);
- in += 3;
- }
- } else if (cinfo.out_color_space == JCS_CMYK) {
- // Convert CMYK->RGB.
- uchar *in = rows[0] + clip.x() * 4;
- QRgb *out = (QRgb*)outImage->scanLine(y);
- for (int i = 0; i < clip.width(); ++i) {
- int k = in[3];
- *out++ = qRgb(k * in[0] / 255, k * in[1] / 255,
- k * in[2] / 255);
- in += 4;
- }
- } else if (cinfo.output_components == 1) {
- // Grayscale.
- memcpy(outImage->scanLine(y),
- rows[0] + clip.x(), clip.width());
+ while (cinfo.output_scanline < cinfo.output_height) {
+ int y = int(cinfo.output_scanline) - clip.y();
+ if (y >= clip.height())
+ break; // We've read the entire clip region, so abort.
+
+ (void) jpeg_read_scanlines(&cinfo, rows, 1);
+
+ if (y < 0)
+ continue; // Haven't reached the starting line yet.
+
+ if (cinfo.output_components == 3) {
+ // Expand 24->32 bpp.
+ uchar *in = rows[0] + clip.x() * 3;
+ QRgb *out = (QRgb*)outImage->scanLine(y);
+ for (int i = 0; i < clip.width(); ++i) {
+ *out++ = qRgb(in[0], in[1], in[2]);
+ in += 3;
}
- }
- } else {
- // Load unclipped grayscale data directly into the QImage.
- (void) jpeg_start_decompress(&cinfo);
- while (cinfo.output_scanline < cinfo.output_height) {
- uchar *row = outImage->scanLine(cinfo.output_scanline);
- (void) jpeg_read_scanlines(&cinfo, &row, 1);
+ } else if (cinfo.out_color_space == JCS_CMYK) {
+ // Convert CMYK->RGB.
+ uchar *in = rows[0] + clip.x() * 4;
+ QRgb *out = (QRgb*)outImage->scanLine(y);
+ for (int i = 0; i < clip.width(); ++i) {
+ int k = in[3];
+ *out++ = qRgb(k * in[0] / 255, k * in[1] / 255,
+ k * in[2] / 255);
+ in += 4;
+ }
+ } else if (cinfo.output_components == 1) {
+ // Grayscale.
+ memcpy(outImage->scanLine(y),
+ rows[0] + clip.x(), clip.width());
}
}
+ } else {
+ // Load unclipped grayscale data directly into the QImage.
+ (void) jpeg_start_decompress(&cinfo);
+ while (cinfo.output_scanline < cinfo.output_height) {
+ uchar *row = outImage->scanLine(cinfo.output_scanline);
+ (void) jpeg_read_scanlines(&cinfo, &row, 1);
+ }
+ }
- if (cinfo.output_scanline == cinfo.output_height)
- (void) jpeg_finish_decompress(&cinfo);
+ if (cinfo.output_scanline == cinfo.output_height)
+ (void) jpeg_finish_decompress(&cinfo);
- if (cinfo.density_unit == 1) {
- outImage->setDotsPerMeterX(int(100. * cinfo.X_density / 2.54));
- outImage->setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54));
- } else if (cinfo.density_unit == 2) {
- outImage->setDotsPerMeterX(int(100. * cinfo.X_density));
- outImage->setDotsPerMeterY(int(100. * cinfo.Y_density));
- }
+ if (cinfo.density_unit == 1) {
+ outImage->setDotsPerMeterX(int(100. * cinfo.X_density / 2.54));
+ outImage->setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54));
+ } else if (cinfo.density_unit == 2) {
+ outImage->setDotsPerMeterX(int(100. * cinfo.X_density));
+ outImage->setDotsPerMeterY(int(100. * cinfo.Y_density));
+ }
- if (scaledSize.isValid() && scaledSize != clip.size())
- *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::FastTransformation);
+ if (scaledSize.isValid() && scaledSize != clip.size()) {
+ *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, quality >= HIGH_QUALITY_THRESHOLD ? Qt::SmoothTransformation : Qt::FastTransformation);
}
}