Skip to content

Commit

Permalink
[llvm-rc] Serialize CURSOR and ICON resources to .res
Browse files Browse the repository at this point in the history
This is part 6 of llvm-rc serialization.

This adds ability to output cursors and icons as resources.

Unfortunately, we can't just copy .cur or .ico files to output - as each
file might contain multiple images, each of them needs to be unpacked
and stored as a separate resource. This forces us to parse cursor and
icon contents. (Fortunately, these formats are pretty similar and can be
processed by mostly common code).

As test files are binary, here is a short explanation of .cur and .ico
files stored:

cursor.cur, cursor-8.cur, cursor-32.cur are sample correct cursor files,
differing in their bit depth.

icon-old.ico, icon-new.ico are sample correct icon files;

icon-png.ico is a sample correct icon file in PNG format (instead of
usual BMP);

cursor-eof.cur is an incorrect cursor file - this is cursor.cur with
some of its final bytes removed.

cursor-bad-offset.cur is an incorrect cursor file - image header states
that image data begins at offset 0xFFFFFFFF.

Sample correct cursors and icons were created by Nico Weber.

Patch by Marek Sokolowski
Differential Revision: https://reviews.llvm.org/D37878

llvm-svn: 315109
  • Loading branch information
Zachary Turner committed Oct 6, 2017
1 parent b6b210e commit c3ab013
Show file tree
Hide file tree
Showing 11 changed files with 672 additions and 4 deletions.
2 changes: 2 additions & 0 deletions llvm/test/tools/llvm-rc/Inputs/tag-icon-cursor-bad-offset.rc
@@ -0,0 +1,2 @@
50 CURSOR "cursor-bad-offset.cur"

1 change: 1 addition & 0 deletions llvm/test/tools/llvm-rc/Inputs/tag-icon-cursor-bad-type.rc
@@ -0,0 +1 @@
100 ICON "cursor.cur"
1 change: 1 addition & 0 deletions llvm/test/tools/llvm-rc/Inputs/tag-icon-cursor-eof.rc
@@ -0,0 +1 @@
72 CURSOR "cursor-eof.cur"
@@ -0,0 +1 @@
500 CURSOR "this-file-does-not-exist.cur"
1 change: 1 addition & 0 deletions llvm/test/tools/llvm-rc/Inputs/tag-icon-cursor-nonsense.rc
@@ -0,0 +1 @@
1 ICON "tag-icon-cursor-nonsense.rc"
6 changes: 6 additions & 0 deletions llvm/test/tools/llvm-rc/Inputs/tag-icon-cursor.rc
@@ -0,0 +1,6 @@
4464 CURSOR "cursor.cur"
4465 CUrsoR "cursor-8.cur"
100 ICON "icon-old.ico"
4466 cURSOR "cursor-32.cur"
100 ICON "icon-new.ico"
100 iCon "icon-png.ico"
357 changes: 357 additions & 0 deletions llvm/test/tools/llvm-rc/tag-icon-cursor.test
@@ -0,0 +1,357 @@
; This .ico file used to write this test was lost when the author left
; before comitting, and the binary wasn't uploaded to Phabricator. This
; will be fixed as soon as we can recover the file.
; XFAIL: *
; RUN: rm -rf %t
; RUN: mkdir %t
; RUN: cd %t
; RUN: cp %p/Inputs/icon*.ico .
; RUN: cp %p/Inputs/cursor*.cur .
; RUN: cp %p/Inputs/tag-icon-cursor-nonsense.rc .

; RUN: llvm-rc /FO %t/tag-icon-cursor.res %p/Inputs/tag-icon-cursor.rc
; RUN: llvm-readobj %t/tag-icon-cursor.res | FileCheck %s

; CHECK: Resource type (int): 1
; CHECK-NEXT: Resource name (int): 1
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 308
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 0A000B00 28000000 20000000 40000000 |....(... ...@...|
; CHECK-NEXT: 0010: 01000100 00000000 80000000 00000000 |................|
; CHECK-NEXT: 0020: 00000000 02000000 00000000 00000000 |................|
; (...)
; CHECK-DAG: 0110: FFFFFFFF FFFFFFFF FFFFFFFF F3CFFFFF |................|
; CHECK-NEXT: 0120: F3CFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
; CHECK-NEXT: 0130: FFFFFFFF |....|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 12
; CHECK-NEXT: Resource name (int): 4464
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1030
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 20
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 00000200 01002000 40000100 01003401 |...... .@.....4.|
; CHECK-NEXT: 0010: 00000100 |....|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 1
; CHECK-NEXT: Resource name (int): 2
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 2220
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 01000C00 28000000 20000000 40000000 |....(... ...@...|
; CHECK-NEXT: 0010: 01000800 00000000 00040000 00000000 |................|
; CHECK-NEXT: 0020: 00000000 00010000 00000000 00000000 |................|
; (...)
; CHECK-DAG: 0880: C001FFFF F557FFFF F557FFFF F551FFFF |.....W...W...Q..|
; CHECK-NEXT: 0890: C005FFFF B557FFFF F557FFFF F557FFFF |.....W...W...W..|
; CHECK-NEXT: 08A0: C001FFFF F557FFFF FFFFFFFF |.....W......|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 12
; CHECK-NEXT: Resource name (int): 4465
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1030
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 20
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 00000200 01002000 40000100 0800AC08 |...... .@.......|
; CHECK-NEXT: 0010: 00000200 |....|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 3
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 1128
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 10000000 20000000 01002000 |(....... ..... .|
; CHECK-NEXT: 0010: 00000000 00040000 C30E0000 C30E0000 |................|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 0440: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0450: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0460: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 4
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 2440
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 18000000 30000000 01002000 |(.......0..... .|
; CHECK-NEXT: 0010: 00000000 00090000 C30E0000 C30E0000 |................|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 0960: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0970: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0980: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 5
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 4264
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 20000000 40000000 01002000 |(... ...@..... .|
; CHECK-NEXT: 0010: 00000000 00100000 C30E0000 C30E0000 |................|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 1080: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 1090: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 10A0: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 6
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 9640
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 30000000 60000000 01002000 |(...0...`..... .|
; CHECK-NEXT: 0010: 00000000 00240000 C30E0000 C30E0000 |.....$..........|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 2580: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 2590: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 25A0: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 14
; CHECK-NEXT: Resource name (int): 100
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1030
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 62
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 00000100 04001010 00000100 20006804 |............ .h.|
; CHECK-NEXT: 0010: 00000300 18180000 01002000 88090000 |.......... .....|
; CHECK-NEXT: 0020: 04002020 00000100 2000A810 00000500 |.. .... .......|
; CHECK-NEXT: 0030: 30300000 01002000 A8250000 0600 |00.... ..%....|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 1
; CHECK-NEXT: Resource name (int): 7
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 4268
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 0D000600 28000000 20000000 40000000 |....(... ...@...|
; CHECK-NEXT: 0010: 01002000 00000000 00100000 00000000 |.. .............|
; CHECK-NEXT: 0020: 00000000 00000000 00000000 00000000 |................|
; (...)
; CHECK-DAG: 1080: E027FFFF C3F3FFFF FFFFFFFF FFFFFFFF |.'..............|
; CHECK-NEXT: 1090: FFFFFFFF F3CFFFFF F3CFFFFF FFFFFFFF |................|
; CHECK-NEXT: 10A0: FFFFFFFF FFFFFFFF FFFFFFFF |............|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 12
; CHECK-NEXT: Resource name (int): 4466
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1030
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 20
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 00000200 01002000 40000100 2000AC10 |...... .@... ...|
; CHECK-NEXT: 0010: 00000700 |....|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 8
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 1128
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 10000000 20000000 01002000 |(....... ..... .|
; CHECK-NEXT: 0010: 00000000 00040000 C30E0000 C30E0000 |................|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 0440: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0450: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0460: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 9
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 2440
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 18000000 30000000 01002000 |(.......0..... .|
; CHECK-NEXT: 0010: 00000000 00090000 C30E0000 C30E0000 |................|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 0960: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0970: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 0980: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 10
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 4264
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 20000000 40000000 01002000 |(... ...@..... .|
; CHECK-NEXT: 0010: 00000000 00100000 C30E0000 C30E0000 |................|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 1080: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 1090: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 10A0: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 11
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 9640
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 28000000 30000000 60000000 01002000 |(...0...`..... .|
; CHECK-NEXT: 0010: 00000000 00240000 C30E0000 C30E0000 |.....$..........|
; CHECK-NEXT: 0020: 00000000 00000000 FFFFFFFF FFFFFFFF |................|
; (...)
; CHECK-DAG: 2580: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 2590: 00000000 00000000 00000000 00000000 |................|
; CHECK-NEXT: 25A0: 00000000 00000000 |........|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 14
; CHECK-NEXT: Resource name (int): 100
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1030
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 62
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 00000100 04001010 00000100 20006804 |............ .h.|
; CHECK-NEXT: 0010: 00000800 18180000 01002000 88090000 |.......... .....|
; CHECK-NEXT: 0020: 09002020 00000100 2000A810 00000A00 |.. .... .......|
; CHECK-NEXT: 0030: 30300000 01002000 A8250000 0B00 |00.... ..%....|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 3
; CHECK-NEXT: Resource name (int): 12
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1010
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 82
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 89504E47 0D0A1A0A 0000000D 49484452 |.PNG........IHDR|
; CHECK-NEXT: 0010: 00000010 00000010 08060000 001FF3FF |................|
; CHECK-NEXT: 0020: 61000000 19494441 5438CB63 FC0F040C |a....IDAT8.c....|
; CHECK-NEXT: 0030: 1400C651 03460D18 3560B818 0000251F |...Q.F..5`....%.|
; CHECK-NEXT: 0040: 3FD1D6DC 546E0000 00004945 4E44AE42 |?...Tn....IEND.B|
; CHECK-NEXT: 0050: 6082 |`.|
; CHECK-NEXT: )

; CHECK-DAG: Resource type (int): 14
; CHECK-NEXT: Resource name (int): 100
; CHECK-NEXT: Data version: 0
; CHECK-NEXT: Memory flags: 0x1030
; CHECK-NEXT: Language ID: 1033
; CHECK-NEXT: Version (major): 0
; CHECK-NEXT: Version (minor): 0
; CHECK-NEXT: Characteristics: 0
; CHECK-NEXT: Data size: 20
; CHECK-NEXT: Data: (
; CHECK-NEXT: 0000: 00000100 01001010 00000100 20005200 |............ .R.|
; CHECK-NEXT: 0010: 00000C00 |....|
; CHECK-NEXT: )


; RUN: not llvm-rc /FO %t/1 %p/Inputs/tag-icon-cursor-nonexistent.rc 2>&1 | FileCheck %s --check-prefix NOFILE
; NOFILE: llvm-rc: Error in CURSOR statement (ID 500):
; NOFILE-NEXT: Error opening cursor 'this-file-does-not-exist.cur':


; RUN: not llvm-rc /FO %t/1 %p/Inputs/tag-icon-cursor-nonsense.rc 2>&1 | FileCheck %s --check-prefix NONSENSE

; NONSENSE: llvm-rc: Error in ICON statement (ID 1):
; NONSENSE-NEXT: Incorrect icon/cursor Reserved field; should be 0.


; RUN: not llvm-rc /FO %t/1 %p/Inputs/tag-icon-cursor-eof.rc 2>&1 | FileCheck %s --check-prefix EOF

; EOF: llvm-rc: Error in CURSOR statement (ID 72):
; EOF-NEXT: Stream Error: The stream is too short to perform the requested operation.


; RUN: not llvm-rc /FO %t/1 %p/Inputs/tag-icon-cursor-bad-offset.rc 2>&1 | FileCheck %s --check-prefix OFFSET

; OFFSET: llvm-rc: Error in CURSOR statement (ID 50):
; OFFSET-NEXT: Stream Error: The specified offset is invalid for the current stream.


; RUN: not llvm-rc /FO %t/1 %p/Inputs/tag-icon-cursor-bad-type.rc 2>&1 | FileCheck %s --check-prefix BADTYPE

; BADTYPE: llvm-rc: Error in ICON statement (ID 100):
; BADTYPE-NEXT: Incorrect icon/cursor ResType field; should be 1.

0 comments on commit c3ab013

Please sign in to comment.