Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a file that is multiple tiff files concatenated together. (note this is not a multipage tiff). I am looking for a way to split the file back into separate files. Preferably from the command line so that the process can be automated.

I could be way oversimplifying it but it appears that each image starts with the hex values 49 49 2A. I did some searching and have tried various suggestions for splitting binary files using AWK and SPLIT but haven't been able to get any to work for my situation.

Is there some other method I could use to get this to work?

share|improve this question
edit: changed to answer – horatio Mar 27 '12 at 20:12
up vote 2 down vote accepted

If you're sure the concatenated TIFFs are all little-endian files (49 49 2A 00 magic number), then this Perl script should work. Invoke as perl < file.tif

#!/usr/bin/env perl                                                         

my $big_endian = "MM\0*";
my $big_endian_regex = "MM\0\\*";
my $little_endian = "II*\0";
my $little_endian_regex = "II\\*\0";

my $tiff_magic = $little_endian;
my $tiff_magic_regex = $little_endian_regex;

my $n = 0;
my $fileprefix = "chunk";
my $buffer;

{ local $/ = undef; $buffer = <stdin>; }

my @images = split /${tiff_magic_regex}/, $buffer;

for my $image (@images) {
    next if $image eq '';
    my $file = sprintf("$fileprefix.%02d.tif", $n++);
    open FILE, ">", $file or die "open $file: ";
    print FILE $tiff_magic, $image or die "print $file: ";
    close FILE or die "close $file: ";

exit 0;
share|improve this answer
This is exactly what I needed. Thanks! – matthew Mar 28 '12 at 21:13

I know that for TIFF files, the first 2 bytes are char and evaluate to ascii "II" or "MM" for byte order (intel or motorola) and then 2 bytes (word) for version which should be decimal 42 (don't panic).

see for instance:

In your example, you are seeing II+42 intel byte order and version 42.

share|improve this answer
That would make sense. Now how can I use that to actually split the file? – matthew Mar 27 '12 at 20:23
That is beyond my experience. One way to do this would be to open the file as a stream and buffer input, checking for the byte sequence and then emitting a new file whenever it encounters a new one. This is not elegant, but if one were to do this, one would get the most speed by reading large chunks at once rather than reading one byte at a time. What little I know of unix utilities tells me that AWK is for text, and maybe there is a utility such as GAWK (?) for binary data – horatio Mar 27 '12 at 20:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .