~ubuntu-branches/ubuntu/precise/exiv2/precise

1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
1
// ***************************************************************** -*- C++ -*-
2
/*
1.3.1 by Mark Purcell
Import upstream version 0.20
3
 * Copyright (C) 2004-2010 Andreas Huggel <ahuggel@gmx.net>
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
4
 *
5
 * This program is part of the Exiv2 distribution.
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
20
 */
21
/*
22
  File:      tiffimage.cpp
1.3.2 by Robert Ancell
Import upstream version 0.21
23
  Version:   $Rev: 2369 $
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
24
  Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
25
  History:   15-Mar-06, ahu: created
26
27
 */
28
// *****************************************************************************
1.3.2 by Robert Ancell
Import upstream version 0.21
29
#include "rcsid_int.hpp"
30
EXIV2_RCSID("@(#) $Id: tiffimage.cpp 2369 2010-10-25 13:16:04Z ahuggel $")
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
31
32
// *****************************************************************************
33
// included header files
34
#ifdef _MSC_VER
35
# include "exv_msvc.h"
36
#else
37
# include "exv_conf.h"
38
#endif
39
40
#include "tiffimage.hpp"
1.1.8 by Mark Purcell
Import upstream version 0.18
41
#include "tiffimage_int.hpp"
42
#include "tiffcomposite_int.hpp"
43
#include "tiffvisitor_int.hpp"
44
#include "makernote_int.hpp"
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
45
#include "image.hpp"
46
#include "error.hpp"
47
#include "futils.hpp"
1.1.8 by Mark Purcell
Import upstream version 0.18
48
#include "types.hpp"
1.1.3 by Mark Purcell
Import upstream version 0.14
49
#include "i18n.h"                // NLS support.
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
50
51
// + standard includes
52
#include <string>
53
#include <iostream>
54
#include <iomanip>
55
#include <cassert>
1.1.8 by Mark Purcell
Import upstream version 0.18
56
#include <memory>
57
58
/* --------------------------------------------------------------------------
59
60
   Todo:
61
62
   + CR2 Makernotes don't seem to have a next pointer but Canon Jpeg Makernotes
63
     do. What a mess. (That'll become an issue when it comes to writing to CR2)
64
   + Sony makernotes in RAW files do not seem to have header like those in Jpegs.
65
     And maybe no next pointer either.
66
67
   in crwimage.* :
68
69
   + Fix CiffHeader according to TiffHeader
70
   + Combine Error(15) and Error(33), add format argument %1
71
   + Search crwimage for todos, fix writeMetadata comment
72
   + rename loadStack to getPath for consistency
73
74
   -------------------------------------------------------------------------- */
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
75
76
// *****************************************************************************
77
// class member definitions
78
namespace Exiv2 {
79
1.1.8 by Mark Purcell
Import upstream version 0.18
80
    using namespace Internal;
81
1.1.3 by Mark Purcell
Import upstream version 0.14
82
    TiffImage::TiffImage(BasicIo::AutoPtr io, bool /*create*/)
1.3.2 by Robert Ancell
Import upstream version 0.21
83
        : Image(ImageType::tiff, mdExif | mdIptc, io),
84
          pixelWidth_(0), pixelHeight_(0)
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
85
    {
86
    } // TiffImage::TiffImage
87
1.3.2 by Robert Ancell
Import upstream version 0.21
88
    struct MimeTypeList {
89
        bool operator==(int compression) const { return compression_ == compression; }
90
        int compression_;
91
        const char* mimeType_;
92
    };
93
94
    MimeTypeList mimeTypeList[] = {
95
        { 32770, "image/x-samsung-srw" },
96
        { 34713, "image/x-nikon-nef"   },
97
        { 65535, "image/x-pentax-pef"  }
98
    };
99
1.2.4 by Mark Purcell
Import upstream version 0.19
100
    std::string TiffImage::mimeType() const
101
    {
1.3.2 by Robert Ancell
Import upstream version 0.21
102
        if (!mimeType_.empty()) return mimeType_;
103
104
        mimeType_ = std::string("image/tiff");
105
        std::string key = "Exif." + primaryGroup() + ".Compression";
106
        ExifData::const_iterator md = exifData_.findKey(ExifKey(key));
107
        if (md != exifData_.end() && md->count() > 0) {
108
            const MimeTypeList* i = find(mimeTypeList, static_cast<int>(md->toLong()));
109
            if (i) mimeType_ = std::string(i->mimeType_);
110
        }
111
        return mimeType_;
1.2.4 by Mark Purcell
Import upstream version 0.19
112
    }
113
114
    std::string TiffImage::primaryGroup() const
115
    {
1.3.2 by Robert Ancell
Import upstream version 0.21
116
        if (!primaryGroup_.empty()) return primaryGroup_;
117
1.2.4 by Mark Purcell
Import upstream version 0.19
118
        static const char* keys[] = {
119
            "Exif.Image.NewSubfileType",
120
            "Exif.SubImage1.NewSubfileType",
121
            "Exif.SubImage2.NewSubfileType",
122
            "Exif.SubImage3.NewSubfileType",
1.3.1 by Mark Purcell
Import upstream version 0.20
123
            "Exif.SubImage4.NewSubfileType",
124
            "Exif.SubImage5.NewSubfileType",
125
            "Exif.SubImage6.NewSubfileType",
126
            "Exif.SubImage7.NewSubfileType",
127
            "Exif.SubImage8.NewSubfileType",
128
            "Exif.SubImage9.NewSubfileType"
1.2.4 by Mark Purcell
Import upstream version 0.19
129
        };
130
        // Find the group of the primary image, default to "Image"
1.3.2 by Robert Ancell
Import upstream version 0.21
131
        primaryGroup_ = std::string("Image");
1.2.4 by Mark Purcell
Import upstream version 0.19
132
        for (unsigned int i = 0; i < EXV_COUNTOF(keys); ++i) {
133
            ExifData::const_iterator md = exifData_.findKey(ExifKey(keys[i]));
134
            // Is it the primary image?
135
            if (md != exifData_.end() && md->count() > 0 && md->toLong() == 0) {
1.3.2 by Robert Ancell
Import upstream version 0.21
136
                // Sometimes there is a JPEG primary image; that's not our first choice
137
                primaryGroup_ = md->groupName();
138
                std::string key = "Exif." + primaryGroup_ + ".JPEGInterchangeFormat";
139
                if (exifData_.findKey(ExifKey(key)) == exifData_.end()) break;
1.2.4 by Mark Purcell
Import upstream version 0.19
140
            }
141
        }
1.3.2 by Robert Ancell
Import upstream version 0.21
142
        return primaryGroup_;
1.2.4 by Mark Purcell
Import upstream version 0.19
143
    }
144
1.1.6 by Jonathan Riddell
Import upstream version 0.17
145
    int TiffImage::pixelWidth() const
146
    {
1.3.2 by Robert Ancell
Import upstream version 0.21
147
        if (pixelWidth_ != 0) return pixelWidth_;
148
1.2.4 by Mark Purcell
Import upstream version 0.19
149
        ExifKey key(std::string("Exif.") + primaryGroup() + std::string(".ImageWidth"));
150
        ExifData::const_iterator imageWidth = exifData_.findKey(key);
1.1.8 by Mark Purcell
Import upstream version 0.18
151
        if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
1.3.2 by Robert Ancell
Import upstream version 0.21
152
            pixelWidth_ = static_cast<int>(imageWidth->toLong());
1.1.6 by Jonathan Riddell
Import upstream version 0.17
153
        }
1.3.2 by Robert Ancell
Import upstream version 0.21
154
        return pixelWidth_;
1.1.6 by Jonathan Riddell
Import upstream version 0.17
155
    }
156
157
    int TiffImage::pixelHeight() const
158
    {
1.3.2 by Robert Ancell
Import upstream version 0.21
159
        if (pixelHeight_ != 0) return pixelHeight_;
160
1.2.4 by Mark Purcell
Import upstream version 0.19
161
        ExifKey key(std::string("Exif.") + primaryGroup() + std::string(".ImageLength"));
162
        ExifData::const_iterator imageHeight = exifData_.findKey(key);
1.1.8 by Mark Purcell
Import upstream version 0.18
163
        if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
1.3.2 by Robert Ancell
Import upstream version 0.21
164
            pixelHeight_ = imageHeight->toLong();
1.1.6 by Jonathan Riddell
Import upstream version 0.17
165
        }
1.3.2 by Robert Ancell
Import upstream version 0.21
166
        return pixelHeight_;
1.1.6 by Jonathan Riddell
Import upstream version 0.17
167
    }
168
1.1.3 by Mark Purcell
Import upstream version 0.14
169
    void TiffImage::setComment(const std::string& /*comment*/)
170
    {
171
        // not supported
172
        throw(Error(32, "Image comment", "TIFF"));
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
173
    }
174
175
    void TiffImage::readMetadata()
176
    {
177
#ifdef DEBUG
178
        std::cerr << "Reading TIFF file " << io_->path() << "\n";
179
#endif
1.1.3 by Mark Purcell
Import upstream version 0.14
180
        if (io_->open() != 0) throw Error(9, io_->path(), strError());
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
181
        IoCloser closer(*io_);
182
        // Ensure that this is the correct image type
1.1.3 by Mark Purcell
Import upstream version 0.14
183
        if (!isTiffType(*io_, false)) {
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
184
            if (io_->error() || io_->eof()) throw Error(14);
1.1.3 by Mark Purcell
Import upstream version 0.14
185
            throw Error(3, "TIFF");
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
186
        }
187
        clearMetadata();
1.1.8 by Mark Purcell
Import upstream version 0.18
188
        ByteOrder bo = TiffParser::decode(exifData_,
189
                                          iptcData_,
190
                                          xmpData_,
191
                                          io_->mmap(),
192
                                          io_->size());
193
        setByteOrder(bo);
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
194
    } // TiffImage::readMetadata
195
196
    void TiffImage::writeMetadata()
197
    {
1.1.8 by Mark Purcell
Import upstream version 0.18
198
#ifdef DEBUG
199
        std::cerr << "Writing TIFF file " << io_->path() << "\n";
200
#endif
201
        ByteOrder bo = byteOrder();
1.2.4 by Mark Purcell
Import upstream version 0.19
202
        byte* pData = 0;
203
        long size = 0;
204
        IoCloser closer(*io_);
1.1.8 by Mark Purcell
Import upstream version 0.18
205
        if (io_->open() == 0) {
206
            // Ensure that this is the correct image type
207
            if (isTiffType(*io_, false)) {
1.2.4 by Mark Purcell
Import upstream version 0.19
208
                pData = io_->mmap(true);
209
                size = io_->size();
1.1.8 by Mark Purcell
Import upstream version 0.18
210
                TiffHeader tiffHeader;
1.2.4 by Mark Purcell
Import upstream version 0.19
211
                if (0 == tiffHeader.read(pData, 8)) {
1.1.8 by Mark Purcell
Import upstream version 0.18
212
                    bo = tiffHeader.byteOrder();
213
                }
214
            }
215
        }
216
        if (bo == invalidByteOrder) {
217
            bo = littleEndian;
218
        }
219
        setByteOrder(bo);
1.2.4 by Mark Purcell
Import upstream version 0.19
220
        TiffParser::encode(*io_, pData, size, bo, exifData_, iptcData_, xmpData_); // may throw
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
221
    } // TiffImage::writeMetadata
222
1.1.8 by Mark Purcell
Import upstream version 0.18
223
    ByteOrder TiffParser::decode(
224
              ExifData& exifData,
225
              IptcData& iptcData,
226
              XmpData&  xmpData,
227
        const byte*     pData,
228
              uint32_t  size
229
    )
230
    {
231
        return TiffParserWorker::decode(exifData,
232
                                        iptcData,
233
                                        xmpData,
234
                                        pData,
235
                                        size,
1.2.2 by Mark Purcell
Import upstream version 0.18.1
236
                                        Tag::root,
1.1.8 by Mark Purcell
Import upstream version 0.18
237
                                        TiffMapping::findDecoder);
238
    } // TiffParser::decode
239
240
    WriteMethod TiffParser::encode(
1.2.4 by Mark Purcell
Import upstream version 0.19
241
              BasicIo&  io,
1.1.8 by Mark Purcell
Import upstream version 0.18
242
        const byte*     pData,
243
              uint32_t  size,
244
              ByteOrder byteOrder,
245
        const ExifData& exifData,
246
        const IptcData& iptcData,
247
        const XmpData&  xmpData
248
    )
249
    {
1.2.2 by Mark Purcell
Import upstream version 0.18.1
250
        // Copy to be able to modify the Exif data
251
        ExifData ed = exifData;
252
253
        // Delete IFDs which do not occur in TIFF images
254
        static const IfdId filteredIfds[] = {
1.3.2 by Robert Ancell
Import upstream version 0.21
255
            panaRawId
1.2.2 by Mark Purcell
Import upstream version 0.18.1
256
        };
257
        for (unsigned int i = 0; i < EXV_COUNTOF(filteredIfds); ++i) {
258
#ifdef DEBUG
259
            std::cerr << "Warning: Exif IFD " << filteredIfds[i] << " not encoded\n";
260
#endif
261
            ed.erase(std::remove_if(ed.begin(),
262
                                    ed.end(),
263
                                    FindExifdatum(filteredIfds[i])),
264
                     ed.end());
265
        }
266
1.1.8 by Mark Purcell
Import upstream version 0.18
267
        std::auto_ptr<TiffHeaderBase> header(new TiffHeader(byteOrder));
1.2.4 by Mark Purcell
Import upstream version 0.19
268
        return TiffParserWorker::encode(io,
1.1.8 by Mark Purcell
Import upstream version 0.18
269
                                        pData,
270
                                        size,
1.2.2 by Mark Purcell
Import upstream version 0.18.1
271
                                        ed,
1.1.8 by Mark Purcell
Import upstream version 0.18
272
                                        iptcData,
273
                                        xmpData,
1.2.2 by Mark Purcell
Import upstream version 0.18.1
274
                                        Tag::root,
1.1.8 by Mark Purcell
Import upstream version 0.18
275
                                        TiffMapping::findEncoder,
276
                                        header.get());
277
    } // TiffParser::encode
278
279
    // *************************************************************************
280
    // free functions
281
    Image::AutoPtr newTiffInstance(BasicIo::AutoPtr io, bool create)
282
    {
283
        Image::AutoPtr image(new TiffImage(io, create));
284
        if (!image->good()) {
285
            image.reset();
286
        }
287
        return image;
288
    }
289
290
    bool isTiffType(BasicIo& iIo, bool advance)
291
    {
292
        const int32_t len = 8;
293
        byte buf[len];
294
        iIo.read(buf, len);
295
        if (iIo.error() || iIo.eof()) {
296
            return false;
297
        }
298
        TiffHeader tiffHeader;
299
        bool rc = tiffHeader.read(buf, len);
300
        if (!advance || !rc) {
301
            iIo.seek(-len, BasicIo::cur);
302
        }
303
        return rc;
304
    }
305
306
}                                       // namespace Exiv2
307
1.2.4 by Mark Purcell
Import upstream version 0.19
308
// Shortcuts for the newTiffBinaryArray templates.
309
#define EXV_BINARY_ARRAY(arrayCfg, arrayDef) (newTiffBinaryArray0<&arrayCfg, EXV_COUNTOF(arrayDef), arrayDef>)
310
#define EXV_SIMPLE_BINARY_ARRAY(arrayCfg) (newTiffBinaryArray1<&arrayCfg>)
311
#define EXV_COMPLEX_BINARY_ARRAY(arraySet, cfgSelFct) (newTiffBinaryArray2<arraySet, EXV_COUNTOF(arraySet), cfgSelFct>)
312
1.1.8 by Mark Purcell
Import upstream version 0.18
313
namespace Exiv2 {
314
    namespace Internal {
315
1.2.4 by Mark Purcell
Import upstream version 0.19
316
    //! Constant for non-encrypted binary arrays
317
    const CryptFct notEncrypted = 0;
318
319
    //! Canon Camera Settings binary array - configuration
320
    extern const ArrayCfg canonCsCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
321
        canonCsId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
322
        invalidByteOrder, // Use byte order from parent
323
        ttUnsignedShort,  // Type for array entry and size element
324
        notEncrypted,     // Not encrypted
325
        true,             // With size element
326
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
327
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
328
        { 0, ttUnsignedShort, 1 }
329
    };
330
    //! Canon Camera Settings binary array - definition
331
    extern const ArrayDef canonCsDef[] = {
332
        { 46, ttUnsignedShort, 3 } // Exif.CanonCs.Lens
333
    };
334
335
    //! Canon Shot Info binary array - configuration
336
    extern const ArrayCfg canonSiCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
337
        canonSiId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
338
        invalidByteOrder, // Use byte order from parent
339
        ttUnsignedShort,  // Type for array entry and size element
340
        notEncrypted,     // Not encrypted
341
        true,             // With size element
342
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
343
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
344
        { 0, ttUnsignedShort, 1 }
345
    };
