summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/webkit/WebCore/WebCore.pro2
-rw-r--r--src/gui/image/qxpmhandler.cpp2
-rw-r--r--src/plugins/graphicssystems/meego/dithering.cpp147
-rw-r--r--src/qbase.pri2
-rw-r--r--src/s60installs/s60installs.pro2
-rw-r--r--src/sql/models/qsqltablemodel.cpp4
-rw-r--r--src/sql/models/qsqltablemodel_p.h2
-rw-r--r--tests/auto/qimagereader/images/corrupt-pixel-count.xpm11
-rw-r--r--tests/auto/qimagereader/tst_qimagereader.cpp3
-rw-r--r--tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp21
10 files changed, 94 insertions, 102 deletions
diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro
index e82ec4c..2de6961 100644
--- a/src/3rdparty/webkit/WebCore/WebCore.pro
+++ b/src/3rdparty/webkit/WebCore/WebCore.pro
@@ -15,7 +15,7 @@ symbian: {
webkitlibs.path = /sys/bin
vendorinfo = \
"; Localised Vendor name" \
- "%{\"Nokia, Qt\"}" \
+ "%{\"Nokia\"}" \
" " \
"; Unique Vendor name" \
":\"Nokia, Qt\"" \
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index ffad75b..075d5da 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -864,7 +864,7 @@ static bool read_xpm_body(
QByteArray buf(200, 0);
int i;
- if (cpp > 15)
+ if (cpp < 0 || cpp > 15)
return false;
// For > 256 colors, we delay creation of the image until
diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp
index 91e3337..2561c22 100644
--- a/src/plugins/graphicssystems/meego/dithering.cpp
+++ b/src/plugins/graphicssystems/meego/dithering.cpp
@@ -39,15 +39,22 @@
**
****************************************************************************/
-// This is an implementation of the 32bit => 16bit Floyd-Steinberg dithering.
+// Implements two dithering methods:
+//
+// * convertRGBA32_to_RGB565
+//
+// This is implemented using Ordered Bayer Dithering. The code has been adapted
+// from QX11PixmapData::fromImage. This method was originally implemented using
+// Floyd-Steinberg dithering but was later changed to Ordered Dithering because
+// of the better quality of the results.
+//
+// * convertRGBA32_to_RGBA4444
+//
+// This is implemented using Floyd-Steinberg dithering.
+//
// The alghorithm used here is not the fastest possible but it's prolly fast enough:
// uses look-up tables, integer-only arthmetics and works in one pass on two lines
// at a time. It's a high-quality dithering using 1/8 diffusion precission.
-// Two functions here to look at:
-//
-// * convertRGBA32_to_RGB565
-// * convertRGBA32_to_RGBA4444
-//
// Each channel (RGBA) is diffused independently and alpha is dithered too.
#include <string.h>
@@ -76,113 +83,63 @@
// Converts incoming RGB32 (QImage::Format_RGB32) to RGB565. Returns the newly allocated data.
unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int height, int stride)
{
+ static bool thresholdMapInitialized = false;
+ static int thresholdMap[16][16];
+
+ if (!thresholdMapInitialized) {
+ int i;
+ int j;
+ int n;
+
+ thresholdMap[0][0] = 0;
+ thresholdMap[1][0] = 2;
+ thresholdMap[0][1] = 3;
+ thresholdMap[1][1] = 1;
+
+ for (n=2; n<16; n*=2) {
+ for (i=0; i<n; i++) {
+ for (j=0; j<n; j++) {
+ thresholdMap[i][j] *= 4;
+ thresholdMap[i+n][j] = thresholdMap[i][j] + 2;
+ thresholdMap[i][j+n] = thresholdMap[i][j] + 3;
+ thresholdMap[i+n][j+n] = thresholdMap[i][j] + 1;
+ }
+ }
+ }
+
+ thresholdMapInitialized = true;
+ }
+
// Output line stride. Aligned to 4 bytes.
int alignedWidth = width;
if (alignedWidth % 2 > 0)
alignedWidth++;
// Will store output
- unsigned short *out = (unsigned short *) malloc(alignedWidth * height * 2);
-
- // Lookup tables for the 8bit => 6bit and 8bit => 5bit conversion
- unsigned char lookup_8bit_to_5bit[256];
- short lookup_8bit_to_5bit_diff[256];
- unsigned char lookup_8bit_to_6bit[256];
- short lookup_8bit_to_6bit_diff[256];
-
- // Macros for the conversion using the lookup table.
- #define CONVERT_8BIT_TO_5BIT(v) (lookup_8bit_to_5bit[v])
- #define DIFF_8BIT_TO_5BIT(v) (lookup_8bit_to_5bit_diff[v])
-
- #define CONVERT_8BIT_TO_6BIT(v) (lookup_8bit_to_6bit[v])
- #define DIFF_8BIT_TO_6BIT(v) (lookup_8bit_to_6bit_diff[v])
-
- int i;
- int x, y, c; // Pixel we're processing. c is component number (0, 1, 2 for r, b, b)
- short component[3]; // Stores the new components (r, g, b) for pixel produced during conversion
- short diff; // The difference between the converted value and the original one. To be accumulated.
- QVarLengthArray <short> accumulatorData(3 * width * 2); // Data for three acumulators for r, g, b. Each accumulator is two lines.
- short *accumulator[3]; // Helper for accessing the accumulator on a per-channel basis more easily.
- accumulator[0] = accumulatorData.data();
- accumulator[1] = accumulatorData.data() + width;
- accumulator[2] = accumulatorData.data() + (width * 2);
-
- // Produce the conversion lookup tables.
- for (i = 0; i < 256; i++) {
- lookup_8bit_to_5bit[i] = round(i / 8.0);
-
- // Before bitshifts: (i * 8) - (... * 8 * 8)
- lookup_8bit_to_5bit_diff[i] = (i << 3) - (lookup_8bit_to_5bit[i] << 6);
- if (lookup_8bit_to_5bit[i] > 31)
- lookup_8bit_to_5bit[i] -= 1;
-
- lookup_8bit_to_6bit[i] = round(i / 4.0);
-
- // Before bitshifts: (i * 8) - (... * 4 * 8)
- lookup_8bit_to_6bit_diff[i] = (i << 3) - (lookup_8bit_to_6bit[i] << 5);
- if (lookup_8bit_to_6bit[i] > 63)
- lookup_8bit_to_6bit[i] -= 1;
- }
+ unsigned short *out = (unsigned short *)malloc (alignedWidth * height * 2);
- // Clear the accumulators
- memset(accumulator[0], 0, width * 4);
- memset(accumulator[1], 0, width * 4);
- memset(accumulator[2], 0, width * 4);
+ int x;
+ int y;
+ int threshold;
// For each line...
for (y = 0; y < height; y++) {
- // For each accumulator, move the second line (index 1) to replace the first line (index 0).
- // Clear the second line (index 1)
- memcpy(accumulator[0], accumulator[0] + width, width * 2);
- memset(accumulator[0] + width, 0, width * 2);
-
- memcpy(accumulator[1], accumulator[1] + width, width * 2);
- memset(accumulator[1] + width, 0, width * 2);
-
- memcpy(accumulator[2], accumulator[2] + width, width * 2);
- memset(accumulator[2] + width, 0, width * 2);
-
// For each column....
for (x = 0; x < width; x++) {
- // For each component (r, g, b)...
- for (c = 0; c < 3; c++) {
+ int r = GET_RGBA_COMPONENT(in, x, y, stride, 0);
+ int g = GET_RGBA_COMPONENT(in, x, y, stride, 1);
+ int b = GET_RGBA_COMPONENT(in, x, y, stride, 2);
- // Get the 8bit value from the original image
- component[c] = GET_RGBA_COMPONENT(in, x, y, stride, c);
-
- // Add the diffusion for this pixel we stored in the accumulator.
- // >> 7 because the values in accumulator are stored * 128
- if (x != 0 && x != (width - 1)) {
- if (accumulator[c][x] >> 7 != 0)
- component[c] += rand() % accumulator[c][x] >> 7;
- }
-
- // Make sure we're not over the boundaries.
- CLAMP_256(component[c]);
-
- // For green component we use 6 bits. Otherwise 5 bits.
- // Store the difference from converting 8bit => 6 bit and the orig pixel.
- // Convert 8bit => 6(5) bit.
- if (c == 1) {
- diff = DIFF_8BIT_TO_6BIT(component[c]);
- component[c] = CONVERT_8BIT_TO_6BIT(component[c]);
- } else {
- diff = DIFF_8BIT_TO_5BIT(component[c]);
- component[c] = CONVERT_8BIT_TO_5BIT(component[c]);
- }
+ threshold = thresholdMap[x%16][y%16];
- // Distribute the difference according to the matrix in the
- // accumulation bufffer.
- ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 3);
- ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 5);
- ACCUMULATE(accumulator[c], x, 1, width, diff * 5);
- ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 3);
- }
+ if (r <= (255-(1<<3)) && ((r<<5) & 255) > threshold) r += (1<<3);
+ if (g <= (255-(1<<2)) && ((g<<6) & 255) > threshold) g += (1<<2);
+ if (b <= (255-(1<<3)) && ((b<<5) & 255) > threshold) b += (1<<3);
// Write the newly produced pixel
- PUT_565(out, x, y, alignedWidth, component[2], component[1], component[0]);
+ PUT_565(out, x, y, alignedWidth, ((b >> 3) & 0x1f), ((g >> 2) & 0x3f), ((r >> 3) & 0x1f));
}
}
diff --git a/src/qbase.pri b/src/qbase.pri
index 4d835bd..ce69757 100644
--- a/src/qbase.pri
+++ b/src/qbase.pri
@@ -197,7 +197,7 @@ symbian {
# Partial upgrade SIS file
vendorinfo = \
"; Localised Vendor name" \
- "%{\"Nokia, Qt\"}" \
+ "%{\"Nokia\"}" \
" " \
"; Unique Vendor name" \
":\"Nokia, Qt\"" \
diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro
index 741a5fc..1c91422 100644
--- a/src/s60installs/s60installs.pro
+++ b/src/s60installs/s60installs.pro
@@ -75,7 +75,7 @@ symbian: {
vendorinfo = \
"; Localised Vendor name" \
- "%{\"Nokia, Qt\"}" \
+ "%{\"Nokia\"}" \
" " \
"; Unique Vendor name" \
":\"Nokia, Qt\"" \
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 4df1d63..bf7c0aa 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -657,7 +657,7 @@ bool QSqlTableModel::insertRowIntoTable(const QSqlRecord &values)
return false;
}
- return d->exec(stmt, prepStatement, rec);
+ return d->exec(stmt, prepStatement, rec, QSqlRecord() /* no where values */);
}
/*!
@@ -695,7 +695,7 @@ bool QSqlTableModel::deleteRowFromTable(int row)
}
stmt.append(QLatin1Char(' ')).append(where);
- return d->exec(stmt, prepStatement, whereValues);
+ return d->exec(stmt, prepStatement, QSqlRecord() /* no new values */, whereValues);
}
/*!
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index d2b96e6..f4f3811 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -75,7 +75,7 @@ public:
QSqlRecord record(const QVector<QVariant> &values) const;
bool exec(const QString &stmt, bool prepStatement,
- const QSqlRecord &rec, const QSqlRecord &whereValues = QSqlRecord());
+ const QSqlRecord &rec, const QSqlRecord &whereValues);
virtual void revertCachedRow(int row);
void revertInsertedRow();
bool setRecord(int row, const QSqlRecord &record);
diff --git a/tests/auto/qimagereader/images/corrupt-pixel-count.xpm b/tests/auto/qimagereader/images/corrupt-pixel-count.xpm
new file mode 100644
index 0000000..3a736ff
--- /dev/null
+++ b/tests/auto/qimagereader/images/corrupt-pixel-count.xpm
@@ -0,0 +1,11 @@
+/* XPM */
+static const char *marble_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"2 2 2 -2",
+/* colors */
+"a c #adadad",
+"b c #dedede",
+/* pixels */
+"ab",
+"ba"
+};
diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp
index 7c2aee8..f02fd6a 100644
--- a/tests/auto/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/qimagereader/tst_qimagereader.cpp
@@ -1410,6 +1410,9 @@ void tst_QImageReader::readFromResources_data()
QTest::newRow("corrupt-pixels.xpm") << QString("corrupt-pixels.xpm")
<< QByteArray("xpm") << QSize(0, 0)
<< QString("QImage: XPM pixels missing on image line 3");
+ QTest::newRow("corrupt-pixel-count.xpm") << QString("corrupt-pixel-count.xpm")
+ << QByteArray("xpm") << QSize(0, 0)
+ << QString("");
QTest::newRow("marble.xpm") << QString("marble.xpm")
<< QByteArray("xpm") << QSize(240, 240)
<< QString("");
diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
index f7d2180..bf68375 100644
--- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -773,6 +773,27 @@ void tst_QSqlTableModel::removeInsertedRow()
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi"));
+
+ // Now insert a row with a null, and check that removing it also works (QTBUG-15979 etc)
+ model.insertRow(1);
+ model.setData(model.index(1,0), 55);
+ model.setData(model.index(1,1), QString("null columns"));
+ model.setData(model.index(1,2), QVariant());
+
+ model.submitAll();
+
+ QCOMPARE(model.rowCount(), 4);
+ QCOMPARE(model.data(model.index(3, 0)).toInt(), 55);
+ QCOMPARE(model.data(model.index(3, 1)).toString(), QString("null columns"));
+ QCOMPARE(model.data(model.index(3, 2)).isNull(), true);
+
+ QVERIFY(model.removeRow(3));
+ model.submitAll();
+ QCOMPARE(model.rowCount(), 3);
+
+ QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
+ QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
+ QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi"));
}
void tst_QSqlTableModel::removeInsertedRows()