PDA

View Full Version : Is there a bug in the (fasttransformation) pixmap scaling in qt 4.5?



captiva
5th March 2009, 11:29
When I create a simple, zoomable, qgraphicsview with a single qgraphicspixmapitem in it, it crashes when zooming out on certain images (not very large ones, aprox. 480*270 and then zoomed out twice with scalefactor 0.5).

The thing is, when I use:

pixitem->setTransformationMode(Qt::SmoothTransformation);
there are no problems, which makes me think there is something wrong with the fasttransformation pixmap scaling.

In the debugger, the fault traces to qt_scale_image_32bit, but I do not understand enough of it to decipher the error. Anyone had similar problems?

captiva
11th March 2009, 16:08
I put together a quick demo application to verify this bug, it loads an image. Could anyone run this program, load an image file and zoom out (zooming in seems to work quite well.)

main.cpp:

#include <QtGui>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui>

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void zoomIn();
void zoomOut();

private:


QAction *Action_zoomIn;
QAction *Action_zoomOut;
QMenu *Menu_view;

QGraphicsScene * scene;
QGraphicsView * view;

};

#endif // MAINWINDOW_H

And mainwindow.cpp:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
Action_zoomIn = new QAction(tr("Zoom In"), this);
Action_zoomIn->setShortcut(tr("="));
Action_zoomOut = new QAction(tr("Zoom Out"), this);
Action_zoomOut->setShortcut(tr("-"));
Menu_view = new QMenu(tr("View"), this);
Menu_view->addAction(Action_zoomIn);
Menu_view->addAction(Action_zoomOut);
menuBar()->addMenu(Menu_view);

scene = new QGraphicsScene();
scene->addText("No files loaded...");

view = new QGraphicsView(scene, this);
this->setCentralWidget(view);

this->show();

QFileDialog::Options options;
QString selectFilt;
QString imgname = QFileDialog::getOpenFileName(this
, tr("Open File")
, ""
, tr("All Files (*)")
, &selectFilt
, options);
scene->clear();
QGraphicsPixmapItem * pixitem = scene->addPixmap( QPixmap(imgname) );

//This seems to work much better: (no crashes at least)
//pixitem->setTransformationMode(Qt::SmoothTransformation);

connect(Action_zoomIn, SIGNAL(triggered()), this, SLOT(zoomIn()));
connect(Action_zoomOut, SIGNAL(triggered()), this, SLOT(zoomOut()));
}

MainWindow::~MainWindow()
{
}

void MainWindow::zoomIn()
{
view->scale(2.0,2.0);
}

void MainWindow::zoomOut()
{
view->scale(0.5,0.5);
}


(I also tried with qpixmap allocated differently. I use fromImage() in some other code, where the image is never "deleted" to make sure the data exists.
Is the above code correct? Does qt keep an internal reference count on pixmaps...?)

lni
11th March 2009, 16:49
work fine for me, no crash on 4.5.0 in Linux

captiva
11th March 2009, 17:38
Weird... did you try zooming out a couple of times?
I am building on Windows XP SP2, with mingw/QT Creator.

In the debugger it shows a problem in some event loop, which traces down to the scaling functions... (and if I enable pixitem->setTransformationMode(Qt::SmoothTransformation); in the above code, there is no problem, but i do not want that interpolation)


qt_scale_image_32bit<Blend_RGB32_on_RGB32_NoAlpha>
qt_scale_image_rgb32_on_rgb32
QRasterPaintEngine::drawImage
QRasterPaintEngine::drawPixmap
QPainter::drawPixmap
QGraphicsPixmapItem::paint
_q_paintItem
QGraphicsScenePrivate::drawItemHelper
QGraphicsScene::drawItems
...

lni
11th March 2009, 18:43
Did zoom in zoom out many times...

captiva
12th March 2009, 10:26
Thanks Ini, in my case sometimes it works and sometimes it crashes (most of the time actually, and only when zooming out).

Am I doing something wrong with the memory allocation of the pixmapitem or something? If there is no problem in my code it is probably a real bug, but I would like for some more people to verify before I report it.

Help wanted :)

Edit: I tested it also on a vista laptop, also crashes (although somehow less often).

mazurekwrc
12th March 2009, 11:28
I try it on Windows Vista, and everything work fine till I make Print Scrn, save it in Paintbrush as jpg file and then load it in your program. I use zoom out function several times and program crashed. I watched than it happen in function "qt_scale_image_32bit"

koral
12th March 2009, 12:39
I think you should seriously fire a bug!
So.. win Qt 4.5, I have no crashes neither in release or debug mode.
BUT: when running the app with valgrind, and 'zooming out twice', with a '480x270 jpeg picture', as you said, I saw what look like an out-of-boundary access to the Image memory.

Please fire a bug in the qtsoftware task tracker and tell us how it's going.

==9781== Invalid read of size 4
==9781== at 0x424D728: (within /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x42E2336: (within /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x42E7E1D: (within /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x42825E4: QPainter::drawPixmap(QRectF const&, QPixmap const&, QRectF const&) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x4706E49: QGraphicsPixmapItem::paint(QPainter*, QStyleOptionGraphicsItem const*, QWidget*) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x472377C: (within /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x4723EF8: (within /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x4725DF5: QGraphicsScene::drawItems(QPainter*, int, QGraphicsItem**, QStyleOptionGraphicsItem const*, QWidget*) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x473B26C: QGraphicsView::drawItems(QPainter*, int, QGraphicsItem**, QStyleOptionGraphicsItem const*) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x4747899: QGraphicsView::paintEvent(QPaintEvent*) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x41BBD3D: QWidget::event(QEvent*) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x45313C3: QFrame::event(QEvent*) (in /usr/lib/qt4/libQtGui.so.4.5.0)

==9781== Address 0x9bc32a8 is 8 bytes after a block of size 518,400 alloc'd
==9781== at 0x40264EF: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==9781== by 0x42048E2: (within /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x4204C97: QImage::QImage(QSize const&, QImage::Format) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x7C78640: (within /usr/lib/qt4/plugins/imageformats/libqjpeg.so)
==9781== by 0x7C793E7: (within /usr/lib/qt4/plugins/imageformats/libqjpeg.so)
==9781== by 0x7C79B96: (within /usr/lib/qt4/plugins/imageformats/libqjpeg.so)
==9781== by 0x42160CA: QImageReader::read(QImage*) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x4216697: QImageReader::read() (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x4224F96: QPixmap::load(QString const&, char const*, QFlags<Qt::ImageConversionFlag>) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x422537B: QPixmap::QPixmap(QString const&, char const*, QFlags<Qt::ImageConversionFlag>) (in /usr/lib/qt4/libQtGui.so.4.5.0)
==9781== by 0x804AEA3: MainWindow::MainWindow(QWidget*) (in /root/a/a)
==9781== by 0x804A94C: main (in /root/a/a)

captiva
12th March 2009, 15:12
Thanks, I submitted a bug report.

I also checked with an image allocated as follows:

QPixmap * img = new QPixmap(imgname);
That gave the same problem, so I'm quite certain that it is a bug.
(Otherwise it might be that the qpixmap dissapears after the constructor call. Although Im not sure qpixmapitem becomes of a deep copy? If anyone knows the proper way to do it...)

[Edit: Thanks for checking it with valgrind! I normally test things using valgrind under linux, but on windows i have never used it.]