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

« back to all changes in this revision

Viewing changes to plugins/meta-tiff/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-2011 Anders Brander <anders@brander.dk>,
 
3
 * * Anders Kvist <akv@lnxbx.dk> and Klaus Post <klauspost@gmail.com>
 
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 <rawstudio.h>
 
21
#include <gtk/gtk.h>
 
22
#include <math.h>
 
23
#ifdef WIN32
 
24
#include <Winsock2.h> /* ntohl() */
 
25
#else
 
26
#include <arpa/inet.h> /* sony_decrypt(): htonl() */
 
27
#endif
 
28
#include <string.h> /* memcpy() */
 
29
#include <stdlib.h>
 
30
#include "rs-utils.h"
 
31
 
 
32
/* It is required having some arbitrary maximum exposure time to prevent borked
 
33
 * shutter speed values being interpreted from the tiff.
 
34
 * 8h seems to be reasonable, even for astronomists with extra battery packs */
 
35
#define EXPO_TIME_MAXVAL (8*60.0*60.0)
 
36
 
 
37
typedef struct {
 
38
        RSMetadata meta;
 
39
        gint sony_offset;
 
40
        gint sony_length;
 
41
        gint sony_key;
 
42
        guint pad[128];
 
43
        guint p;
 
44
} SonyMeta;
 
45
 
 
46
struct IFD {
 
47
        gushort tag;
 
48
        gushort type;
 
49
        guint count;
 
50
        guint value_offset;
 
51
        guchar value_uchar;
 
52
        gushort value_ushort;
 
53
        guint value_uint;
 
54
        gdouble value_rational;
 
55
        guint offset;
 
56
        gdouble value;
 
57
};
 
58
 
 
59
static gfloat get_rational(RAWFILE *rawfile, guint offset);
 
60
inline static void read_ifd(RAWFILE *rawfile, guint offset, struct IFD *ifd);
 
