~ubuntu-branches/ubuntu/vivid/rawstudio/vivid

« back to all changes in this revision

Viewing changes to src/tiff-meta.c

  • Committer: Bazaar Package Importer
  • Author(s): Bernd Zeimetz
  • Date: 2011-07-28 17:36:32 UTC
  • mfrom: (2.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20110728173632-5czluz9ye3c83zc5
Tags: 2.0-1
* [3750b2cf] Merge commit 'upstream/2.0'
* [63637468] Removing Patch, not necessary anymore.
* [2fb580dc] Add new build-dependencies.
* [c57d953b] Run dh_autoreconf due to patches in configure.in
* [13febe39] Add patch to remove the libssl requirement.
* [5ae773fe] Replace libjpeg62-dev by libjpeg8-dev :)
* [1969d755] Don't build static libraries.
* [7cfe0a2e] Add a patch to fix the plugin directory path.
  As plugins are shared libraries, they need to go into /usr/lib,
  not into /usr/share.
  Thanks to Andrew McMillan
* [c1d0d9dd] Don't install .la files for all plugins and libraries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2006-2009 Anders Brander <anders@brander.dk> and 
3
 
 * Anders Kvist <akv@lnxbx.dk>
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License
7
 
 * as published by the Free Software Foundation; either version 2
8
 
 * of the License, or (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
 
 */
19
 
 
20
 
#include <gtk/gtk.h>
21
 
#include <math.h>
22
 
#include "rawstudio.h"
23
 
#include "rawfile.h"
24
 
#include "tiff-meta.h"
25
 
#include "adobe-coeff.h"
26
 
#include "rs-image.h"
27
 
#include "rs-color-transform.h"
28
 
#include "rs-utils.h"
29
 
#include "rs-filetypes.h"
30
 
#include "rs-metadata.h"
31
 
#include <arpa/inet.h> /* sony_decrypt(): htonl() */
32
 
 
33
 
/* It is required having some arbitrary maximum exposure time to prevent borked
34
 
 * shutter speed values being interpreted from the tiff.
35
 
 * 8h seems to be reasonable, even for astronomists with extra battery packs */
36
 
#define EXPO_TIME_MAXVAL (8*60.0*60.0)
37
 
 
38
 
typedef struct {
39
 
        RSMetadata meta;
40
 
        gint sony_offset;
41
 
        gint sony_length;
42
 
        gint sony_key;
43
 
        guint pad[128];
44
 
        guint p;
45
 
} SonyMeta;
46
 
 
47
 
struct IFD {
48
 
        gushort tag;
49
 
        gushort type;
50
 
        guint count;
51
 
        guint value_offset;
52
 
        guchar value_uchar;
53
 
        gushort value_ushort;
54
 
        guint value_uint;
55
 
        gdouble value_rational;
56
 
        guint offset;
57
 
        gdouble value;
58
 
};
59
 
 
60
 
static gfloat get_rational(RAWFILE *rawfile, guint offset);
61
 
inline static void read_ifd(RAWFILE *rawfile, guint offset, struct IFD *ifd);
62
 
static gboolean makernote_canon(RAWFILE *rawfile, guint offset, RSMetadata *meta);
63
 
static gboolean makernote_leica(RAWFILE *rawfile, guint offset, RSMetadata *meta);
64
 
static gboolean makernote_minolta(RAWFILE *rawfile, guint offset, RSMetadata *meta);
65
 
static gboolean makernote_nikon(RAWFILE *rawfile, guint offset, RSMetadata *meta);
66
 
static gboolean makernote_olympus(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta);
67
 
static gboolean makernote_olympus_camerasettings(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta);
68
 
static gboolean makernote_olympus_imageprocessing(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta);
69
 
static gboolean makernote_panasonic(RAWFILE *rawfile, guint offset, RSMetadata *meta);
70
 
static gboolean makernote_pentax(RAWFILE *rawfile, guint offset, RSMetadata *meta);
71
 
static void sony_decrypt(SonyMeta *sony, guint *data, gint len);
72
 
static gboolean private_sony(RAWFILE *rawfile, guint offset, RSMetadata *meta);
73
 
static gboolean ifd_reader(RAWFILE *rawfile, guint offset, RSMetadata *meta);
74
 
static gboolean thumbnail_reader(const gchar *service, RAWFILE *rawfile, guint offset, guint length, RSMetadata *meta);
75
 
 
76
 
typedef enum tiff_field_type
77
 
{
78
 
        TIFF_FIELD_TYPE_UNDEF__ = 0,
79
 
        TIFF_FIELD_TYPE_BYTE = 1,
80
 
        TIFF_FIELD_TYPE_ASCII = 2,
81
 
        TIFF_FIELD_TYPE_SHORT = 3,
82
 
        TIFF_FIELD_TYPE_LONG = 4,
83
 
        TIFF_FIELD_TYPE_RATIONAL = 5,
84
 
 
85
 
        /* Added in TIFF 6.0 */
86
 
        TIFF_FIELD_TYPE_SBYTE = 6,
87
 
        TIFF_FIELD_TYPE_UNDEFINED = 7,
88
 
        TIFF_FIELD_TYPE_SSHORT = 8,
89
 
        TIFF_FIELD_TYPE_SLONG = 9,
90
 
        TIFF_FIELD_TYPE_SRATIONAL = 10,
91
 
        TIFF_FIELD_TYPE_FLOAT = 11,
92
 
        TIFF_FIELD_TYPE_DOUBLE = 12,
93
 
 
94
 
        /* Just for convenience */
95
 
        TIFF_FIELD_TYPE_MAX = 12,
96
 
} TIFF_FIELD_TYPE;
97
 
 
98
 
guint tiff_field_size[TIFF_FIELD_TYPE_MAX+1] = {1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
99
 
 
100
 
/**
101
 
 * Get a TIFF_FIELD_TYPE_RATIONAL value from a TIFF file
102
 
 */
103
 
static gfloat
104
 
get_rational(RAWFILE *rawfile, guint offset)
105
 
{
106
 
        guint uint1=0, uint2=1;
107
 
        raw_get_uint(rawfile, offset, &uint1);
108
 
        raw_get_uint(rawfile, offset+4, &uint2);
109
 
 
110
 
        return ((gdouble) uint1) / ((gdouble) uint2);
111
 
}
112
 
 
113
 
inline static void
114
 
read_ifd(RAWFILE *rawfile, guint offset, struct IFD *ifd)
115
 
{
116
 
/*      guint size = 0; */
117
 
        guint uint1, uint2;
118
 
 
119
 
        raw_get_ushort(rawfile, offset, &ifd->tag);
120
 
        raw_get_ushort(rawfile, offset+2, &ifd->type);
121
 
        raw_get_uint(rawfile, offset+4, &ifd->count);
122
 
        raw_get_uint(rawfile, offset+8, &ifd->value_offset);
123
 
 
124
 
        ifd->value = 0;
125
 
 
126
 
        if (ifd->type > 0 && ifd->type <= TIFF_FIELD_TYPE_MAX)
127
 
        {
128
 
                if ((ifd->count * tiff_field_size[ifd->type]) < 5)
129
 
                        ifd->offset = offset+8;
130
 
                else
131
 
                        ifd->offset = ifd->value_offset;
132
 
        }
133
 
 
134
 
        if (ifd->count == 1)
135
 
                switch (ifd->type)
136
 
                {
137
 
                        case TIFF_FIELD_TYPE_BYTE:
138
 
                                raw_get_uchar(rawfile, offset+8, &ifd->value_uchar);
139
 
                                ifd->value = ifd->value_uchar;
140
 
                                break;
141
 
                        case TIFF_FIELD_TYPE_SHORT:
142
 
                                raw_get_ushort(rawfile, offset+8, &ifd->value_ushort);
143
 
                                ifd->value = ifd->value_ushort;
144
 
                                break;
145
 
                        case TIFF_FIELD_TYPE_LONG:
146
 
                                raw_get_uint(rawfile, offset+8, &ifd->value_uint);
147
 
                                ifd->value = ifd->value_uint;
148
 
                                break;
149
 
                        case TIFF_FIELD_TYPE_RATIONAL:
150
 
                                raw_get_uint(rawfile, ifd->value_offset, &uint1);
151
 
                                raw_get_uint(rawfile, ifd->value_offset+4, &uint2);
152
 
                                ifd->value_rational = ((gdouble) uint1) / ((gdouble) uint2);
153
 
                                ifd->value = ifd->value_rational;
154
 
                        default:
155
 
                                /* FIXME: Implement types from TIFF 6.0 */
156
 
                                break;
157
 
                }
158
 
}
159
 
 
160
 
#if 0
161
 
static void
162
 
print_ifd(RAWFILE *rawfile, struct IFD *ifd)
163
 
{
164
 
        gchar *tmp;
165
 
        printf("tag: %04x ", ifd->tag);
166
 
        printf("%8u ", ifd->type);
167
 
        printf("%8u * ", ifd->count);
168
 
        switch (ifd->type)
169
 
        {
170
 
                case TIFF_FIELD_TYPE_ASCII:
171
 
                        tmp = raw_strdup (rawfile, ifd->value_offset, ifd->count);
172
 
                        printf("[%-30s] ", tmp);
173
 
                        g_free(tmp);
174
 
                        break;
175
 
                case TIFF_FIELD_TYPE_SHORT:
176
 
                        printf("[%8u] ", ifd->value_ushort);
177
 
                        break;
178
 
                case TIFF_FIELD_TYPE_LONG:
179
 
                        printf("[%8u] ", ifd->value_offset);
180
 
                        break;
181
 
                case TIFF_FIELD_TYPE_RATIONAL:
182
 
                        printf("[%.03f] ", ifd->value_rational);
183
 
                        break;
184
 
                default:
185
 
                        printf("[0x%08x] ", ifd->value_offset);
186
 
                        break;
187
 
        }
188
 
        printf("@ %d ", ifd->offset);
189
 
        printf("{ %.05f }", ifd->value);
190
 
        printf("\n");
191
 
}
192
 
#endif
193
 
 
194
 
static gboolean
195
 
makernote_canon(RAWFILE *rawfile, guint offset, RSMetadata *meta)
196
 
{
197
 
        gushort number_of_entries = 0;
198
 
        gushort ushort_temp1;
199
 
 
200
 
        struct IFD ifd;
201
 
 
202
 
        /* get number of entries */
203
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
204
 
                return FALSE;
205
 
        offset += 2;
206
 
 
207
 
        while(number_of_entries--)
208
 
        {
209
 
                read_ifd(rawfile, offset, &ifd);
210
 
                offset += 12;
211
 
 
212
 
                switch (ifd.tag)
213
 
                {
214
 
                        case 0x4001: /* white balance for mulpiple Canon cameras */
215
 
                                switch (ifd.count)
216
 
                                {
217
 
                                        case 582: /* Canon 20D, 350D */
218
 
                                                ifd.value_offset += 50;
219
 
                                                break;
220
 
                                        case 653: /* Canon EOS 1D Mk II, Canon 1Ds Mk2 */
221
 
                                                ifd.value_offset += 68;
222
 
                                                break;
223
 
                                        case 674: /* Canon EOS 1D Mk III */
224
 
                                        case 692: /* Canon EOS 40D */
225
 
                                        case 702: /* Canon EOS 1Ds Mk III */
226
 
                                        case 796: /* Canon EOS 5D, Canon EOS 30D, Canon EOS 400D */
227
 
                                        case 1227: /* Canon EOS 450D */
228
 
                                        case 1250: /* Canon EOS 5D Mk II */
229
 
                                                ifd.value_offset += 126;
230
 
                                                break;
231
 
                                        case 5120: /* Canon PowerShot G10 */
232
 
                                                ifd.value_offset += 142;
233
 
                                                break;
234
 
                                }
235
 
                                /* RGGB-format! */
236
 
                                raw_get_ushort(rawfile, ifd.value_offset, &ushort_temp1);
237
 
                                meta->cam_mul[0] = (gdouble) ushort_temp1;
238
 
                                raw_get_ushort(rawfile, ifd.value_offset+2, &ushort_temp1);
239
 
                                meta->cam_mul[1] = (gdouble) ushort_temp1;
240
 
                                raw_get_ushort(rawfile, ifd.value_offset+4, &ushort_temp1);
241
 
                                meta->cam_mul[3] = (gdouble) ushort_temp1;
242
 
                                raw_get_ushort(rawfile, ifd.value_offset+6, &ushort_temp1);
243
 
                                meta->cam_mul[2] = (gdouble) ushort_temp1;
244
 
                                rs_metadata_normalize_wb(meta);
245
 
                                break;
246
 
                }
247
 
        }
248
 
 
249
 
        return TRUE;
250
 
}
251
 
 
252
 
static gboolean
253
 
makernote_leica(RAWFILE *rawfile, guint offset, RSMetadata *meta)
254
 
{
255
 
        gboolean ret = FALSE;
256
 
        gushort number_of_entries = 0;
257
 
        guint version = 0;
258
 
 
259
 
        struct IFD ifd;
260
 
 
261
 
        /* get number of entries */
262
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
263
 
                return FALSE;
264
 
        offset += 2;
265
 
 
266
 
        while(number_of_entries--)
267
 
        {
268
 
                read_ifd(rawfile, offset, &ifd);
269
 
                offset += 12;
270
 
 
271
 
                switch (version)
272
 
                {
273
 
                        case 100:
274
 
                                switch(ifd.tag)
275
 
                                {
276
 
                                        case 0x0011: /* Red balance */
277
 
                                                meta->cam_mul[1] = 1.0;
278
 
                                                meta->cam_mul[3] = 1.0;
279
 
                                                meta->cam_mul[0] = ifd.value / 256.0;
280
 
                                                break;
281
 
                                        case 0x0012: /* Blue balance */
282
 
                                                meta->cam_mul[2] = ifd.value / 256.0;
283
 
                                                break;
284
 
                                        case 0x8769: /* ExifIFDPointer */
285
 
                                                exif_reader(rawfile, ifd.value_offset, meta);
286
 
                                                break;
287
 
                                }
288
 
                                break;
289
 
                        case 200:
290
 
                                switch(ifd.tag)
291
 
                                {
292
 
                                        case 0x0024: /* WB Red Level */
293
 
                                                meta->cam_mul[0] = ifd.value;
294
 
                                                break;
295
 
                                        case 0x0025: /* WB Green Level */
296
 
                                                meta->cam_mul[1] = ifd.value;
297
 
                                                meta->cam_mul[3] = ifd.value;
298
 
                                                break;
299
 
                                        case 0x0026: /* WB Blue Level */
300
 
                                                meta->cam_mul[2] = ifd.value;
301
 
                                                break;
302
 
                                        case 0x8769: /* ExifIFDPointer */
303
 
                                                exif_reader(rawfile, ifd.value_offset, meta);
304
 
                                                break;
305
 
                                }
306
 
                                break;
307
 
                        default:
308
 
                                switch(ifd.tag)
309
 
                                {
310
 
                                        case 0x0001: /* Raw version */
311
 
                                                switch (ifd.value_offset)
312
 
                                                {
313
 
                                                        case 0x30303130: /* Leica */
314
 
                                                                version = 100;
315
 
                                                                ret = TRUE;
316
 
                                                                break;
317
 
                                                        case 0x30303230: /* Leica / Panasonic */
318
 
                                                                version = 200;
319
 
                                                                ret = FALSE;
320
 
                                                                break;
321
 
                                                        case 0x30313230: /* Panasonic */
322
 
                                                                version = 210;
323
 
                                                                ret = FALSE;
324
 
                                                                break;
325
 
                                                        case 0x31303230: /* Panasonic */
326
 
                                                                version = 201;
327
 
                                                                ret = FALSE;
328
 
                                                                break;
329
 
                                                        case 0x32303230: /* Panasonic */
330
 
                                                                version = 202;
331
 
                                                                ret = FALSE;
332
 
                                                                break;
333
 
                                                        default:
334
 
                                                                ret = FALSE;
335
 
                                                                break;
336
 
                                                }
337
 
                                                break;
338
 
                                }
339
 
                                break;
340
 
                }
341
 
        }
342
 
        rs_metadata_normalize_wb(meta);
343
 
 
344
 
        return ret;
345
 
}
346
 
 
347
 
static gboolean
348
 
makernote_minolta(RAWFILE *rawfile, guint offset, RSMetadata *meta)
349
 
{
350
 
        gushort number_of_entries = 0;
351
 
 
352
 
        struct IFD ifd;
353
 
 
354
 
        /* get number of entries */
355
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
356
 
                return FALSE;
357
 
        offset += 2;
358
 
 
359
 
        while(number_of_entries--)
360
 
        {
361
 
                read_ifd(rawfile, offset, &ifd);
362
 
                offset += 12;
363
 
 
364
 
                switch (ifd.tag)
365
 
                {
366
 
                        case 0x0088: /* Minolta */
367
 
                                meta->preview_start = ifd.value_offset + raw_get_base(rawfile);
368
 
                                break;
369
 
                        case 0x0081: /* Minolta DiMAGE 5 */
370
 
                                meta->thumbnail_start = ifd.value_offset + raw_get_base(rawfile);
371
 
                                meta->thumbnail_length = ifd.count;
372
 
                                break;
373
 
                        case 0x0089: /* Minolta */
374
 
                                meta->preview_length = ifd.value_offset;
375
 
                                break;
376
 
                }
377
 
        }
378
 
 
379
 
        return TRUE;
380
 
}
381
 
 
382
 
static gboolean
383
 
makernote_nikon(RAWFILE *rawfile, guint offset, RSMetadata *meta)
384
 
{
385
 
        static const guchar xlat[2][256] = {
386
 
        { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
387
 
        0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
388
 
        0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
389
 
        0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
390
 
        0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
391
 
        0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
392
 
        0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
393
 
        0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
394
 
        0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
395
 
        0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
396
 
        0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
397
 
        0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
398
 
        0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
399
 
        0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
400
 
        0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
401
 
        0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
402
 
        { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
403
 
        0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
404
 
        0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
405
 
        0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
406
 
        0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
407
 
        0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
408
 
        0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
409
 
        0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
410
 
        0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
411
 
        0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
412
 
        0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
413
 
        0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
414
 
        0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
415
 
        0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
416
 
        0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
417
 
        0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
418
 
        gint i;
419
 
        guint tmp;
420
 
        gushort number_of_entries;
421
 
        gushort fieldtag=0;
422
 
        gushort fieldtype;
423
 
        gushort ushort_temp1=0;
424
 
        gfloat float_temp1=0.0, float_temp2=0.0;
425
 
        guint valuecount;
426
 
        guint uint_temp1=0;
427
 
        guchar char_tmp='\0';
428
 
        guint base;
429
 
        guint save;
430
 
        gint serial = 0;
431
 
        guint ver97 = 0;
432
 
        guchar buf97[324], ci, cj, ck;
433
 
        gboolean magic; /* Nikon's makernote type */
434
 
 
435
 
        if (raw_strcmp(rawfile, offset, "Nikon", 5))
436
 
        {
437
 
                base = offset +=10;
438
 
                raw_get_uint(rawfile, offset+4, &tmp);
439
 
                offset += tmp;
440
 
                magic = TRUE;
441
 
        }
442
 
        else
443
 
        {
444
 
                magic = FALSE;
445
 
                base = offset;
446
 
        }
447
 
 
448
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
449
 
                return FALSE;
450
 
        if (number_of_entries>5000)
451
 
                return FALSE;
452
 
        offset += 2;
453
 
 
454
 
        save = offset;
455
 
        while(number_of_entries--)
456
 
        {
457
 
                /* FIXME: Port to read_ifd() */
458
 
                offset = save;
459
 
                raw_get_ushort(rawfile, offset, &fieldtag);
460
 
                raw_get_ushort(rawfile, offset+2, &fieldtype);
461
 
                raw_get_uint(rawfile, offset+4, &valuecount);
462
 
                offset += 8;
463
 
 
464
 
                save = offset + 4;
465
 
                if ((valuecount * ("1112481124848"[fieldtype < 13 ? fieldtype:0]-'0') > 4) && magic)
466
 
                {
467
 
                        raw_get_uint(rawfile, offset, &uint_temp1);
468
 
                        offset = base + uint_temp1;
469
 
                }
470
 
                switch(fieldtag)
471
 
                {
472
 
                        case 0x0002: /* ISO */
473
 
                                raw_get_ushort(rawfile, offset+2, &meta->iso);
474
 
                                break;
475
 
                        case 0x000c: /* D1 White Balance */
476
 
                                if (g_str_equal(meta->model_ascii, "NIKON D1X") || g_str_equal(meta->model_ascii, "NIKON D90"))
477
 
                                {
478
 
                                        meta->cam_mul[0] = get_rational(rawfile, offset);
479
 
                                        meta->cam_mul[2] = get_rational(rawfile, offset+8);
480
 
                                        meta->cam_mul[1] = get_rational(rawfile, offset+16);
481
 
                                        meta->cam_mul[3] = get_rational(rawfile, offset+24);
482
 
                                        rs_metadata_normalize_wb(meta);
483
 
                                }
484
 
                                else
485
 
                                {
486
 
                                        /* This is fucked, where did these two magic constants come from? */
487
 
                                        raw_get_float(rawfile, uint_temp1, &float_temp1);
488
 
                                        raw_get_float(rawfile, uint_temp1+4, &float_temp2);
489
 
                                        meta->cam_mul[0] = (gdouble) (float_temp1/float_temp2)/1.0;//2.218750;
490
 
 
491
 
                                        raw_get_float(rawfile, uint_temp1+8, &float_temp1);
492
 
                                        raw_get_float(rawfile, uint_temp1+12, &float_temp2);
493
 
                                        meta->cam_mul[2] = (gdouble) (float_temp1/float_temp2)/1.0;//1.148438;
494
 
 
495
 
                                        raw_get_float(rawfile, uint_temp1+16, &float_temp1);
496
 
                                        raw_get_float(rawfile, uint_temp1+20, &float_temp2);
497
 
                                        meta->cam_mul[1] = (gdouble) (float_temp1/float_temp2);
498
 
 
499
 
                                        raw_get_float(rawfile, uint_temp1+24, &float_temp1);
500
 
                                        raw_get_float(rawfile, uint_temp1+28, &float_temp2);
501
 
                                        meta->cam_mul[3] = (gdouble) (float_temp1/float_temp2);
502
 
 
503
 
                                        rs_metadata_normalize_wb(meta);
504
 
                                }
505
 
                                break;
506
 
                        case 0x0011: /* NikonPreview */
507
 
                                raw_get_uint(rawfile, offset, &uint_temp1);
508
 
                                ifd_reader(rawfile, uint_temp1+base, meta);
509
 
                                meta->thumbnail_start += base;
510
 
                                break;
511
 
                        case 0x0097: /* white balance */
512
 
                                if (g_str_equal(meta->model_ascii, "NIKON D90"))
513
 
                                        break;
514
 
 
515
 
                                for(i=0;i<4;i++)
516
 
                                {
517
 
                                        raw_get_uchar(rawfile, offset+i, &char_tmp);
518
 
                                        ver97 = (ver97 << 4) + char_tmp-'0';
519
 
                                }
520
 
                                offset += 4;
521
 
                                switch (ver97)
522
 
                                {
523
 
                                        case 0x100:
524
 
                                                /* RBGG-format */
525
 
                                                offset += 68;
526
 
                                                raw_get_ushort(rawfile, offset, &ushort_temp1);
527
 
                                                meta->cam_mul[0] = (gdouble) ushort_temp1;
528
 
                                                raw_get_ushort(rawfile, offset+2, &ushort_temp1);
529
 
                                                meta->cam_mul[2] = (gdouble) ushort_temp1;
530
 
                                                raw_get_ushort(rawfile, offset+4, &ushort_temp1);
531
 
                                                meta->cam_mul[1] = (gdouble) ushort_temp1;
532
 
                                                raw_get_ushort(rawfile, offset+6, &ushort_temp1);
533
 
                                                meta->cam_mul[3] = (gdouble) ushort_temp1;
534
 
                                                rs_metadata_normalize_wb(meta);
535
 
                                                break;
536
 
                                        case 0x102:
537
 
                                                /* RGGB-format */
538
 
                                                offset += 6;
539
 
                                                raw_get_ushort(rawfile, offset, &ushort_temp1);
540
 
                                                meta->cam_mul[0] = (gdouble) ushort_temp1;
541
 
                                                raw_get_ushort(rawfile, offset+2, &ushort_temp1);
542
 
                                                meta->cam_mul[1] = (gdouble) ushort_temp1;
543
 
                                                raw_get_ushort(rawfile, offset+4, &ushort_temp1);
544
 
                                                meta->cam_mul[3] = (gdouble) ushort_temp1;
545
 
                                                raw_get_ushort(rawfile, offset+6, &ushort_temp1);
546
 
                                                meta->cam_mul[2] = (gdouble) ushort_temp1;
547
 
                                                rs_metadata_normalize_wb(meta);
548
 
                                                break;
549
 
                                        case 0x103:
550
 
                                                offset += 16;
551
 
                                                for(i=0;i<4;i++)
552
 
                                                {
553
 
                                                        raw_get_ushort(rawfile, offset+2*i, &ushort_temp1);
554
 
                                                        meta->cam_mul[i] = ushort_temp1;
555
 
                                                }
556
 
                                                rs_metadata_normalize_wb(meta);
557
 
                                                break;
558
 
                                }
559
 
                                if (ver97 >> 8 == 2)
560
 
                                {
561
 
                                        if (ver97 != 0x205)
562
 
                                                offset += 280;
563
 
                                        raw_strcpy(rawfile, offset, buf97, 324);
564
 
                                }
565
 
                                break;
566
 
                        case 0x001d: /* serial */
567
 
                                raw_get_uchar(rawfile, offset++, &char_tmp);
568
 
                                while(char_tmp)
569
 
                                {
570
 
                                        serial = serial*10 + (g_ascii_isdigit(char_tmp) ? char_tmp - '0' : char_tmp % 10);
571
 
                                        raw_get_uchar(rawfile, offset++, &char_tmp);
572
 
                                }
573
 
                                break;
574
 
                        case 0x00a7: /* white balance */
575
 
                                if (ver97 >> 8 == 2)
576
 
                                {
577
 
                                        guchar ctmp[4];
578
 
                                        raw_get_uchar(rawfile, offset++, ctmp);
579
 
                                        raw_get_uchar(rawfile, offset++, ctmp+1);
580
 
                                        raw_get_uchar(rawfile, offset++, ctmp+2);
581
 
                                        raw_get_uchar(rawfile, offset, ctmp+3);
582
 
                                        ci = xlat[0][serial & 0xff];
583
 
                                        cj = xlat[1][ctmp[0]^ctmp[1]^ctmp[2]^ctmp[3]];
584
 
                                        ck = 0x60;
585
 
                                        for (i=0; i < 324; i++)
586
 
                                                buf97[i] ^= (cj += ci * ck++);
587
 
 
588
 
                                        for (i=0; i<4; i++)
589
 
                                                meta->cam_mul[i ^ (i >> 1)] = raw_get_ushort_from_string(
590
 
                                                        rawfile, (gchar *)(buf97 + (ver97 == 0x205 ? 14:6) + i*2));
591
 
                                        if (ver97 == 0x209) /* D300 */
592
 
                                                for(i=0; i<4; i++)
593
 
                                                        meta->cam_mul[i ^ (i >> 1) ^ 1] = raw_get_ushort_from_string(rawfile, (gchar *)(buf97 + 10 + i*2));
594
 
                                        rs_metadata_normalize_wb(meta);
595
 
                                }
596
 
                                break;
597
 
                        case 0x00aa: /* Nikon Saturation */
598
 
                                if (meta->make == MAKE_NIKON)
599
 
                                {       
600
 
                                        if (raw_strcmp(rawfile, offset, "ENHANCED", 8))
601
 
                                                meta->saturation = 1.5;
602
 
                                        else if (raw_strcmp(rawfile, offset, "MODERATE", 8))
603
 
                                                meta->saturation = 0.5;
604
 
                                        else
605
 
                                                meta->saturation = 1.0;
606
 
                                }
607
 
                                break;
608
 
                        case 0x0081: /* Nikon ToneComp (contrast)*/
609
 
                                if (meta->make == MAKE_NIKON)
610
 
                                {
611
 
                                        if (raw_strcmp(rawfile, offset, "HIGH", 4))
612
 
                                                meta->contrast = 1.2;
613
 
                                        else if (raw_strcmp(rawfile, offset, "LOW", 3))
614
 
                                                meta->contrast= 0.8;
615
 
                                        else
616
 
                                                meta->contrast = 1.0;
617
 
                                }
618
 
                                break;
619
 
 
620
 
                }
621
 
        }
622
 
        return TRUE;
623
 
}
624
 
 
625
 
static gboolean
626
 
makernote_olympus_camerasettings(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta)
627
 
{
628
 
        /* NOTE! At least on E-410 the offsets in this section is relative to
629
 
           the base of the MakerNotes! */
630
 
 
631
 
        gushort number_of_entries;
632
 
        gushort fieldtag=0;
633
 
        gushort fieldtype;
634
 
        guint valuecount;
635
 
        guint uint_temp1=0;
636
 
        guint save;
637
 
 
638
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
639
 
                return FALSE;
640
 
        if (number_of_entries>5000)
641
 
                return FALSE;
642
 
        offset += 2;
643
 
 
644
 
        save = offset;
645
 
        while(number_of_entries--)
646
 
        {
647
 
                /* FIXME: Port to read_ifd() */
648
 
                offset = save;
649
 
                raw_get_ushort(rawfile, offset, &fieldtag);
650
 
                raw_get_ushort(rawfile, offset+2, &fieldtype);
651
 
                raw_get_uint(rawfile, offset+4, &valuecount);
652
 
                offset += 8;
653
 
 
654
 
                save = offset + 4;
655
 
                if ((valuecount * ("1112481124848"[fieldtype < 13 ? fieldtype:0]-'0') > 4))
656
 
                {
657
 
                        raw_get_uint(rawfile, offset, &uint_temp1);
658
 
                        offset = base + uint_temp1;
659
 
                }
660
 
                raw_get_uint(rawfile, offset, &uint_temp1);
661
 
                switch(fieldtag)
662
 
                {
663
 
                        case 0x0101: /* PreviewImageStart */
664
 
                                raw_get_uint(rawfile, offset, &meta->preview_start);
665
 
                                meta->preview_start += raw_get_base(rawfile);
666
 
                                break;
667
 
                        case 0x0102: /* PreviewImageLength */
668
 
                                raw_get_uint(rawfile, offset, &meta->preview_length);
669
 
                                break;
670
 
                }
671
 
        }
672
 
        return TRUE;
673
 
}
674
 
 
675
 
static gboolean
676
 
makernote_olympus_imageprocessing(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta)
677
 
{
678
 
        gushort number_of_entries;
679
 
        struct IFD ifd;
680
 
        gushort ushort_temp1, ushort_temp2;
681
 
 
682
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
683
 
                return FALSE;
684
 
 
685
 
        if (number_of_entries>5000)
686
 
                return FALSE;
687
 
 
688
 
        offset += 2;
689
 
 
690
 
        while(number_of_entries--)
691
 
        {
692
 
                read_ifd(rawfile, offset, &ifd);
693
 
                offset += 12;
694
 
 
695
 
                switch(ifd.tag)
696
 
                {
697
 
                        case 0x0100: /* WB on E-510 */
698
 
                                if (ifd.count == 2)
699
 
                                {
700
 
                                        raw_get_ushort(rawfile, ifd.offset, &ushort_temp1);
701
 
                                        raw_get_ushort(rawfile, ifd.offset+2, &ushort_temp2);
702
 
                                }
703
 
                                else if (ifd.count == 4)
704
 
                                {
705
 
                                        raw_get_ushort(rawfile, ifd.offset+base, &ushort_temp1);
706
 
                                        raw_get_ushort(rawfile, ifd.offset+base+2, &ushort_temp2);
707
 
                                }
708
 
                                meta->cam_mul[0] = (gdouble) ushort_temp1 / 256.0;
709
 
                                meta->cam_mul[2] = (gdouble) ushort_temp2 / 256.0;
710
 
                                rs_metadata_normalize_wb(meta);
711
 
                                break;
712
 
                }
713
 
        }
714
 
        return TRUE;
715
 
}
716
 
 
717
 
static gboolean
718
 
makernote_olympus(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta)
719
 
{
720
 
        gushort number_of_entries;
721
 
        gushort fieldtag=0;
722
 
        gushort fieldtype;
723
 
        gushort ushort_temp1=0;
724
 
        guint valuecount;
725
 
        guint uint_temp1=0;
726
 
        guint save;
727
 
 
728
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
729
 
                return FALSE;
730
 
        if (number_of_entries>5000)
731
 
                return FALSE;
732
 
        offset += 2;
733
 
 
734
 
        save = offset;
735
 
        while(number_of_entries--)
736
 
        {
737
 
                /* FIXME: Port to read_ifd() */
738
 
                offset = save;
739
 
                raw_get_ushort(rawfile, offset, &fieldtag);
740
 
                raw_get_ushort(rawfile, offset+2, &fieldtype);
741
 
                raw_get_uint(rawfile, offset+4, &valuecount);
742
 
                offset += 8;
743
 
 
744
 
                save = offset + 4;
745
 
                if ((valuecount * ("1112481124848"[fieldtype < 13 ? fieldtype:0]-'0') > 4))
746
 
                {
747
 
                        raw_get_uint(rawfile, offset, &uint_temp1);
748
 
                        offset = base + uint_temp1;
749
 
                }
750
 
                raw_get_uint(rawfile, offset, &uint_temp1);
751
 
                switch(fieldtag)
752
 
                {
753
 
                        case 0x0100: /* Thumbnail */
754
 
                                raw_get_ushort(rawfile, save-4, &ushort_temp1);
755
 
                                meta->thumbnail_start = ushort_temp1;
756
 
                                meta->thumbnail_length = valuecount;
757
 
                                break;
758
 
                        case 0x1017: /* Red multiplier on many Olympus's (E-10, E-300, E-330, E-400, E-500) */
759
 
                                raw_get_ushort(rawfile, offset, &ushort_temp1);
760
 
                                meta->cam_mul[0] = (gdouble) ushort_temp1 / 256.0;
761
 
                                break;
762
 
                        case 0x1018: /* Blue multiplier on many Olympus's (E-10, E-300, E-330, E-400, E-500) */
763
 
                                raw_get_ushort(rawfile, offset, &ushort_temp1);
764
 
                                meta->cam_mul[2] = (gdouble) ushort_temp1 / 256.0;
765
 
                                break;
766
 
                        case 0x2020: /* Olympus CameraSettings Tags */
767
 
                                raw_get_uint(rawfile, offset, &uint_temp1);
768
 
                                makernote_olympus_camerasettings(rawfile, base+uint_temp1, base+uint_temp1, meta);
769
 
                                meta->preview_start += base; /* Stupid hack! */
770
 
                                break;
771
 
                        case 0x2040: /* Olympus ImageProcessing  */
772
 
                                raw_get_uint(rawfile, offset, &uint_temp1);
773
 
                                makernote_olympus_imageprocessing(rawfile, base, base+uint_temp1, meta);
774
 
                                break;
775
 
                }
776
 
        }
777
 
        return TRUE;
778
 
}
779
 
 
780
 
static gboolean
781
 
makernote_panasonic(RAWFILE *rawfile, guint offset, RSMetadata *meta)
782
 
{
783
 
        gushort number_of_entries;
784
 
        struct IFD ifd;
785
 
 
786
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
787
 
                return FALSE;
788
 
 
789
 
        if (number_of_entries>5000)
790
 
                return FALSE;
791
 
 
792
 
        offset += 2;
793
 
 
794
 
        while(number_of_entries--)
795
 
        {
796
 
                read_ifd(rawfile, offset, &ifd);
797
 
                offset += 12;
798
 
 
799
 
                switch(ifd.tag)
800
 
                {
801
 
                        case 0x0017: /* ISO */
802
 
                                meta->iso = ifd.value_offset;
803
 
                                break;
804
 
                        case 0x0024: /* WBRedLevel */
805
 
                                meta->cam_mul[0] = ifd.value_offset;
806
 
                                break;
807
 
                        case 0x0025: /* WBGreenLevel */
808
 
                                meta->cam_mul[1] = ifd.value_offset;
809
 
                                meta->cam_mul[3] = ifd.value_offset;
810
 
                                break;
811
 
                        case 0x0026: /* WBBlueLevel */
812
 
                                meta->cam_mul[2] = ifd.value_offset;
813
 
                                break;
814
 
                        case 0x002e: /* PreviewImage */
815
 
                                meta->preview_start = ifd.value_offset;
816
 
                                meta->preview_length = ifd.count;
817
 
                                break;
818
 
                        case 0x8769: /* ExifIFDPointer */
819
 
                                exif_reader(rawfile, ifd.value_offset, meta);
820
 
                                break;
821
 
                }
822
 
        }
823
 
 
824
 
        return TRUE;
825
 
}
826
 
 
827
 
static gboolean
828
 
makernote_pentax(RAWFILE *rawfile, guint offset, RSMetadata *meta)
829
 
{
830
 
        gushort number_of_entries;
831
 
        gushort ushort_temp1=0;
832
 
        struct IFD ifd;
833
 
 
834
 
        if (raw_strcmp(rawfile, offset, "AOC", 3))
835
 
                offset += 6;
836
 
        else
837
 
                return FALSE;
838
 
 
839
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
840
 
                return FALSE;
841
 
 
842
 
        if (number_of_entries>5000)
843
 
                return FALSE;
844
 
 
845
 
        offset += 2;
846
 
 
847
 
        while(number_of_entries--)
848
 
        {
849
 
                read_ifd(rawfile, offset, &ifd);
850
 
                offset += 12;
851
 
                switch(ifd.tag)
852
 
                {
853
 
                        case 0x0201: /* White balance */
854
 
                                raw_get_ushort(rawfile, ifd.value_offset, &ushort_temp1);
855
 
                                meta->cam_mul[0] = (gdouble) ushort_temp1;
856
 
                                raw_get_ushort(rawfile, ifd.value_offset+2, &ushort_temp1);
857
 
                                meta->cam_mul[1] = (gdouble) ushort_temp1;
858
 
                                raw_get_ushort(rawfile, ifd.value_offset+4, &ushort_temp1);
859
 
                                meta->cam_mul[3] = (gdouble) ushort_temp1;
860
 
                                raw_get_ushort(rawfile, ifd.value_offset+6, &ushort_temp1);
861
 
                                meta->cam_mul[2] = (gdouble) ushort_temp1;
862
 
                                break;
863
 
                }
864
 
        }
865
 
 
866
 
        return TRUE;
867
 
}
868
 
 
869
 
static void
870
 
sony_decrypt(SonyMeta *sony, guint *data, gint len)
871
 
{
872
 
        while (len--)
873
 
                *data++ ^= sony->pad[sony->p++ & 127] = sony->pad[(sony->p+1) & 127] ^ sony->pad[(sony->p+65) & 127];
874
 
}
875
 
 
876
 
static gboolean
877
 
private_sony(RAWFILE *rawfile, guint offset, RSMetadata *meta)
878
 
{
879
 
        gushort number_of_entries;
880
 
        struct IFD ifd;
881
 
        gint i;
882
 
        gint key;
883
 
        SonyMeta *sony = (SonyMeta *) meta;
884
 
 
885
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
886
 
                return FALSE;
887
 
 
888
 
        if (number_of_entries>5000)
889
 
                return FALSE;
890
 
 
891
 
        offset += 2;
892
 
 
893
 
        while(number_of_entries--)
894
 
        {
895
 
                read_ifd(rawfile, offset, &ifd);
896
 
                offset += 12;
897
 
 
898
 
                switch(ifd.tag)
899
 
                {
900
 
                        case 0x7200: /* SR2SubIFDOffset */
901
 
                                sony->sony_offset = ifd.value_offset;
902
 
                                break;
903
 
                        case 0x7201: /* SR2SubIFDLength */
904
 
                                sony->sony_length = ifd.value_offset;
905
 
                                break;
906
 
                        case 0x7221: /* SR2SubIFDKey */
907
 
                                sony->sony_key = ifd.value_offset;
908
 
 
909
 
                                /* Initialize decrypter */
910
 
                                key = sony->sony_key;
911
 
                                for (sony->p=0; sony->p < 4; sony->p++)
912
 
                                        sony->pad[sony->p] = key = key * 48828125 + 1;
913
 
                                sony->pad[3] = sony->pad[3] << 1 | (sony->pad[0]^sony->pad[2]) >> 31;
914
 
                                for (sony->p=4; sony->p < 127; sony->p++)
915
 
                                        sony->pad[sony->p] = (sony->pad[sony->p-4]^sony->pad[sony->p-2]) << 1 | (sony->pad[sony->p-3]^sony->pad[sony->p-1]) >> 31;
916
 
                                for (sony->p=0; sony->p < 127; sony->p++)
917
 
                                        sony->pad[sony->p] = htonl(sony->pad[sony->p]);
918
 
                                break;
919
 
                }
920
 
        }
921
 
 
922
 
        if ((sony->sony_offset > 0) && (sony->sony_length > 0) && (sony->sony_key != 0))
923
 
        {
924
 
                gpointer buf = g_new0(guchar, sony->sony_length);
925
 
                if (raw_strcpy(rawfile, sony->sony_offset, buf, sony->sony_length))
926
 
                {
927
 
                        sony_decrypt(sony, buf, sony->sony_length/4);
928
 
                        gushort *sbuf = (gushort *)(buf);
929
 
                        gushort tag_count = sbuf[0];
930
 
                        struct IFD *private_ifd;
931
 
 
932
 
                        for(i=0;i<tag_count;i++)
933
 
                        {
934
 
#if BYTE_ORDER == BIG_ENDIAN
935
 
#warning FIXME: This will NOT work as expected on a big endian host
936
 
#endif
937
 
                                private_ifd = (struct IFD *) (buf+2+i*12);
938
 
 
939
 
                                switch (private_ifd->tag)
940
 
                                {
941
 
                                        case 0x7303: /* WB_GRBGLevels */
942
 
                                                sbuf = (gushort *)(buf + private_ifd->value_offset - sony->sony_offset);
943
 
                                                meta->cam_mul[1] = (gdouble) sbuf[0];
944
 
                                                meta->cam_mul[0] = (gdouble) sbuf[1];
945
 
                                                meta->cam_mul[2] = (gdouble) sbuf[2];
946
 
                                                meta->cam_mul[3] = (gdouble) sbuf[3];
947
 
 
948
 
                                                rs_metadata_normalize_wb(meta);
949
 
                                                break;
950
 
                                        case 0x7313: /* WB_RGGBLevels */
951
 
                                                sbuf = (gushort *)(buf + private_ifd->value_offset - sony->sony_offset);
952
 
                                                meta->cam_mul[0] = (gdouble) sbuf[0];
953
 
                                                meta->cam_mul[1] = (gdouble) sbuf[1];
954
 
                                                meta->cam_mul[3] = (gdouble) sbuf[2];
955
 
                                                meta->cam_mul[2] = (gdouble) sbuf[3];
956
 
 
957
 
                                                rs_metadata_normalize_wb(meta);
958
 
                                                break;
959
 
                                }
960
 
                        }
961
 
                }
962
 
        }
963
 
 
964
 
        return TRUE;
965
 
}
966
 
 
967
 
gboolean
968
 
exif_reader(RAWFILE *rawfile, guint offset, RSMetadata *meta)
969
 
{
970
 
        gushort number_of_entries = 0;
971
 
 
972
 
        struct IFD ifd;
973
 
 
974
 
        /* get number of entries */
975
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
976
 
                return FALSE;
977
 
        offset += 2;
978
 
 
979
 
        while(number_of_entries--)
980
 
        {
981
 
                read_ifd(rawfile, offset, &ifd);
982
 
                offset += 12;
983
 
 
984
 
                switch (ifd.tag)
985
 
                {
986
 
                        case 0x010f: /* Make */
987
 
                                if (!meta->make_ascii)
988
 
                                        meta->make_ascii = raw_strdup(rawfile, ifd.value_offset, ifd.count);
989
 
                                break;
990
 
                        case 0x0110: /* Model */
991
 
                                if (!meta->model_ascii)
992
 
                                        meta->model_ascii = raw_strdup(rawfile, ifd.value_offset, ifd.count);
993
 
                                break;
994
 
                        case 0x9003: /* DateTime */
995
 
                        case 0x9004: /* DateTime */
996
 
                                if (!meta->time_ascii)
997
 
                                {
998
 
                                        meta->time_ascii = raw_strdup(rawfile, ifd.value_offset, ifd.count);
999
 
                                        meta->timestamp = rs_exiftime_to_unixtime(meta->time_ascii);
1000
 
                                }
1001
 
                                break;
1002
 
                        case 0x829A: /* ExposureTime */
1003
 
                                if (ifd.count == 1 && ifd.value_rational < EXPO_TIME_MAXVAL)
1004
 
                                        meta->shutterspeed = 1.0 / ifd.value_rational;
1005
 
                                break;
1006
 
                        case 0x829D: /* FNumber */
1007
 
                                if (ifd.count == 1)
1008
 
                                        meta->aperture = ifd.value_rational;
1009
 
                                break;
1010
 
                        case 0x8827: /* ISOSpeedRatings */
1011
 
                                if (ifd.count == 1)
1012
 
                                        meta->iso = ifd.value_ushort;
1013
 
                                break;
1014
 
                        case 0x920A: /* Focal length */
1015
 
                                        meta->focallength = ifd.value_rational;
1016
 
                                break;
1017
 
                        case 0x927c: /* MakerNote */
1018
 
                                switch (meta->make)
1019
 
                                {
1020
 
                                        case MAKE_CANON:
1021
 
                                                makernote_canon(rawfile, ifd.value_offset, meta);
1022
 
                                                break;
1023
 
                                        case MAKE_MINOLTA:
1024
 
                                                makernote_minolta(rawfile, ifd.value_offset, meta);
1025
 
                                                break;
1026
 
                                        case MAKE_NIKON:
1027
 
                                                makernote_nikon(rawfile, ifd.value_offset, meta);
1028
 
                                                break;
1029
 
                                        case MAKE_PENTAX:
1030
 
                                                makernote_pentax(rawfile, ifd.value_offset, meta);
1031
 
                                                break;
1032
 
                                        case MAKE_OLYMPUS:
1033
 
                                                if (raw_strcmp(rawfile, ifd.value_offset, "OLYMPUS", 7))
1034
 
                                                        makernote_olympus(rawfile, ifd.value_offset, ifd.value_offset+12, meta);
1035
 
                                                else if (raw_strcmp(rawfile, ifd.value_offset, "OLYMP", 5))
1036
 
                                                        makernote_olympus(rawfile, ifd.value_offset+8, ifd.value_offset+8, meta);
1037
 
                                                break;
1038
 
                                        default:
1039
 
                                                break;
1040
 
                                }
1041
 
                                break;
1042
 
                }
1043
 
        }
1044
 
 
1045
 
        return TRUE;
1046
 
}
1047
 
 
1048
 
static gboolean
1049
 
ifd_reader(RAWFILE *rawfile, guint offset, RSMetadata *meta)
1050
 
{
1051
 
        gushort number_of_entries = 0;
1052
 
        gboolean is_preview = FALSE;
1053
 
        guint uint_temp1;
1054
 
 
1055
 
        struct IFD ifd;
1056
 
 
1057
 
        /* get number of entries */
1058
 
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
1059
 
                return FALSE;
1060
 
        offset += 2;
1061
 
 
1062
 
        while(number_of_entries--)
1063
 
        {
1064
 
                read_ifd(rawfile, offset, &ifd);
1065
 
                offset += 12;
1066
 
 
1067
 
                switch (ifd.tag)
1068
 
                {
1069
 
                        case 0x00fe: /* Subfile type */
1070
 
                                is_preview = (((gint)ifd.value) & 1) != 0;
1071
 
                                break;
1072
 
                        case 0x0100: /* Image width */
1073
 
                                if (is_preview)
1074
 
                                        meta->preview_width = ifd.value;
1075
 
                                break;
1076
 
                        case 0x0101: /* Image length (aka height in human language) */
1077
 
                                if (is_preview)
1078
 
                                        meta->preview_height = ifd.value;
1079
 
                                break;
1080
 
                        case 0x0102: /* Bits per sample */
1081
 
                                if (is_preview)
1082
 
                                {
1083
 
                                        raw_get_ushort (rawfile, ifd.value_offset + 0, &meta->preview_bits [0]);
1084
 
                                        raw_get_ushort (rawfile, ifd.value_offset + 2, &meta->preview_bits [1]);
1085
 
                                        raw_get_ushort (rawfile, ifd.value_offset + 4, &meta->preview_bits [2]);
1086
 
                                }
1087
 
                                break;
1088
 
                        case 0x0103: /* Compression */
1089
 
                                break;
1090
 
                        case 0x010f: /* Make */
1091
 
                                if (!meta->make_ascii)
1092
 
                                {
1093
 
                                        meta->make_ascii = raw_strdup(rawfile, ifd.value_offset, ifd.count);
1094
 
                                        if (raw_strcmp(rawfile, ifd.value_offset, "Canon", 5))
1095
 
                                                meta->make = MAKE_CANON;
1096
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "KODAK", 5))
1097
 
                                                meta->make = MAKE_KODAK;
1098
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "EASTMAN KODAK", 13))
1099
 
                                                meta->make = MAKE_KODAK;
1100
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Minolta", 7))
1101
 
                                                meta->make = MAKE_MINOLTA;
1102
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "KONICA MINOLTA", 14))
1103
 
                                                meta->make = MAKE_MINOLTA;
1104
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "NIKON", 5))
1105
 
                                                meta->make = MAKE_NIKON;
1106
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "OLYMPUS", 7))
1107
 
                                                meta->make = MAKE_OLYMPUS;
1108
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Panasonic", 9))
1109
 
                                                meta->make = MAKE_PANASONIC;
1110
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "PENTAX", 6))
1111
 
                                                meta->make = MAKE_PENTAX;
1112
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Phase One", 9))
1113
 
                                                meta->make = MAKE_PHASEONE;
1114
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "SAMSUNG", 7))
1115
 
                                                meta->make = MAKE_SAMSUNG;
1116
 
                                        /* Do not detect SONY, we don't want to call private_sony() unless
1117
 
                                           we're sure we have a hidden SonyMeta */
1118
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "FUJIFILM", 4))
1119
 
                                                meta->make = MAKE_FUJIFILM;
1120
 
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "SEIKO EPSON", 11))
1121
 
                                                meta->make = MAKE_EPSON;
1122
 
                                }
1123
 
                                break;
1124
 
                        case 0x0110: /* Model */
1125
 
                                if (!meta->model_ascii)
1126
 
                                        meta->model_ascii = raw_strdup(rawfile, ifd.value_offset, ifd.count);
1127
 
                                break;
1128
 
                        case 0x0111: /* StripOffsets */
1129
 
                                if (meta->preview_start==0 || is_preview)
1130
 
                                        meta->preview_start = ifd.value + raw_get_base(rawfile);
1131
 
                                break;
1132
 
                        case 0x0112: /* Orientation */
1133
 
                                if (ifd.count == 1)
1134
 
                                {
1135
 
                                        meta->orientation = ifd.value_ushort;
1136
 
                                        switch (meta->orientation)
1137
 
                                        {
1138
 
                                                case 6: meta->orientation = 90;
1139
 
                                                        break;
1140
 
                                                case 8: meta->orientation = 270;
1141
 
                                                        break;
1142
 
                                        }
1143
 
                                }
1144
 
                                break;
1145
 
                        case 0x0117: /* StripByteCounts */
1146
 
                                if (meta->preview_length==0 || is_preview)
1147
 
                                        meta->preview_length = ifd.value;
1148
 
                                break;
1149
 
                        case 0x011c: /* Planar configuration */
1150
 
                                if (is_preview)
1151
 
                                        meta->preview_planar_config = ifd.value;
1152
 
                                break;
1153
 
                        case 0x0132: /* DateTime */
1154
 
                                break;
1155
 
                        case 0x014a: /* SubIFD */
1156
 
                                if (ifd.count == 1)
1157
 
                                        ifd_reader(rawfile, ifd.value_offset, meta);
1158
 
                                else
1159
 
                                {
1160
 
                                        raw_get_uint(rawfile, ifd.value_offset, &uint_temp1);
1161
 
                                        ifd_reader(rawfile, uint_temp1, meta);
1162
 
                                }
