2006-08-12
Most of my development these days is on ImageIngester, which has evolved into a rather feature-rich program that does much more than just ingest images. If you're at all serious about digital photography, take a look at the ImageIngester site (link at left). There's a new blog there that's just about ImageIngester.
Here's a recent development story that shows that, while I almost never get lucky with programming errors, "almost" means that I sometimes do.
I wanted to use dcraw (Google it) to get the date and time from so-called EXIF data in image files, and I read in the documentation for it that it didn't decode JPEGs, only raws. So, I wrote the interface like this:
const char *read_EXIF_datetime(const char *path)
{
static char buf[20];
const char *ext = strrchr(path, '/');
if (ext != NULL)
if (strcasecmp(ext, ".JPG") == 0) // dcraw doesn't handle JPEG datetime
return "20400101_000000";
else {
time_t t = read_time(path);
if (t != 0) {
struct tm *tmbuf = localtime(&t);
strftime(buf, sizeof(buf), "%Y%m%d_%H%M%S", tmbuf);
return buf;
}
}
return NULL;
}
I ran a test, and it worked fine, retrieving the date and time for raw files perfectly. Only one little problem: It was working on JPEGs, too!
Maybe you've spotted the bug. The call to strrchr should have been:
const char *ext = strrchr(path, '.');
Because of that bug, it was calling read_time (an entry into dcraw) for all files, not skipping the JPEGs as I had intended.
But... dcraw wasn't failing on JPEGs, it was getting the date and time. Turns out I misread the doc: True, it couldn't decode JPEGs, but it could get the date and time just fine. Had I programmed the strrchr call correctly, I probably never would have known that dcraw could handle JPEG EXIF data, and would have spent hours programming an alternative.
Like I said, you don't get lucky that often when you're programming. Usually, you're much better off paying attention.