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
<p>So there are two ways to get this working: grab the <a href="/wp-content/uploads/2005/02/24/ilife-05-iphoto-501-and-canon-powershot-g3-raw-files/fixdatesG3.zip">OS X 10.3.8 binary</a> file, or build it yourself.</p>
<p>To build it, ensure you have the Developer Tools loaded, grab <a href="http://www.cybercom.net/~dcoffin/dcraw/fixdates.c">fixdates.c</a>, patch with the <a href="/wp-content/uploads/2005/02/24/ilife-05-iphoto-501-and-canon-powershot-g3-raw-files/fixdatesG3.diff">.diff</a>, and then build with something like:</p>
gcc -o fixdatesG3 fixdates.c
<p>and you're done. Run the program with the name of a <code>.CRW</code> 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.</p>
<p>You can automate this for all the files on a CF card with something like this:</p>
find . -name "*.CRW" -exec fixdatesG3 {} \;
<p>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.</p>
<p>You might also want to run:</p>
find . -name "*.THM" -exec rm {} \;
<p>to clean up the unneeded thumbnail files.</p>
<p>After that, simply fire up [iPhoto](http://www.apple.com/ilife/iphoto/) and import the directory. If you use the <code>find</code> command line above, it's perfectly safe to have <code>.JPG</code> and <code>.MOV</code> 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.</p>
<p>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.</p>