1 ! Copyright (C) 2007, 2009 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types arrays byte-arrays columns
4 combinators fry grouping io io.binary io.encodings.binary io.files
5 kernel macros math math.bitwise math.functions namespaces sequences
6 strings images endian summary ;
9 TUPLE: bitmap-image < image ;
11 ! Currently can only handle 24/32bit bitmaps.
12 ! Handles row-reversed bitmaps (their height is negative)
14 TUPLE: bitmap magic size reserved offset header-length width
15 height planes bit-count compression size-image
16 x-pels y-pels color-used color-important rgb-quads color-index
19 : array-copy ( bitmap array -- bitmap array' )
20 over size-image>> abs memory>byte-array ;
22 : 8bit>buffer ( bitmap -- array )
23 [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
24 [ color-index>> >array ] bi [ swap nth ] with map concat ;
26 ERROR: bmp-not-supported n ;
28 : raw-bitmap>buffer ( bitmap -- array )
31 { 32 [ color-index>> ] }
32 { 24 [ color-index>> ] }
33 { 16 [ bmp-not-supported ] }
35 { 4 [ bmp-not-supported ] }
36 { 2 [ bmp-not-supported ] }
37 { 1 [ bmp-not-supported ] }
42 M: bitmap-magic summary
43 drop "First two bytes of bitmap stream must be 'BM'" ;
45 : read2 ( -- n ) 2 read le> ;
46 : read4 ( -- n ) 4 read le> ;
48 : parse-file-header ( bitmap -- bitmap )
49 2 read >string dup "BM" = [ bitmap-magic ] unless >>magic
54 : parse-bitmap-header ( bitmap -- bitmap )
65 read4 >>color-important ;
67 : rgb-quads-length ( bitmap -- n )
68 [ offset>> 14 - ] [ header-length>> ] bi - ;
70 : color-index-length ( bitmap -- n )
74 [ bit-count>> * 31 + 32 /i 4 * ]
78 : parse-bitmap ( bitmap -- bitmap )
79 dup rgb-quads-length read >>rgb-quads
80 dup color-index-length read >>color-index ;
82 : load-bitmap-data ( path -- bitmap )
85 parse-file-header parse-bitmap-header parse-bitmap
88 : process-bitmap-data ( bitmap -- bitmap )
89 dup raw-bitmap>buffer >>buffer ;
91 : load-bitmap ( path -- bitmap )
92 load-bitmap-data process-bitmap-data ;
94 ERROR: unknown-component-order bitmap ;
96 : bitmap>component-order ( bitmap -- object )
101 [ unknown-component-order ]
104 : >image ( bitmap -- bitmap-image )
106 [ [ width>> ] [ height>> ] bi 2array ]
107 [ bitmap>component-order ]
109 } cleave bitmap-image boa ;
111 M: bitmap-image load-image* ( path bitmap -- bitmap-image )
112 drop load-bitmap >image ;
114 M: bitmap-image normalize-scan-line-order
116 _ first 4 * <sliced-groups> reverse concat
119 MACRO: (nbits>bitmap) ( bits -- )
122 2over * _ * >>size-image
125 swap array-copy [ >>buffer ] [ >>color-index ] bi
129 : bgr>bitmap ( array height width -- bitmap )
132 : bgra>bitmap ( array height width -- bitmap )
135 : write2 ( n -- ) 2 >le write ;
136 : write4 ( n -- ) 4 >le write ;
138 : save-bitmap ( bitmap path -- )
140 B{ CHAR: B CHAR: M } write
142 buffer>> length 14 + 40 + write4
150 [ planes>> 1 or write2 ]
151 [ bit-count>> 24 or write2 ]
152 [ compression>> 0 or write4 ]
153 [ size-image>> write4 ]
154 [ x-pels>> 0 or write4 ]
155 [ y-pels>> 0 or write4 ]
156 [ color-used>> 0 or write4 ]
157 [ color-important>> 0 or write4 ]
158 [ rgb-quads>> write ]
159 [ color-index>> write ]