Tomáš Zato
Tomáš Zato

Reputation: 53129

When can I delete data provided to QImage?

I create QImage like this:

unsigned char* const rawImage = (unsigned char*)std::malloc(WIDTH*HEIGHT*3);
for ( ... ) {
    // Populate the image here
}
QImage img(rawImage, WIDTH, HEIGHT, QImage::Format_RGB888);

I then post signal with that image to another thread (GUI thread in particular):

emit imageRendered(img);

I thought I can delete the data afterwards:

delete rawImage;

But this causes segmentation errors in the other thread. If I do not delete the raw image, the program consumes all available memory. How to make safe copy of QImage so that I can delete my raw data?

Upvotes: 0

Views: 1287

Answers (1)

dtech
dtech

Reputation: 49289

The documentation is pretty specific on the subject:

The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer. The image does not delete the buffer at destruction. You can provide a function pointer cleanupFunction along with an extra pointer cleanupInfo that will be called when the last copy is destroyed.

You'd use the following constructor:

QImage::QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR)

Pretty much what you have safe for the actual clean up pointers.

As for making an actual copy of the data, keeping in mind QImage uses CoW, calling a non-const function might do the trick (haven't tested it myself though):

uchar *QImage::bits()

Note that QImage uses implicit data sharing. This function performs a deep copy of the shared pixel data, thus ensuring that this QImage is the only one using the current return value.

You might also try simply auto newImage = img.copy();

Upvotes: 1

Related Questions