diff options
author | Martin Storsjo <martin@martin.st> | 2018-05-15 06:35:20 +0000 |
---|---|---|
committer | Martin Storsjo <martin@martin.st> | 2018-05-15 06:35:20 +0000 |
commit | 860e5fcdf4305c0681c4e77e17b22d2e54fe163b (patch) | |
tree | e6ab342b6301180bc62ec867d82e71fbd7371dac /llvm/tools/llvm-rc/ResourceFileWriter.cpp | |
parent | b7d50115ba4900da6db7afb6460ad42ff19ba6a2 (diff) | |
download | bcm5719-llvm-860e5fcdf4305c0681c4e77e17b22d2e54fe163b.tar.gz bcm5719-llvm-860e5fcdf4305c0681c4e77e17b22d2e54fe163b.zip |
[llvm-rc] Read the Planes/BitCount fields from BITMAPINFOHEADER for icons
Previously these fields were only read from this header for cursors,
while Planes was hardcoded to 1 for icons (with a comment that it was
unknown why this was needed) and BitCount was left at the value
read originally in the RESDIRENTRY.
This fixes the single byte that was differing for the icon/cursor test
compared to rc.exe.
This is based on research/testing by Nico Weber.
Differential Revision: https://reviews.llvm.org/D46816
llvm-svn: 332328
Diffstat (limited to 'llvm/tools/llvm-rc/ResourceFileWriter.cpp')
-rw-r--r-- | llvm/tools/llvm-rc/ResourceFileWriter.cpp | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.cpp b/llvm/tools/llvm-rc/ResourceFileWriter.cpp index f468fa67f52..70274b6e051 100644 --- a/llvm/tools/llvm-rc/ResourceFileWriter.cpp +++ b/llvm/tools/llvm-rc/ResourceFileWriter.cpp @@ -922,33 +922,39 @@ Error ResourceFileWriter::visitIconOrCursorResource(const RCResource *Base) { // Now, write all the headers concatenated into a separate resource. for (size_t ID = 0; ID < NumItems; ++ID) { - if (Type == IconCursorGroupType::Icon) { - // rc.exe seems to always set NumPlanes to 1. No idea why it happens. - ItemEntries[ID].Planes = 1; - continue; - } - - // We need to rewrite the cursor headers. + // We need to rewrite the cursor headers, and fetch actual values + // for Planes/BitCount. const auto &OldHeader = ItemEntries[ID]; - ResourceDirEntryStart NewHeader; - NewHeader.Cursor.Width = OldHeader.Icon.Width; - // Each cursor in fact stores two bitmaps, one under another. - // Height provided in cursor definition describes the height of the - // cursor, whereas the value existing in resource definition describes - // the height of the bitmap. Therefore, we need to double this height. - NewHeader.Cursor.Height = OldHeader.Icon.Height * 2; + ResourceDirEntryStart NewHeader = OldHeader; + + if (Type == IconCursorGroupType::Cursor) { + NewHeader.Cursor.Width = OldHeader.Icon.Width; + // Each cursor in fact stores two bitmaps, one under another. + // Height provided in cursor definition describes the height of the + // cursor, whereas the value existing in resource definition describes + // the height of the bitmap. Therefore, we need to double this height. + NewHeader.Cursor.Height = OldHeader.Icon.Height * 2; + + // Two WORDs were written at the beginning of the resource (hotspot + // location). This is reflected in Size field. + NewHeader.Size += 2 * sizeof(uint16_t); + } // Now, we actually need to read the bitmap header to find // the number of planes and the number of bits per pixel. Reader.setOffset(ItemOffsets[ID]); const BitmapInfoHeader *BMPHeader; RETURN_IF_ERROR(Reader.readObject(BMPHeader)); - NewHeader.Planes = BMPHeader->Planes; - NewHeader.BitCount = BMPHeader->BitCount; - - // Two WORDs were written at the beginning of the resource (hotspot - // location). This is reflected in Size field. - NewHeader.Size = OldHeader.Size + 2 * sizeof(uint16_t); + if (BMPHeader->Size == sizeof(BitmapInfoHeader)) { + NewHeader.Planes = BMPHeader->Planes; + NewHeader.BitCount = BMPHeader->BitCount; + } else { + // A PNG .ico file. + // https://blogs.msdn.microsoft.com/oldnewthing/20101022-00/?p=12473 + // "The image must be in 32bpp" + NewHeader.Planes = 1; + NewHeader.BitCount = 32; + } ItemEntries[ID] = NewHeader; } |