346
347
    //! Canon Panorama binary array - configuration
348
    extern const ArrayCfg canonPaCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
349
        canonPaId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
350
        invalidByteOrder, // Use byte order from parent
351
        ttUnsignedShort,  // Type for array entry and size element
352
        notEncrypted,     // Not encrypted
353
        false,            // No size element
354
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
355
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
356
        { 0, ttUnsignedShort, 1 }
357
    };
358
359
    //! Canon Custom Function binary array - configuration
360
    extern const ArrayCfg canonCfCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
361
        canonCfId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
362
        invalidByteOrder, // Use byte order from parent
363
        ttUnsignedShort,  // Type for array entry and size element
364
        notEncrypted,     // Not encrypted
365
        true,             // With size element
366
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
367
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
368
        { 0, ttUnsignedShort, 1 }
369
    };
370
371
    //! Canon Picture Info binary array - configuration
372
    extern const ArrayCfg canonPiCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
373
        canonPiId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
374
        invalidByteOrder, // Use byte order from parent
375
        ttUnsignedShort,  // Type for array entry and size element
376
        notEncrypted,     // Not encrypted
377
        false,            // No size element
378
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
379
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
380
        { 0, ttUnsignedShort, 1 }
381
    };
382
383
    //! Canon File Info binary array - configuration
384
    extern const ArrayCfg canonFiCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
385
        canonFiId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
386
        invalidByteOrder, // Use byte order from parent
387
        ttUnsignedShort,  // Type for array entry and size element
388
        notEncrypted,     // Not encrypted
389
        true,             // Has a size element
390
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
391
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
392
        { 0, ttSignedShort, 1 }
393
    };
394
    //! Canon File Info binary array - definition
395
    extern const ArrayDef canonFiDef[] = {
396
        { 2, ttUnsignedLong, 1 }
397
    };
398
1.3.2 by Robert Ancell
Import upstream version 0.21
399
    //! Canon Processing Info binary array - configuration
400
    extern const ArrayCfg canonPrCfg = {
401
        canonPrId,        // Group for the elements
402
        invalidByteOrder, // Use byte order from parent
403
        ttUnsignedShort,  // Type for array entry and size element
404
        notEncrypted,     // Not encrypted
405
        true,             // Has a size element
406
        false,            // No fillers
407
        false,            // Don't concatenate gaps
408
        { 0, ttSignedShort, 1 }
409
    };
410
1.2.4 by Mark Purcell
Import upstream version 0.19
411
    //! Nikon Vibration Reduction binary array - configuration
412
    extern const ArrayCfg nikonVrCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
413
        nikonVrId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
414
        invalidByteOrder, // Use byte order from parent
415
        ttUndefined,      // Type for array entry
416
        notEncrypted,     // Not encrypted
417
        false,            // No size element
418
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
419
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
420
        { 0, ttUnsignedByte,  1 }
421
    };
422
    //! Nikon Vibration Reduction binary array - definition
423
    extern const ArrayDef nikonVrDef[] = {
424
        { 0, ttUndefined,     4 }, // Version
425
        { 7, ttUnsignedByte,  1 }  // The array contains 8 bytes
426
    };
427
428
    //! Nikon Picture Control binary array - configuration
429
    extern const ArrayCfg nikonPcCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
430
        nikonPcId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
431
        invalidByteOrder, // Use byte order from parent
432
        ttUndefined,      // Type for array entry
433
        notEncrypted,     // Not encrypted
434
        false,            // No size element
435
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
436
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
437
        { 0, ttUnsignedByte,  1 }
438
    };
439
    //! Nikon Picture Control binary array - definition
440
    extern const ArrayDef nikonPcDef[] = {
441
        {  0, ttUndefined,     4 }, // Version
442
        {  4, ttAsciiString,  20 },
443
        { 24, ttAsciiString,  20 },
1.3.1 by Mark Purcell
Import upstream version 0.20
444
        { 48, ttUnsignedByte,  1 },
445
        { 49, ttUnsignedByte,  1 },
446
        { 50, ttUnsignedByte,  1 },
447
        { 51, ttUnsignedByte,  1 },
448
        { 52, ttUnsignedByte,  1 },
449
        { 53, ttUnsignedByte,  1 },
450
        { 54, ttUnsignedByte,  1 },
451
        { 55, ttUnsignedByte,  1 },
452
        { 56, ttUnsignedByte,  1 },
1.2.4 by Mark Purcell
Import upstream version 0.19
453
        { 57, ttUnsignedByte,  1 }  // The array contains 58 bytes
454
    };
455
456
    //! Nikon World Time binary array - configuration
457
    extern const ArrayCfg nikonWtCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
458
        nikonWtId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
459
        invalidByteOrder, // Use byte order from parent
460
        ttUndefined,      // Type for array entry
461
        notEncrypted,     // Not encrypted
462
        false,            // No size element
463
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
464
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
465
        { 0, ttUnsignedByte,  1 }
466
    };
467
    //! Nikon World Time binary array - definition
468
    extern const ArrayDef nikonWtDef[] = {
469
        { 0, ttSignedShort,   1 },
1.3.1 by Mark Purcell
Import upstream version 0.20
470
        { 2, ttUnsignedByte,  1 },
1.2.4 by Mark Purcell
Import upstream version 0.19
471
        { 3, ttUnsignedByte,  1 }
472
    };
473
474
    //! Nikon ISO info binary array - configuration
475
    extern const ArrayCfg nikonIiCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
476
        nikonIiId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
477
        bigEndian,        // Byte order
478
        ttUndefined,      // Type for array entry
479
        notEncrypted,     // Not encrypted
480
        false,            // No size element
481
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
482
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
483
        { 0, ttUnsignedByte,  1 }
484
    };
485
    //! Nikon ISO info binary array - definition
486
    extern const ArrayDef nikonIiDef[] = {
1.3.1 by Mark Purcell
Import upstream version 0.20
487
        {  0, ttUnsignedByte,  1 },
1.2.4 by Mark Purcell
Import upstream version 0.19
488
        {  4, ttUnsignedShort, 1 },
1.3.1 by Mark Purcell
Import upstream version 0.20
489
        {  6, ttUnsignedByte,  1 },
1.2.4 by Mark Purcell
Import upstream version 0.19
490
        { 10, ttUnsignedShort, 1 },
491
        { 13, ttUnsignedByte,  1 }  // The array contains 14 bytes
492
    };
493
494
    //! Nikon Auto Focus binary array - configuration
495
    extern const ArrayCfg nikonAfCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
496
        nikonAfId,        // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
497
        littleEndian,     // Byte order
498
        ttUndefined,      // Type for array entry
499
        notEncrypted,     // Not encrypted
500
        false,            // No size element
501
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
502
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
503
        { 0, ttUnsignedByte,  1 }
504
    };
505
    //! Nikon Auto Focus binary array - definition
506
    extern const ArrayDef nikonAfDef[] = {
1.3.1 by Mark Purcell
Import upstream version 0.20
507
        { 0, ttUnsignedByte,  1 },
508
        { 1, ttUnsignedByte,  1 },
1.2.4 by Mark Purcell
Import upstream version 0.19
509
        { 2, ttUnsignedShort, 1 } // The array contains 4 bytes
510
    };
511
1.3.1 by Mark Purcell
Import upstream version 0.20
512
    //! Nikon Auto Focus 2 binary array - configuration
513
    extern const ArrayCfg nikonAf2Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
514
        nikonAf2Id,       // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
515
        littleEndian,     // Byte order
516
        ttUndefined,      // Type for array entry
517
        notEncrypted,     // Not encrypted
518
        false,            // No size element
519
        true,             // Write all tags
520
        true,             // Concatenate gaps
521
        { 0, ttUnsignedByte,  1 }
522
    };
523
    //! Nikon Auto Focus 2 binary array - definition
524
    extern const ArrayDef nikonAf2Def[] = {
525
        {  0, ttUndefined,     4 }, // Version
526
        {  4, ttUnsignedByte,  1 }, // ContrastDetectAF
527
        {  5, ttUnsignedByte,  1 }, // AFAreaMode
528
        {  6, ttUnsignedByte,  1 }, // PhaseDetectAF
529
        {  7, ttUnsignedByte,  1 }, // PrimaryAFPoint
530
        {  8, ttUnsignedByte,  7 }, // AFPointsUsed
531
        { 16, ttUnsignedShort, 1 }, // AFImageWidth
532
        { 18, ttUnsignedShort, 1 }, // AFImageHeight
533
        { 20, ttUnsignedShort, 1 }, // AFAreaXPosition
534
        { 22, ttUnsignedShort, 1 }, // AFAreaYPosition
535
        { 24, ttUnsignedShort, 1 }, // AFAreaWidth
536
        { 26, ttUnsignedShort, 1 }, // AFAreaHeight
537
        { 28, ttUnsignedShort, 1 }, // ContrastDetectAFInFocus
538
    };
539
540
    //! Nikon File Info binary array - configuration
541
    extern const ArrayCfg nikonFiCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
542
        nikonFiId,        // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
543
        littleEndian,     // Byte order
544
        ttUndefined,      // Type for array entry
545
        notEncrypted,     // Not encrypted
546
        false,            // No size element
547
        true,             // Write all tags
548
        true,             // Concatenate gaps
549
        { 0, ttUnsignedByte,  1 }
550
    };
551
    //! Nikon File Info binary array - definition
552
    extern const ArrayDef nikonFiDef[] = {
553
        { 0, ttUndefined,     4 }, // Version
554
        { 6, ttUnsignedShort, 1 }, // Directory Number
555
        { 8, ttUnsignedShort, 1 }  // File Number
556
    };
557
558
    //! Nikon Multi Exposure binary array - configuration
559
    extern const ArrayCfg nikonMeCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
560
        nikonMeId,        // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
561
        littleEndian,     // Byte order
562
        ttUndefined,      // Type for array entry
563
        notEncrypted,     // Not encrypted
564
        false,            // No size element
565
        true,             // Write all tags
566
        true,             // Concatenate gaps
567
        { 0, ttUnsignedByte,  1 }
568
    };
569
    //! Nikon Multi Exposure binary array - definition
570
    extern const ArrayDef nikonMeDef[] = {
571
        {  0, ttUndefined,     4 }, // Version
572
        {  4, ttUnsignedLong,  1 }, // MultiExposureMode
573
        {  8, ttUnsignedLong,  1 }, // MultiExposureShots
574
        { 12, ttUnsignedLong,  1 }  // MultiExposureAutoGain
575
    };
576
577
    //! Nikon Flash Info binary array - configuration 1
578
    extern const ArrayCfg nikonFl1Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
579
        nikonFl1Id,       // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
580
        littleEndian,     // Byte order
581
        ttUndefined,      // Type for array entry
582
        notEncrypted,     // Not encrypted
583
        false,            // No size element
584
        true,             // Write all tags
585
        true,             // Concatenate gaps
586
        { 0, ttUnsignedByte,  1 }
587
    };
588
    //! Nikon Flash Info binary array - definition 1
589
    extern const ArrayDef nikonFl1Def[] = {
590
        {  0, ttUndefined,     4 }, // Version
591
        {  4, ttUnsignedByte,  1 }, // FlashSource
592
        {  6, ttUnsignedShort, 1 }, // ExternalFlashFirmware
593
        {  8, ttUnsignedByte,  1 }, // ExternalFlashFlags
594
        { 11, ttUnsignedByte,  1 }, // FlashFocalLength
595
        { 12, ttUnsignedByte,  1 }, // RepeatingFlashRate
596
        { 13, ttUnsignedByte,  1 }, // RepeatingFlashCount
597
        { 14, ttUnsignedByte,  1 }, // FlashGNDistance
598
        { 15, ttUnsignedByte,  1 }, // FlashGroupAControlMode
1.3.2 by Robert Ancell
Import upstream version 0.21
599
        { 16, ttUnsignedByte,  1 }  // FlashGroupBControlMode
1.3.1 by Mark Purcell
Import upstream version 0.20
600
    };
601
    //! Nikon Flash Info binary array - configuration 2
602
    extern const ArrayCfg nikonFl2Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
603
        nikonFl2Id,       // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
604
        littleEndian,     // Byte order
605
        ttUndefined,      // Type for array entry
606
        notEncrypted,     // Not encrypted
607
        false,            // No size element
608
        true,             // Write all tags
609
        true,             // Concatenate gaps
610
        { 0, ttUnsignedByte,  1 }
611
    };
612
    //! Nikon Flash Info binary array - definition 2
613
    extern const ArrayDef nikonFl2Def[] = {
614
        {  0, ttUndefined,     4 }, // Version
615
        {  4, ttUnsignedByte,  1 }, // FlashSource
616
        {  6, ttUnsignedShort, 1 }, // ExternalFlashFirmware
617
        {  8, ttUnsignedByte,  1 }, // ExternalFlashFlags
618
        { 12, ttUnsignedByte,  1 }, // FlashFocalLength
619
        { 13, ttUnsignedByte,  1 }, // RepeatingFlashRate
620
        { 14, ttUnsignedByte,  1 }, // RepeatingFlashCount
621
        { 15, ttUnsignedByte,  1 }, // FlashGNDistance
622
    };
623
    //! Nikon Flash Info binary array - configuration 3
624
    extern const ArrayCfg nikonFl3Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
625
        nikonFl3Id,       // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
626
        littleEndian,     // Byte order
627
        ttUndefined,      // Type for array entry
628
        notEncrypted,     // Not encrypted
629
        false,            // No size element
630
        true,             // Write all tags
631
        true,             // Concatenate gaps
632
        { 0, ttUnsignedByte,  1 }
633
    };
634
    //! Nikon Flash Info binary array - definition
635
    extern const ArrayDef nikonFl3Def[] = {
636
        {  0, ttUndefined,     4 }, // Version
637
        {  4, ttUnsignedByte,  1 }, // FlashSource
638
        {  6, ttUnsignedShort, 1 }, // ExternalFlashFirmware
639
        {  8, ttUnsignedByte,  1 }, // ExternalFlashFlags
640
        { 12, ttUnsignedByte,  1 }, // FlashFocalLength
641
        { 13, ttUnsignedByte,  1 }, // RepeatingFlashRate
642
        { 14, ttUnsignedByte,  1 }, // RepeatingFlashCount
643
        { 15, ttUnsignedByte,  1 }, // FlashGNDistance
644
        { 16, ttUnsignedByte,  1 }, // FlashColorFilter
645
    };
646
    //! Nikon Lens Data configurations and definitions
647
    extern const ArraySet nikonFlSet[] = {
648
        { nikonFl1Cfg, nikonFl1Def, EXV_COUNTOF(nikonFl1Def) },
649
        { nikonFl2Cfg, nikonFl2Def, EXV_COUNTOF(nikonFl2Def) },
650
        { nikonFl3Cfg, nikonFl3Def, EXV_COUNTOF(nikonFl3Def) }
651
    };
652
1.2.4 by Mark Purcell
Import upstream version 0.19
653
    //! Nikon Shot Info binary array - configuration 1 (D80)
654
    extern const ArrayCfg nikonSi1Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
655
        nikonSi1Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
