; fasmg.exe -n -i "ico equ 'RamXP.ico'" ICO_dir.asm
; List/Audit ICO File Image Characteristics:
; First Support Version for Various Features:
; + Win95/WinNT4 image size of 256x256 (stored as zero)
; + WinXP auto-corrects bColorCount of zero
; + WinXP ARGB format 32bpp images
; + WinXP down-sampling of 256x256 images
; + Vista PNG format, but not .ICL icon libraries
;
; Many ICO tools don't correctly store the image directory - which is
; important for default icon selection in several API functions.
match _,DISPLAY 10 ; just lazy typing
virtual ; create address space with file data
ICO:: file ico
.sizeof := $
; ICONHEADER
load type:dword from 0
assert type = 0x10000 ; only .ICO file for now
;assert type = 0x20000 ; .CUR
load images:word from 4
_, 'file name: ',ico
_, ' type: .ICO'
iterate f,STAR,95,XP,VISTA
FLAG.f := 1 shl %
end iterate
repeat images
if % = 1 ; initialize
NOTES = 0
_, ' images: ',`%%,10
_, 'ICONDIRENTRY(s):'
_, ' W x H |colors|planes| BPP| bytes | offset'
; ' 256 x 256 | 2^32 | 0 | 32 | 9999999 | 99999999 9XV*
end if
notes = 1 ; just to avoid an 'if', bit 0 is not used
load bWidth : byte from (% shl 4)-10 + 0
load bHeight : byte from (% shl 4)-10 + 1
load bColorCount : byte from (% shl 4)-10 + 2
load bReserved : byte from (% shl 4)-10 + 3
load wPlanes : word from (% shl 4)-10 + 4
load wBitCount : word from (% shl 4)-10 + 6
load dwBytesInRes :dword from (% shl 4)-10 + 8
load dwImageOffset :dword from (% shl 4)-10 + 12
; check if image is PNG
load png:qword from dwImageOffset
if png = $0A1A0A0D'474E50'89
notes = notes or FLAG.VISTA
else
; documentation states member use of BITMAPINFOHEADER as:
; biSize, biWidth, biHeight, biPlanes, biBitCount, biSizeImage
; calculate actual color use from BITMAPINFOHEADER
end if
if bWidth = 0
bWidth = 256
notes = notes or FLAG.95
end if
if bHeight = 0
bHeight = 256
notes = notes or FLAG.95
end if
if wBitCount = 32
notes = notes or FLAG.XP
end if
_,9
FIELD bWidth,3
display ' x '
FIELD bHeight,-3
; XP will calculate value, but not during search
if bColorCount = 0
bColorCount = wBitCount * wPlanes
if bColorCount < 8
notes = notes or FLAG.XP or FLAG.STAR
display ' | '
if bColorCount
bColorCount = 1 shl bColorCount
else
bColorCount = 256
end if
FIELD bColorCount,3
else if bColorCount > 9
display ' | 2^'
FIELD bColorCount,2
else
display ' | '
bColorCount = 1 shl bColorCount
FIELD bColorCount,3
end if
else
display ' | '
FIELD bColorCount,3
end if
display ' |'
FIELD wPlanes,5
display ' |'
FIELD wBitCount,3
display ' |'
FIELD dwBytesInRes,8
display ' |'
FIELD dwImageOffset,8
display ' '
; only keep most significant OS flag and bit 1 (FLAG_!)
notes = ((1 shl (bsr notes)) or (notes and 2)) and -2
NOTES = NOTES or notes
iterate n,'*','9','X','V'
while notes > 0
indx bsr notes
notes = notes xor (1 shl (bsr notes))
display n
end while
break
end iterate
end repeat
_
iterate n,\
'* note: incorrect color count',\
'9 note: requires Windows 95/NT4 or greater',\
'X note: requires Windows XP or greater',\
'V note: PNG requires Windows Vista or greater'
while NOTES > 0
indx bsr NOTES
NOTES = NOTES xor (1 shl (bsr NOTES))
_,n
end while
break
end iterate
end virtual
end match
macro FIELD value*,width:0,fill:' '
local text
virtual at 0
if width > 0 ; right-justify
db width dup (fill)
end if
if value < 0
db '-'
repeat 1,N:-value
db `N
end repeat
else
repeat 1,N:value
db `N
end repeat
end if
if width = 0 ; raw output
load text:$ from 0
else if width < 0 ; left-justify
; don't show a fragment
if $ > -width
db '?'
db -width dup (fill)
load text:-width from $+width-1
else
db -width dup (fill)
load text:-width from 0
end if
else ; right-justify
; don't show a fragment
if $ > width shl 1
db width dup (fill)
db '?'
end if
load text:width from $ - width
end if
end virtual
display text
end macro
When there is missing data windows takes longer to find the correct icon - if it finds it (output sample):
file name: RamXP.ico
type: .ICO
images: 6
ICONDIRENTRY(s):
W x H |Colors|Planes|BPP | bytes | offset
32 x 32 | 16 | 0 | 0 | 744 | 102
16 x 16 | 16 | 0 | 0 | 296 | 846
48 x 48 | 16 | 0 | 0 | 1640 | 1142
32 x 32 | 256 | 0 | 0 | 2216 | 2782 X*
48 x 48 | 256 | 0 | 0 | 3752 | 4998 X*
16 x 16 | 256 | 0 | 0 | 1384 | 8750 X*
X note: requires Windows XP or greater
* note: incorrect color count