From 18276a863b81aeca6d6f8fcd6bca29c78f21ac98 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Thu, 12 Feb 2009 17:44:43 -0600 Subject: [PATCH] initial bitstreams checkin --- basis/bitstreams/authors.txt | 1 + basis/bitstreams/bitstreams-tests.factor | 31 +++++++++ basis/bitstreams/bitstreams.factor | 87 ++++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 basis/bitstreams/authors.txt create mode 100644 basis/bitstreams/bitstreams-tests.factor create mode 100644 basis/bitstreams/bitstreams.factor diff --git a/basis/bitstreams/authors.txt b/basis/bitstreams/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/basis/bitstreams/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/basis/bitstreams/bitstreams-tests.factor b/basis/bitstreams/bitstreams-tests.factor new file mode 100644 index 0000000000..8fac3f52f9 --- /dev/null +++ b/basis/bitstreams/bitstreams-tests.factor @@ -0,0 +1,31 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors bitstreams io io.streams.string kernel tools.test +grouping compression.lzw multiline ; +IN: bitstreams.tests + +[ 1 ] +[ B{ 254 } read-bit ] unit-test + +[ 254 ] +[ B{ 254 } 8 swap read-bits ] unit-test + +[ 4095 ] +[ B{ 255 255 } 12 swap read-bits ] unit-test + +[ B{ 254 } ] +[ + 254 8 rot + [ write-bits ] keep stream>> >byte-array +] unit-test + + +/* +[ + +] [ + B{ 7 7 7 8 8 7 7 9 7 } + [ byte-array>bignum >bin 72 CHAR: 0 pad-head 9 group [ bin> ] map ] + [ lzw-compress ] bi +] unit-test +*/ diff --git a/basis/bitstreams/bitstreams.factor b/basis/bitstreams/bitstreams.factor new file mode 100644 index 0000000000..ae980795bc --- /dev/null +++ b/basis/bitstreams/bitstreams.factor @@ -0,0 +1,87 @@ +! Copyright (C) 2009 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors byte-arrays destructors fry io kernel locals +math sequences ; +IN: bitstreams + +TUPLE: bitstream stream current-bits #bits disposed ; +TUPLE: bitstream-reader < bitstream ; + +: reset-bitstream ( stream -- stream ) + 0 >>#bits 0 >>current-bits ; inline + +: new-bitstream ( stream class -- bitstream ) + new + swap >>stream + reset-bitstream ; inline + +M: bitstream-reader dispose ( stream -- ) + stream>> dispose ; + +: ( stream -- bitstream ) + bitstream-reader new-bitstream ; inline + +: read-next-byte ( bitstream -- bitstream ) + dup stream>> stream-read1 + [ >>current-bits ] [ 8 0 ? >>#bits ] bi ; inline + +: maybe-read-next-byte ( bitstream -- bitstream ) + dup #bits>> 0 = [ read-next-byte ] when ; inline + +: shift-one-bit ( bitstream -- n ) + [ current-bits>> ] [ #bits>> ] bi 1- neg shift 1 bitand ; inline + +: next-bit ( bitstream -- n ) + maybe-read-next-byte [ + shift-one-bit + ] [ + [ 1- ] change-#bits maybe-read-next-byte drop + ] bi ; inline + +: read-bit ( bitstream -- n ) + dup #bits>> 1 = [ + [ current-bits>> 1 bitand ] + [ read-next-byte drop ] bi + ] [ + next-bit + ] if ; inline + +: bits>integer ( seq -- n ) + 0 [ [ 1 shift ] dip bitor ] reduce ; inline + +: read-bits ( width bitstream -- n ) + '[ _ read-bit ] replicate bits>integer ; inline + + +TUPLE: bitstream-writer < bitstream ; + +: ( stream -- bitstream ) + bitstream-writer new-bitstream ; inline + +: write-bit ( n bitstream -- ) + [ 1 shift bitor ] change-current-bits + [ 1+ ] change-#bits + dup #bits>> 8 = [ + [ [ current-bits>> ] [ stream>> stream-write1 ] bi ] + [ reset-bitstream drop ] bi + ] [ + drop + ] if ; inline + +ERROR: invalid-bit-width n ; + +:: write-bits ( n width bitstream -- ) + n 0 < [ n invalid-bit-width ] when + n 0 = [ + width [ 0 bitstream write-bit ] times + ] [ + width n log2 1+ dup :> n-length - [ 0 bitstream write-bit ] times + n-length [ + n-length swap - 1- neg n swap shift 1 bitand + bitstream write-bit + ] each + ] if ; + +: flush-bits ( bitstream -- ) stream>> stream-flush ; + +: bitstream-output ( bitstream -- bytes ) stream>> >byte-array ;