diff src/format_olympus.c @ 101:847e4bc6b54c

Tue Nov 7 15:35:59 2006 John Ellis <johne@verizon.net> * exif.c: Use new format_raw_exif_offset() function to find Exif in raw files. * filelist.c: Add orf and pef to displayed file types. * format_canon.h, format_fuji.h: Update to new #define format. * format_fuji.c: Use same offset for Exif as the jpeg image as the Exif is always embedded in the jpeg and assuming offset of 12 is just broken. * format_nikon.h: Update to new #define format, and add pentax here as finding the jpeg will be same code. * format_olympus.[ch]: Support Olympus raw files with embedded jpegs, not all raw files will have a jpeg, but all appear to have Exif tags. * format_raw.[ch]: Add new camera types, and add a debugging facility to easily list all tags within tiff files (see format_raw.h to enable).
author gqview
date Tue, 07 Nov 2006 21:00:50 +0000
parents deafec7cd99f
children 71e1ebee420e
line wrap: on
line diff
--- a/src/format_olympus.c	Tue Nov 07 01:57:19 2006 +0000
+++ b/src/format_olympus.c	Tue Nov 07 21:00:50 2006 +0000
@@ -28,6 +28,115 @@
 
 /*
  *-----------------------------------------------------------------------------
+ * Raw ORF embedded jpeg extraction for Olympus
+ *-----------------------------------------------------------------------------
+ */
+
+static guint olympus_tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
+				gint level,
+				guint *image_offset, guint *exif_offset);
+
+
+static void olympus_tiff_entry(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
+			       gint level,
+			       guint *image_offset, guint *exif_offset)
+{
+	guint tag;
+	guint type;
+	guint count;
+	guint segment;
+	guint seg_len;
+
+	tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo);
+	type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo);
+	count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo);
+
+	/* so far, we only care about tags with type long */
+	if (type != EXIF_FORMAT_LONG_UNSIGNED && type != EXIF_FORMAT_LONG) return;
+
+	seg_len = ExifFormatList[type].size * count;
+	if (seg_len > 4)
+		{
+		segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo);
+		if (segment + seg_len > len) return;
+		}
+	else
+		{
+		segment = offset + EXIF_TIFD_OFFSET_DATA;
+		}
+
+	if (tag == 0x201)
+		{
+		/* start of embedded jpeg, not all olympus cameras embed a jpeg */
+		*image_offset = exif_byte_get_int32(data + segment, bo);
+		}
+
+	if (tag == 0x8769)
+		{
+		/* This is the Exif info */
+		*exif_offset = exif_byte_get_int32(data + segment, bo);
+		}
+}
+
+static guint olympus_tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
+				gint level,
+				guint *image_offset, guint *exif_offset)
+{
+	guint count;
+	guint i;
+
+	if (level > EXIF_TIFF_MAX_LEVELS) return 0;
+
+	if (len < offset + 2) return FALSE;
+
+	count = exif_byte_get_int16(data + offset, bo);
+	offset += 2;
+	if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;
+
+	for (i = 0; i < count; i++)
+		{
+		olympus_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level,
+				   image_offset, exif_offset);
+		}
+
+	return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo);
+}
+
+gint format_olympus_raw(unsigned char *data, const guint len,
+			guint *image_offset, guint *exif_offset)
+{
+	guint i_off = 0;
+	guint e_off = 0;
+	guint offset;
+	gint level;
+
+	if (len < 8) return FALSE;
+
+	/* these are in tiff file format with a different magick header */
+	if (memcmp(data, "IIR", 3) != 0) return FALSE;
+
+	offset = exif_byte_get_int32(data + 4, EXIF_BYTE_ORDER_INTEL);
+
+	level = 0;
+	while (offset && level < EXIF_TIFF_MAX_LEVELS)
+		{
+		offset = olympus_tiff_table(data, len, offset, EXIF_BYTE_ORDER_INTEL, 0, &i_off, &e_off);
+		level++;
+		}
+
+	if (i_off != 0 || e_off != 0)
+		{
+		if (image_offset) *image_offset = i_off;
+		if (exif_offset) *exif_offset = e_off;
+		return TRUE;
+		}
+
+	return FALSE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
  * EXIF Makernote for Olympus
  *-----------------------------------------------------------------------------
  */