Added: better detection of jpeg size

This commit is contained in:
vl 2010-07-08 16:01:01 +02:00
parent 8366c51608
commit 83a4a51b1e

View file

@ -3052,9 +3052,14 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
break; break;
} }
// end of file chunk
else if (chunkName == NL_MAKEFOURCC('I', 'E', 'N', 'D'))
{
break;
}
// skip data of this chunk // skip data of this chunk and CRC32
f.seek(chunkLength, IStream::current); f.seek(chunkLength+4, IStream::current);
} }
catch(...) catch(...)
{ {
@ -3065,7 +3070,8 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
} }
else if(fileType == JPG_HEADER) else if(fileType == JPG_HEADER)
{ {
uint16 blockMarker = 0; uint8 blockMarker1 = 0;
uint8 blockMarker2 = 0;
uint16 blockSize = 0; uint16 blockSize = 0;
bool eof = false; bool eof = false;
@ -3073,39 +3079,67 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
{ {
try try
{ {
// since we read the first marker // marker of a block
// we should skip this (blockSize should not be equal to zero) f.serial(blockMarker1);
if (blockSize > 1)
if (blockMarker1 == 0xff)
{ {
// marker of a block // marker of a block
f.serial(blockMarker); f.serial(blockMarker2);
NLMISC_BSWAP16(blockMarker);
// 0xff00 is only found in image data
if (blockMarker2 == 0x00)
{
// image data 0xff
}
// 0xffda is image data
else if (blockMarker2 == 0xda)
{
// next data is image data which must end with 0xffd9
}
// 0xffd9 is the end of an image // 0xffd9 is the end of an image
if (blockMarker == 0xffd9) break; else if (blockMarker2 == 0xd9)
{
// real end of file
break;
}
else if (blockMarker2 == 0xdd || blockMarker2 == 0xdc)
{
f.seek(4, IStream::current);
}
else if (blockMarker2 == 0xdf)
{
f.seek(3, IStream::current);
}
else if (blockMarker2 >= 0xd0 && blockMarker2 <= 0xd8)
{
// no content
}
else
{
// size of a block
f.serial(blockSize);
NLMISC_BSWAP16(blockSize);
// frame marker (which contains image width and height)
if (blockMarker2 >= 0xc0 && blockMarker2 <= 0xc3)
{
uint8 imagePrecision = 0; // sample precision
uint32 imageSize = 0; // width and height
f.serial(imagePrecision);
f.serial(imageSize);
NLMISC_BSWAP32(imageSize);
retWidth = imageSize & 0xffff;
retHeight = (imageSize & 0xffff0000) >> 16;
break;
}
// skip the block
f.seek(blockSize - 2, IStream::current);
}
} }
// size of a block
f.serial(blockSize);
NLMISC_BSWAP16(blockSize);
// frame marker (which contains image width and height)
if (blockMarker >= 0xffc0 && blockMarker <= 0xffc3)
{
uint8 imagePrecision = 0; // sample precision
uint32 imageSize = 0; // width and height
f.serial(imagePrecision);
f.serial(imageSize);
NLMISC_BSWAP32(imageSize);
retWidth = imageSize & 0xffff;
retHeight = (imageSize & 0xffff0000) >> 16;
break;
}
// skip the block
f.seek(blockSize - 2, IStream::current);
} }
catch(...) catch(...)
{ {