1163
 
                                break;
1164
 
                        case 0x0201: /* JPEGInterchangeFormat */
1165
 
                                meta->thumbnail_start = ifd.value_uint + raw_get_base(rawfile);
1166
 
                                break;
1167
 
                        case 0x0202: /* JPEGInterchangeFormatLength */
1168
 
                                meta->thumbnail_length = ifd.value_uint;
1169
 
                                break;
1170
 
                        case 0x8769: /* ExifIFDPointer */
1171
 
                                exif_reader(rawfile, ifd.value_offset, meta);
1172
 
                                break;
1173
 
 
1174
 
                        /* The following tags are from the DNG spec, they should be safe */
1175
 
                        case 0xc628: /* DNG: AsShotNeutral */
1176
 
                                if (((ifd.type == TIFF_FIELD_TYPE_RATIONAL)||(ifd.type == TIFF_FIELD_TYPE_SRATIONAL)) && ifd.count == 3)
1177
 
                                {
1178
 
                                        meta->cam_mul[0] = 1.0/get_rational(rawfile, ifd.value_offset);
1179
 
                                        meta->cam_mul[1] = 1.0/get_rational(rawfile, ifd.value_offset+8);
1180
 
                                        meta->cam_mul[2] = 1.0/get_rational(rawfile, ifd.value_offset+16);
1181
 
                                        meta->cam_mul[3] = meta->cam_mul[1];
1182
 
                                        rs_metadata_normalize_wb(meta);
1183
 
                                }
