/*
 * libopenraw - arwfile.cpp
 *
 * Copyright (C) 2006-2023 Hubert Figuière
 *
 * This library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 */

#include <libopenraw/cameraids.h>

#include "arwfile.hpp"
#include "ifdfilecontainer.hpp"
#include "rawfile_private.hpp"

using namespace Debug;

namespace OpenRaw {

class RawData;

namespace Internals {

#define OR_MAKE_SONY_TYPEID(camid)                                             \
    OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_SONY, camid)

static const ModelIdMap modelid_map = {
    /* source: https://exiftool.org/TagNames/Sony.html */
    /* SR2 */
    { 2, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_R1) },
    /* ARW */
    { 256, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A100) },
    { 257, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A900) },
    { 258, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A700) },
    { 259, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A200) },
    { 260, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A350) },
    { 261, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A300) },
    // 262 DSLR-A900 (APS-C mode)
    { 263, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A380) },
    { 263, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A390) },
    { 264, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A330) },
    { 265, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A230) },
    { 266, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A290) },
    { 269, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A850) },
    // 270 DSLR-A850 (APS-C mode)
    { 273, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A550) },
    { 274, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A500) },
    { 275, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A450) },
    { 278, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5) },
    { 279, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX3) },
    { 280, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA33) },
    { 281, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA55) },
    { 282, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A560) },
    { 283, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A580) },
    { 284, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEXC3) },
    { 285, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA35) },
    { 286, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA65) },
    { 287, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA77) },
    { 288, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5N) },
    { 289, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX7) },
    // 290 NEX-VG20E
    { 291, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA37) },
    { 292, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA57) },
    { 293, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEXF3) },
    { 294, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA99) },
    { 295, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX6) },
    { 296, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5R) },
    { 297, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100) },
    { 298, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1) },
    // 299 NEX-VG900
    // 300 NEX-VG30E
    { 302, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE3000) },
    { 303, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA58) },
    { 305, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX3N) },
    { 306, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7) },
    { 307, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5T) },
    { 308, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M2) },
    { 309, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10) },
    { 310, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1R) },
    { 311, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7R) },
    { 312, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6000) },
    { 313, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE5000) },
    { 317, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M3) },
    { 318, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7S) },
    { 319, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA77M2) },
    { 339, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE5100) },
    { 340, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M2) },
    { 341, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M4) },
    { 342, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M2) },
    { 344, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1RM2) },
    { 346, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCEQX1) },
    { 347, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM2) },
    { 350, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7SM2) },
    { 353, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA68) },
    { 354, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA99M2) },
    { 355, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M3) },
    { 356, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M5) },
    { 357, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6300) },
    { 358, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE9) },
    { 360, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6500) },
    { 362, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM3) },
    { 363, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M3) },
    { 364, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX0) },
    { 365, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M4) },
    { 366, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M6) },
    { 367, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_HX99) },
    { 369, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M5A) },
    { 371, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6400) },
    { 372, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX0M2) },
    { 373, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_HX95) },
    { 374, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M7) },
    { 375, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM4) },
    { 376, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE9M2) },
    { 378, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6600) },
    { 379, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6100) },
    { 380, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZV1) },
    { 381, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7C) },
    { 382, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZVE10) },
    { 383, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7SM3) },
    { 384, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE1) },
    { 386, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM3A) },
    { 387, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM4A) },
    { 388, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M4) },
    { 390, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM5) },
    { 391, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILME_FX30) },
    { 393, OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZVE1) },
};

