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-06-03 00:29:04 -04:00
|
|
|
combinators compression.run-length endian fry grouping images
|
|
|
|
images.loader io io.binary io.encodings.binary io.files kernel
|
|
|
|
locals macros math math.bitwise math.functions namespaces
|
|
|
|
sequences strings summary ;
|
2009-02-09 21:57:26 -05:00
|
|
|
IN: images.bitmap
|
|
|
|
|
2009-03-14 16:17:51 -04:00
|
|
|
: assert-sequence= ( a b -- )
|
|
|
|
2dup sequence= [ 2drop ] [ assert ] if ;
|
|
|
|
|
|
|
|
: read2 ( -- n ) 2 read le> ;
|
|
|
|
: read4 ( -- n ) 4 read le> ;
|
2009-03-14 16:31:59 -04:00
|
|
|
: write2 ( n -- ) 2 >le write ;
|
|
|
|
: write4 ( n -- ) 4 >le write ;
|
2009-03-14 16:17:51 -04:00
|
|
|
|
|
|
|
TUPLE: bitmap-image < image ;
|
|
|
|
|
|
|
|
! Used to construct the final bitmap-image
|
|
|
|
|
2009-03-14 16:08:50 -04:00
|
|
|
TUPLE: loading-bitmap
|
2009-03-14 16:52:04 -04:00
|
|
|
size reserved offset header-length width
|
2009-03-02 20:38:28 -05:00
|
|
|
height planes bit-count compression size-image
|
2009-06-03 00:20:07 -04:00
|
|
|
x-pels y-pels color-used color-important color-palette color-index
|
|
|
|
uncompressed-bytes ;
|
2009-02-09 21:57:26 -05:00
|
|
|
|
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
|
|
|
|
|
|
|
: 8bit>buffer ( bitmap -- array )
|
2009-06-03 00:20:07 -04:00
|
|
|
[ color-palette>> 4 <sliced-groups> [ 3 head-slice ] map ]
|
2009-02-09 21:57:26 -05:00
|
|
|
[ color-index>> >array ] bi [ swap nth ] with map concat ;
|
|
|
|
|
|
|
|
ERROR: bmp-not-supported n ;
|
|
|
|
|
2009-03-14 16:31:59 -04:00
|
|
|
: reverse-lines ( byte-array width -- byte-array )
|
2009-04-08 19:42:01 -04:00
|
|
|
<sliced-groups> <reversed> concat ; inline
|
2009-03-14 16:31:59 -04:00
|
|
|
|
2009-06-03 00:20:07 -04:00
|
|
|
: bitmap>bytes ( loading-bitmap -- array )
|
2009-02-09 21:57:26 -05:00
|
|
|
dup bit-count>>
|
|
|
|
{
|
|
|
|
{ 32 [ color-index>> ] }
|
2009-04-08 19:42:01 -04:00
|
|
|
{ 24 [ [ color-index>> ] [ width>> 3 * ] bi reverse-lines ] }
|
|
|
|
{ 8 [ [ 8bit>buffer ] [ width>> 3 * ] bi reverse-lines ] }
|
2009-03-14 16:17:51 -04:00
|
|
|
[ bmp-not-supported ]
|
2009-02-09 21:57:26 -05:00
|
|
|
} case >byte-array ;
|
|
|
|
|
2009-06-03 00:20:07 -04:00
|
|
|
ERROR: unsupported-bitmap-compression compression ;
|
|
|
|
|
|
|
|
: uncompress-bitmap ( loading-bitmap -- loading-bitmap' )
|
|
|
|
dup compression>> {
|
|
|
|
{ 0 [ ] }
|
2009-06-03 00:29:04 -04:00
|
|
|
{ 1 [ [ run-length-uncompress8 ] change-color-index ] }
|
2009-06-03 00:20:07 -04:00
|
|
|
{ 2 [ "run-length encoding 4" unsupported-bitmap-compression ] }
|
|
|
|
{ 3 [ "bitfields" unsupported-bitmap-compression ] }
|
|
|
|
{ 4 [ "jpeg" unsupported-bitmap-compression ] }
|
|
|
|
{ 5 [ "png" unsupported-bitmap-compression ] }
|
|
|
|
} case ;
|
|
|
|
|
|
|
|
: loading-bitmap>bytes ( loading-bitmap -- byte-array )
|
|
|
|
uncompress-bitmap bitmap>bytes ;
|
|
|
|
|
2009-03-14 16:31:59 -04:00
|
|
|
: parse-file-header ( loading-bitmap -- loading-bitmap )
|
2009-03-14 16:17:51 -04:00
|
|
|
2 read "BM" assert-sequence=
|
2009-02-09 21:57:26 -05:00
|
|
|
read4 >>size
|
|
|
|
read4 >>reserved
|
|
|
|
read4 >>offset ;
|
|
|
|
|
2009-03-14 16:31:59 -04:00
|
|
|
: parse-bitmap-header ( loading-bitmap -- loading-bitmap )
|
2009-02-09 21:57:26 -05:00
|
|
|
read4 >>header-length
|
|
|
|
read4 >>width
|
2009-03-15 00:23:49 -04:00
|
|
|
read4 32 >signed >>height
|
2009-02-09 21:57:26 -05:00
|
|
|
read2 >>planes
|
|
|
|
read2 >>bit-count
|
|
|
|
read4 >>compression
|
|
|
|
read4 >>size-image
|
|
|
|
read4 >>x-pels
|
|
|
|
read4 >>y-pels
|
|
|
|
read4 >>color-used
|
|
|
|
read4 >>color-important ;
|
|
|
|
|
2009-06-03 00:20:07 -04:00
|
|
|
: color-palette-length ( loading-bitmap -- n )
|
2009-02-09 21:57:26 -05:00
|
|
|
[ offset>> 14 - ] [ header-length>> ] bi - ;
|
|
|
|
|
2009-03-14 16:08:50 -04:00
|
|
|
: color-index-length ( loading-bitmap -- n )
|
2009-02-09 21:57:26 -05:00
|
|
|
{
|
|
|
|
[ width>> ]
|
|
|
|
[ planes>> * ]
|
|
|
|
[ bit-count>> * 31 + 32 /i 4 * ]
|
|
|
|
[ height>> abs * ]
|
|
|
|
} cleave ;
|
|
|
|
|
2009-03-15 16:08:55 -04:00
|
|
|
: image-size ( loading-bitmap -- n )
|
|
|
|
[ [ width>> ] [ height>> ] bi * ] [ bit-count>> 8 /i ] bi * abs ;
|
|
|
|
|
2009-04-08 19:42:01 -04:00
|
|
|
: bitmap-padding ( width -- n )
|
|
|
|
3 * 4 mod 4 swap - 4 mod ; inline
|
|
|
|
|
2009-03-15 16:08:55 -04:00
|
|
|
:: fixup-color-index ( loading-bitmap -- loading-bitmap )
|
|
|
|
loading-bitmap width>> :> width
|
2009-03-16 08:08:35 -04:00
|
|
|
width 3 * :> width*3
|
2009-04-08 19:42:01 -04:00
|
|
|
loading-bitmap width>> bitmap-padding :> padding
|
|
|
|
loading-bitmap [ color-index>> length ] [ height>> abs ] bi /i :> stride
|
|
|
|
loading-bitmap
|
2009-03-16 08:08:35 -04:00
|
|
|
padding 0 > [
|
2009-04-08 19:42:01 -04:00
|
|
|
[
|
2009-03-16 08:08:35 -04:00
|
|
|
stride <sliced-groups>
|
|
|
|
[ width*3 head-slice ] map concat
|
2009-03-15 16:08:55 -04:00
|
|
|
] change-color-index
|
2009-04-08 19:42:01 -04:00
|
|
|
] when ;
|
2009-03-15 16:08:55 -04:00
|
|
|
|
2009-03-14 16:17:51 -04:00
|
|
|
: parse-bitmap ( loading-bitmap -- loading-bitmap )
|
2009-06-03 00:20:07 -04:00
|
|
|
dup color-palette-length read >>color-palette
|
2009-03-15 16:08:55 -04:00
|
|
|
dup color-index-length read >>color-index
|
|
|
|
fixup-color-index ;
|
2009-02-09 21:57:26 -05:00
|
|
|
|
2009-06-03 00:20:07 -04:00
|
|
|
: load-bitmap ( path -- loading-bitmap )
|
2009-04-08 19:42:01 -04:00
|
|
|
binary [
|
|
|
|
loading-bitmap new
|
|
|
|
parse-file-header parse-bitmap-header parse-bitmap
|
2009-02-09 21:57:26 -05:00
|
|
|
] with-file-reader ;
|
|
|
|
|
2009-02-10 18:17:36 -05:00
|
|
|
ERROR: unknown-component-order bitmap ;
|
|
|
|
|
2009-03-14 16:31:59 -04:00
|
|
|
: bitmap>component-order ( loading-bitmap -- object )
|
2009-02-10 18:17:36 -05:00
|
|
|
bit-count>> {
|
|
|
|
{ 32 [ BGRA ] }
|
|
|
|
{ 24 [ BGR ] }
|
|
|
|
{ 8 [ BGR ] }
|
|
|
|
[ unknown-component-order ]
|
|
|
|
} case ;
|
|
|
|
|
2009-04-08 19:42:01 -04:00
|
|
|
: loading-bitmap>bitmap-image ( bitmap-image loading-bitmap -- bitmap-image )
|
2009-03-14 16:08:50 -04:00
|
|
|
{
|
2009-06-03 00:20:07 -04:00
|
|
|
[ loading-bitmap>bytes >>bitmap ]
|
2009-03-15 00:23:49 -04:00
|
|
|
[ [ width>> ] [ height>> abs ] bi 2array >>dim ]
|
2009-03-15 16:08:55 -04:00
|
|
|
[ height>> 0 < [ t >>upside-down? ] when ]
|
2009-03-02 20:38:28 -05:00
|
|
|
[ bitmap>component-order >>component-order ]
|
|
|
|
} cleave ;
|
2009-02-09 21:57:26 -05:00
|
|
|
|
2009-03-14 16:08:50 -04:00
|
|
|
M: bitmap-image load-image* ( path loading-bitmap -- bitmap )
|
2009-06-03 00:20:07 -04:00
|
|
|
swap load-bitmap loading-bitmap>bitmap-image ;
|
2009-02-09 21:57:26 -05:00
|
|
|
|
2009-06-02 21:39:51 -04:00
|
|
|
"bmp" bitmap-image register-image-class
|
|
|
|
|
2009-03-02 20:38:28 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
2009-04-08 19:42:01 -04:00
|
|
|
: bitmap>color-index ( bitmap -- byte-array )
|
|
|
|
[
|
|
|
|
bitmap>>
|
|
|
|
4 <sliced-groups>
|
|
|
|
[ 3 head-slice <reversed> ] map
|
|
|
|
B{ } join
|
|
|
|
] [
|
|
|
|
dim>> first dup bitmap-padding dup 0 > [
|
|
|
|
[ 3 * group ] dip '[ _ <byte-array> append ] map
|
|
|
|
B{ } join
|
|
|
|
] [
|
|
|
|
2drop
|
|
|
|
] if
|
|
|
|
] bi ;
|
2009-03-14 15:48:28 -04:00
|
|
|
|
|
|
|
: save-bitmap ( image path -- )
|
2009-02-09 21:57:26 -05:00
|
|
|
binary [
|
|
|
|
B{ CHAR: B CHAR: M } write
|
|
|
|
[
|
2009-04-08 19:42:01 -04:00
|
|
|
bitmap>color-index length 14 + 40 + write4
|
2009-02-09 21:57:26 -05:00
|
|
|
0 write4
|
|
|
|
54 write4
|
|
|
|
40 write4
|
|
|
|
] [
|
|
|
|
{
|
2009-03-14 16:08:50 -04:00
|
|
|
! width height
|
2009-03-14 15:48:28 -04:00
|
|
|
[ dim>> first2 [ write4 ] bi@ ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! planes
|
2009-03-14 15:48:28 -04:00
|
|
|
[ drop 1 write2 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! bit-count
|
2009-03-14 15:48:28 -04:00
|
|
|
[ drop 24 write2 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! compression
|
2009-03-14 15:48:28 -04:00
|
|
|
[ drop 0 write4 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! size-image
|
2009-04-08 19:42:01 -04:00
|
|
|
[ bitmap>color-index length write4 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! x-pels
|
2009-03-14 15:48:28 -04:00
|
|
|
[ drop 0 write4 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! y-pels
|
2009-03-14 15:48:28 -04:00
|
|
|
[ drop 0 write4 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! color-used
|
2009-03-14 15:48:28 -04:00
|
|
|
[ drop 0 write4 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
|
|
|
! color-important
|
2009-03-14 15:48:28 -04:00
|
|
|
[ drop 0 write4 ]
|
2009-03-14 16:08:50 -04:00
|
|
|
|
2009-06-03 00:20:07 -04:00
|
|
|
! color-palette
|
2009-03-14 16:31:59 -04:00
|
|
|
[
|
2009-04-08 19:42:01 -04:00
|
|
|
[ bitmap>color-index ]
|
|
|
|
[ dim>> first 3 * ]
|
|
|
|
[ dim>> first bitmap-padding + ] tri
|
2009-03-14 16:31:59 -04:00
|
|
|
reverse-lines write
|
|
|
|
]
|
2009-02-09 21:57:26 -05:00
|
|
|
} cleave
|
|
|
|
] bi
|
|
|
|
] with-file-writer ;
|