1184
 
                                break;
1185
 
                        case 0xc634: /* DNG: PrivateData */
1186
 
                                if (meta->make == MAKE_SONY)
1187
 
                                        private_sony(rawfile, ifd.value_offset, meta);
1188
 
                                break;
1189
 
                }
1190
 
        }
1191
 
 
1192
 
        return TRUE;
1193
 
}
1194
 
 
1195
 
void
1196
 
rs_tiff_load_meta_from_rawfile(RAWFILE *rawfile, guint offset, RSMetadata *meta)
1197
 
{
1198
 
        guint next = 0;
1199
 
        gushort ifd_num = 0;
1200
 
        guchar version;
1201
 
 
1202
 
        version = raw_init_file_tiff(rawfile, offset);
1203
 
 
1204
 
        if (version == 0x55)
1205
 
                meta->make = MAKE_LEICA;
1206
 
 
1207
 
        offset = get_first_ifd_offset(rawfile);
1208
 
        do {
1209
 
                if (!raw_get_ushort(rawfile, offset, &ifd_num)) break; /* used for calculating next IFD */
1210
 
                if (!raw_get_uint(rawfile, offset+2+ifd_num*12, &next)) break; /* 2: offset+short(ifd_num), 12: length of ifd-entry */
1211
 
 
1212
 
                switch (meta->make)
1213
 
                {
1214
 
                        case MAKE_LEICA:
1215
 
                                if (!makernote_leica(rawfile, offset, meta))
1216
 
                                        ifd_reader(rawfile, offset, meta);
1217
 
                                break;
1218
 
                        default:
1219
 
                                ifd_reader(rawfile, offset, meta);
1220
 
                                break;
1221
 
                }
1222
 
 
1223
 
                /* Hack to support a few cameras that embeds EXIF-info or Makernotes in IFD 0 */
1224
 
                if (meta->make == MAKE_CANON && g_str_equal(meta->model_ascii, "EOS D2000C"))
1225
 
                        exif_reader(rawfile, offset, meta);
1226
 
                if (meta->make == MAKE_KODAK && g_str_equal(meta->model_ascii, "DCS520C"))
1227
 
                        exif_reader(rawfile, offset, meta);
1228
 
                if (meta->make == MAKE_KODAK && g_str_equal(meta->model_ascii, "DCS Pro 14N"))
1229
 
                        exif_reader(rawfile, offset, meta);
1230
 
                if (meta->make == MAKE_PANASONIC)
1231
 
                        makernote_panasonic(rawfile, offset, meta);
1232
 
 
1233
 
                if (offset == next) break; /* avoid infinite loops */
1234
 
                offset = next;
1235
 
        } while (next>0);
1236
 
 
1237
 
        rs_metadata_normalize_wb(meta);
1238
 
        adobe_coeff_set(&meta->adobe_coeff, meta->make_ascii, meta->model_ascii);
1239
 
}
1240
 
 
1241
 
