incorrect rendering of JPEG images on Windows Server 2008 x64 #1638
Comments
Same problem for me. Server configuration, if helps:
Seems that creates two or more negative images and superimposed on the original. |
I have the same issue with an image that I unfortunately can't share. I'm using the shared library and the problem is in both the mingw and the msvc versions on the same os'es. Also it doesn't seems to matter whether run as 32- or 64-bit on the affected 64-bit systems. Tested on these systems: Present: Windows XP x86, Windows Server 2003 x86, Windows Server 2003 R2 x86, Windows Server 2008 x64, Windows Server 2008 R2 x64 Not present: Windows 7 x64, Windows 8 x64, Windows 8.1 x64, Windows Server 2012 x64 |
I know that this is important, but it is so platform-specific that it will take me quite a bit of time to debug it -- the crash took me more than a week to debug and finding a server where you can install debugging tools is not easy at all. And the crash is easier to fix because you have to start investigation at a single point :-) |
Hi ashkulz First, thank you for your hard work, The incorrect rendering of JPEG images happen also on Widows 2003 Server I installed wkhtmltox-0.11.0_rc1-installer.exe Back to v12.1(not rc) the version in http://wkhtmltopdf.org/downloads.html The most Important thing That I notice is that when I Use Imagick Libary (http://www.imagemagick.org/) to write an Jpeg image it's happens. I hope it's help in something... Dvir. |
can you upload the files somewhere? Maybe examining the structure will give a clue as to why there is a difference. |
Hi ashkulz PDF Originial link: 1.bad image link: 2.good image link: Step procedures:
If need anything please let me know.. Dvir. |
Can you try if the following patch gives you better output? commit 2591d7fd741cf4ae679dd495121537497eacf09d
Author: Ashish Kulkarni <kulkarni.ashish@gmail.com>
Date: Tue May 27 15:07:56 2014 +0530
fix jpeg issue
diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
index 78e6301..8775e2e 100644
--- a/src/gui/painting/qprintengine_pdf.cpp
+++ b/src/gui/painting/qprintengine_pdf.cpp
@@ -754,85 +754,6 @@ void QPdfEnginePrivate::convertImage(const QImage & image, QByteArray & imageDat
}
}
-#include <iostream>
-
-class jpg_header_reader {
-private:
- const QByteArray * data;
- int index;
-
- class jpeg_exception {};
-
- unsigned char next() {
- if (index == data->size()) throw jpeg_exception();
- return data->data()[index++];
- }
-
- void skip() {
- int l = (next() << 8) + next();
- if (l < 2) throw jpeg_exception();
- for (int i=2; i < l; ++i) next();
- }
-
- void read_header() {
- int l = (next() << 8) + next();
- if (l < 2) throw jpeg_exception();
- precision = next();
- height = (next() << 8) + next();
- width = (next() << 8) + next();
- components = next();
- if (l != 8 + components*3) throw jpeg_exception();
- }
-
-public:
- bool read(const QByteArray * d) {
- index=0;
- data=d;
- try {
- if (next() != 0xFF) throw jpeg_exception();
- unsigned char marker = next();
- if (marker != 0xD8) throw jpeg_exception();
- while (true) {
- marker = next();
- while (marker != 0xFF) marker=next();
- while (marker == 0xFF) marker=next();
- switch(marker) {
- case 0xC0: // SOF0 Start Of Frame N - BaseLine
- case 0xC1: // SOF1 N indicates which compression process - Extended Sequential
- case 0xC2: // SOF2 Only SOF0-SOF2 are now in common use - Progressive
- case 0xC3: // SOF3 Lossless
- case 0xC5: // SOF5 Differential sequential
- case 0xC6: // SOF6 Differential progressive
- case 0xC7: // SOF7 Differential lossless
- case 0xC9: // SOF9 Extended sequential, arithmetic coding
- case 0xCA: // SOF10 Progressive, arithmetic coding
- case 0xCB: // SOF11 Lossless, arithmetic coding
- case 0xCD: // SOF13 Differential sequential, arithmetic coding
- case 0xCE: // SOF14 Differential progressive, arithmetic coding
- case 0xCF: // SOF15 Differential lossless, arithmetic coding
- case 0xE1: // EXIF/XMP Exif marker. Also used for XMP data!
- read_header();
- return true;
- case 0xDA: // SOS Start Of Scan (begins compressed data)
- case 0xD9: // EOI End Of Image (end of datastream)
- return false;
- default:
- skip();
- break;
- }
- }
- } catch(jpeg_exception) {
- return false;
- }
- return true;
- }
-
- int precision, height, width, components;
-
-};
-
-
-
/*!
* Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
*/
@@ -937,9 +858,9 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
if (colorMode != QPrinter::GrayScale && noneScaled != 0 && data != 0) {
- jpg_header_reader header;
- if (header.read(data)) {
- d = header.components == 3?32:8;
+ QImage jpeg;
+ if (jpeg.loadFromData(*data, "JPEG")) {
+ d = jpeg.depth();
imageData = *data;
target=data->size();
dct=true; I have uploaded a precompiled binary with MSVC 2013 for 32-bit Windows, can't test it as I don't have access to a Windows server box for the next week. |
Hi thanks for the fix... The precompiled binary not working ... :( I will try to recompile with MSVC 2010 for 32-bit and I will let you know... Thanks. |
Hi ashkulz, I tried the patch ... same problem..
Thanks again for all your helping Br, |
@BDvirus: does that mean it did not fix the issue i.e. still generates that weird pattern? I can't test it myself as I mentioned above:
And yes, compilation can take that long on even a very fast machine. |
@ashkulz: It did not fix the issue.. Any suggestions? |
I think the core of the problem is that QPdfEnginePrivate::addImage assumes that the formats of img and noneScaled are the same, which apparently they end up not being. When making a debug build i'm getting a crash at qprintengine_pdf.cpp:965. img.format() is Format_ARGB32 but noneScaled->fomat() is Format_RGB16. So for every scanline we are actually reading two rows of the image. |
The code in question is really quite weird: if (format != QImage::Format_RGB32) {
softMaskData.resize(w * h);
uchar *sdata = (uchar *)softMaskData.data();
for (int y = 0; y < h; ++y) {
const QRgb *rgb = (const QRgb *)(uns?noneScaled->scanLine(y):image.scanLine(y));
for (int x = 0; x < w; ++x) {
uchar alpha = qAlpha(*rgb);
*sdata++ = alpha;
hasMask |= (alpha < 255);
hasAlpha |= (alpha != 0 && alpha != 255);
++rgb;
}
}
} The format isn't RGB32. But it's not ARGB32 either, so it doesn't make sense to just loop through QRgb pixels (which are ARGB32). |
Try this patch: diff --git "a/src/gui/painting/qprintengine_pdf.cpp" "b/src/gui/painting/qprintengine_pdf.cpp"
index 78e6301..1087b56 100644
--- "a/src/gui/painting/qprintengine_pdf.cpp"
+++ "b/src/gui/painting/qprintengine_pdf.cpp"
@@ -956,7 +956,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
bool hasAlpha = false;
bool hasMask = false;
- if (format != QImage::Format_RGB32) {
+ if ((!uns && format == QImage::Format_ARGB32) || (uns && noneScaled->format() == QImage::Format_ARGB32)) {
softMaskData.resize(w * h);
uchar *sdata = (uchar *)softMaskData.data();
for (int y = 0; y < h; ++y) { I'm not sure if it's isn't still wrong as we are failing to handle the other formats with alpha channels - there are several:
|
@poizan42: I think that converting noneScaled to ARGB32 would be the correct thing to do. What do you think? |
fixes #1539 via wkhtmltopdf/qt@5a8d870 fixes #1638 via wkhtmltopdf/qt@b18df9f fixes #1722 via wkhtmltopdf/qt@7683bbb also sync the changelog with latest changes
fixes #1539 via wkhtmltopdf/qt@5a8d870 fixes #1638 via wkhtmltopdf/qt@b18df9f fixes #1722 via wkhtmltopdf/qt@7683bbb also sync the changelog with latest changes
Please test this with the latest 0.12.2 test release available from the downloads page and report back if you find any problems. |
|
This was originally reported as #1512 and has been split off from it.
HTML:
Image:
This results in a PDF where the image comes out as corrupt or not rendered properly:
This testcase was originally made by @DomusMaximus and affects @boeserwolf and @denu as well.
The text was updated successfully, but these errors were encountered: