PDA

View Full Version : loadFromData() of QImage crash in case of .gif loading



santosh.kumar
4th March 2011, 09:31
HI
I m using Qt 4.4.3 on Windows. I m using loadfromData function of QImage.
But sometimes it crashes while loading .gif files.

Sample code for this:

unsigned char *qBuffer= new unsigned char[SizeToRead-BytesToIgnore];
memset(qBuffer,0x00,SizeToRead-BytesToIgnore);
memcpy(qBuffer,(const void*)&pBuff[BytesToIgnore],SizeToRead-BytesToIgnore);
QImage image;
image.loadFromData(qBuffer,(SizeToRead-BytesToIgnore));//Load Image from the UChar * array qbuffer


Crash happens in image.loadFromData(qBuffer,(SizeToRead-BytesToIgnore)); for corrupt gif image.

Collect the Call Stack of Crash from Attachment.

Kindly tell me solution.



Thanks

wysota
4th March 2011, 11:12
I don't think the code is correct. loadFromData() requires a valid image format header and it seems you have it filled with zeroes.

santosh.kumar
4th March 2011, 11:29
I don't think the code is correct. loadFromData() requires a valid image format header and it seems you have it filled with zeroes.

I have also try with
image.loadFromData(qBuffer,(SizeToRead-BytesToIgnore),"GIF");

It again crashes..

wysota
4th March 2011, 11:34
Your buffer still doesn't contain the image header. Do you understand what I mean?

santosh.kumar
4th March 2011, 12:36
Your buffer still doesn't contain the image header. Do you understand what I mean?

I have debugg and checked the Starting some byte/signature. it is the GIF file's signature in which it is crashing.

If you are saying some other way, kindly tell me soon..

Thanks
Santosh

wysota
4th March 2011, 12:43
Your image header contains zeroes while it should contain a proper GIF header that informs about things as the dimensions of the image, depth, then the color map, etc.
To me it seems you are only passing (partial) pixel data and this is not enough. Either create a proper gif header and include it in your buffer or create the QImage object manually and use QImage::bits() to fill it with data in a format compliant with the pixel format (e.g. premultiplied RGBA) of the image you passed when constructing your QImage object.

santosh.kumar
7th March 2011, 07:17
Your image header contains zeroes while it should contain a proper GIF header that informs about things as the dimensions of the image, depth, then the color map, etc.
To me it seems you are only passing (partial) pixel data and this is not enough. Either create a proper gif header and include it in your buffer or create the QImage object manually and use QImage::bits() to fill it with data in a format compliant with the pixel format (e.g. premultiplied RGBA) of the image you passed when constructing your QImage object.

/*Your image header contains zeroes while it should contain a proper GIF header that informs about things as the dimensions of the image, depth, then the color map, etc.*/

In our code, buffer contains the GIF data in hex format, and ofcourse it contains the Starting Header of GIF in Hexformat.


/*To me it seems you are only passing (partial) pixel data and this is not enough.*/
No we are sending complete size of GIF data up to files size.

/*or create the QImage object manually and use QImage::bits() to fill it with data in a format compliant with the pixel format (e.g. premultiplied RGBA) of the image you passed when constructing your QImage object.*/

Kindly we can work in last sent solution. But we have no QImage's object so how we can

uchar* imagedata = image.bits();
we have buffer up to Imagesize, we can use loadFromData() in this case.

Can I use like this

QImage image;
uchar *data1 = QImage::bits();
memcpy(data1,pBuffer,size);
loadFromData(data1,size,"GIF");
Kindly sent one example for this...

wysota
7th March 2011, 10:45
In our code, buffer contains the GIF data in hex format, and ofcourse it contains the Starting Header of GIF in Hexformat.
So what does the following return?

QByteArray ba(&pBuff[BytesToIgnore], 4);
qDebug() << "Header present:" << (ba=="GIF8" ? "Yes" : "No");


Can I use like this

QImage image;
uchar *data1 = QImage::bits();
memcpy(data1,pBuffer,size);
loadFromData(data1,size,"GIF");
If you send me code such as this then you have no idea what you are doing. loadFromData() expects to receive a full file in GIF format (in your case) while bits() needs to be initalized with pure pixel data in the format compliant with what was set on QImage (which is certainly not what your pBuffer contains).

santosh.kumar
7th March 2011, 12:29
So what does the following return?

QByteArray ba(&pBuff[BytesToIgnore], 4);
qDebug() << "Header present:" << (ba=="GIF8" ? "Yes" : "No");


If you send me code such as this then you have no idea what you are doing. loadFromData() expects to receive a full file in GIF format (in your case) while bits() needs to be initalized with pure pixel data in the format compliant with what was set on QImage (which is certainly not what your pBuffer contains).


We are working on Signature found software that scan each file according to signature. Our software read harddrive and search signature for each file.
just for signature of GIF is as:

unsigned char signature1[] = {0x47, 0x49, 0x46, 0x38, 0x39, 0x61}; ///GIF89a
unsigned char signature2[] = {0x47, 0x49, 0x46, 0x38, 0x37, 0x61}; ///GIF87a

