1 ! Copyright (C) 2007 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: alien arrays byte-arrays combinators summary
5 graphics.viewer io io.binary io.files kernel libc math
6 math.functions math.bitwise namespaces opengl opengl.gl
7 prettyprint sequences strings ui ui.gadgets.panes fry
8 io.encodings.binary accessors grouping macros alien.c-types ;
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 array ;
18 : (array-copy) ( bitmap array -- bitmap array' )
19 over size-image>> abs memory>byte-array ;
21 MACRO: (nbits>bitmap) ( bits -- )
24 2over * _ * >>size-image
27 swap (array-copy) [ >>array ] [ >>color-index ] bi
31 : bgr>bitmap ( array height width -- bitmap )
34 : bgra>bitmap ( array height width -- bitmap )
37 : 8bit>array ( bitmap -- array )
38 [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
39 [ color-index>> >array ] bi [ swap nth ] with map concat ;
41 : 4bit>array ( bitmap -- array )
42 [ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
43 [ color-index>> >array ] bi [ swap nth ] with map concat ;
45 : raw-bitmap>array ( bitmap -- array )
48 { 32 [ "32bit" throw ] }
49 { 24 [ color-index>> ] }
50 { 16 [ "16bit" throw ] }
53 { 2 [ "2bit" throw ] }
54 { 1 [ "1bit" throw ] }
59 M: bitmap-magic summary
60 drop "First two bytes of bitmap stream must be 'BM'" ;
62 : parse-file-header ( bitmap -- )
63 2 read >string dup "BM" = [ bitmap-magic ] unless >>magic
66 4 read le> >>offset drop ;
68 : parse-bitmap-header ( bitmap -- )
69 4 read le> >>header-length
70 4 read signed-le> >>width
71 4 read signed-le> >>height
73 2 read le> >>bit-count
74 4 read le> >>compression
75 4 read le> >>size-image
78 4 read le> >>color-used
79 4 read le> >>color-important drop ;
81 : rgb-quads-length ( bitmap -- n )
82 [ offset>> 14 - ] keep header-length>> - ;
84 : color-index-length ( bitmap -- n )
85 [ width>> ] keep [ planes>> * ] keep
86 [ bit-count>> * 31 + 32 /i 4 * ] keep
89 : parse-bitmap ( bitmap -- )
90 dup rgb-quads-length read >>rgb-quads
91 dup color-index-length read >>color-index drop ;
93 : load-bitmap ( path -- bitmap )
97 dup parse-bitmap-header
100 dup raw-bitmap>array >>array ;
102 : save-bitmap ( bitmap path -- )
104 "BM" >byte-array write
105 dup array>> length 14 + 40 + 4 >le write
111 [ width>> 4 >le write ]
112 [ height>> 4 >le write ]
113 [ planes>> 1 or 2 >le write ]
114 [ bit-count>> 24 or 2 >le write ]
115 [ compression>> 0 or 4 >le write ]
116 [ size-image>> 4 >le write ]
117 [ x-pels>> 0 or 4 >le write ]
118 [ y-pels>> 0 or 4 >le write ]
119 [ color-used>> 0 or 4 >le write ]
120 [ color-important>> 0 or 4 >le write ]
121 [ rgb-quads>> write ]
122 [ color-index>> write ]
126 M: bitmap draw-image ( bitmap -- )
131 0 over height>> abs glRasterPos2i
136 [ height>> abs ] keep
138 { 32 [ GL_BGRA GL_UNSIGNED_BYTE ] }
139 { 24 [ GL_BGR GL_UNSIGNED_BYTE ] }
140 { 8 [ GL_BGR GL_UNSIGNED_BYTE ] }
141 { 4 [ GL_BGR GL_UNSIGNED_BYTE ] }
143 ] keep array>> glDrawPixels ;
145 M: bitmap width ( bitmap -- ) width>> ;
146 M: bitmap height ( bitmap -- ) height>> ;
148 : bitmap. ( path -- )
149 load-bitmap <graphics-gadget> gadget. ;
151 : bitmap-window ( path -- gadget )
152 load-bitmap <graphics-gadget> [ "bitmap" open-window ] keep ;
154 : test-bitmap24 ( -- )
155 "resource:extra/graphics/bitmap/test-images/thiswayup24.bmp" bitmap. ;
157 : test-bitmap8 ( -- )
158 "resource:extra/graphics/bitmap/test-images/rgb8bit.bmp" bitmap. ;
160 : test-bitmap4 ( -- )
161 "resource:extra/graphics/bitmap/test-images/rgb4bit.bmp" bitmap. ;
163 : test-bitmap1 ( -- )
164 "resource:extra/graphics/bitmap/test-images/1bit.bmp" bitmap. ;