1 |
/* |
2 |
Because they are parsed from the end, Canon CRW files |
3 |
become unreadable if garbage data is appended to them, as |
4 |
often happens when files are recovered from damaged media. |
5 |
This program truncates CRW files to the correct size. |
6 |
|
7 |
Copyright 2005 by Dave Coffin, dcoffin a cybercom o net |
8 |
Free for all uses. |
9 |
|
10 |
$Revision$ |
11 |
$Date$ |
12 |
*/ |
13 |
|
14 |
#include <stdio.h> |
15 |
#include <stdlib.h> |
16 |
#include <string.h> |
17 |
|
18 |
unsigned char *buffer; |
19 |
|
20 |
int get4 (int i) |
21 |
{ |
22 |
if (buffer[0] == 'I') |
23 |
return buffer[i+3] << 24 | buffer[i+2] << 16 | buffer[i+1] << 8 | buffer[i]; |
24 |
else |
25 |
return buffer[i] << 24 | buffer[i+1] << 16 | buffer[i+2] << 8 | buffer[i+3]; |
26 |
} |
27 |
|
28 |
int main (int argc, char **argv) |
29 |
{ |
30 |
int arg, size, end, diff, status=1; |
31 |
unsigned char *fname; |
32 |
FILE *fp; |
33 |
|
34 |
if (argc == 1) |
35 |
fprintf (stderr, "Usage: %s crw_0001.crw crw_0002.crw ...\n", argv[0]); |
36 |
|
37 |
for (arg=1; arg < argc; arg++) { |
38 |
status = 1; |
39 |
fp = fopen (argv[arg], "rb"); |
40 |
fseek (fp, 0, SEEK_END); |
41 |
size = ftell(fp); |
42 |
buffer = malloc (size + strlen(argv[arg]) + 10); |
43 |
if (!buffer) { |
44 |
fprintf (stderr, "Cannot allocate memory!\n"); |
45 |
return 2; |
46 |
} |
47 |
fname = buffer + size; |
48 |
sprintf (fname, "%s.clean", argv[arg]); |
49 |
fseek (fp, 0, SEEK_SET); |
50 |
fread (buffer, 1, size, fp); |
51 |
fclose (fp); |
52 |
if (strncmp (buffer, "II\x1a\0\0\0HEAPCCDR", 14) && |
53 |
strncmp (buffer, "MM\0\0\0\x1aHEAPCCDR", 14)) { |
54 |
fprintf (stderr, "%s is not a CRW file!\n", argv[arg]); |
55 |
free (buffer); |
56 |
continue; |
57 |
} |
58 |
for (end=size; end > 0xa0000; end--) { |
59 |
diff = end - get4(end-4); |
60 |
if (diff > 50 && diff < 120 && diff % 10 == 2) { |
61 |
status = 0; |
62 |
break; |
63 |
} |
64 |
} |
65 |
if (status) |
66 |
fprintf (stderr, "Failed to clean %s\n", argv[arg]); |
67 |
else { |
68 |
if ((fp = fopen (fname, "wb"))) { |
69 |
fprintf (stderr, "Writing %s\n", fname); |
70 |
fwrite (buffer, 1, end, fp); |
71 |
fclose (fp); |
72 |
} else { |
73 |
perror (fname); |
74 |
status = 1; |
75 |
} |
76 |
} |
77 |
free (buffer); |
78 |
} |
79 |
return status; |
80 |
} |