Skip to content

Commit

Permalink
Merge branch 4.7 into qt-master-from-4.7
Browse files Browse the repository at this point in the history
  • Loading branch information
Qt Continuous Integration System committed Feb 18, 2011
2 parents 6796df2 + 177131d commit f175c9e
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 102 deletions.
2 changes: 1 addition & 1 deletion src/3rdparty/webkit/WebCore/WebCore.pro
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ symbian: {
webkitlibs.path = /sys/bin
vendorinfo = \
"; Localised Vendor name" \
"%{\"Nokia, Qt\"}" \
"%{\"Nokia\"}" \
" " \
"; Unique Vendor name" \
":\"Nokia, Qt\"" \
Expand Down
2 changes: 1 addition & 1 deletion src/gui/image/qxpmhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
147 changes: 52 additions & 95 deletions src/plugins/graphicssystems/meego/dithering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/qbase.pri
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ symbian {
# Partial upgrade SIS file
vendorinfo = \
"; Localised Vendor name" \
"%{\"Nokia, Qt\"}" \
"%{\"Nokia\"}" \
" " \
"; Unique Vendor name" \
":\"Nokia, Qt\"" \
Expand Down
2 changes: 1 addition & 1 deletion src/s60installs/s60installs.pro
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ symbian: {

vendorinfo = \
"; Localised Vendor name" \
"%{\"Nokia, Qt\"}" \
"%{\"Nokia\"}" \
" " \
"; Unique Vendor name" \
":\"Nokia, Qt\"" \
Expand Down
4 changes: 2 additions & 2 deletions src/sql/models/qsqltablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */);
}

/*!
Expand Down Expand Up @@ -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);
}

/*!
Expand Down
2 changes: 1 addition & 1 deletion src/sql/models/qsqltablemodel_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class QSqlTableModelPrivate: public QSqlQueryModelPrivate
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);
Expand Down
11 changes: 11 additions & 0 deletions tests/auto/qimagereader/images/corrupt-pixel-count.xpm
Original file line number Diff line number Diff line change
@@ -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"
};
3 changes: 3 additions & 0 deletions tests/auto/qimagereader/tst_qimagereader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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("");
Expand Down
21 changes: 21 additions & 0 deletions tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit f175c9e

Please sign in to comment.