656
        bigEndian,        // Use byte order from parent
657
        ttUndefined,      // Type for array entry
658
        nikonCrypt,       // Encryption function
659
        false,            // No size element
660
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
661
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
662
        { 0, ttUnsignedByte,  1 }
663
    };
664
    //! Nikon Shot Info binary array - definition 1 (D80)
665
    extern const ArrayDef nikonSi1Def[] = {
666
        {    0, ttUndefined,    4 }, // Version
667
        {  586, ttUnsignedLong, 1 }, // ShutterCount
668
        { 1155, ttUnsignedByte, 1 }  // The array contains 1156 bytes
669
    };
670
    //! Nikon Shot Info binary array - configuration 2 (D40)
671
    extern const ArrayCfg nikonSi2Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
672
        nikonSi2Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
673
        bigEndian,        // Use byte order from parent
674
        ttUndefined,      // Type for array entry
675
        nikonCrypt,       // Encryption function
676
        false,            // No size element
677
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
678
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
679
        { 0, ttUnsignedByte,  1 }
680
    };
681
    //! Nikon Shot Info binary array - definition 2 (D40)
682
    extern const ArrayDef nikonSi2Def[] = {
683
        {    0, ttUndefined,    4 }, // Version
684
        {  582, ttUnsignedLong, 1 }, // ShutterCount
1.3.1 by Mark Purcell
Import upstream version 0.20
685
        {  738, ttUnsignedByte, 1 },
1.2.4 by Mark Purcell
Import upstream version 0.19
686
        { 1112, ttUnsignedByte, 1 }  // The array contains 1113 bytes
687
    };
688
    //! Nikon Shot Info binary array - configuration 3 (D300a)
689
    extern const ArrayCfg nikonSi3Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
690
        nikonSi3Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
691
        bigEndian,        // Use byte order from parent
692
        ttUndefined,      // Type for array entry
693
        nikonCrypt,       // Encryption function
694
        false,            // No size element
695
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
696
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
697
        { 0, ttUnsignedByte,  1 }
698
    };
699
    //! Nikon Shot Info binary array - definition 3 (D300a)
700
    extern const ArrayDef nikonSi3Def[] = {
701
        {    0, ttUndefined,     4 }, // Version
1.3.1 by Mark Purcell
Import upstream version 0.20
702
        {  604, ttUnsignedByte,  1 }, // ISO
1.2.4 by Mark Purcell
Import upstream version 0.19
703
        {  633, ttUnsignedLong,  1 }, // ShutterCount
704
        {  721, ttUnsignedShort, 1 }, // AFFineTuneAdj
705
        {  814, ttUndefined,  4478 }  // The array contains 5291 bytes
706
    };
707
    //! Nikon Shot Info binary array - configuration 4 (D300b)
708
    extern const ArrayCfg nikonSi4Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
709
        nikonSi4Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
710
        bigEndian,        // Use byte order from parent
711
        ttUndefined,      // Type for array entry
712
        nikonCrypt,       // Encryption function
713
        false,            // No size element
714
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
715
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
716
        { 0, ttUnsignedByte,  1 }
717
    };
718
    //! Nikon Shot Info binary array - definition 4 (D300b)
719
    extern const ArrayDef nikonSi4Def[] = {
720
        {    0, ttUndefined,     4 }, // Version
721
        {  644, ttUnsignedLong,  1 }, // ShutterCount
722
        {  732, ttUnsignedShort, 1 }, // AFFineTuneAdj
723
        {  826, ttUndefined,  4478 }  // The array contains 5303 bytes
724
    };
725
    //! Nikon Shot Info binary array - configuration 5 (ver 02.xx)
726
    extern const ArrayCfg nikonSi5Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
727
        nikonSi5Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
728
        bigEndian,        // Use byte order from parent
729
        ttUndefined,      // Type for array entry
730
        nikonCrypt,       // Encryption function
731
        false,            // No size element
732
        false,            // Write all tags (don't know how many)
1.3.1 by Mark Purcell
Import upstream version 0.20
733
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
734
        { 0, ttUnsignedByte,  1 }
735
    };
736
    //! Nikon Shot Info binary array - definition 5 (ver 01.xx and ver 02.xx)
737
    extern const ArrayDef nikonSi5Def[] = {
738
        {    0, ttUndefined,     4 }, // Version
1.3.1 by Mark Purcell
Import upstream version 0.20
739
        {  106, ttUnsignedLong,  1 }, // ShutterCount1
1.2.4 by Mark Purcell
Import upstream version 0.19
740
        {  110, ttUnsignedLong,  1 }, // DeletedImageCount
1.3.1 by Mark Purcell
Import upstream version 0.20
741
        {  117, ttUnsignedByte,  1 }, // VibrationReduction
742
        {  130, ttUnsignedByte,  1 }, // VibrationReduction1
1.2.4 by Mark Purcell
Import upstream version 0.19
743
        {  343, ttUndefined,     2 }, // ShutterCount
1.3.1 by Mark Purcell
Import upstream version 0.20
744
        {  430, ttUnsignedByte,  1 }, // VibrationReduction2
745
        {  598, ttUnsignedByte,  1 }, // ISO
1.2.4 by Mark Purcell
Import upstream version 0.19
746
        {  630, ttUnsignedLong,  1 }  // ShutterCount
747
    };
748
    //! Nikon Shot Info binary array - configuration 6 (ver 01.xx)
749
    extern const ArrayCfg nikonSi6Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
750
        nikonSi6Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
751
        bigEndian,        // Use byte order from parent
752
        ttUndefined,      // Type for array entry
753
        notEncrypted,     // Encryption function
754
        false,            // No size element
755
        false,            // Write all tags (don't know how many)
1.3.1 by Mark Purcell
Import upstream version 0.20
756
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
757
        { 0, ttUnsignedByte,  1 }
758
    };
759
    //! Nikon Lens Data configurations and definitions
760
    extern const ArraySet nikonSiSet[] = {
761
        { nikonSi1Cfg, nikonSi1Def, EXV_COUNTOF(nikonSi1Def) },
762
        { nikonSi2Cfg, nikonSi2Def, EXV_COUNTOF(nikonSi2Def) },
763
        { nikonSi3Cfg, nikonSi3Def, EXV_COUNTOF(nikonSi3Def) },
764
        { nikonSi4Cfg, nikonSi4Def, EXV_COUNTOF(nikonSi4Def) },
765
        { nikonSi5Cfg, nikonSi5Def, EXV_COUNTOF(nikonSi5Def) },
766
        { nikonSi6Cfg, nikonSi5Def, EXV_COUNTOF(nikonSi5Def) }  // uses nikonSi5Def
767
    };
768
769
    //! Nikon Lens Data binary array - configuration 1
770
    extern const ArrayCfg nikonLd1Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
771
        nikonLd1Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
772
        invalidByteOrder, // Use byte order from parent
773
        ttUndefined,      // Type for array entry
774
        notEncrypted,     // Encryption function
775
        false,            // No size element
776
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
777
        false,            // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
778
        { 0, ttUnsignedByte,  1 }
779
    };
780
    //! Nikon Lens Data binary array - configuration 2
781
    extern const ArrayCfg nikonLd2Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
782
        nikonLd2Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
783
        invalidByteOrder, // Use byte order from parent
784
        ttUndefined,      // Type for array entry
785
        nikonCrypt,       // Encryption function
786
        false,            // No size element
787
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
788
        false,            // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
789
        { 0, ttUnsignedByte,  1 }
790
    };
791
    //! Nikon Lens Data binary array - configuration 3
792
    extern const ArrayCfg nikonLd3Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
793
        nikonLd3Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
794
        invalidByteOrder, // Use byte order from parent
795
        ttUndefined,      // Type for array entry
796
        nikonCrypt,       // Encryption function
797
        false,            // No size element
798
        true,             // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
799
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
800
        { 0, ttUnsignedByte,  1 }
801
    };
802
    //! Nikon Lens Data binary array - definition
803
    extern const ArrayDef nikonLdDef[] = {
804
        { 0, ttUndefined, 4 } // Version
805
    };
806
    //! Nikon Lens Data configurations and definitions
807
    extern const ArraySet nikonLdSet[] = {
808
        { nikonLd1Cfg, nikonLdDef, EXV_COUNTOF(nikonLdDef) },
809
        { nikonLd2Cfg, nikonLdDef, EXV_COUNTOF(nikonLdDef) },
810
        { nikonLd3Cfg, nikonLdDef, EXV_COUNTOF(nikonLdDef) }
811
    };
812
813
    //! Nikon Color Balance binary array - configuration 1
814
    extern const ArrayCfg nikonCb1Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
815
        nikonCb1Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
816
        invalidByteOrder, // Use byte order from parent
817
        ttUndefined,      // Type for array entry
818
        notEncrypted,     // Encryption function
819
        false,            // No size element
820
        false,            // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
821
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
822
        { 0, ttUnsignedShort, 1 }
823
    };
824
    //! Nikon Color Balance binary array - configuration 2
825
    extern const ArrayCfg nikonCb2Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
826
        nikonCb2Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
827
        invalidByteOrder, // Use byte order from parent
828
        ttUndefined,      // Type for array entry
829
        nikonCrypt,       // Encryption function
830
        false,            // No size element
831
        false,            // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
832
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
833
        { 0, ttUnsignedShort, 1 }
834
    };
835
    //! Nikon Color Balance binary array - configuration 2a
836
    extern const ArrayCfg nikonCb2aCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
837
        nikonCb2aId,      // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
838
        invalidByteOrder, // Use byte order from parent
839
        ttUndefined,      // Type for array entry
840
        nikonCrypt,       // Encryption function
841
        false,            // No size element
842
        false,            // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
843
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
844
        { 0, ttUnsignedShort, 1 }
845
    };
846
    //! Nikon Color Balance binary array - configuration 2b
847
    extern const ArrayCfg nikonCb2bCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
848
        nikonCb2bId,      // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
849
        invalidByteOrder, // Use byte order from parent
850
        ttUndefined,      // Type for array entry
851
        nikonCrypt,       // Encryption function
852
        false,            // No size element
853
        false,            // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
854
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
855
        { 0, ttUnsignedShort, 1 }
856
    };
857
    //! Nikon Color Balance binary array - configuration 3
858
    extern const ArrayCfg nikonCb3Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
859
        nikonCb3Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
860
        invalidByteOrder, // Use byte order from parent
861
        ttUndefined,      // Type for array entry
862
        notEncrypted,     // Encryption function
863
        false,            // No size element
864
        false,            // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
865
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
866
        { 0, ttUnsignedShort, 1 }
867
    };
868
    //! Nikon Color Balance binary array - configuration 4
869
    extern const ArrayCfg nikonCb4Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
870
        nikonCb4Id,       // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
871
        invalidByteOrder, // Use byte order from parent
872
        ttUndefined,      // Type for array entry
873
        nikonCrypt,       // Encryption function
874
        false,            // No size element
875
        false,            // Write all tags
1.3.1 by Mark Purcell
Import upstream version 0.20
876
        true,             // Concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
877
        { 0, ttUnsignedShort, 1 }
878
    };
879
    //! Nikon Color Balance binary array - definition 1 (D100)
880
    extern const ArrayDef nikonCb1Def[] = {
881
        {  0, ttUndefined,        4 }, // Version
1.3.1 by Mark Purcell
Import upstream version 0.20
882
        { 72, ttUnsignedShort,    4 }  // Color balance levels
1.2.4 by Mark Purcell
Import upstream version 0.19
883
    };
884
    //! Nikon Color Balance binary array - definition 2 (D2H)
885
    extern const ArrayDef nikonCb2Def[] = {
886
        {  0, ttUndefined,        4 }, // Version
1.3.1 by Mark Purcell
Import upstream version 0.20
887
        { 10, ttUnsignedShort,    4 }  // Color balance levels
1.2.4 by Mark Purcell
Import upstream version 0.19
888
    };
889
    //! Nikon Color Balance binary array - definition 2a (D50)
890
    extern const ArrayDef nikonCb2aDef[] = {
891
        {  0, ttUndefined,        4 }, // Version
1.3.1 by Mark Purcell
Import upstream version 0.20
892
        { 18, ttUnsignedShort,    4 }  // Color balance levels
1.2.4 by Mark Purcell
Import upstream version 0.19
893
    };
894
    //! Nikon Color Balance binary array - definition 2b (D2X=0204,D2Hs=0206,D200=0207,D40=0208)
895
    extern const ArrayDef nikonCb2bDef[] = {
896
        {  0, ttUndefined,        4 }, // Version
897
        {  4, ttUnsignedShort,  140 }, // Unknown
898
        {284, ttUnsignedShort,    3 }, // Unknown (encrypted)
1.3.1 by Mark Purcell
Import upstream version 0.20
899
        {290, ttUnsignedShort,    4 }  // Color balance levels
1.2.4 by Mark Purcell
Import upstream version 0.19
900
    };
901
    //! Nikon Color Balance binary array - definition 3 (D70)
902
    extern const ArrayDef nikonCb3Def[] = {
903
        {  0, ttUndefined,        4 }, // Version
1.3.1 by Mark Purcell
Import upstream version 0.20
904
        { 20, ttUnsignedShort,    4 }  // Color balance levels
1.2.4 by Mark Purcell
Import upstream version 0.19
905
    };
906
    //! Nikon Color Balance binary array - definition 4 (D3)
907
    extern const ArrayDef nikonCb4Def[] = {
908
        {  0, ttUndefined,        4 }, // Version
909
        {  4, ttUnsignedShort,  140 }, // Unknown
910
        {284, ttUnsignedShort,    5 }, // Unknown (encrypted)
1.3.1 by Mark Purcell
Import upstream version 0.20
911
        {294, ttUnsignedShort,    4 }  // Color balance levels
1.2.4 by Mark Purcell
Import upstream version 0.19
912
    };
913
    //! Nikon Color Balance configurations and definitions
914
    extern const ArraySet nikonCbSet[] = {
915
        { nikonCb1Cfg,  nikonCb1Def,  EXV_COUNTOF(nikonCb1Def)  },
916
        { nikonCb2Cfg,  nikonCb2Def,  EXV_COUNTOF(nikonCb2Def)  },
917
        { nikonCb2aCfg, nikonCb2aDef, EXV_COUNTOF(nikonCb2aDef) },
918
        { nikonCb2bCfg, nikonCb2bDef, EXV_COUNTOF(nikonCb2bDef) },
919
        { nikonCb3Cfg,  nikonCb3Def,  EXV_COUNTOF(nikonCb3Def)  },
920
        { nikonCb4Cfg,  nikonCb4Def,  EXV_COUNTOF(nikonCb4Def)  }
921
    };
922
923
    //! Minolta Camera Settings (old) binary array - configuration
924
    extern const ArrayCfg minoCsoCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
925
        minoltaCsOldId,   // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
926
        bigEndian,        // Big endian
927
        ttUndefined,      // Type for array entry and size element
928
        notEncrypted,     // Not encrypted
929
        false,            // No size element
930
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
931
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
932
        { 0, ttUnsignedLong, 1 }
933
    };
934
935
    //! Minolta Camera Settings (new) binary array - configuration
936
    extern const ArrayCfg minoCsnCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
937
        minoltaCsNewId,   // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
938
        bigEndian,        // Big endian
939
        ttUndefined,      // Type for array entry and size element
940
        notEncrypted,     // Not encrypted
941
        false,            // No size element
942
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
943
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
944
        { 0, ttUnsignedLong, 1 }
945
    };
946
947
    //! Minolta 7D Camera Settings binary array - configuration
948
    extern const ArrayCfg minoCs7Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
949
        minoltaCs7DId,    // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
950
        bigEndian,        // Big endian
951
        ttUndefined,      // Type for array entry and size element
952
        notEncrypted,     // Not encrypted
953
        false,            // No size element
954
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
955
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
956
        { 0, ttUnsignedShort, 1 }
957
    };
958
    //! Minolta 7D Camera Settings binary array - definition
959
    extern const ArrayDef minoCs7Def[] = {
960
        {  60, ttSignedShort, 1 }, // Exif.MinoltaCs7D.ExposureCompensation
961
        { 126, ttSignedShort, 1 }  // Exif.MinoltaCs7D.ColorTemperature
962
    };
