Accidentally Concatenated Images...
October 2, 2005 7:37 AM   Subscribe

I accidentally copied a selection of jpgs from my digital camera to the same filename, concatenating them into one big file. Is there an easy way to unconcatenate them again? (I can view the first one fine if I load the file into an image view, but the others are tantalising out of reach!) (Linux, btw...)
posted by benzo8 to Computers & Internet (11 answers total)
 
my (fairly uneducated) guess would be to open the file in a text editor, look for the JPEG markers at the beginning of each picture, then save each snippet individually?
posted by slater at 7:47 AM on October 2, 2005


I think..

csplit -k -f pic concatenatedjpegfilename.jpg /....JFIF/ /....JFIF/ /....JFIF/ /....JFIF/ /....JFIF/ /....JFIF/ /....JFIF/ /....JFIF/ /....JFIF/ etc..

It'll need work.
posted by wackybrit at 8:21 AM on October 2, 2005


"JFIF" appears several times in some JPEGs I have, so it will need a little more work.
posted by grouse at 8:33 AM on October 2, 2005


How about this perl script:
#!/usr/bin/perl -wuse strict;my $soi = "\xFF\xD8";my $buffer;my $byte;my $index = 0;my $filename = $ARGV[ 0 ] || 'image-';binmode STDIN;die "cannot read ($!)" unless read( STDIN, $buffer, 2 );die "does not being with JPEG SOI marker" unless $buffer eq $soi;$byte = substr( $buffer, 0, 1 );FILE: while (1) {        open IMAGE, '>', sprintf( "%s%03i.jpg", $filename, ++$index )                || die "cannot open new file ($!)";        binmode IMAGE;        do {                print IMAGE $byte;                $buffer = substr( $buffer, 1, 1 );                last FILE unless read( STDIN, $byte, 1 );                $buffer .= $byte;                $byte = substr( $buffer, 0, 1 );        } while ($buffer ne $soi);        close IMAGE;}
It isn't exactly write, but seems to work somewhat in my test cases.
posted by sbutler at 8:47 AM on October 2, 2005


Actually, using the information at this site you could build a more correct parser than I've posted. A JPEG file is basically a bunch of blocks which all contain their length information, so it wouldn't be very hard.
posted by sbutler at 8:50 AM on October 2, 2005


Best answer: http://nmiell.home.comcast.net/stuff/jpegsplit.c

Thanks for the Sunday project, benzo8.
posted by nmiell at 9:51 PM on October 2, 2005 [1 favorite]


If that's not a best answer, I don't know what is.
posted by grouse at 5:14 AM on October 3, 2005


Response by poster: nmiell - thanks! It's a great answer, to be sure, but when running it against my file, I just get that file back. And opening the file with a hex editor and using search shows that there are only two markers in the whole file, so it looks like I munged it worse that I'd imagined... All I did was: find sd -iname '*.jpg -exec mv -v {} ~/Documents/My\ Pictures/051002 but, of course, I forgot to create that directory in advance! Looks like the pictures from my 35th birthday party are gone forever... :: sniff ::
posted by benzo8 at 6:52 AM on October 3, 2005


mv replaces existing files, so, yes, there's only one image in that file. :(

The real solution to this problem is to give digital cameras to all your friends and then get copies of their pictures. :)
posted by nmiell at 5:55 PM on October 3, 2005


Best answer: Though the files were moved from the camera, the file itself is (often) not physically removed from the card, only the directory reference will be removed. It is possible to resurrect the images even after the card has been formatted.

You need to get an image of the card - The Windows voodoo escapes me, but on Linux, use:

dd if=/dev/sda1 of=image.img bs=512

This image file (image.img) may then be processed to extract the files. Homely/rough Java code to do this is available from:

source or compiled

Get the class [or compile the source] then do:

java jpegExtract image.img

This will extract all the jpeg and avi files from the image into the current directory. There may be some false/incomplete matches but it does a pretty thorough job.
posted by azlondon at 6:37 PM on October 3, 2005


Response by poster: azlondon emailed me his solution yesterday and it worked a charm! I had to ask him to write it up here so I could mark it as best answer. Thanks to everyone, particularly those who wrote code (all of which would have worked with azlondon's image of the SD card) - you're all stars!
posted by benzo8 at 12:12 AM on October 4, 2005


« Older Does an open-source Access killer exist?   |   A job I can stand Newer »
This thread is closed to new comments.