/* taken from dcraw, by default */
static const BuiltinColourMatrix s_matrices[] = {
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A100),
      0,
      0xfeb,
      { 9437, -2811, -774, -8405, 16215, 2290, -710, 596, 7181 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A200),
      0,
      0,
      { 9847, -3091, -928, -8485, 16345, 2225, -715, 595, 7103 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A230),
      0,
      0,
      { 9847, -3091, -928, -8485, 16345, 2225, -715, 595, 7103 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A290),
      0,
      0,
      { 6038, -1484, -579, -9145, 16746, 2512, -875, 746, 7218 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A300),
      0,
      0,
      { 9847, -3091, -928, -8485, 16345, 2225, -715, 595, 7103 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A330),
      0,
      0,
      { 9847, -3091, -928, -8485, 16345, 2225, -715, 595, 7103 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A350),
      0,
      0,
      { 6038, -1484, -579, -9145, 16746, 2512, -875, 746, 7218 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A380),
      0,
      0,
      { 6038, -1484, -579, -9145, 16746, 2512, -875, 746, 7218 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A450),
      128,
      0xfeb,
      { 4950, -580, -103, -5228, 12542, 3029, -709, 1435, 7371 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A500),
      0,
      0,
      { 6046, -1127, -278, -5574, 13076, 2786, -691, 1419, 7625 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A550),
      128,
      0xfeb,
      { 4950, -580, -103, -5228, 12542, 3029, -709, 1435, 7371 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A560),
      128,
      0xfeb,
      { 4950, -580, -103, -5228, 12542, 3029, -709, 1435, 7371 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A580),
      128,
      0,
      { 5932, -1492, -411, -4813, 12285, 2856, -741, 1524, 6739 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A700),
      126,
      0,
      { 5775, -805, -359, -8574, 16295, 2391, -1943, 2341, 7249 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A850),
      128,
      0,
      { 5413, -1162, -365, -5665, 13098, 2866, -608, 1179, 8440 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A900),
      128,
      0,
      { 5209, -1072, -397, -8845, 16120, 2919, -1618, 1803, 8654 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA33),
      128,
      0,
      { 6069, -1221, -366, -5221, 12779, 2734, -1024, 2066, 6834 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA35),
      128,
      0,
      { 5986, -1618, -415, -4557, 11820, 3120, -681, 1404, 6971 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA37),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA55),
      128,
      0,
      { 5932, -1492, -411, -4813, 12285, 2856, -741, 1524, 6739 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA57),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA58),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA65),
      128,
      0,
      { 5491, -1192, -363, -4951, 12342, 2948, -911, 1722, 7192 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA68),
      128,
      0,
      { 6435, -1903, -536, -4722, 12449, 2550, -663, 1363, 6517 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA77),
      128,
      0,
      { 5491, -1192, -363, -4951, 12342, 2948, -911, 1722, 7192 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA77M2),
      128,
      0,
      { 5991, -1732, -443, -4100, 11989, 2381, -704, 1467, 5992 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA99),
      0,
      0,
      { 6344, -1612, -462, -4863, 12477, 2681, -865, 1786, 6899 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA99M2),
      0,
      0,
      { 6660, -1918, -471, -4613, 12398, 2485, -649, 1433, 6447 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX3),
      128,
      0, /* Adobe */
      { 6549, -1550, -436, -4880, 12435, 2753, -854, 1868, 6976 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_HX95),
      0,
      0,
      { 13076, -5686, -1481, -4027, 12851, 1251, -167, 725, 4937 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_HX99),
      0,
      0,
      { 13076, -5686, -1481, -4027, 12851, 1251, -167, 725, 4937 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX3N),
      128,
      0,
      { 6129, -1545, -418, -4930, 12490, 2743, -977, 1693, 6615 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5),
      128,
      0, /* Adobe */
      { 6549, -1550, -436, -4880, 12435, 2753, -854, 1868, 6976 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5N),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5R),
      128,
      0,
      { 6129, -1545, -418, -4930, 12490, 2743, -977, 1693, 6615 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5T),
      128,
      0,
      { 6129, -1545, -418, -4930, 12490, 2743, -977, 1693, 6615 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEXC3),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEXF3),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX6),
      128,
      0,
      { 6129, -1545, -418, -4930, 12490, 2743, -977, 1693, 6615 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX7),
      128,
      0,
      { 5491, -1192, -363, -4951, 12342, 2948, -911, 1722, 7192 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_R1),
      0,
      0,
      { 8512, -2641, -694, -8041, 15670, 2526, -1820, 2117, 7414 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100),
      0,
      0,
      { 8651, -2754, -1057, -3464, 12207, 1373, -568, 1398, 4434 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M2),
      0,
      0,
      { 6596, -2079, -562, -4782, 13016, 1933, -970, 1581, 5181 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M3),
      0,
      0,
      { 6596, -2079, -562, -4782, 13016, 1933, -970, 1581, 5181 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M4),
      0,
      0,
      { 6596, -2079, -562, -4782, 13016, 1933, -970, 1581, 5181 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M5),
      0,
      0,
      { 6596, -2079, -562, -4782, 13016, 1933, -970, 1581, 5181 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M5A),
      0,
      0,
      { 11176, -4700, -965, -4004, 12184, 2032, -763, 1726, 5876 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M6),
      0,
      0,
      { 7325, -2321, -596, -3494, 11674, 2055, -668, 1562, 5031 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M7),
      0,
      0,
      { 7325, -2321, -596, -3494, 11674, 2055, -668, 1562, 5031 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX0),
      0,
      0,
      { 9396, -3507, -843, -2497, 11111, 1572, -343, 1355, 5089 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX0M2),
      0,
      0,
      { 9396, -3507, -843, -2497, 11111, 1572, -343, 1355, 5089 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1),
      0,
      0,
      { 6344, -1612, -462, -4863, 12477, 2681, -865, 1786, 6899 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1R),
      0,
      0,
      { 6344, -1612, -462, -4863, 12477, 2681, -865, 1786, 6899 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1RM2),
      0,
      0,
      { 6629, -1900, -483, -4618, 12349, 2550, -622, 1381, 6514 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10),
      0,
      0,
      { 6679, -1825, -745, -5047, 13256, 1953, -1580, 2422, 5183 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M2),
      0,
      0,
      { 6679, -1825, -745, -5047, 13256, 1953, -1580, 2422, 5183 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M3),
      0,
      0,
      { 6679, -1825, -745, -5047, 13256, 1953, -1580, 2422, 5183 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M4),
      0,
      0,
      { 7699, -2566, -629, -2967, 11270, 1928, -378, 1286, 4807 } },

    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE1),
      128,
      0,
      { 8161, -2947, -739, -4811, 12668, 2389, -437, 1229, 6524 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE3000),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE5000),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE5100),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6000),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6100),
      128,
      0,
      { 7657, -2847, -607, -4083, 11966, 2389, -684, 1418, 5844 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6300),
      0,
      0,
      { 5973, -1695, -419, -3826, 11797, 2293, -639, 1398, 5789 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6400),
      0,
      0,
      { 5973, -1695, -419, -3826, 11797, 2293, -639, 1398, 5789 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6500),
      0,
      0,
      { 5973, -1695, -419, -3826, 11797, 2293, -639, 1398, 5789 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6600),
      128,
      0,
      { 7657, -2847, -607, -4083, 11966, 2389, -684, 1418, 5844 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7),
      128,
      0,
      { 5271, -712, -347, -6153, 13653, 2763, -1601, 2366, 7242 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M2),
      128,
      0,
      { 5271, -712, -347, -6153, 13653, 2763, -1601, 2366, 7242 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M3),
      128,
      0,
      { 7374, -2389, -551, -5435, 13162, 2519, -1006, 1795, 6552 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M4),
      128,
      0,
      { 7460, -2365, -588, -5687, 13442, 2474, -624, 1156, 6584 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7R),
      128,
      0,
      { 4913, -541, -202, -6130, 13513, 2906, -1564, 2151, 7183 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM2),
      0,
      0,
      { 6629, -1900, -483, -4618, 12349, 2550, -622, 1381, 6514 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM3),
      0,
      0,
      { 6640, -1847, -503, -5238, 13010, 2474, -993, 1673, 6527 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM3A),
      0,
      0,
      { 6640, -1847, -503, -5238, 13010, 2474, -993, 1673, 6527 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM4),
      0,
      0,
      { 6640, -1847, -503, -5238, 13010, 2474, -993, 1673, 6527 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM4A),
      0,
      0,
      { 7662, -2686, -660, -5240, 12965, 2530, -796, 1508, 6167 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM5),
      0,
      0,
      { 8200, -2976, -719, -4296, 12053, 2532, -429, 1282, 5774 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7S),
      128,
      0,
      { 5838, -1430, -246, -3497, 11477, 2297, -748, 1885, 5778 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7SM2),
      128,
      0,
      { 5838, -1430, -246, -3497, 11477, 2297, -748, 1885, 5778 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7SM3),
      128,
      0,
      { 6912, -2127, -469, -4470, 12175, 2587, -398, 1478, 6492 } },

    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7C),
      128,
      0,
      { 7374, -2389, -551, -5435, 13162, 2519, -1006, 1795, 6552 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE9),
      128,
      0,
      { 6389, -1703, -378, -4562, 12265, 2587, -670, 1489, 6550 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE9M2),
      128,
      0,
      { 6389, -1703, -378, -4562, 12265, 2587, -670, 1489, 6550 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCEQX1),
      128,
      0,
      { 5991, -1456, -455, -4764, 12135, 2980, -707, 1425, 6701 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILME_FX30),
      128,
      0,
      { 6972, -2408, -600, -4330, 12101, 2515, -388, 1277, 5847 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZV1),
      128,
      0,
      { 8280, -2987, -703, -3531, 11645, 2133, -550, 1542, 5312 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZVE1),
      128,
      0,
      { 6912, -2127, -469, -4470, 12175, 2587, -398, 1478, 6492 } },
    { OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZVE10),
      128,
      0,
      { 6355, -2067, -490, -3653, 11542, 2400, -406, 1258, 5506 } },

    /* The Hasselblad Lunar is like a Nex7 */
    { OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_HASSELBLAD,
                          OR_TYPEID_HASSELBLAD_LUNAR),
      128,
      0,
      { 5491, -1192, -363, -4951, 12342, 2948, -911, 1722, 7192 } },

    { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
};

