View in color | License | Download script | History |
30-Apr 15:49 UTC
[0.084] 15.085k
[0.084] 15.085k
ico-parser.rREBOL [
Title: "ico-parser"
Date: 31-Jul-2001/0:25:23+2:00
Version: 0.0.1
File: %ico-parser.r
Author: "Oldes"
Usage: {
^-^-ico-parser/file http://sweb.cz/desold/icons/Icon21.ico
^-^-ico-parser/file %Icon21.ico
^-^-;--->see script %ico-view.r how to use it}
Purpose: "To get data from the windows *.ico files"
Comment: {Not finnished yet, I need a help with the rest:
^-^-1. how to create transparent parts from the mask image
^-^-2. how to flip the mask image (in binary format)
^-^-... and some time to sleep as well:)
^-^-(this is probably working only for icons in 24bits color depth!)}
Email: %oldes--bigfoot--com
library: [
level: 'advanced
platform: none
type: 'tool
domain: [GUI file-handling]
tested-under: none
support: none
license: none
see-also: none
]
]
ico-parser: make object! [
reversed: func[w][copy head reverse w]
ico: none
icon: none
specs: make object! [
icon: [
;name bytes comment
'Reserved 2 ;Reserved (always 0)
'ResourceType 2 ;Resource ID (always 1)
'IconCount 2 ;Number of icon bitmaps in file
]
iconDir: [
'Width 1 ;Width of icon in pixels
'Height 1 ;Height of icon in pixels
'NumColors 1 ;Maximum number of colors - If the bitmap contains 256 or more colors the value of NumColors will be 0.
'Reserved 1 ;Not used (always 0)
'NumPlanes 2 ;Not used (always 0)
'BitsPerPixel 2 ;Not used (always 0)
'DataSize 4 ;Length of icon bitmap in bytes
'DataOffset 4 ;Offset position of icon bitmap in file
]
BITMAPINFOHEADER: [
'biSize 4 ;specifies the size of the BITMAPINFOHEADER structure, in bytes.
'biWidth 4 ;specifies the width of the image, in pixels.
'biHeight 4 ;specifies the height of the image, in pixels.
'biPlanes 2 ;specifies the number of planes of the target device, must be set to zero.
'biBitCount 2 ;specifies the number of bits per pixel.
'biCompression 4 ;Specifies the type of compression, usually set to zero (no compression).
'biSizeImage 4 ;specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero.
'biXPelsPerMeter 4 ;specifies the the horizontal pixels per meter on the designated targer device, usually set to zero.
'biYPelsPerMeter 4 ;specifies the the vertical pixels per meter on the designated targer device, usually set to zero.
'biClrUsed 4 ;specifies the number of colors used in the bitmap, if set to zero the number of colors is calculated using the biBitCount member.
'biClrImportant 4
]
]
get-data-by-spec: func[
"Returns block of word and values and rest of the data file"
data [binary!] "Binary data for examination"
spec [block!] "Specification block of words and length in bytes"
][
values: make block! []
foreach [name bytes] spec [
repend values [name to-integer b: reversed copy/part data bytes]
data: skip data bytes
]
reduce [values data]
]
file: func[
"Main converting function"
source-file [file! url!]
/local tmp tmp2
width height image-data-length
icXor flipedicXor dataOffset i
icAnd maskBits
][
icon: either url? source-file [
read-thru source-file
][ read/binary source-file ]
ico: make object! [
icons: 0
dirs: make block! []
bitmapinfoheaders: make block! []
imgs: make block! []
masks: make block! []
]
tmp: get-data-by-spec icon specs/icon
ico/icons: select tmp/1 'IconCount
loop ico/icons [
tmp: get-data-by-spec copy tmp/2 specs/iconDir
append/only ico/dirs tmp/1
tmp2: get-data-by-spec skip icon select tmp/1 'DataOffset specs/BITMAPINFOHEADER
append/only ico/bitmapinfoheaders tmp2/1
width: select tmp/1 'Width
height: select tmp/1 'Height
image-data-length: 3 * (width * height)
dataOffset: (select tmp2/1 'biSize) + (select tmp/1 'DataOffset)
icXor: copy/part ( skip icon dataOffset ) image-data-length
flipedicXor: make binary! length? icXor
while [not tail? icXor][
insert head flipedicXor copy/part icXor (width * 3)
icXor: skip icXor (width * 3)
]
img: make image! reduce [to-pair reduce [width height] flipedicXor]
append ico/imgs img
icAnd: copy/part ( skip icon dataOffset + image-data-length)
((select tmp/1 'DataSize) - image-data-length)
img: make image! to-pair reduce [width height]
maskBits: (enbase/base icAnd 2)
for i 1 (width * height) 1 [
if #"1" = maskBits/:i [poke img i 255.255.255]
]
append ico/masks head img
]
ico
]
] Notes
|