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

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004 
0005  LibRaw is free software; you can redistribute it and/or modify
0006  it under the terms of the one of two licenses as you choose:
0007 
0008 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0009    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0010 
0011 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0012    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0013 
0014  */
0015 
0016 #include "../../internal/dcraw_defs.h"
0017 #include "../../internal/libraw_cameraids.h"
0018 
0019 void LibRaw::setPentaxBodyFeatures(unsigned long long id)
0020 {
0021 
0022   ilm.CamID = id;
0023 
0024   switch (id) {
0025   case PentaxID_staristD:
0026   case PentaxID_staristDS:
0027   case PentaxID_staristDL:
0028   case PentaxID_staristDS2:
0029   case PentaxID_GX_1S:
0030   case PentaxID_staristDL2:
0031   case PentaxID_GX_1L:
0032   case PentaxID_K100D:
0033   case PentaxID_K110D:
0034   case PentaxID_K100D_Super:
0035   case PentaxID_K10D:
0036   case PentaxID_GX10:
0037   case PentaxID_K20D:
0038   case PentaxID_GX20:
0039   case PentaxID_K200D:
0040   case PentaxID_K2000:
0041   case PentaxID_K_m:
0042   case PentaxID_K_7:
0043   case PentaxID_K_x:
0044   case PentaxID_K_r:
0045   case PentaxID_K_5:
0046   case PentaxID_K_01:
0047   case PentaxID_K_30:
0048   case PentaxID_K_5_II:
0049   case PentaxID_K_5_II_s:
0050   case PentaxID_K_50:
0051   case PentaxID_K_3:
0052   case PentaxID_K_500:
0053   case PentaxID_K_S1:
0054   case PentaxID_K_S2:
0055   case PentaxID_K_3_II:
0056   case PentaxID_K_3_III:
0057   case PentaxID_K_70:
0058   case PentaxID_KP:
0059     ilm.CameraMount = LIBRAW_MOUNT_Pentax_K;
0060     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
0061     break;
0062   case PentaxID_K_1:
0063   case PentaxID_K_1_Mark_II:
0064     ilm.CameraMount = LIBRAW_MOUNT_Pentax_K;
0065     ilm.CameraFormat = LIBRAW_FORMAT_FF;
0066     break;
0067   case PentaxID_645D:
0068   case PentaxID_645Z:
0069     ilm.CameraMount = LIBRAW_MOUNT_Pentax_645;
0070     ilm.CameraFormat = LIBRAW_FORMAT_CROP645;
0071     break;
0072   case PentaxID_Q:
0073   case PentaxID_Q10:
0074     ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q;
0075     ilm.CameraFormat = LIBRAW_FORMAT_1div2p3INCH;
0076     break;
0077   case PentaxID_Q7:
0078   case PentaxID_Q_S1:
0079     ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q;
0080     ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH;
0081     break;
0082   case PentaxID_MX_1:
0083     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
0084     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
0085     ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH;
0086     ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
0087     break;
0088   case PentaxID_GR_III:
0089   case PentaxID_GR_IIIx:
0090     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
0091     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
0092     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
0093     ilm.LensFormat = LIBRAW_FORMAT_APSC;
0094     ilm.FocalType = LIBRAW_FT_PRIME_LENS;
0095     break;
0096   default:
0097     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
0098     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
0099   }
0100   return;
0101 }
0102 
0103 void LibRaw::PentaxISO(ushort c)
0104 {
0105   int code[] = {3,    4,    5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
0106                 15,   16,   17,  18,  19,  20,  21,  22,  23,  24,  25,  26,
0107                 27,   28,   29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
0108                 39,   40,   41,  42,  43,  44,  45,  50,  100, 200, 400, 800,
0109                 1600, 3200, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
0110                 268,  269,  270, 271, 272, 273, 274, 275, 276, 277, 278};
0111   double value[] = {
0112       50,     64,     80,     100,    125,    160,    200,    250,    320,
0113       400,    500,    640,    800,    1000,   1250,   1600,   2000,   2500,
0114       3200,   4000,   5000,   6400,   8000,   10000,  12800,  16000,  20000,
0115       25600,  32000,  40000,  51200,  64000,  80000,  102400, 128000, 160000,
0116       204800, 258000, 325000, 409600, 516000, 650000, 819200, 50,     100,
0117       200,    400,    800,    1600,   3200,   50,     70,     100,    140,
0118       200,    280,    400,    560,    800,    1100,   1600,   2200,   3200,
0119       4500,   6400,   9000,   12800,  18000,  25600,  36000,  51200};
0120 #define numel (sizeof(code) / sizeof(code[0]))
0121   int i;
0122   for (i = 0; i < (int)numel; i++)
0123   {
0124     if (code[i] == c)
0125     {
0126       iso_speed = value[i];
0127       return;
0128     }
0129   }
0130   if (i == numel)
0131     iso_speed = 65535.0f;
0132 }
0133 #undef numel
0134 
0135 void LibRaw::PentaxLensInfo(unsigned long long id, unsigned len) // tag 0x0207
0136 {
0137   ushort iLensData = 0;
0138   uchar *table_buf;
0139   table_buf = (uchar *)malloc(MAX(len, 128));
0140   fread(table_buf, len, 1, ifp);
0141   if ((id < PentaxID_K100D) ||
0142       (((id == PentaxID_K100D) ||
0143         (id == PentaxID_K110D) ||
0144         (id == PentaxID_K100D_Super)) &&
0145        ((!table_buf[20] ||
0146         (table_buf[20] == 0xff)))))
0147   {
0148     iLensData = 3;
0149     if (ilm.LensID == LIBRAW_LENS_NOT_SET)
0150       ilm.LensID = (((unsigned)table_buf[0]) << 8) + table_buf[1];
0151   }
0152   else
0153     switch (len)
0154     {
0155     case 90: // LensInfo3
0156       iLensData = 13;
0157       if (ilm.LensID == LIBRAW_LENS_NOT_SET)
0158         ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) +
0159                      table_buf[4];
0160       break;
0161     case 91: // LensInfo4
0162       iLensData = 12;
0163       if (ilm.LensID == LIBRAW_LENS_NOT_SET)
0164         ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) +
0165                      table_buf[4];
0166       break;
0167     case 80: // LensInfo5
0168     case 128:
0169       iLensData = 15;
0170       if (ilm.LensID == LIBRAW_LENS_NOT_SET)
0171         ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) << 8) +
0172                      table_buf[5];
0173       break;
0174     case 168: // Ricoh GR III, id 0x1320e
0175       break;
0176     default:
0177       if (id >= 0x12b9cULL) // LensInfo2
0178       {
0179         iLensData = 4;
0180         if (ilm.LensID == LIBRAW_LENS_NOT_SET)
0181           ilm.LensID = ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) << 8) +
0182                        table_buf[3];
0183       }
0184     }
0185   if (iLensData)
0186   {
0187     if (table_buf[iLensData + 9] && (fabs(ilm.CurFocal) < 0.1f))
0188       ilm.CurFocal = 10 * (table_buf[iLensData + 9] >> 2) *
0189                      libraw_powf64l(4, (table_buf[iLensData + 9] & 0x03) - 2);
0190     if (table_buf[iLensData + 10] & 0xf0)
0191       ilm.MaxAp4CurFocal = libraw_powf64l(
0192           2.0f, (float)((table_buf[iLensData + 10] & 0xf0) >> 4) / 4.0f);
0193     if (table_buf[iLensData + 10] & 0x0f)
0194       ilm.MinAp4CurFocal = libraw_powf64l(
0195           2.0f, (float)((table_buf[iLensData + 10] & 0x0f) + 10) / 4.0f);
0196 
0197     if (iLensData != 12)
0198     {
0199       switch (table_buf[iLensData] & 0x06)
0200       {
0201       case 0:
0202         ilm.MinAp4MinFocal = 22.0f;
0203         break;
0204       case 2:
0205         ilm.MinAp4MinFocal = 32.0f;
0206         break;
0207       case 4:
0208         ilm.MinAp4MinFocal = 45.0f;
0209         break;
0210       case 6:
0211         ilm.MinAp4MinFocal = 16.0f;
0212         break;
0213       }
0214       if (table_buf[iLensData] & 0x70)
0215         ilm.LensFStops =
0216             ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f +
0217             5.0f;
0218 
0219       ilm.MinFocusDistance = (float)(table_buf[iLensData + 3] & 0xf8);
0220       ilm.FocusRangeIndex = (float)(table_buf[iLensData + 3] & 0x07);
0221 
0222       if ((table_buf[iLensData + 14] > 1) && (fabs(ilm.MaxAp4CurFocal) < 0.7f))
0223         ilm.MaxAp4CurFocal = libraw_powf64l(
0224             2.0f, (float)((table_buf[iLensData + 14] & 0x7f) - 1) / 32.0f);
0225     }
0226     else if ((id != 0x12e76ULL) && // K-5
0227              (table_buf[iLensData + 15] > 1) &&
0228              (fabs(ilm.MaxAp4CurFocal) < 0.7f))
0229     {
0230       ilm.MaxAp4CurFocal = libraw_powf64l(
0231           2.0f, (float)((table_buf[iLensData + 15] & 0x7f) - 1) / 32.0f);
0232     }
0233   }
0234   free(table_buf);
0235   return;
0236 }
0237 
0238 void LibRaw::parsePentaxMakernotes(int /*base*/, unsigned tag, unsigned type,
0239                                    unsigned len, unsigned dng_writer)
0240 {
0241 
0242   int c;
0243 // printf ("==>> =%s= tag:0x%x, type: %d, len:%d\n", model, tag, type, len);
0244 
0245   if (tag == 0x0005)
0246   {
0247     unique_id = get4();
0248     setPentaxBodyFeatures(unique_id);
0249   }
0250   else if (tag == 0x0008)
0251   { /* 4 is raw, 7 is raw w/ pixel shift, 8 is raw w/ dynamic pixel shift */
0252     imPentax.Quality = get2();
0253   }
0254   else if (tag == 0x000d)
0255   {
0256     imgdata.shootinginfo.FocusMode = imPentax.FocusMode[0] = get2();
0257   }
0258   else if (tag == 0x000e)
0259   {
0260     imgdata.shootinginfo.AFPoint = imPentax.AFPointSelected[0] = get2();
0261     if (len == 2)
0262       imPentax.AFPointSelected_Area = get2();
0263   }
0264   else if (tag == 0x000f)
0265   {
0266     if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
0267     {
0268       imPentax.AFPointsInFocus = get4();
0269       if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff;
0270       else imPentax.AFPointsInFocus_version = 3;
0271     }
0272     else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT))
0273     {
0274       imPentax.AFPointsInFocus = (unsigned) get2();
0275       if (imPentax.AFPointsInFocus == 0x0000ffff)
0276         imPentax.AFPointsInFocus = 0xffffffff;
0277       else imPentax.AFPointsInFocus_version = 2;
0278     }
0279   }
0280   else if (tag == 0x0010)
0281   {
0282     imPentax.FocusPosition = get2();
0283   }
0284   else if (tag == 0x0013)
0285   {
0286     ilm.CurAp = (float)get2() / 10.0f;
0287   }
0288   else if (tag == 0x0014)
0289   {
0290     PentaxISO(get2());
0291   }
0292   else if (tag == 0x0017)
0293   {
0294     imgdata.shootinginfo.MeteringMode = get2();
0295   }
0296   else if (tag == 0x001b) {
0297     cam_mul[2] = get2() / 256.0;
0298   }
0299   else if (tag == 0x001c) {
0300     cam_mul[0] = get2() / 256.0;
0301   }
0302   else if (tag == 0x001d)
0303   {
0304     ilm.CurFocal = (float)get4() / 100.0f;
0305   }
0306   else if (tag == 0x0034)
0307   {
0308     uchar uc;
0309     FORC4
0310     {
0311       fread(&uc, 1, 1, ifp);
0312       imPentax.DriveMode[c] = uc;
0313     }
0314     imgdata.shootinginfo.DriveMode = imPentax.DriveMode[0];
0315   }
0316   else if (tag == 0x0037) {
0317     switch (get2()) {
0318     case 0:
0319       imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
0320       break;
0321     case 1:
0322       imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
0323       break;
0324     default:
0325       imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
0326       break;
0327     }
0328   }
0329   else if (tag == 0x0038)
0330   {
0331     imgdata.sizes.raw_inset_crops[0].cleft = get2();
0332     imgdata.sizes.raw_inset_crops[0].ctop = get2();
0333   }
0334   else if (tag == 0x0039)
0335   {
0336     imgdata.sizes.raw_inset_crops[0].cwidth = get2();
0337     imgdata.sizes.raw_inset_crops[0].cheight = get2();
0338   }
0339   else if (tag == 0x003c)
0340   {
0341     if ((len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) {
0342       imPentax.AFPointsInFocus = get4() & 0x7ff;
0343       if (!imPentax.AFPointsInFocus) {
0344         imPentax.AFPointsInFocus = 0xffffffff;
0345       }
0346       else {
0347         imPentax.AFPointsInFocus_version = 1;
0348       }
0349     }
0350   }
0351   else if (tag == 0x003f)
0352   {
0353     unsigned a = unsigned(fgetc(ifp)) << 8;
0354     ilm.LensID = a | fgetc(ifp);
0355   }
0356   else if (tag == 0x0047)
0357   {
0358     imCommon.CameraTemperature = (float)fgetc(ifp);
0359   }
0360   else if (tag == 0x004d)
0361   {
0362     if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG))
0363       imCommon.FlashEC = getreal(type) / 256.0f;
0364     else
0365       imCommon.FlashEC = (float)((signed short)fgetc(ifp)) / 6.0f;
0366   }
0367   else if (tag == 0x005c)
0368   {
0369     fgetc(ifp);
0370     imgdata.shootinginfo.ImageStabilization = (short)fgetc(ifp);
0371   }
0372   else if (tag == 0x0072)
0373   {
0374     imPentax.AFAdjustment = get2();
0375   }
0376   else if ((tag == 0x007e) && (dng_writer == nonDNG))
0377   {
0378     imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
0379         imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
0380             get4();
0381   }
0382   else if (tag == 0x0080)
0383   {
0384     short a = (short)fgetc(ifp);
0385     switch (a)
0386     {
0387     case 0:
0388       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3;
0389       break;
0390     case 1:
0391       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
0392       break;
0393     case 2:
0394       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9;
0395       break;
0396     case 3:
0397       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1;
0398       break;
0399     }
0400   }
0401 
0402   else if ((tag == 0x0200) && (dng_writer == nonDNG)) { // Pentax black level
0403     FORC4 cblack[RGGB_2_RGBG(c)] = get2();
0404   }
0405 
0406   else if ((tag == 0x0201) && (dng_writer == nonDNG)) { // Pentax As Shot WB
0407     FORC4 cam_mul[RGGB_2_RGBG(c)] = get2();
0408   }
0409 
0410   else if ((tag == 0x0203) && (dng_writer == nonDNG))
0411   {
0412     for (int i = 0; i < 3; i++)
0413       FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0;
0414   }
0415   else if (tag == 0x0205)
0416   {
0417     if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT)
0418     {
0419       imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
0420       imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
0421       imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
0422       imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
0423       fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
0424       if ((len < 25) && (len >= 11))
0425       {
0426         imPentax.AFPointMode = (imCommon.afdata[imCommon.afcount].AFInfoData[3] >>4) & 0x0f;
0427         imPentax.FocusMode[1] = imCommon.afdata[imCommon.afcount].AFInfoData[3] & 0x0f;
0428         imPentax.AFPointSelected[1] = sget2(imCommon.afdata[imCommon.afcount].AFInfoData+4);
0429 // Pentax K-m has multiexposure set to 8 when no multi-exposure is in effect
0430         imPentax.MultiExposure = imCommon.afdata[imCommon.afcount].AFInfoData[10] & 0x0f;
0431       }
0432       imCommon.afcount++;
0433     }
0434   }
0435   else if (tag == 0x0207)
0436   {
0437     if (len < 65535) // Safety belt
0438       PentaxLensInfo(ilm.CamID, len);
0439   }
0440   else if ((tag >= 0x020d) && (tag <= 0x0214))
0441   {
0442     FORC4 icWBC[Pentax_wb_list1[tag - 0x020d]][RGGB_2_RGBG(c)] = get2();
0443   }
0444   else if ((tag == 0x021d) && (len == 18) &&
0445            tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && (dng_writer == nonDNG))
0446   {
0447     for (int i = 0; i < 3; i++)
0448       FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0;
0449   }
0450   else if (tag == 0x021f)
0451   {
0452     if ((unique_id != PentaxID_K_1)    &&
0453         (unique_id != PentaxID_K_3)    &&
0454         (unique_id != PentaxID_K_3_II) &&
0455         (unique_id != PentaxID_K_1_Mark_II))
0456     {
0457       fseek (ifp, 0x0b, SEEK_CUR);
0458       imPentax.AFPointsInFocus = (unsigned) fgetc(ifp);
0459       if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff;
0460       else imPentax.AFPointsInFocus_version = 4;
0461     }
0462   }
0463   else if ((tag == 0x0220) && (dng_writer == nonDNG)) {
0464     meta_offset = ftell(ifp);
0465   }
0466   else if (tag == 0x0221)
0467   {
0468     int nWB = get2();
0469     if (nWB <= int(sizeof(icWBCCTC) / sizeof(icWBCCTC[0])))
0470       FORC(nWB)
0471       {
0472         icWBCCTC[c][0] = (unsigned)0xcfc6 - get2();
0473         fseek(ifp, 2, SEEK_CUR);
0474         icWBCCTC[c][1] = get2();
0475         icWBCCTC[c][2] = icWBCCTC[c][4] = 0x2000;
0476         icWBCCTC[c][3] = get2();
0477       }
0478   }
0479   else if (tag == 0x0215)
0480   {
0481     fseek(ifp, 16, SEEK_CUR);
0482     sprintf(imgdata.shootinginfo.InternalBodySerial, "%d", get4());
0483   }
0484   else if (tag == 0x0229)
0485   {
0486     stmread(imgdata.shootinginfo.BodySerial, len, ifp);
0487   }
0488   else if (tag == 0x022d)
0489   {
0490     int wb_ind;
0491     getc(ifp);
0492     for (int wb_cnt = 0; wb_cnt < (int)Pentax_wb_list2.size(); wb_cnt++)
0493     {
0494       wb_ind = getc(ifp);
0495       if (wb_ind >= 0 && wb_ind < (int)Pentax_wb_list2.size() )
0496         FORC4 icWBC[Pentax_wb_list2[wb_ind]][RGGB_2_RGBG(c)] = get2();
0497     }
0498   }
0499   else if (tag == 0x0239) // Q-series lens info (LensInfoQ)
0500   {
0501     char LensInfo[20];
0502     fseek(ifp, 12, SEEK_CUR);
0503     stread(ilm.Lens, 30, ifp);
0504     strcat(ilm.Lens, " ");
0505     stread(LensInfo, 20, ifp);
0506     strcat(ilm.Lens, LensInfo);
0507   }
0508   else if (tag == 0x0245)
0509   {
0510     if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) {
0511       imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
0512       imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
0513       imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
0514       imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
0515       fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
0516       imCommon.afcount++;
0517     }
0518   }
0519 }
0520 
0521 void LibRaw::parseRicohMakernotes(int /*base*/, unsigned tag, unsigned type,
0522                                   unsigned /*len*/, unsigned /*dng_writer */)
0523 {
0524   char buffer[17];
0525   if (tag == 0x0005)
0526   {
0527     int c;
0528     int count = 0;
0529     fread(buffer, 16, 1, ifp);
0530     buffer[16] = 0;
0531     FORC(16)
0532     {
0533       if ((isspace(buffer[c])) || (buffer[c] == 0x2D) || (isalnum(buffer[c])))
0534         count++;
0535       else
0536         break;
0537     }
0538     if (count == 16)
0539     {
0540       if (strncmp(model, "GXR", 3))
0541       {
0542         sprintf(imgdata.shootinginfo.BodySerial, "%8s", buffer + 8);
0543       }
0544       buffer[8] = 0;
0545       sprintf(imgdata.shootinginfo.InternalBodySerial, "%8s", buffer);
0546     }
0547     else
0548     {
0549       sprintf(imgdata.shootinginfo.BodySerial, "%02x%02x%02x%02x", buffer[4],
0550               buffer[5], buffer[6], buffer[7]);
0551       sprintf(imgdata.shootinginfo.InternalBodySerial, "%02x%02x%02x%02x",
0552               buffer[8], buffer[9], buffer[10], buffer[11]);
0553     }
0554   }
0555   else if ((tag == 0x1001) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT))
0556   {
0557     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
0558     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
0559     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
0560     ilm.LensID = LIBRAW_LENS_NOT_SET;
0561     ilm.FocalType = LIBRAW_FT_PRIME_LENS;
0562     imgdata.shootinginfo.ExposureProgram = get2();
0563   }
0564   else if ((tag == 0x1002) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT))
0565   {
0566     imgdata.shootinginfo.DriveMode = get2();
0567   }
0568   else if (tag == 0x1006)
0569   {
0570     imgdata.shootinginfo.FocusMode = get2();
0571   }
0572   else if (tag == 0x1007)
0573   {
0574     imRicoh.AutoBracketing = get2();
0575   }
0576   else if (tag == 0x1009)
0577   {
0578     imRicoh.MacroMode = get2();
0579   }
0580   else if (tag == 0x100a)
0581   {
0582     imRicoh.FlashMode = get2();
0583   }
0584   else if (tag == 0x100b)
0585   {
0586     imRicoh.FlashExposureComp = getreal(type);
0587   }
0588   else if (tag == 0x100c)
0589   {
0590     imRicoh.ManualFlashOutput = getreal(type);
0591   }
0592   else if ((tag == 0x100b) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL))
0593   {
0594     imCommon.FlashEC = getreal(type);
0595   }
0596   else if ((tag == 0x1017) && ((imRicoh.WideAdapter = get2()) == 2))
0597   {
0598     strcpy(ilm.Attachment, "Wide-Angle Adapter");
0599   }
0600   else if (tag == 0x1018)
0601   {
0602     imRicoh.CropMode = get2();
0603   }
0604   else if (tag == 0x1019)
0605   {
0606     imRicoh.NDFilter = get2();
0607   }
0608   else if (tag == 0x1200)
0609   {
0610     imRicoh.AFStatus = get2();
0611   }
0612   else if (tag == 0x1201)
0613   {
0614     imRicoh.AFAreaXPosition[1] = get4();
0615   }
0616   else if (tag == 0x1202)
0617   {
0618     imRicoh.AFAreaYPosition[1] = get4();
0619   }
0620   else if (tag == 0x1203)
0621   {
0622     imRicoh.AFAreaXPosition[0] = get4();
0623   }
0624   else if (tag == 0x1204)
0625   {
0626     imRicoh.AFAreaYPosition[0] = get4();
0627   }
0628   else if (tag == 0x1205)
0629   {
0630     imRicoh.AFAreaMode = get2();
0631   }
0632   else if (tag == 0x1500)
0633   {
0634     ilm.CurFocal = getreal(type);
0635   }
0636   else if (tag == 0x1601)
0637   {
0638     imRicoh.SensorWidth = get4();
0639   }
0640   else if (tag == 0x1602)
0641   {
0642     imRicoh.SensorHeight = get4();
0643   }
0644   else if (tag == 0x1603)
0645   {
0646     imRicoh.CroppedImageWidth = get4();
0647   }
0648   else if (tag == 0x1604)
0649   {
0650     imRicoh.CroppedImageHeight= get4();
0651   }
0652   else if ((tag == 0x2001) && !strncmp(model, "GXR", 3))
0653   {
0654     short cur_tag;
0655     fseek(ifp, 20, SEEK_CUR);
0656     /*ntags =*/ get2();
0657     cur_tag = get2();
0658     while (cur_tag != 0x002c)
0659     {
0660       fseek(ifp, 10, SEEK_CUR);
0661       cur_tag = get2();
0662     }
0663     fseek(ifp, 6, SEEK_CUR);
0664     fseek(ifp, get4(), SEEK_SET);
0665     for (int i=0; i<4; i++) {
0666       stread(buffer, 16, ifp);
0667       if ((buffer[0] == 'S') && (buffer[1] == 'I') && (buffer[2] == 'D'))
0668         memcpy(imgdata.shootinginfo.BodySerial, buffer+4, 12);
0669       else if ((buffer[0] == 'R') && (buffer[1] == 'L'))
0670         ilm.LensID = buffer[2] - '0';
0671       else if ((buffer[0] == 'L') && (buffer[1] == 'I') && (buffer[2] == 'D'))
0672         memcpy(imgdata.lens.LensSerial, buffer+4, 12);
0673     }
0674   }
0675 }