const IfdFile::camera_ids_t ArwFile::s_def[] = {
    { "DSLR-A100", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A100) },
    { "DSLR-A200", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A200) },
    { "DSLR-A230", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A230) },
    { "DSLR-A290", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A290) },
    { "DSLR-A300", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A300) },
    { "DSLR-A330", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A330) },
    { "DSLR-A350", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A350) },
    { "DSLR-A380", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A380) },
    { "DSLR-A390", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A390) },
    { "DSLR-A450", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A450) },
    { "DSLR-A500", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A500) },
    { "DSLR-A550", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A550) },
    { "DSLR-A560", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A560) },
    { "DSLR-A580", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A580) },
    { "DSLR-A700", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A700) },
    { "DSLR-A850", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A850) },
    { "DSLR-A900", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_A900) },
    { "SLT-A33", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA33) },
    { "SLT-A35", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA35) },
    { "SLT-A37", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA37) },
    { "SLT-A55V", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA55) },
    { "SLT-A57", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA57) },
    { "SLT-A58", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA58) },
    { "SLT-A65V", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA65) },
    { "SLT-A77V", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA77) },
    { "SLT-A99V", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_SLTA99) },
    { "NEX-3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX3) },
    { "NEX-3N", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX3N) },
    { "NEX-5", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5) },
    { "NEX-5N", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5N) },
    { "NEX-5R", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5R) },
    { "NEX-5T", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX5T) },
    { "NEX-C3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEXC3) },
    { "NEX-F3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEXF3) },
    { "NEX-6", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX6) },
    { "NEX-7", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_NEX7) },
    { "DSC-HX95", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_HX95) },
    { "DSC-HX99", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_HX99) },
    { "DSC-R1", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_R1) },
    { "DSC-RX10", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10) },
    { "DSC-RX10M2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M2) },
    { "DSC-RX10M3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M3) },
    { "DSC-RX10M4", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX10M4) },
    { "DSC-RX100", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100) },
    { "DSC-RX100M2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M2) },
    { "DSC-RX100M3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M3) },
    { "DSC-RX100M4", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M4) },
    { "DSC-RX100M5", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M5) },
    { "DSC-RX100M5A", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M5A) },
    { "DSC-RX100M6", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M6) },
    { "DSC-RX100M7", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX100M7) },
    { "DSC-RX0", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX0) },
    { "DSC-RX0M2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX0M2) },
    { "DSC-RX1", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1) },
    { "DSC-RX1R", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1R) },
    { "DSC-RX1RM2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_RX1RM2) },
    { "ILCA-68", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA68) },
    { "ILCA-77M2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA77M2) },
    { "ILCA-99M2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCA99M2) },
    { "ILCE-1", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE1) },
    { "ILCE-3000", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE3000) },
    { "ILCE-3500", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE3500) },
    { "ILCE-5000", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE5000) },
    { "ILCE-5100", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE5100) },
    { "ILCE-6000", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6000) },
    { "ILCE-6100", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6100) },
    { "ILCE-6300", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6300) },
    { "ILCE-6400", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6400) },
    { "ILCE-6500", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6500) },
    { "ILCE-6600", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE6600) },
    { "ILCE-7", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7) },
    { "ILCE-7C", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7C) },
    { "ILCE-7M2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M2) },
    { "ILCE-7M3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M3) },
    { "ILCE-7M4", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7M4) },
    { "ILCE-7R", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7R) },
    { "ILCE-7RM2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM2) },
    { "ILCE-7RM3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM3) },
    { "ILCE-7RM3A", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM3A) },
    { "ILCE-7RM4", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM4) },
    { "ILCE-7RM4A", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM4A) },
    { "ILCE-7RM5", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7RM5) },
    { "ILCE-7S", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7S) },
    { "ILCE-7SM2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7SM2) },
    { "ILCE-7SM3", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE7SM3) },
    { "ILCE-9", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE9) },
    { "ILCE-9M2", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCE9M2) },
    { "ILCE-QX1", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ILCEQX1) },
    { "ZV-1", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZV1) },
    { "ZV-E1", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZVE1) },
    { "ZV-E10", OR_MAKE_SONY_TYPEID(OR_TYPEID_SONY_ZVE10) },

    { "Lunar", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_HASSELBLAD,
                                   OR_TYPEID_HASSELBLAD_LUNAR) },
    { 0, 0 }
};

RawFile *ArwFile::factory(const IO::Stream::Ptr &s)
{
    return new ArwFile(s);
}

ArwFile::ArwFile(const IO::Stream::Ptr &s)
    : TiffEpFile(s, OR_RAWFILE_TYPE_ARW)
{
    _setIdMap(s_def);
    _setMatrices(s_matrices);
}

ArwFile::~ArwFile()
{
}

IfdDir::Ref ArwFile::_locateCfaIfd()
{
    if (!isA100()) {
        return TiffEpFile::_locateCfaIfd();
    }
    return mainIfd();
}

::or_error ArwFile::_getRawData(RawData &data, uint32_t options)
{
    if (isA100()) {
        // TODO implement for A100
        return OR_ERROR_NOT_FOUND;
    }
    return TiffEpFile::_getRawData(data, options);
}

bool ArwFile::vendorCameraIdLocation(Internals::IfdDir::Ref& ifd, uint16_t& index,
                            const ModelIdMap*& model_map)
{
    auto mn = makerNoteIfd();
    if (mn) {
        // There is a camera model ID in the MakerNote tag 0xb001.
        ifd = mn;
        index = IFD::MNOTE_SONY_MODEL_ID;
        model_map = &modelid_map;
        return true;
    }
    return false;
}

}
}
/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0))
  indent-tabs-mode:nil
  fill-column:80
  End:
*/
