From 6e26ea1952b4c49fd387d9854cdc8727a85296a8 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Tue, 9 Jun 2009 11:50:21 -0400 Subject: [PATCH] fix bitmap unit tests, tweaking bitmap loading --- basis/images/bitmap/bitmap-tests.factor | 7 +- basis/images/bitmap/bitmap.factor | 63 ++++++-------- basis/images/bitmap/loading/loading.factor | 97 +++++++++++++++++----- 3 files changed, 107 insertions(+), 60 deletions(-) diff --git a/basis/images/bitmap/bitmap-tests.factor b/basis/images/bitmap/bitmap-tests.factor index ea8b0d4c0c..950fd0b3a6 100644 --- a/basis/images/bitmap/bitmap-tests.factor +++ b/basis/images/bitmap/bitmap-tests.factor @@ -1,7 +1,6 @@ USING: images.bitmap images.viewer io.encodings.binary io.files io.files.unique kernel tools.test images.loader -literals sequences checksums.md5 checksums -images.normalization ; +literals sequences checksums.md5 checksums ; IN: images.bitmap.tests CONSTANT: test-bitmap24 "vocab:images/test-images/thiswayup24.bmp" @@ -26,8 +25,8 @@ ${ : test-bitmap-save ( path -- ? ) [ md5 checksum-file ] - [ load-image normalize-image ] bi - "bitmap-save-test" unique-file + [ load-image ] bi + "bitmap-save-test" ".bmp" make-unique-file [ save-bitmap ] [ md5 checksum-file ] bi = ; diff --git a/basis/images/bitmap/bitmap.factor b/basis/images/bitmap/bitmap.factor index 004bca6db0..cf75a40d97 100755 --- a/basis/images/bitmap/bitmap.factor +++ b/basis/images/bitmap/bitmap.factor @@ -2,10 +2,10 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors alien alien.c-types arrays byte-arrays columns combinators compression.run-length endian fry grouping images -images.bitmap.loading images.loader io io.binary -io.encodings.8-bit io.encodings.binary io.encodings.string -io.files io.streams.limited kernel locals macros math -math.bitwise math.functions namespaces sequences +images.bitmap.loading images.bitmap.saving images.loader io +io.binary io.encodings.8-bit io.encodings.binary +io.encodings.string io.files io.streams.limited kernel locals +macros math math.bitwise math.functions namespaces sequences specialized-arrays.uint specialized-arrays.ushort strings summary ; QUALIFIED-WITH: bitstreams b @@ -16,33 +16,26 @@ SINGLETON: bitmap-image ! endpoints-triple is ciexyzX/Y/Z, 3x fixed-point-2.30 aka 3x uint -: write2 ( n -- ) 2 >le write ; -: write4 ( n -- ) 4 >le write ; - > >array ] [ color-palette>> 3 ] bi '[ _ nth ] map concat ; -: os2v2-color-lookup ( loading-bitmap -- seq ) - [ color-index>> >array ] - [ color-palette>> 3 ] bi - '[ _ nth ] map concat ; - -: v3-color-lookup ( loading-bitmap -- seq ) +: color-lookup4 ( loading-bitmap -- seq ) [ color-index>> >array ] [ color-palette>> 4 [ 3 head-slice ] map ] bi '[ _ nth ] map concat ; +! os2v1 is 3bytes each, all others are 3 + 1 unused : color-lookup ( loading-bitmap -- seq ) dup file-header>> header-length>> { - { 12 [ os2-color-lookup ] } - { 64 [ os2v2-color-lookup ] } - { 40 [ v3-color-lookup ] } - ! { 108 [ v4-color-lookup ] } - ! { 124 [ v5-color-lookup ] } + { 12 [ color-lookup3 ] } + { 64 [ color-lookup4 ] } + { 40 [ color-lookup4 ] } + { 108 [ color-lookup4 ] } + { 124 [ color-lookup4 ] } } case ; ERROR: bmp-not-supported n ; @@ -71,7 +64,7 @@ ERROR: bmp-not-supported n ; color-index>> ] } { 8 [ color-lookup ] } - { 4 [ B [ 4 b:byte-array-n>seq ] change-color-index color-lookup ] } + { 4 [ [ 4 b:byte-array-n>seq ] change-color-index color-lookup ] } { 1 [ [ 1 b:byte-array-n>seq ] change-color-index color-lookup ] } [ bmp-not-supported ] } case >byte-array ; @@ -95,11 +88,7 @@ M: unsupported-bitfield-widths summary byte-array>ushort-array _ uncompress-bitfield ] change-color-index ] } - { 32 [ - dup bitfields>> '[ - byte-array>uint-array _ uncompress-bitfield - ] change-color-index - ] } + { 32 [ ] } [ unsupported-bitfield-widths ] } case ; @@ -113,12 +102,20 @@ GENERIC: uncompress-bitmap* ( loading-bitmap header -- loading-bitmap ) M: os2-header uncompress-bitmap* ( loading-bitmap header -- loading-bitmap' ) drop ; +: do-run-length-uncompress ( loading-bitmap -- loading-bitmap ) + dup '[ + _ header>> [ width>> ] [ height>> ] bi + run-length-uncompress-bitmap + ] change-color-index ; + M: v-header uncompress-bitmap* ( loading-bitmap header -- loading-bitmap' ) compression>> { { f [ ] } { 0 [ ] } { 1 [ [ run-length-uncompress ] change-color-index ] } - { 2 [ [ 4 b:byte-array-n>seq run-length-uncompress >byte-array ] change-color-index ] } + { 2 [ [ 4 b:byte-array-n>seq run-length-uncompress ] change-color-index ] } + ! { 1 [ do-run-length-uncompress ] } + ! { 2 [ [ 4 b:byte-array-n>seq ] change-color-index do-run-length-uncompress ] } { 3 [ uncompress-bitfield-widths ] } { 4 [ "jpeg" unsupported-bitmap-compression ] } { 5 [ "png" unsupported-bitmap-compression ] } @@ -128,8 +125,7 @@ M: v-header uncompress-bitmap* ( loading-bitmap header -- loading-bitmap' ) 3 * 4 mod 4 swap - 4 mod ; inline : loading-bitmap>bytes ( loading-bitmap -- byte-array ) - uncompress-bitmap - bitmap>bytes ; + uncompress-bitmap bitmap>bytes ; : color-palette-length ( loading-bitmap -- n ) file-header>> @@ -169,7 +165,7 @@ PRIVATE> binary [ B{ CHAR: B CHAR: M } write [ - bitmap>color-index length 14 + 40 + write4 + bitmap>> length 14 + 40 + write4 0 write4 54 write4 40 write4 @@ -188,7 +184,7 @@ PRIVATE> [ drop 0 write4 ] ! image-size - [ bitmap>color-index length write4 ] + [ bitmap>> length write4 ] ! x-pels [ drop 0 write4 ] @@ -203,12 +199,7 @@ PRIVATE> [ drop 0 write4 ] ! color-palette - [ - [ bitmap>color-index ] - [ dim>> first 3 * ] - [ dim>> first bitmap-padding + ] tri - reverse-lines write - ] + [ bitmap>> write ] } cleave ] bi ] with-file-writer ; diff --git a/basis/images/bitmap/loading/loading.factor b/basis/images/bitmap/loading/loading.factor index f8fa52cd6f..3b2bafa92e 100644 --- a/basis/images/bitmap/loading/loading.factor +++ b/basis/images/bitmap/loading/loading.factor @@ -3,10 +3,12 @@ USING: accessors arrays combinators images images.bitmap images.bitmap.private io io.binary io.encodings.8-bit io.encodings.binary io.encodings.string io.streams.limited -kernel math math.bitwise ; +kernel math math.bitwise grouping sequences ; +QUALIFIED-WITH: syntax S IN: images.bitmap.loading ! http://www.fileformat.info/format/bmp/egff.htm +! http://www.digicamsoft.com/bmp/bmp.html ERROR: unknown-component-order bitmap ; ERROR: unknown-bitmap-header n ; @@ -19,26 +21,63 @@ TUPLE: loading-bitmap color-palette color-index bitfields ; TUPLE: file-header - magic size reserved1 reserved2 offset header-length ; + { magic initial: "BM" } + { size } + { reserved1 initial: 0 } + { reserved2 initial: 0 } + { offset } + { header-length } ; TUPLE: v3-header - width height planes bit-count - compression image-size x-resolution y-resolution - colors-used colors-important ; + { width initial: 0 } + { height initial: 0 } + { planes initial: 0 } + { bit-count initial: 0 } + { compression initial: 0 } + { image-size initial: 0 } + { x-resolution initial: 0 } + { y-resolution initial: 0 } + { colors-used initial: 0 } + { colors-important initial: 0 } ; TUPLE: v4-header < v3-header - red-mask green-mask blue-mask alpha-mask - cs-type end-points - gamma-red gamma-green gamma-blue ; + { red-mask initial: 0 } + { green-mask initial: 0 } + { blue-mask initial: 0 } + { alpha-mask initial: 0 } + { cs-type initial: 0 } + { end-points initial: 0 } + { gamma-red initial: 0 } + { gamma-green initial: 0 } + { gamma-blue initial: 0 } ; TUPLE: v5-header < v4-header - intent profile-data profile-size reserved3 ; + { intent initial: 0 } + { profile-data initial: 0 } + { profile-size initial: 0 } + { reserved3 initial: 0 } ; + +TUPLE: os2v1-header + { width initial: 0 } + { height initial: 0 } + { planes initial: 0 } + { bit-count initial: 0 } ; -TUPLE: os2v1-header width height planes bit-count ; TUPLE: os2v2-header < os2v1-header - compression image-size x-resolution y-resolution - colors-used colors-important units reserved - recording rendering size1 size2 color-encoding identifier ; + { compression initial: 0 } + { image-size initial: 0 } + { x-resolution initial: 0 } + { y-resolution initial: 0 } + { colors-used initial: 0 } + { colors-important initial: 0 } + { units initial: 0 } + { reserved initial: 0 } + { recording initial: 0 } + { rendering initial: 0 } + { size1 initial: 0 } + { size2 initial: 0 } + { color-encoding initial: 0 } + { identifier initial: 0 } ; UNION: v-header v3-header v4-header v5-header ; UNION: os2-header os2v1-header os2v2-header ; @@ -121,7 +160,7 @@ UNION: os2-header os2v1-header os2v2-header ; read4 >>size1 read4 >>size2 read4 >>color-encoding - 4 read >>identifier ; + read4 >>identifier ; : read-os2v2-header ( -- os2v2-header ) \ os2v2-header new @@ -149,15 +188,20 @@ M: os2v1-header parse-color-data* ( loading-bitmap header -- loading-bitmap ) color-index-length read >>color-index ; M: object parse-color-data* ( loading-bitmap header -- loading-bitmap ) - dup image-size>> [ - nip - ] [ - color-index-length - ] if* read >>color-index ; + dup image-size>> [ 0 ] unless* dup 0 > + [ nip ] [ drop color-index-length ] if read >>color-index ; + +: alpha-used? ( loading-bitmap -- ? ) + color-index>> 4 [ fourth 0 = ] all? not ; + +GENERIC: bitmap>component-order* ( loading-bitmap header -- object ) : bitmap>component-order ( loading-bitmap -- object ) + dup header>> bitmap>component-order* ; + +: simple-bitmap>component-order ( loading-bitamp -- object ) header>> bit-count>> { - { 32 [ BGR ] } + { 32 [ BGRX ] } { 24 [ BGR ] } { 16 [ BGR ] } { 8 [ BGR ] } @@ -166,6 +210,19 @@ M: object parse-color-data* ( loading-bitmap header -- loading-bitmap ) [ unknown-component-order ] } case ; +: advanced-bitmap>component-order ( loading-bitmap -- object ) + [ ] [ header>> bit-count>> ] [ alpha-used? ] tri 2array { + { { 32 t } [ drop BGRA ] } + { { 32 f } [ drop BGRX ] } + [ drop simple-bitmap>component-order ] + } case ; + +M: os2v1-header bitmap>component-order* drop simple-bitmap>component-order ; +M: os2v2-header bitmap>component-order* drop simple-bitmap>component-order ; +M: v3-header bitmap>component-order* drop simple-bitmap>component-order ; +M: v4-header bitmap>component-order* drop advanced-bitmap>component-order ; +M: v5-header bitmap>component-order* drop advanced-bitmap>component-order ; + ERROR: unsupported-bitmap-file magic ; : load-bitmap ( path -- loading-bitmap )