2009-02-09 21:57:26 -05:00
|
|
|
! Copyright (C) 2007, 2009 Doug Coleman.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: accessors alien alien.c-types arrays byte-arrays columns
|
2009-02-12 05:25:33 -05:00
|
|
|
combinators fry grouping io io.binary io.encodings.binary io.files
|
|
|
|
kernel macros math math.bitwise math.functions namespaces sequences
|
2009-02-13 16:47:07 -05:00
|
|
|
strings images endian summary ;
|
2009-02-09 21:57:26 -05:00
|
|
|
IN: images.bitmap
|
|
|
|
|
2009-03-02 20:38:28 -05:00
|
|
|
TUPLE: bitmap-image < image
|
|
|
|
magic size reserved offset header-length width
|
|
|
|
height planes bit-count compression size-image
|
|
|
|
x-pels y-pels color-used color-important rgb-quads color-index ;
|
2009-02-09 21:57:26 -05:00
|
|
|
|
|
|
|
! Currently can only handle 24/32bit bitmaps.
|
|
|
|
! Handles row-reversed bitmaps (their height is negative)
|
|
|
|
|
2009-03-02 20:38:28 -05:00
|
|
|
ERROR: bitmap-magic magic ;
|
|
|
|
|
|
|
|
M: bitmap-magic summary
|
|
|
|
drop "First two bytes of bitmap stream must be 'BM'" ;
|
|
|
|
|
|
|
|
<PRIVATE
|
2009-02-09 21:57:26 -05:00
|
|
|
|
|
|
|
: array-copy ( bitmap array -- bitmap array' )
|
|
|
|
over size-image>> abs memory>byte-array ;
|
|
|
|
|
|
|
|
: 8bit>buffer ( bitmap -- array )
|
|
|
|
[ rgb-quads>> 4 <sliced-groups> [ 3 head-slice ] map ]
|
|
|
|
[ color-index>> >array ] bi [ swap nth ] with map concat ;
|
|
|
|
|
|
|
|
ERROR: bmp-not-supported n ;
|
|
|
|
|
|
|
|
: raw-bitmap>buffer ( bitmap -- array )
|
|
|
|
dup bit-count>>
|
|
|
|
{
|
|
|
|
{ 32 [ color-index>> ] }
|
|
|
|
{ 24 [ color-index>> ] }
|
|
|
|
{ 16 [ bmp-not-supported ] }
|
|
|
|
{ 8 [ 8bit>buffer ] }
|
|
|
|
{ 4 [ bmp-not-supported ] }
|
|
|
|
{ 2 [ bmp-not-supported ] }
|
|
|
|
{ 1 [ bmp-not-supported ] }
|
|
|
|
} case >byte-array ;
|
|
|
|
|
|
|
|
: read2 ( -- n ) 2 read le> ;
|
|
|
|
: read4 ( -- n ) 4 read le> ;
|
|
|
|
|
|
|
|
: parse-file-header ( bitmap -- bitmap )
|
2009-03-02 20:38:28 -05:00
|
|
|
2 read dup "BM" sequence= [ bitmap-magic ] unless >>magic
|
2009-02-09 21:57:26 -05:00
|
|
|
read4 >>size
|
|
|
|
read4 >>reserved
|
|
|
|
read4 >>offset ;
|
|
|
|
|
|
|
|
: parse-bitmap-header ( bitmap -- bitmap )
|
|
|
|
read4 >>header-length
|
|
|
|
read4 >>width
|
|
|
|
read4 >>height
|
|
|
|
read2 >>planes
|
|
|
|
read2 >>bit-count
|
|
|
|
read4 >>compression
|
|
|
|
read4 >>size-image
|
|
|
|
read4 >>x-pels
|
|
|
|
read4 >>y-pels
|
|
|
|
read4 >>color-used
|
|
|
|
read4 >>color-important ;
|
|
|
|
|
|
|
|
: rgb-quads-length ( bitmap -- n )
|
|
|
|
[ offset>> 14 - ] [ header-length>> ] bi - ;
|
|
|
|
|
|
|
|
: color-index-length ( bitmap -- n )
|
|
|
|
{
|
|
|
|
[ width>> ]
|
|
|
|
[ planes>> * ]
|
|
|
|
[ bit-count>> * 31 + 32 /i 4 * ]
|
|
|
|
[ height>> abs * ]
|
|
|
|
} cleave ;
|
|
|
|
|
|
|
|
: parse-bitmap ( bitmap -- bitmap )
|
|
|
|
dup rgb-quads-length read >>rgb-quads
|
|
|
|
dup color-index-length read >>color-index ;
|
|
|
|
|
2009-03-02 20:38:28 -05:00
|
|
|
: load-bitmap-data ( path bitmap -- bitmap )
|
|
|
|
[ binary ] dip '[
|
|
|
|
_ parse-file-header parse-bitmap-header parse-bitmap
|
2009-02-09 21:57:26 -05:00
|
|
|
] with-file-reader ;
|
|
|
|
|
2009-02-09 22:15:57 -05:00
|
|
|
: process-bitmap-data ( bitmap -- bitmap )
|
2009-03-02 20:38:28 -05:00
|
|
|
dup raw-bitmap>buffer >>bitmap ;
|
2009-02-09 22:15:57 -05:00
|
|
|
|
2009-02-10 18:17:36 -05:00
|
|
|
ERROR: unknown-component-order bitmap ;
|
|
|
|
|
|
|
|
: bitmap>component-order ( bitmap -- object )
|
|
|
|
bit-count>> {
|
|
|
|
{ 32 [ BGRA ] }
|
|
|
|
{ 24 [ BGR ] }
|
|
|
|
{ 8 [ BGR ] }
|
|
|
|
[ unknown-component-order ]
|
|
|
|
} case ;
|
|
|
|
|
2009-03-02 20:38:28 -05:00
|
|
|
: fill-image-slots ( bitmap -- bitmap )
|
|
|
|
dup {
|
|
|
|
[ [ width>> ] [ height>> ] bi 2array >>dim ]
|
|
|
|
[ bitmap>component-order >>component-order ]
|
|
|
|
[ bitmap>> >>bitmap ]
|
|
|
|
} cleave ;
|
2009-02-09 21:57:26 -05:00
|
|
|
|
2009-03-02 20:38:28 -05:00
|
|
|
M: bitmap-image load-image* ( path bitmap -- bitmap )
|
|
|
|
load-bitmap-data process-bitmap-data
|
|
|
|
fill-image-slots ;
|
2009-02-09 21:57:26 -05:00
|
|
|
|
2009-02-09 22:26:52 -05:00
|
|
|
MACRO: (nbits>bitmap) ( bits -- )
|
|
|
|
[ -3 shift ] keep '[
|
2009-03-02 20:38:28 -05:00
|
|
|
bitmap-image new
|
2009-02-09 22:26:52 -05:00
|
|
|
2over * _ * >>size-image
|
|
|
|
swap >>height
|
|
|
|
swap >>width
|
2009-03-02 20:38:28 -05:00
|
|
|
swap array-copy [ >>bitmap ] [ >>color-index ] bi
|
|
|
|
_ >>bit-count fill-image-slots
|
2009-03-10 17:35:47 -04:00
|
|
|
t >>upside-down?
|
2009-02-09 22:26:52 -05:00
|
|
|
] ;
|
|
|
|
|
|
|
|
: bgr>bitmap ( array height width -- bitmap )
|
|
|
|
24 (nbits>bitmap) ;
|
|
|
|
|
|
|
|
: bgra>bitmap ( array height width -- bitmap )
|
|
|
|
32 (nbits>bitmap) ;
|
|
|
|
|
2009-02-09 21:57:26 -05:00
|
|
|
: write2 ( n -- ) 2 >le write ;
|
|
|
|
: write4 ( n -- ) 4 >le write ;
|
|
|
|
|
2009-03-02 20:38:28 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
2009-03-14 15:48:28 -04:00
|
|
|
: bitmap>color-index ( bitmap-array -- byte-array )
|
|
|
|
4 <sliced-groups> [ 3 head-slice reverse ] map B{ } join ; inline
|
|
|
|
|
|
|
|
: save-bitmap ( image path -- )
|
2009-02-09 21:57:26 -05:00
|
|
|
binary [
|
|
|
|
B{ CHAR: B CHAR: M } write
|
|
|
|
[
|
2009-03-14 15:48:28 -04:00
|
|
|
bitmap>> bitmap>color-index length 14 + 40 + write4
|
2009-02-09 21:57:26 -05:00
|
|
|
0 write4
|
|
|
|
54 write4
|
|
|
|
40 write4
|
|
|
|
] [
|
|
|
|
{
|
2009-03-14 15:48:28 -04:00
|
|
|
[ dim>> first2 [ write4 ] bi@ ]
|
|
|
|
[ drop 1 write2 ]
|
|
|
|
[ drop 24 write2 ]
|
|
|
|
[ drop 0 write4 ]
|
|
|
|
[ bitmap>> bitmap>color-index length write4 ]
|
|
|
|
[ drop 0 write4 ]
|
|
|
|
[ drop 0 write4 ]
|
|
|
|
[ drop 0 write4 ]
|
|
|
|
[ drop 0 write4 ]
|
|
|
|
! rgb-quads
|
|
|
|
[ bitmap>> bitmap>color-index write ]
|
2009-02-09 21:57:26 -05:00
|
|
|
} cleave
|
|
|
|
] bi
|
|
|
|
] with-file-writer ;
|