963
964
    //! Minolta 5D Camera Settings binary array - configuration
965
    extern const ArrayCfg minoCs5Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
966
        minoltaCs5DId,    // Group for the elements
1.2.4 by Mark Purcell
Import upstream version 0.19
967
        bigEndian,        // Big endian
968
        ttUndefined,      // Type for array entry and size element
969
        notEncrypted,     // Not encrypted
970
        false,            // No size element
971
        false,            // No fillers
1.3.1 by Mark Purcell
Import upstream version 0.20
972
        false,            // Don't concatenate gaps
1.2.4 by Mark Purcell
Import upstream version 0.19
973
        { 0, ttUnsignedShort, 1 }
974
    };
975
    //! Minolta 5D Camera Settings binary array - definition
976
    extern const ArrayDef minoCs5Def[] = {
977
        { 146, ttSignedShort, 1 } // Exif.MinoltaCs5D.ColorTemperature
978
    };
979
1.3.1 by Mark Purcell
Import upstream version 0.20
980
    // Todo: Performance of the handling of Sony Camera Settings can be
981
    //       improved by defining all known array elements in the definitions
982
    //       sonyCsDef and sonyCs2Def below and enabling the 'concatenate gaps'
983
    //       setting in all four configurations.
984
985
    //! Sony1 Camera Settings binary array - configuration
986
    extern const ArrayCfg sony1CsCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
987
        sony1CsId,        // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
988
        bigEndian,        // Big endian
989
        ttUndefined,      // Type for array entry and size element
990
        notEncrypted,     // Not encrypted
991
        false,            // No size element
992
        false,            // No fillers
993
        false,            // Don't concatenate gaps
994
        { 0, ttUnsignedShort, 1 }
995
    };
996
    //! Sony1 Camera Settings 2 binary array - configuration
997
    extern const ArrayCfg sony1Cs2Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
998
        sony1Cs2Id,       // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
999
        bigEndian,        // Big endian
1000
        ttUndefined,      // Type for array entry and size element
1001
        notEncrypted,     // Not encrypted
1002
        false,            // No size element
1003
        false,            // No fillers
1004
        false,            // Don't concatenate gaps
1005
        { 0, ttUnsignedShort, 1 }
1006
    };
1007
    //! Sony[12] Camera Settings binary array - definition
1008
    extern const ArrayDef sonyCsDef[] = {
1009
        {  12, ttSignedShort,   1 }  // Exif.Sony[12]Cs.WhiteBalanceFineTune
1010
    };
1011
    //! Sony2 Camera Settings binary array - configuration
1012
    extern const ArrayCfg sony2CsCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
1013
        sony2CsId,        // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
1014
        bigEndian,        // Big endian
1015
        ttUndefined,      // Type for array entry and size element
1016
        notEncrypted,     // Not encrypted
1017
        false,            // No size element
1018
        false,            // No fillers
1019
        false,            // Don't concatenate gaps
1020
        { 0, ttUnsignedShort, 1 }
1021
    };
1022
    //! Sony2 Camera Settings 2 binary array - configuration
1023
    extern const ArrayCfg sony2Cs2Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
1024
        sony2Cs2Id,       // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
1025
        bigEndian,        // Big endian
1026
        ttUndefined,      // Type for array entry and size element
1027
        notEncrypted,     // Not encrypted
1028
        false,            // No size element
1029
        false,            // No fillers
1030
        false,            // Don't concatenate gaps
1031
        { 0, ttUnsignedShort, 1 }
1032
    };
1033
    //! Sony[12] Camera Settings 2 binary array - definition
1034
    extern const ArrayDef sonyCs2Def[] = {
1035
        {  44, ttUnsignedShort, 1 } // Exif.Sony[12]Cs2.FocusMode
1036
    };
1037
    //! Sony1 Camera Settings configurations and definitions
1038
    extern const ArraySet sony1CsSet[] = {
1039
        { sony1CsCfg,  sonyCsDef,  EXV_COUNTOF(sonyCsDef)  },
1040
        { sony1Cs2Cfg, sonyCs2Def, EXV_COUNTOF(sonyCs2Def) }
1041
    };
1042
    //! Sony2 Camera Settings configurations and definitions
1043
    extern const ArraySet sony2CsSet[] = {
1044
        { sony2CsCfg,  sonyCsDef,  EXV_COUNTOF(sonyCsDef)  },
1045
        { sony2Cs2Cfg, sonyCs2Def, EXV_COUNTOF(sonyCs2Def) }
1046
    };
1047
1048
    //! Sony Minolta Camera Settings (old) binary array - configuration
1049
    extern const ArrayCfg sony1MCsoCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
1050
        sony1MltCsOldId,  // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
1051
        bigEndian,        // Big endian
1052
        ttUndefined,      // Type for array entry and size element
1053
        notEncrypted,     // Not encrypted
1054
        false,            // No size element
1055
        false,            // No fillers
1056
        false,            // Don't concatenate gaps
1057
        { 0, ttUnsignedLong, 1 }
1058
    };
1059
1060
    //! Sony Minolta Camera Settings (new) binary array - configuration
1061
    extern const ArrayCfg sony1MCsnCfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
1062
        sony1MltCsNewId,  // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
1063
        bigEndian,        // Big endian
1064
        ttUndefined,      // Type for array entry and size element
1065
        notEncrypted,     // Not encrypted
1066
        false,            // No size element
1067
        false,            // No fillers
1068
        false,            // Don't concatenate gaps
1069
        { 0, ttUnsignedLong, 1 }
1070
    };
1071
1072
    //! Sony Minolta 7D Camera Settings binary array - configuration
1073
    extern const ArrayCfg sony1MCs7Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
1074
        sony1MltCs7DId,   // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
1075
        bigEndian,        // Big endian
1076
        ttUndefined,      // Type for array entry and size element
1077
        notEncrypted,     // Not encrypted
1078
        false,            // No size element
1079
        false,            // No fillers
1080
        false,            // Don't concatenate gaps
1081
        { 0, ttUnsignedShort, 1 }
1082
    };
1083
1084
    //! Sony Minolta A100 Camera Settings binary array - configuration
1085
    extern const ArrayCfg sony1MCsA100Cfg = {
1.3.2 by Robert Ancell
Import upstream version 0.21
1086
        sony1MltCsA100Id, // Group for the elements
1.3.1 by Mark Purcell
Import upstream version 0.20
1087
        bigEndian,        // Big endian
1088
        ttUndefined,      // Type for array entry and size element
1089
        notEncrypted,     // Not encrypted
1090
        false,            // No size element
1091
        false,            // No fillers
1092
        false,            // Don't concatenate gaps
1093
        { 0, ttUnsignedShort, 1 }
1094
    };
1095
    //! Sony Minolta A100 Camera Settings binary array - definition
1096
    extern const ArrayDef sony1MCsA100Def[] = {
1097
        { 112, ttSignedShort, 1 }, // Exif.Sony1MltCsA100.WhiteBalanceFineTune
1098
        { 116, ttSignedShort, 1 }, // Exif.Sony1MltCsA100.ColorCompensationFilter
1099
        { 190, ttSignedShort, 1 }  // Exif.Sony1MltCsA100.ColorCompensationFilter2
1100
    };
1101
1.2.4 by Mark Purcell
Import upstream version 0.19
1102
    /*
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1103
      This table lists for each group in a tree, its parent group and tag.
1104
      Root identifies the root of a TIFF tree, as there is a need for multiple
1105
      trees. Groups are the nodes of a TIFF tree. A group is an IFD or any
1106
      other composite component.
1107
1108
      With this table, it is possible, for a given group (and tag) to find a
1109
      path, i.e., a list of groups and tags, from the root to that group (tag).
1110
    */
1111
    const TiffTreeStruct TiffCreator::tiffTreeStruct_[] = {
1.2.4 by Mark Purcell
Import upstream version 0.19
1112
        // root      group             parent group      parent tag
1113
        //---------  ----------------- ----------------- ----------
1.3.2 by Robert Ancell
Import upstream version 0.21
1114
        { Tag::root, ifdIdNotSet,      ifdIdNotSet,      Tag::root },
1115
        { Tag::root, ifd0Id,           ifdIdNotSet,      Tag::root },
1116
        { Tag::root, subImage1Id,      ifd0Id,           0x014a    },
1117
        { Tag::root, subImage2Id,      ifd0Id,           0x014a    },
1118
        { Tag::root, subImage3Id,      ifd0Id,           0x014a    },
1119
        { Tag::root, subImage4Id,      ifd0Id,           0x014a    },
1120
        { Tag::root, subImage5Id,      ifd0Id,           0x014a    },
1121
        { Tag::root, subImage6Id,      ifd0Id,           0x014a    },
1122
        { Tag::root, subImage7Id,      ifd0Id,           0x014a    },
1123
        { Tag::root, subImage8Id,      ifd0Id,           0x014a    },
1124
        { Tag::root, subImage9Id,      ifd0Id,           0x014a    },
1125
        { Tag::root, exifId,           ifd0Id,           0x8769    },
1126
        { Tag::root, gpsId,            ifd0Id,           0x8825    },
1127
        { Tag::root, iopId,            exifId,           0xa005    },
1128
        { Tag::root, ifd1Id,           ifd0Id,           Tag::next },
1129
        { Tag::root, ifd2Id,           ifd1Id,           Tag::next },
1130
        { Tag::root, ifd3Id,           ifd2Id,           Tag::next },
1131
        { Tag::root, olympusId,        exifId,           0x927c    },
1132
        { Tag::root, olympus2Id,       exifId,           0x927c    },
1133
        { Tag::root, subThumb1Id,      ifd1Id,           0x014a    },
1134
        { Tag::root, olympusEqId,      olympus2Id,       0x2010    },
1135
        { Tag::root, olympusCsId,      olympus2Id,       0x2020    },
1136
        { Tag::root, olympusRdId,      olympus2Id,       0x2030    },
1137
        { Tag::root, olympusRd2Id,     olympus2Id,       0x2031    },
1138
        { Tag::root, olympusIpId,      olympus2Id,       0x2040    },
1139
        { Tag::root, olympusFiId,      olympus2Id,       0x2050    },
1140
        { Tag::root, olympusFe1Id,     olympus2Id,       0x2100    },
1141
        { Tag::root, olympusFe2Id,     olympus2Id,       0x2200    },
1142
        { Tag::root, olympusFe3Id,     olympus2Id,       0x2300    },
1143
        { Tag::root, olympusFe4Id,     olympus2Id,       0x2400    },
1144
        { Tag::root, olympusFe5Id,     olympus2Id,       0x2500    },
1145
        { Tag::root, olympusFe6Id,     olympus2Id,       0x2600    },
1146
        { Tag::root, olympusFe7Id,     olympus2Id,       0x2700    },
1147
        { Tag::root, olympusFe8Id,     olympus2Id,       0x2800    },
1148
        { Tag::root, olympusFe9Id,     olympus2Id,       0x2900    },
1149
        { Tag::root, olympusRiId,      olympus2Id,       0x3000    },
1150
        { Tag::root, fujiId,           exifId,           0x927c    },
1151
        { Tag::root, canonId,          exifId,           0x927c    },
1152
        { Tag::root, canonCsId,        canonId,          0x0001    },
1153
        { Tag::root, canonSiId,        canonId,          0x0004    },
1154
        { Tag::root, canonPaId,        canonId,          0x0005    },
1155
        { Tag::root, canonCfId,        canonId,          0x000f    },
1156
        { Tag::root, canonPiId,        canonId,          0x0012    },
1157
        { Tag::root, canonFiId,        canonId,          0x0093    },
1158
        { Tag::root, canonPrId,        canonId,          0x00a0    },
1159
        { Tag::root, nikon1Id,         exifId,           0x927c    },
1160
        { Tag::root, nikon2Id,         exifId,           0x927c    },
1161
        { Tag::root, nikon3Id,         exifId,           0x927c    },
1162
        { Tag::root, nikonPvId,        nikon3Id,         0x0011    },
1163
        { Tag::root, nikonVrId,        nikon3Id,         0x001f    },
1164
        { Tag::root, nikonPcId,        nikon3Id,         0x0023    },
1165
        { Tag::root, nikonWtId,        nikon3Id,         0x0024    },
1166
        { Tag::root, nikonIiId,        nikon3Id,         0x0025    },
1167
        { Tag::root, nikonAfId,        nikon3Id,         0x0088    },
1168
        { Tag::root, nikonSi1Id,       nikon3Id,         0x0091    },
1169
        { Tag::root, nikonSi2Id,       nikon3Id,         0x0091    },
1170
        { Tag::root, nikonSi3Id,       nikon3Id,         0x0091    },
1171
        { Tag::root, nikonSi4Id,       nikon3Id,         0x0091    },
1172
        { Tag::root, nikonSi5Id,       nikon3Id,         0x0091    },
1173
        { Tag::root, nikonSi6Id,       nikon3Id,         0x0091    },
1174
        { Tag::root, nikonCb1Id,       nikon3Id,         0x0097    },
1175
        { Tag::root, nikonCb2Id,       nikon3Id,         0x0097    },
1176
        { Tag::root, nikonCb2aId,      nikon3Id,         0x0097    },
1177
        { Tag::root, nikonCb2bId,      nikon3Id,         0x0097    },
1178
        { Tag::root, nikonCb3Id,       nikon3Id,         0x0097    },
1179
        { Tag::root, nikonCb4Id,       nikon3Id,         0x0097    },
1180
        { Tag::root, nikonLd1Id,       nikon3Id,         0x0098    },
1181
        { Tag::root, nikonLd2Id,       nikon3Id,         0x0098    },
1182
        { Tag::root, nikonLd3Id,       nikon3Id,         0x0098    },
1183
        { Tag::root, nikonMeId,        nikon3Id,         0x00b0    },
1184
        { Tag::root, nikonAf2Id,       nikon3Id,         0x00b7    },
1185
        { Tag::root, nikonFiId,        nikon3Id,         0x00b8    },
1186
        { Tag::root, nikonFl1Id,       nikon3Id,         0x00a8    },
1187
        { Tag::root, nikonFl2Id,       nikon3Id,         0x00a8    },
1188
        { Tag::root, nikonFl3Id,       nikon3Id,         0x00a8    },
1189
        { Tag::root, panasonicId,      exifId,           0x927c    },
1190
        { Tag::root, pentaxId,         exifId,           0x927c    },
1191
        { Tag::root, samsung2Id,       exifId,           0x927c    },
1192
        { Tag::root, samsungPvId,      samsung2Id,       0x0035    },
1193
        { Tag::root, sigmaId,          exifId,           0x927c    },
1194
        { Tag::root, sony1Id,          exifId,           0x927c    },
1195
        { Tag::root, sony1CsId,        sony1Id,          0x0114    },
1196
        { Tag::root, sony1Cs2Id,       sony1Id,          0x0114    },
1197
        { Tag::root, sonyMltId,        sony1Id,          0xb028    },
1198
        { Tag::root, sony1MltCsOldId,  sonyMltId,        0x0001    },
1199
        { Tag::root, sony1MltCsNewId,  sonyMltId,        0x0003    },
1200
        { Tag::root, sony1MltCs7DId,   sonyMltId,        0x0004    },
1201
        { Tag::root, sony1MltCsA100Id, sonyMltId,        0x0114    },
1202
        { Tag::root, sony2Id,          exifId,           0x927c    },
1203
        { Tag::root, sony2CsId,        sony2Id,          0x0114    },
1204
        { Tag::root, sony2Cs2Id,       sony2Id,          0x0114    },
1205
        { Tag::root, minoltaId,        exifId,           0x927c    },
1206
        { Tag::root, minoltaCsOldId,   minoltaId,        0x0001    },
1207
        { Tag::root, minoltaCsNewId,   minoltaId,        0x0003    },
1208
        { Tag::root, minoltaCs7DId,    minoltaId,        0x0004    },
1209
        { Tag::root, minoltaCs5DId,    minoltaId,        0x0114    },
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1210
        // ---------------------------------------------------------
1211
        // Panasonic RW2 raw images
1.3.2 by Robert Ancell
Import upstream version 0.21
1212
        { Tag::pana, ifdIdNotSet,      ifdIdNotSet,      Tag::pana },
1213
        { Tag::pana, panaRawId,        ifdIdNotSet,      Tag::pana },
1214
        { Tag::pana, exifId,           panaRawId,        0x8769    },
1215
        { Tag::pana, gpsId,            panaRawId,        0x8825    }
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1216
    };
