Skip to content
This repository has been archived by the owner on Jan 2, 2023. It is now read-only.

Use smart-growing buffer size for compression #28

Open
wants to merge 1 commit into
base: wk_4.8.7
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 40 additions & 27 deletions src/gui/painting/qprintengine_pdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,31 @@ class jpg_header_reader {

};

bool QPdfEnginePrivate::smartCompressDeflate(const char *source, int size, QByteArray& compressed, unsigned long maxSize)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a static function, as it's unlikely to be used outside of this file.

{
if (maxSize == 0) {
maxSize = ::compressBound(size);
}

const unsigned long initialBufferSize = 10 * 1024 * 1024;

unsigned long destLen = min(initialBufferSize, maxSize);

while (true) {
compressed.resize(destLen);
if (Z_OK == ::compress(reinterpret_cast<Bytef *>(compressed.data()), &destLen, reinterpret_cast<const Bytef *>(source), size)) {
compressed.truncate(destLen);
break;
}
if (static_cast<unsigned long>(compressed.size()) >= maxSize) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the manual, compressBound returns an upper bound on the compressed size after the compress call. So not really sure what this is supposed to protect against? Z_BUF_ERROR is obviously not going to happen, so maybe you should check for Z_MEM_ERROR directly if that was what you had in mind.

compressed.clear();
return false;
}
destLen = min(static_cast<unsigned long>(compressed.size()) * 2, maxSize);
}

return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this check maxSize with compressed.size() e.g. as in line 930 (uLongf)destLen < target?

}

/*!
* Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
Expand Down Expand Up @@ -907,33 +931,25 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
if (noneScaled && noneScaled->rect() != image.rect()) {
QByteArray imageData2;
convertImage(*noneScaled, imageData2);
uLongf len = imageData2.size();
uLongf destLen = len + len/100 + 13; // zlib requirement
Bytef* dest = new Bytef[destLen];
if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) &&
(uLongf)destLen < target) {
imageData=imageData2;
target=destLen;
dct=false;
uns=true;
QByteArray compressed;
if (smartCompressDeflate(imageData2.data(), imageData2.size(), compressed, target)) {
imageData = imageData2;
target = compressed.size();
dct = false;
uns = true;
}
delete[] dest;
}

{
QByteArray imageData2;
convertImage(image, imageData2);
uLongf len = imageData2.size();
uLongf destLen = len + len/100 + 13; // zlib requirement
Bytef* dest = new Bytef[destLen];
if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) &&
(uLongf)destLen < target) {
imageData=imageData2;
target=destLen;
dct=false;
uns=false;
QByteArray compressed;
if (smartCompressDeflate(imageData2.data(), imageData2.size(), compressed, target)) {
imageData = imageData2;
target = compressed.size();
dct = false;
uns = false;
}
delete[] dest;
}


Expand Down Expand Up @@ -1182,16 +1198,13 @@ int QPdfEnginePrivate::writeCompressed(const char *src, int len)
{
#ifndef QT_NO_COMPRESS
if(doCompress) {
uLongf destLen = len + len/100 + 13; // zlib requirement
Bytef* dest = new Bytef[destLen];
if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) {
stream->writeRawData((const char*)dest, destLen);
QByteArray compressed;
if (smartCompressDeflate(src, len, compressed)) {
stream->writeRawData((const char*)compressed.data(), compressed.size());
} else {
qWarning("QPdfStream::writeCompressed: Error in compress()");
destLen = 0;
}
delete [] dest;
len = destLen;
len = compressed.size();
} else
#endif
{
Expand Down
1 change: 1 addition & 0 deletions src/gui/painting/qprintengine_pdf_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class QPdfEnginePrivate : public QPdfBaseEnginePrivate
streampos += data.size();
}

bool smartCompressDeflate(const char *source, int size, QByteArray& compressed, unsigned long maxSize = 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this.

int writeCompressed(const char *src, int len);
inline int writeCompressed(const QByteArray &data) { return writeCompressed(data.constData(), data.length()); }
int writeCompressed(QIODevice *dev);
Expand Down