void
1242
 
rs_tiff_load_meta(const gchar *filename, RSMetadata *meta)
1243
 
{
1244
 
        RAWFILE *rawfile;
1245
 
 
1246
 
        raw_init();
1247
 
 
1248
 
        if(!(rawfile = raw_open_file(filename)))
1249
 
                return;
1250
 
 
1251
 
        rs_tiff_load_meta_from_rawfile(rawfile, 0, meta);
1252
 
 
1253
 
        /* Phase One and Samsung doesn't set this */
1254
 
        if ((meta->make == MAKE_PHASEONE) || (meta->make == MAKE_SAMSUNG))
1255
 
                meta->preview_planar_config = 1;
1256
 
 
1257
 
        /* Load thumbnail - try thumbnail first - then preview image */
1258
 
        if (!thumbnail_reader(filename, rawfile, meta->thumbnail_start, meta->thumbnail_length, meta))
1259
 
                thumbnail_reader(filename, rawfile, meta->preview_start, meta->preview_length, meta);
1260
 
 
1261
 
        raw_close_file(rawfile);
1262
 
}
1263
 
 
1264
 
static gboolean
1265
 
thumbnail_reader(const gchar *service, RAWFILE *rawfile, guint offset, guint length, RSMetadata *meta)
1266
 
{
1267
 
        gboolean ret = FALSE;
1268
 
        GdkPixbuf *pixbuf=NULL, *pixbuf2=NULL;
1269
 
 
1270
 
        if ((offset>0) && (length>0) && (length<5000000))
1271
 
        {
1272
 
                if ((length==165888) && (meta->make == MAKE_CANON))
1273
 
                        pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8, 288, 192, 288*3, NULL, NULL);
1274
 
                else if (length==57600) /* Multiple Nikon, Pentax and Samsung cameras */
1275
 
                        pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8, 160, 120, 160*3, NULL, NULL);
