dialer/embed.jrt

52 lines
1.8 KiB
Plaintext
Raw Normal View History

: filebytes ( fp -- ) >arg
(( begin dup fgetc dup EOF != while yield repeat drop close )) ;
{
( rle encoding is designed for textmode screens and assumes a file with an
even number of bytes )
var rle-start
var rle-run
: >rle-start 0 rle-run ! target rle-start ! 0 w>t ;
: rle-ctrl ( -- b ) rle-run @ b@t 0xff & ;
: rle-word ( -- v ) rle-run @ 1+ @t ;
: repeating? ( -- f ) rle-ctrl 0x80 & not ;
: inc-run ( -- f )
rle-ctrl dup 0x7f & 0x7f < if 1+ rle-run @ b!t 1 else drop 0 then ;
: >rle ( v -- ) rle-run @ if
dup rle-word = if ( is match )
repeating? if ( is repeating run )
inc-run if drop return then
else ( undo last value of non-repeating run )
rle-ctrl 1- rle-run @ b!t
target cell - rle-run !
1 rle-run @ b!t
( grow target by 1 byte ) 0 >t
rle-run @ 1+ !t ( write value at end of target )
return
then
else ( no match )
repeating? not if inc-run if w>t return then then
then
then ( if we have gotten here, start a new run )
target rle-run ! 0 >t w>t ;
: >rle-done 0 rle-run ! target rle-start @ !t ;
2023-10-11 02:11:56 +00:00
: encode-rle ( call with iterator that returns bytes )
>rle-start each i iterate if i 8 << | >rle else drop then next >rle-done ;
: embed-rle ( host-filename -- ) open filebytes encode-rle ;
: embed ( host-filename -- )
target 0 w>t open filebytes each i >t next target swap !t ;
}
: embed-size ( embed -- v ) dup @ swap - ;
: embed-data ( embed -- p ) cell + ;
: rle-decode ( p -- )
>arg (( dup @ swap cell + +arg ( pend p )
begin
1+ dup 1- ub@ dup 0x80 & swap 0x7f & 1+ times
if ( non-repeating ) each dup @ map cell + next
else ( repeating ) each dup @ map next cell + then
2dup <= until drop drop )) ;