Bug 668068 - ICO width/height of 0 should mean 256 width/height. r=joe

This commit is contained in:
Brian R. Bondy 2011-09-22 09:43:13 -04:00
Родитель dfc23f5812
Коммит 8a7e8ca8b8
24 изменённых файлов: 60 добавлений и 19 удалений

Просмотреть файл

@ -71,7 +71,7 @@ PRUint32
nsICODecoder::CalcAlphaRowSize()
{
// Calculate rowsize in DWORD's and then return in # of bytes
PRUint32 rowSize = (mDirEntry.mWidth + 31) / 32; // +31 to round up
PRUint32 rowSize = (GetRealWidth() + 31) / 32; // + 31 to round up
return rowSize * 4; // Return rowSize in bytes
}
@ -149,10 +149,10 @@ PRBool nsICODecoder::FillBitmapFileHeaderBuffer(PRInt8 *bfh)
return PR_FALSE;
}
dataOffset += 4 * numColors;
fileSize = dataOffset + mDirEntry.mWidth * mDirEntry.mHeight;
fileSize = dataOffset + GetRealWidth() * GetRealHeight();
} else {
fileSize = dataOffset + (mDirEntry.mBitCount * mDirEntry.mWidth *
mDirEntry.mHeight) / 8;
fileSize = dataOffset + (mDirEntry.mBitCount * GetRealWidth() *
GetRealHeight()) / 8;
}
fileSize = NATIVE32_TO_LITTLE(fileSize);
@ -168,7 +168,7 @@ PRBool nsICODecoder::FillBitmapFileHeaderBuffer(PRInt8 *bfh)
void
nsICODecoder::FillBitmapInformationBufferHeight(PRInt8 *bih)
{
PRInt32 height = mDirEntry.mHeight;
PRInt32 height = GetRealHeight();
height = NATIVE32_TO_LITTLE(height);
memcpy(bih + 8, &height, sizeof(height));
}
@ -265,8 +265,11 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
(mCurrIcon * sizeof(mDirEntryArray))) {
mCurrIcon++;
ProcessDirEntry(e);
if ((e.mWidth == PREFICONSIZE && e.mHeight == PREFICONSIZE &&
e.mBitCount >= colorDepth) ||
// We can't use GetRealWidth and GetRealHeight here because those operate
// on mDirEntry, here we are going through each item in the directory
if (((e.mWidth == 0 ? 256 : e.mWidth) == PREFICONSIZE &&
(e.mHeight == 0 ? 256 : e.mHeight) == PREFICONSIZE &&
(e.mBitCount >= colorDepth)) ||
(mCurrIcon == mNumIcons && mImageOffset == 0)) {
mImageOffset = e.mImageOffset;
@ -477,11 +480,11 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
// The alpha mask should be checked in all other cases.
if (static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetBitsPerPixel() != 32 ||
!static_cast<nsBMPDecoder*>(mContainedDecoder.get())->HasAlphaData()) {
PRUint32 rowSize = ((mDirEntry.mWidth + 31) / 32) * 4; // + 31 to round up
PRUint32 rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
if (mPos == bmpDataEnd) {
mPos++;
mRowBytes = 0;
mCurLine = mDirEntry.mHeight;
mCurLine = GetRealHeight();
mRow = (PRUint8*)moz_realloc(mRow, rowSize);
if (!mRow) {
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
@ -515,8 +518,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
PostDataError();
return;
}
PRUint32* decoded = imageData + mCurLine * mDirEntry.mWidth;
PRUint32* decoded_end = decoded + mDirEntry.mWidth;
PRUint32* decoded = imageData + mCurLine * GetRealWidth();
PRUint32* decoded_end = decoded + GetRealWidth();
PRUint8* p = mRow, *p_end = mRow + rowSize;
while (p < p_end) {
PRUint8 idx = *p++;

Просмотреть файл

@ -61,6 +61,18 @@ public:
nsICODecoder();
virtual ~nsICODecoder();
// Obtains the width of the icon directory entry
PRUint32 GetRealWidth() const
{
return mDirEntry.mWidth == 0 ? 256 : mDirEntry.mWidth;
}
// Obtains the height of the icon directory entry
PRUint32 GetRealHeight() const
{
return mDirEntry.mHeight == 0 ? 256 : mDirEntry.mHeight;
}
virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
virtual void FinishInternal();

Просмотреть файл

@ -178,8 +178,8 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
aStride, aInputFormat, params);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 andMaskSize = ((mICODirEntry.mWidth + 31) / 32) * 4 * // row AND mask
mICODirEntry.mHeight; // num rows
PRUint32 andMaskSize = ((GetRealWidth() + 31) / 32) * 4 * // row AND mask
GetRealHeight(); // num rows
PRUint32 imageBufferSize;
mContainedEncoder->GetImageBufferSize(&imageBufferSize);
@ -204,15 +204,15 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
memcpy(mImageBufferCurr, imageBuffer + BFH_LENGTH,
imageBufferSize - BFH_LENGTH);
// We need to fix the BMP height to be *2 for the AND mask
PRUint32 fixedHeight = mICODirEntry.mHeight * 2;
PRUint32 fixedHeight = GetRealHeight() * 2;
fixedHeight = NATIVE32_TO_LITTLE(fixedHeight);
// The height is stored at an offset of 8 from the DIB header
memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight));
mImageBufferCurr += imageBufferSize - BFH_LENGTH;
// Calculate rowsize in DWORD's
PRUint32 rowSize = ((mICODirEntry.mWidth + 31) / 32) * 4; // + 31 to round up
PRInt32 currentLine = mICODirEntry.mHeight;
PRUint32 rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
PRInt32 currentLine = GetRealHeight();
// Write out the AND mask
while (currentLine > 0) {
@ -250,7 +250,7 @@ NS_IMETHODIMP nsICOEncoder::StartImageEncode(PRUint32 aWidth,
}
// Icons are only 1 byte, so make sure our bitmap is in range
if (aWidth > 255 || aHeight > 255) {
if (aWidth > 256 || aHeight > 256) {
return NS_ERROR_INVALID_ARG;
}
@ -263,7 +263,9 @@ NS_IMETHODIMP nsICOEncoder::StartImageEncode(PRUint32 aWidth,
mUsePNG = usePNG;
InitFileHeader();
InitInfoHeader(bpp, (PRUint8)aWidth, (PRUint8)aHeight); // range checks above
// The width and height are stored as 0 when we have a value of 256
InitInfoHeader(bpp, aWidth == 256 ? 0 : (PRUint8)aWidth,
aHeight == 256 ? 0 : (PRUint8)aHeight);
return NS_OK;
}

Просмотреть файл

@ -68,6 +68,18 @@ public:
nsICOEncoder();
~nsICOEncoder();
// Obtains the width of the icon directory entry
PRUint32 GetRealWidth() const
{
return mICODirEntry.mWidth == 0 ? 256 : mICODirEntry.mWidth;
}
// Obtains the height of the icon directory entry
PRUint32 GetRealHeight() const
{
return mICODirEntry.mHeight == 0 ? 256 : mICODirEntry.mHeight;
}
protected:
nsresult ParseOptions(const nsAString& aOptions, PRUint32* bpp,
@ -92,7 +104,9 @@ protected:
// or if no encoding options specified will use the default (PNG)
nsCOMPtr<imgIEncoder> mContainedEncoder;
// These headers will always contain endian independent stuff
// These headers will always contain endian independent stuff.
// Don't trust the width and height of mICODirEntry directly,
// instead use the accessors GetRealWidth() and GetRealHeight().
mozilla::imagelib::IconFileHeader mICOFileHeader;
mozilla::imagelib::IconDirEntry mICODirEntry;

Просмотреть файл

@ -101,6 +101,7 @@ HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.
HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon
HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon
HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon
HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon
# ICO using image/vnd.microsoft.icon mime type and 32bpp parse options with bmp
HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
@ -118,6 +119,7 @@ HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.
HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
# ICO using image/vnd.microsoft.icon mime type and 24bpp parse options with bmp
HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
@ -135,6 +137,7 @@ HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.
HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
# ICO using image/vnd.microsoft.icon mime type png
HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
@ -152,4 +155,5 @@ HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.
HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng

Двоичные данные
modules/libpr0n/test/reftest/encoders-lossless/size-256x256.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Просмотреть файл

@ -16,6 +16,7 @@
== ico-size-31x31-1bpp.ico ico-size-31x31-1bpp.png
== ico-size-32x32-1bpp.ico ico-size-32x32-1bpp.png
== ico-size-33x33-1bpp.ico ico-size-33x33-1bpp.png
== ico-size-256x256-1bpp.ico ico-size-256x256-1bpp.png
== ico-partial-transparent-1bpp.ico ico-partial-transparent-1bpp.png
== ico-transparent-1bpp.ico ico-transparent-1bpp.png
== ico-not-square-transparent-1bpp.ico ico-not-square-transparent-1bpp.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 200 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

Просмотреть файл

@ -16,6 +16,7 @@
== ico-size-31x31-24bpp.ico ico-size-31x31-24bpp.png
== ico-size-32x32-24bpp.ico ico-size-32x32-24bpp.png
== ico-size-33x33-24bpp.ico ico-size-33x33-24bpp.png
== ico-size-256x256-24bpp.ico ico-size-256x256-24bpp.png
== ico-partial-transparent-24bpp.ico ico-partial-transparent-24bpp.png
== ico-transparent-24bpp.ico ico-transparent-24bpp.png
== ico-not-square-transparent-24bpp.ico ico-not-square-transparent-24bpp.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 264 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

Просмотреть файл

@ -16,6 +16,7 @@
== ico-size-31x31-32bpp.ico ico-size-31x31-32bpp.png
== ico-size-32x32-32bpp.ico ico-size-32x32-32bpp.png
== ico-size-33x33-32bpp.ico ico-size-33x33-32bpp.png
== ico-size-256x256-32bpp.ico ico-size-256x256-32bpp.png
== ico-partial-transparent-32bpp.ico ico-partial-transparent-32bpp.png
== ico-transparent-32bpp.ico ico-transparent-32bpp.png
== ico-not-square-transparent-32bpp.ico ico-not-square-transparent-32bpp.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 40 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Просмотреть файл

@ -16,6 +16,7 @@
== ico-size-31x31-4bpp.ico ico-size-31x31-4bpp.png
== ico-size-32x32-4bpp.ico ico-size-32x32-4bpp.png
== ico-size-33x33-4bpp.ico ico-size-33x33-4bpp.png
== ico-size-256x256-4bpp.ico ico-size-256x256-4bpp.png
== ico-partial-transparent-4bpp.ico ico-partial-transparent-4bpp.png
== ico-transparent-4bpp.ico ico-transparent-4bpp.png
== ico-not-square-transparent-4bpp.ico ico-not-square-transparent-4bpp.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 73 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 22 KiB

Просмотреть файл

@ -16,6 +16,7 @@
== ico-size-31x31-8bpp.ico ico-size-31x31-8bpp.png
== ico-size-32x32-8bpp.ico ico-size-32x32-8bpp.png
== ico-size-33x33-8bpp.ico ico-size-33x33-8bpp.png
== ico-size-256x256-8bpp.ico ico-size-256x256-8bpp.png
== ico-partial-transparent-8bpp.ico ico-partial-transparent-8bpp.png
== ico-transparent-8bpp.ico ico-transparent-8bpp.png
== ico-not-square-transparent-8bpp.ico ico-not-square-transparent-8bpp.png

Двоичные данные
modules/libpr0n/test/reftest/ico/ico-png/ico-size-256x256-png.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Двоичные данные
modules/libpr0n/test/reftest/ico/ico-png/ico-size-256x256-png.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Просмотреть файл

@ -16,6 +16,7 @@
== ico-size-31x31-png.ico ico-size-31x31-png.png
== ico-size-32x32-png.ico ico-size-32x32-png.png
== ico-size-33x33-png.ico ico-size-33x33-png.png
== ico-size-256x256-png.ico ico-size-256x256-png.png
# Corrupted files so no image should be loaded
# x00n0g01 - empty 0x0 grayscale file