1217
1.1.8 by Mark Purcell
Import upstream version 0.18
1218
    /*
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1219
      This table describes the layout of each known TIFF group (including
1220
      non-standard structures and IFDs only seen in RAW images).
1221
1222
      The key of the table consists of the first two attributes, (extended) tag
1223
      and group. Tag is the TIFF tag or one of a few extended tags, group
1224
      identifies the IFD or any other composite component.
1225
1226
      Each entry of the table defines for a particular tag and group combination
1227
      the corresponding TIFF component create function.
1.1.8 by Mark Purcell
Import upstream version 0.18
1228
     */
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1229
    const TiffGroupStruct TiffCreator::tiffGroupStruct_[] = {
1230
        // ext. tag  group             create function
1231
        //---------  ----------------- -----------------------------------------
1.1.8 by Mark Purcell
Import upstream version 0.18
1232
        // Root directory
1.3.2 by Robert Ancell
Import upstream version 0.21
1233
        { Tag::root, ifdIdNotSet,      newTiffDirectory<ifd0Id>                  },
1.1.8 by Mark Purcell
Import upstream version 0.18
1234
1235
        // IFD0
1.3.2 by Robert Ancell
Import upstream version 0.21
1236
        {    0x8769, ifd0Id,           newTiffSubIfd<exifId>                     },
1237
        {    0x8825, ifd0Id,           newTiffSubIfd<gpsId>                      },
1238
        {    0x0111, ifd0Id,           newTiffImageData<0x0117, ifd0Id>          },
1239
        {    0x0117, ifd0Id,           newTiffImageSize<0x0111, ifd0Id>          },
1240
        {    0x0144, ifd0Id,           newTiffImageData<0x0145, ifd0Id>          },
1241
        {    0x0145, ifd0Id,           newTiffImageSize<0x0144, ifd0Id>          },
1242
        {    0x0201, ifd0Id,           newTiffImageData<0x0202, ifd0Id>          },
1243
        {    0x0202, ifd0Id,           newTiffImageSize<0x0201, ifd0Id>          },
1244
        {    0x014a, ifd0Id,           newTiffSubIfd<subImage1Id>                },
1245
        { Tag::next, ifd0Id,           newTiffDirectory<ifd1Id>                  },
1246
        {  Tag::all, ifd0Id,           newTiffEntry                              },
1247
1248
        // Subdir subImage1
1249
        {    0x0111, subImage1Id,      newTiffImageData<0x0117, subImage1Id>     },
1250
        {    0x0117, subImage1Id,      newTiffImageSize<0x0111, subImage1Id>     },
1251
        {    0x0144, subImage1Id,      newTiffImageData<0x0145, subImage1Id>     },
1252
        {    0x0145, subImage1Id,      newTiffImageSize<0x0144, subImage1Id>     },
1253
        {    0x0201, subImage1Id,      newTiffImageData<0x0202, subImage1Id>     },
1254
        {    0x0202, subImage1Id,      newTiffImageSize<0x0201, subImage1Id>     },
1255
        { Tag::next, subImage1Id,      newTiffDirectory<ignoreId>                },
1256
        {  Tag::all, subImage1Id,      newTiffEntry                              },
1257
1258
        // Subdir subImage2
1259
        {    0x0111, subImage2Id,      newTiffImageData<0x0117, subImage2Id>     },
1260
        {    0x0117, subImage2Id,      newTiffImageSize<0x0111, subImage2Id>     },
1261
        {    0x0144, subImage2Id,      newTiffImageData<0x0145, subImage2Id>     },
1262
        {    0x0145, subImage2Id,      newTiffImageSize<0x0144, subImage2Id>     },
1263
        {    0x0201, subImage2Id,      newTiffImageData<0x0202, subImage2Id>     },
1264
        {    0x0202, subImage2Id,      newTiffImageSize<0x0201, subImage2Id>     },
1265
        { Tag::next, subImage2Id,      newTiffDirectory<ignoreId>                },
1266
        {  Tag::all, subImage2Id,      newTiffEntry                              },
1267
1268
        // Subdir subImage3
1269
        {    0x0111, subImage3Id,      newTiffImageData<0x0117, subImage3Id>     },
1270
        {    0x0117, subImage3Id,      newTiffImageSize<0x0111, subImage3Id>     },
1271
        {    0x0144, subImage3Id,      newTiffImageData<0x0145, subImage3Id>     },
1272
        {    0x0145, subImage3Id,      newTiffImageSize<0x0144, subImage3Id>     },
1273
        {    0x0201, subImage3Id,      newTiffImageData<0x0202, subImage3Id>     },
1274
        {    0x0202, subImage3Id,      newTiffImageSize<0x0201, subImage3Id>     },
1275
        { Tag::next, subImage3Id,      newTiffDirectory<ignoreId>                },
1276
        {  Tag::all, subImage3Id,      newTiffEntry                              },
1277
1278
        // Subdir subImage4
1279
        {    0x0111, subImage4Id,      newTiffImageData<0x0117, subImage4Id>     },
1280
        {    0x0117, subImage4Id,      newTiffImageSize<0x0111, subImage4Id>     },
1281
        {    0x0144, subImage4Id,      newTiffImageData<0x0145, subImage4Id>     },
1282
        {    0x0145, subImage4Id,      newTiffImageSize<0x0144, subImage4Id>     },
1283
        {    0x0201, subImage4Id,      newTiffImageData<0x0202, subImage4Id>     },
1284
        {    0x0202, subImage4Id,      newTiffImageSize<0x0201, subImage4Id>     },
1285
        { Tag::next, subImage4Id,      newTiffDirectory<ignoreId>                },
1286
        {  Tag::all, subImage4Id,      newTiffEntry                              },
1287
1288
        // Subdir subImage5
1289
        {    0x0111, subImage5Id,      newTiffImageData<0x0117, subImage5Id>     },
1290
        {    0x0117, subImage5Id,      newTiffImageSize<0x0111, subImage5Id>     },
1291
        {    0x0144, subImage5Id,      newTiffImageData<0x0145, subImage5Id>     },
1292
        {    0x0145, subImage5Id,      newTiffImageSize<0x0144, subImage5Id>     },
1293
        {    0x0201, subImage5Id,      newTiffImageData<0x0202, subImage5Id>     },
1294
        {    0x0202, subImage5Id,      newTiffImageSize<0x0201, subImage5Id>     },
1295
        { Tag::next, subImage5Id,      newTiffDirectory<ignoreId>                },
1296
        {  Tag::all, subImage5Id,      newTiffEntry                              },
1297
1298
        // Subdir subImage6
1299
        {    0x0111, subImage6Id,      newTiffImageData<0x0117, subImage6Id>     },
1300
        {    0x0117, subImage6Id,      newTiffImageSize<0x0111, subImage6Id>     },
1301
        {    0x0144, subImage6Id,      newTiffImageData<0x0145, subImage6Id>     },
1302
        {    0x0145, subImage6Id,      newTiffImageSize<0x0144, subImage6Id>     },
1303
        {    0x0201, subImage6Id,      newTiffImageData<0x0202, subImage6Id>     },
1304
        {    0x0202, subImage6Id,      newTiffImageSize<0x0201, subImage6Id>     },
1305
        { Tag::next, subImage6Id,      newTiffDirectory<ignoreId>                },
1306
        {  Tag::all, subImage6Id,      newTiffEntry                              },
1307
1308
        // Subdir subImage7
1309
        {    0x0111, subImage7Id,      newTiffImageData<0x0117, subImage7Id>     },
1310
        {    0x0117, subImage7Id,      newTiffImageSize<0x0111, subImage7Id>     },
1311
        {    0x0144, subImage7Id,      newTiffImageData<0x0145, subImage7Id>     },
1312
        {    0x0145, subImage7Id,      newTiffImageSize<0x0144, subImage7Id>     },
1313
        {    0x0201, subImage7Id,      newTiffImageData<0x0202, subImage7Id>     },
1314
        {    0x0202, subImage7Id,      newTiffImageSize<0x0201, subImage7Id>     },
1315
        { Tag::next, subImage7Id,      newTiffDirectory<ignoreId>                },
1316
        {  Tag::all, subImage7Id,      newTiffEntry                              },
1317
1318
        // Subdir subImage8
1319
        {    0x0111, subImage8Id,      newTiffImageData<0x0117, subImage8Id>     },
1320
        {    0x0117, subImage8Id,      newTiffImageSize<0x0111, subImage8Id>     },
1321
        {    0x0144, subImage8Id,      newTiffImageData<0x0145, subImage8Id>     },
1322
        {    0x0145, subImage8Id,      newTiffImageSize<0x0144, subImage8Id>     },
1323
        {    0x0201, subImage8Id,      newTiffImageData<0x0202, subImage8Id>     },
1324
        {    0x0202, subImage8Id,      newTiffImageSize<0x0201, subImage8Id>     },
1325
        { Tag::next, subImage8Id,      newTiffDirectory<ignoreId>                },
1326
        {  Tag::all, subImage8Id,      newTiffEntry                              },
1327
1328
        // Subdir subImage9
1329
        {    0x0111, subImage9Id,      newTiffImageData<0x0117, subImage9Id>     },
1330
        {    0x0117, subImage9Id,      newTiffImageSize<0x0111, subImage9Id>     },
1331
        {    0x0144, subImage9Id,      newTiffImageData<0x0145, subImage9Id>     },
1332
        {    0x0145, subImage9Id,      newTiffImageSize<0x0144, subImage9Id>     },
1333
        {    0x0201, subImage9Id,      newTiffImageData<0x0202, subImage9Id>     },
1334
        {    0x0202, subImage9Id,      newTiffImageSize<0x0201, subImage9Id>     },
1335
        { Tag::next, subImage9Id,      newTiffDirectory<ignoreId>                },
1336
        {  Tag::all, subImage9Id,      newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1337
1338
        // Exif subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1339
        {    0xa005, exifId,           newTiffSubIfd<iopId>                      },
1340
        {    0x927c, exifId,           newTiffMnEntry                            },
1341
        { Tag::next, exifId,           newTiffDirectory<ignoreId>                },
1342
        {  Tag::all, exifId,           newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1343
1344
        // GPS subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1345
        { Tag::next, gpsId,            newTiffDirectory<ignoreId>                },
1346
        {  Tag::all, gpsId,            newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1347
1348
        // IOP subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1349
        { Tag::next, iopId,            newTiffDirectory<ignoreId>                },
1350
        {  Tag::all, iopId,            newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1351
1352
        // IFD1
1.3.2 by Robert Ancell
Import upstream version 0.21
1353
        {    0x0111, ifd1Id,           newTiffThumbData<0x0117, ifd1Id>          },
1354
        {    0x0117, ifd1Id,           newTiffThumbSize<0x0111, ifd1Id>          },
1355
        {    0x0144, ifd1Id,           newTiffImageData<0x0145, ifd1Id>          },
1356
        {    0x0145, ifd1Id,           newTiffImageSize<0x0144, ifd1Id>          },
1357
        {    0x014a, ifd1Id,           newTiffSubIfd<subThumb1Id>                },
1358
        {    0x0201, ifd1Id,           newTiffThumbData<0x0202, ifd1Id>          },
1359
        {    0x0202, ifd1Id,           newTiffThumbSize<0x0201, ifd1Id>          },
1360
        { Tag::next, ifd1Id,           newTiffDirectory<ifd2Id>                  },
1361
        {  Tag::all, ifd1Id,           newTiffEntry                              },
1362
1363
        // Subdir subThumb1
1364
        {    0x0111, subThumb1Id,      newTiffImageData<0x0117, subThumb1Id>     },
1365
        {    0x0117, subThumb1Id,      newTiffImageSize<0x0111, subThumb1Id>     },
1366
        {    0x0144, subThumb1Id,      newTiffImageData<0x0145, subThumb1Id>     },
1367
        {    0x0145, subThumb1Id,      newTiffImageSize<0x0144, subThumb1Id>     },
1368
        {    0x0201, subThumb1Id,      newTiffImageData<0x0202, subThumb1Id>     },
1369
        {    0x0202, subThumb1Id,      newTiffImageSize<0x0201, subThumb1Id>     },
1370
        { Tag::next, subThumb1Id,      newTiffDirectory<ignoreId>                },
1371
        {  Tag::all, subThumb1Id,      newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1372
1.2.4 by Mark Purcell
Import upstream version 0.19
1373
        // IFD2 (eg, in Pentax PEF and Canon CR2 files)
1.3.2 by Robert Ancell
Import upstream version 0.21
1374
        {    0x0111, ifd2Id,           newTiffImageData<0x0117, ifd2Id>          },
1375
        {    0x0117, ifd2Id,           newTiffImageSize<0x0111, ifd2Id>          },
1376
        {    0x0144, ifd1Id,           newTiffImageData<0x0145, ifd2Id>          },
1377
        {    0x0145, ifd1Id,           newTiffImageSize<0x0144, ifd2Id>          },
1378
        {    0x0201, ifd2Id,           newTiffImageData<0x0202, ifd2Id>          },
1379
        {    0x0202, ifd2Id,           newTiffImageSize<0x0201, ifd2Id>          },
1380
        { Tag::next, ifd2Id,           newTiffDirectory<ifd3Id>                  },
1381
        {  Tag::all, ifd2Id,           newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1382
1.2.4 by Mark Purcell
Import upstream version 0.19
1383
        // IFD3 (eg, in Canon CR2 files)
1.3.2 by Robert Ancell
Import upstream version 0.21
1384
        {    0x0111, ifd3Id,           newTiffImageData<0x0117, ifd3Id>          },
1385
        {    0x0117, ifd3Id,           newTiffImageSize<0x0111, ifd3Id>          },
1386
        {    0x0144, ifd1Id,           newTiffImageData<0x0145, ifd3Id>          },
1387
        {    0x0145, ifd1Id,           newTiffImageSize<0x0144, ifd3Id>          },
1388
        {    0x0201, ifd3Id,           newTiffImageData<0x0202, ifd3Id>          },
1389
        {    0x0202, ifd3Id,           newTiffImageSize<0x0201, ifd3Id>          },
1390
        { Tag::next, ifd3Id,           newTiffDirectory<ignoreId>                },
1391
        {  Tag::all, ifd3Id,           newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1392
1393
        // Olympus makernote - some Olympus cameras use Minolta structures
1394
        // Todo: Adding such tags will not work (maybe result in a Minolta makernote), need separate groups
1.3.2 by Robert Ancell
Import upstream version 0.21
1395
        {    0x0001, olympusId,        EXV_SIMPLE_BINARY_ARRAY(minoCsoCfg)       },
1396
        {    0x0003, olympusId,        EXV_SIMPLE_BINARY_ARRAY(minoCsnCfg)       },
1397
        { Tag::next, olympusId,        newTiffDirectory<ignoreId>                },
1398
        {  Tag::all, olympusId,        newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1399
1400
        // Olympus2 makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1401
        {    0x0001, olympus2Id,       EXV_SIMPLE_BINARY_ARRAY(minoCsoCfg)       },
1402
        {    0x0003, olympus2Id,       EXV_SIMPLE_BINARY_ARRAY(minoCsnCfg)       },
1403
        {    0x2010, olympus2Id,       newTiffSubIfd<olympusEqId>                },
1404
        {    0x2020, olympus2Id,       newTiffSubIfd<olympusCsId>                },
1405
        {    0x2030, olympus2Id,       newTiffSubIfd<olympusRdId>                },
1406
        {    0x2031, olympus2Id,       newTiffSubIfd<olympusRd2Id>               },
1407
        {    0x2040, olympus2Id,       newTiffSubIfd<olympusIpId>                },
1408
        {    0x2050, olympus2Id,       newTiffSubIfd<olympusFiId>                },
1409
        {    0x2100, olympus2Id,       newTiffSubIfd<olympusFe1Id>               },
1410
        {    0x2200, olympus2Id,       newTiffSubIfd<olympusFe2Id>               },
1411
        {    0x2300, olympus2Id,       newTiffSubIfd<olympusFe3Id>               },
1412
        {    0x2400, olympus2Id,       newTiffSubIfd<olympusFe4Id>               },
1413
        {    0x2500, olympus2Id,       newTiffSubIfd<olympusFe5Id>               },
1414
        {    0x2600, olympus2Id,       newTiffSubIfd<olympusFe6Id>               },
1415
        {    0x2700, olympus2Id,       newTiffSubIfd<olympusFe7Id>               },
1416
        {    0x2800, olympus2Id,       newTiffSubIfd<olympusFe8Id>               },
1417
        {    0x2900, olympus2Id,       newTiffSubIfd<olympusFe9Id>               },
1418
        {    0x3000, olympus2Id,       newTiffSubIfd<olympusRiId>                },
1419
        { Tag::next, olympus2Id,       newTiffDirectory<ignoreId>                },
1420
        {  Tag::all, olympus2Id,       newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1421
1422
        // Olympus2 equipment subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1423
        {  Tag::all, olympusEqId,        newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1424
1425
        // Olympus2 camera settings subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1426
        {    0x0101, olympusCsId,        newTiffImageData<0x0102, olympusCsId>   },
1427
        {    0x0102, olympusCsId,        newTiffImageSize<0x0101, olympusCsId>   },
1428
        {  Tag::all, olympusCsId,        newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1429
1430
        // Olympus2 raw development subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1431
        {  Tag::all, olympusRdId,        newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1432
1433
        // Olympus2 raw development 2 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1434
        {  Tag::all, olympusRd2Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1435
1436
        // Olympus2 image processing subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1437
        {  Tag::all, olympusIpId,        newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1438
1439
        // Olympus2 focus info subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1440
        {  Tag::all, olympusFiId,        newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1441
1442
        // Olympus2 FE 1 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1443
        {  Tag::all, olympusFe1Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1444
1445
        // Olympus2 FE 2 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1446
        {  Tag::all, olympusFe2Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1447
1448
        // Olympus2 FE 3 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1449
        {  Tag::all, olympusFe3Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1450
1451
        // Olympus2 FE 4 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1452
        {  Tag::all, olympusFe4Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1453
1454
        // Olympus2 FE 5 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1455
        {  Tag::all, olympusFe5Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1456
1457
        // Olympus2 FE 6 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1458
        {  Tag::all, olympusFe6Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1459
1460
        // Olympus2 FE 7 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1461
        {  Tag::all, olympusFe7Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1462
1463
        // Olympus2 FE 8 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1464
        {  Tag::all, olympusFe8Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1465
1466
        // Olympus2 FE 9 subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1467
        {  Tag::all, olympusFe9Id,       newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1468
1469
        // Olympus2 Raw Info subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1470
        {  Tag::all, olympusRiId,        newTiffEntry                            },
1.1.8 by Mark Purcell
Import upstream version 0.18
1471
1472
        // Fujifilm makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1473
        { Tag::next, fujiId,           newTiffDirectory<ignoreId>                },
1474
        {  Tag::all, fujiId,           newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1475
1476
        // Canon makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1477
        {    0x0001, canonId,          EXV_BINARY_ARRAY(canonCsCfg, canonCsDef)  },
1478
        {    0x0004, canonId,          EXV_SIMPLE_BINARY_ARRAY(canonSiCfg)       },
1479
        {    0x0005, canonId,          EXV_SIMPLE_BINARY_ARRAY(canonPaCfg)       },
1480
        {    0x000f, canonId,          EXV_SIMPLE_BINARY_ARRAY(canonCfCfg)       },
1481
        {    0x0012, canonId,          EXV_SIMPLE_BINARY_ARRAY(canonPiCfg)       },
1482
        {    0x0093, canonId,          EXV_BINARY_ARRAY(canonFiCfg, canonFiDef)  },
1483
        {    0x00a0, canonId,          EXV_SIMPLE_BINARY_ARRAY(canonPrCfg)  },
1484
        { Tag::next, canonId,          newTiffDirectory<ignoreId>                },
1485
        {  Tag::all, canonId,          newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1486
1487
        // Canon makernote composite tags
1.3.2 by Robert Ancell
Import upstream version 0.21
1488
        {  Tag::all, canonCsId,        newTiffBinaryElement                      },
1489
        {  Tag::all, canonSiId,        newTiffBinaryElement                      },
1490
        {  Tag::all, canonPaId,        newTiffBinaryElement                      },
1491
        {  Tag::all, canonCfId,        newTiffBinaryElement                      },
1492
        {  Tag::all, canonPiId,        newTiffBinaryElement                      },
1493
        {  Tag::all, canonFiId,        newTiffBinaryElement                      },
1494
        {  Tag::all, canonPrId,        newTiffBinaryElement                      },
1.1.8 by Mark Purcell
Import upstream version 0.18
1495
1496
        // Nikon1 makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1497
        { Tag::next, nikon1Id,         newTiffDirectory<ignoreId>                },
1498
        {  Tag::all, nikon1Id,         newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1499
1500
        // Nikon2 makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1501
        { Tag::next, nikon2Id,         newTiffDirectory<ignoreId>                },
1502
        {  Tag::all, nikon2Id,         newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1503
1504
        // Nikon3 makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1505
        { Tag::next, nikon3Id,         newTiffDirectory<ignoreId>                },
1506
        {    0x0011, nikon3Id,         newTiffSubIfd<nikonPvId>                  },
1507
        {    0x001f, nikon3Id,         EXV_BINARY_ARRAY(nikonVrCfg, nikonVrDef)  },
1508
        {    0x0023, nikon3Id,         EXV_BINARY_ARRAY(nikonPcCfg, nikonPcDef)  },
1509
        {    0x0024, nikon3Id,         EXV_BINARY_ARRAY(nikonWtCfg, nikonWtDef)  },
1510
        {    0x0025, nikon3Id,         EXV_BINARY_ARRAY(nikonIiCfg, nikonIiDef)  },
1511
        {    0x0088, nikon3Id,         EXV_BINARY_ARRAY(nikonAfCfg, nikonAfDef)  },
1512
        {    0x0091, nikon3Id,         EXV_COMPLEX_BINARY_ARRAY(nikonSiSet, nikonSelector) },
1513
        {    0x0097, nikon3Id,         EXV_COMPLEX_BINARY_ARRAY(nikonCbSet, nikonSelector) },
1514
        {    0x0098, nikon3Id,         EXV_COMPLEX_BINARY_ARRAY(nikonLdSet, nikonSelector) },
1515
        {    0x00a8, nikon3Id,         EXV_COMPLEX_BINARY_ARRAY(nikonFlSet, nikonSelector) },
1516
        {    0x00b0, nikon3Id,         EXV_BINARY_ARRAY(nikonMeCfg, nikonMeDef)  },
1517
        {    0x00b7, nikon3Id,         EXV_BINARY_ARRAY(nikonAf2Cfg, nikonAf2Def)},
1518
        {    0x00b8, nikon3Id,         EXV_BINARY_ARRAY(nikonFiCfg, nikonFiDef)  },
1519
        {  Tag::all, nikon3Id,         newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1520
1521
        // Nikon3 makernote preview subdir
1.3.2 by Robert Ancell
Import upstream version 0.21
1522
        {    0x0201, nikonPvId,        newTiffThumbData<0x0202, nikonPvId>       },
1523
        {    0x0202, nikonPvId,        newTiffThumbSize<0x0201, nikonPvId>       },
1524
        { Tag::next, nikonPvId,        newTiffDirectory<ignoreId>                },
1525
        {  Tag::all, nikonPvId,        newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1526
1.2.4 by Mark Purcell
Import upstream version 0.19
1527
        // Nikon3 vibration reduction
1.3.2 by Robert Ancell
Import upstream version 0.21
1528
        {  Tag::all, nikonVrId,        newTiffBinaryElement                      },
1.2.4 by Mark Purcell
Import upstream version 0.19
1529
1530
        // Nikon3 picture control
1.3.2 by Robert Ancell
Import upstream version 0.21
1531
        {  Tag::all, nikonPcId,        newTiffBinaryElement                      },
1.2.4 by Mark Purcell
Import upstream version 0.19
1532
1533
        // Nikon3 world time
1.3.2 by Robert Ancell
Import upstream version 0.21
1534
        {  Tag::all, nikonWtId,        newTiffBinaryElement                      },
1.2.4 by Mark Purcell
Import upstream version 0.19
1535
1536
        // Nikon3 ISO info
1.3.2 by Robert Ancell
Import upstream version 0.21
1537
        {  Tag::all, nikonIiId,        newTiffBinaryElement                      },
1.2.4 by Mark Purcell
Import upstream version 0.19
1538
1539
        // Nikon3 auto focus
1.3.2 by Robert Ancell
Import upstream version 0.21
1540
        {  Tag::all, nikonAfId,        newTiffBinaryElement                      },
1.3.1 by Mark Purcell
Import upstream version 0.20
1541
        
1542
        // Nikon3 auto focus 2
1.3.2 by Robert Ancell
Import upstream version 0.21
1543
        {  Tag::all, nikonAf2Id,       newTiffBinaryElement                      },
1.3.1 by Mark Purcell
Import upstream version 0.20
1544
        
1545
        // Nikon3 file info
1.3.2 by Robert Ancell
Import upstream version 0.21
1546
        {  Tag::all, nikonFiId,        newTiffBinaryElement                      },
1.3.1 by Mark Purcell
Import upstream version 0.20
1547
1548
        // Nikon3 multi exposure
1.3.2 by Robert Ancell
Import upstream version 0.21
1549
        {  Tag::all, nikonMeId,        newTiffBinaryElement                      },
1.3.1 by Mark Purcell
Import upstream version 0.20
1550
1551
        // Nikon3 flash info
1.3.2 by Robert Ancell
Import upstream version 0.21
1552
        {  Tag::all, nikonFl1Id,       newTiffBinaryElement                      },
1553
        {  Tag::all, nikonFl2Id,       newTiffBinaryElement                      },
1554
        {  Tag::all, nikonFl3Id,       newTiffBinaryElement                      },
1.2.4 by Mark Purcell
Import upstream version 0.19
1555
1556
        // Nikon3 shot info
1.3.2 by Robert Ancell
Import upstream version 0.21
1557
        {  Tag::all, nikonSi1Id,       newTiffBinaryElement                      },
1558
        {  Tag::all, nikonSi2Id,       newTiffBinaryElement                      },
1559
        {  Tag::all, nikonSi3Id,       newTiffBinaryElement                      },
1560
        {  Tag::all, nikonSi4Id,       newTiffBinaryElement                      },
1561
        {  Tag::all, nikonSi5Id,       newTiffBinaryElement                      },
1562
        {  Tag::all, nikonSi6Id,       newTiffBinaryElement                      },
1.2.4 by Mark Purcell
Import upstream version 0.19
1563
1564
        // Nikon3 color balance
1.3.2 by Robert Ancell
Import upstream version 0.21
1565
        {  Tag::all, nikonCb1Id,       newTiffBinaryElement                      },
1566
        {  Tag::all, nikonCb2Id,       newTiffBinaryElement                      },
1567
        {  Tag::all, nikonCb2aId,      newTiffBinaryElement                      },
1568
        {  Tag::all, nikonCb2bId,      newTiffBinaryElement                      },
1569
        {  Tag::all, nikonCb3Id,       newTiffBinaryElement                      },
1570
        {  Tag::all, nikonCb4Id,       newTiffBinaryElement                      },
1.2.4 by Mark Purcell
Import upstream version 0.19
1571
1572
        // Nikon3 lens data
1.3.2 by Robert Ancell
Import upstream version 0.21
1573
        {  Tag::all, nikonLd1Id,       newTiffBinaryElement                      },
1574
        {  Tag::all, nikonLd2Id,       newTiffBinaryElement                      },
1575
        {  Tag::all, nikonLd3Id,       newTiffBinaryElement                      },
1.1.8 by Mark Purcell
Import upstream version 0.18
1576
1577
        // Panasonic makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1578
        { Tag::next, panasonicId,      newTiffDirectory<ignoreId>                },
1579
        {  Tag::all, panasonicId,      newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1580
1581
        // Pentax makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1582
        {    0x0003, pentaxId,         newTiffThumbSize<0x0004, pentaxId>        },
1583
        {    0x0004, pentaxId,         newTiffThumbData<0x0003, pentaxId>        },
1584
        { Tag::next, pentaxId,         newTiffDirectory<ignoreId>                },
1585
        {  Tag::all, pentaxId,         newTiffEntry                              },
1586
1587
        // Samsung2 makernote
1588
        {    0x0035, samsung2Id,       newTiffSubIfd<samsungPvId>                },
1589
        { Tag::next, samsung2Id,       newTiffDirectory<ignoreId>                },
1590
        {  Tag::all, samsung2Id,       newTiffEntry                              },
1591
1592
        // Samsung2 makernote preview subdir
1593
        {    0x0201, samsungPvId,      newTiffThumbData<0x0202, samsungPvId>     },
1594
        {    0x0202, samsungPvId,      newTiffThumbSize<0x0201, samsungPvId>     },
1595
        { Tag::next, samsungPvId,      newTiffDirectory<ignoreId>                },
1596
        {  Tag::all, samsungPvId,      newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1597
1598
        // Sigma/Foveon makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1599
        { Tag::next, sigmaId,          newTiffDirectory<ignoreId>                },
1600
        {  Tag::all, sigmaId,          newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1601
1602
        // Sony1 makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1603
        {    0x0114, sony1Id,          EXV_COMPLEX_BINARY_ARRAY(sony1CsSet, sonyCsSelector) },
1604
        {    0xb028, sony1Id,          newTiffSubIfd<sonyMltId>                  },
1605
        { Tag::next, sony1Id,          newTiffDirectory<ignoreId>                },
1606
        {  Tag::all, sony1Id,          newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1607
1.3.1 by Mark Purcell
Import upstream version 0.20
1608
        // Sony1 camera settings
1.3.2 by Robert Ancell
Import upstream version 0.21
1609
        {  Tag::all, sony1CsId,        newTiffBinaryElement                      },
1610
        {  Tag::all, sony1Cs2Id,       newTiffBinaryElement                      },
1.1.8 by Mark Purcell
Import upstream version 0.18
1611
1612
        // Sony2 makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1613
        {    0x0114, sony2Id,          EXV_COMPLEX_BINARY_ARRAY(sony2CsSet, sonyCsSelector) },
1614
        { Tag::next, sony2Id,          newTiffDirectory<ignoreId>                },
1615
        {  Tag::all, sony2Id,          newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1616
1.3.1 by Mark Purcell
Import upstream version 0.20
1617
        // Sony2 camera settings
1.3.2 by Robert Ancell
Import upstream version 0.21
1618
        {  Tag::all, sony2CsId,        newTiffBinaryElement                      },
1619
        {  Tag::all, sony2Cs2Id,       newTiffBinaryElement                      },
1.3.1 by Mark Purcell
Import upstream version 0.20
1620
1621
        // Sony1 Minolta makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1622
        {    0x0001, sonyMltId,        EXV_SIMPLE_BINARY_ARRAY(sony1MCsoCfg)     },
1623
        {    0x0003, sonyMltId,        EXV_SIMPLE_BINARY_ARRAY(sony1MCsnCfg)     },
1624
        {    0x0004, sonyMltId,        EXV_BINARY_ARRAY(sony1MCs7Cfg, minoCs7Def)}, // minoCs7Def [sic]
1625
        {    0x0088, sonyMltId,        newTiffThumbData<0x0089, sonyMltId>       },
1626
        {    0x0089, sonyMltId,        newTiffThumbSize<0x0088, sonyMltId>       },
1627
        {    0x0114, sonyMltId,        EXV_BINARY_ARRAY(sony1MCsA100Cfg, sony1MCsA100Def)},
1628
        { Tag::next, sonyMltId,        newTiffDirectory<ignoreId>                },
1629
        {  Tag::all, sonyMltId,        newTiffEntry                              },
1.3.1 by Mark Purcell
Import upstream version 0.20
1630
1631
        // Sony1 Minolta makernote composite tags
1.3.2 by Robert Ancell
Import upstream version 0.21
1632
        {  Tag::all, sony1MltCsOldId,  newTiffBinaryElement                      },
1633
        {  Tag::all, sony1MltCsNewId,  newTiffBinaryElement                      },
1634
        {  Tag::all, sony1MltCs7DId,   newTiffBinaryElement                      },
1635
        {  Tag::all, sony1MltCsA100Id, newTiffBinaryElement                      },
1.1.8 by Mark Purcell
Import upstream version 0.18
1636
1637
        // Minolta makernote
1.3.2 by Robert Ancell
Import upstream version 0.21
1638
        {    0x0001, minoltaId,        EXV_SIMPLE_BINARY_ARRAY(minoCsoCfg)       },
1639
        {    0x0003, minoltaId,        EXV_SIMPLE_BINARY_ARRAY(minoCsnCfg)       },
1640
        {    0x0004, minoltaId,        EXV_BINARY_ARRAY(minoCs7Cfg, minoCs7Def)  },
1641
        {    0x0088, minoltaId,        newTiffThumbData<0x0089, minoltaId>       },
1642
        {    0x0089, minoltaId,        newTiffThumbSize<0x0088, minoltaId>       },
1643
        {    0x0114, minoltaId,        EXV_BINARY_ARRAY(minoCs5Cfg, minoCs5Def)  },
1644
        { Tag::next, minoltaId,        newTiffDirectory<ignoreId>                },
1645
        {  Tag::all, minoltaId,        newTiffEntry                              },
1.1.8 by Mark Purcell
Import upstream version 0.18
1646
1647
        // Minolta makernote composite tags
1.3.2 by Robert Ancell
Import upstream version 0.21
1648
        {  Tag::all, minoltaCsOldId,   newTiffBinaryElement                      },
1649
        {  Tag::all, minoltaCsNewId,   newTiffBinaryElement                      },
1650
        {  Tag::all, minoltaCs7DId,    newTiffBinaryElement                      },
1651
        {  Tag::all, minoltaCs5DId,    newTiffBinaryElement                      },
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1652
1653
        // -----------------------------------------------------------------------
1654
        // Root directory of Panasonic RAW images
1.3.2 by Robert Ancell
Import upstream version 0.21
1655
        { Tag::pana, ifdIdNotSet,      newTiffDirectory<panaRawId>               },
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1656
1.2.4 by Mark Purcell
Import upstream version 0.19
1657
        // IFD0 of Panasonic RAW images
1.3.2 by Robert Ancell
Import upstream version 0.21
1658
        {    0x8769, panaRawId,        newTiffSubIfd<exifId>                     },
1659
        {    0x8825, panaRawId,        newTiffSubIfd<gpsId>                      },
1660
//        {    0x0111, panaRawId,        newTiffImageData<0x0117, panaRawId>       },
1661
//        {    0x0117, panaRawId,        newTiffImageSize<0x0111, panaRawId>       },
1662
        { Tag::next, panaRawId,        newTiffDirectory<ignoreId>                },
1663
        {  Tag::all, panaRawId,        newTiffEntry                              },
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1664
1665
        // -----------------------------------------------------------------------
1.1.8 by Mark Purcell
Import upstream version 0.18
1666
        // Tags which are not de/encoded
1.3.2 by Robert Ancell
Import upstream version 0.21
1667
        { Tag::next, ignoreId,           newTiffDirectory<ignoreId>              },
1668
        {  Tag::all, ignoreId,           newTiffEntry                            }
1.1.8 by Mark Purcell
Import upstream version 0.18
1669
    };
1670
1671
    // TIFF mapping table for special decoding and encoding requirements
1672
    const TiffMappingInfo TiffMapping::tiffMappingInfo_[] = {
1.3.2 by Robert Ancell
Import upstream version 0.21
1673
        { "*",       Tag::all, ignoreId,  0, 0 }, // Do not decode tags with group == ignoreId
1674
        { "*",         0x02bc, ifd0Id,    &TiffDecoder::decodeXmp,          0 /*done before the tree is traversed*/ },
1675
        { "*",         0x83bb, ifd0Id,    &TiffDecoder::decodeIptc,         0 /*done before the tree is traversed*/ },
1676
        { "*",         0x8649, ifd0Id,    &TiffDecoder::decodeIptc,         0 /*done before the tree is traversed*/ }
1.1.8 by Mark Purcell
Import upstream version 0.18
1677
    };
1678
1679
    DecoderFct TiffMapping::findDecoder(const std::string& make,
1680
                                              uint32_t     extendedTag,
1.3.2 by Robert Ancell
Import upstream version 0.21
1681
                                              IfdId        group)
1.1.8 by Mark Purcell
Import upstream version 0.18
1682
    {
1683
        DecoderFct decoderFct = &TiffDecoder::decodeStdTiffEntry;
1684
        const TiffMappingInfo* td = find(tiffMappingInfo_,
1685
                                         TiffMappingInfo::Key(make, extendedTag, group));
1686
        if (td) {
1687
            // This may set decoderFct to 0, meaning that the tag should not be decoded
1688
            decoderFct = td->decoderFct_;
1689
        }
1690
        return decoderFct;
1691
    }
1692
1693
    EncoderFct TiffMapping::findEncoder(
1694
        const std::string& make,
1695
              uint32_t     extendedTag,
1.3.2 by Robert Ancell
Import upstream version 0.21
1696
              IfdId        group
1.1.8 by Mark Purcell
Import upstream version 0.18
1697
    )
1698
    {
1699
        EncoderFct encoderFct = 0;
1700
        const TiffMappingInfo* td = find(tiffMappingInfo_,
1701
                                         TiffMappingInfo::Key(make, extendedTag, group));
1702
        if (td) {
1703
            // Returns 0 if no special encoder function is found
1704
            encoderFct = td->encoderFct_;
1705
        }
1706
        return encoderFct;
1707
    }
1708
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1709
    bool TiffTreeStruct::operator==(const TiffTreeStruct::Key& key) const
1710
    {
1711
        return key.r_ == root_ && key.g_ == group_;
1712
    }
1713
1.1.8 by Mark Purcell
Import upstream version 0.18
1714
    TiffComponent::AutoPtr TiffCreator::create(uint32_t extendedTag,
1.3.2 by Robert Ancell
Import upstream version 0.21
1715
                                               IfdId    group)
1.1.8 by Mark Purcell
Import upstream version 0.18
1716
    {
1717
        TiffComponent::AutoPtr tc(0);
1718
        uint16_t tag = static_cast<uint16_t>(extendedTag & 0xffff);
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1719
        const TiffGroupStruct* ts = find(tiffGroupStruct_,
1720
                                         TiffGroupStruct::Key(extendedTag, group));
1.1.8 by Mark Purcell
Import upstream version 0.18
1721
        if (ts && ts->newTiffCompFct_) {
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1722
            tc = ts->newTiffCompFct_(tag, group);
1.1.8 by Mark Purcell
Import upstream version 0.18
1723
        }
1724
#ifdef DEBUG
1725
        else {
1726
            if (!ts) {
1727
                std::cerr << "Warning: No TIFF structure entry found for ";
1728
            }
1729
            else {
1730
                std::cerr << "Warning: No TIFF component creator found for ";
1731
            }
1732
            std::cerr << "extended tag 0x" << std::setw(4) << std::setfill('0')
1733
                      << std::hex << std::right << extendedTag
1.3.2 by Robert Ancell
Import upstream version 0.21
1734
                      << ", group " << ifdItem(group) << "\n";
1.1.8 by Mark Purcell
Import upstream version 0.18
1735
        }
1736
#endif
1737
        return tc;
1738
    } // TiffCreator::create
1739
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1740
    void TiffCreator::getPath(TiffPath& tiffPath,
1741
                              uint32_t  extendedTag,
1.3.2 by Robert Ancell
Import upstream version 0.21
1742
                              IfdId     group,
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1743
                              uint32_t  root)
1.1.8 by Mark Purcell
Import upstream version 0.18
1744
    {
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1745
        const TiffTreeStruct* ts = 0;
1.1.8 by Mark Purcell
Import upstream version 0.18
1746
        do {
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1747
            tiffPath.push(TiffPathItem(extendedTag, group));
1748
            ts = find(tiffTreeStruct_, TiffTreeStruct::Key(root, group));
1.1.8 by Mark Purcell
Import upstream version 0.18
1749
            assert(ts != 0);
1750
            extendedTag = ts->parentExtTag_;
1751
            group = ts->parentGroup_;
1.3.2 by Robert Ancell
Import upstream version 0.21
1752
        } while (!(ts->root_ == root && ts->group_ == ifdIdNotSet));
1.1.8 by Mark Purcell
Import upstream version 0.18
1753
1754
    } // TiffCreator::getPath
1755
1756
    ByteOrder TiffParserWorker::decode(
1757
              ExifData&          exifData,
1758
              IptcData&          iptcData,
1759
              XmpData&           xmpData,
1760
        const byte*              pData,
1761
              uint32_t           size,
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1762
              uint32_t           root,
1.1.8 by Mark Purcell
Import upstream version 0.18
1763
              FindDecoderFct     findDecoderFct,
1764
              TiffHeaderBase*    pHeader
1765
    )
1766
    {
1767
        // Create standard TIFF header if necessary
1768
        std::auto_ptr<TiffHeaderBase> ph;
1769
        if (!pHeader) {
1770
            ph = std::auto_ptr<TiffHeaderBase>(new TiffHeader);
1771
            pHeader = ph.get();
1772
        }
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1773
        TiffComponent::AutoPtr rootDir = parse(pData, size, root, pHeader);
1.1.8 by Mark Purcell
Import upstream version 0.18
1774
        if (0 != rootDir.get()) {
1775
            TiffDecoder decoder(exifData,
1776
                                iptcData,
1777
                                xmpData,
1778
                                rootDir.get(),
1779
                                findDecoderFct);
1780
            rootDir->accept(decoder);
1781
        }
1782
        return pHeader->byteOrder();
1783
1784
    } // TiffParserWorker::decode
1785
1786
    WriteMethod TiffParserWorker::encode(
1.2.4 by Mark Purcell
Import upstream version 0.19
1787
              BasicIo&           io,
1.1.8 by Mark Purcell
Import upstream version 0.18
1788
        const byte*              pData,
1789
              uint32_t           size,
1790
        const ExifData&          exifData,
1791
        const IptcData&          iptcData,
1792
        const XmpData&           xmpData,
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1793
              uint32_t           root,
1.1.8 by Mark Purcell
Import upstream version 0.18
1794
              FindEncoderFct     findEncoderFct,
1795
              TiffHeaderBase*    pHeader
1796
    )
1797
    {
1798
        /*
1799
           1) parse the binary image, if one is provided, and
1800
           2) attempt updating the parsed tree in-place ("non-intrusive writing")
1801
           3) else, create a new tree and write a new TIFF structure ("intrusive
1802
              writing"). If there is a parsed tree, it is only used to access the
1803
              image data in this case.
1804
         */
1805
        assert(pHeader);
1806
        assert(pHeader->byteOrder() != invalidByteOrder);
1807
        WriteMethod writeMethod = wmIntrusive;
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1808
        TiffComponent::AutoPtr parsedTree = parse(pData, size, root, pHeader);
1.3.1 by Mark Purcell
Import upstream version 0.20
1809
        PrimaryGroups primaryGroups;
1810
        findPrimaryGroups(primaryGroups, parsedTree.get());
1.1.8 by Mark Purcell
Import upstream version 0.18
1811
        if (0 != parsedTree.get()) {
1812
            // Attempt to update existing TIFF components based on metadata entries
1813
            TiffEncoder encoder(exifData,
1814
                                iptcData,
1815
                                xmpData,
1816
                                parsedTree.get(),
1.3.1 by Mark Purcell
Import upstream version 0.20
1817
                                false,
1818
                                &primaryGroups,
1819
                                pHeader,
1.1.8 by Mark Purcell
Import upstream version 0.18
1820
                                findEncoderFct);
1821
            parsedTree->accept(encoder);
1822
            if (!encoder.dirty()) writeMethod = wmNonIntrusive;
1823
        }
1824
        if (writeMethod == wmIntrusive) {
1.3.2 by Robert Ancell
Import upstream version 0.21
1825
            TiffComponent::AutoPtr createdTree = TiffCreator::create(root, ifdIdNotSet);
1.3.1 by Mark Purcell
Import upstream version 0.20
1826
            if (0 != parsedTree.get()) {
1827
                // Copy image tags from the original image to the composite
1828
                TiffCopier copier(createdTree.get(), root, pHeader, &primaryGroups);
1829
                parsedTree->accept(copier);
1830
            }
1831
            // Add entries from metadata to composite
1.1.8 by Mark Purcell
Import upstream version 0.18
1832
            TiffEncoder encoder(exifData,
1833
                                iptcData,
1834
                                xmpData,
1835
                                createdTree.get(),
1.3.1 by Mark Purcell
Import upstream version 0.20
1836
                                parsedTree.get() == 0,
1837
                                &primaryGroups,
1838
                                pHeader,
1.1.8 by Mark Purcell
Import upstream version 0.18
1839
                                findEncoderFct);
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1840
            encoder.add(createdTree.get(), parsedTree.get(), root);
1.1.8 by Mark Purcell
Import upstream version 0.18
1841
            // Write binary representation from the composite tree
1.2.4 by Mark Purcell
Import upstream version 0.19
1842
            DataBuf header = pHeader->write();
1843
            BasicIo::AutoPtr tempIo(io.temporary()); // may throw
1844
            assert(tempIo.get() != 0);
1845
            IoWrapper ioWrapper(*tempIo, header.pData_, header.size_);
1.1.8 by Mark Purcell
Import upstream version 0.18
1846
            uint32_t imageIdx(uint32_t(-1));
1.2.4 by Mark Purcell
Import upstream version 0.19
1847
            createdTree->write(ioWrapper,
1848
                               pHeader->byteOrder(),
1849
                               header.size_,
1850
                               uint32_t(-1),
1851
                               uint32_t(-1),
1852
                               imageIdx);
1853
            io.transfer(*tempIo); // may throw
1.1.8 by Mark Purcell
Import upstream version 0.18
1854
#ifdef DEBUG
1855
            std::cerr << "Intrusive writing\n";
1856
#endif
1857
        }
1858
#ifdef DEBUG
1859
        else {
1860
            std::cerr << "Non-intrusive writing\n";
1861
        }
1862
#endif
1863
        return writeMethod;
1864
    } // TiffParserWorker::encode
1865
1866
    TiffComponent::AutoPtr TiffParserWorker::parse(
1867
        const byte*              pData,
1868
              uint32_t           size,
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1869
              uint32_t           root,
1.1.8 by Mark Purcell
Import upstream version 0.18
1870
              TiffHeaderBase*    pHeader
1871
    )
1872
    {
1873
        if (pData == 0 || size == 0) return TiffComponent::AutoPtr(0);
1874
        if (!pHeader->read(pData, size) || pHeader->offset() >= size) {
1875
            throw Error(3, "TIFF");
1876
        }
1.3.2 by Robert Ancell
Import upstream version 0.21
1877
        TiffComponent::AutoPtr rootDir = TiffCreator::create(root, ifdIdNotSet);
1.1.8 by Mark Purcell
Import upstream version 0.18
1878
        if (0 != rootDir.get()) {
1879
            rootDir->setStart(pData + pHeader->offset());
1880
            TiffRwState::AutoPtr state(
1.2.2 by Mark Purcell
Import upstream version 0.18.1
1881
                new TiffRwState(pHeader->byteOrder(), 0));
1.1.8 by Mark Purcell
Import upstream version 0.18
1882
            TiffReader reader(pData, size, rootDir.get(), state);
1883
            rootDir->accept(reader);
1.2.4 by Mark Purcell
Import upstream version 0.19
1884
            reader.postProcess();
1.1.8 by Mark Purcell
Import upstream version 0.18
1885
        }
1886
        return rootDir;
1887
1888
    } // TiffParserWorker::parse
1889
1.3.1 by Mark Purcell
Import upstream version 0.20
1890
    void TiffParserWorker::findPrimaryGroups(PrimaryGroups& primaryGroups,
1891
                                             TiffComponent* pSourceDir)
1892
    {
1893
        if (0 == pSourceDir) return;
1894
1.3.2 by Robert Ancell
Import upstream version 0.21
1895
        const IfdId imageGroups[] = {
1896
            ifd0Id,
1897
            ifd1Id,
1898
            ifd2Id,
1899
            ifd3Id,
1900
            subImage1Id,
1901
            subImage2Id,
1902
            subImage3Id,
1903
            subImage4Id,
1904
            subImage5Id,
1905
            subImage6Id,
1906
            subImage7Id,
1907
            subImage8Id,
1908
            subImage9Id
1.3.1 by Mark Purcell
Import upstream version 0.20
1909
        };
1910
1911
        for (unsigned int i = 0; i < EXV_COUNTOF(imageGroups); ++i) {
1912
            TiffFinder finder(0x00fe, imageGroups[i]);
1913
            pSourceDir->accept(finder);
1914
            TiffEntryBase* te = dynamic_cast<TiffEntryBase*>(finder.result());
1915
            if (   te
1916
                && te->pValue()->typeId() == unsignedLong
1917
                && te->pValue()->count() == 1
1918
                && (te->pValue()->toLong() & 1) == 0) {
1919
                primaryGroups.push_back(te->group());
1920
            }
1921
        }
1922
1923
    } // TiffParserWorker::findPrimaryGroups
1924
1.1.5 by Jonathan Riddell
Import upstream version 0.16
1925
    TiffHeaderBase::TiffHeaderBase(uint16_t  tag,
1926
                                   uint32_t  size,
1927
                                   ByteOrder byteOrder,
1928
                                   uint32_t  offset)
1929
        : tag_(tag),
1930
          size_(size),
1931
          byteOrder_(byteOrder),
1932
          offset_(offset)
1933
    {
1934
    }
1935
1936
    TiffHeaderBase::~TiffHeaderBase()
1937
    {
1938
    }
1939
1940
    bool TiffHeaderBase::read(const byte* pData, uint32_t size)
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
1941
    {
1.1.8 by Mark Purcell
Import upstream version 0.18
1942
        if (!pData || size < 8) return false;
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
1943
1944
        if (pData[0] == 0x49 && pData[1] == 0x49) {
1945
            byteOrder_ = littleEndian;
1946
        }
1947
        else if (pData[0] == 0x4d && pData[1] == 0x4d) {
1948
            byteOrder_ = bigEndian;
1949
        }
1950
        else {
1951
            return false;
1952
        }
1953
        if (tag_ != getUShort(pData + 2, byteOrder_)) return false;
1954
        offset_ = getULong(pData + 4, byteOrder_);
1955
1956
        return true;
1.1.5 by Jonathan Riddell
Import upstream version 0.16
1957
    } // TiffHeaderBase::read
1958
1.2.4 by Mark Purcell
Import upstream version 0.19
1959
    DataBuf TiffHeaderBase::write() const
1.1.5 by Jonathan Riddell
Import upstream version 0.16
1960
    {
1.2.4 by Mark Purcell
Import upstream version 0.19
1961
        DataBuf buf(8);
1.1.8 by Mark Purcell
Import upstream version 0.18
1962
        switch (byteOrder_) {
1963
        case littleEndian:
1.2.4 by Mark Purcell
Import upstream version 0.19
1964
            buf.pData_[0] = 0x49;
1965
            buf.pData_[1] = 0x49;
1.1.8 by Mark Purcell
Import upstream version 0.18
1966
            break;
1967
        case bigEndian:
1.2.4 by Mark Purcell
Import upstream version 0.19
1968
            buf.pData_[0] = 0x4d;
1969
            buf.pData_[1] = 0x4d;
1.1.8 by Mark Purcell
Import upstream version 0.18
1970
            break;
1971
        case invalidByteOrder:
1972
            assert(false);
1973
            break;
1974
        }
1.2.4 by Mark Purcell
Import upstream version 0.19
1975
        us2Data(buf.pData_ + 2, tag_, byteOrder_);
1976
        ul2Data(buf.pData_ + 4, 0x00000008, byteOrder_);
1977
        return buf;
1.1.5 by Jonathan Riddell
Import upstream version 0.16
1978
    }
1979
1980
    void TiffHeaderBase::print(std::ostream& os, const std::string& prefix) const
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
1981
    {
1982
        os << prefix
1.1.8 by Mark Purcell
Import upstream version 0.18
1983
           << _("TIFF header, offset") << " = 0x"
1.1.5 by Jonathan Riddell
Import upstream version 0.16
1984
           << std::setw(8) << std::setfill('0') << std::hex << std::right
1985
           << offset_;
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
1986
1987
        switch (byteOrder_) {
1.1.3 by Mark Purcell
Import upstream version 0.14
1988
        case littleEndian:     os << ", " << _("little endian encoded"); break;
1989
        case bigEndian:        os << ", " << _("big endian encoded");    break;
1.1.1 by Ubuntu Merge-o-Matic
Import upstream version 0.10
1990
        case invalidByteOrder: break;
1991
        }
1992
        os << "\n";
1.1.5 by Jonathan Riddell
Import upstream version 0.16
1993
    } // TiffHeaderBase::print
1994
1995
    ByteOrder TiffHeaderBase::byteOrder() const
1996
    {
1997
        return byteOrder_;
1998
    }
1999
2000
    void TiffHeaderBase::setByteOrder(ByteOrder byteOrder)
2001
    {
2002
        byteOrder_ = byteOrder;
2003
    }
2004
2005
    uint32_t TiffHeaderBase::offset() const
2006
    {
2007
        return offset_;
2008
    }
2009
2010
    void TiffHeaderBase::setOffset(uint32_t offset)
2011
    {
2012
        offset_ = offset;
2013
    }
2014
2015
    uint32_t TiffHeaderBase::size() const
2016
    {
2017
        return size_;
2018
    }
2019
2020
    uint16_t TiffHeaderBase::tag() const
2021
    {
2022
        return tag_;
2023
    }
2024
1.3.2 by Robert Ancell
Import upstream version 0.21
2025
    bool TiffHeaderBase::isImageTag(      uint16_t       /*tag*/,
2026
                                          IfdId          /*group*/,
1.3.1 by Mark Purcell
Import upstream version 0.20
2027
                                    const PrimaryGroups* /*primaryGroups*/) const
2028
    {
2029
        return false;
2030
    }
2031
2032
    TiffHeader::TiffHeader(ByteOrder byteOrder, uint32_t offset, bool hasImageTags)
2033
        : TiffHeaderBase(42, 8, byteOrder, offset),
2034
          hasImageTags_(hasImageTags)
1.1.8 by Mark Purcell
Import upstream version 0.18
2035
    {
2036
    }
2037
2038
    TiffHeader::~TiffHeader()
2039
    {
2040
    }
2041
1.3.1 by Mark Purcell
Import upstream version 0.20
2042
    bool TiffHeader::isImageTag(      uint16_t       tag,
1.3.2 by Robert Ancell
Import upstream version 0.21
2043
                                      IfdId          group,
1.3.1 by Mark Purcell
Import upstream version 0.20
2044
                                const PrimaryGroups* pPrimaryGroups) const
2045
    {
2046
        //! List of TIFF image tags
2047
        static const TiffImgTagStruct tiffImageTags[] = {
1.3.2 by Robert Ancell
Import upstream version 0.21
2048
            { 0x00fe, ifd0Id }, // Exif.Image.NewSubfileType
2049
            { 0x00ff, ifd0Id }, // Exif.Image.SubfileType
2050
            { 0x0100, ifd0Id }, // Exif.Image.ImageWidth
2051
            { 0x0101, ifd0Id }, // Exif.Image.ImageLength
2052
            { 0x0102, ifd0Id }, // Exif.Image.BitsPerSample
2053
            { 0x0103, ifd0Id }, // Exif.Image.Compression
2054
            { 0x0106, ifd0Id }, // Exif.Image.PhotometricInterpretation
2055
            { 0x010a, ifd0Id }, // Exif.Image.FillOrder
2056
            { 0x0111, ifd0Id }, // Exif.Image.StripOffsets
2057
            { 0x0115, ifd0Id }, // Exif.Image.SamplesPerPixel
2058
            { 0x0116, ifd0Id }, // Exif.Image.RowsPerStrip
2059
            { 0x0117, ifd0Id }, // Exif.Image.StripByteCounts
2060
            { 0x011a, ifd0Id }, // Exif.Image.XResolution
2061
            { 0x011b, ifd0Id }, // Exif.Image.YResolution
2062
            { 0x011c, ifd0Id }, // Exif.Image.PlanarConfiguration
2063
            { 0x0122, ifd0Id }, // Exif.Image.GrayResponseUnit
2064
            { 0x0123, ifd0Id }, // Exif.Image.GrayResponseCurve
2065
            { 0x0124, ifd0Id }, // Exif.Image.T4Options
2066
            { 0x0125, ifd0Id }, // Exif.Image.T6Options
2067
            { 0x0128, ifd0Id }, // Exif.Image.ResolutionUnit
2068
            { 0x012d, ifd0Id }, // Exif.Image.TransferFunction
2069
            { 0x013d, ifd0Id }, // Exif.Image.Predictor
2070
            { 0x013e, ifd0Id }, // Exif.Image.WhitePoint
2071
            { 0x013f, ifd0Id }, // Exif.Image.PrimaryChromaticities
2072
            { 0x0140, ifd0Id }, // Exif.Image.ColorMap
2073
            { 0x0141, ifd0Id }, // Exif.Image.HalftoneHints
2074
            { 0x0142, ifd0Id }, // Exif.Image.TileWidth
2075
            { 0x0143, ifd0Id }, // Exif.Image.TileLength
2076
            { 0x0144, ifd0Id }, // Exif.Image.TileOffsets
2077
            { 0x0145, ifd0Id }, // Exif.Image.TileByteCounts
2078
            { 0x014c, ifd0Id }, // Exif.Image.InkSet
2079
            { 0x014d, ifd0Id }, // Exif.Image.InkNames
2080
            { 0x014e, ifd0Id }, // Exif.Image.NumberOfInks
2081
            { 0x0150, ifd0Id }, // Exif.Image.DotRange
2082
            { 0x0151, ifd0Id }, // Exif.Image.TargetPrinter
2083
            { 0x0152, ifd0Id }, // Exif.Image.ExtraSamples
2084
            { 0x0153, ifd0Id }, // Exif.Image.SampleFormat
2085
            { 0x0154, ifd0Id }, // Exif.Image.SMinSampleValue
2086
            { 0x0155, ifd0Id }, // Exif.Image.SMaxSampleValue
2087
            { 0x0156, ifd0Id }, // Exif.Image.TransferRange
2088
            { 0x0157, ifd0Id }, // Exif.Image.ClipPath
2089
            { 0x0158, ifd0Id }, // Exif.Image.XClipPathUnits
2090
            { 0x0159, ifd0Id }, // Exif.Image.YClipPathUnits
2091
            { 0x015a, ifd0Id }, // Exif.Image.Indexed
2092
            { 0x015b, ifd0Id }, // Exif.Image.JPEGTables
2093
            { 0x0200, ifd0Id }, // Exif.Image.JPEGProc
2094
            { 0x0201, ifd0Id }, // Exif.Image.JPEGInterchangeFormat
2095
            { 0x0202, ifd0Id }, // Exif.Image.JPEGInterchangeFormatLength
2096
            { 0x0203, ifd0Id }, // Exif.Image.JPEGRestartInterval
2097
            { 0x0205, ifd0Id }, // Exif.Image.JPEGLosslessPredictors
2098
            { 0x0206, ifd0Id }, // Exif.Image.JPEGPointTransforms
2099
            { 0x0207, ifd0Id }, // Exif.Image.JPEGQTables
2100
            { 0x0208, ifd0Id }, // Exif.Image.JPEGDCTables
2101
            { 0x0209, ifd0Id }, // Exif.Image.JPEGACTables
2102
            { 0x0211, ifd0Id }, // Exif.Image.YCbCrCoefficients
2103
            { 0x0212, ifd0Id }, // Exif.Image.YCbCrSubSampling
2104
            { 0x0213, ifd0Id }, // Exif.Image.YCbCrPositioning
2105
            { 0x0214, ifd0Id }, // Exif.Image.ReferenceBlackWhite
2106
            { 0x828d, ifd0Id }, // Exif.Image.CFARepeatPatternDim
2107
            { 0x828e, ifd0Id }, // Exif.Image.CFAPattern
2108
            { 0x8773, ifd0Id }, // Exif.Image.InterColorProfile
2109
            { 0x8824, ifd0Id }, // Exif.Image.SpectralSensitivity
2110
            { 0x8828, ifd0Id }, // Exif.Image.OECF
2111
            { 0x9102, ifd0Id }, // Exif.Image.CompressedBitsPerPixel
2112
            { 0x9217, ifd0Id }, // Exif.Image.SensingMethod
1.3.1 by Mark Purcell
Import upstream version 0.20
2113
        };
2114
2115
        if (!hasImageTags_) {
2116
#ifdef DEBUG
2117
            std::cerr << "No image tags in this image\n";
2118
#endif
2119
            return false;
2120
        }
2121
#ifdef DEBUG
1.3.2 by Robert Ancell
Import upstream version 0.21
2122
        ExifKey key(tag, ifdItem(group));
1.3.1 by Mark Purcell
Import upstream version 0.20
2123
#endif
2124
        // If there are primary groups and none matches group, we're done
2125
        if (   pPrimaryGroups != 0
2126
            && !pPrimaryGroups->empty()
2127
            && std::find(pPrimaryGroups->begin(), pPrimaryGroups->end(), group)
2128
               == pPrimaryGroups->end()) {
2129
#ifdef DEBUG
2130
            std::cerr << "Not an image tag: " << key << " (1)\n";
2131
#endif
2132
            return false;
2133
        }
2134
        // All tags of marked primary groups other than IFD0 are considered
2135
        // image tags. That should take care of NEFs until we know better.
2136
        if (   pPrimaryGroups != 0
2137
            && !pPrimaryGroups->empty()
1.3.2 by Robert Ancell
Import upstream version 0.21
2138
            && group != ifd0Id) {
1.3.1 by Mark Purcell
Import upstream version 0.20
2139
#ifdef DEBUG
1.3.2 by Robert Ancell
Import upstream version 0.21
2140
            ExifKey key(tag, ifdItem(group));
1.3.1 by Mark Purcell
Import upstream version 0.20
2141
            std::cerr << "Image tag: " << key << " (2)\n";
2142
#endif
2143
            return true;
2144
        }
2145
        // If tag, group is one of the image tags listed above -> bingo!
2146
        if (find(tiffImageTags, TiffImgTagStruct::Key(tag, group))) {
2147
#ifdef DEBUG
1.3.2 by Robert Ancell
Import upstream version 0.21
2148
            ExifKey key(tag, ifdItem(group));
1.3.1 by Mark Purcell
Import upstream version 0.20
2149
            std::cerr << "Image tag: " << key << " (3)\n";
2150
#endif
2151
            return true;
2152
        }
2153
#ifdef DEBUG
2154
        std::cerr << "Not an image tag: " << key << " (4)\n";
2155
#endif
2156
        return false;
2157
    }
2158
1.1.8 by Mark Purcell
Import upstream version 0.18
2159
}}                                       // namespace Internal, Exiv2