summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-13 12:46:44 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-22 07:20:36 +0000
commit12a382e3bc75192a11145ef5cf29ef1baf377dc9 (patch)
tree4770619db9fe59b2bbdd6d10681573a522dc918b /src/gui
parent4c025ca9c73bda320f0e7577a4fbd141c31d7c8c (diff)
Fix saving QImage with longer than necessary bytes-per-line
We should only copy the minimum bytes-per-line when saving an image. Task-number: QTBUG-30515 Change-Id: Idd34a389cf88210c3f127599ccf54d27d3ec9a06 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qbmphandler.cpp55
1 files changed, 22 insertions, 33 deletions
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 4350a5c192..703c5c0f31 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -562,27 +562,12 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
}
// this is also used in qmime_win.cpp
-bool qt_write_dib(QDataStream &s, QImage image)
+bool qt_write_dib(QDataStream &s, const QImage &image, int bpl, int bpl_bmp, int nbits)
{
- int nbits;
- int bpl_bmp;
- int bpl = image.bytesPerLine();
-
QIODevice* d = s.device();
if (!d->isWritable())
return false;
- if (image.depth() == 8 && image.colorCount() <= 16) {
- bpl_bmp = (((bpl+1)/2+3)/4)*4;
- nbits = 4;
- } else if (image.depth() == 32) {
- bpl_bmp = ((image.width()*24+31)/32)*4;
- nbits = 24;
- } else {
- bpl_bmp = bpl;
- nbits = image.depth();
- }
-
BMP_INFOHDR bi;
bi.biSize = BMP_WIN; // build info header
bi.biWidth = image.width();
@@ -617,9 +602,6 @@ bool qt_write_dib(QDataStream &s, QImage image)
delete [] color_table;
}
- if (image.format() == QImage::Format_MonoLSB)
- image = image.convertToFormat(QImage::Format_Mono);
-
int y;
if (nbits == 1 || nbits == 8) { // direct output
@@ -769,21 +751,17 @@ bool QBmpHandler::read(QImage *image)
bool QBmpHandler::write(const QImage &img)
{
- if (m_format == DibFormat) {
- QDataStream dibStream(device());
- dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order
- return qt_write_dib(dibStream, img);
- }
-
QImage image;
switch (img.format()) {
case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
case QImage::Format_Indexed8:
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
image = img;
break;
+ case QImage::Format_MonoLSB:
+ image = img.convertToFormat(QImage::Format_Mono);
+ break;
case QImage::Format_Alpha8:
case QImage::Format_Grayscale8:
image = img.convertToFormat(QImage::Format_Indexed8);
@@ -796,21 +774,32 @@ bool QBmpHandler::write(const QImage &img)
break;
}
- QIODevice *d = device();
- QDataStream s(d);
- BMP_FILEHDR bf;
+ int nbits;
int bpl_bmp;
- int bpl = image.bytesPerLine();
+ // Calculate a minimum bytes-per-line instead of using whatever value this QImage is using internally.
+ int bpl = ((image.width() * image.depth() + 31) >> 5) << 2;
- // Code partially repeated in qt_write_dib
if (image.depth() == 8 && image.colorCount() <= 16) {
bpl_bmp = (((bpl+1)/2+3)/4)*4;
- } else if (image.depth() == 32) {
+ nbits = 4;
+ } else if (image.depth() == 32) {
bpl_bmp = ((image.width()*24+31)/32)*4;
+ nbits = 24;
} else {
bpl_bmp = bpl;
+ nbits = image.depth();
}
+ if (m_format == DibFormat) {
+ QDataStream dibStream(device());
+ dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order
+ return qt_write_dib(dibStream, img, bpl, bpl_bmp, nbits);
+ }
+
+ QIODevice *d = device();
+ QDataStream s(d);
+ BMP_FILEHDR bf;
+
// Intel byte order
s.setByteOrder(QDataStream::LittleEndian);
@@ -825,7 +814,7 @@ bool QBmpHandler::write(const QImage &img)
s << bf;
// write image
- return qt_write_dib(s, image);
+ return qt_write_dib(s, image, bpl, bpl_bmp, nbits);
}
bool QBmpHandler::supportsOption(ImageOption option) const