diff options
author | hpa <hpa> | 2001-04-10 04:09:23 +0000 |
---|---|---|
committer | hpa <hpa> | 2001-04-10 04:09:23 +0000 |
commit | ed56f4cb38df19ed0d3ec046a4439ba1fc033a2a (patch) | |
tree | 96a7367abcbc5c97bea844e59e6159e1ad200e85 /lss16toppm | |
parent | c7474677042dbfc2480fb8832f3ddcb60610f60f (diff) | |
download | syslinux-ed56f4cb38df19ed0d3ec046a4439ba1fc033a2a.tar.gz |
Program to convert an LSS-16 image to PPM.
Diffstat (limited to 'lss16toppm')
-rwxr-xr-x | lss16toppm | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/lss16toppm b/lss16toppm new file mode 100755 index 00000000..513aa9e8 --- /dev/null +++ b/lss16toppm @@ -0,0 +1,97 @@ +#!/usr/bin/perl +# +# Convert an LSS-16 image to PPM +# +# Usage: +# +# lss16toppm [-map] < file.lss > file.ppm +# +# The -map causes the color map to be output on stderr. +# + +$map = 0; +foreach $arg ( @ARGV ) { + if ( $arg eq '-map' ) { + $map = 1; + } else { + print STDERR "$0: Unknown option: $arg\n"; + exit 127; + } +} + +if ( read(STDIN, $header, 56) != 56 ) { + print STDERR "$0: Short file\n"; + exit 1; +} + +($magic, $xsize, $ysize, @colorset) = unpack("Vvvc48", $header); + +if ( $magic != 0x1413f33d ) { + print STDERR "$0: Invalid file format\n"; + exit 1; +} + +%color = (); +for ( $i = 0 ; $i < 16 ; $i++ ) { + $r = int((shift @colorset) * 255 / 63 + 0.5); + $g = int((shift @colorset) * 255 / 63 + 0.5); + $b = int((shift @colorset) * 255 / 63 + 0.5); + + $color{$i} = pack("ccc", $r, $g, $b); + + if ( $map ) { + printf STDERR "#%02x%02x%02x=%d\n", $r, $g, $b, $i; + } +} + +sub get_nybble() { + my($ch,$n); + if ( defined($nybble_buf) ) { + $n = $nybble_buf; + undef $nybble_buf; + } else { + if ( read(STDIN, $ch, 1) != 1 ) { + print STDERR "$0: Short read on input (file corrupt)\n"; + exit 1; + } + $ch = ord($ch); + $nybble_buf = $ch >> 4; + $n = $ch & 0xF; + } + return $n; +} + +print "P6\n"; +print "$xsize $ysize\n"; +print "255\n"; + +for ( $y = 0 ; $y < $ysize ; $y++ ) { + $x = 0; + $last = 0; + undef $nybble_buf; # Nybble buffer starts clear on each line + while ( $x < $xsize ) { + $n = get_nybble(); + + if ( $n != $last ) { + print $color{$n}; + $last = $n; + $x++; + } else { + $c = get_nybble(); + if ( $c == 0 ) { + # Double-nybble run + $c = get_nybble(); + $c += get_nybble() << 4; + $c += 16; + } + # Truncate overlong runs + $c = $xsize-$x if ( $c > $xsize-$x ); + # Output run + while ( $c ) { + print $color{$n}; + $c--; + $x++; + } + } + } +} |