-
Notifications
You must be signed in to change notification settings - Fork 0
/
Split-Exif.c
executable file
·139 lines (119 loc) · 3.48 KB
/
Split-Exif.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/****************************************************************************
*
* Copyright (c) 2008 Dave Hylands <dhylands@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*
****************************************************************************/
//
// This utility was used to recover photos from a formatted CF card
// from my Canon Rebel XTi.
//
// The command to copy the image off the camera was:
// dd if=/dev/sdb1 of=CF.img blocksize-1024
//
// And then run this utility on the CF.img file.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
unsigned char buf[ 4096 ];
void ExtractImage( FILE *fs, int imgNum, long startOffset, long endOffset )
{
char imgFileName[ 20 ];
FILE *imgFs;
size_t bytesToRead;
long offset;
printf( "ExtractImage %d 0x%08lx 0x%08lx\n", imgNum, startOffset, endOffset );
snprintf( imgFileName, sizeof( imgFileName ), "rec_%04d.jpg", imgNum );
if (( imgFs = fopen( imgFileName, "wb" )) == NULL )
{
fprintf( stderr, "Unable to open '%s' for writing\n", imgFileName );
exit( 1 );
}
if ( fseek( fs, startOffset, SEEK_SET ) != 0 )
{
fprintf( stderr, "Seek to offset 0x%08lx failed\n", startOffset );
exit( 1 );
}
offset = startOffset;
while ( offset < endOffset )
{
if (( bytesToRead = ( endOffset - offset )) > sizeof( buf ))
{
bytesToRead = sizeof( buf );
}
if ( fread( buf, 1, bytesToRead, fs ) != bytesToRead )
{
fprintf( stderr, "Error reading %d bytes @ %08lx\n", bytesToRead, offset );
exit( 1 );
}
if ( fwrite( buf, 1, bytesToRead, imgFs ) != bytesToRead )
{
fprintf( stderr, "Error writing %d bytes @ %08lx\n", bytesToRead, offset );
exit( 1 );
}
offset += bytesToRead;
}
fclose( imgFs );
}
int main( int argc, char **argv )
{
char *fileName;
FILE *fs;
int imgNum = 0;
struct stat sb;
long offset;
long prevOffset = 0;
if ( argc != 2 )
{
fprintf( stderr, "Must specify a filename\n" );
exit( 1 );
}
fileName = argv[ 1 ];
if (( fs = fopen( fileName, "rb" )) == NULL )
{
fprintf( stderr, "Unable to open '%s' for reading\n", fileName );
exit( 1 );
}
if ( fstat( fileno( fs ), &sb ) != 0 )
{
perror( "fstat" );
exit( 1 );
}
offset = 0;
while ( offset < sb.st_size )
{
fseek( fs, offset, SEEK_SET );
if ( fread( buf, 10, 1, fs ) != 1 )
{
fprintf( stderr, "Error reading 10 bytes from offset: %lx\n", offset );
exit( 1 );
}
if ( memcmp( &buf[6], "Exif", 4 ) == 0 )
{
imgNum++;
if ( prevOffset > 0 )
{
ExtractImage( fs, imgNum, prevOffset, offset );
}
printf( "Detected Exif %d @ 0x%08lx\n", imgNum, offset );
prevOffset = offset;
}
offset += 512;
}
imgNum++;
if ( prevOffset > 0 )
{
ExtractImage( fs, imgNum, prevOffset, sb.st_size );
}
fclose( fs );
exit( 0 );
return 0;
}