From 0f3b19b652b4e022f42732dfde5feb609d6df1be Mon Sep 17 00:00:00 2001 From: "mscott%netscape.com" Date: Tue, 10 Jul 2001 00:55:06 +0000 Subject: [PATCH] Bug #89181 --> dword align the moz-icon RGB data so they render at certain resolutions. r=pavlov sr=sspitzer --- .../decoders/icon/win/nsIconChannel.cpp | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp b/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp index 198123812629..adc720a9121f 100644 --- a/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp +++ b/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp @@ -44,6 +44,7 @@ // Takes a bitmap from the windows registry and converts it into 4 byte RGB data. void ConvertColorBitMap(unsigned char * aBitmapBuffer, PBITMAPINFO pBitMapInfo, nsCString& iconBuffer); void ConvertMaskBitMap(unsigned char * aBitMaskBuffer, PBITMAPINFOHEADER pBitMapInfo, nsCString& iconBuffer); +PRUint32 CalcWordAlignedRowSpan(PRUint32 aWidth, PRUint32 aBitCount); // nsIconChannel methods nsIconChannel::nsIconChannel() @@ -187,8 +188,15 @@ void ConvertColorBitMap(unsigned char * buffer, PBITMAPINFO pBitMapInfo, nsCStri // windows invers the row order in their bitmaps. So we need to invert the rows back into a top-down order. PRUint32 bytesPerPixel = pBitMapInfo->bmiHeader.biBitCount / 8; + PRUint32 unalignedBytesPerRow = pBitMapInfo->bmiHeader.biWidth * 3; InvertRows(buffer, pBitMapInfo->bmiHeader.biSizeImage, pBitMapInfo->bmiHeader.biWidth * bytesPerPixel); + PRUint32 alignedBytesPerRow = CalcWordAlignedRowSpan(pBitMapInfo->bmiHeader.biWidth, 24); + PRInt32 numBytesPaddingPerRow = alignedBytesPerRow - unalignedBytesPerRow; + PRUint32 pos = 0; + if (numBytesPaddingPerRow < 0) // this should never happen..... + numBytesPaddingPerRow = 0; + PRUint32 index = 0; // if each pixel uses 16 bits to describe the color then each R, G, and B value uses 5 bites. Use some fancy // bit operations to blow up the 16 bit case into 1 byte per component color. Actually windows @@ -222,6 +230,15 @@ void ConvertColorBitMap(unsigned char * buffer, PBITMAPINFO pBitMapInfo, nsCStri iconBuffer.Append((char) blueValue); iconBuffer.Append((char) greenValue); iconBuffer.Append((char) redValue); + pos += bytesPerPixel; + if (pos == unalignedBytesPerRow && numBytesPaddingPerRow) // if we have reached the end of a current row, add padding to force dword alignment + { + pos = 0; + for (PRUint32 i = 0; i < numBytesPaddingPerRow; i++) + { + iconBuffer.Append((char) 0); + } + } index += bytesPerPixel; } } @@ -232,11 +249,34 @@ void ConvertColorBitMap(unsigned char * buffer, PBITMAPINFO pBitMapInfo, nsCStri iconBuffer.Append((char) buffer[index]); iconBuffer.Append((char) buffer[index+1]); iconBuffer.Append((char) buffer[index+2]); + pos += 3; + if (pos == unalignedBytesPerRow && numBytesPaddingPerRow) // if we have reached the end of a current row, add padding to force dword alignment + { + pos = 0; + for (PRUint32 i = 0; i < numBytesPaddingPerRow; i++) + { + iconBuffer.Append((char) 0); + } + } index += bytesPerPixel; } } } +PRUint32 CalcWordAlignedRowSpan(PRUint32 aWidth, PRUint32 aBitCount) +{ + PRUint32 spanBytes; + + spanBytes = (aWidth * aBitCount) >> 5; + + if (((PRUint32) aWidth * aBitCount) & 0x1F) + spanBytes++; + + spanBytes <<= 2; + + return spanBytes; +} + void ConvertMaskBitMap(unsigned char * aBitMaskBuffer, PBITMAPINFOHEADER pBitMapHeaderInfo, nsCString& iconBuffer) { InvertRows(aBitMaskBuffer, pBitMapHeaderInfo->biSizeImage, 4);