clean_crw.c

00001 /*
00002    Because they are parsed from the end, Canon CRW files
00003    become unreadable if garbage data is appended to them, as
00004    often happens when files are recovered from damaged media.
00005    This program truncates CRW files to the correct size.
00006 
00007    Copyright 2005 by Dave Coffin, dcoffin a cybercom o net
00008    Free for all uses.
00009 
00010    $Revision: 1.1 $
00011    $Date: 2005/06/27 14:07:24 $
00012  */
00013 
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 
00018 unsigned char *buffer;
00019 
00020 int get4 (int i)
00021 {
00022   if (buffer[0] == 'I')
00023     return buffer[i+3] << 24 | buffer[i+2] << 16 | buffer[i+1] << 8 | buffer[i];
00024   else
00025     return buffer[i] << 24 | buffer[i+1] << 16 | buffer[i+2] << 8 | buffer[i+3];
00026 }
00027 
00028 int main (int argc, char **argv)
00029 {
00030   int arg, size, end, diff, status=1;
00031   unsigned char *fname;
00032   FILE *fp;
00033 
00034   if (argc == 1)
00035     fprintf (stderr, "Usage:  %s crw_0001.crw crw_0002.crw ...\n", argv[0]);
00036 
00037   for (arg=1; arg < argc; arg++) {
00038     status = 1;
00039     fp = fopen (argv[arg], "rb");
00040     fseek (fp, 0, SEEK_END);
00041     size = ftell(fp);
00042     buffer = malloc (size + strlen(argv[arg]) + 10);
00043     if (!buffer) {
00044       fprintf (stderr, "Cannot allocate memory!\n");
00045       return 2;
00046     }
00047     fname = buffer + size;
00048     sprintf (fname, "%s.clean", argv[arg]);
00049     fseek (fp, 0, SEEK_SET);
00050     fread (buffer, 1, size, fp);
00051     fclose (fp);
00052     if (strncmp (buffer, "II\x1a\0\0\0HEAPCCDR", 14) &&
00053     strncmp (buffer, "MM\0\0\0\x1aHEAPCCDR", 14)) {
00054       fprintf (stderr, "%s is not a CRW file!\n", argv[arg]);
00055       free (buffer);
00056       continue;
00057     }
00058     for (end=size; end > 0xa0000; end--) {
00059       diff = end - get4(end-4);
00060       if (diff > 50 && diff < 120 && diff % 10 == 2) {
00061     status = 0;
00062     break;
00063       }
00064     }
00065     if (status)
00066       fprintf (stderr, "Failed to clean %s\n", argv[arg]);
00067     else {
00068       if ((fp = fopen (fname, "wb"))) {
00069     fprintf (stderr, "Writing %s\n", fname);
00070     fwrite (buffer, 1, end, fp);
00071     fclose (fp);
00072       } else {
00073     perror (fname);
00074     status = 1;
00075       }
00076     }
00077     free (buffer);
00078   }
00079   return status;
00080 }

Generated on Sat Jan 27 11:36:11 2007 for libopenraw by  doxygen 1.4.7