1276
 
                else if (length==48672)
1277
 
                        pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8, 156, 104, 156*3, NULL, NULL);
1278
 
                else
1279
 
                        /* Many RAW files are based on TIFF and include the preview image
1280
 
                         * as the "main" image in the TIFF so that "normal" image viewing
1281
 
                         * programs can display at least the thumbnail. So we will
1282
 
                         * check if the TIFF contains such a thumbnail in the simplest
1283
 
                         * possible format (e.g. uncompressed R8G8B8) and use it
1284
 
                         * if it is present.
1285
 
                         */
1286
 
                        if (offset == meta->preview_start && /* if we're using the preview image */
1287
 
                                meta->preview_planar_config == 1 && /* uncompressed */
1288
 
                                meta->preview_bits [0] == 8 &&
1289
 
                                meta->preview_bits [1] == 8 &&
1290
 
                                meta->preview_bits [2] == 8 && /* R8G8B8 */
1291
 
                                meta->preview_width * meta->preview_height * 3 == length &&
1292
 
                                meta->preview_width > 16 &&
1293
 
                                meta->preview_width < 1024 &&
1294
 
                                meta->preview_height > 16 &&
1295
 
                                meta->preview_height < 1024)    /* Some arbitrary sane limit */
1296
 
                                pixbuf = gdk_pixbuf_new_from_data(
1297
 
                                        raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8,
1298
 
                                        meta->preview_width, meta->preview_height,
1299
 
                                        meta->preview_width * 3, NULL, NULL);
1300
 
                        else
1301
 
                                /* Try to guess file format based on contents (JPEG previews) */
1302
 
                        pixbuf = raw_get_pixbuf(rawfile, offset, length);
1303
 
        }
1304
 
        /* Special case for Panasonic - most have no embedded thumbnail */
1305
 
        else if (meta->make == MAKE_PANASONIC)
1306
 
        {
1307
 
                RS_IMAGE16 *input;
1308
 
                if ((input = rs_filetype_load(service, TRUE)))
1309
 
                {
1310
 
                        gint c;
1311
 
                        gfloat pre_mul[4];
1312
 
                        RS_IMAGE16 *image;
1313
 
                        RSColorTransform *rct = rs_color_transform_new();
1314
 
                        image = rs_image16_transform(input, NULL,
1315
 
                                NULL, NULL, NULL, 128, 128, TRUE, -1.0,
1316
 
                                0.0, 0, NULL);
1317
 
                        pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, image->w, image->h);
1318
 
 
1319
 
                        for(c=0;c<4;c++)
1320
 
                                pre_mul[c] = (gfloat) meta->cam_mul[c];
1321
 
 
1322
 
                        rs_color_transform_set_premul(rct, pre_mul);
1323
 
                        rs_color_transform_transform(rct, image->w, image->h, image->pixels,
1324
 
                                        image->rowstride, gdk_pixbuf_get_pixels(pixbuf),
1325
 
                                        gdk_pixbuf_get_rowstride(pixbuf));
1326
 
 
1327
 
                        g_object_unref(input);
1328
 
                        g_object_unref(image);
1329
 
                        g_object_unref(rct);
1330
 
                }
1331
 
        }
1332
 
 
1333
 
        if (pixbuf)
1334
 
        {
1335
 
                gdouble ratio;
1336
 
 
1337
 
                /* Handle Canon/Nikon cropping */
1338
 
                if ((gdk_pixbuf_get_width(pixbuf) == 160) && (gdk_pixbuf_get_height(pixbuf)==120))
1339
 
                {
1340
 
                        pixbuf2 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 160, 106);
1341
 
                        gdk_pixbuf_copy_area(pixbuf, 0, 7, 160, 106, pixbuf2, 0, 0);
1342
 
                        g_object_unref(pixbuf);
1343
 
                        pixbuf = pixbuf2;
1344
 
                }
1345
 
 
1346
 
                /* Scale to a bounding box of 128x128 pixels */
1347
 
                ratio = ((gdouble) gdk_pixbuf_get_width(pixbuf))/((gdouble) gdk_pixbuf_get_height(pixbuf));
1348
 
                if (ratio>1.0)
1349
 
                        pixbuf2 = gdk_pixbuf_scale_simple(pixbuf, 128, (gint) (128.0/ratio), GDK_INTERP_BILINEAR);
1350
 
                else
1351
 
                        pixbuf2 = gdk_pixbuf_scale_simple(pixbuf, (gint) (128.0*ratio), 128, GDK_INTERP_BILINEAR);
1352
 
                g_object_unref(pixbuf);
1353
 
                pixbuf = pixbuf2;
1354
 
 
1355
 
                /* Rotate thumbnail in place */
1356
 
                switch (meta->orientation)
1357
 
                {
1358
 
                        /* this is very COUNTER-intuitive - gdk_pixbuf_rotate_simple() is wierd */
1359
 
                        case 90:
1360
 
                                pixbuf2 = gdk_pixbuf_rotate_simple(pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
1361
 
                                g_object_unref(pixbuf);
1362
 
                                pixbuf = pixbuf2;
1363
 
                                break;
1364
 
                        case 270:
1365
 
                                pixbuf2 = gdk_pixbuf_rotate_simple(pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
1366
 
                                g_object_unref(pixbuf);
1367
 
                                pixbuf = pixbuf2;
1368
 
                                break;
1369
 
                }
1370
 
                meta->thumbnail = pixbuf;
1371
 
                ret = TRUE;
1372
 
        }
1373
 
 
1374
 
        return ret;
1375
 
}
1376
 
 
1377
 
void
1378
 
rs_sony_load_meta(const gchar *filename, RSMetadata *meta)
1379
 
{
1380
 
        SonyMeta sony;
1381
 
        sony.sony_offset = 0;
1382
 
        sony.sony_length = 0;
1383
 
        sony.sony_key = 0;
1384
 
        meta->make = MAKE_SONY;
1385
 
 
1386
 
        memcpy(&sony, meta, sizeof(RSMetadata));
1387
 
        rs_tiff_load_meta(filename, RS_METADATA(&sony));
1388
 
        memcpy(meta, &sony, sizeof(RSMetadata));
1389
 
}