Going with a little-endian order:
{ my %prev; sub c_out { my( $fh, $c )= @_; if( ! defined $c ) { print $fh pack "CC", $c & 0xff, $c >> 8 if exists $prev{$fh}; } elsif( exists $prev{$fh} ) { print $fh pack "CC", $prev{$fh} | (($c&0xf)<<4), $c>>4; } else { print $fh pack "C", $c & 0xff; $prev{$fh}= ( $c>>8 ) & 0xf; return; } delete $prev{$fh}; } } { my %prev; sub c_in { my( $fh )= @_; my $c; if( exists $prev{$fh} ) { if( ! read( $fh, $c, 1 ) ) { die "Invalid trailing nybble ($prev{$fh})" unless 0 == delete $prev{$fh}; return; } return delete($prev{$fh})<<8 | unpack("C",$c); } else { my $len= read( $fh, $c, 2 ); die "Extra trailing byte (",unpack("C",$c),")" if 1 == $len; return if 0 == $len; ( $c, $prev{$fh} )= unpack "CC", $c; $c |= ($prev{$fh}&0xf)<<8; $prev{$fh} >>= 4; return $c; } } }
I have you pass the file handle to the routine and don't handle bareword file handles so use c_out(\*FILE,$sesqui) and finish up by doing c_out(\*FILE) to flush the final nybble, if any. (Also, don't intermix *FILE and \*FILE as I didn't bother to make the code robust in the face of that either.)
- tye (but my friends call me "Tye")In reply to (tye)Re: 12 bit ints pairs into 3 bytes
by tye
in thread 12 bit ints pairs into 3 bytes
by jhanna
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |