File indexing completed on 2025-01-05 03:57:01

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
0005  dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
0006  LibRaw do not use RESTRICTED code from dcraw.c
0007 
0008  LibRaw is free software; you can redistribute it and/or modify
0009  it under the terms of the one of two licenses as you choose:
0010 
0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0012    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0013 
0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0015    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0016 
0017  */
0018 
0019 #include "../../internal/dcraw_defs.h"
0020 
0021 void LibRaw::parseSigmaMakernote (int base, int /*uptag*/, unsigned /*dng_writer*/) {
0022 unsigned wb_table1 [] = {
0023   LIBRAW_WBI_Auto, LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy,
0024   LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Flash,
0025   LIBRAW_WBI_Custom, LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2
0026 };
0027 
0028   unsigned entries, tag, type, len, save;
0029   unsigned i;
0030 
0031   entries = get2();
0032   if (entries > 1000)
0033     return;
0034   while (entries--) {
0035     tiff_get(base, &tag, &type, &len, &save);
0036     if (tag == 0x0027) {
0037       ilm.LensID = get2();
0038     } else if (tag == 0x002a) {
0039       ilm.MinFocal = getreal(type);
0040       ilm.MaxFocal = getreal(type);
0041     } else if (tag == 0x002b) {
0042       ilm.MaxAp4MinFocal = getreal(type);
0043       ilm.MaxAp4MaxFocal = getreal(type);
0044     } else if (tag == 0x0120) {
0045       const unsigned tblsz = (sizeof wb_table1 / sizeof wb_table1[0]);
0046       if ((len >= tblsz) && (len%3 == 0) && len/3 <= tblsz) {
0047         for (i=0; i<(len/3); i++) {
0048           icWBC[wb_table1[i]][0] = (int)(getreal(type)*10000.0);
0049           icWBC[wb_table1[i]][1] = icWBC[wb_table1[i]][3] = (int)(getreal(type)*10000.0);
0050           icWBC[wb_table1[i]][2] = (int)(getreal(type)*10000.0);
0051         }
0052       }
0053     }
0054     fseek(ifp, save, SEEK_SET);
0055   }
0056 
0057   return;
0058 }
0059 
0060 void LibRaw::parse_makernote_0xc634(int base, int uptag, unsigned dng_writer)
0061 {
0062 
0063   if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
0064     throw LIBRAW_EXCEPTION_IO_CORRUPT;
0065 
0066   if (!strncmp(make, "NIKON", 5))
0067   {
0068     parseNikonMakernote(base, uptag, AdobeDNG);
0069     return;
0070   }
0071   else if (!strncasecmp(make, "LEICA", 5))
0072   {
0073     parseLeicaMakernote(base, uptag, is_0xc634);
0074     return;
0075   }
0076 
0077   short morder, sorder = order;
0078   char buf[10];
0079   INT64 fsize = ifp->size();
0080 
0081   fread(buf, 1, 10, ifp);
0082 
0083   if (!strcmp(buf, "EPSON"))
0084   {
0085     parseEpsonMakernote(base, uptag, AdobeDNG);
0086     return;
0087   }
0088   else if (!strcmp(buf, "SIGMA"))
0089   {
0090     parseSigmaMakernote(base, uptag, AdobeDNG);
0091     return;
0092   }
0093 
0094   unsigned entries, tag, type, len, save, c;
0095 
0096   uchar *CanonCameraInfo = NULL;
0097   unsigned lenCanonCameraInfo = 0;
0098   unsigned typeCanonCameraInfo = 0;
0099 
0100   uchar *table_buf_0x0116;
0101   ushort table_buf_0x0116_len = 0;
0102   uchar *table_buf_0x2010;
0103   ushort table_buf_0x2010_len = 0;
0104   uchar *table_buf_0x9050;
0105   ushort table_buf_0x9050_len = 0;
0106   uchar *table_buf_0x9400;
0107   ushort table_buf_0x9400_len = 0;
0108   uchar *table_buf_0x9402;
0109   ushort table_buf_0x9402_len = 0;
0110   uchar *table_buf_0x9403;
0111   ushort table_buf_0x9403_len = 0;
0112   uchar *table_buf_0x9406;
0113   ushort table_buf_0x9406_len = 0;
0114   uchar *table_buf_0x940c;
0115   ushort table_buf_0x940c_len = 0;
0116   uchar *table_buf_0x940e;
0117   ushort table_buf_0x940e_len = 0;
0118 
0119   if (!strcmp(buf, "OLYMPUS") || !strcmp(buf, "PENTAX ") || !strncmp(buf,"OM SYS",6)||
0120       (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG)))
0121   {
0122     base = ftell(ifp) - 10;
0123     fseek(ifp, -2, SEEK_CUR);
0124     order = get2();
0125     if (buf[0] == 'O')
0126       get2();
0127     else if (buf[0] == 'P')
0128       is_PentaxRicohMakernotes = 1;
0129   }
0130   else if (is_PentaxRicohMakernotes && (dng_writer == CameraDNG))
0131   {
0132     base = ftell(ifp) - 10;
0133     fseek(ifp, -4, SEEK_CUR);
0134     order = get2();
0135   }
0136   else if (!strncmp(buf, "SONY", 4) ||
0137            !strcmp(buf, "Panasonic"))
0138   {
0139     order = 0x4949;
0140     fseek(ifp, 2, SEEK_CUR);
0141   }
0142   else if (!strncmp(buf, "FUJIFILM", 8))
0143   {
0144     base = ftell(ifp) - 10;
0145     order = 0x4949;
0146     fseek(ifp, 2, SEEK_CUR);
0147   }
0148   else if (!strcmp(buf, "OLYMP") ||
0149            !strcmp(buf, "Ricoh"))
0150   {
0151     fseek(ifp, -2, SEEK_CUR);
0152   }
0153   else if (!strcmp(buf, "AOC") || !strcmp(buf, "QVC"))
0154   {
0155     fseek(ifp, -4, SEEK_CUR);
0156   }
0157   else
0158   {
0159     fseek(ifp, -10, SEEK_CUR);
0160     if ((!strncmp(make, "SAMSUNG", 7) && (dng_writer == AdobeDNG)))
0161       base = ftell(ifp);
0162   }
0163 
0164   entries = get2();
0165   if (entries > 1000)
0166     return;
0167 
0168   if (!strncasecmp(make, "SONY", 4) ||
0169       !strncasecmp(make, "Konica", 6) ||
0170       !strncasecmp(make, "Minolta", 7) ||
0171       (!strncasecmp(make, "Hasselblad", 10) &&
0172        (!strncasecmp(model, "Stellar", 7) ||
0173         !strncasecmp(model, "Lunar", 5) ||
0174         !strncasecmp(model, "Lusso", 5) ||
0175         !strncasecmp(model, "HV", 2))))
0176     is_Sony = 1;
0177 
0178   if (!is_Olympus &&
0179       (!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) ||
0180       (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) {
0181     is_Olympus = 1;
0182     OlympusDNG_SubDirOffsetValid =
0183           strncmp(model, "E-300", 5) && strncmp(model, "E-330", 5) &&
0184           strncmp(model, "E-400", 5) && strncmp(model, "E-500", 5) &&
0185           strncmp(model, "E-1", 3);
0186   }
0187 
0188   morder = order;
0189   while (entries--)
0190   {
0191     order = morder;
0192 
0193     tiff_get(base, &tag, &type, &len, &save);
0194 
0195     INT64 pos = ifp->tell();
0196     if (len > 8 && pos + len > 2 * fsize)
0197     {
0198       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0199       continue;
0200     }
0201     tag |= uptag << 16;
0202     if (len > 100 * 1024 * 1024)
0203       goto next; // 100Mb tag? No!
0204 
0205     if (!strncmp(make, "Canon", 5))
0206     {
0207       if (tag == 0x000d && len < 256000)
0208       { // camera info
0209         if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0210         {
0211           CanonCameraInfo = (uchar *)malloc(MAX(16, len));
0212           fread(CanonCameraInfo, len, 1, ifp);
0213         }
0214         else
0215         {
0216           CanonCameraInfo = (uchar *)malloc(MAX(16, len * 4));
0217           fread(CanonCameraInfo, len, 4, ifp);
0218         }
0219         lenCanonCameraInfo = len;
0220         typeCanonCameraInfo = type;
0221       }
0222 
0223       else if (tag == 0x0010) // Canon ModelID
0224       {
0225         unique_id = get4();
0226         setCanonBodyFeatures(unique_id);
0227         if (lenCanonCameraInfo)
0228         {
0229           processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo,
0230                                  typeCanonCameraInfo, AdobeDNG);
0231           free(CanonCameraInfo);
0232           CanonCameraInfo = 0;
0233           lenCanonCameraInfo = 0;
0234         }
0235       }
0236 
0237       else
0238         parseCanonMakernotes(tag, type, len, AdobeDNG);
0239     }
0240 
0241     else if (!strncmp(make, "FUJI", 4)) {
0242       parseFujiMakernotes(tag, type, len, AdobeDNG);
0243 
0244     } else if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
0245       if (tag == 0x0011) {
0246         imHassy.SensorCode = getint(type);
0247       } else if ((tag == 0x0015) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) {
0248         stmread (imHassy.SensorUnitConnector, len, ifp);
0249         for (int i=0; i<(int)len; i++) {
0250           if(!isalnum(imHassy.SensorUnitConnector[i]) &&
0251              (imHassy.SensorUnitConnector[i]!=' ')    &&
0252              (imHassy.SensorUnitConnector[i]!='/')    &&
0253              (imHassy.SensorUnitConnector[i]!='-')) {
0254             imHassy.SensorUnitConnector[0] = 0;
0255             break;
0256           }
0257         }
0258       } else if (tag == 0x0016) {
0259         imHassy.CoatingCode = getint(type);
0260       } else if ((tag == 0x002a) &&
0261                  tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) &&
0262                  (len == 12) &&
0263                  imHassy.SensorUnitConnector[0]) {
0264         FORC4 for (int i = 0; i < 3; i++)
0265                 imHassy.mnColorMatrix[c][i] = getreal(type);
0266 
0267       } else if ((tag == 0x0031) &&
0268                  imHassy.SensorUnitConnector[0]) {
0269         imHassy.RecommendedCrop[0] = getint(type);
0270         imHassy.RecommendedCrop[1] = getint(type);
0271       }
0272 
0273     } else if (is_Olympus) {
0274 
0275       if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) ||
0276           (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
0277           (tag == 0x3000))
0278       {
0279         fseek(ifp, save - 4, SEEK_SET);
0280         fseek(ifp, base + get4(), SEEK_SET);
0281         parse_makernote_0xc634(base, tag, dng_writer);
0282       }
0283 
0284       if (!OlympusDNG_SubDirOffsetValid &&
0285           ((len > 4) ||
0286            ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) ||
0287             tagtypeIs(LIBRAW_EXIFTAG_TYPE_SSHORT)) && (len > 2)) ||
0288            ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) ||
0289              tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG)) && (len > 1)) ||
0290            tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL) ||
0291            (type > LIBRAW_EXIFTAG_TYPE_SLONG))) {
0292         goto skip_Oly_broken_tags;
0293       }
0294       else {
0295         parseOlympusMakernotes(base, tag, type, len, AdobeDNG);
0296       }
0297     skip_Oly_broken_tags:;
0298     }
0299 
0300     else if (!strncmp(make, "PENTAX", 6)  ||
0301              !strncmp(model, "PENTAX", 6) ||
0302              is_PentaxRicohMakernotes)
0303     {
0304       parsePentaxMakernotes(base, tag, type, len, dng_writer);
0305     }
0306     else if (!strncmp(make, "SAMSUNG", 7))
0307     {
0308       if (dng_writer == AdobeDNG)
0309         parseSamsungMakernotes(base, tag, type, len, dng_writer);
0310       else
0311         parsePentaxMakernotes(base, tag, type, len, dng_writer);
0312     }
0313     else if (is_Sony)
0314     {
0315       parseSonyMakernotes(
0316           base, tag, type, len, AdobeDNG,
0317           table_buf_0x0116, table_buf_0x0116_len,
0318           table_buf_0x2010, table_buf_0x2010_len,
0319           table_buf_0x9050, table_buf_0x9050_len,
0320           table_buf_0x9400, table_buf_0x9400_len,
0321           table_buf_0x9402, table_buf_0x9402_len,
0322           table_buf_0x9403, table_buf_0x9403_len,
0323           table_buf_0x9406, table_buf_0x9406_len,
0324           table_buf_0x940c, table_buf_0x940c_len,
0325           table_buf_0x940e, table_buf_0x940e_len);
0326     }
0327   next:
0328     fseek(ifp, save, SEEK_SET);
0329   }
0330 
0331   order = sorder;
0332 }
0333 
0334 void LibRaw::parse_makernote(int base, int uptag)
0335 {
0336 
0337   if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
0338     throw LIBRAW_EXCEPTION_IO_CORRUPT;
0339 
0340   if (!strncmp(make, "NIKON", 5))
0341   {
0342     parseNikonMakernote(base, uptag, nonDNG);
0343     return;
0344   }
0345   else if (!strncasecmp(make, "LEICA", 5))
0346   {
0347     parseLeicaMakernote(base, uptag, is_0x927c);
0348     return;
0349   }
0350 
0351   if (!strncmp(make, "Nokia", 5))
0352     return;
0353 
0354   char buf[10];
0355   char another_buf[128];
0356 
0357   fseek(ifp, -12, SEEK_CUR);
0358   fread (another_buf, 1, 12, ifp);
0359   if (!strncmp(another_buf, "SONY", 4) ||
0360       !strncmp(another_buf, "VHAB", 4)) { // Sony branded as Hasselblad
0361     is_Sony = 1;
0362   }
0363 
0364   fread(buf, 1, 10, ifp);
0365 
0366   if (!strncmp(buf, "KDK", 3)  || /* these aren't TIFF tables */
0367       !strncmp(buf, "VER", 3)  ||
0368       !strncmp(buf, "IIII", 4) ||
0369       !strncmp(buf, "MMMM", 4))
0370     return;
0371 
0372   if (!strcmp(buf, "EPSON"))
0373   {
0374     parseEpsonMakernote(base, uptag, nonDNG);
0375     return;
0376   }
0377   else if (!strcmp(buf, "SIGMA"))
0378   {
0379     parseSigmaMakernote(base, uptag, CameraDNG);
0380     return;
0381   }
0382 
0383 
0384   unsigned entries, tag, type, len, save, c;
0385   unsigned i, wb[4] = {0, 0, 0, 0};
0386   short morder, sorder = order;
0387 
0388   uchar *CanonCameraInfo = 0;;
0389   unsigned lenCanonCameraInfo = 0;
0390   unsigned typeCanonCameraInfo = 0;
0391   imCanon.wbi = 0;
0392 
0393   uchar *table_buf_0x0116;
0394   ushort table_buf_0x0116_len = 0;
0395   uchar *table_buf_0x2010;
0396   ushort table_buf_0x2010_len = 0;
0397   uchar *table_buf_0x9050;
0398   ushort table_buf_0x9050_len = 0;
0399   uchar *table_buf_0x9400;
0400   ushort table_buf_0x9400_len = 0;
0401   uchar *table_buf_0x9402;
0402   ushort table_buf_0x9402_len = 0;
0403   uchar *table_buf_0x9403;
0404   ushort table_buf_0x9403_len = 0;
0405   uchar *table_buf_0x9406;
0406   ushort table_buf_0x9406_len = 0;
0407   uchar *table_buf_0x940c;
0408   ushort table_buf_0x940c_len = 0;
0409   uchar *table_buf_0x940e;
0410   ushort table_buf_0x940e_len = 0;
0411 
0412   INT64 fsize = ifp->size();
0413 
0414   /*
0415        The MakerNote might have its own TIFF header (possibly with
0416        its own byte-order!), or it might just be a table.
0417   */
0418 
0419   if (!strncmp(buf, "KC", 2) || /* Konica KD-400Z, KD-510Z */
0420       !strncmp(buf, "MLY", 3))  /* Minolta DiMAGE G series */
0421   {
0422     order = 0x4d4d;
0423     while ((i = ftell(ifp)) < data_offset && i < 16384)
0424     {
0425       wb[0] = wb[2];
0426       wb[2] = wb[1];
0427       wb[1] = wb[3];
0428       if (feof(ifp))
0429           break;
0430       wb[3] = get2();
0431       if (wb[1] == 256 && wb[3] == 256 && wb[0] > 256 && wb[0] < 640 &&
0432           wb[2] > 256 && wb[2] < 640)
0433         FORC4 cam_mul[c] = wb[c];
0434     }
0435     goto quit;
0436   }
0437 
0438   if (!strcmp(buf, "OLYMPUS") || !strncmp(buf, "OM SYS",6) ||
0439       !strcmp(buf, "PENTAX "))
0440   {
0441     base = ftell(ifp) - 10;
0442     fseek(ifp, -2, SEEK_CUR);
0443     if (buf[1] == 'M')
0444         get4();
0445     order = get2();
0446     if (buf[0] == 'O')
0447       get2();
0448   }
0449   else if (!strncmp(buf, "SONY", 4) || // DSLR-A100
0450            !strcmp(buf, "Panasonic")) {
0451     if (buf[0] == 'S')
0452       is_Sony = 1;
0453     goto nf;
0454   }
0455   else if (!strncmp(buf, "FUJIFILM", 8))
0456   {
0457     base = ftell(ifp) - 10;
0458   nf:
0459     order = 0x4949;
0460     fseek(ifp, 2, SEEK_CUR);
0461   }
0462   else if (!strcmp (buf, "OLYMP")    ||
0463            !strncmp(buf, "LEICA", 5) ||
0464            !strcmp (buf, "Ricoh"))
0465   {
0466     fseek(ifp, -2, SEEK_CUR);
0467   }
0468   else if (!strcmp(buf, "AOC") || // Pentax, tribute to Asahi Optical Co.
0469            !strcmp(buf, "QVC"))   // Casio, from "QV-Camera"
0470   {
0471     fseek(ifp, -4, SEEK_CUR);
0472   }
0473   else if (!strncmp(buf, "CMT3", 4))
0474   {
0475     order = sget2((uchar *)(buf + 4));
0476     fseek(ifp, 2L, SEEK_CUR);
0477   }
0478   else if (libraw_internal_data.unpacker_data.CR3_CTMDtag)
0479   {
0480     order = sget2((uchar *)buf);
0481     fseek(ifp, -2L, SEEK_CUR);
0482   }
0483   else
0484   {
0485     fseek(ifp, -10, SEEK_CUR);
0486     if (!strncmp(make, "SAMSUNG", 7))
0487       base = ftell(ifp);
0488   }
0489 
0490   if (!is_Olympus &&
0491       (!strncasecmp(make, "Olympus", 7) || !strncmp(make, "OM Digi", 7) ||
0492       (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) {
0493     is_Olympus = 1;
0494   }
0495 
0496   if (!is_Sony &&
0497       (!strncasecmp(make, "SONY", 4) ||
0498        !strncasecmp(make, "Konica", 6) ||
0499        !strncasecmp(make, "Minolta", 7) ||
0500        (!strncasecmp(make, "Hasselblad", 10) &&
0501         (!strncasecmp(model, "Stellar", 7) ||
0502          !strncasecmp(model, "Lunar", 5) ||
0503          !strncasecmp(model, "Lusso", 5) ||
0504          !strncasecmp(model, "HV", 2))))) {
0505     is_Sony = 1;
0506   }
0507 
0508   if (strcasestr(make, "Kodak") &&
0509       (sget2((uchar *)buf) > 1) && // check number of entries
0510       (sget2((uchar *)buf) < 128) &&
0511       (sget2((uchar *)(buf + 4)) > 0) && // check type
0512       (sget2((uchar *)(buf + 4)) < 13) &&
0513       (sget4((uchar *)(buf + 6)) < 256) // check count
0514   )
0515     imKodak.MakerNoteKodak8a = 1; // Kodak P712 / P850 / P880
0516 
0517   entries = get2();
0518   if (entries > 1000)
0519     return;
0520 
0521   morder = order;
0522   while (entries--)
0523   {
0524     order = morder;
0525     tiff_get(base, &tag, &type, &len, &save);
0526     tag |= uptag << 16;
0527 
0528     INT64 _pos = ftell(ifp);
0529     if (len > 100 * 1024 * 1024)
0530     goto next; // 100Mb tag? No!
0531     if (len > 8 && _pos + len > 2 * fsize)
0532     {
0533       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0534       continue;
0535     }
0536     if (imKodak.MakerNoteKodak8a)
0537     {
0538       if ((tag == 0xff00) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) && (len == 1))
0539       {
0540         INT64 _pos1 = get4();
0541         if ((_pos1 < fsize) && (_pos1 > 0))
0542         {
0543           fseek(ifp, _pos1, SEEK_SET);
0544           parse_makernote(base, tag);
0545         }
0546       }
0547       else if (tag == 0xff00f90b)
0548       {
0549         imKodak.clipBlack = get2();
0550       }
0551       else if (tag == 0xff00f90c)
0552       {
0553         imKodak.clipWhite = imgdata.color.linear_max[0] =
0554             imgdata.color.linear_max[1] = imgdata.color.linear_max[2] =
0555                 imgdata.color.linear_max[3] = get2();
0556       }
0557     }
0558     else if (!strncmp(make, "Canon", 5))
0559     {
0560       if (tag == 0x000d && len < 256000) // camera info
0561       {
0562         if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0563         {
0564           CanonCameraInfo = (uchar *)malloc(MAX(16, len));
0565           fread(CanonCameraInfo, len, 1, ifp);
0566         }
0567         else
0568         {
0569           CanonCameraInfo = (uchar *)malloc(MAX(16, len * 4));
0570           fread(CanonCameraInfo, len, 4, ifp);
0571         }
0572         lenCanonCameraInfo = len;
0573         typeCanonCameraInfo = type;
0574       }
0575 
0576       else if (tag == 0x0010) // Canon ModelID
0577       {
0578         unique_id = get4();
0579         setCanonBodyFeatures(unique_id);
0580         if (lenCanonCameraInfo)
0581         {
0582           processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo,
0583                                  typeCanonCameraInfo, nonDNG);
0584       if(CanonCameraInfo)
0585             free(CanonCameraInfo);
0586           CanonCameraInfo = 0;
0587           lenCanonCameraInfo = 0;
0588         }
0589       }
0590 
0591       else
0592         parseCanonMakernotes(tag, type, len, nonDNG);
0593     }
0594 
0595     else if (!strncmp(make, "FUJI", 4))
0596       parseFujiMakernotes(tag, type, len, nonDNG);
0597 
0598     else if (!strncasecmp(model, "Hasselblad X1D", 14) ||
0599              !strncasecmp(model, "Hasselblad H6D", 14) ||
0600              !strncasecmp(model, "Hasselblad A6D", 14))
0601     {
0602       if (tag == 0x0045)
0603       {
0604         imHassy.BaseISO = get4();
0605       }
0606       else if (tag == 0x0046)
0607       {
0608         imHassy.Gain = getreal(type);
0609       }
0610     }
0611 
0612     else if (!strncmp(make, "PENTAX", 6) ||
0613              !strncmp(make, "RICOH", 5) ||
0614              !strncmp(model, "PENTAX", 6))
0615     {
0616       if (!strncmp(model, "GR", 2) ||
0617           !strncmp(model, "GXR", 3))
0618       {
0619         parseRicohMakernotes(base, tag, type, len, CameraDNG);
0620       }
0621       else
0622       {
0623         parsePentaxMakernotes(base, tag, type, len, nonDNG);
0624       }
0625     }
0626 
0627     else if (!strncmp(make, "SAMSUNG", 7))
0628     {
0629       if (!dng_version)
0630         parseSamsungMakernotes(base, tag, type, len, nonDNG);
0631       else
0632         parsePentaxMakernotes(base, tag, type, len, CameraDNG);
0633     }
0634 
0635     else if (is_Sony)
0636     {
0637       if ((tag == 0xb028) && (len == 1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) // DSLR-A100
0638       {
0639         if ((c = get4()))
0640         {
0641           fseek(ifp, c, SEEK_SET);
0642           parse_makernote(base, tag);
0643         }
0644       }
0645       else
0646       {
0647         parseSonyMakernotes(
0648             base, tag, type, len, nonDNG,
0649             table_buf_0x0116, table_buf_0x0116_len,
0650             table_buf_0x2010, table_buf_0x2010_len,
0651             table_buf_0x9050, table_buf_0x9050_len,
0652             table_buf_0x9400, table_buf_0x9400_len,
0653             table_buf_0x9402, table_buf_0x9402_len,
0654             table_buf_0x9403, table_buf_0x9403_len,
0655             table_buf_0x9406, table_buf_0x9406_len,
0656             table_buf_0x940c, table_buf_0x940c_len,
0657             table_buf_0x940e, table_buf_0x940e_len);
0658       }
0659     }
0660     fseek(ifp, _pos, SEEK_SET);
0661 
0662     if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) {
0663       if (tag == 0x0011)
0664         imHassy.SensorCode = getint(type);
0665       else if (tag == 0x0016)
0666         imHassy.CoatingCode = getint(type);
0667       else if ((tag == 0x002a) &&
0668                tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) &&
0669                (len == 12)) {
0670         FORC4 for (int ii = 0; ii < 3; ii++)
0671                 imHassy.mnColorMatrix[c][ii] = getreal(type);
0672 
0673       } else if (tag == 0x0031) {
0674         imHassy.RecommendedCrop[0] = getint(type);
0675         imHassy.RecommendedCrop[1] = getint(type);
0676       }
0677     }
0678 
0679     if ((tag == 0x0004 || tag == 0x0114) && !strncmp(make, "KONICA", 6))
0680     {
0681       fseek(ifp, tag == 0x0004 ? 140 : 160, SEEK_CUR);
0682       switch (get2())
0683       {
0684       case 72:
0685         flip = 0;
0686         break;
0687       case 76:
0688         flip = 6;
0689         break;
0690       case 82:
0691         flip = 5;
0692         break;
0693       }
0694     }
0695 
0696     if (is_Olympus) {
0697       INT64 _pos2 = ftell(ifp);
0698       if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) ||
0699           (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) ||
0700           (tag == 0x3000))
0701       {
0702         if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) {
0703           parse_makernote(base, tag);
0704 
0705         } else if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_ifd) ||
0706                    tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_int32u)) {
0707           fseek(ifp, base + get4(), SEEK_SET);
0708           parse_makernote(base, tag);
0709         }
0710 
0711       } else {
0712         parseOlympusMakernotes(base, tag, type, len, nonDNG);
0713       }
0714       fseek(ifp, _pos2, SEEK_SET);
0715     }
0716 
0717     if ((tag == 0x0015) &&
0718         tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) &&
0719         is_raw)
0720     { // Hasselblad
0721       stmread (imHassy.SensorUnitConnector, len, ifp);
0722     }
0723 
0724     if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
0725         ((tag == 0x0081) || // Minolta
0726          (tag == 0x0100)))  // Olympus
0727     {
0728       thumb_offset = ftell(ifp);
0729       thumb_length = len;
0730     }
0731     if ((tag == 0x0088) && // Minolta, possibly Olympus too
0732         tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) &&
0733         (thumb_offset = get4()))
0734       thumb_offset += base;
0735 
0736     if ((tag == 0x0089) && // Minolta, possibly Olympus too
0737         tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0738       thumb_length = get4();
0739 
0740     if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&  // Nikon
0741         ((tag == 0x008c) ||
0742          (tag == 0x0096))) {
0743       meta_offset = ftell(ifp);
0744     }
0745 
0746     if ((tag == 0x00a1) &&
0747         tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) &&
0748         strncasecmp(make, "Samsung", 7))
0749     {
0750       order = 0x4949;
0751       fseek(ifp, 140, SEEK_CUR);
0752       FORC3 cam_mul[c] = get4();
0753     }
0754 
0755     if (tag == 0xb001 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) // Sony ModelID
0756     {
0757       unique_id = get2();
0758     }
0759     if (tag == 0x0200 && len == 3) // Olympus
0760       shot_order = (get4(), get4());
0761 
0762     if (tag == 0x0f00 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED))
0763     {
0764       if (len == 614)
0765         fseek(ifp, 176, SEEK_CUR);
0766       else if (len == 734 || len == 1502) // Kodak, Minolta, Olympus
0767         fseek(ifp, 148, SEEK_CUR);
0768       else
0769         goto next;
0770       goto get2_256;
0771     }
0772 
0773     if (tag == 0x2011 && len == 2) // Casio
0774     {
0775     get2_256:
0776       order = 0x4d4d;
0777       cam_mul[0] = get2() / 256.0;
0778       cam_mul[2] = get2() / 256.0;
0779     }
0780 
0781   next:
0782     fseek(ifp, save, SEEK_SET);
0783   }
0784 quit:
0785   order = sorder;
0786 }