#!/usr/bin/perl
#
# flash-recover.pl v0.1
#
# Released into the public domain. By Ben Buxton (bb at cactii.net)
#
# This script attempts to recover JPEG files from a compact flash
# disk image. It uses the perl "$/" variable as the line separator
# in reading the disk image to extract the pictures.
#
# This script cannot guarantee complete recovery. It will only work
# when images are saved contiguously to the flash. This generally
# means that a flash where lots of files have been individually
# deleted and overwritten is less likely to have recoverable files
# than one that has been completely deleted before having photos
# saved to it that need to be recovered.
#
# To (attempt to ) recover files from a flash device, do the following:
#
# - Extract a FULL dump of the flash device
#   -> dd if=/dev/sda of=flashimage bs=1M (substitute /dev/sda for your dev)
# - Run this script with 'flashimage' as the filename
#
# Recovered images will be restored to the files 'img.NN.jpg'. The image
# files will probably be significantly larger than the originals as  the
# script doesnt attempt to determine the end of the file. You should use
# something like 'convert' to regenerate the images correctly:
#
# for i in img.*.jpg ; do convert $i fixed-$i ; done
#
# 'convert' might complain about some files being corrupt - there's not
# much that can be done about these - this script isnt smart enough.
#

$image = $ARGV[0];

if (! -r "$image") {
  print "Usage: $0 <flash_image>\n";
  print "Please see top of script for details\n";
  exit;
}

if (!open(IMAGE, "$image")) {
  die "Can't find or open flash image $image: $!";
}

binmode IMAGE;

$magic = "\377\330\377\341";
$/ = $magic;

$n = 0;
while (<IMAGE>) {
  open (CRAP, ">img.$n.jpg") or die;
  print CRAP $magic . $_;
  print "Recovered image...\n";
  $n++;
}
