From b6a022392d904df1ec5639927a1afbf515935951 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Fri, 15 Feb 2019 09:24:52 +1100 Subject: [PATCH] start a jpeg dump tool --- fileformatdocs/jpegdump.pl | 106 +++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 fileformatdocs/jpegdump.pl diff --git a/fileformatdocs/jpegdump.pl b/fileformatdocs/jpegdump.pl new file mode 100644 index 00000000..4a4e309f --- /dev/null +++ b/fileformatdocs/jpegdump.pl @@ -0,0 +1,106 @@ +#!perl +use strict; +use Getopt::Long; + +my $dumpall = 0; +my $exiffile; +GetOptions(dumpall => \$dumpall, + "e|exif=s" => \$exiffile); + +my $file = shift + or die "Usage: $0 filename\n"; + +open my $fh, "<", $file + or die "$0: cannot open '$file': $!\n"; + +binmode $fh; + + +while (!eof($fh)) { + my $chead; + unless (read($fh, $chead, 2) == 2) { + eof $fh or die "Failed to read start of chunk: $!"; + last; + } + if ($chead eq "\xFF\xD8") { + print "Start of image\n"; + } + elsif ($chead =~ /^\xFF[\xE0-\xEF]$/) { + # APP0-APP15 + my $clen; + unless (read($fh, $clen, 2) == 2) { + die "Couldn't read length for APPn\n"; + } + my $len = unpack("S>", $clen); + my $appdata; + unless (read($fh, $appdata, $len-2) == $len-2) { + print "length ", length $appdata, " expected $len\n"; + die "Couldn't read application data for APPn\n"; + } + if ($chead eq "\xFF\xE0") { + # APP0 + my $type = substr($appdata, 0, 5, ''); + print "APP0 ", $type =~ tr/\0//dr, "\n"; + if ($type eq "JFIF\0") { + my ($version, $units, $xdens, $ydens, $tx, $ty, $rest) = + unpack("S>CS>S>CCa*", $appdata); + printf " Version: %x\n", $version; + print " Units: $units\n"; + print " Density: $xdens x $ydens\n"; + print " Thumbnail: $tx x $ty\n"; + } + else { + # more to do + } + } + elsif ($chead eq "\xFF\xE1") { + # APP1 + if ($appdata =~ s/^Exif\0.//) { + print " EXIF data\n"; + if ($exiffile) { + open my $eh, ">", $exiffile + or die "Cannot create $exiffile: $!\n"; + binmode $eh; + print $eh $appdata; + close $eh + or die "Cannot close $exiffile: $!\n"; + } + } + } + } + else { + die "I don't know how to handle ", unpack("H*", $chead), "\n"; + } +} + +=head HEAD + +jpegdump.pl - dump the structure of a JPEG image file. + +=head1 SYNOPSIS + + perl jpegdump.pl [-dumpall] [-exif=exifdata] filename + +=head1 DESCRIPTION + +Dumps the structure of a JPEG image file. + +Options: + +=over + +=item * + +C<-dumpall> - dump the entire contents of each chunk rather than just +the leading bytes. Currently unimplemented. + +=item * + +C<< -exif I >> - extract the EXIF blob to a file. + +=back + +This is incomplete, I mostly wrote it to extract the EXIF blob, but I +expect I'll finish it at some point. + +=cut -- 2.39.5