1 /* -*- C++ -*-
2  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
3  *
4 
5  LibRaw is free software; you can redistribute it and/or modify
6  it under the terms of the one of two licenses as you choose:
7 
8 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
9    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
10 
11 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
12    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
13 
14  */
15 
16 #include "../../internal/dcraw_defs.h"
17 #include "../../internal/libraw_cameraids.h"
18 
setPentaxBodyFeatures(unsigned long long id)19 void LibRaw::setPentaxBodyFeatures(unsigned long long id)
20 {
21 
22   ilm.CamID = id;
23 
24   switch (id) {
25   case PentaxID_staristD:
26   case PentaxID_staristDS:
27   case PentaxID_staristDL:
28   case PentaxID_staristDS2:
29   case PentaxID_GX_1S:
30   case PentaxID_staristDL2:
31   case PentaxID_GX_1L:
32   case PentaxID_K100D:
33   case PentaxID_K110D:
34   case PentaxID_K100D_Super:
35   case PentaxID_K10D:
36   case PentaxID_GX10:
37   case PentaxID_K20D:
38   case PentaxID_GX20:
39   case PentaxID_K200D:
40   case PentaxID_K2000:
41   case PentaxID_K_m:
42   case PentaxID_K_7:
43   case PentaxID_K_x:
44   case PentaxID_K_r:
45   case PentaxID_K_5:
46   case PentaxID_K_01:
47   case PentaxID_K_30:
48   case PentaxID_K_5_II:
49   case PentaxID_K_5_II_s:
50   case PentaxID_K_50:
51   case PentaxID_K_3:
52   case PentaxID_K_500:
53   case PentaxID_K_S1:
54   case PentaxID_K_S2:
55   case PentaxID_K_3_II:
56   case PentaxID_K_3_III:
57   case PentaxID_K_70:
58   case PentaxID_KP:
59     ilm.CameraMount = LIBRAW_MOUNT_Pentax_K;
60     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
61     break;
62   case PentaxID_K_1:
63   case PentaxID_K_1_Mark_II:
64     ilm.CameraMount = LIBRAW_MOUNT_Pentax_K;
65     ilm.CameraFormat = LIBRAW_FORMAT_FF;
66     break;
67   case PentaxID_645D:
68   case PentaxID_645Z:
69     ilm.CameraMount = LIBRAW_MOUNT_Pentax_645;
70     ilm.CameraFormat = LIBRAW_FORMAT_CROP645;
71     break;
72   case PentaxID_Q:
73   case PentaxID_Q10:
74     ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q;
75     ilm.CameraFormat = LIBRAW_FORMAT_1div2p3INCH;
76     break;
77   case PentaxID_Q7:
78   case PentaxID_Q_S1:
79     ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q;
80     ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH;
81     break;
82   case PentaxID_MX_1:
83     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
84     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
85     ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH;
86     ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
87     break;
88   case PentaxID_GR_III:
89   case PentaxID_GR_IIIx:
90     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
91     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
92     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
93     ilm.LensFormat = LIBRAW_FORMAT_APSC;
94     ilm.FocalType = LIBRAW_FT_PRIME_LENS;
95     break;
96   default:
97     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
98     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
99   }
100   return;
101 }
102 
PentaxISO(ushort c)103 void LibRaw::PentaxISO(ushort c)
104 {
105   int code[] = {3,    4,    5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
106                 15,   16,   17,  18,  19,  20,  21,  22,  23,  24,  25,  26,
107                 27,   28,   29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
108                 39,   40,   41,  42,  43,  44,  45,  50,  100, 200, 400, 800,
109                 1600, 3200, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
110                 268,  269,  270, 271, 272, 273, 274, 275, 276, 277, 278};
111   double value[] = {
112       50,     64,     80,     100,    125,    160,    200,    250,    320,
113       400,    500,    640,    800,    1000,   1250,   1600,   2000,   2500,
114       3200,   4000,   5000,   6400,   8000,   10000,  12800,  16000,  20000,
115       25600,  32000,  40000,  51200,  64000,  80000,  102400, 128000, 160000,
116       204800, 258000, 325000, 409600, 516000, 650000, 819200, 50,     100,
117       200,    400,    800,    1600,   3200,   50,     70,     100,    140,
118       200,    280,    400,    560,    800,    1100,   1600,   2200,   3200,
119       4500,   6400,   9000,   12800,  18000,  25600,  36000,  51200};
120 #define numel (sizeof(code) / sizeof(code[0]))
121   int i;
122   for (i = 0; i < (int)numel; i++)
123   {
124     if (code[i] == c)
125     {
126       iso_speed = value[i];
127       return;
128     }
129   }
130   if (i == numel)
131     iso_speed = 65535.0f;
132 }
133 #undef numel
134 
PentaxLensInfo(unsigned long long id,unsigned len)135 void LibRaw::PentaxLensInfo(unsigned long long id, unsigned len) // tag 0x0207
136 {
137   ushort iLensData = 0;
138   uchar *table_buf;
139   table_buf = (uchar *)malloc(MAX(len, 128));
140   fread(table_buf, len, 1, ifp);
141   if ((id < PentaxID_K100D) ||
142       (((id == PentaxID_K100D) ||
143         (id == PentaxID_K110D) ||
144         (id == PentaxID_K100D_Super)) &&
145        ((!table_buf[20] ||
146         (table_buf[20] == 0xff)))))
147   {
148     iLensData = 3;
149     if (ilm.LensID == LIBRAW_LENS_NOT_SET)
150       ilm.LensID = (((unsigned)table_buf[0]) << 8) + table_buf[1];
151   }
152   else
153     switch (len)
154     {
155     case 90: // LensInfo3
156       iLensData = 13;
157       if (ilm.LensID == LIBRAW_LENS_NOT_SET)
158         ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) +
159                      table_buf[4];
160       break;
161     case 91: // LensInfo4
162       iLensData = 12;
163       if (ilm.LensID == LIBRAW_LENS_NOT_SET)
164         ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) +
165                      table_buf[4];
166       break;
167     case 80: // LensInfo5
168     case 128:
169       iLensData = 15;
170       if (ilm.LensID == LIBRAW_LENS_NOT_SET)
171         ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) << 8) +
172                      table_buf[5];
173       break;
174     case 168: // Ricoh GR III, id 0x1320e
175       break;
176     default:
177       if (id >= 0x12b9cULL) // LensInfo2
178       {
179         iLensData = 4;
180         if (ilm.LensID == LIBRAW_LENS_NOT_SET)
181           ilm.LensID = ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) << 8) +
182                        table_buf[3];
183       }
184     }
185   if (iLensData)
186   {
187     if (table_buf[iLensData + 9] && (fabs(ilm.CurFocal) < 0.1f))
188       ilm.CurFocal = 10 * (table_buf[iLensData + 9] >> 2) *
189                      libraw_powf64l(4, (table_buf[iLensData + 9] & 0x03) - 2);
190     if (table_buf[iLensData + 10] & 0xf0)
191       ilm.MaxAp4CurFocal = libraw_powf64l(
192           2.0f, (float)((table_buf[iLensData + 10] & 0xf0) >> 4) / 4.0f);
193     if (table_buf[iLensData + 10] & 0x0f)
194       ilm.MinAp4CurFocal = libraw_powf64l(
195           2.0f, (float)((table_buf[iLensData + 10] & 0x0f) + 10) / 4.0f);
196 
197     if (iLensData != 12)
198     {
199       switch (table_buf[iLensData] & 0x06)
200       {
201       case 0:
202         ilm.MinAp4MinFocal = 22.0f;
203         break;
204       case 2:
205         ilm.MinAp4MinFocal = 32.0f;
206         break;
207       case 4:
208         ilm.MinAp4MinFocal = 45.0f;
209         break;
210       case 6:
211         ilm.MinAp4MinFocal = 16.0f;
212         break;
213       }
214       if (table_buf[iLensData] & 0x70)
215         ilm.LensFStops =
216             ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f +
217             5.0f;
218 
219       ilm.MinFocusDistance = (float)(table_buf[iLensData + 3] & 0xf8);
220       ilm.FocusRangeIndex = (float)(table_buf[iLensData + 3] & 0x07);
221 
222       if ((table_buf[iLensData + 14] > 1) && (fabs(ilm.MaxAp4CurFocal) < 0.7f))
223         ilm.MaxAp4CurFocal = libraw_powf64l(
224             2.0f, (float)((table_buf[iLensData + 14] & 0x7f) - 1) / 32.0f);
225     }
226     else if ((id != 0x12e76ULL) && // K-5
227              (table_buf[iLensData + 15] > 1) &&
228              (fabs(ilm.MaxAp4CurFocal) < 0.7f))
229     {
230       ilm.MaxAp4CurFocal = libraw_powf64l(
231           2.0f, (float)((table_buf[iLensData + 15] & 0x7f) - 1) / 32.0f);
232     }
233   }
234   free(table_buf);
235   return;
236 }
237 
parsePentaxMakernotes(int base,unsigned tag,unsigned type,unsigned len,unsigned dng_writer)238 void LibRaw::parsePentaxMakernotes(int base, unsigned tag, unsigned type,
239                                    unsigned len, unsigned dng_writer)
240 {
241 
242   int c;
243 // printf ("==>> =%s= tag:0x%x, type: %d, len:%d\n", model, tag, type, len);
244 
245   if (tag == 0x0005)
246   {
247     unique_id = get4();
248     setPentaxBodyFeatures(unique_id);
249   }
250   else if (tag == 0x0008)
251   { /* 4 is raw, 7 is raw w/ pixel shift, 8 is raw w/ dynamic pixel shift */
252     imPentax.Quality = get2();
253   }
254   else if (tag == 0x000d)
255   {
256     imgdata.shootinginfo.FocusMode = imPentax.FocusMode[0] = get2();
257   }
258   else if (tag == 0x000e)
259   {
260     imgdata.shootinginfo.AFPoint = imPentax.AFPointSelected[0] = get2();
261     if (len == 2)
262       imPentax.AFPointSelected_Area = get2();
263   }
264   else if (tag == 0x000f)
265   {
266     if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG))
267     {
268       imPentax.AFPointsInFocus = get4();
269       if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff;
270       else imPentax.AFPointsInFocus_version = 3;
271     }
272     else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT))
273     {
274       imPentax.AFPointsInFocus = (unsigned) get2();
275       if (imPentax.AFPointsInFocus == 0x0000ffff)
276         imPentax.AFPointsInFocus = 0xffffffff;
277       else imPentax.AFPointsInFocus_version = 2;
278     }
279   }
280   else if (tag == 0x0010)
281   {
282     imPentax.FocusPosition = get2();
283   }
284   else if (tag == 0x0013)
285   {
286     ilm.CurAp = (float)get2() / 10.0f;
287   }
288   else if (tag == 0x0014)
289   {
290     PentaxISO(get2());
291   }
292   else if (tag == 0x0017)
293   {
294     imgdata.shootinginfo.MeteringMode = get2();
295   }
296   else if (tag == 0x001b) {
297     cam_mul[2] = get2() / 256.0;
298   }
299   else if (tag == 0x001c) {
300     cam_mul[0] = get2() / 256.0;
301   }
302   else if (tag == 0x001d)
303   {
304     ilm.CurFocal = (float)get4() / 100.0f;
305   }
306   else if (tag == 0x0034)
307   {
308     uchar uc;
309     FORC4
310     {
311       fread(&uc, 1, 1, ifp);
312       imPentax.DriveMode[c] = uc;
313     }
314     imgdata.shootinginfo.DriveMode = imPentax.DriveMode[0];
315   }
316   else if (tag == 0x0037) {
317     switch (get2()) {
318     case 0:
319       imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
320       break;
321     case 1:
322       imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
323       break;
324     default:
325       imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
326       break;
327     }
328   }
329   else if (tag == 0x0038)
330   {
331     imgdata.sizes.raw_inset_crops[0].cleft = get2();
332     imgdata.sizes.raw_inset_crops[0].ctop = get2();
333   }
334   else if (tag == 0x0039)
335   {
336     imgdata.sizes.raw_inset_crops[0].cwidth = get2();
337     imgdata.sizes.raw_inset_crops[0].cheight = get2();
338   }
339   else if (tag == 0x003c)
340   {
341     if ((len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) {
342       imPentax.AFPointsInFocus = get4() & 0x7ff;
343       if (!imPentax.AFPointsInFocus) {
344         imPentax.AFPointsInFocus = 0xffffffff;
345       }
346       else {
347         imPentax.AFPointsInFocus_version = 1;
348       }
349     }
350   }
351   else if (tag == 0x003f)
352   {
353     unsigned a = unsigned(fgetc(ifp)) << 8;
354     ilm.LensID = a | fgetc(ifp);
355   }
356   else if (tag == 0x0047)
357   {
358     imCommon.CameraTemperature = (float)fgetc(ifp);
359   }
360   else if (tag == 0x004d)
361   {
362     if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG))
363       imCommon.FlashEC = getreal(type) / 256.0f;
364     else
365       imCommon.FlashEC = (float)((signed short)fgetc(ifp)) / 6.0f;
366   }
367   else if (tag == 0x005c)
368   {
369     fgetc(ifp);
370     imgdata.shootinginfo.ImageStabilization = (short)fgetc(ifp);
371   }
372   else if (tag == 0x0072)
373   {
374     imPentax.AFAdjustment = get2();
375   }
376   else if ((tag == 0x007e) && (dng_writer == nonDNG))
377   {
378     imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
379         imgdata.color.linear_max[2] = imgdata.color.linear_max[3] =
380             get4();
381   }
382   else if (tag == 0x0080)
383   {
384     short a = (short)fgetc(ifp);
385     switch (a)
386     {
387     case 0:
388       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3;
389       break;
390     case 1:
391       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
392       break;
393     case 2:
394       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9;
395       break;
396     case 3:
397       imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1;
398       break;
399     }
400   }
401 
402   else if ((tag == 0x0200) && (dng_writer == nonDNG)) { // Pentax black level
403     FORC4 cblack[RGGB_2_RGBG(c)] = get2();
404   }
405 
406   else if ((tag == 0x0201) && (dng_writer == nonDNG)) { // Pentax As Shot WB
407     FORC4 cam_mul[RGGB_2_RGBG(c)] = get2();
408   }
409 
410   else if ((tag == 0x0203) && (dng_writer == nonDNG))
411   {
412     for (int i = 0; i < 3; i++)
413       FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0;
414   }
415   else if (tag == 0x0205)
416   {
417     if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT)
418     {
419       imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
420       imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
421       imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
422       imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
423       fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
424       if ((len < 25) && (len >= 11))
425       {
426         imPentax.AFPointMode = (imCommon.afdata[imCommon.afcount].AFInfoData[3] >>4) & 0x0f;
427         imPentax.FocusMode[1] = imCommon.afdata[imCommon.afcount].AFInfoData[3] & 0x0f;
428         imPentax.AFPointSelected[1] = sget2(imCommon.afdata[imCommon.afcount].AFInfoData+4);
429 // Pentax K-m has multiexposure set to 8 when no multi-exposure is in effect
430         imPentax.MultiExposure = imCommon.afdata[imCommon.afcount].AFInfoData[10] & 0x0f;
431       }
432       imCommon.afcount++;
433     }
434   }
435   else if (tag == 0x0207)
436   {
437     if (len < 65535) // Safety belt
438       PentaxLensInfo(ilm.CamID, len);
439   }
440   else if ((tag >= 0x020d) && (tag <= 0x0214))
441   {
442     FORC4 icWBC[Pentax_wb_list1[tag - 0x020d]][RGGB_2_RGBG(c)] = get2();
443   }
444   else if ((tag == 0x021d) && (len == 18) &&
445            tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && (dng_writer == nonDNG))
446   {
447     for (int i = 0; i < 3; i++)
448       FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0;
449   }
450   else if (tag == 0x021f)
451   {
452     if ((unique_id != PentaxID_K_1)    &&
453         (unique_id != PentaxID_K_3)    &&
454         (unique_id != PentaxID_K_3_II) &&
455         (unique_id != PentaxID_K_1_Mark_II))
456     {
457       fseek (ifp, 0x0b, SEEK_CUR);
458       imPentax.AFPointsInFocus = (unsigned) fgetc(ifp);
459       if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff;
460       else imPentax.AFPointsInFocus_version = 4;
461     }
462   }
463   else if ((tag == 0x0220) && (dng_writer == nonDNG)) {
464     meta_offset = ftell(ifp);
465   }
466   else if (tag == 0x0221)
467   {
468     int nWB = get2();
469     if (nWB <= int(sizeof(icWBCCTC) / sizeof(icWBCCTC[0])))
470       FORC(nWB)
471       {
472         icWBCCTC[c][0] = (unsigned)0xcfc6 - get2();
473         fseek(ifp, 2, SEEK_CUR);
474         icWBCCTC[c][1] = get2();
475         icWBCCTC[c][2] = icWBCCTC[c][4] = 0x2000;
476         icWBCCTC[c][3] = get2();
477       }
478   }
479   else if (tag == 0x0215)
480   {
481     fseek(ifp, 16, SEEK_CUR);
482     sprintf(imgdata.shootinginfo.InternalBodySerial, "%d", get4());
483   }
484   else if (tag == 0x0229)
485   {
486     stmread(imgdata.shootinginfo.BodySerial, len, ifp);
487   }
488   else if (tag == 0x022d)
489   {
490     int wb_ind;
491     getc(ifp);
492     for (int wb_cnt = 0; wb_cnt < (int)Pentax_wb_list2.size(); wb_cnt++)
493     {
494       wb_ind = getc(ifp);
495       if (wb_ind >= 0 && wb_ind < (int)Pentax_wb_list2.size() )
496         FORC4 icWBC[Pentax_wb_list2[wb_ind]][RGGB_2_RGBG(c)] = get2();
497     }
498   }
499   else if (tag == 0x0239) // Q-series lens info (LensInfoQ)
500   {
501     char LensInfo[20];
502     fseek(ifp, 12, SEEK_CUR);
503     stread(ilm.Lens, 30, ifp);
504     strcat(ilm.Lens, " ");
505     stread(LensInfo, 20, ifp);
506     strcat(ilm.Lens, LensInfo);
507   }
508   else if (tag == 0x0245)
509   {
510     if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) {
511       imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
512       imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
513       imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
514       imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length);
515       fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
516       imCommon.afcount++;
517     }
518   }
519 }
520 
parseRicohMakernotes(int base,unsigned tag,unsigned type,unsigned len,unsigned dng_writer)521 void LibRaw::parseRicohMakernotes(int base, unsigned tag, unsigned type,
522                                   unsigned len, unsigned dng_writer)
523 {
524   char buffer[17];
525   if (tag == 0x0005)
526   {
527     int c;
528     int count = 0;
529     fread(buffer, 16, 1, ifp);
530     buffer[16] = 0;
531     FORC(16)
532     {
533       if ((isspace(buffer[c])) || (buffer[c] == 0x2D) || (isalnum(buffer[c])))
534         count++;
535       else
536         break;
537     }
538     if (count == 16)
539     {
540       if (strncmp(model, "GXR", 3))
541       {
542         sprintf(imgdata.shootinginfo.BodySerial, "%8s", buffer + 8);
543       }
544       buffer[8] = 0;
545       sprintf(imgdata.shootinginfo.InternalBodySerial, "%8s", buffer);
546     }
547     else
548     {
549       sprintf(imgdata.shootinginfo.BodySerial, "%02x%02x%02x%02x", buffer[4],
550               buffer[5], buffer[6], buffer[7]);
551       sprintf(imgdata.shootinginfo.InternalBodySerial, "%02x%02x%02x%02x",
552               buffer[8], buffer[9], buffer[10], buffer[11]);
553     }
554   }
555   else if ((tag == 0x1001) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT))
556   {
557     ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
558     ilm.LensMount = LIBRAW_MOUNT_FixedLens;
559     ilm.CameraFormat = LIBRAW_FORMAT_APSC;
560     ilm.LensID = LIBRAW_LENS_NOT_SET;
561     ilm.FocalType = LIBRAW_FT_PRIME_LENS;
562     imgdata.shootinginfo.ExposureProgram = get2();
563   }
564   else if ((tag == 0x1002) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT))
565   {
566     imgdata.shootinginfo.DriveMode = get2();
567   }
568   else if (tag == 0x1006)
569   {
570     imgdata.shootinginfo.FocusMode = get2();
571   }
572   else if (tag == 0x1007)
573   {
574     imRicoh.AutoBracketing = get2();
575   }
576   else if (tag == 0x1009)
577   {
578     imRicoh.MacroMode = get2();
579   }
580   else if (tag == 0x100a)
581   {
582     imRicoh.FlashMode = get2();
583   }
584   else if (tag == 0x100b)
585   {
586     imRicoh.FlashExposureComp = getreal(type);
587   }
588   else if (tag == 0x100c)
589   {
590     imRicoh.ManualFlashOutput = getreal(type);
591   }
592   else if ((tag == 0x100b) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL))
593   {
594     imCommon.FlashEC = getreal(type);
595   }
596   else if ((tag == 0x1017) && ((imRicoh.WideAdapter = get2()) == 2))
597   {
598     strcpy(ilm.Attachment, "Wide-Angle Adapter");
599   }
600   else if (tag == 0x1018)
601   {
602     imRicoh.CropMode = get2();
603   }
604   else if (tag == 0x1019)
605   {
606     imRicoh.NDFilter = get2();
607   }
608   else if (tag == 0x1200)
609   {
610     imRicoh.AFStatus = get2();
611   }
612   else if (tag == 0x1201)
613   {
614     imRicoh.AFAreaXPosition[1] = get4();
615   }
616   else if (tag == 0x1202)
617   {
618     imRicoh.AFAreaYPosition[1] = get4();
619   }
620   else if (tag == 0x1203)
621   {
622     imRicoh.AFAreaXPosition[0] = get4();
623   }
624   else if (tag == 0x1204)
625   {
626     imRicoh.AFAreaYPosition[0] = get4();
627   }
628   else if (tag == 0x1205)
629   {
630     imRicoh.AFAreaMode = get2();
631   }
632   else if (tag == 0x1500)
633   {
634     ilm.CurFocal = getreal(type);
635   }
636   else if (tag == 0x1601)
637   {
638     imRicoh.SensorWidth = get4();
639   }
640   else if (tag == 0x1602)
641   {
642     imRicoh.SensorHeight = get4();
643   }
644   else if (tag == 0x1603)
645   {
646     imRicoh.CroppedImageWidth = get4();
647   }
648   else if (tag == 0x1604)
649   {
650     imRicoh.CroppedImageHeight= get4();
651   }
652   else if ((tag == 0x2001) && !strncmp(model, "GXR", 3))
653   {
654     short cur_tag;
655     fseek(ifp, 20, SEEK_CUR);
656     /*ntags =*/ get2();
657     cur_tag = get2();
658     while (cur_tag != 0x002c)
659     {
660       fseek(ifp, 10, SEEK_CUR);
661       cur_tag = get2();
662     }
663     fseek(ifp, 6, SEEK_CUR);
664     fseek(ifp, get4(), SEEK_SET);
665     for (int i=0; i<4; i++) {
666       stread(buffer, 16, ifp);
667       if ((buffer[0] == 'S') && (buffer[1] == 'I') && (buffer[2] == 'D'))
668         memcpy(imgdata.shootinginfo.BodySerial, buffer+4, 12);
669       else if ((buffer[0] == 'R') && (buffer[1] == 'L'))
670         ilm.LensID = buffer[2] - '0';
671       else if ((buffer[0] == 'L') && (buffer[1] == 'I') && (buffer[2] == 'D'))
672         memcpy(imgdata.lens.LensSerial, buffer+4, 12);
673     }
674   }
675 }
676