Pentax raw support
Zach Bagnall <[email protected]> Fri, 12 Aug 2005 22:13:35 +1200
| Newsgroups | gmane.comp.gnome.apps.gqview.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi all. In keeping with the new format_xyz.[ch] scheme, attached is a first run at support for the Pentax PEF raw format. This was adapted from the format_fuji.[ch] files crossbred with some dcparse.c code. It works fine for me with files from the Pentax *ist DS. Apparently the files from the *ist D are slightly different. I don't have any D files to test with but have put in a request on the dpreview forum. Critisism? It's probably larger than it needs to be for starters.. and I'm not sure if more is required on the EXIF part - essential EXIF info is shown in GQview. Zach.
gqview-2.1.1-ptx_pl1.diff
(text/plain, 8 KB)
diff -urN gqview-2.1.1/src/Makefile.am gqview-2.1.1-ptx/src/Makefile.am
--- gqview-2.1.1/src/Makefile.am 2005-06-11 05:10:14.000000000 +1200
+++ gqview-2.1.1-ptx/src/Makefile.am 2005-08-12 17:21:22.000000000 +1200
@@ -92,6 +92,8 @@
format_nikon.h \
format_olympus.c \
format_olympus.h \
+ format_pentax.c \
+ format_pentax.h \
format_raw.c \
format_raw.h \
fullscreen.c \
diff -urN gqview-2.1.1/src/filelist.c gqview-2.1.1-ptx/src/filelist.c
--- gqview-2.1.1/src/filelist.c 2005-06-07 19:30:05.000000000 +1200
+++ gqview-2.1.1-ptx/src/filelist.c 2005-08-12 17:21:22.000000000 +1200
@@ -214,6 +214,7 @@
filter_add_if_missing("crw", "Canon raw format", ".crw;.cr2", TRUE);
filter_add_if_missing("raf", "Fujifilm raw format", ".raf", TRUE);
filter_add_if_missing("nef", "Nikon raw format", ".nef", TRUE);
+ filter_add_if_missing("pef", "Pentax raw format", ".pef", TRUE);
}
static GList *filter_to_list(const gchar *extensions)
diff -urN gqview-2.1.1/src/format_pentax.c gqview-2.1.1-ptx/src/format_pentax.c
--- gqview-2.1.1/src/format_pentax.c 1970-01-01 12:00:00.000000000 +1200
+++ gqview-2.1.1-ptx/src/format_pentax.c 2005-08-12 17:21:23.000000000 +1200
@@ -0,0 +1,223 @@
+/*
+ * GQView
+ * (C) 2005 John Ellis
+ *
+ * Authors:
+ * Original version 2005 Lars Ellenberg, base on dcraw by David coffin.
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "intl.h"
+
+#include "format_pentax.h"
+#include "format_raw.h"
+
+#include "exif.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * Raw (PEF) embedded jpeg extraction for Pentax
+ *-----------------------------------------------------------------------------
+ */
+
+struct ptx_thumb_meta {
+ long offset;
+ long length;
+};
+
+long ptx_dget2(unsigned char **data_ptr, int le) {
+ int a = 0, b = 0;
+
+ a = *((*data_ptr)++);
+ b = *((*data_ptr)++);
+
+ return (le)
+ ? a + (b << 8)
+ : (a << 8) + b;
+}
+
+long ptx_dget4(unsigned char **data_ptr, int le) {
+ int a, b, c, d;
+
+ a = *((*data_ptr)++);
+ b = *((*data_ptr)++);
+ c = *((*data_ptr)++);
+ d = *((*data_ptr)++);
+
+ return (le)
+ ? a + (b << 8) + (c << 16) + (d << 24)
+ : (a << 24) + (b << 16) + (c << 8) + d;
+}
+
+
+int find_thumb(unsigned char *data, unsigned char **seek_ptr, struct ptx_thumb_meta *thumb, int level, int le) {
+ unsigned char *save, *save2;
+ int entries, tag, type, count, slen, val, i;
+ int comp=0;
+
+ int found_offset = 0, found_length = 0;
+
+ entries = ptx_dget2(seek_ptr, le);
+
+ while (entries--) {
+ save = *seek_ptr;
+ tag = ptx_dget2(seek_ptr, le);
+ type = ptx_dget2(seek_ptr, le);
+ count= ptx_dget4(seek_ptr, le);
+
+ slen = count > 128 ? 128 : count;
+
+ save2 = *seek_ptr;
+
+ val = (type == 3) /* short int */
+ ? ptx_dget2(seek_ptr, le)
+ : ptx_dget4(seek_ptr, le);
+
+ *seek_ptr = save2;
+
+ switch (tag) {
+ case 0x14a: /* SubIFD tag */
+ save2 = *seek_ptr;
+
+ for (i = 0; i < count; i++) {
+ // printf("ptx: Reading SubIFD %d..\n", i);
+
+ *seek_ptr = save2 + i * 4;
+ *seek_ptr = data + ptx_dget4(seek_ptr, le);
+
+ if( find_thumb(data, seek_ptr, thumb, level+1, le) == 1 )
+ return 1;
+ }
+ break;
+ case 0x201:
+ thumb->offset = val;
+ found_offset = 1;
+ break;
+ case 0x202:
+ thumb->length = val;
+ found_length = 1;
+ break;
+ }
+
+ *seek_ptr = save + 12;
+ }
+
+ return found_offset && found_length ? 1 : 0;
+}
+
+
+gint format_pentax_raw(unsigned char *data, const guint len,
+ guint *image_offset, guint *exif_offset)
+{
+ guint io = 0;
+ guint eo = 0;
+
+ unsigned char *seeking;
+ int order = 0, le = 0;
+ int ifd = 0;
+ long ifd_off = 0;
+
+ struct ptx_thumb_meta cur_thumb, best_thumb;
+
+ seeking = data;
+
+ order = ptx_dget2(&seeking, 0);
+
+ if(order == 0x4949) {
+ // printf("ptx: Byte order: little-endian\n");
+ le = 1;
+ }
+ else if(order == 0x4D4D) {
+ // printf("ptx: Byte order: big-endian\n");
+ le = 0;
+ }
+ else {
+ printf("ptx: Unknown byte order: 0x%04X! Assuming big-endian..\n", order);
+ le = 0;
+ }
+
+
+ int marker = ptx_dget2(&seeking, le);
+
+ if(marker == 42) {
+ // printf("ptx: TIFF format confirmed\n");
+ }
+ else {
+ printf("ptx: TIFF marker not found: %d\n", marker);
+ return FALSE;
+ }
+
+
+ // seeking = data;
+
+ best_thumb.length = 0;
+
+ while(ifd_off = ptx_dget4(&seeking, le)) {
+ seeking = data + ifd_off;
+
+ // printf("ptx: Reading IFD %d..\n", ifd++);
+
+ if( find_thumb(data, &seeking, &cur_thumb, 0, le) == 1 ) {
+ // printf("ptx: Found a thumbnail\n");
+
+ // simple fitness test: biggest means best
+ if(cur_thumb.length > best_thumb.length) {
+ best_thumb.offset = cur_thumb.offset;
+ best_thumb.length = cur_thumb.length;
+ }
+ }
+ }
+
+ if(best_thumb.length > 0) {
+ // printf("ptx: Best thumbnail found: Offset: 0x%08X; Length: %ld bytes.\n", best_thumb.offset, best_thumb.length);
+
+ io = best_thumb.offset;
+
+ /* verify jpeg marker */
+ if (memcmp(data+io, "\xff\xd8\xff", 3) != 0) {
+ return FALSE;
+ }
+ }
+ else {
+ // printf("ptx: No thumbnail found.\n");
+ }
+
+ /* EXIF info is always in the first TIFF segment */
+ eo = 0;
+
+ if (image_offset) *image_offset = io;
+ if (exif_offset) *exif_offset = eo;
+
+ // printf("ptx: raw Pentax format file\n");
+
+ return TRUE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXIF Makernote for Pentax
+ *-----------------------------------------------------------------------------
+ */
+
+gint format_pentax_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+ guint size, ExifByteOrder bo)
+{
+ return FALSE;
+}
+
diff -urN gqview-2.1.1/src/format_pentax.h gqview-2.1.1-ptx/src/format_pentax.h
--- gqview-2.1.1/src/format_pentax.h 1970-01-01 12:00:00.000000000 +1200
+++ gqview-2.1.1-ptx/src/format_pentax.h 2005-08-12 17:21:23.000000000 +1200
@@ -0,0 +1,37 @@
+/*
+ * GQView
+ * (C) 2005 John Ellis
+ *
+ * Authors:
+ * Original version 2005 Lars Ellenberg, base on dcraw by David coffin.
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+#ifndef __FORMAT_PENTAX_H
+#define __FORMAT_PENTAX_H
+
+
+#include "exif.h"
+
+
+gint format_pentax_raw(unsigned char *data, const guint len,
+ guint *image_offset, guint *exif_offset);
+
+
+#define FORMAT_RAW_PENTAX { "pef", \
+ FORMAT_RAW_MATCH_TIFF_MAKE, 0, "PENTAX Corporation ", 19, \
+ "Pentax raw", format_pentax_raw }
+
+
+gint format_pentax_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+ guint size, ExifByteOrder bo);
+
+#define FORMAT_EXIF_PENTAX { FORMAT_EXIF_MATCH_MAKERNOTE, "PENTAX Corporation ", 19, "Pentax", format_pentax_makernote }
+
+
+
+#endif
+
diff -urN gqview-2.1.1/src/format_raw.c gqview-2.1.1-ptx/src/format_raw.c
--- gqview-2.1.1/src/format_raw.c 2005-06-13 11:25:08.000000000 +1200
+++ gqview-2.1.1-ptx/src/format_raw.c 2005-08-12 17:21:23.000000000 +1200
@@ -32,6 +32,7 @@
#include "format_fuji.h"
#include "format_nikon.h"
#include "format_olympus.h"
+#include "format_pentax.h"
/* so that debugging is honored */
@@ -53,6 +54,7 @@
FORMAT_RAW_CANON,
FORMAT_RAW_FUJI,
FORMAT_RAW_NIKON,
+ FORMAT_RAW_PENTAX,
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};
@@ -71,6 +73,7 @@
FORMAT_EXIF_FUJI,
FORMAT_EXIF_NIKON,
FORMAT_EXIF_OLYMPUS,
+ FORMAT_EXIF_PENTAX,
{ 0, NULL, 0, NULL }
};