]> git.imager.perl.org - imager.git/commitdiff
start a jpeg dump tool
authorTony Cook <tony@develop-help.com>
Thu, 14 Feb 2019 22:24:52 +0000 (09:24 +1100)
committerTony Cook <tony@develop-help.com>
Thu, 14 Feb 2019 22:24:52 +0000 (09:24 +1100)
fileformatdocs/jpegdump.pl [new file with mode: 0644]

diff --git a/fileformatdocs/jpegdump.pl b/fileformatdocs/jpegdump.pl
new file mode 100644 (file)
index 0000000..4a4e309
--- /dev/null
@@ -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<filename> >> - 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