iLife ’05, iPhoto 5.0.1 and Canon PowerShot G3 RAW files

Update: This is now no longer required when using OS X 10.4: noted here

Well, I’ve given up sulking about iPhoto 5 not supporting my G3 RAW files, fixed it myself, and am now really annoyed at Apple for being so lazy. Basically, the fix means changing the camera ident string in each .CRW file to say G5 instead of G3 – what a totally pointless and trivial change that a slightly expanded set of test strings within iPhoto would have cured from the outset. I’m not sure if the G1 and G2 cameras can use this same modification, but the G3 and G5 have the same DIGIC image processor: the only real difference is the G5 has more pixels and more noise in low light conditions. Oh, and a black case.

The patch given below is to be applied to Dave Coffin’s fixdates.c file. The camera ident string test was taken from his parse.c code – I have tried to keep the strings to check fairly abstracted, so feel free to apply this to any other cameras that are just a model number away from proper compatibility:

--- fixdatesG3.c	Thu Feb 24 21:03:16 2005
+++ fixdates.c	        Thu Feb 24 21:42:42 2005
@@ -17,12 +17,6 @@
 short order;
 int timestamp;

-// make sure we don't make mistakes randomly rewriting data
-// (iws - 24feb05)
-char *MUST_MATCH_MAKE="Canon";
-char *MUST_MATCH_MODEL="Canon PowerShot G3";
-char *NEW_FAKE_MODEL="Canon PowerShot G5";
-
 /*
    Get a 2-byte integer, making no assumptions about CPU byte order.
    Nor should we assume that the compiler evaluates left-to-right.
@@ -62,8 +56,7 @@
  */
 void parse_ciff(int offset, int length)
 {
-  int tboff, nrecs, i, type, len, roff, aoff, save, j;
-  char name[256],make[128],model[128];
+  int tboff, nrecs, i, type, len, roff, aoff, save;
 
   fseek (ifp, offset+length-4, SEEK_SET);
   tboff = fget4(ifp) + offset;
@@ -75,25 +68,6 @@
     roff = fget4(ifp);
     aoff = offset + roff;
     save = ftell(ifp);
-
-    // confuse iPhoto 5/5.0.1 into working with PowerShot G3 RAW images
-    if (type == 0x080a) {                       /* Model tag */
-      fseek(ifp, aoff, SEEK_SET);
-      fread(name, 256, 1, ifp);
-      strcpy(make, name);
-      strcpy(model, name + strlen(make)+1);
-      // do we have a match ?
-      if (strcmp(make,MUST_MATCH_MAKE) == 0) {
-        if (strcmp(model,MUST_MATCH_MODEL) == 0) {
-          // looks good, so paste our text over the original buffer,
-          // and chuck all of that back out again
-          strcpy(name+strlen(make)+1,NEW_FAKE_MODEL);
-          fseek(ifp, aoff, SEEK_SET);
-          fwrite(name, 256, 1, ifp);
-        }
-      }
-    }
-
     if (type == 0x180e) {		/* Get the timestamp */
       fseek (ifp, aoff, SEEK_SET);
       timestamp = fget4(ifp);
@@ -116,7 +90,7 @@
   }
   for (arg=1; arg < argc; arg++)
   {
-    ifp = fopen(argv[arg],"r+b");
+    ifp = fopen(argv[arg],"r");
     if (!ifp)
     { perror(argv[arg]);
       continue;

So there are two ways to get this working: grab the OS X 10.3.8 binary file, or build it yourself.

To build it, ensure you have the Developer Tools loaded, grab fixdates.c, patch with the .diff, and then build with something like:

gcc -o fixdatesG3 fixdates.c

and you're done. Run the program with the name of a .CRW file, and the file will be changed so that the model reads G5 and the timestamp of the file is set to the time the image was taken.

You can automate this for all the files on a CF card with something like this:

find . -name "*.CRW" -exec fixdatesG3 {} \;

but do make sure you have copied them to a local directory first - don't risk loosing images for the sake of a few seconds wait.

You might also want to run:

find . -name "*.THM" -exec rm {} \;

to clean up the unneeded thumbnail files.

After that, simply fire up iPhoto and import the directory. If you use the find command line above, it's perfectly safe to have .JPG and .MOV files on the card too, and they will not be modified. Also note that the camera make and model have to match 100% before the name will be changed, and that the strings have to be embedded within a Canon format RAW file block before the contents will be modified. There will be no warning in the case of failure, although the timestamp will still be updated if a shooting date is found.

I'm contemplating wrapping this code into an Applescript droplet so it can be called directly from Image Capture, but that's not a priority for me right now.

5 Comments

  1. Ben February 25, 2005

    You can probably get the system to run this every time your camera card is inserted into a media reader (may be more difficult for direct camera-mac connections but you’re probably not doing that in any case). The iTunes MuVo helper (curiously, this blog comes up as the first hit in Google when you search for “iTunes MuVo helper”) could be modified to do this but it may also be possible to configure the system to run a script on removable media insertion.

  2. frez August 30, 2005

    Has anyone tried this with G2 RAW files yet?

    I’m contemplating giving this a go, but I’ll be trying all this compiling stuff for the first time and want to avoid unnecessarily going down a rabbit hole.

  3. ian August 30, 2005

    I did have an email a while ago asking the very same thing, but I never got a response. If you want to send me a G2 RAW file I can check to see if OS X 10.4 and iPhoto from iLife ’05 will recognise it – if it doesn’t I can modify the code to support both G3 and G2.

    HTH

  4. shmuel January 21, 2006

    Would you be willing to do another version of this for iPhoto 6? And this time would you be willing to look at the G2 as well? I could send you a few raw files shot on the G2 for testing if you’d like. Thanks, Shmuel

  5. ian January 23, 2006

    Just for the record, Shmuel sent me some G2 sample files and nothing that I did could get iPhoto/Preview to display them properly under OS X 10.4.4 – the compression used is too different from the G3/G5, sadly.

    HTH

Comments are Disabled