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

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw is free software; you can redistribute it and/or modify
0005  it under the terms of the one of two licenses as you choose:
0006 
0007 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0008    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0009 
0010 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0011    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0012 
0013  */
0014 
0015 #include "../../internal/dcraw_defs.h"
0016 
0017 // void hexDump(char *title, void *addr, int len);
0018 
0019 unsigned sget4_order (short _order, uchar *s);
0020 double sget_fixed32u (short _order, uchar *s);
0021 double AngleConversion_a (short _order, uchar *s);
0022 double AngleConversion (short _order, uchar *s);
0023 
0024 static const uchar xlat[2][256] = {
0025     {0xc1, 0xbf, 0x6d, 0x0d, 0x59, 0xc5, 0x13, 0x9d, 0x83, 0x61, 0x6b, 0x4f,
0026      0xc7, 0x7f, 0x3d, 0x3d, 0x53, 0x59, 0xe3, 0xc7, 0xe9, 0x2f, 0x95, 0xa7,
0027      0x95, 0x1f, 0xdf, 0x7f, 0x2b, 0x29, 0xc7, 0x0d, 0xdf, 0x07, 0xef, 0x71,
0028      0x89, 0x3d, 0x13, 0x3d, 0x3b, 0x13, 0xfb, 0x0d, 0x89, 0xc1, 0x65, 0x1f,
0029      0xb3, 0x0d, 0x6b, 0x29, 0xe3, 0xfb, 0xef, 0xa3, 0x6b, 0x47, 0x7f, 0x95,
0030      0x35, 0xa7, 0x47, 0x4f, 0xc7, 0xf1, 0x59, 0x95, 0x35, 0x11, 0x29, 0x61,
0031      0xf1, 0x3d, 0xb3, 0x2b, 0x0d, 0x43, 0x89, 0xc1, 0x9d, 0x9d, 0x89, 0x65,
0032      0xf1, 0xe9, 0xdf, 0xbf, 0x3d, 0x7f, 0x53, 0x97, 0xe5, 0xe9, 0x95, 0x17,
0033      0x1d, 0x3d, 0x8b, 0xfb, 0xc7, 0xe3, 0x67, 0xa7, 0x07, 0xf1, 0x71, 0xa7,
0034      0x53, 0xb5, 0x29, 0x89, 0xe5, 0x2b, 0xa7, 0x17, 0x29, 0xe9, 0x4f, 0xc5,
0035      0x65, 0x6d, 0x6b, 0xef, 0x0d, 0x89, 0x49, 0x2f, 0xb3, 0x43, 0x53, 0x65,
0036      0x1d, 0x49, 0xa3, 0x13, 0x89, 0x59, 0xef, 0x6b, 0xef, 0x65, 0x1d, 0x0b,
0037      0x59, 0x13, 0xe3, 0x4f, 0x9d, 0xb3, 0x29, 0x43, 0x2b, 0x07, 0x1d, 0x95,
0038      0x59, 0x59, 0x47, 0xfb, 0xe5, 0xe9, 0x61, 0x47, 0x2f, 0x35, 0x7f, 0x17,
0039      0x7f, 0xef, 0x7f, 0x95, 0x95, 0x71, 0xd3, 0xa3, 0x0b, 0x71, 0xa3, 0xad,
0040      0x0b, 0x3b, 0xb5, 0xfb, 0xa3, 0xbf, 0x4f, 0x83, 0x1d, 0xad, 0xe9, 0x2f,
0041      0x71, 0x65, 0xa3, 0xe5, 0x07, 0x35, 0x3d, 0x0d, 0xb5, 0xe9, 0xe5, 0x47,
0042      0x3b, 0x9d, 0xef, 0x35, 0xa3, 0xbf, 0xb3, 0xdf, 0x53, 0xd3, 0x97, 0x53,
0043      0x49, 0x71, 0x07, 0x35, 0x61, 0x71, 0x2f, 0x43, 0x2f, 0x11, 0xdf, 0x17,
0044      0x97, 0xfb, 0x95, 0x3b, 0x7f, 0x6b, 0xd3, 0x25, 0xbf, 0xad, 0xc7, 0xc5,
0045      0xc5, 0xb5, 0x8b, 0xef, 0x2f, 0xd3, 0x07, 0x6b, 0x25, 0x49, 0x95, 0x25,
0046      0x49, 0x6d, 0x71, 0xc7},
0047     {0xa7, 0xbc, 0xc9, 0xad, 0x91, 0xdf, 0x85, 0xe5, 0xd4, 0x78, 0xd5, 0x17,
0048      0x46, 0x7c, 0x29, 0x4c, 0x4d, 0x03, 0xe9, 0x25, 0x68, 0x11, 0x86, 0xb3,
0049      0xbd, 0xf7, 0x6f, 0x61, 0x22, 0xa2, 0x26, 0x34, 0x2a, 0xbe, 0x1e, 0x46,
0050      0x14, 0x68, 0x9d, 0x44, 0x18, 0xc2, 0x40, 0xf4, 0x7e, 0x5f, 0x1b, 0xad,
0051      0x0b, 0x94, 0xb6, 0x67, 0xb4, 0x0b, 0xe1, 0xea, 0x95, 0x9c, 0x66, 0xdc,
0052      0xe7, 0x5d, 0x6c, 0x05, 0xda, 0xd5, 0xdf, 0x7a, 0xef, 0xf6, 0xdb, 0x1f,
0053      0x82, 0x4c, 0xc0, 0x68, 0x47, 0xa1, 0xbd, 0xee, 0x39, 0x50, 0x56, 0x4a,
0054      0xdd, 0xdf, 0xa5, 0xf8, 0xc6, 0xda, 0xca, 0x90, 0xca, 0x01, 0x42, 0x9d,
0055      0x8b, 0x0c, 0x73, 0x43, 0x75, 0x05, 0x94, 0xde, 0x24, 0xb3, 0x80, 0x34,
0056      0xe5, 0x2c, 0xdc, 0x9b, 0x3f, 0xca, 0x33, 0x45, 0xd0, 0xdb, 0x5f, 0xf5,
0057      0x52, 0xc3, 0x21, 0xda, 0xe2, 0x22, 0x72, 0x6b, 0x3e, 0xd0, 0x5b, 0xa8,
0058      0x87, 0x8c, 0x06, 0x5d, 0x0f, 0xdd, 0x09, 0x19, 0x93, 0xd0, 0xb9, 0xfc,
0059      0x8b, 0x0f, 0x84, 0x60, 0x33, 0x1c, 0x9b, 0x45, 0xf1, 0xf0, 0xa3, 0x94,
0060      0x3a, 0x12, 0x77, 0x33, 0x4d, 0x44, 0x78, 0x28, 0x3c, 0x9e, 0xfd, 0x65,
0061      0x57, 0x16, 0x94, 0x6b, 0xfb, 0x59, 0xd0, 0xc8, 0x22, 0x36, 0xdb, 0xd2,
0062      0x63, 0x98, 0x43, 0xa1, 0x04, 0x87, 0x86, 0xf7, 0xa6, 0x26, 0xbb, 0xd6,
0063      0x59, 0x4d, 0xbf, 0x6a, 0x2e, 0xaa, 0x2b, 0xef, 0xe6, 0x78, 0xb6, 0x4e,
0064      0xe0, 0x2f, 0xdc, 0x7c, 0xbe, 0x57, 0x19, 0x32, 0x7e, 0x2a, 0xd0, 0xb8,
0065      0xba, 0x29, 0x00, 0x3c, 0x52, 0x7d, 0xa8, 0x49, 0x3b, 0x2d, 0xeb, 0x25,
0066      0x49, 0xfa, 0xa3, 0xaa, 0x39, 0xa7, 0xc5, 0xa7, 0x50, 0x11, 0x36, 0xfb,
0067      0xc6, 0x67, 0x4a, 0xf5, 0xa5, 0x12, 0x65, 0x7e, 0xb0, 0xdf, 0xaf, 0x4e,
0068      0xb3, 0x61, 0x7f, 0x2f} };
0069 
0070 void LibRaw::processNikonLensData(uchar *LensData, unsigned len)
0071 {
0072 
0073   ushort i=0;
0074   if (imgdata.lens.nikon.LensType & 0x80) {
0075     strcpy (ilm.LensFeatures_pre, "AF-P");
0076   } else if (!(imgdata.lens.nikon.LensType & 0x01)) {
0077     ilm.LensFeatures_pre[0] = 'A';
0078     ilm.LensFeatures_pre[1] = 'F';
0079   } else {
0080     ilm.LensFeatures_pre[0] = 'M';
0081     ilm.LensFeatures_pre[1] = 'F';
0082   }
0083 
0084   if (imgdata.lens.nikon.LensType & 0x40) {
0085     ilm.LensFeatures_suf[0] = 'E';
0086   } else if (imgdata.lens.nikon.LensType & 0x04) {
0087     ilm.LensFeatures_suf[0] = 'G';
0088   } else if (imgdata.lens.nikon.LensType & 0x02) {
0089     ilm.LensFeatures_suf[0] = 'D';
0090   }
0091 
0092   if (imgdata.lens.nikon.LensType & 0x08)
0093   {
0094     ilm.LensFeatures_suf[1] = ' ';
0095     ilm.LensFeatures_suf[2] = 'V';
0096     ilm.LensFeatures_suf[3] = 'R';
0097   }
0098 
0099   if (imgdata.lens.nikon.LensType & 0x10)
0100   {
0101     ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX;
0102     ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1INCH;
0103   }
0104   else
0105     ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_F;
0106 
0107   if (imgdata.lens.nikon.LensType & 0x20)
0108   {
0109     strcpy(ilm.Adapter, "FT-1");
0110     ilm.LensMount = LIBRAW_MOUNT_Nikon_F;
0111     ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX;
0112     ilm.CameraFormat = LIBRAW_FORMAT_1INCH;
0113   }
0114 
0115   imgdata.lens.nikon.LensType = imgdata.lens.nikon.LensType & 0xdf;
0116 
0117   if ((len < 20) || (len == 58) || (len == 108))
0118   {
0119     switch (len)
0120     {
0121     case 9:
0122       i = 2;
0123       break;
0124     case 15:
0125       i = 7;
0126       break;
0127     case 16:
0128       i = 8;
0129       break;
0130     case  58: // "Z 6", "Z 6 II", "Z 7", "Z 7 II", "Z 50", D780, "Z 5", "Z fc"
0131     case 108: // "Z 9"
0132       if (model[6] == 'Z')
0133         ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z;
0134       if (imNikon.HighSpeedCropFormat != 12)
0135         ilm.CameraFormat = LIBRAW_FORMAT_FF;
0136       i = 1;
0137       while ((LensData[i] == LensData[0]) && (i < 17))
0138         i++;
0139       if (i == 17)
0140       {
0141         ilm.LensMount = LIBRAW_MOUNT_Nikon_Z;
0142         ilm.LensID = sget2(LensData + 0x2c);
0143         if (
0144                (ilm.LensID == 11)
0145             || (ilm.LensID == 12)
0146             || (ilm.LensID == 26)
0147            ) ilm.LensFormat = LIBRAW_FORMAT_APSC;
0148         else ilm.LensFormat = LIBRAW_FORMAT_FF;
0149         if (ilm.MaxAp4CurFocal < 0.7f)
0150           ilm.MaxAp4CurFocal = libraw_powf64l(
0151               2.0f, (float)sget2(LensData + 0x32) / 384.0f - 1.0f);
0152         if (ilm.CurAp < 0.7f)
0153           ilm.CurAp = libraw_powf64l(
0154               2.0f, (float)sget2(LensData + 0x34) / 384.0f - 1.0f);
0155         if (fabsf(ilm.CurFocal) < 1.1f)
0156           ilm.CurFocal = sget2(LensData + 0x38);
0157         return;
0158       }
0159       i = 9;
0160       ilm.LensMount = LIBRAW_MOUNT_Nikon_F;
0161       if (ilm.CameraMount == LIBRAW_MOUNT_Nikon_Z)
0162         strcpy(ilm.Adapter, "FTZ");
0163       break;
0164     }
0165     imgdata.lens.nikon.LensIDNumber = LensData[i];
0166     imgdata.lens.nikon.LensFStops = LensData[i + 1];
0167     ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f;
0168     if (fabsf(ilm.MinFocal) < 1.1f)
0169     {
0170       if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 2])
0171         ilm.MinFocal =
0172             5.0f * libraw_powf64l(2.0f, (float)LensData[i + 2] / 24.0f);
0173       if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 3])
0174         ilm.MaxFocal =
0175             5.0f * libraw_powf64l(2.0f, (float)LensData[i + 3] / 24.0f);
0176       if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 4])
0177         ilm.MaxAp4MinFocal =
0178             libraw_powf64l(2.0f, (float)LensData[i + 4] / 24.0f);
0179       if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 5])
0180         ilm.MaxAp4MaxFocal =
0181             libraw_powf64l(2.0f, (float)LensData[i + 5] / 24.0f);
0182     }
0183     imgdata.lens.nikon.MCUVersion = LensData[i + 6];
0184     if (i != 2)
0185     {
0186       if ((LensData[i - 1]) && (fabsf(ilm.CurFocal) < 1.1f))
0187         ilm.CurFocal =
0188             5.0f * libraw_powf64l(2.0f, (float)LensData[i - 1] / 24.0f);
0189       if (LensData[i + 7])
0190         imgdata.lens.nikon.EffectiveMaxAp =
0191             libraw_powf64l(2.0f, (float)LensData[i + 7] / 24.0f);
0192     }
0193     ilm.LensID = (unsigned long long)LensData[i] << 56 |
0194                  (unsigned long long)LensData[i + 1] << 48 |
0195                  (unsigned long long)LensData[i + 2] << 40 |
0196                  (unsigned long long)LensData[i + 3] << 32 |
0197                  (unsigned long long)LensData[i + 4] << 24 |
0198                  (unsigned long long)LensData[i + 5] << 16 |
0199                  (unsigned long long)LensData[i + 6] << 8 |
0200                  (unsigned long long)imgdata.lens.nikon.LensType;
0201   }
0202   else if ((len == 459) || (len == 590))
0203   {
0204     memcpy(ilm.Lens, LensData + 390, 64);
0205   }
0206   else if (len == 509)
0207   {
0208     memcpy(ilm.Lens, LensData + 391, 64);
0209   }
0210   else if (len == 879)
0211   {
0212     memcpy(ilm.Lens, LensData + 680, 64);
0213   }
0214 
0215   return;
0216 }
0217 
0218 void LibRaw::Nikon_NRW_WBtag(int wb, int skip)
0219 {
0220 
0221   int r, g0, g1, b;
0222   if (skip)
0223     get4(); // skip wb "CCT", it is not unique
0224   r = get4();
0225   g0 = get4();
0226   g1 = get4();
0227   b = get4();
0228   if (r && g0 && g1 && b)
0229   {
0230     icWBC[wb][0] = r << 1;
0231     icWBC[wb][1] = g0;
0232     icWBC[wb][2] = b << 1;
0233     icWBC[wb][3] = g1;
0234   }
0235   return;
0236 }
0237 
0238 void LibRaw::parseNikonMakernote(int base, int uptag, unsigned /*dng_writer */)
0239 {
0240 
0241   unsigned offset = 0, entries, tag, type, len, save;
0242 
0243   unsigned c, i;
0244   unsigned LensData_len = 0;
0245   uchar *LensData_buf=0;
0246   uchar ColorBalanceData_buf[324];
0247   int ColorBalanceData_ready = 0;
0248   uchar ci, cj, ck;
0249   unsigned serial = 0;
0250   unsigned custom_serial = 0;
0251 
0252   unsigned ShotInfo_len = 0;
0253   uchar *ShotInfo_buf=0;
0254 
0255 /* for dump:
0256 uchar *cj_block, *ck_block;
0257 */
0258 
0259   short morder, sorder = order;
0260   char buf[10];
0261   INT64 fsize = ifp->size();
0262 
0263   fread(buf, 1, 10, ifp);
0264 
0265   if (!strcmp(buf, "Nikon"))
0266   {
0267     if (buf[6] != '\2')
0268       return;
0269     base = ftell(ifp);
0270     order = get2();
0271     if (get2() != 42)
0272       goto quit;
0273     offset = get4();
0274     fseek(ifp, INT64(offset) - 8LL, SEEK_CUR);
0275   }
0276   else
0277   {
0278     fseek(ifp, -10, SEEK_CUR);
0279   }
0280 
0281   entries = get2();
0282   if (entries > 1000)
0283     return;
0284   morder = order;
0285 
0286   while (entries--)
0287   {
0288     order = morder;
0289     tiff_get(base, &tag, &type, &len, &save);
0290 
0291     INT64 pos = ifp->tell();
0292     if (len > 8 && pos + len > 2 * fsize)
0293     {
0294       fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
0295       continue;
0296     }
0297     tag |= uptag << 16;
0298     if (len > 100 * 1024 * 1024)
0299       goto next; // 100Mb tag? No!
0300 
0301     if (tag == 0x0002)
0302     {
0303       if (!iso_speed)
0304         iso_speed = (get2(), get2());
0305     }
0306     else if (tag == 0x000a)
0307     {
0308       ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
0309       ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
0310     }
0311     else if ((tag == 0x000c) && (len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL))
0312     {
0313       cam_mul[0] = getreal(type);
0314       cam_mul[2] = getreal(type);
0315       cam_mul[1] = getreal(type);
0316       cam_mul[3] = getreal(type);
0317     }
0318     else if (tag == 0x0011)
0319     {
0320       if (is_raw)
0321       {
0322         fseek(ifp, get4() + base, SEEK_SET);
0323         parse_tiff_ifd(base);
0324       }
0325     }
0326     else if (tag == 0x0012)
0327     {
0328       uchar uc1 = fgetc(ifp);
0329       uchar uc2 = fgetc(ifp);
0330       uchar uc3 = fgetc(ifp);
0331       if (uc3)
0332         imCommon.FlashEC = (float)(uc1 * uc2) / (float)uc3;
0333     }
0334     else if (tag == 0x0014)
0335     {
0336       if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary))
0337       {
0338         if (len == 2560)
0339         { // E5400, E8400, E8700, E8800
0340           fseek(ifp, 0x4e0L, SEEK_CUR);
0341           order = 0x4d4d;
0342           cam_mul[0] = get2() / 256.0;
0343           cam_mul[2] = get2() / 256.0;
0344           cam_mul[1] = cam_mul[3] = 1.0;
0345           icWBC[LIBRAW_WBI_Auto][0] = get2();
0346           icWBC[LIBRAW_WBI_Auto][2] = get2();
0347           icWBC[LIBRAW_WBI_Daylight][0] = get2();
0348           icWBC[LIBRAW_WBI_Daylight][2] = get2();
0349           fseek(ifp, 0x18L, SEEK_CUR);
0350           icWBC[LIBRAW_WBI_Tungsten][0] = get2();
0351           icWBC[LIBRAW_WBI_Tungsten][2] = get2();
0352           fseek(ifp, 0x18L, SEEK_CUR);
0353           icWBC[LIBRAW_WBI_FL_W][0] = get2();
0354           icWBC[LIBRAW_WBI_FL_W][2] = get2();
0355           icWBC[LIBRAW_WBI_FL_N][0] = get2();
0356           icWBC[LIBRAW_WBI_FL_N][2] = get2();
0357           icWBC[LIBRAW_WBI_FL_D][0] = get2();
0358           icWBC[LIBRAW_WBI_FL_D][2] = get2();
0359           icWBC[LIBRAW_WBI_Cloudy][0] = get2();
0360           icWBC[LIBRAW_WBI_Cloudy][2] = get2();
0361           fseek(ifp, 0x18L, SEEK_CUR);
0362           icWBC[LIBRAW_WBI_Flash][0] = get2();
0363           icWBC[LIBRAW_WBI_Flash][2] = get2();
0364 
0365           icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] =
0366             icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] =
0367             icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] =
0368             icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] =
0369             icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] =
0370             icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] =
0371             icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] =
0372             icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = 256;
0373 
0374           if (strncmp(model, "E8700", 5))
0375           {
0376             fseek(ifp, 0x18L, SEEK_CUR);
0377             icWBC[LIBRAW_WBI_Shade][0] = get2();
0378             icWBC[LIBRAW_WBI_Shade][2] = get2();
0379             icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = 256;
0380           }
0381         }
0382         else if (len == 1280)
0383         { // E5000, E5700
0384           cam_mul[0] = cam_mul[1] = cam_mul[2] = cam_mul[3] = 1.0;
0385         }
0386         else
0387         {
0388           fread(buf, 1, 10, ifp);
0389           if (!strncmp(buf, "NRW ", 4))
0390           { // P6000, P7000, P7100, B700, P1000
0391             if (!strcmp(buf + 4, "0100"))
0392             { // P6000
0393               fseek(ifp, 0x13deL, SEEK_CUR);
0394               cam_mul[0] = get4() << 1;
0395               cam_mul[1] = get4();
0396               cam_mul[3] = get4();
0397               cam_mul[2] = get4() << 1;
0398               Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 0);
0399               Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 0);
0400               fseek(ifp, 0x10L, SEEK_CUR);
0401               Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 0);
0402               Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 0);
0403               Nikon_NRW_WBtag(LIBRAW_WBI_Flash, 0);
0404               fseek(ifp, 0x10L, SEEK_CUR);
0405               Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 0);
0406               Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 0);
0407             }
0408             else
0409             { // P7000, P7100, B700, P1000
0410               fseek(ifp, 0x16L, SEEK_CUR);
0411               black = get2();
0412               if (cam_mul[0] < 0.1f)
0413               {
0414                 fseek(ifp, 0x16L, SEEK_CUR);
0415                 cam_mul[0] = get4() << 1;
0416                 cam_mul[1] = get4();
0417                 cam_mul[3] = get4();
0418                 cam_mul[2] = get4() << 1;
0419               }
0420               else
0421               {
0422                 fseek(ifp, 0x26L, SEEK_CUR);
0423               }
0424               if (len != 332)
0425               { // not A1000
0426                 Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 1);
0427                 Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 1);
0428                 Nikon_NRW_WBtag(LIBRAW_WBI_Shade, 1);
0429                 Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 1);
0430                 Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 1);
0431                 Nikon_NRW_WBtag(LIBRAW_WBI_FL_N, 1);
0432                 Nikon_NRW_WBtag(LIBRAW_WBI_FL_D, 1);
0433                 Nikon_NRW_WBtag(LIBRAW_WBI_HT_Mercury, 1);
0434                 fseek(ifp, 0x14L, SEEK_CUR);
0435                 Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 1);
0436                 Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1);
0437               }
0438               else
0439               {
0440                 fseek(ifp, 0xc8L, SEEK_CUR);
0441                 Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1);
0442               }
0443             }
0444           }
0445         }
0446       }
0447     }
0448     else if (tag == 0x001b)
0449     {
0450       imNikon.HighSpeedCropFormat = get2();
0451       imNikon.SensorHighSpeedCrop.cwidth = get2();
0452       imNikon.SensorHighSpeedCrop.cheight = get2();
0453       imNikon.SensorWidth = get2();
0454       imNikon.SensorHeight = get2();
0455       imNikon.SensorHighSpeedCrop.cleft = get2();
0456       imNikon.SensorHighSpeedCrop.ctop = get2();
0457       switch (imNikon.HighSpeedCropFormat)
0458       {
0459       case 0:
0460       case 1:
0461       case 2:
0462       case 4:
0463         imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
0464         break;
0465       case 11:
0466         ilm.CameraFormat = LIBRAW_FORMAT_FF;
0467         imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
0468         break;
0469       case 12:
0470         ilm.CameraFormat = LIBRAW_FORMAT_APSC;
0471         imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
0472         break;
0473       case 3:
0474         imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4;
0475         break;
0476       case 6:
0477         imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9;
0478         break;
0479       case 17:
0480         imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1;
0481         break;
0482       default:
0483         imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER;
0484         break;
0485       }
0486     }
0487     else if (tag == 0x001d)
0488     { // serial number
0489       if (len > 0)
0490       {
0491         int model_len = (int)strbuflen(model);
0492         while ((c = fgetc(ifp)) && (len-- > 0) && (c != (unsigned)EOF))
0493         {
0494           if ((!custom_serial) && (!isdigit(c)))
0495           {
0496             if (((model_len == 3) && !strcmp(model, "D50")) ||
0497                 ((model_len >= 4) && !isalnum(model[model_len - 4]) &&
0498                  !strncmp(&model[model_len - 3], "D50", 3)))
0499             {
0500               custom_serial = 34;
0501             }
0502             else
0503             {
0504               custom_serial = 96;
0505             }
0506             break;
0507           }
0508           serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10);
0509         }
0510         if (!imgdata.shootinginfo.BodySerial[0])
0511           sprintf(imgdata.shootinginfo.BodySerial, "%d", serial);
0512       }
0513     }
0514     else if (tag == 0x001e) {
0515       switch (get2()) {
0516       case 1:
0517         imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
0518         break;
0519       case 2:
0520         imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
0521         break;
0522       default:
0523         imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
0524         break;
0525       }
0526     } else if (tag == 0x0025)
0527     {
0528       imCommon.real_ISO = int(100.0 * libraw_powf64l(2.0, double((uchar)fgetc(ifp)) / 12.0 - 5.0));
0529       if (!iso_speed || (iso_speed == 65535))
0530       {
0531         iso_speed = imCommon.real_ISO;
0532       }
0533     }
0534     else if (tag == 0x0022)
0535     {
0536       imNikon.Active_D_Lighting = get2();
0537     }
0538     else if (tag == 0x003b)
0539     { // WB for multi-exposure (ME); all 1s for regular exposures
0540       imNikon.ME_WB[0] = getreal(type);
0541       imNikon.ME_WB[2] = getreal(type);
0542       imNikon.ME_WB[1] = getreal(type);
0543       imNikon.ME_WB[3] = getreal(type);
0544     }
0545     else if (tag == 0x003d)
0546     { // not corrected for file bitcount, to be patched in open_datastream
0547       FORC4 cblack[RGGB_2_RGBG(c)] = get2();
0548       i = cblack[3];
0549       FORC3 if (i > cblack[c]) i = cblack[c];
0550       FORC4 cblack[c] -= i;
0551       black += i;
0552     }
0553     else if (tag == 0x0045)
0554     { /* upper left pixel (x,y), size (width,height) */
0555       imgdata.sizes.raw_inset_crops[0].cleft = get2();
0556       imgdata.sizes.raw_inset_crops[0].ctop = get2();
0557       imgdata.sizes.raw_inset_crops[0].cwidth = get2();
0558       imgdata.sizes.raw_inset_crops[0].cheight = get2();
0559     }
0560     else if (tag == 0x0051)
0561     {
0562       fseek(ifp, 10LL, SEEK_CUR);
0563       imNikon.NEFCompression = get2();
0564     }
0565     else if (tag == 0x0082)
0566     { // lens attachment
0567       stmread(ilm.Attachment, len, ifp);
0568     }
0569     else if (tag == 0x0083)
0570     { // lens type
0571       imgdata.lens.nikon.LensType = fgetc(ifp);
0572     }
0573     else if (tag == 0x0084)
0574     { // lens
0575       ilm.MinFocal = getreal(type);
0576       ilm.MaxFocal = getreal(type);
0577       ilm.MaxAp4MinFocal = getreal(type);
0578       ilm.MaxAp4MaxFocal = getreal(type);
0579     }
0580     else if (tag == 0x0088) // AFInfo
0581     {
0582       if (!imCommon.afcount)
0583       {
0584         imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
0585         imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
0586         imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
0587         imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
0588         fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
0589         imCommon.afcount = 1;
0590       }
0591     }
0592     else if (tag == 0x008b) // lens f-stops
0593     {
0594       uchar uc1 = fgetc(ifp);
0595       uchar uc2 = fgetc(ifp);
0596       uchar uc3 = fgetc(ifp);
0597       if (uc3)
0598       {
0599         imgdata.lens.nikon.LensFStops = uc1 * uc2 * (12 / uc3);
0600         ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f;
0601       }
0602     }
0603     else if ((tag == 0x008c) || (tag == 0x0096))
0604     {
0605       meta_offset = ftell(ifp);
0606     }
0607     else if ((tag == 0x0091) && (len > 4))
0608     {
0609       ShotInfo_len = len;
0610       ShotInfo_buf = (uchar *)malloc(ShotInfo_len);
0611 
0612 /* for dump:
0613 cj_block = (uchar *)malloc(ShotInfo_len);
0614 ck_block = (uchar *)malloc(ShotInfo_len);
0615 */
0616 
0617       fread(ShotInfo_buf, ShotInfo_len, 1, ifp);
0618       FORC4 imNikon.ShotInfoVersion =
0619           imNikon.ShotInfoVersion * 10 + ShotInfo_buf[c] - '0';
0620     }
0621     else if (tag == 0x0093)
0622     {
0623       imNikon.NEFCompression = i = get2();
0624       if ((i == 7) || (i == 9))
0625       {
0626         ilm.LensMount = LIBRAW_MOUNT_FixedLens;
0627         ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
0628       }
0629     }
0630     else if (tag == 0x0097)
0631     { // ver97
0632       FORC4 imNikon.ColorBalanceVersion =
0633           imNikon.ColorBalanceVersion * 10 + fgetc(ifp) - '0';
0634       switch (imNikon.ColorBalanceVersion)
0635       {
0636       case 100: // NIKON D100
0637         fseek(ifp, 0x44L, SEEK_CUR);
0638         FORC4 cam_mul[RBGG_2_RGBG(c)] = get2();
0639         break;
0640       case 102: // NIKON D2H
0641         fseek(ifp, 0x6L, SEEK_CUR);
0642         FORC4 cam_mul[RGGB_2_RGBG(c)] = get2();
0643         break;
0644       case 103: // NIKON D70, D70s
0645         fseek(ifp, 0x10L, SEEK_CUR);
0646         FORC4 cam_mul[c] = get2();
0647       }
0648       if (imNikon.ColorBalanceVersion >= 200)
0649       {
0650         /*
0651         204: NIKON D2X, D2Xs
0652         205: NIKON D50
0653         206: NIKON D2Hs
0654         207: NIKON D200
0655         208: NIKON D40, D40X, D80
0656         209: NIKON D3, D3X, D300, D700
0657         210: NIKON D60
0658         211: NIKON D90, D5000
0659         212: NIKON D300S
0660         213: NIKON D3000
0661         214: NIKON D3S
0662         215: NIKON D3100
0663         216: NIKON D5100, D7000
0664         217: NIKON D4, D600, D800, D800E, D3200
0665         -= unknown =-
0666         218: NIKON D5200, D7100
0667         219: NIKON D5300
0668         220: NIKON D610, Df
0669         221: NIKON D3300
0670         222: NIKON D4S
0671         223: NIKON D750, D810
0672         224: NIKON D3400, D3500, D5500, D5600, D7200
0673         225: NIKON D5, D500
0674         226: NIKON D7500
0675         227: NIKON D850
0676          */
0677         if (imNikon.ColorBalanceVersion != 205)
0678         {
0679           fseek(ifp, 0x118L, SEEK_CUR);
0680         }
0681         ColorBalanceData_ready =
0682             (fread(ColorBalanceData_buf, 324, 1, ifp) == 1);
0683       }
0684       if ((imNikon.ColorBalanceVersion >= 400) &&
0685           (imNikon.ColorBalanceVersion <= 405))
0686       { // 1 J1, 1 V1, 1 J2, 1 V2, 1 J3, 1 S1, 1 AW1, 1 S2, 1 J4, 1 V3, 1 J5
0687         ilm.CameraFormat = LIBRAW_FORMAT_1INCH;
0688         ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX;
0689       }
0690       else if ((imNikon.ColorBalanceVersion >= 500) &&
0691                (imNikon.ColorBalanceVersion <= 502))
0692       { // P7700, P7800, P330, P340
0693         ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens;
0694         ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
0695       }
0696       else if (imNikon.ColorBalanceVersion == 601)
0697       { // Coolpix A
0698         ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC;
0699         ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens;
0700         ilm.FocalType = LIBRAW_FT_PRIME_LENS;
0701       }
0702     }
0703     else if (tag == 0x0098) // contains lens data
0704     {
0705       FORC4 imNikon.LensDataVersion =
0706           imNikon.LensDataVersion * 10 + fgetc(ifp) - '0';
0707       switch (imNikon.LensDataVersion)
0708       {
0709       case 100:
0710         LensData_len = 9;
0711         break;
0712       case 101:
0713       case 201: // encrypted, starting from v.201
0714       case 202:
0715       case 203:
0716         LensData_len = 15;
0717         break;
0718       case 204:
0719         LensData_len = 16;
0720         break;
0721       case 400:
0722         LensData_len = 459;
0723         break;
0724       case 401:
0725         LensData_len = 590;
0726         break;
0727       case 402:
0728         LensData_len = 509;
0729         break;
0730       case 403:
0731         LensData_len = 879;
0732         break;
0733       case 800:
0734       case 801:
0735         LensData_len = 58;
0736         break;
0737       case 802:
0738         LensData_len = 108;
0739         break;
0740       }
0741       if (LensData_len)
0742       {
0743         LensData_buf = (uchar *)malloc(LensData_len);
0744         fread(LensData_buf, LensData_len, 1, ifp);
0745       }
0746     }
0747     else if (tag == 0x00a0)
0748     {
0749       stmread(imgdata.shootinginfo.BodySerial, len, ifp);
0750     }
0751     else if (tag == 0x00a7) // shutter count
0752     {
0753       imNikon.key = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp);
0754       if (custom_serial)
0755       {
0756         ci = xlat[0][custom_serial];
0757       }
0758       else
0759       {
0760         ci = xlat[0][serial & 0xff];
0761       }
0762       cj = xlat[1][imNikon.key];
0763       ck = 0x60;
0764       if (((unsigned)(imNikon.ColorBalanceVersion - 200) < 18) &&
0765           ColorBalanceData_ready)
0766       {
0767         for (i = 0; i < 324; i++)
0768           ColorBalanceData_buf[i] ^= (cj += ci * ck++);
0769         i = "66666>666;6A;:;555"[imNikon.ColorBalanceVersion - 200] - '0';
0770         FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
0771             sget2(ColorBalanceData_buf + (i & -2) + c * 2);
0772       }
0773 
0774       if (LensData_len)
0775       {
0776         if (imNikon.LensDataVersion > 200)
0777         {
0778           cj = xlat[1][imNikon.key];
0779           ck = 0x60;
0780           for (i = 0; i < LensData_len; i++)
0781           {
0782             LensData_buf[i] ^= (cj += ci * ck++);
0783           }
0784         }
0785         processNikonLensData(LensData_buf, LensData_len);
0786         LensData_len = 0;
0787         free(LensData_buf);
0788       }
0789       if (ShotInfo_len && (imNikon.ShotInfoVersion >= 208)) {
0790         unsigned RotationOffset = 0,
0791                  OrientationOffset = 0;
0792 
0793         cj = xlat[1][imNikon.key];
0794         ck = 0x60;
0795         for (i = 4; i < ShotInfo_len; i++) {
0796           ShotInfo_buf[i] ^= (cj += ci * ck++);
0797 
0798 /* for dump:
0799 cj_block[i-4] = cj;
0800 ck_block[i-4] = ck-1;
0801 */
0802         }
0803 /* for dump:
0804 printf ("==>> ci: 0x%02x, cj at start: 0x%02x\n",
0805 ci, xlat[1][imNikon.key]);
0806 hexDump("ck array:", ck_block, ShotInfo_len-4);
0807 hexDump("cj array:", cj_block, ShotInfo_len-4);
0808 free(cj_block);
0809 free(ck_block);
0810 */
0811 
0812         switch (imNikon.ShotInfoVersion) {
0813         case 208: // ShotInfoD80, Rotation
0814           RotationOffset = 590;
0815           if (RotationOffset<ShotInfo_len) {
0816             imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x07;
0817           }
0818           break;
0819 
0820         case 231: // ShotInfoD4S, Rotation, Roll/Pitch/Yaw
0821           OrientationOffset  = 0x350b;
0822           RotationOffset     = 0x3693;
0823           if (RotationOffset<ShotInfo_len) {
0824             imNikon.MakernotesFlip = (*(ShotInfo_buf+RotationOffset)>>4) & 0x03;
0825           }
0826           break;
0827 
0828         case 233: // ShotInfoD810, Roll/Pitch/Yaw
0829           OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84);
0830           break;
0831 
0832         case 238: // D5,   ShotInfoD500, Rotation, Roll/Pitch/Yaw
0833         case 239: // D500, ShotInfoD500, Rotation, Roll/Pitch/Yaw
0834           RotationOffset = sget4_order(morder, ShotInfo_buf+0x10) + 0xca;
0835           if (RotationOffset > 0xca) {
0836             RotationOffset -= 0xb0;
0837           }
0838           if (RotationOffset<ShotInfo_len) {
0839             imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x03;
0840           }
0841           OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0);
0842           break;
0843 
0844         case 243: // ShotInfoD850, Roll/Pitch/Yaw
0845           OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0);
0846           break;
0847 
0848         case 246: // ShotInfoD6, Roll/Pitch/Yaw
0849           OrientationOffset = sget4_order(morder, ShotInfo_buf+0x9c);
0850           break;
0851 
0852         case 800: // Z 6, Z 7,     ShotInfoZ7II, Roll/Pitch/Yaw
0853         case 801: // Z 50,         ShotInfoZ7II, Roll/Pitch/Yaw
0854         case 802: // Z 5,          ShotInfoZ7II, Roll/Pitch/Yaw
0855         case 803: // Z 6_2, Z 7_2, ShotInfoZ7II, Roll/Pitch/Yaw
0856         case 804: // Z fc          ShotInfoZ7II, Roll/Pitch/Yaw
0857           OrientationOffset = sget4_order(morder, ShotInfo_buf+0x98);
0858           break;
0859 
0860         case 805: // Z 9,          ShotInfoZ9, Roll/Pitch/Yaw
0861           OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84);
0862           break;
0863         }
0864 
0865         if (OrientationOffset && ((OrientationOffset+12)<ShotInfo_len) && OrientationOffset < 0xffff) {
0866           if (imNikon.ShotInfoVersion == 231) // ShotInfoD4S
0867             imNikon.RollAngle = AngleConversion_a(morder, ShotInfo_buf+OrientationOffset);
0868           else
0869             imNikon.RollAngle = AngleConversion(morder, ShotInfo_buf+OrientationOffset);
0870           imNikon.PitchAngle  = AngleConversion (morder, ShotInfo_buf+OrientationOffset+4);
0871           imNikon.YawAngle    = AngleConversion (morder, ShotInfo_buf+OrientationOffset+8);
0872         }
0873         if ((RotationOffset) && (imNikon.MakernotesFlip < 4) && (imNikon.MakernotesFlip >= 0))
0874           imNikon.MakernotesFlip = "0863"[imNikon.MakernotesFlip] - '0';
0875         ShotInfo_len = 0;
0876         free(ShotInfo_buf);
0877       }
0878     }
0879     else if (tag == 0x00a8)
0880     { // contains flash data
0881       FORC4 imNikon.FlashInfoVersion =
0882           imNikon.FlashInfoVersion * 10 + fgetc(ifp) - '0';
0883     }
0884     else if (tag == 0x00b0)
0885     {
0886       get4(); // ME (multi-exposure) tag version, 4 symbols
0887       imNikon.ExposureMode = get4();
0888       imNikon.nMEshots = get4();
0889       imNikon.MEgainOn = get4();
0890     }
0891     else if (tag == 0x00b7) // AFInfo2
0892     {
0893       if (!imCommon.afcount && len > 4)
0894       {
0895         imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
0896         imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
0897         int ver = 0;
0898         FORC4  ver = ver * 10 + (fgetc(ifp) - '0');
0899         imCommon.afdata[imCommon.afcount].AFInfoData_version = ver;
0900         imCommon.afdata[imCommon.afcount].AFInfoData_length = len-4;
0901         imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
0902         fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
0903         imCommon.afcount = 1;
0904       }
0905     }
0906     else if (tag == 0x00b9)
0907     {
0908       imNikon.AFFineTune = fgetc(ifp);
0909       imNikon.AFFineTuneIndex = fgetc(ifp);
0910       imNikon.AFFineTuneAdj = (int8_t)fgetc(ifp);
0911     }
0912     else if ((tag == 0x0100) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED))
0913     {
0914       thumb_offset = ftell(ifp);
0915       thumb_length = len;
0916     }
0917     else if (tag == 0x0e01)
0918     { /* Nikon Software / in-camera edit Note */
0919       int loopc = 0;
0920       int WhiteBalanceAdj_active = 0;
0921       order = 0x4949;
0922       fseek(ifp, 22, SEEK_CUR);
0923       for (offset = 22; offset + 22 < len; offset += 22 + i)
0924       {
0925         if (loopc++ > 1024)
0926           throw LIBRAW_EXCEPTION_IO_CORRUPT;
0927         tag = get4();
0928         fseek(ifp, 14, SEEK_CUR);
0929         i = get4() - 4;
0930 
0931         if (tag == 0x76a43204)
0932         {
0933           WhiteBalanceAdj_active = fgetc(ifp);
0934         }
0935         else if (tag == 0xbf3c6c20)
0936         {
0937           if (WhiteBalanceAdj_active)
0938           {
0939             union {
0940               double dbl;
0941               unsigned long long lng;
0942             } un;
0943             un.dbl = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE);
0944             if ((un.lng != 0x3FF0000000000000ULL) &&
0945                 (un.lng != 0x000000000000F03FULL))
0946             {
0947               cam_mul[0] = un.dbl;
0948               cam_mul[2] = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE);
0949               cam_mul[1] = cam_mul[3] = 1.0;
0950               i -= 16;
0951             }
0952             else
0953               i -= 8;
0954           }
0955           fseek(ifp, i, SEEK_CUR);
0956         }
0957         else if (tag == 0x76a43207)
0958         {
0959           flip = get2();
0960         }
0961         else
0962         {
0963           fseek(ifp, i, SEEK_CUR);
0964         }
0965       }
0966     }
0967     else if (tag == 0x0e22)
0968     {
0969       FORC4 imNikon.NEFBitDepth[c] = get2();
0970     }
0971   next:
0972     fseek(ifp, save, SEEK_SET);
0973   }
0974 quit:
0975   order = sorder;
0976 }
0977 
0978 unsigned sget4_order (short _order, uchar *s) {
0979   unsigned v;
0980   if (_order == 0x4949)
0981     v= s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
0982   else
0983     v= s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
0984   return v;
0985 }
0986 
0987 double sget_fixed32u (short _order, uchar *s) {
0988   unsigned v = sget4_order (_order, s);
0989   return ((double)v / 6.5536 + 0.5) / 10000.0;
0990 }
0991 
0992 double AngleConversion_a (short _order, uchar *s) {
0993   double v = sget_fixed32u(_order, s);
0994   if (v < 180.0) return -v;
0995   return 360.0-v;
0996 }
0997 
0998 double AngleConversion (short _order, uchar *s) {
0999   double v = sget_fixed32u(_order, s);
1000   if (v <= 180.0) return v;
1001   return v-360.0;
1002 }
1003 
1004 /* ========= */
1005 /*
1006 void hexDump(char *title, void *addr, int len)
1007 {
1008     int i;
1009     unsigned char buff[17];
1010     unsigned char *pc = (unsigned char*)addr;
1011 
1012     // Output description if given.
1013     if (title != NULL)
1014         printf ("%s:\n", title);
1015 
1016     // Process every byte in the data.
1017     for (i = 0; i < len; i++) {
1018         // Multiple of 16 means new line (with line offset).
1019 
1020         if ((i % 16) == 0) {
1021             // Just don't print ASCII for the zeroth line.
1022             if (i != 0)
1023                 printf("  %s\n", buff);
1024 
1025             // Output the offset.
1026             printf("  %04x ", i);
1027         }
1028 
1029         // Now the hex code for the specific character.
1030         printf(" %02x", pc[i]);
1031 
1032         // And store a printable ASCII character for later.
1033         if ((pc[i] < 0x20) || (pc[i] > 0x7e)) {
1034             buff[i % 16] = '.';
1035         } else {
1036             buff[i % 16] = pc[i];
1037         }
1038 
1039         buff[(i % 16) + 1] = '\0';
1040     }
1041 
1042     // Pad out last line if not exactly 16 characters.
1043     while ((i % 16) != 0) {
1044         printf("   ");
1045         i++;
1046     }
1047 
1048     // And print the final ASCII bit.
1049     printf("  %s\n", buff);
1050 }
1051 */