Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read image files with QImageReader using QtConcurrent

I am trying to use QImageReader to read portions of an image file at a time (per Tile), so that for very large images they are not read into memory from disk until they need to be displayed.

It seems liek I am running into some thread safety issues.

This is what I currently have:

#include "rastertile.h"

QMutex RasterTile::mutex;
RasterTile::RasterTile()
{
}

//RasterTile::RasterTile(QImageReader *reader, int nBlocksX, int nBlocksY, int xoffset, int yoffset, int nXBlockSize, int nYBlockSize)
RasterTile::RasterTile(QString filename, int nBlocksX, int nBlocksY, int xoffset, int yoffset, int nXBlockSize, int nYBlockSize)

    : Tile(nBlocksX, nBlocksY, xoffset, yoffset, nXBlockSize, nYBlockSize)
{
        this->reader = new QImageReader(filename);
        connect(&watcher,SIGNAL(finished()),this,SLOT(updateSceneSlot()));
}


void RasterTile::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    if(image.isNull())
    {
        TilePainter=painter;
        TileOption=option;
        TileWidget=widget;
        future = QtConcurrent::run(this, &RasterTile::LoadTilePixmap);
        watcher.setFuture(future);

    }else
    {
        QRectF imageRect = image.rect();
        painter->drawImage(imageRect, image);
    }

}

QImage RasterTile::LoadTilePixmap()
{
    QMutexLocker locker(&mutex);

    QImage img(nBlockXSize, nBlockYSize, QImage::Format_RGB32);

    QRect rect(tilePosX*nBlockXSize, tilePosY*nBlockYSize, nBlockXSize, nBlockYSize);

    reader->setClipRect(rect);
    reader->read(&img);
    if(reader->error())
    {
        qDebug("Not null error");
        qDebug()<<"Error string is: "<<reader->errorString();
    }
    return img;

}

So this is basically instantiating a new reader for each tile, and update the "image" variable of the superclass, which I can then paint.

This seems to give me a lot of errors from the reader, which simply say "Unable to read image data"

I think this is probably something to do with many tiles accessing the same file, but I dont know how to prove that, or fix it.

I think Qt uses libjpeg and libpng and whatever else to read various image formats.

like image 830
Derek Avatar asked Jun 23 '11 19:06

Derek


1 Answers

Check out the source code of QImageReader.

You will get "Unable to read image data" when the reader returns InvalidDataError.

If you also read the explanation of InvalidDataError QT Doc says that

The image data was invalid, and QImageReader was unable to read an image from it. The can happen if the image file is damaged.

So probably your file is corrupt.

like image 151
O.C. Avatar answered Sep 28 '22 23:09

O.C.