/*

Data inside buffer is like

47 49 46 38 39 61 FA 00 42 00 F7 00 00 00 00 00 FF FF FF 1B 33 82 F9 F9 FC FA FA FC FE FE FF FD FD FE ED EE F5 DD DF EB E1 E3 EE F0 F1 F7 01 14 6F D8 DB E9 F1 F2 F7 4D 5D 9D 68 75 AA B0 B7 D3 D1 D5 E6 DE E1 EE DE E1 ED DD E0 EC E8 EA F2 F5 F6 FA F4 F5 F9 F2 F3 F7 18 2F 80 1B 31 82 1C 33 82 1E 35 84 2A 3F 8A 3C 4F 94 3C 4F 93 44 57 98 46 59 9A 4E 60 9E 5C 6B A4 62 72 A9 62 71 A8 6A 79 AD 6D 7B AE 73 81 B2 75 83 B4 7A 86 B5 7E 8B B8 84 90 BB 89 95 BE 88 94 BD 93 9E C4 9C A6 C9 9B A5 C8 A4 AD CD A6 AF CE A5 AE CD AD B5 D2 AF B7 D3 B2 B9 D4 B4 BB D6 B6 BD D7 B7 BE D7 B8 BF D8 BB C2 DA BA C1 D9 BF C5 DC C5 CB E0 C4 CA DF C9 CE E1 CB D0 E2 CC D1 E3 D5 D9 E8 D7 DB E9 D6 DA E8 DF E2 ED EB ED F4 04 1E 75 07 21 77 07 21 76 08 22 78 09 24 79 0A 25 7A 0A 24 79 0A 23 78 0C 25 7A 0C 25 79 0D 27 7B 0D 26 7A 0E 27 7B 0F 29 7C 0F 28 7B 10 29 7C 10 2A 7B 11 2A 7C 12 2B
*/


This buffer contains the GIF Header and we also pass "GIF" as third argument in loadFromData();

I m not saying loadFromData() is always crashing, it crashes in some GIF files.
Our code

QImage image;
image.loadFromData(&pBuff[offset],FileSize-Offset,"GIF");
if(image.isNull())
{
}
else
{
}

/////////////////
But you are saying QImage::bits() will use for initialize image upto total pixel.

QImage image( /* what parameter will use */ );
uchar* data1 = image.bits();

It just return pointer of header of file.

Am i doing something wrong....But how we use this in loadFromData().
because image.loadFromData() is crashing

small crash report is as follows:

QtCored4.dll!QBasicAtomic::deref() Line 76 + 0x10 bytes C++
QtCored4.dll!QByteArray::operator=(const QByteArray & other={...}) Line 795 + 0x8 bytes C++
QtGuid4.dll!QImageReader::read(QImage * image=0x0012d478) Line 977 + 0x21 bytes C++
QtGuid4.dll!QImageReader::read() Line 921 + 0xc bytes C++
QtGuid4.dll!QImage::fromData(const unsigned char * data=0x0202c028, int size=0x0000ba00, const char * format=0x01f71cf8) Line 4123 + 0x3a bytes C++
QtGuid4.dll!QImage::loadFromData(const unsigned char * data=0x0202c028, int len=0x0000ba00, const char * format=0x01f71cf8) Line 4087 + 0x15 bytes C++
StellarPhoenixPhotoRecovery.exe!QFileView::GetItem Preview(void * DosDir=0x01a0f638, QString strFormat={...}) Line 1897 + 0x5a bytes C++
StellarPhoenixPhotoRecovery.exe!QFileView::qt_meta call(QMetaObject::Call _c=InvokeMetaMethod, int _id=0x0000000a, void * * _a=0x0012dacc)Line 157 + 0x27 bytes C++
QtCored4.dll!QMetaObject::activate(QObject * sender=0x0141b858, int from_signal_index=0x0000000b, int to_signal_index=0x0000000b, void * * argv=0x0012dacc) QtCored4.dll!QMetaObject::activate(QObject * sender=0x0141b858, const QMetaObject * m=0x0070b8fc, int local_signal_index=0x00000000, void * * argv=0x0012dacc) Line
StellarPhoenixPhotoRecovery.exe!QRawRecoveryThread ::GetFilePreview(void * _t1=0x01a0f638, QString _t2={...}) Line 118 + 0x15 bytes C++


Thanks
Santosh

wysota
7th March 2011, 12:46
Am i doing something wrong....But how we use this in loadFromData().
because image.loadFromData() is crashing
It will be crashing because you pass it invalid data. If you want to work on a corrupt image, it's best to do all the decoding yourself and then fill QImage with proper data manually.

First create an emtpy QImage object with a defined size and format (QImage::Format_Indexed8 will probably be best for a gif image).
Then fill the color table based on the data from the corrupt file.
Then fill pixel data either using QImage::setPixel or with QImage::bits() if you have the data in a proper format. The data needs to be formatted linearly and it should contain indexes of the color table. You can't just copy the data straight into the pixel buffer of QImage because GIF stores it compressed, so you need to decompress it first manually.

santosh.kumar
9th March 2011, 05:44
It will be crashing because you pass it invalid data. If you want to work on a corrupt image, it's best to do all the decoding yourself and then fill QImage with proper data manually.

First create an emtpy QImage object with a defined size and format (QImage::Format_Indexed8 will probably be best for a gif image).
Then fill the color table based on the data from the corrupt file.
Then fill pixel data either using QImage::setPixel or with QImage::bits() if you have the data in a proper format. The data needs to be formatted linearly and it should contain indexes of the color table. You can't just copy the data straight into the pixel buffer of QImage because GIF stores it compressed, so you need to decompress it first manually.

I m so confused, can u send some sample code for this... Can u tell me some easiest soltuin for this..
Our software will scan a lakh/multi thousand files and show the preveiw of all files one by one. So GIF or other files's preview process should be fast.

Is there any alternative or kind send some sample code for this
Thanks
Santosh

wysota
9th March 2011, 11:52
I m so confused, can u send some sample code for this...
No, I can't. I don't intend to do your work for you.

Can u tell me some easiest soltuin for this..
Sure. Pay someone to write the application for you.