summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraavit <eirik.aavitsland@digia.com>2012-11-07 15:19:20 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-08 11:35:04 +0100
commitc309d424f45dc0e7b62fbbbabf20dbfe355f48a7 (patch)
treea5b0e6405652b4e2f2af98a9a90934c26ad91409
parent5ec6e2aca2950634d39195cc858bf062a2e2618d (diff)
Fix GIF image decoding: do not zero transparent pixels
For the special transparent color index, the decoder would skip writing anything out (thus leaving the pixels at 0 rgba value). Although correct for later frames, for the initial frame this would loose the color information for such pixels (which one otherwise could have made visible e.g. by converting then image to an alpha-less image format). Change-Id: I316cefce8f21797feedebfbf98296ad84eaa4b99 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
-rw-r--r--src/gui/image/qgifhandler.cpp15
-rw-r--r--tests/auto/qimagereader/images/trans.gifbin0 -> 3234 bytes
-rw-r--r--tests/auto/qimagereader/tst_qimagereader.cpp9
3 files changed, 15 insertions, 9 deletions
diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp
index cedb27c193..b60d1a1711 100644
--- a/src/gui/image/qgifhandler.cpp
+++ b/src/gui/image/qgifhandler.cpp
@@ -488,7 +488,7 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
} else {
if (needfirst) {
firstcode=oldcode=code;
- if (!out_of_bounds && image->height() > y && firstcode!=trans_index)
+ if (!out_of_bounds && image->height() > y && ((frame == 0) || (firstcode != trans_index)))
((QRgb*)FAST_SCAN_LINE(bits, bpl, y))[x] = color(firstcode);
x++;
if (x>=swidth) out_of_bounds = true;
@@ -540,17 +540,13 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
}
oldcode=incode;
const int h = image->height();
- const QRgb *map = lcmap ? localcmap : globalcmap;
QRgb *line = 0;
if (!out_of_bounds && h > y)
line = (QRgb*)FAST_SCAN_LINE(bits, bpl, y);
while (sp>stack) {
const uchar index = *(--sp);
- if (!out_of_bounds && h > y && index!=trans_index) {
- if (index > ncols)
- line[x] = Q_TRANSPARENT;
- else
- line[x] = map ? map[index] : 0;
+ if (!out_of_bounds && h > y && ((frame == 0) || (index != trans_index))) {
+ line[x] = color(index);
}
x++;
if (x>=swidth) out_of_bounds = true;
@@ -1031,11 +1027,12 @@ void QGIFFormat::nextY(unsigned char *bits, int bpl)
inline QRgb QGIFFormat::color(uchar index) const
{
- if (index == trans_index || index > ncols)
+ if (index > ncols)
return Q_TRANSPARENT;
QRgb *map = lcmap ? localcmap : globalcmap;
- return map ? map[index] : 0;
+ QRgb col = map ? map[index] : 0;
+ return index == trans_index ? col & Q_TRANSPARENT : col;
}
//-------------------------------------------------------------------------
diff --git a/tests/auto/qimagereader/images/trans.gif b/tests/auto/qimagereader/images/trans.gif
new file mode 100644
index 0000000000..e26398af53
--- /dev/null
+++ b/tests/auto/qimagereader/images/trans.gif
Binary files differ
diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp
index 7a2acee792..14ce74bf61 100644
--- a/tests/auto/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/qimagereader/tst_qimagereader.cpp
@@ -855,6 +855,15 @@ void tst_QImageReader::gifHandlerBugs()
QVERIFY(io.canRead());
QCOMPARE(io.loopCount(), -1);
}
+
+ // Check that pixels with the transparent color are transparent but not zeroed
+ {
+ QImageReader io(prefix + "trans.gif");
+ QVERIFY(io.canRead());
+ QImage im = io.read();
+ QCOMPARE(im.pixel(0,0), qRgba(0x3f, 0xff, 0x7f, 0x00));
+ QCOMPARE(im.pixel(10,10), qRgba(0x3f, 0xff, 0x7f, 0x00));
+ }
}
void tst_QImageReader::animatedGif()