61
static gboolean makernote_canon(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
62
static gboolean makernote_leica(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
63
static gboolean makernote_minolta(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
64
static gboolean makernote_nikon(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
65
static gboolean makernote_olympus(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta);
 
66
static gboolean makernote_olympus_camerasettings(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta);
 
67
static gboolean makernote_olympus_imageprocessing(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta);
 
68
static gboolean makernote_olympus_equipment(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta);
 
69
static gboolean ifd_panasonic(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
70
static gboolean makernote_pentax(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
71
static gboolean makernote_samsung(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
72
static gboolean makernote_sony(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
73
static void sony_decrypt(SonyMeta *sony, guint *data, gint len);
 
74
static gboolean private_sony(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
75
static gboolean exif_reader(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
76
static gboolean ifd_reader(RAWFILE *rawfile, guint offset, RSMetadata *meta);
 
77
static gboolean thumbnail_reader(const gchar *service, RAWFILE *rawfile, guint offset, guint length, RSMetadata *meta);
 
78
static gboolean thumbnail_store(GdkPixbuf *pixbuf, RSMetadata *meta);
 
79
static GdkPixbuf* raw_thumbnail_reader(const gchar *service, RSMetadata *meta);
 
80
 
 
81
typedef enum tiff_field_type
 
82
{
 
83
        TIFF_FIELD_TYPE_UNDEF__ = 0,
 
84
        TIFF_FIELD_TYPE_BYTE = 1,
 
85
        TIFF_FIELD_TYPE_ASCII = 2,
 
86
        TIFF_FIELD_TYPE_SHORT = 3,
 
87
        TIFF_FIELD_TYPE_LONG = 4,
 
88
        TIFF_FIELD_TYPE_RATIONAL = 5,
 
89
 
 
90
        /* Added in TIFF 6.0 */
 
91
        TIFF_FIELD_TYPE_SBYTE = 6,
 
92
        TIFF_FIELD_TYPE_UNDEFINED = 7,
 
93
        TIFF_FIELD_TYPE_SSHORT = 8,
 
94
        TIFF_FIELD_TYPE_SLONG = 9,
 
95
        TIFF_FIELD_TYPE_SRATIONAL = 10,
 
96
        TIFF_FIELD_TYPE_FLOAT = 11,
 
97
        TIFF_FIELD_TYPE_DOUBLE = 12,
 
98
 
 
99
        /* Just for convenience */
 
100
        TIFF_FIELD_TYPE_MAX = 12,
 
101
} TIFF_FIELD_TYPE;
 
102
 
 
103
guint tiff_field_size[TIFF_FIELD_TYPE_MAX+1] = {1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
 
104
 
 
105
/**
 
106
 * Get a TIFF_FIELD_TYPE_RATIONAL value from a TIFF file
 
107
 */
 
108
static gfloat
 
109
get_rational(RAWFILE *rawfile, guint offset)
 
110
{
 
111
        guint uint1=0, uint2=1;
 
112
        if (!raw_get_uint(rawfile, offset, &uint1))
 
113
                return 0;
 
114
        if (!raw_get_uint(rawfile, offset+4, &uint2))
 
115
                return 0;
 
116
 
 
117
        if (uint2 == 0)
 
118
                return 0;
 
119
        return ((gdouble) uint1) / ((gdouble) uint2);
 
120
}
 
121
 
 
122
inline static void
 
123
read_ifd(RAWFILE *rawfile, guint offset, struct IFD *ifd)
 
124
{
 
125
/*      guint size = 0; */
 
126
 
 
127
        raw_get_ushort(rawfile, offset, &ifd->tag);
 
128
        raw_get_ushort(rawfile, offset+2, &ifd->type);
 
129
        raw_get_uint(rawfile, offset+4, &ifd->count);
 
130
        raw_get_uint(rawfile, offset+8, &ifd->value_offset);
 
131
 
 
132
        ifd->value = 0;
 
133
 
 
134
        if (ifd->type > 0 && ifd->type <= TIFF_FIELD_TYPE_MAX)
 
135
        {
 
136
                if ((ifd->count * tiff_field_size[ifd->type]) < 5)
 
137
                        ifd->offset = offset+8;
 
138
                else
 
139
                        ifd->offset = ifd->value_offset;
 
140
        }
 
141
 
 
142
        if (ifd->count == 1)
 
143
                switch (ifd->type)
 
144
                {
 
145
                        case TIFF_FIELD_TYPE_BYTE:
 
146
                                raw_get_uchar(rawfile, offset+8, &ifd->value_uchar);
 
147
                                ifd->value = ifd->value_uchar;
 
148
                                break;
 
149
                        case TIFF_FIELD_TYPE_SHORT:
 
150
                                raw_get_ushort(rawfile, offset+8, &ifd->value_ushort);
 
151
                                ifd->value = ifd->value_ushort;
 
152
                                break;
 
153
                        case TIFF_FIELD_TYPE_LONG:
 
154
                                raw_get_uint(rawfile, offset+8, &ifd->value_uint);
 
155
                                ifd->value = ifd->value_uint;
 
156
                                break;
 
157
                        case TIFF_FIELD_TYPE_RATIONAL:
 
158
                                ifd->value_rational = get_rational(rawfile,  ifd->value_offset);
 
159
                                ifd->value = ifd->value_rational;
 
160
                                break;
 
161
                        default:
 
162
                                /* FIXME: Implement types from TIFF 6.0 */
 
163
                                break;
 
164
                }
 
165
}
 
166
 
 
167
#if 0
 
168
static void
 
169
print_ifd(RAWFILE *rawfile, struct IFD *ifd)
 
170
{
 
171
        gchar *tmp;
 
172
        printf("tag: %04x ", ifd->tag);
 
173
        printf("%8u ", ifd->type);
 
174
        printf("%8u * ", ifd->count);
 
175
        switch (ifd->type)
 
176
        {
 
177
                case TIFF_FIELD_TYPE_ASCII:
 
178
                        tmp = raw_strdup (rawfile, ifd->value_offset, ifd->count);
 
179
                        printf("[%-30s] ", tmp);
 
180
                        g_free(tmp);
 
181
                        break;
 
182
                case TIFF_FIELD_TYPE_SHORT:
 
183
                        printf("[%8u] ", ifd->value_ushort);
 
184
                        break;
 
185
                case TIFF_FIELD_TYPE_LONG:
 
186
                        printf("[%8u] ", ifd->value_offset);
 
187
                        break;
 
188
                case TIFF_FIELD_TYPE_RATIONAL:
 
189
                        printf("[%.03f] ", ifd->value_rational);
 
190
                        break;
 
191
                default:
 
192
                        printf("[0x%08x] ", ifd->value_offset);
 
193
                        break;
 
194
        }
 
195
        printf("@ %d ", ifd->offset);
 
196
        printf("{ %.05f }", ifd->value);
 
197
        printf("\n");
 
198
}
 
199
#endif
 
200
 
 
201
static gboolean
 
202
makernote_canon(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
203
{
 
204
        gushort number_of_entries = 0;
 
205
        gushort ushort_temp1;
 
206
        guint uint_temp1;
 
207
        gushort wb_index = 0;
 
208
        gchar* lens_name;
 
209
 
 
210
        struct IFD ifd;
 
211
 
 
212
        /* get number of entries */
 
213
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
214
                return FALSE;
 
215
        offset += 2;
 
216
 
 
217
        while(number_of_entries--)
 
218
        {
 
219
                read_ifd(rawfile, offset, &ifd);
 
220
                offset += 12;
 
221
 
 
222
                switch (ifd.tag)
 
223
                {
 
224
 
 
225
                case 0x0001: /* CanonCameraSettings */
 
226
                        if (meta->make == MAKE_CANON)
 
227
                        {
 
228
                                gshort temp, focalunits;
 
229
 
 
230
                                /* Lens ID */
 
231
                                raw_get_short(rawfile, ifd.value_offset+44, &temp);
 
232
                                meta->lens_id = temp;
 
233
 
 
234
                                /* Focalunits */
 
235
                                raw_get_short(rawfile, ifd.value_offset+50, &focalunits);
 
236
 
 
237
                                /* Max Focal */
 
238
                                raw_get_short(rawfile, ifd.value_offset+46, &temp);
 
239
                                meta->lens_max_focal = (gfloat) temp * (gfloat) focalunits;
 
240
 
 
241
                                /* Min Focal */
 
242
                                raw_get_short(rawfile, ifd.value_offset+48, &temp);
 
243
                                meta->lens_min_focal = (gfloat) temp * (gfloat) focalunits;
 
244
 
 
245
                                /* Max Aperture */
 
246
                                raw_get_short(rawfile, ifd.value_offset+52, &temp);
 
247
                                meta->lens_max_aperture = (gfloat) exp(CanonEv(temp)*log(2)/2);
 
248
 
 
249
                                /* Min Aperture */
 
250
                                raw_get_short(rawfile, ifd.value_offset+54, &temp);
 
251
                                meta->lens_min_aperture = (gfloat) exp(CanonEv(temp)*log(2)/2);
 
252
                        }
 
253
                        break;
 
254
                case 0x0004: /* CanonShotInfo */
 
255
                        raw_get_ushort(rawfile, ifd.value_offset+14, &wb_index);
 
256
                        break;
 
257
                case 0x0029: /* White Balance for G9 */
 
258
                        if (g_str_equal(meta->model_ascii, "Canon PowerShot G9"))
 
259
                        {
 
260
                                gint wb_offset = (wb_index < 18) ? "012347800000005896"[wb_index]-'0' : 0;
 
261
                                wb_offset = ifd.value_offset + wb_offset*32 + 8;
 
262
 
 
263
                                raw_get_uint(rawfile, wb_offset, &uint_temp1);
 
264
                                meta->cam_mul[1] = (gdouble) uint_temp1;
 
265
                                raw_get_uint(rawfile, wb_offset+4, &uint_temp1);
 
266
                                meta->cam_mul[0] = (gdouble) uint_temp1;
 
267
                                raw_get_uint(rawfile, wb_offset+8, &uint_temp1);
 
268
                                meta->cam_mul[2] = (gdouble) uint_temp1;
 
269
                                raw_get_uint(rawfile, wb_offset+12, &uint_temp1);
 
270
                                meta->cam_mul[3] = (gdouble) uint_temp1;
 
271
                                rs_metadata_normalize_wb(meta);
 
272
                        }
 
273
                        break;
 
274
                case 0x0095: /* Lens Name */
 
275
                         lens_name = raw_strdup(rawfile, ifd.value_offset, ifd.count);
 
276
                        /* We only add Canon lenses, since others are simply registered as "30mm", etc. */
 
277
                        if (lens_name[0] == 'E' && lens_name[1] == 'F')
 
278
                                meta->fixed_lens_identifier = g_strconcat("Canon ", lens_name, NULL);
 
279
                        g_free(lens_name);
 
280
                        break;
 
281
                case 0x00a4: /* WhiteBalanceTable */
 
282
                        raw_get_ushort(rawfile, ifd.value_offset+wb_index*48+0, &ushort_temp1);
 
283
                        meta->cam_mul[0] = (gdouble) ushort_temp1;
 
284
                        raw_get_ushort(rawfile, ifd.value_offset+wb_index*48+2, &ushort_temp1);
 
285
                        meta->cam_mul[1] = (gdouble) ushort_temp1;
 
286
                        raw_get_ushort(rawfile, ifd.value_offset+wb_index*48+4, &ushort_temp1);
 
287
                        meta->cam_mul[2] = (gdouble) ushort_temp1;
 
288
                        meta->cam_mul[3] = meta->cam_mul[1];
 
289
                        rs_metadata_normalize_wb(meta);
 
290
                        break;
 
291
                case 0x4001: /* white balance for mulpiple Canon cameras */
 
292
                        switch (ifd.count)
 
293
                        {
 
294
                                case 582: /* Canon 20D, 350D */
 
295
                                        ifd.value_offset += 50;
 
296
                                        break;
 
297
                                case 653: /* Canon EOS 1D Mk II, Canon 1Ds Mk2 */
 
298
                                        ifd.value_offset += 68;
 
299
                                        break;
 
300
                                case 674: /* Canon EOS 1D Mk III */
 
301
                                case 692: /* Canon EOS 40D */
 
302
                                case 702: /* Canon EOS 1Ds Mk III */
 
303
                                case 796: /* Canon EOS 5D, Canon EOS 30D, Canon EOS 400D */
 
304
                                case 1227: /* Canon EOS 450D */
 
305
                                case 1250: /* Canon EOS 5D Mk II */
 
306
                                case 1273: /* Canon EOS 600D */
 
307
                                case 1337: /* Canon 1D Mk IV */
 
308
                                case 1251: /* Canon EOS 500D - is this really correct? */
 
309
                                case 1338: /* Canon EOS 550D */
 
310
                                case 1346: /* Canon EOS 60D */
 
311
                                        ifd.value_offset += 126;
 
312
                                        break;
 
313
                                case 5120: /* Canon PowerShot G10 */
 
314
                                        ifd.value_offset += 142;
 
315
                                        break;
 
316
                        }
 
317
                        /* RGGB-format! */
 
318
                        raw_get_ushort(rawfile, ifd.value_offset, &ushort_temp1);
 
319
                        meta->cam_mul[0] = (gdouble) ushort_temp1;
 
320
                        raw_get_ushort(rawfile, ifd.value_offset+2, &ushort_temp1);
 
321
                        meta->cam_mul[1] = (gdouble) ushort_temp1;
 
322
                        raw_get_ushort(rawfile, ifd.value_offset+4, &ushort_temp1);
 
323
                        meta->cam_mul[3] = (gdouble) ushort_temp1;
 
324
                        raw_get_ushort(rawfile, ifd.value_offset+6, &ushort_temp1);
 
325
                        meta->cam_mul[2] = (gdouble) ushort_temp1;
 
326
                        rs_metadata_normalize_wb(meta);
 
327
                        break;
 
328
                }
 
329
        }
 
330
 
 
331
        return TRUE;
 
332
}
 
333
 
 
334
static gboolean
 
335
makernote_leica(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
336
{
 
337
        gboolean ret = FALSE;
 
338
        gushort number_of_entries = 0;
 
339
        guint version = 0;
 
340
 
 
341
        struct IFD ifd;
 
342
 
 
343
        /* get number of entries */
 
344
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
345
                return FALSE;
 
346
        offset += 2;
 
347
 
 
348
        while(number_of_entries--)
 
349
        {
 
350
                read_ifd(rawfile, offset, &ifd);
 
351
                offset += 12;
 
352
 
 
353
                switch (version)
 
354
                {
 
355
                        case 100:
 
356
                                switch(ifd.tag)
 
357
                                {
 
358
                                        case 0x0011: /* Red balance */
 
359
                                                meta->cam_mul[1] = 1.0;
 
360
                                                meta->cam_mul[3] = 1.0;
 
361
                                                meta->cam_mul[0] = ifd.value / 256.0;
 
362
                                                break;
 
363
                                        case 0x0012: /* Blue balance */
 
364
                                                meta->cam_mul[2] = ifd.value / 256.0;
 
365
                                                break;
 
366
                                        case 0x8769: /* ExifIFDPointer */
 
367
                                                exif_reader(rawfile, ifd.value_offset, meta);
 
368
                                                break;
 
369
                                }
 
370
                                break;
 
371
                        case 200:
 
372
                                switch(ifd.tag)
 
373
                                {
 
374
                                        case 0x0024: /* WB Red Level */
 
375
                                                meta->cam_mul[0] = ifd.value;
 
376
                                                break;
 
377
                                        case 0x0025: /* WB Green Level */
 
378
                                                meta->cam_mul[1] = ifd.value;
 
379
                                                meta->cam_mul[3] = ifd.value;
 
380
                                                break;
 
381
                                        case 0x0026: /* WB Blue Level */
 
382
                                                meta->cam_mul[2] = ifd.value;
 
383
                                                break;
 
384
                                        case 0x8769: /* ExifIFDPointer */
 
385
                                                exif_reader(rawfile, ifd.value_offset, meta);
 
386
                                                break;
 
387
                                }
 
388
                                break;
 
389
                        default:
 
390
                                switch(ifd.tag)
 
391
                                {
 
392
                                        case 0x0001: /* Raw version */
 
393
                                                switch (ifd.value_offset)
 
394
                                                {
 
395
                                                        case 0x30303130: /* Leica */
 
396
                                                                version = 100;
 
397
                                                                ret = TRUE;
 
398
                                                                break;
 
399
                                                        case 0x30303230: /* Leica / Panasonic */
 
400
                                                                version = 200;
 
401
                                                                ret = FALSE;
 
402
                                                                break;
 
403
                                                        case 0x30313230: /* Panasonic */
 
404
                                                                version = 210;
 
405
                                                                ret = FALSE;
 
406
                                                                break;
 
407
                                                        case 0x31303230: /* Panasonic */
 
408
                                                                version = 201;
 
409
                                                                ret = FALSE;
 
410
                                                                break;
 
411
                                                        case 0x32303230: /* Panasonic */
 
412
                                                                version = 202;
 
413
                                                                ret = FALSE;
 
414
                                                                break;
 
415
                                                        default:
 
416
                                                                ret = FALSE;
 
417
                                                                break;
 
418
                                                }
 
419
                                                break;
 
420
                                }
 
421
                                break;
 
422
                }
 
423
        }
 
424
        rs_metadata_normalize_wb(meta);
 
425
 
 
426
        return ret;
 
427
}
 
428
 
 
429
static gboolean
 
430
makernote_minolta(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
431
{
 
432
        gushort number_of_entries = 0;
 
433
 
 
434
        struct IFD ifd;
 
435
 
 
436
        /* get number of entries */
 
437
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
438
                return FALSE;
 
439
        offset += 2;
 
440
 
 
441
        while(number_of_entries--)
 
442
        {
 
443
                read_ifd(rawfile, offset, &ifd);
 
444
                offset += 12;
 
445
 
 
446
                switch (ifd.tag)
 
447
                {
 
448
                        case 0x0088: /* Minolta */
 
449
                                meta->preview_start = ifd.value_offset + raw_get_base(rawfile);
 
450
                                break;
 
451
                        case 0x0081: /* Minolta DiMAGE 5 */
 
452
                                meta->thumbnail_start = ifd.value_offset + raw_get_base(rawfile);
 
453
                                meta->thumbnail_length = ifd.count;
 
454
                                break;
 
455
                        case 0x0089: /* Minolta */
 
456
                                meta->preview_length = ifd.value_offset;
 
457
                                break;
 
458
                }
 
459
        }
 
460
 
 
461
        return TRUE;
 
462
}
 
463
 
 
464
static gboolean
 
465
makernote_nikon(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
466
{
 
467
        static const guchar xlat[2][256] = {
 
468
        { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
 
469
        0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
 
470
        0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
 
471
        0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
 
472
        0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
 
473
        0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
 
474
        0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
 
475
        0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
 
476
        0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
 
477
        0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
 
478
        0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
 
479
        0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
 
480
        0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
 
481
        0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
 
482
        0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
 
483
        0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
 
484
        { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
 
485
        0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
 
486
        0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
 
487
        0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
 
488
        0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
 
489
        0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
 
490
        0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
 
491
        0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
 
492
        0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
 
493
        0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
 
494
        0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
 
495
        0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
 
496
        0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
 
497
        0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
 
498
        0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
 
499
        0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
 
500
        gint i;
 
501
        guint tmp;
 
502
        gushort number_of_entries;
 
503
        gushort fieldtag=0;
 
504
        gushort fieldtype;
 
505
        gushort ushort_temp1=0;
 
506
        gfloat float_temp1=0.0, float_temp2=0.0;
 
507
        guint valuecount;
 
508
        guint uint_temp1=0;
 
509
        guchar char_tmp='\0';
 
510
        guint base;
 
511
        guint save;
 
512
        gint serial = 0;
 
513
        gint key = 0;
 
514
        guint ver97 = 0;
 
515
        guchar buf97[324], ci, cj, ck;
 
516
        guchar buf98[33] = "";
 
517
        gushort lensdata = 0;
 
518
        gboolean magic; /* Nikon's makernote type */
 
519
        gboolean got_wb = FALSE;
 
520
 
 
521
        if (raw_strcmp(rawfile, offset, "Nikon", 5))
 
522
        {
 
523
                base = offset +=10;
 
524
                raw_get_uint(rawfile, offset+4, &tmp);
 
525
                offset += tmp;
 
526
                magic = TRUE;
 
527
        }
 
528
        else
 
529
        {
 
530
                magic = FALSE;
 
531
                base = offset;
 
532
        }
 
533
 
 
534
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
535
                return FALSE;
 
536
        if (number_of_entries>5000)
 
537
                return FALSE;
 
538
        offset += 2;
 
539
 
 
540
        save = offset;
 
541
        while(number_of_entries--)
 
542
        {
 
543
                /* FIXME: Port to read_ifd() */
 
544
                offset = save;
 
545
                raw_get_ushort(rawfile, offset, &fieldtag);
 
546
                raw_get_ushort(rawfile, offset+2, &fieldtype);
 
547
                raw_get_uint(rawfile, offset+4, &valuecount);
 
548
                offset += 8;
 
549
 
 
550
                save = offset + 4;
 
551
                if ((valuecount * ("1112481124848"[fieldtype < 13 ? fieldtype:0]-'0') > 4) && magic)
 
552
                {
 
553
                        raw_get_uint(rawfile, offset, &uint_temp1);
 
554
                        offset = base + uint_temp1;
 
555
                }
 
556
                switch(fieldtag)
 
557
                {
 
558
                        case 0x0002: /* ISO */
 
559
                                raw_get_ushort(rawfile, offset+2, &meta->iso);
 
560
                                break;
 
561
                        case 0x000c: /* D1 White Balance */
 
562
                                if (g_str_equal(meta->model_ascii, "NIKON D1X")
 
563
                                    || g_str_equal(meta->model_ascii, "NIKON D90")
 
564
                                        || g_str_equal(meta->model_ascii, "NIKON D3S")
 
565
                                    || g_str_equal(meta->model_ascii, "NIKON D300S")
 
566
                                    || g_str_equal(meta->model_ascii, "NIKON D3000")
 
567
                                    || g_str_equal(meta->model_ascii, "NIKON D3100")
 
568
                                    || g_str_equal(meta->model_ascii, "NIKON D5000")
 
569
                                    || g_str_equal(meta->model_ascii, "NIKON D7000"))
 
570
                                {
 
571
                                        meta->cam_mul[0] = get_rational(rawfile, offset);
 
572
                                        meta->cam_mul[2] = get_rational(rawfile, offset+8);
 
573
                                        meta->cam_mul[1] = get_rational(rawfile, offset+16);
 
574
                                        meta->cam_mul[3] = get_rational(rawfile, offset+24);
 
575
                                        rs_metadata_normalize_wb(meta);
 
576
                                        got_wb = TRUE;
 
577
                                }
 
578
                                else
 
579
                                {
 
580
                                        /* This is fucked, where did these two magic constants come from? */
 
581
                                        raw_get_float(rawfile, uint_temp1, &float_temp1);
 
582
                                        raw_get_float(rawfile, uint_temp1+4, &float_temp2);
 
583
                                        meta->cam_mul[0] = (gdouble) (float_temp1/float_temp2)/1.0;//2.218750;
 
584
 
 
585
                                        raw_get_float(rawfile, uint_temp1+8, &float_temp1);
 
586
                                        raw_get_float(rawfile, uint_temp1+12, &float_temp2);
 
587
                                        meta->cam_mul[2] = (gdouble) (float_temp1/float_temp2)/1.0;//1.148438;
 
588
 
 
589
                                        raw_get_float(rawfile, uint_temp1+16, &float_temp1);
 
590
                                        raw_get_float(rawfile, uint_temp1+20, &float_temp2);
 
591
                                        meta->cam_mul[1] = (gdouble) (float_temp1/float_temp2);
 
592
 
 
593
                                        raw_get_float(rawfile, uint_temp1+24, &float_temp1);
 
594
                                        raw_get_float(rawfile, uint_temp1+28, &float_temp2);
 
595
                                        meta->cam_mul[3] = (gdouble) (float_temp1/float_temp2);
 
596
 
 
597
                                        rs_metadata_normalize_wb(meta);
 
598
                                }
 
599
                                break;
 
600
                        case 0x0011: /* NikonPreview */
 
601
                                raw_get_uint(rawfile, offset, &uint_temp1);
 
602
                                ifd_reader(rawfile, uint_temp1+base, meta);
 
603
                                meta->thumbnail_start += base;
 
604
                                break;
 
605
                        case 0x0084: /* Lens - rational64u[4] */
 
606
                                raw_get_rational(rawfile, offset, &float_temp1);
 
607
                                meta->lens_min_focal = float_temp1;
 
608
                                raw_get_rational(rawfile, offset+8, &float_temp1);
 
609
                                meta->lens_max_focal = float_temp1;
 
610
                                raw_get_rational(rawfile, offset+16, &float_temp1);
 
611
                                meta->lens_max_aperture = float_temp1;
 
612
                                raw_get_rational(rawfile, offset+24, &float_temp1);
 
613
                                meta->lens_min_aperture = float_temp1;
 
614
                                break;
 
615
                        case 0x0097: /* white balance */
 
616
                                if (g_str_equal(meta->model_ascii, "NIKON D90")
 
617
                                        || g_str_equal(meta->model_ascii, "NIKON D3S")
 
618
                                        || g_str_equal(meta->model_ascii, "NIKON D300S"))
 
619
                                        break;
 
620
 
 
621
                                for(i=0;i<4;i++)
 
622
                                {
 
623
                                        raw_get_uchar(rawfile, offset+i, &char_tmp);
 
624
                                        ver97 = (ver97 << 4) + char_tmp-'0';
 
625
                                }
 
626
                                offset += 4;
 
627
                                switch (ver97)
 
628
                                {
 
629
                                        case 0x100:
 
630
                                                /* RBGG-format */
 
631
                                                offset += 68;
 
632
                                                raw_get_ushort(rawfile, offset, &ushort_temp1);
 
633
                                                meta->cam_mul[0] = (gdouble) ushort_temp1;
 
634
                                                raw_get_ushort(rawfile, offset+2, &ushort_temp1);
 
635
                                                meta->cam_mul[2] = (gdouble) ushort_temp1;
 
636
                                                raw_get_ushort(rawfile, offset+4, &ushort_temp1);
 
637
                                                meta->cam_mul[1] = (gdouble) ushort_temp1;
 
638
                                                raw_get_ushort(rawfile, offset+6, &ushort_temp1);
 
639
                                                meta->cam_mul[3] = (gdouble) ushort_temp1;
 
640
                                                rs_metadata_normalize_wb(meta);
 
641
                                                break;
 
642
                                        case 0x102:
 
643
                                                /* RGGB-format */
 
644
                                                offset += 6;
 
645
                                                raw_get_ushort(rawfile, offset, &ushort_temp1);
 
646
                                                meta->cam_mul[0] = (gdouble) ushort_temp1;
 
647
                                                raw_get_ushort(rawfile, offset+2, &ushort_temp1);
 
648
                                                meta->cam_mul[1] = (gdouble) ushort_temp1;
 
649
                                                raw_get_ushort(rawfile, offset+4, &ushort_temp1);
 
650
                                                meta->cam_mul[3] = (gdouble) ushort_temp1;
 
651
                                                raw_get_ushort(rawfile, offset+6, &ushort_temp1);
 
652
                                                meta->cam_mul[2] = (gdouble) ushort_temp1;
 
653
                                                rs_metadata_normalize_wb(meta);
 
654
                                                break;
 
655
                                        case 0x103:
 
656
                                                offset += 16;
 
657
                                                for(i=0;i<4;i++)
 
658
                                                {
 
659
                                                        raw_get_ushort(rawfile, offset+2*i, &ushort_temp1);
 
660
                                                        meta->cam_mul[i] = ushort_temp1;
 
661
                                                }
 
662
                                                rs_metadata_normalize_wb(meta);
 
663
                                                break;
 
664
                                }
 
665
                                if (ver97 >> 8 == 2)
 
666
                                {
 
667
                                        if (ver97 != 0x205)
 
668
                                                offset += 280;
 
669
                                        raw_strcpy(rawfile, offset, buf97, 324);
 
670
                                }
 
671
                                break;
 
672
                        case 0x0098: /* LensData - LensData0100 | LensData0101 | LensData0201 | LensData0204 | LensDataUnknown */
 
673
                                /* Will be used in 0x00a7 */
 
674
                                raw_strcpy(rawfile, offset, &buf98, 33);
 
675
                                gchar *str = raw_strdup(rawfile, offset, 4);
 
676
                                lensdata = atoi(str);
 
677
                                g_free(str);
 
678
 
 
679
                                /* Unencrypted LensIDNumber */
 
680
                                if (lensdata == 100)
 
681
                                        meta->lens_id = buf98[0x06];
 
682
                                break;
 
683
                        case 0x001d: /* serial */
 
684
                                raw_get_uchar(rawfile, offset++, &char_tmp);
 
685
                                while(char_tmp)
 
686
                                {
 
687
                                        serial = serial*10 + (g_ascii_isdigit(char_tmp) ? char_tmp - '0' : char_tmp % 10);
 
688
                                        raw_get_uchar(rawfile, offset++, &char_tmp);
 
689
                                }
 
690
                                break;
 
691
                        case 0x00a7: /* white balance */
 
692
                        {
 
693
                                guchar ctmp[4];
 
694
                                raw_get_uchar(rawfile, offset++, ctmp);
 
695
                                raw_get_uchar(rawfile, offset++, ctmp+1);
 
696
                                raw_get_uchar(rawfile, offset++, ctmp+2);
 
697
                                raw_get_uchar(rawfile, offset, ctmp+3);
 
698
                                key = ctmp[0]^ctmp[1]^ctmp[2]^ctmp[3];
 
699
 
 
700
                                /* data from 0x0098 */
 
701
                                if (strlen((const gchar *) buf98))
 
702
                                {
 
703
                                        ci = xlat[0][serial & 0xff];
 
704
                                        cj = xlat[1][key];
 
705
                                        ck = 0x60;
 
706
 
 
707
                                        for (i=4; i < sizeof(buf98); i++)
 
708
                                                buf98[i] = buf98[i] ^ (cj += ci * ck++);
 
709
 
 
710
                                        /* Finding LensIDNumber - 101 untested */
 
711
                                        if (lensdata == 101 || lensdata == 201 || lensdata == 202 || lensdata == 203)
 
712
                                                meta->lens_id = buf98[0x0b];
 
713
                                        else if (lensdata == 204)
 
714
                                                meta->lens_id = buf98[0x0c];
 
715
                                }
 
716
 
 
717
                                if (got_wb)
 
718
                                        break;
 
719
 
 
720
                                if (ver97 >> 8 == 2)
 
721
                                {
 
722
                                        ci = xlat[0][serial & 0xff];
 
723
                                        cj = xlat[1][key];
 
724
                                        ck = 0x60;
 
725
                                        for (i=0; i < 324; i++)
 
726
                                                buf97[i] ^= (cj += ci * ck++);
 
727
 
 
728
                                        for (i=0; i<4; i++)
 
729
                                                meta->cam_mul[i ^ (i >> 1)] = raw_get_ushort_from_string(
 
730
                                                        rawfile, (gchar *)(buf97 + (ver97 == 0x205 ? 14:6) + i*2));
 
731
                                        if (ver97 == 0x209) /* D300 */
 
732
                                                for(i=0; i<4; i++)
 
733
                                                        meta->cam_mul[i ^ (i >> 1) ^ 1] = raw_get_ushort_from_string(rawfile, (gchar *)(buf97 + 10 + i*2));
 
734
                                        rs_metadata_normalize_wb(meta);
 
735
                                }
 
736
                                break;
 
737
                        }
 
738
                        case 0x00aa: /* Nikon Saturation */
 
739
                                if (meta->make == MAKE_NIKON)
 
740
                                {
 
741
                                        if (raw_strcmp(rawfile, offset, "ENHANCED", 8))
 
742
                                                meta->saturation = 1.5;
 
743
                                        else if (raw_strcmp(rawfile, offset, "MODERATE", 8))
 
744
                                                meta->saturation = 0.5;
 
745
                                        else
 
746
                                                meta->saturation = 1.0;
 
747
                                }
 
748
                                break;
 
749
                        case 0x0081: /* Nikon ToneComp (contrast)*/
 
750
                                if (meta->make == MAKE_NIKON)
 
751
                                {
 
752
                                        if (raw_strcmp(rawfile, offset, "HIGH", 4))
 
753
                                                meta->contrast = 1.2;
 
754
                                        else if (raw_strcmp(rawfile, offset, "LOW", 3))
 
755
                                                meta->contrast= 0.8;
 
756
                                        else
 
757
                                                meta->contrast = 1.0;
 
758
                                }
 
759
                                break;
 
760
 
 
761
                }
 
762
        }
 
763
        return TRUE;
 
764
}
 
765
 
 
766
static gboolean
 
767
makernote_olympus_camerasettings(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta)
 
768
{
 
769
        /* NOTE! At least on E-410 the offsets in this section is relative to
 
770
           the base of the MakerNotes! */
 
771
 
 
772
        gushort number_of_entries;
 
773
        gushort fieldtag=0;
 
774
        gushort fieldtype;
 
775
        guint valuecount;
 
776
        guint uint_temp1=0;
 
777
        guint save;
 
778
 
 
779
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
780
                return FALSE;
 
781
        if (number_of_entries>5000)
 
782
                return FALSE;
 
783
        offset += 2;
 
784
 
 
785
        save = offset;
 
786
        while(number_of_entries--)
 
787
        {
 
788
                /* FIXME: Port to read_ifd() */
 
789
                offset = save;
 
790
                raw_get_ushort(rawfile, offset, &fieldtag);
 
791
                raw_get_ushort(rawfile, offset+2, &fieldtype);
 
792
                raw_get_uint(rawfile, offset+4, &valuecount);
 
793
                offset += 8;
 
794
 
 
795
                save = offset + 4;
 
796
                if ((valuecount * ("1112481124848"[fieldtype < 13 ? fieldtype:0]-'0') > 4))
 
797
                {
 
798
                        raw_get_uint(rawfile, offset, &uint_temp1);
 
799
                        offset = base + uint_temp1;
 
800
                }
 
801
                raw_get_uint(rawfile, offset, &uint_temp1);
 
802
                switch(fieldtag)
 
803
                {
 
804
                        case 0x0101: /* PreviewImageStart */
 
805
                                raw_get_uint(rawfile, offset, &meta->preview_start);
 
806
                                meta->preview_start += raw_get_base(rawfile);
 
807
                                break;
 
808
                        case 0x0102: /* PreviewImageLength */
 
809
                                raw_get_uint(rawfile, offset, &meta->preview_length);
 
810
                                break;
 
811
                }
 
812
        }
 
813
        return TRUE;
 
814
}
 
815
 
 
816
static gboolean
 
817
makernote_olympus_imageprocessing(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta)
 
818
{
 
819
        gushort number_of_entries;
 
820
        struct IFD ifd;
 
821
        gushort ushort_temp1, ushort_temp2;
 
822
 
 
823
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
824
                return FALSE;
 
825
 
 
826
        if (number_of_entries>5000)
 
827
                return FALSE;
 
828
 
 
829
        offset += 2;
 
830
 
 
831
        while(number_of_entries--)
 
832
        {
 
833
                read_ifd(rawfile, offset, &ifd);
 
834
                offset += 12;
 
835
 
 
836
                switch(ifd.tag)
 
837
                {
 
838
                        case 0x0100: /* WB on E-510 */
 
839
                                if (ifd.count == 2)
 
840
                                {
 
841
                                        raw_get_ushort(rawfile, ifd.offset, &ushort_temp1);
 
842
                                        raw_get_ushort(rawfile, ifd.offset+2, &ushort_temp2);
 
843
                                }
 
844
                                else if (ifd.count == 4)
 
845
                                {
 
846
                                        raw_get_ushort(rawfile, ifd.offset+base, &ushort_temp1);
 
847
                                        raw_get_ushort(rawfile, ifd.offset+base+2, &ushort_temp2);
 
848
                                }
 
849
                                meta->cam_mul[0] = (gdouble) ushort_temp1 / 256.0;
 
850
                                meta->cam_mul[2] = (gdouble) ushort_temp2 / 256.0;
 
851
                                rs_metadata_normalize_wb(meta);
 
852
                                break;
 
853
                }
 
854
        }
 
855
        return TRUE;
 
856
}
 
857
 
 
858
static gboolean
 
859
makernote_olympus_equipment(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta)
 
860
{
 
861
        gushort number_of_entries;
 
862
        struct IFD ifd;
 
863
        gushort ushort_temp1;
 
864
        gchar *str = NULL;
 
865
        gint total;
 
866
 
 
867
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
868
                return FALSE;
 
869
 
 
870
        if (number_of_entries>5000)
 
871
                return FALSE;
 
872
 
 
873
        offset += 2;
 
874
 
 
875
        while(number_of_entries--)
 
876
        {
 
877
                read_ifd(rawfile, offset, &ifd);
 
878
                offset += 12;
 
879
 
 
880
                switch(ifd.tag)
 
881
                {
 
882
                        case 0x0202: /* LensSerialNumber */
 
883
                                str = raw_strdup(rawfile, base + ifd.value_offset, 32);
 
884
 
 
885
                                /* Make a number from the string we just got */
 
886
                                gint i = 0;
 
887
                                while(str[i])
 
888
                                        total += str[i++];
 
889
 
 
890
                                meta->lens_id = total;
 
891
                                break;
 
892
                        case 0x0205: /* MinApertureAtMinFocal */
 
893
                                raw_get_ushort(rawfile, offset-4, &ushort_temp1);
 
894
                                meta->lens_min_aperture = (gfloat) pow(sqrt(2),(ushort_temp1/256));
 
895
                                break;
 
896
                        case 0x0206: /* MaxApertureAtMaxFocal */
 
897
                                raw_get_ushort(rawfile, offset-4, &ushort_temp1);
 
898
                                meta->lens_max_aperture = (gfloat) pow(sqrt(2),(ushort_temp1/256));
 
899
                                break;
 
900
                        case 0x0207: /* MinFocalLength */
 
901
                                raw_get_ushort(rawfile, offset-4, &ushort_temp1);
 
902
                                meta->lens_min_focal = ushort_temp1;
 
903
                                break;
 
904
                        case 0x0208: /* MaxFocalLength */
 
905
                                raw_get_ushort(rawfile, offset-4, &ushort_temp1);
 
906
                                meta->lens_max_focal = ushort_temp1;
 
907
                                break;
 
908
                }
 
909
        }
 
910
        return TRUE;
 
911
}
 
912
 
 
913
 
 
914
static gboolean
 
915
makernote_olympus(RAWFILE *rawfile, guint base, guint offset, RSMetadata *meta)
 
916
{
 
917
        gushort number_of_entries;
 
918
        gushort fieldtag=0;
 
919
        gushort fieldtype;
 
920
        gushort ushort_temp1=0;
 
921
        guint valuecount;
 
922
        guint uint_temp1=0;
 
923
        guint save;
 
924
 
 
925
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
926
                return FALSE;
 
927
        if (number_of_entries>5000)
 
928
                return FALSE;
 
929
        offset += 2;
 
930
 
 
931
        save = offset;
 
932
        while(number_of_entries--)
 
933
        {
 
934
                /* FIXME: Port to read_ifd() */
 
935
                offset = save;
 
936
                raw_get_ushort(rawfile, offset, &fieldtag);
 
937
                raw_get_ushort(rawfile, offset+2, &fieldtype);
 
938
                raw_get_uint(rawfile, offset+4, &valuecount);
 
939
                offset += 8;
 
940
 
 
941
                save = offset + 4;
 
942
                if ((valuecount * ("1112481124848"[fieldtype < 13 ? fieldtype:0]-'0') > 4))
 
943
                {
 
944
                        raw_get_uint(rawfile, offset, &uint_temp1);
 
945
                        offset = base + uint_temp1;
 
946
                }
 
947
                raw_get_uint(rawfile, offset, &uint_temp1);
 
948
                switch(fieldtag)
 
949
                {
 
950
                        case 0x0100: /* Thumbnail */
 
951
                                raw_get_ushort(rawfile, save-4, &ushort_temp1);
 
952
                                meta->thumbnail_start = ushort_temp1;
 
953
                                meta->thumbnail_length = valuecount;
 
954
                                break;
 
955
                        case 0x1017: /* Red multiplier on many Olympus's (E-10, E-300, E-330, E-400, E-500) */
 
956
                                raw_get_ushort(rawfile, offset, &ushort_temp1);
 
957
                                meta->cam_mul[0] = (gdouble) ushort_temp1 / 256.0;
 
958
                                break;
 
959
                        case 0x1018: /* Blue multiplier on many Olympus's (E-10, E-300, E-330, E-400, E-500) */
 
960
                                raw_get_ushort(rawfile, offset, &ushort_temp1);
 
961
                                meta->cam_mul[2] = (gdouble) ushort_temp1 / 256.0;
 
962
                                break;
 
963
                        case 0x2010: /* Equipment2 */
 
964
                                raw_get_uint(rawfile, offset, &uint_temp1);
 
965
                                makernote_olympus_equipment(rawfile, base, base+uint_temp1, meta);
 
966
                                break;
 
967
                        case 0x2020: /* Olympus CameraSettings Tags */
 
968
                                raw_get_uint(rawfile, offset, &uint_temp1);
 
969
                                makernote_olympus_camerasettings(rawfile, base+uint_temp1, base+uint_temp1, meta);
 
970
                                meta->preview_start += base; /* Stupid hack! */
 
971
                                break;
 
972
                        case 0x2040: /* Olympus ImageProcessing  */
 
973
                                raw_get_uint(rawfile, offset, &uint_temp1);
 
974
                                makernote_olympus_imageprocessing(rawfile, base, base+uint_temp1, meta);
 
975
                                break;
 
976
                }
 
977
        }
 
978
        return TRUE;
 
979
}
 
980
 
 
981
static gboolean
 
982
makernote_panasonic(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
983
{
 
984
        gushort number_of_entries;
 
985
        struct IFD ifd;
 
986
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
987
        return FALSE;
 
988
 
 
989
        if (number_of_entries>5000)
 
990
                return FALSE;
 
991
 
 
992
        offset += 2;
 
993
 
 
994
        while(number_of_entries--)
 
995
        {
 
996
                read_ifd(rawfile, offset, &ifd);
 
997
                offset += 12;
 
998
                switch(ifd.tag)
 
999
                {
 
1000
                        case 81: /* Lens type */
 
1001
                                meta->fixed_lens_identifier = raw_strdup(rawfile, ifd.value_offset, ifd.count);
 
1002
                                break;
 
1003
                        case 82: /* Lens serial number */
 
1004
                                if (!meta->fixed_lens_identifier)
 
1005
                                        meta->fixed_lens_identifier = raw_strdup(rawfile, ifd.value_offset, ifd.count);
 
1006
                                break;
 
1007
                        case 0x8769: /* ExifIFDPointer */
 
1008
                                exif_reader(rawfile, ifd.value_offset, meta);
 
1009
                                break;
 
1010
                        case 0x0111: /* StripOffsets - may be jpeg data */
 
1011
                                if (ifd.count == 1 && raw_get_uint(rawfile, ifd.offset, &meta->thumbnail_start))
 
1012
                                        meta->thumbnail_start += raw_get_base(rawfile);
 
1013
                                else
 
1014
                                        meta->thumbnail_start = 0;
 
1015
                                break;
 
1016
                        case 0x0117: /* StripByteCounts */
 
1017
                                if (ifd.value_offset)
 
1018
                                        meta->thumbnail_length = ifd.value_offset;
 
1019
                                break;
 
1020
                }
 
1021
        }
 
1022
        return TRUE;
 
1023
}
 
1024
 
 
1025
static gboolean
 
1026
likely_jpeg_at(RAWFILE *rawfile, guint offset)
 
1027
{
 
1028
        guchar thumb_test_1 = 0;
 
1029
        guchar thumb_test_2 = 0;
 
1030
        guchar thumb_test_comps = 0;
 
1031
 
 
1032
        if (raw_get_uchar(rawfile, offset, &thumb_test_1))
 
1033
        {
 
1034
                /* If SOI marker, it is likely valid JPEG*/
 
1035
                if (thumb_test_1 == 0xff && raw_get_uchar(rawfile, offset+1, &thumb_test_2))
 
1036
                        if (thumb_test_2 == 0xd8)
 
1037
                                /* We read the "number of components", any value > 4 doesn't make sense */
 
1038
                                if (raw_get_uchar(rawfile, offset+6, &thumb_test_comps))
 
1039
                                        if (thumb_test_comps <= 4)
 
1040
                                                return TRUE;
 
1041
        }
 
1042
        return FALSE;
 
1043
}
 
1044
 
 
1045
 
 
1046
static gboolean
 
1047
ifd_panasonic(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1048
{
 
1049
        gushort number_of_entries;
 
1050
        struct IFD ifd;
 
1051
        RAWFILE *internal_file;
 
1052
        guint off_first;
 
1053
        gushort byteorder;
 
1054
 
 
1055
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
1056
                return FALSE;
 
1057
 
 
1058
        if (number_of_entries>5000)
 
1059
                return FALSE;
 
1060
 
 
1061
        offset += 2;
 
1062
 
 
1063
        while(number_of_entries--)
 
1064
        {
 
1065
                read_ifd(rawfile, offset, &ifd);
 
1066
                offset += 12;
 
1067
                switch(ifd.tag)
 
1068
                {
 
1069
                        case 0x0017: /* ISO */
 
1070
                                meta->iso = ifd.value_offset;
 
1071
                                break;
 
1072
                        case 0x0024: /* WBRedLevel */
 
1073
                                meta->cam_mul[0] = ifd.value_offset;
 
1074
                                break;
 
1075
                        case 0x0025: /* WBGreenLevel */
 
1076
                                meta->cam_mul[1] = ifd.value_offset;
 
1077
                                meta->cam_mul[3] = ifd.value_offset;
 
1078
                                break;
 
1079
                        case 0x0026: /* WBBlueLevel */
 
1080
                                meta->cam_mul[2] = ifd.value_offset;
 
1081
                                break;
 
1082
                        case 0x002e: /* Data Dump */
 
1083
                                if (ifd.type != 7 || ifd.count <= 16)
 
1084
                                        break;
 
1085
                                if (!raw_get_uint(rawfile, ifd.value_offset+12+4, &off_first))
 
1086
                                        break;
 
1087
                                if (!raw_get_ushort(rawfile,ifd.value_offset+12, &byteorder))
 
1088
                                        break;
 
1089
                                meta->thumbnail_length = ifd.count;
 
1090
                                internal_file = raw_create_from_memory(raw_get_map(rawfile)+ifd.value_offset+12, ifd.count, off_first, byteorder);
 
1091
                                ifd_reader(internal_file, off_first, meta);
 
1092
                                raw_close_file(internal_file);
 
1093
                                break;
 
1094
                }
 
1095
        }
 
1096
        if (meta->thumbnail_start > raw_get_filesize(rawfile))
 
1097
                meta->thumbnail_start = 0;
 
1098
        if (!likely_jpeg_at(rawfile, meta->thumbnail_start))
 
1099
                meta->thumbnail_start = 0;
 
1100
 
 
1101
        guint thumb_guess =0x1000;
 
1102
        /* Thumbnails in Panasonic are always at 0x100 byte boundaries, and never observed start after byte 0x3000, so we play safe */
 
1103
        while (meta->thumbnail_start == 0 && thumb_guess < 0x8000)
 
1104
        {
 
1105
                if (likely_jpeg_at(rawfile, thumb_guess))
 
1106
                        meta->thumbnail_start = thumb_guess;
 
1107
                thumb_guess += 0x100;
 
1108
        }
 
1109
        /* Find end of image */
 
1110
        if (meta->thumbnail_start)
 
1111
        {
 
1112
                thumb_guess = 0;
 
1113
                guchar* image = raw_get_map(rawfile) + meta->thumbnail_start;
 
1114
                do {
 
1115
                        if (image[thumb_guess] == 0xff && image[thumb_guess] == 0xd9)
 
1116
                                meta->thumbnail_length = thumb_guess+2;
 
1117
                } while (thumb_guess++ < raw_get_filesize(rawfile) - meta->thumbnail_start);
 
1118
        }
 
1119
        return TRUE;
 
1120
}
 
1121
 
 
1122
static gboolean
 
1123
makernote_pentax(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1124
{
 
1125
        gushort number_of_entries;
 
1126
        gushort ushort_temp1=0;
 
1127
        struct IFD ifd;
 
1128
 
 
1129
        if (raw_strcmp(rawfile, offset, "AOC", 3))
 
1130
                offset += 6;
 
1131
        else
 
1132
                return FALSE;
 
1133
 
 
1134
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
1135
                return FALSE;
 
1136
 
 
1137
        if (number_of_entries>5000)
 
1138
                return FALSE;
 
1139
 
 
1140
        offset += 2;
 
1141
 
 
1142
        while(number_of_entries--)
 
1143
        {
 
1144
                read_ifd(rawfile, offset, &ifd);
 
1145
                offset += 12;
 
1146
                switch(ifd.tag)
 
1147
                {
 
1148
                        case 0x0201: /* White balance */
 
1149
                                raw_get_ushort(rawfile, ifd.value_offset, &ushort_temp1);
 
1150
                                meta->cam_mul[0] = (gdouble) ushort_temp1;
 
1151
                                raw_get_ushort(rawfile, ifd.value_offset+2, &ushort_temp1);
 
1152
                                meta->cam_mul[1] = (gdouble) ushort_temp1;
 
1153
                                raw_get_ushort(rawfile, ifd.value_offset+4, &ushort_temp1);
 
1154
                                meta->cam_mul[3] = (gdouble) ushort_temp1;
 
1155
                                raw_get_ushort(rawfile, ifd.value_offset+6, &ushort_temp1);
 
1156
                                meta->cam_mul[2] = (gdouble) ushort_temp1;
 
1157
                                break;
 
1158
                }
 
1159
        }
 
1160
 
 
1161
        return TRUE;
 
1162
}
 
1163
 
 
1164
static gboolean
 
1165
makernote_samsung(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1166
{
 
1167
        gushort number_of_entries = 0;
 
1168
        guint base = offset;
 
1169
        guint uint_temp1;
 
1170
        gushort ushort_temp1;
 
1171
 
 
1172
        struct IFD ifd;
 
1173
 
 
1174
        /* get number of entries */
 
1175
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
1176
                return FALSE;
 
1177
        offset += 2;
 
1178
 
 
1179
        while(number_of_entries--)
 
1180
        {
 
1181
                read_ifd(rawfile, offset, &ifd);
 
1182
                offset += 12;
 
1183
 
 
1184
                switch (ifd.tag)
 
1185
                {
 
1186
                case 0xa021: /* White Balance */
 
1187
                                raw_get_uint(rawfile, base+ifd.value_offset, &uint_temp1);
 
1188
                                meta->cam_mul[0] = (gdouble) uint_temp1;
 
1189
                                raw_get_uint(rawfile, base+ifd.value_offset+4, &uint_temp1);
 
1190
                                meta->cam_mul[1] = (gdouble) uint_temp1;
 
1191
                                raw_get_uint(rawfile, base+ifd.value_offset+8, &uint_temp1);
 
1192
                                meta->cam_mul[3] = (gdouble) uint_temp1;
 
1193
                                raw_get_uint(rawfile, base+ifd.value_offset+12, &uint_temp1);
 
1194
                                meta->cam_mul[2] = (gdouble) uint_temp1;
 
1195
                        break;
 
1196
                case 0xa028: /* White Balance */
 
1197
                                raw_get_uint(rawfile, base+ifd.value_offset, &uint_temp1);
 
1198
                                meta->cam_mul[0] -= (gdouble) uint_temp1;
 
1199
                                raw_get_uint(rawfile, base+ifd.value_offset+4, &uint_temp1);
 
1200
                                meta->cam_mul[1] -= (gdouble) uint_temp1;
 
1201
                                raw_get_uint(rawfile, base+ifd.value_offset+8, &uint_temp1);
 
1202
                                meta->cam_mul[3] -= (gdouble) uint_temp1;
 
1203
                                raw_get_uint(rawfile, base+ifd.value_offset+12, &uint_temp1);
 
1204
                                meta->cam_mul[2] -= (gdouble) uint_temp1;
 
1205
                        break;
 
1206
                case 0xa003: /* LensType */
 
1207
                        raw_get_ushort(rawfile, offset-4, &ushort_temp1);
 
1208
                        meta->lens_id = ushort_temp1;
 
1209
                        break;
 
1210
                }
 
1211
        }
 
1212
        rs_metadata_normalize_wb(meta);
 
1213
        return TRUE;
 
1214
}
 
1215
 
 
1216
 
 
1217
static gboolean
 
1218
makernote_sony(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1219
{
 
1220
        gushort number_of_entries = 0;
 
1221
        guint uint_temp1;
 
1222
 
 
1223
        struct IFD ifd;
 
1224
 
 
1225
        /* get number of entries */
 
1226
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
1227
                return FALSE;
 
1228
        offset += 2;
 
1229
 
 
1230
        while(number_of_entries--)
 
1231
        {
 
1232
                read_ifd(rawfile, offset, &ifd);
 
1233
                offset += 12;
 
1234
 
 
1235
                switch (ifd.tag)
 
1236
                {
 
1237
                case 0xb027: /* LensType */
 
1238
                        raw_get_uint(rawfile, offset-4, &uint_temp1);
 
1239
                        meta->lens_id = uint_temp1;
 
1240
                        break;
 
1241
                }
 
1242
        }
 
1243
 
 
1244
        return TRUE;
 
1245
}
 
1246
 
 
1247
static void
 
1248
sony_decrypt(SonyMeta *sony, guint *data, gint len)
 
1249
{
 
1250
        while (len--)
 
1251
                *data++ ^= sony->pad[sony->p++ & 127] = sony->pad[(sony->p+1) & 127] ^ sony->pad[(sony->p+65) & 127];
 
1252
}
 
1253
 
 
1254
static gboolean
 
1255
private_sony(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1256
{
 
1257
        gushort number_of_entries;
 
1258
        struct IFD ifd;
 
1259
        gint i;
 
1260
        gint key;
 
1261
        SonyMeta *sony = (SonyMeta *) meta;
 
1262
 
 
1263
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
1264
                return FALSE;
 
1265
 
 
1266
        if (number_of_entries>5000)
 
1267
                return FALSE;
 
1268
 
 
1269
        offset += 2;
 
1270
 
 
1271
        while(number_of_entries--)
 
1272
        {
 
1273
                read_ifd(rawfile, offset, &ifd);
 
1274
                offset += 12;
 
1275
 
 
1276
                switch(ifd.tag)
 
1277
                {
 
1278
                        case 0x7200: /* SR2SubIFDOffset */
 
1279
                                sony->sony_offset = ifd.value_offset;
 
1280
                                break;
 
1281
                        case 0x7201: /* SR2SubIFDLength */
 
1282
                                sony->sony_length = ifd.value_offset;
 
1283
                                break;
 
1284
                        case 0x7221: /* SR2SubIFDKey */
 
1285
                                sony->sony_key = ifd.value_offset;
 
1286
 
 
1287
                                /* Initialize decrypter */
 
1288
                                key = sony->sony_key;
 
1289
                                for (sony->p=0; sony->p < 4; sony->p++)
 
1290
                                        sony->pad[sony->p] = key = key * 48828125 + 1;
 
1291
                                sony->pad[3] = sony->pad[3] << 1 | (sony->pad[0]^sony->pad[2]) >> 31;
 
1292
                                for (sony->p=4; sony->p < 127; sony->p++)
 
1293
                                        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;
 
1294
                                for (sony->p=0; sony->p < 127; sony->p++)
 
1295
                                        sony->pad[sony->p] = htonl(sony->pad[sony->p]);
 
1296
                                break;
 
1297
                }
 
1298
        }
 
1299
 
 
1300
        if ((sony->sony_offset > 0) && (sony->sony_length > 0) && (sony->sony_key != 0))
 
1301
        {
 
1302
                gpointer buf = g_new0(guchar, sony->sony_length);
 
1303
                if (raw_strcpy(rawfile, sony->sony_offset, buf, sony->sony_length))
 
1304
                {
 
1305
                        sony_decrypt(sony, buf, sony->sony_length/4);
 
1306
                        gushort *sbuf = (gushort *)(buf);
 
1307
                        gushort tag_count = sbuf[0];
 
1308
                        struct IFD *private_ifd;
 
1309
 
 
1310
                        for(i=0;i<tag_count;i++)
 
1311
                        {
 
1312
#if BYTE_ORDER == BIG_ENDIAN
 
1313
#warning FIXME: This will NOT work as expected on a big endian host
 
1314
#endif
 
1315
                                private_ifd = (struct IFD *) (buf+2+i*12);
 
1316
 
 
1317
                                switch (private_ifd->tag)
 
1318
                                {
 
1319
                                        case 0x7303: /* WB_GRBGLevels */
 
1320
                                                sbuf = (gushort *)(buf + private_ifd->value_offset - sony->sony_offset);
 
1321
                                                meta->cam_mul[1] = (gdouble) sbuf[0];
 
1322
                                                meta->cam_mul[0] = (gdouble) sbuf[1];
 
1323
                                                meta->cam_mul[2] = (gdouble) sbuf[2];
 
1324
                                                meta->cam_mul[3] = (gdouble) sbuf[3];
 
1325
 
 
1326
                                                rs_metadata_normalize_wb(meta);
 
1327
                                                break;
 
1328
                                        case 0x7313: /* WB_RGGBLevels */
 
1329
                                                sbuf = (gushort *)(buf + private_ifd->value_offset - sony->sony_offset);
 
1330
                                                meta->cam_mul[0] = (gdouble) sbuf[0];
 
1331
                                                meta->cam_mul[1] = (gdouble) sbuf[1];
 
1332
                                                meta->cam_mul[3] = (gdouble) sbuf[2];
 
1333
                                                meta->cam_mul[2] = (gdouble) sbuf[3];
 
1334
 
 
1335
                                                rs_metadata_normalize_wb(meta);
 
1336
                                                break;
 
1337
                                }
 
1338
                        }
 
1339
                }
 
1340
        }
 
1341
 
 
1342
        return TRUE;
 
1343
}
 
1344
 
 
1345
static gboolean
 
1346
exif_reader(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1347
{
 
1348
        gushort number_of_entries = 0;
 
1349
        
 
1350
        struct IFD ifd;
 
1351
 
 
1352
        /* get number of entries */
 
1353
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
1354
                return FALSE;
 
1355
        offset += 2;
 
1356
 
 
1357
        while(number_of_entries--)
 
1358
        {
 
1359
                read_ifd(rawfile, offset, &ifd);
 
1360
                offset += 12;
 
1361
 
 
1362
                switch (ifd.tag)
 
1363
                {
 
1364
                        case 0x010f: /* Make */
 
1365
                                if (!meta->make_ascii)
 
1366
                                        meta->make_ascii = rs_remove_tailing_spaces(raw_strdup(rawfile, ifd.offset, ifd.count), TRUE);
 
1367
                                break;
 
1368
                        case 0x0110: /* Model */
 
1369
                                if (!meta->model_ascii)
 
1370
                                        meta->model_ascii = rs_remove_tailing_spaces(raw_strdup(rawfile, ifd.offset, ifd.count), TRUE);
 
1371
                                break;
 
1372
                        case 0x9003: /* DateTime */
 
1373
                        case 0x9004: /* DateTime */
 
1374
                                if (!meta->time_ascii)
 
1375
                                {
 
1376
                                        meta->time_ascii = raw_strdup(rawfile, ifd.value_offset, ifd.count);
 
1377
                                        meta->timestamp = rs_exiftime_to_unixtime(meta->time_ascii);
 
1378
                                }
 
1379
                                break;
 
1380
                        case 0x829A: /* ExposureTime */
 
1381
                                if (ifd.count == 1 && ifd.value_rational < EXPO_TIME_MAXVAL)
 
1382
                                        meta->shutterspeed = 1.0 / ifd.value_rational;
 
1383
                                break;
 
1384
                        case 0x829D: /* FNumber */
 
1385
                                if (ifd.count == 1)
 
1386
                                        meta->aperture = ifd.value_rational;
 
1387
                                break;
 
1388
                        case 0x8827: /* ISOSpeedRatings */
 
1389
                                if (ifd.count == 1)
 
1390
                                        meta->iso = ifd.value_ushort;
 
1391
                                break;
 
1392
                        case 0x920A: /* Focal length */
 
1393
                                        meta->focallength = ifd.value_rational;
 
1394
                                break;
 
1395
                        case 0x927c: /* MakerNote */
 
1396
                                switch (meta->make)
 
1397
                                {
 
1398
                                        case MAKE_CANON:
 
1399
                                                makernote_canon(rawfile, ifd.value_offset, meta);
 
1400
                                                break;
 
1401
                                        case MAKE_MINOLTA:
 
1402
                                                makernote_minolta(rawfile, ifd.value_offset, meta);
 
1403
                                                break;
 
1404
                                        case MAKE_NIKON:
 
1405
                                                makernote_nikon(rawfile, ifd.value_offset, meta);
 
1406
                                                break;
 
1407
                                        case MAKE_PENTAX:
 
1408
                                                makernote_pentax(rawfile, ifd.value_offset, meta);
 
1409
                                                break;
 
1410
                                        case MAKE_OLYMPUS:
 
1411
                                                if (raw_strcmp(rawfile, ifd.value_offset, "OLYMPUS", 7))
 
1412
                                                        makernote_olympus(rawfile, ifd.value_offset, ifd.value_offset+12, meta);
 
1413
                                                else if (raw_strcmp(rawfile, ifd.value_offset, "OLYMP", 5))
 
1414
                                                        makernote_olympus(rawfile, ifd.value_offset+8, ifd.value_offset+8, meta);
 
1415
                                                break;
 
1416
                                        case MAKE_SAMSUNG:
 
1417
                                                makernote_samsung(rawfile, ifd.value_offset, meta);
 
1418
                                                break;
 
1419
                                        case MAKE_SONY:
 
1420
                                                makernote_sony(rawfile, ifd.value_offset, meta);
 
1421
                                                break;
 
1422
                                        case MAKE_PANASONIC:
 
1423
                                                if (raw_strcmp(rawfile, ifd.value_offset, "Panasonic", 9))
 
1424
                                                        makernote_panasonic(rawfile, ifd.value_offset+12, meta);
 
1425
                                                break;
 
1426
                                        default:
 
1427
                                                break;
 
1428
                                }
 
1429
                                break;
 
1430
                }
 
1431
        }
 
1432
 
 
1433
        return TRUE;
 
1434
}
 
1435
 
 
1436
static gboolean 
 
1437
parse_dng_private_data(RAWFILE *rawfile, guint offset, RSMetadata *meta) 
 
1438
{
 
1439
  /*
 
1440
  1. Six bytes containing the zero-terminated string "Adobe". (The DNG specification calls for the DNGPrivateData tag to start with an ASCII string identifying the creator/format).
 
1441
  2. 4 bytes: an ASCII string ("MakN" for a Makernote),  indicating what sort of data is being stored here. Note that this is not zero-terminated.
 
1442
  3. A four-byte count (number of data bytes following); this is the length of the original MakerNote data. (This is always in "most significant byte first" format).
 
1443
  4. 2 bytes: the byte-order indicator from the original file (the usual 'MM'/4D4D or 'II'/4949).
 
1444
  5. 4 bytes: the original file offset for the MakerNote tag data (stored according to the byte order given above).
 
1445
  6. The contents of the MakerNote tag. This is a simple byte-for-byte copy, with no modification.
 
1446
  */
 
1447
        gushort tiff_byteorder = raw_get_byteorder(rawfile);
 
1448
 
 
1449
        /* Check if first string is "Adobe" */
 
1450
        if (!raw_strcmp(rawfile, offset, "Adobe", 5))
 
1451
                return FALSE;
 
1452
        offset+=6;
 
1453
 
 
1454
        /* Check if type is Adobe Makernote */
 
1455
        if (!raw_strcmp(rawfile, offset, "MakN", 4))
 
1456
                return FALSE;
 
1457
        offset+=4;
 
1458
 
 
1459
        /* Read makernote info */
 
1460
        raw_set_byteorder(rawfile, 0x4D4D);
 
1461
        guint org_size;
 
1462
        if (!raw_get_uint(rawfile, offset, &org_size))
 
1463
        {
 
1464
                raw_set_byteorder(rawfile, tiff_byteorder);
 
1465
                return FALSE;
 
1466
        }
 
1467
        if (org_size > raw_get_filesize(rawfile)-offset)
 
1468
        {
 
1469
                raw_set_byteorder(rawfile, tiff_byteorder);
 
1470
                return FALSE;
 
1471
        }
 
1472
        offset+=4;
 
1473
 
 
1474
        gushort byteorder = 0;
 
1475
        raw_get_ushort(rawfile, offset, &byteorder);
 
1476
        offset+=2;
 
1477
        if (byteorder != 0x4D4D && byteorder != 0x4949)
 
1478
        {
 
1479
                raw_set_byteorder(rawfile, tiff_byteorder);
 
1480
                return FALSE;
 
1481
        }
 
1482
 
 
1483
        guint org_offset;
 
1484
        if (!raw_get_uint(rawfile, offset, &org_offset))
 
1485
        {
 
1486
                raw_set_byteorder(rawfile, tiff_byteorder);
 
1487
                return FALSE;
 
1488
        }
 
1489
        offset+=4;
 
1490
 
 
1491
        /* Create memory mapped TIFF */
 
1492
        const gchar* data = raw_get_map(rawfile);
 
1493
        gchar* maker_data = g_malloc(org_offset + org_size);
 
1494
        memcpy(&maker_data[org_offset],&data[offset], org_size);
 
1495
        RAWFILE *maker_raw = raw_create_from_memory(maker_data, org_offset + org_size, org_offset, byteorder);
 
1496
 
 
1497
        /* Read makernote, as if this was the original file */
 
1498
        /* We preserve WB since it might have changed - converted Canon sRAW for instance */
 
1499
        gdouble stored_mul[4];
 
1500
        memcpy(stored_mul, meta->cam_mul,4*sizeof(gdouble));
 
1501
        switch (meta->make)
 
1502
        {
 
1503
                case MAKE_CANON:
 
1504
                        makernote_canon(maker_raw, org_offset, meta);
 
1505
                        break;
 
1506
                case MAKE_MINOLTA:
 
1507
                        makernote_minolta(maker_raw, org_offset, meta);
 
1508
                        break;
 
1509
                case MAKE_NIKON:
 
1510
                        makernote_nikon(maker_raw, org_offset, meta);
 
1511
                        break;
 
1512
                case MAKE_PENTAX:
 
1513
                        makernote_pentax(maker_raw, org_offset, meta);
 
1514
                        break;
 
1515
                case MAKE_OLYMPUS:
 
1516
                        if (raw_strcmp(maker_raw, org_offset, "OLYMPUS", 7))
 
1517
                                makernote_olympus(maker_raw, org_offset, org_offset+12, meta);
 
1518
                        else if (raw_strcmp(maker_raw,org_offset, "OLYMP", 5))
 
1519
                                makernote_olympus(maker_raw, org_offset+8, org_offset+8, meta);
 
1520
                        break;
 
1521
                case MAKE_SAMSUNG:
 
1522
                        makernote_samsung(maker_raw, org_offset, meta);
 
1523
                        break;
 
1524
                case MAKE_SONY:
 
1525
                        makernote_sony(maker_raw, org_offset, meta);
 
1526
                        break;
 
1527
                case MAKE_PANASONIC:
 
1528
                        if (raw_strcmp(maker_raw, org_offset, "Panasonic", 9))
 
1529
                                makernote_panasonic(maker_raw, org_offset+12, meta);
 
1530
                        break;
 
1531
                default:
 
1532
                        break;
 
1533
        }
 
1534
        /* Restore WB */
 
1535
        memcpy(meta->cam_mul, stored_mul, 4*sizeof(gdouble));
 
1536
        raw_close_file(maker_raw);
 
1537
        g_free(maker_data);
 
1538
        raw_set_byteorder(rawfile, tiff_byteorder);
 
1539
        return TRUE;
 
1540
}
 
1541
 
 
1542
 
 
1543
static gboolean
 
1544
ifd_reader(RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1545
{
 
1546
        gushort number_of_entries = 0;
 
1547
        gboolean is_preview = FALSE;
 
1548
        guint uint_temp1;
 
1549
        gfloat float_temp;
 
1550
 
 
1551
        struct IFD ifd;
 
1552
 
 
1553
        /* get number of entries */
 
1554
        if(!raw_get_ushort(rawfile, offset, &number_of_entries))
 
1555
                return FALSE;
 
1556
        offset += 2;
 
1557
 
 
1558
        while(number_of_entries--)
 
1559
        {
 
1560
                read_ifd(rawfile, offset, &ifd);
 
1561
                offset += 12;
 
1562
 
 
1563
                switch (ifd.tag)
 
1564
                {
 
1565
                        case 0x00fe: /* Subfile type */
 
1566
                                is_preview = (((gint)ifd.value) & 1) != 0;
 
1567
                                break;
 
1568
                        case 0x0100: /* Image width */
 
1569
                                if (is_preview)
 
1570
                                        meta->preview_width = ifd.value;
 
1571
                                break;
 
1572
                        case 0x0101: /* Image length (aka height in human language) */
 
1573
                                if (is_preview)
 
1574
                                        meta->preview_height = ifd.value;
 
1575
                                break;
 
1576
                        case 0x0102: /* Bits per sample */
 
1577
                                if (is_preview)
 
1578
                                {
 
1579
                                        raw_get_ushort (rawfile, ifd.value_offset + 0, &meta->preview_bits [0]);
 
1580
                                        raw_get_ushort (rawfile, ifd.value_offset + 2, &meta->preview_bits [1]);
 
1581
                                        raw_get_ushort (rawfile, ifd.value_offset + 4, &meta->preview_bits [2]);
 
1582
                                }
 
1583
                                break;
 
1584
                        case 0x0103: /* Compression */
 
1585
                                break;
 
1586
                        case 0x010f: /* Make */
 
1587
                                if (!meta->make_ascii)
 
1588
                                {
 
1589
                                        meta->make_ascii = rs_remove_tailing_spaces(raw_strdup(rawfile, ifd.offset, ifd.count), TRUE);
 
1590
                                        if (raw_strcmp(rawfile, ifd.value_offset, "Canon", 5))
 
1591
                                                meta->make = MAKE_CANON;
 
1592
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "CASIO", 5))
 
1593
                                                meta->make = MAKE_CASIO;
 
1594
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Hasselblad", 10))
 
1595
                                                meta->make = MAKE_HASSELBLAD;
 
1596
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "KODAK", 5))
 
1597
                                                meta->make = MAKE_KODAK;
 
1598
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "EASTMAN KODAK", 13))
 
1599
                                                meta->make = MAKE_KODAK;
 
1600
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Leica", 5))
 
1601
                                                meta->make = MAKE_LEICA;
 
1602
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Minolta", 7))
 
1603
                                                meta->make = MAKE_MINOLTA;
 
1604
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "KONICA MINOLTA", 14))
 
1605
                                                meta->make = MAKE_MINOLTA;
 
1606
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Mamiya", 6))
 
1607
                                                meta->make = MAKE_MAMIYA;
 
1608
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "NIKON", 5))
 
1609
                                                meta->make = MAKE_NIKON;
 
1610
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "OLYMPUS", 7))
 
1611
                                                meta->make = MAKE_OLYMPUS;
 
1612
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Panasonic", 9))
 
1613
                                                meta->make = MAKE_PANASONIC;
 
1614
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "PENTAX", 6))
 
1615
                                                meta->make = MAKE_PENTAX;
 
1616
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Phase One", 9))
 
1617
                                                meta->make = MAKE_PHASEONE;
 
1618
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "Ricoh", 5))
 
1619
                                                meta->make = MAKE_RICOH;
 
1620
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "SAMSUNG", 7))
 
1621
                                                meta->make = MAKE_SAMSUNG;
 
1622
                                        /* Do not detect SONY, we don't want to call private_sony() unless
 
1623
                                           we're sure we have a hidden SonyMeta */
 
1624
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "FUJIFILM", 4))
 
1625
                                                meta->make = MAKE_FUJIFILM;
 
1626
                                        else if (raw_strcmp(rawfile, ifd.value_offset, "SEIKO EPSON", 11))
 
1627
                                                meta->make = MAKE_EPSON;
 
1628
                                }
 
1629
                                break;
 
1630
                        case 0x0110: /* Model */
 
1631
                                if (!meta->model_ascii)
 
1632
                                        meta->model_ascii = rs_remove_tailing_spaces(raw_strdup(rawfile, ifd.offset, ifd.count), TRUE);
 
1633
                                break;
 
1634
                        case 0x0111: /* StripOffsets */
 
1635
                                if (meta->preview_start==0 || is_preview)
 
1636
                                        meta->preview_start = ifd.value + raw_get_base(rawfile);
 
1637
                                break;
 
1638
                        case 0x0112: /* Orientation */
 
1639
                                if (ifd.count == 1)
 
1640
                                {
 
1641
                                        meta->orientation = ifd.value_ushort;
 
1642
                                        switch (meta->orientation)
 
1643
                                        {
 
1644
                                                case 6: meta->orientation = 90;
 
1645
                                                        break;
 
1646
                                                case 8: meta->orientation = 270;
 
1647
                                                        break;
 
1648
                                        }
 
1649
                                }
 
1650
                                break;
 
1651
                        case 0x0117: /* StripByteCounts */
 
1652
                                if (meta->preview_length==0 || is_preview)
 
1653
                                        meta->preview_length = ifd.value;
 
1654
                                break;
 
1655
                        case 0x011c: /* Planar configuration */
 
1656
                                if (is_preview)
 
1657
                                        meta->preview_planar_config = ifd.value;
 
1658
                                break;
 
1659
                        case 0x0132: /* DateTime */
 
1660
                                break;
 
1661
                        case 0x014a: /* SubIFD */
 
1662
                                /*Sony DSLR-A100 tag 0x014a points to RAW data */
 
1663
                                if (meta->make == MAKE_SONY)
 
1664
                                        if (g_strcmp0(meta->model_ascii, "DSLR-A100") == 0)
 
1665
                                                break;
 
1666
                                if (ifd.count == 1)
 
1667
                                        ifd_reader(rawfile, ifd.value_offset, meta);
 
1668
                                else
 
1669
                                {
 
1670
                                        raw_get_uint(rawfile, ifd.value_offset, &uint_temp1);
 
1671
                                        ifd_reader(rawfile, uint_temp1, meta);
 
1672
                                }
 
1673
                                break;
 
1674
                        case 0x0201: /* JPEGInterchangeFormat */
 
1675
                                meta->thumbnail_start = ifd.value_uint + raw_get_base(rawfile);
 
1676
                                break;
 
1677
                        case 0x0202: /* JPEGInterchangeFormatLength */
 
1678
                                meta->thumbnail_length = ifd.value_uint;
 
1679
                                break;
 
1680
                        case 0x8769: /* ExifIFDPointer */
 
1681
                                exif_reader(rawfile, ifd.value_offset, meta);
 
1682
                                break;
 
1683
 
 
1684
                        /* The following tags are from the DNG spec, they should be safe */
 
1685
                        case 0xc628: /* DNG: AsShotNeutral */
 
1686
                                if (((ifd.type == TIFF_FIELD_TYPE_RATIONAL)||(ifd.type == TIFF_FIELD_TYPE_SRATIONAL)) && ifd.count == 3)
 
1687
                                {
 
1688
                                        meta->cam_mul[0] = 1.0/get_rational(rawfile, ifd.value_offset);
 
1689
                                        meta->cam_mul[1] = 1.0/get_rational(rawfile, ifd.value_offset+8);
 
1690
                                        meta->cam_mul[2] = 1.0/get_rational(rawfile, ifd.value_offset+16);
 
1691
                                        meta->cam_mul[3] = meta->cam_mul[1];
 
1692
                                        rs_metadata_normalize_wb(meta);
 
1693
                                }
 
1694
                                break;
 
1695
                        case 0xc634: /* DNG: PrivateData */
 
1696
                                if (meta->make == MAKE_SONY)
 
1697
                                        private_sony(rawfile, ifd.value_offset, meta);
 
1698
                                parse_dng_private_data(rawfile, ifd.value_offset, meta);
 
1699
                                break;
 
1700
                        case 0xc630: /* DNG LensInfo */
 
1701
                                if (raw_get_rational(rawfile, ifd.value_offset, &float_temp))
 
1702
                                        meta->lens_min_focal = float_temp;
 
1703
                                if (raw_get_rational(rawfile, ifd.value_offset+8, &float_temp))
 
1704
                                        meta->lens_max_focal = float_temp;
 
1705
                                if (raw_get_rational(rawfile, ifd.value_offset+16, &float_temp))
 
1706
                                        meta->lens_min_aperture = float_temp;
 
1707
                                if (raw_get_rational(rawfile, ifd.value_offset+24, &float_temp))
 
1708
                                        meta->lens_max_aperture = float_temp;
 
1709
                                break;
 
1710
                }
 
1711
        }
 
1712
 
 
1713
        return TRUE;
 
1714
}
 
1715
 
 
1716
/**
 
1717
 * Generic TIFF reader
 
1718
 */
 
1719
static gboolean
 
1720
tiff_load_meta(const gchar *service, RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1721
{
 
1722
        guint next = 0;
 
1723
        gushort ifd_num = 0;
 
1724
        guchar version;
 
1725
 
 
1726
        version = raw_init_file_tiff(rawfile, offset);
 
1727
 
 
1728
        if (version == 0x55)
 
1729
                meta->make = MAKE_LEICA;
 
1730
 
 
1731
        offset = get_first_ifd_offset(rawfile);
 
1732
        do {
 
1733
                if (!raw_get_ushort(rawfile, offset, &ifd_num)) break; /* used for calculating next IFD */
 
1734
                if (!raw_get_uint(rawfile, offset+2+ifd_num*12, &next)) break; /* 2: offset+short(ifd_num), 12: length of ifd-entry */
 
1735
 
 
1736
                switch (meta->make)
 
1737
                {
 
1738
                        case MAKE_LEICA:
 
1739
                                if (!makernote_leica(rawfile, offset, meta))
 
1740
                                        ifd_reader(rawfile, offset, meta);
 
1741
                                break;
 
1742
                        default:
 
1743
                                ifd_reader(rawfile, offset, meta);
 
1744
                                break;
 
1745
                }
 
1746
 
 
1747
                /* Hack to support a few cameras that embeds EXIF-info or Makernotes in IFD 0 */
 
1748
                if (meta->make == MAKE_CANON && g_str_equal(meta->model_ascii, "EOS D2000C"))
 
1749
                        exif_reader(rawfile, offset, meta);
 
1750
                if (meta->make == MAKE_KODAK && g_str_equal(meta->model_ascii, "DCS520C"))
 
1751
                        exif_reader(rawfile, offset, meta);
 
1752
                if (meta->make == MAKE_KODAK && g_str_equal(meta->model_ascii, "DCS Pro 14N"))
 
1753
                        exif_reader(rawfile, offset, meta);
 
1754
                if (meta->make == MAKE_PANASONIC)
 
1755
                        ifd_panasonic(rawfile, offset, meta);
 
1756
 
 
1757
                if (offset == next) break; /* avoid infinite loops */
 
1758
                offset = next;
 
1759
        } while (next>0);
 
1760
 
 
1761
        rs_metadata_normalize_wb(meta);
 
1762
        return !!meta->make;
 
1763
}
 
1764
 
 
1765
/**
 
1766
 * .TIF reader
 
1767
 */
 
1768
static gboolean
 
1769
tif_load_meta(const gchar *service, RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1770
{
 
1771
 
 
1772
        if (!tiff_load_meta(service, rawfile, offset, meta))
 
1773
                return FALSE;
 
1774
 
 
1775
        /* Phase One and Samsung doesn't set this */
 
1776
        if ((meta->make == MAKE_PHASEONE) || (meta->make == MAKE_SAMSUNG))
 
1777
                meta->preview_planar_config = 1;
 
1778
 
 
1779
        /* Load thumbnail - try thumbnail first - then preview image - then decode the RAW image*/
 
1780
        if (!thumbnail_reader(service, rawfile, meta->thumbnail_start, meta->thumbnail_length, meta))
 
1781
                if (!thumbnail_reader(service, rawfile, meta->preview_start, meta->preview_length, meta))
 
1782
                        thumbnail_store(raw_thumbnail_reader(service, meta), meta);
 
1783
 
 
1784
        return TRUE;
 
1785
}
 
1786
 
 
1787
static gboolean
 
1788
thumbnail_reader(const gchar *service, RAWFILE *rawfile, guint offset, guint length, RSMetadata *meta)
 
1789
{
 
1790
        GdkPixbuf *pixbuf=NULL;
 
1791
 
 
1792
        if ((offset>0) && (length>0) && (length<5000000))
 
1793
        {
 
1794
                if ((length==165888) && (meta->make == MAKE_CANON))
 
1795
                        pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8, 288, 192, 288*3, NULL, NULL);
 
1796
                else if (length==57600) /* Multiple Nikon, Pentax and Samsung cameras */
 
1797
                        pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8, 160, 120, 160*3, NULL, NULL);
 
1798
                else if (length==48672)
 
1799
                        pixbuf = gdk_pixbuf_new_from_data(raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8, 156, 104, 156*3, NULL, NULL);
 
1800
                else
 
1801
                        /* Many RAW files are based on TIFF and include the preview image
 
1802
                         * as the "main" image in the TIFF so that "normal" image viewing
 
1803
                         * programs can display at least the thumbnail. So we will
 
1804
                         * check if the TIFF contains such a thumbnail in the simplest
 
1805
                         * possible format (e.g. uncompressed R8G8B8) and use it
 
1806
                         * if it is present.
 
1807
                         */
 
1808
                        if (offset == meta->preview_start && /* if we're using the preview image */
 
1809
                                meta->preview_planar_config == 1 && /* uncompressed */
 
1810
                                meta->preview_bits [0] == 8 &&
 
1811
                                meta->preview_bits [1] == 8 &&
 
1812
                                meta->preview_bits [2] == 8 && /* R8G8B8 */
 
1813
                                meta->preview_width * meta->preview_height * 3 == length &&
 
1814
                                meta->preview_width > 16 &&
 
1815
                                meta->preview_width < 1024 &&
 
1816
                                meta->preview_height > 16 &&
 
1817
                                meta->preview_height < 1024)    /* Some arbitrary sane limit */
 
1818
                                pixbuf = gdk_pixbuf_new_from_data(
 
1819
                                        raw_get_map(rawfile)+offset, GDK_COLORSPACE_RGB, FALSE, 8,
 
1820
                                        meta->preview_width, meta->preview_height,
 
1821
                                        meta->preview_width * 3, NULL, NULL);
 
1822
                        else
 
1823
                                /* Try to guess file format based on contents (JPEG previews) */
 
1824
                        pixbuf = raw_get_pixbuf(rawfile, offset, length);
 
1825
        }
 
1826
        if ( pixbuf && (gdk_pixbuf_get_width(pixbuf) < 10 || gdk_pixbuf_get_height(pixbuf) < 10))
 
1827
                pixbuf = NULL;
 
1828
 
 
1829
        return thumbnail_store(pixbuf, meta);
 
1830
}
 
1831
 
 
1832
static gboolean
 
1833
thumbnail_store(GdkPixbuf *pixbuf, RSMetadata *meta)
 
1834
{
 
1835
        GdkPixbuf *pixbuf2=NULL;
 
1836
        if (pixbuf)
 
1837
        {
 
1838
                gdouble ratio;
 
1839
                /* Handle Canon/Nikon cropping */
 
1840
                if ((gdk_pixbuf_get_width(pixbuf) == 160) && (gdk_pixbuf_get_height(pixbuf)==120))
 
1841
                {
 
1842
                        pixbuf2 = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 160, 106);
 
1843
                        gdk_pixbuf_copy_area(pixbuf, 0, 7, 160, 106, pixbuf2, 0, 0);
 
1844
                        g_object_unref(pixbuf);
 
1845
                        pixbuf = pixbuf2;
 
1846
                }
 
1847
 
 
1848
                /* Scale to a bounding box of 128x128 pixels */
 
1849
                ratio = ((gdouble) gdk_pixbuf_get_width(pixbuf))/((gdouble) gdk_pixbuf_get_height(pixbuf));
 
1850
                if (ratio>1.0)
 
1851
                        pixbuf2 = gdk_pixbuf_scale_simple(pixbuf, 128, (gint) (128.0/ratio), GDK_INTERP_BILINEAR);
 
1852
                else
 
1853
                        pixbuf2 = gdk_pixbuf_scale_simple(pixbuf, (gint) (128.0*ratio), 128, GDK_INTERP_BILINEAR);
 
1854
                g_object_unref(pixbuf);
 
1855
                pixbuf = pixbuf2;
 
1856
 
 
1857
                /* Rotate thumbnail in place */
 
1858
                switch (meta->orientation)
 
1859
                {
 
1860
                        /* this is very COUNTER-intuitive - gdk_pixbuf_rotate_simple() is wierd */
 
1861
                        case 90:
 
1862
                                pixbuf2 = gdk_pixbuf_rotate_simple(pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
 
1863
                                g_object_unref(pixbuf);
 
1864
                                pixbuf = pixbuf2;
 
1865
                                break;
 
1866
                        case 270:
 
1867
                                pixbuf2 = gdk_pixbuf_rotate_simple(pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
 
1868
                                g_object_unref(pixbuf);
 
1869
                                pixbuf = pixbuf2;
 
1870
                                break;
 
1871
                }
 
1872
                meta->thumbnail = pixbuf;
 
1873
                return TRUE;
 
1874
        }
 
1875
        return FALSE;   
 
1876
}
 
1877
 
 
1878
                
 
1879
static GdkPixbuf*
 
1880
raw_thumbnail_reader(const gchar *service, RSMetadata *meta)
 
1881
{
 
1882
        GdkPixbuf* pixbuf = 0;
 
1883
        gint c;
 
1884
        gfloat pre_mul[4];
 
1885
 
 
1886
        RSFilter *finput = rs_filter_new("RSInputFile", NULL);
 
1887
        RSFilter *fdemosaic = rs_filter_new("RSDemosaic", finput);
 
1888
        RSFilter *fresample = rs_filter_new("RSResample", fdemosaic);
 
1889
        RSFilter *fcst = rs_filter_new("RSColorspaceTransform", fresample);
 
1890
        
 
1891
        g_object_set(fresample, "width", 256,
 
1892
                                 "height", 256, 
 
1893
                                "bounding-box", TRUE, NULL);
 
1894
 
 
1895
        g_object_set(finput, "filename", service, 
 
1896
                                 "color-space", rs_color_space_new_singleton("RSSrgb"), NULL);
 
1897
 
 
1898
        rs_filter_set_recursive(RS_FILTER(fdemosaic), "demosaic-allow-downscale",  TRUE, NULL);
 
1899
        
 
1900
        RSFilterRequest *request = rs_filter_request_new();
 
1901
        rs_filter_request_set_roi(request, FALSE);
 
1902
        rs_filter_request_set_quick(request, TRUE);
 
1903
 
 
1904
        for(c=0;c<4;c++)
 
1905
                pre_mul[c] = (gfloat) meta->cam_mul[c] * 1.5f;
 
1906
 
 
1907
        rs_filter_param_set_float4(RS_FILTER_PARAM(request), "premul", pre_mul);
 
1908
        rs_filter_param_set_object(RS_FILTER_PARAM(request), "colorspace", rs_color_space_new_singleton("RSSrgb"));     
 
1909
 
 
1910
        RSFilterResponse *response = rs_filter_get_image8(fcst, request);
 
1911
        pixbuf = rs_filter_response_get_image8(response);
 
1912
 
 
1913
        g_object_unref(finput);
 
1914
        g_object_unref(fdemosaic);
 
1915
        g_object_unref(fresample);
 
1916
        g_object_unref(fcst);
 
1917
        g_object_unref(request);
 
1918
        g_object_unref(response);
 
1919
 
 
1920
        return pixbuf;
 
1921
}
 
1922
 
 
1923
static gboolean
 
1924
sony_load_meta(const gchar *service, RAWFILE *rawfile, guint offset, RSMetadata *meta)
 
1925
{
 
1926
        SonyMeta sony;
 
1927
        sony.sony_offset = 0;
 
1928
        sony.sony_length = 0;
 
1929
        sony.sony_key = 0;
 
1930
        meta->make = MAKE_SONY;
 
1931
 
 
1932
        memcpy(&sony, meta, sizeof(RSMetadata));
 
1933
        gboolean ret = tif_load_meta(service, rawfile, offset, RS_METADATA(&sony));
 
1934
        memcpy(meta, &sony, sizeof(RSMetadata));
 
1935
        return ret;
 
1936
}
 
1937
 
 
1938
G_MODULE_EXPORT void
 
1939
rs_plugin_load(RSPlugin *plugin)
 
1940
{
 
1941
        rs_filetype_register_meta_loader(".cr2", "Canon CR2", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1942
        rs_filetype_register_meta_loader(".nef", "Nikon NEF", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1943
        rs_filetype_register_meta_loader(".nrw", "Nikon NEF 2", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1944
        rs_filetype_register_meta_loader(".tif", "Canon TIFF", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1945
        rs_filetype_register_meta_loader(".rwl", "Leica", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1946
        rs_filetype_register_meta_loader(".arw", "Sony", sony_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1947
        rs_filetype_register_meta_loader(".sr2", "Sony", sony_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1948
        rs_filetype_register_meta_loader(".srf", "Sony", sony_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1949
        rs_filetype_register_meta_loader(".kdc", "Kodak", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1950
        rs_filetype_register_meta_loader(".dcr", "Kodak", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1951
        rs_filetype_register_meta_loader(".orf", "Olympus", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1952
        rs_filetype_register_meta_loader(".raw", "Panasonic raw", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1953
        rs_filetype_register_meta_loader(".rw2", "Panasonic raw 2", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1954
        rs_filetype_register_meta_loader(".pef", "Pentax raw", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1955
        rs_filetype_register_meta_loader(".dng", "Adobe Digital negative", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1956
        rs_filetype_register_meta_loader(".mef", "Mamiya", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1957
        rs_filetype_register_meta_loader(".3fr", "Hasselblad", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1958
        rs_filetype_register_meta_loader(".erf", "Epson", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1959
        rs_filetype_register_meta_loader(".srw", "Samsung", tif_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1960
 
 
1961
        rs_filetype_register_meta_loader(".tiff", "Generic TIFF meta loader", tiff_load_meta, 10, RS_LOADER_FLAGS_RAW);
 
1962
}