#!/usr/local/bin/perl
#
# by Edd Dumbill <edd-web@usefulinc.com>
# Wed Jan 23 18:20:42 GMT 2002
# $Id: diddle.pl,v 1.1 2002/01/23 18:21:34 edmundd Exp $


use Palm::PDB;
use Palm::Raw;

my $convert="/usr/bin/convert";

my $pdb=new Palm::PDB;
$pdb->Load("DiddleBugDB.pdb");

my $x, $i;

$i=0;

for $x (@{$pdb->{records}}) {
	my $data, $img;
	$data=$x->{data};
	my $offset=106;
	$img=&uncompress(substr($data,$offset+1), length($data)-$offset);
	if ($img) {
		# convert -depth 8 -size 160x160 gray:image0.raw image0.png
		open(IMG, "|${convert} -depth 8 -size 160x160 gray:- image${i}.png");
		print IMG &rawpgm($img);
		close(IMG);
	}
	$i++;
}

print "Written $i PNG images\n";

exit;

sub uncompress() {
	my $data=shift;
	my $size=shift;
	my $i,$j;
	my $outbuf="\0" x 3200;
	my $num_bytes;

# uPtr is uncompressed buffer,
# cPtr is compressed buffer
#
# UInt32 i, j;
#  UInt8 num_bytes;
#
#  j = 0;

	$j=0;

	for($i=0; $i<$size && $j<3200; $i++) {			#  for (i=0; i<size; i++) {
		my $b=ord(substr($data, $i, 1));		#    if (cPtr[i]&0x80) {
		# print sprintf("b is %d\n", $b);
		if ($b&0x80) {
			$num_bytes=$b&0x3f; 		#      num_bytes = cPtr[i]&0x3f;
			$num_bytes++;				#      num_bytes++;
			if ($num_bytes > 3200-$j+1) {
				print("overflow at ${j}, read ${i} wanted to write $b\n"); return 0;} 			#      if (num_bytes > (3200-j)) abort();
			if ($b&0x40) { 				#      if (cPtr[i]&0x40) {
										#	/* Mixed */
										#  MemMove(uPtr+j, cPtr+i+1, num_bytes);
				substr($outbuf, $j, $num_bytes) =
					substr($data, $i+1, $num_bytes);
				$i+=$num_bytes; 		#	i += num_bytes;
			} else {					#      }
										#      else {
										#	/* Black */
				                        # MemSet(uPtr+j, num_bytes, 0xff);
				substr($outbuf, $j, $num_bytes) =
					"\xFF" x $num_bytes;
			} 							#      }
		} else {						#    }
										#    else {
										#      /* White */
			$num_bytes=$b&0x7f; 		#num_bytes = cPtr[i]&0x7f; /* ~0x80 */
			$num_bytes++;				#num_bytes++;
			if ($num_bytes > 3200-$j+1) {
					print("white overflow at ${j}, read ${i} wanted to write $b\n"); return 0;} 			#      if (num_bytes > (3200-j)) abort();
										#      MemSet(uPtr+j, num_bytes, 0x00);
			# NO-OP: we init'd to zero anyway
		} 								#    }
		$j+=$num_bytes; 				#    j += num_bytes;
	}									#  }
	return $outbuf;
}

sub rawpgm() {
	my $data=shift;
	my $op="";
	my @bits=(0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1);

	for(my $i=0; $i<3200; $i++) {
		my $b=ord(substr($data, $i, 1));
		for(my $bit=0; $bit<8; $bit++) {
			if ($b&$bits[$bit]) {
				$op.="\0";
			} else {
				$op.="\xff";
			}
		}
	}
	return $op;
}
