Mercurial > geeqie.yaz
annotate src/format_nikon.c @ 53:00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
* filelist.c (filter_add_defaults): Add Nikon file extension for nef.
* format_canon.[ch], format_fuji.[ch]: Add comment tile, and
description field for MakerNote parser.
* format_nikon.[ch]: Add support for jpegs embedded in Nikon nef files.
* format_raw.c: Add debug description output and Nikon raw parser hook.
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
##### an offical release when making enhancements and translation updates. #####
author | gqview |
---|---|
date | Tue, 07 Jun 2005 07:55:00 +0000 |
parents | 276ea4c98d33 |
children | b58cac75ad12 |
rev | line source |
---|---|
51 | 1 /* |
2 * GQView | |
3 * (C) 2005 John Ellis | |
4 * | |
53
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
5 * Authors: |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
6 * Raw NEF jpeg extraction based on nefextract.c by Joseph Heled, |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
7 * in addition nefextract.c is based on dcraw by Dave Coffin. |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
8 * |
51 | 9 * This software is released under the GNU General Public License (GNU GPL). |
10 * Please read the included file COPYING for more information. | |
11 * This software comes with no warranty of any kind, use at your own risk! | |
12 */ | |
13 | |
14 #ifdef HAVE_CONFIG_H | |
15 # include "config.h" | |
16 #endif | |
17 | |
18 | |
19 #include <stdio.h> | |
20 #include <string.h> | |
21 #include <unistd.h> | |
22 | |
23 #include <glib.h> | |
24 | |
25 #include "intl.h" | |
26 | |
27 #include "format_nikon.h" | |
28 | |
29 #include "exif.h" | |
30 | |
31 | |
32 /* | |
33 *----------------------------------------------------------------------------- | |
53
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
34 * Raw NEF embedded jpeg extraction for Nikon |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
35 *----------------------------------------------------------------------------- |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
36 */ |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
37 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
38 static guint tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder byte_order, |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
39 guint *image_offset, guint *jpeg_len); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
40 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
41 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
42 static void tiff_entry(unsigned char *data, const guint len, guint offset, ExifByteOrder byte_order, |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
43 guint *image_offset, guint *image_length, guint *jpeg_start, guint *jpeg_len) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
44 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
45 static gint size[] = { 1,1,1,2,4,8,1,1,2,4,8,4,8 }; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
46 guint tag; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
47 guint type; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
48 guint count; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
49 guint segment; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
50 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
51 tag = exif_byte_get_int16(data + offset, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
52 type = exif_byte_get_int16(data + offset + 2, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
53 count = exif_byte_get_int32(data + offset + 4, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
54 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
55 if (type > 12) return; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
56 if (count * size[type] > 4) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
57 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
58 segment = exif_byte_get_int32(data + offset + 8, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
59 if (len < segment + count * size[type]) return; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
60 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
61 else |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
62 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
63 segment = offset + 8; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
64 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
65 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
66 if (tag == 0x14a && |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
67 type == EXIF_FORMAT_LONG_UNSIGNED) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
68 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
69 /* sub IFD table */ |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
70 gint i; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
71 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
72 for (i = 0; i < count; i++) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
73 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
74 guint subset; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
75 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
76 subset = exif_byte_get_int32(data + segment + i * 4, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
77 tiff_table(data, len, subset, byte_order, image_offset, image_length); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
78 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
79 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
80 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
81 else if (tag == 0x201) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
82 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
83 /* jpeg data start offset */ |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
84 *jpeg_start = exif_byte_get_int32(data + segment, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
85 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
86 else if (tag == 0x202) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
87 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
88 /* jpeg data length */ |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
89 *jpeg_len = exif_byte_get_int32(data + segment, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
90 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
91 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
92 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
93 static guint tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder byte_order, |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
94 guint *image_offset, guint *image_length) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
95 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
96 guint count; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
97 guint i; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
98 guint jpeg_start = 0; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
99 guint jpeg_len = 0; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
100 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
101 if (len < offset + 2) return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
102 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
103 count = exif_byte_get_int16((unsigned char *)data + offset, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
104 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
105 if (len < offset + count * 12 + 4) return 0; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
106 offset += 2; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
107 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
108 for (i = 0; i < count; i++) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
109 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
110 tiff_entry(data, len, offset + i * 12, byte_order, |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
111 image_offset, image_length, &jpeg_start, &jpeg_len); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
112 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
113 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
114 if (jpeg_start > 0 && |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
115 jpeg_len > *image_length) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
116 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
117 *image_offset = jpeg_start; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
118 *image_length = jpeg_len; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
119 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
120 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
121 return exif_byte_get_int32((unsigned char *)data + offset + count * 12, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
122 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
123 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
124 /* |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
125 * Walk the first TIFF IFD table and check for existence of a "make" tag (0x10f) that |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
126 * identifies NIKON CORPORATION, so that we can abort quickly if it is not a raw NEF. |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
127 */ |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
128 static gint tiff_nikon_verify(unsigned char *data, const guint len, guint offset, ExifByteOrder byte_order) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
129 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
130 guint nb_entries; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
131 guint i; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
132 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
133 if (len < offset + 2) return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
134 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
135 nb_entries = exif_byte_get_int16(data + offset, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
136 offset += 2; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
137 if (len < offset + nb_entries * 12 + 4) return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
138 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
139 for (i = 0; i < nb_entries; i++) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
140 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
141 guint segment; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
142 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
143 segment = offset + i * 12; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
144 if (exif_byte_get_int16(data + segment, byte_order) == 0x10f && |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
145 exif_byte_get_int16(data + segment + 2, byte_order) == EXIF_FORMAT_STRING) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
146 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
147 guint count; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
148 guint make_text; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
149 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
150 count = exif_byte_get_int32(data + segment + 4, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
151 make_text = exif_byte_get_int32(data + segment + 8, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
152 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
153 if (count >= 17 && |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
154 memcmp(data + make_text, "NIKON CORPORATION", 17) == 0) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
155 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
156 return TRUE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
157 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
158 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
159 return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
160 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
161 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
162 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
163 return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
164 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
165 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
166 gint format_nikon_raw(const void *data, const guint len, |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
167 guint *image_offset, guint *exif_offset) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
168 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
169 guint i_off = 0; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
170 guint i_len = 0; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
171 ExifByteOrder byte_order; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
172 guint offset; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
173 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
174 if (len < 8) return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
175 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
176 if (memcmp(data, "II", 2) == 0) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
177 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
178 byte_order = EXIF_BYTE_ORDER_INTEL; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
179 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
180 else if (memcmp(data, "MM", 2) == 0) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
181 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
182 byte_order = EXIF_BYTE_ORDER_MOTOROLA; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
183 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
184 else |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
185 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
186 return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
187 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
188 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
189 if (exif_byte_get_int16((unsigned char *)data + 2, byte_order) != 0x002A) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
190 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
191 return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
192 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
193 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
194 offset = exif_byte_get_int32((unsigned char *)data + 4, byte_order); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
195 if (!tiff_nikon_verify((unsigned char *)data, len, offset, byte_order)) return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
196 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
197 while (offset != 0) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
198 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
199 guint next_offset = 0; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
200 tiff_table((unsigned char *)data, len, offset, byte_order, &i_off, &i_len); |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
201 offset = next_offset; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
202 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
203 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
204 if (i_off != 0) |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
205 { |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
206 if (image_offset) *image_offset = i_off; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
207 return TRUE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
208 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
209 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
210 return FALSE; |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
211 } |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
212 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
213 |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
214 /* |
00843150f7c8
Tue Jun 7 03:47:03 2005 John Ellis <johne@verizon.net>
gqview
parents:
51
diff
changeset
|
215 *----------------------------------------------------------------------------- |
51 | 216 * EXIF Makernote for Nikon |
217 *----------------------------------------------------------------------------- | |
218 */ | |
219 | |
220 static ExifTextList NikonTagQuality[]= { | |
221 { 1, "VGA basic" }, | |
222 { 2, "VGA normal" }, | |
223 { 3, "VGA fine" }, | |
224 { 4, "SXGA basic" }, | |
225 { 5, "SXGA normal" }, | |
226 { 6, "SXGA fine" }, | |
227 { 7, "XGA basic (?)" }, | |
228 { 8, "XGA normal (?)" }, | |
229 { 9, "XGA fine (?)" }, | |
230 { 10, "UXGA basic" }, | |
231 { 11, "UXGA normal" }, | |
232 { 12, "UXGA fine" }, | |
233 EXIF_TEXT_LIST_END | |
234 }; | |
235 | |
236 static ExifTextList NikonTagColorMode[]= { | |
237 { 1, "color" }, | |
238 { 2, "monochrome" }, | |
239 EXIF_TEXT_LIST_END | |
240 }; | |
241 | |
242 static ExifTextList NikonTagImgAdjust[]= { | |
243 { 0, "normal" }, | |
244 { 1, "bright+" }, | |
245 { 2, "bright-" }, | |
246 { 3, "contrast+" }, | |
247 { 4, "contrast-" }, | |
248 EXIF_TEXT_LIST_END | |
249 }; | |
250 | |
251 static ExifTextList NikonTagISOSensitivity[]= { | |
252 { 0, "80" }, | |
253 { 2, "160" }, | |
254 { 4, "320" }, | |
255 { 5, "100" }, | |
256 EXIF_TEXT_LIST_END | |
257 }; | |
258 | |
259 static ExifTextList NikonTagWhiteBalance[]= { | |
260 { 0, "auto" }, | |
261 { 1, "preset" }, | |
262 { 2, "daylight" }, | |
263 { 3, "incandescent" }, | |
264 { 4, "fluorescence" }, | |
265 { 5, "cloudy" }, | |
266 { 6, "speedlight" }, | |
267 EXIF_TEXT_LIST_END | |
268 }; | |
269 | |
270 static ExifTextList NikonTagConverter[]= { | |
271 { 0, "none" }, | |
272 { 1, "Fisheye" }, | |
273 EXIF_TEXT_LIST_END | |
274 }; | |
275 | |
276 #if 0 | |
277 static ExifTextList NikonTag[]= { | |
278 { , "" }, | |
279 { , "" }, | |
280 EXIF_TEXT_LIST_END | |
281 }; | |
282 #endif | |
283 | |
284 static ExifMarker NikonExifMarkersList1[] = { | |
285 { 0x0002, EXIF_FORMAT_STRING, 6, "MkN.Nikon.unknown", NULL, NULL }, | |
286 { 0x0003, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.Quality", "Quality", NikonTagQuality }, | |
287 { 0x0004, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.ColorMode", "Color mode", NikonTagColorMode }, | |
288 { 0x0005, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.ImageAdjustment", | |
289 "Image adjustment", NikonTagImgAdjust }, | |
290 { 0x0006, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.ISOSensitivity", | |
291 "ISO sensitivity", NikonTagISOSensitivity }, | |
292 { 0x0007, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.WhiteBalance", | |
293 "White balance", NikonTagWhiteBalance }, | |
294 { 0x0008, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "MkN.Nikon.Focus", "Focus", NULL }, | |
295 { 0x000a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "MkN.Nikon.DigitalZoom","Digital zoom", NULL }, | |
296 { 0x000b, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.Converter", "Converter", NikonTagConverter }, | |
297 EXIF_MARKER_LIST_END | |
298 }; | |
299 | |
300 static ExifTextList NikonTag2FlashComp[]= { | |
301 { 0x06, "+1.0 EV" }, | |
302 { 0x04, "+0.7 EV" }, | |
303 { 0x03, "+0.5 EV" }, | |
304 { 0x02, "+0.3 EV" }, | |
305 { 0x00, "0.0 EV" }, | |
306 { 0xfe, "-0.3 EV" }, | |
307 { 0xfd, "-0.5 EV" }, | |
308 { 0xfc, "-0.7 EV" }, | |
309 { 0xfa, "-1.0 EV" }, | |
310 { 0xf8, "-1.3 EV" }, | |
311 { 0xf7, "-1.5 EV" }, | |
312 { 0xf6, "-1.7 EV" }, | |
313 { 0xf4, "-2.0 EV" }, | |
314 { 0xf2, "-2.3 EV" }, | |
315 { 0xf1, "-2.5 EV" }, | |
316 { 0xf0, "-2.7 EV" }, | |
317 { 0xee, "-3.0 EV" }, | |
318 EXIF_TEXT_LIST_END | |
319 }; | |
320 | |
321 static ExifTextList NikonTag2FlashUsed[]= { | |
322 { 0, "no" }, | |
323 { 9, "yes" }, | |
324 EXIF_TEXT_LIST_END | |
325 }; | |
326 | |
327 #if 0 | |
328 static ExifTextList NikonTagi2Saturation[]= { | |
329 { -3, "black and white" }, | |
330 { -2, "-2" }, | |
331 { -1, "-1" }, | |
332 { 0, "normal" }, | |
333 { 1, "+1" }, | |
334 { 2, "+2" }, | |
335 EXIF_TEXT_LIST_END | |
336 }; | |
337 #endif | |
338 | |
339 static ExifMarker NikonExifMarkersList2[] = { | |
340 { 0x0002, EXIF_FORMAT_SHORT_UNSIGNED, 2, "MkN.Nikon.ISOSpeed", "ISO speed", NULL }, | |
341 { 0x0003, EXIF_FORMAT_STRING, -1, "MkN.Nikon.ColorMode", "Color mode", NULL }, | |
342 { 0x0004, EXIF_FORMAT_STRING, -1, "MkN.Nikon.Quality", "Quality", NULL }, | |
343 { 0x0005, EXIF_FORMAT_STRING, -1, "MkN.Nikon.WhiteBalance", | |
344 "White balance", NULL }, | |
345 { 0x0006, EXIF_FORMAT_STRING, -1, "MkN.Nikon.Sharpening", "Sharpening", NULL }, | |
346 { 0x0007, EXIF_FORMAT_STRING, -1, "MkN.Nikon.FocusMode", "Focus mode", NULL }, | |
347 { 0x0008, EXIF_FORMAT_STRING, -1, "MkN.Nikon.FlashSetting", | |
348 "Flash setting", NULL }, | |
349 { 0x0009, EXIF_FORMAT_STRING, -1, "MkN.Nikon.AutoFlashMode","Auto flash mode",NULL }, | |
350 { 0x000b, EXIF_FORMAT_SHORT, 1, "MkN.Nikon.WhiteBalanceBias", | |
351 "White balance bias value", NULL }, | |
352 /* { 0x000c, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.WhiteBalanceCoeff", | |
353 "White balance red/blue coefficents", NULL }, */ | |
354 /* { 0x000f, EXIF_FORMAT_STRING, -1, "MkN.Nikon.ISOSelect", "ISO selection",NULL }, */ | |
355 { 0x0012, EXIF_FORMAT_UNDEFINED, 4, "MkN.Nikon.FlashCompensation", | |
356 "Flash compensation", NikonTag2FlashComp }, | |
357 { 0x0013, EXIF_FORMAT_SHORT_UNSIGNED, 2, "MkN.Nikon.ISOSpeedRequest", | |
358 "ISO speed requested", NULL }, | |
359 { 0x0016, EXIF_FORMAT_SHORT_UNSIGNED, 4, "MkN.Nikon.CornerCoord", | |
360 "Corner coordinates", NULL }, | |
361 { 0x0018, EXIF_FORMAT_UNDEFINED, 4, "MkN.Nikon.FlashBracketCompensation", | |
362 "Flash bracket compensation", NikonTag2FlashComp }, | |
363 { 0x0019, EXIF_FORMAT_RATIONAL, 1, "MkN.Nikon.AEBracketCompensation", | |
364 "AE bracket compensation", NULL }, | |
365 { 0x0080, EXIF_FORMAT_STRING, -1, "MkN.Nikon.ImageAdjustment", | |
366 "Image adjustment", NULL }, | |
367 { 0x0081, EXIF_FORMAT_STRING, -1, "MkN.Nikon.Contrast", "Contrast", NULL }, | |
368 { 0x0082, EXIF_FORMAT_STRING, -1, "MkN.Nikon.AuxLens","Aux lens adapter", NULL }, | |
369 { 0x0083, EXIF_FORMAT_BYTE_UNSIGNED, -1, "MkN.Nikon.LensType", "Lens type", NULL }, | |
370 { 0x0084, EXIF_FORMAT_RATIONAL_UNSIGNED, -1, "MkN.Nikon.LensFocalLength", | |
371 "Lens min/max focal length and aperture", NULL }, | |
372 { 0x0085, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.ManualFocusDistance", | |
373 "Manual focus distance", NULL }, | |
374 { 0x0086, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.DigitalZoomFactor", | |
375 "Digital zoom facotr", NULL }, | |
376 { 0x0087, EXIF_FORMAT_BYTE_UNSIGNED, 1, "MkN.Nikon.FlashUsed", "Flash used", NikonTag2FlashUsed }, | |
377 { 0x0088, EXIF_FORMAT_UNDEFINED, -1, "MkN.Nikon.AutoFocusArea", NULL, NULL }, | |
378 /* { 0x0089, EXIF_FORMAT_SHORT_UNSIGNED, -1, "MkN.Nikon.Bracket/ShootingMode", NULL, NULL }, */ | |
379 { 0x008d, EXIF_FORMAT_STRING, -1, "MkN.Nikon.ColorMode", "Color mode", NULL }, | |
380 { 0x008f, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.SceneMode", NULL, NULL }, | |
381 { 0x0090, EXIF_FORMAT_STRING, -1, "MkN.Nikon.LightingType", "Lighting type", NULL }, | |
382 { 0x0092, EXIF_FORMAT_SHORT, 1, "MkN.Nikon.HueAdjust", "Hue adjustment", NULL }, | |
383 /* { 0x0094, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Nikon.Saturation", "Saturation", NikonTag2Saturation }, */ | |
384 { 0x0095, EXIF_FORMAT_STRING, -1, "MkN.Nikon.NoiseReduction", "Noise reduction", NULL }, | |
385 { 0x00a7, EXIF_FORMAT_LONG_UNSIGNED, 1, "MkN.Nikon.ShutterCount", "Shutter release count", NULL }, | |
386 { 0x00a9, EXIF_FORMAT_STRING, -1, "MkN.Nikon.ImageOptimization", "Image optimization", NULL }, | |
387 { 0x00aa, EXIF_FORMAT_STRING, -1, "MkN.Nikon.Saturation", "Saturation", NULL }, | |
388 { 0x00ab, EXIF_FORMAT_STRING, -1, "MkN.Nikon.DigitalVariProg", "Digital Vari-program", NULL }, | |
389 EXIF_MARKER_LIST_END | |
390 }; | |
391 | |
392 | |
393 gint format_nikon_makernote(ExifData *exif, unsigned char *tiff, guint offset, | |
394 guint size, ExifByteOrder byte_order) | |
395 { | |
396 unsigned char *data; | |
397 | |
398 if (offset + 8 + 4 >= size) return FALSE; | |
399 | |
400 data = tiff + offset; | |
401 if (memcmp(data, "Nikon\x00\x01\x00", 8) == 0) | |
402 { | |
403 if (exif_parse_IFD_table(exif, tiff, offset + 8, size, | |
404 byte_order, NikonExifMarkersList1) != 0) | |
405 { | |
406 return FALSE; | |
407 } | |
408 return TRUE; | |
409 } | |
410 | |
411 if (memcmp(data, "Nikon\x00\x02\x00\x00\x00", 10) == 0 || | |
412 memcmp(data, "Nikon\x00\x02\x10\x00\x00", 10) == 0) | |
413 { | |
414 guint tiff_header; | |
415 | |
416 tiff_header = offset + 10; | |
417 if (exif_parse_TIFF(exif, tiff + tiff_header, size - tiff_header, | |
418 NikonExifMarkersList2) != 0) | |
419 { | |
420 return FALSE; | |
421 } | |
422 return TRUE; | |
423 } | |
424 | |
425 /* fixme: support E990 and D1 */ | |
426 if (exif_parse_IFD_table(exif, tiff, offset, size, | |
427 byte_order, NikonExifMarkersList2) != 0) | |
428 { | |
429 return FALSE; | |
430 } | |
431 | |
432 return FALSE; | |
433 } | |
434 |