exifparser 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # mk_nikonflensname.rb
4
+ #
5
+ # .. makes the Ruby source code of hash table: Nikon EXIF LensParameters => Lens model name.
6
+ # This is for Exif::Makernote::Tag::LensParameters class
7
+ # in exifparser/nmakernote/nikon2.rb
8
+ #
9
+ # usage : ruby mk_nikonlens_hash.rb nikonmn.cpp >nikonflensname.rb
10
+ # ("nikonmn.cpp" is a exiv2(http://www.exiv2.org/)'s nikon makernote module source code. )
11
+ #
12
+ # Copyright (c) 2009 N.KASHIJUKU <n-kashi[at]whi.m-net.ne.jp>
13
+ # You can redistribute it and/or modify it under GPL2.
14
+ #
15
+ print <<TEOS
16
+ module Exif
17
+ module Tag
18
+ module NikonFmount
19
+ LensName = {
20
+ TEOS
21
+
22
+ open(ARGV[0], "r") do |file|
23
+ file.each_line do |s|
24
+ if (/^\{(0x..),(0x..),(0x..),(0x..),(0x..),(0x..),(0x..),0x..,0x..,0x..,0x.., \"(.*)\", ".*", "(.*)"\}/ =~ s) != nil
25
+ str = %Q[ \[#{$1}, #{$2}, #{$3}, #{$4}, #{$5}, #{$6}, #{$7}\] => "#{$8} #{$9}"]
26
+ str.sub!("f/", "F") if str.include?("Nikon")
27
+ print str + ",\n"
28
+ end
29
+ end
30
+ end
31
+
32
+ print <<EEOS
33
+ [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] => ""
34
+ }
35
+ end
36
+ end
37
+ end
38
+ EEOS
39
+
@@ -0,0 +1,267 @@
1
+ #
2
+ # exifparser/makernote/nikon.rb -
3
+ #
4
+ # Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
5
+ #
6
+ # $Revision: 1.1.1.1 $
7
+ # $Date: 2002/12/16 07:59:00 $
8
+ #
9
+ require 'exifparser/tag'
10
+ require 'exifparser/utils'
11
+
12
+ module Exif
13
+
14
+ module Tag
15
+
16
+ module MakerNote
17
+
18
+ #
19
+ # 0x0003 - Quality
20
+ #
21
+ class Quality < Base
22
+
23
+ def to_s
24
+ n = @formatted.to_i - 1
25
+ (s, q) = n.divmod(3)
26
+
27
+ f =
28
+ case s
29
+ when 0
30
+ 'VGA'
31
+ when 1
32
+ 'SVGA'
33
+ when 2
34
+ 'SXGA'
35
+ when 3
36
+ 'UXGA'
37
+ else
38
+ 'Unknown size'
39
+ end
40
+
41
+ f << ' ' <<
42
+ case q
43
+ when 0
44
+ 'Basic'
45
+ when 1
46
+ 'Normal'
47
+ when 2
48
+ 'Fine'
49
+ else
50
+ 'Unknown quality'
51
+ end
52
+ f
53
+ end
54
+
55
+ end
56
+
57
+ #
58
+ # 0x0004 - ColorMode
59
+ #
60
+ class ColorMode < Base
61
+
62
+ def to_s
63
+ case @formatted
64
+ when 1
65
+ 'Color'
66
+ when 2
67
+ 'Monochrome'
68
+ else
69
+ 'Unknown'
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ #
76
+ # 0x0005 - ImageAdjustment
77
+ #
78
+ class ImageAdjustment < Base
79
+
80
+ def to_s
81
+ case @formatted
82
+ when 0
83
+ 'Normal'
84
+ when 1
85
+ 'Bright+'
86
+ when 2
87
+ 'Bright-'
88
+ when 3
89
+ 'Contrast+'
90
+ when 4
91
+ 'Contrast-'
92
+ else
93
+ 'Unknown'
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ #
100
+ # 0x0006 - CCDSensitivity
101
+ #
102
+ class CCDSensitivity < Base
103
+
104
+ def to_s
105
+ case @formatted
106
+ when 0
107
+ 'ISO80'
108
+ when 2
109
+ 'ISO160'
110
+ when 4
111
+ 'ISO320'
112
+ when 5
113
+ 'ISO100'
114
+ else
115
+ "Unknown(#{@formatted})"
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ #
122
+ # 0x0007 - WhiteBalance
123
+ #
124
+ class WhiteBalance < Base
125
+
126
+ def to_s
127
+ case @formatted
128
+ when 0
129
+ 'Auto'
130
+ when 1
131
+ 'Preset'
132
+ when 2
133
+ 'Daylight'
134
+ when 3
135
+ 'Incandescense'
136
+ when 4
137
+ 'Fluorescence'
138
+ when 5
139
+ 'Cloudy'
140
+ when 6
141
+ 'SpeedLight'
142
+ else
143
+ "Unknown(#{@formatted})"
144
+ end
145
+ end
146
+
147
+ end
148
+
149
+ #
150
+ # 0x0008 - Focus
151
+ #
152
+ class Focus < Base
153
+
154
+ def to_s
155
+ n = @formatted.numerator
156
+ d = @formatted.denominator
157
+ (n == 1 && d == 0) ? 'Pan Focus' : "#{n}/#{d}"
158
+ end
159
+
160
+ end
161
+
162
+ #
163
+ # 0x000a - DigitalZoom
164
+ #
165
+ class DigitalZoom < Base
166
+
167
+ def to_s
168
+ n = @formatted.numerator
169
+ d = @formatted.denominator
170
+ (n == 0 && d == 100) ? 'None' : "%0.1f"%[n.to_f/d.to_f]
171
+ end
172
+
173
+ end
174
+
175
+ #
176
+ # 0x000b - Converter
177
+ #
178
+ class Converter < Base
179
+
180
+ def to_s
181
+ case @formatted
182
+ when 0
183
+ 'None'
184
+ when 1
185
+ 'Fisheye'
186
+ else
187
+ 'Unknown'
188
+ end
189
+ end
190
+
191
+ end
192
+
193
+ end
194
+
195
+ NikonIFDTable = {
196
+ 0x0003 => MakerNote::Quality,
197
+ 0x0004 => MakerNote::ColorMode,
198
+ 0x0005 => MakerNote::ImageAdjustment,
199
+ 0x0006 => MakerNote::CCDSensitivity,
200
+ 0x0007 => MakerNote::WhiteBalance,
201
+ 0x0008 => MakerNote::Focus,
202
+ 0x000a => MakerNote::DigitalZoom,
203
+ 0x000b => MakerNote::Converter
204
+ }
205
+
206
+ end
207
+
208
+ class Nikon
209
+
210
+ def initialize(fin, tiff_origin, dataPos, byteOrder_module)
211
+ @fin = fin
212
+ @tiffHeader0 = tiff_origin
213
+ @dataPos = dataPos
214
+ @byteOrder_module = byteOrder_module
215
+ self.extend @byteOrder_module
216
+ end
217
+
218
+ def scan_IFD
219
+ #
220
+ # Nikon MakerNote starts from 8 byte from the origin.
221
+ #
222
+ @fin.pos = @dataPos + 8
223
+ #
224
+ # get the number of tags
225
+ #
226
+ num_dirs = decode_ushort(fin_read_n(2))
227
+
228
+ #
229
+ # now scan them
230
+ #
231
+ 1.upto(num_dirs) {
232
+ curpos_tag = @fin.pos
233
+ tag = parseTagID(fin_read_n(2))
234
+ tagclass = Tag.find(tag.hex, Tag::NikonIFDTable)
235
+ unit, formatter = Tag::Format::Unit[decode_ushort(fin_read_n(2))]
236
+ count = decode_ulong(fin_read_n(4))
237
+ tagdata = fin_read_n(4)
238
+ obj = tagclass.new(tag, "MakerNote", count)
239
+ obj.extend formatter, @byteOrder_module
240
+ obj.pos = curpos_tag
241
+ if unit * count > 4
242
+ curpos = @fin.pos
243
+ begin
244
+ @fin.pos = @tiffHeader0 + decode_ulong(tagdata)
245
+ obj.dataPos = @fin.pos
246
+ obj.data = fin_read_n(unit*count)
247
+ ensure
248
+ @fin.pos = curpos
249
+ end
250
+ else
251
+ obj.dataPos = @fin.pos - 4
252
+ obj.data = tagdata
253
+ end
254
+ obj.processData
255
+ yield obj
256
+ }
257
+ end
258
+
259
+ private
260
+
261
+ def fin_read_n(n)
262
+ @fin.read(n)
263
+ end
264
+
265
+ end
266
+
267
+ end
@@ -0,0 +1,581 @@
1
+ #
2
+ # exif/makernote/nikon2.rb
3
+ #
4
+ # $Revision: 1.3 $
5
+ # $Date: 2003/04/27 13:54:52 $
6
+ #
7
+ #== Reference
8
+ #
9
+ #http://www.ba.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html
10
+ #
11
+ require 'exifparser/tag'
12
+ require 'exifparser/utils'
13
+ require 'exifparser/makernote/nikonflensname'
14
+
15
+ module Exif
16
+ #
17
+ # Tags used in Nikon Makernote
18
+ #
19
+ module Tag
20
+
21
+ module MakerNote
22
+ #
23
+ # Shared Datas between Tags
24
+ #
25
+ module SharedData
26
+ @@nikon_serial_no = nil # written by NikonCameaSerialNumber Tag
27
+ @@release_count = nil # written by ReleaseCount Tag
28
+ end
29
+
30
+ #
31
+ # Subclass for Tags need shared datas
32
+ #
33
+ class NikonBase < Base
34
+ include SharedData
35
+ end
36
+
37
+ #
38
+ # 0x0001 - Data Version
39
+ #
40
+ class DataVersion < Base
41
+ end
42
+
43
+
44
+ #
45
+ # 0x0002 - ISOUsed
46
+ #
47
+ # class ISOUsed < Base
48
+ # end
49
+
50
+ #
51
+ # 0x0003 - ColorMode
52
+ #
53
+ class ColorMode < Base
54
+ end
55
+
56
+ #
57
+ # 0x0004 - ImageQuality
58
+ #
59
+ class ImageQuality < Base
60
+ end
61
+
62
+ #
63
+ # 0x0005 - Whitebalance
64
+ #
65
+ class Whitebalance < Base
66
+ end
67
+
68
+ #
69
+ # 0x0006 - ImageSharpening
70
+ #
71
+ class ImageSharpening < Base
72
+ end
73
+
74
+ #
75
+ # 0x0007 - FocusingMode
76
+ #
77
+ class FocusingMode < Base
78
+ end
79
+
80
+ #
81
+ # 0x0008 - FlashSetting
82
+ #
83
+ class FlashSetting < Base
84
+ end
85
+
86
+ #
87
+ # 0x0009 - SpeedlightMode
88
+ #
89
+ class SpeedlightMode < Base
90
+ end
91
+
92
+ #
93
+ # 0x000d - ProgramShift
94
+ #
95
+ class ProgramShift < Base
96
+
97
+ def to_s
98
+ case @formatted
99
+ when [0xfc, 0x01, 0x06, 0x00]
100
+ "-2/3EV"
101
+ when [0xfd, 0x01, 0x06, 0x00]
102
+ "-1/2EV"
103
+ when [0xfe, 0x01, 0x06, 0x00]
104
+ "-1/3EV"
105
+ when [0x00, 0x01, 0x06, 0x00]
106
+ "+0EV"
107
+ when [0x02, 0x01, 0x06, 0x00]
108
+ "+1/3EV"
109
+ when [0x03, 0x01, 0x06, 0x00]
110
+ "+1/2EV"
111
+ when [0x04, 0x01, 0x06, 0x00]
112
+ "+2/3EV"
113
+ else
114
+ ""
115
+ end
116
+ end
117
+
118
+ end
119
+
120
+ #
121
+ # 0x000e - ExposureDifference
122
+ #
123
+ class ExposureDifference < Base
124
+
125
+ def to_s
126
+ case @formatted
127
+ when [0xf7, 0x01, 0x0c, 0x00]
128
+ "-2/3EV"
129
+ when [0xf9, 0x01, 0x0c, 0x00]
130
+ "-1/2EV"
131
+ when [0xfc, 0x01, 0x0c, 0x00]
132
+ "-1/3EV"
133
+ when [0x00, 0x01, 0x0c, 0x00]
134
+ "+0EV"
135
+ when [0x04, 0x01, 0x0c, 0x00]
136
+ "+1/3EV"
137
+ when [0x06, 0x01, 0x0c, 0x00]
138
+ "+1/2EV"
139
+ when [0x08, 0x01, 0x0c, 0x00]
140
+ "+2/3EV"
141
+ else
142
+ ""
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ #
149
+ # 0x000f - ISOSelection
150
+ #
151
+ class ISOSelection < Base
152
+ end
153
+
154
+ #
155
+ # 0x0010 - DataDump
156
+ #
157
+ class DataDump < Base
158
+ end
159
+
160
+ #
161
+ # 0x0012 - Speedlight Bias
162
+ #
163
+ class SpeedlightBias < Base
164
+
165
+ def to_s
166
+ case @formatted
167
+ when [0xfc, 0x01, 0x06, 0x00]
168
+ "-2/3EV"
169
+ when [0xfd, 0x01, 0x06, 0x00]
170
+ "-1/2EV"
171
+ when [0xfe, 0x01, 0x06, 0x00]
172
+ "-1/3EV"
173
+ when [0x00, 0x01, 0x06, 0x00]
174
+ "+0EV"
175
+ when [0x02, 0x01, 0x06, 0x00]
176
+ "+1/3EV"
177
+ when [0x03, 0x01, 0x06, 0x00]
178
+ "+1/2EV"
179
+ when [0x04, 0x01, 0x06, 0x00]
180
+ "+2/3EV"
181
+ else
182
+ ""
183
+ end
184
+ end
185
+
186
+ end
187
+
188
+ #
189
+ # 0x001d - NikonCameraSerialNumber
190
+ #
191
+ class NikonCameraSerialNumber < NikonBase
192
+
193
+ def processData
194
+ super
195
+ @@nikon_serial_no = @formatted # This value is used for LensParamaters tag.
196
+ end
197
+
198
+ end
199
+
200
+ #
201
+ # 0x0022 ActiveD_Lighting
202
+ #
203
+ class ActiveD_Lighting < Base
204
+
205
+ def to_s
206
+ case @formatted
207
+ when 0
208
+ "Off"
209
+ when 1
210
+ "Low"
211
+ when 3
212
+ "Normal"
213
+ when 5
214
+ "Hight"
215
+ when 7
216
+ "Extra High"
217
+ when 65535
218
+ "Auto"
219
+ else
220
+ ""
221
+ end
222
+ end
223
+
224
+ end
225
+
226
+ #
227
+ # 0x0023 - PictureControl
228
+ #
229
+ class PictureControl < Base
230
+ def to_s
231
+ @formatted[4,20].pack('C*')
232
+ end
233
+ end
234
+
235
+ #
236
+ # 0x0080 - ImageAdjustment
237
+ #
238
+ class ImageAdjustment < Base
239
+ end
240
+
241
+ #
242
+ # 0x0081 - Tone Compensation
243
+ #
244
+ class ToneCompensation < Base
245
+ end
246
+
247
+ #
248
+ # 0x0082 - Adapter
249
+ #
250
+ class Adapter < Base
251
+ end
252
+
253
+ #
254
+ # 0x0083 - LensType
255
+ #
256
+ class LensType < Base
257
+ def to_s
258
+ data = @formatted[0]
259
+ isVR = (data[3] == 1 ? "Yes":"No")
260
+ isG = (data[2] == 1 ? "Yes":"No")
261
+ isD = (data[1] == 1 ? "Yes":"No")
262
+ isMF = (data[0] == 1 ? "Yes":"No")
263
+ "VR:#{isVR}, G:#{isG}, D:#{isD}, MF:#{isMF}"
264
+ end
265
+ end
266
+
267
+ #
268
+ # 0x0084 - LensSpecification
269
+ #
270
+ class LensSpecification < Base
271
+ def processData
272
+ @formatted = []
273
+ partition_data(@count) do |data|
274
+ @formatted.push _formatData(data)
275
+ end
276
+ end
277
+
278
+ def to_s
279
+ if @formatted[0] != @formatted[1]
280
+ "#{@formatted[0]}-#{@formatted[1]}mm, F#{@formatted[2].to_f}-#{@formatted[3].to_f}"
281
+ else
282
+ "#{@formatted[0]}mm, F#{@formatted[2].to_f} (Prime Lens)"
283
+ end
284
+ end
285
+ end
286
+
287
+ #
288
+ # 0x0085 - ManualForcusDistance
289
+ #
290
+ class ManualForcusDistance < Base
291
+ end
292
+
293
+ #
294
+ # 0x0086 - DigitalZoom
295
+ #
296
+ class DigitalZoom < Base
297
+ end
298
+
299
+ #
300
+ # 0x0088 - AFFocusPosition
301
+ #
302
+ class AFFocusPosition < Base
303
+ end
304
+
305
+ #
306
+ # 0x008D - CameraColorMode
307
+ #
308
+ class CameraColorMode < Base
309
+ end
310
+
311
+ #
312
+ # 0x008F - SceneMode
313
+ #
314
+ class SceneMode < Base
315
+ end
316
+
317
+ #
318
+ # 0x0090 - LightSource
319
+ #
320
+ class LightSource < Base
321
+ end
322
+
323
+ #
324
+ # 0x0095 - LongtimeExposureNR
325
+ #
326
+ class LongtimeExposureNR < Base
327
+ end
328
+
329
+ #
330
+ # 0x0098 - LensParamaters
331
+ #
332
+ class LensParameters < NikonBase
333
+ def _format0(data)
334
+ data.unpack("C*").collect{|e| e.to_i}
335
+ end
336
+
337
+ def to_hex
338
+ str = ""
339
+ @formatted.each do |dat|
340
+ str += sprintf("%02x ", dat)
341
+ end
342
+ return str
343
+ end
344
+
345
+ XLAT0 = [0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
346
+ 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
347
+ 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
348
+ 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
349
+ 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
350
+ 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
351
+ 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
352
+ 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
353
+ 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
354
+ 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
355
+ 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
356
+ 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
357
+ 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
358
+ 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
359
+ 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
360
+ 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7]
361
+
362
+ XLAT1 = [0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
363
+ 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
364
+ 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
365
+ 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
366
+ 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
367
+ 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
368
+ 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
369
+ 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
370
+ 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
371
+ 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
372
+ 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
373
+ 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
374
+ 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
375
+ 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
376
+ 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
377
+ 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f]
378
+
379
+ def to_s
380
+ data = @formatted
381
+ lens_data = ""
382
+ version = data[0, 4].pack('C*')
383
+ case version
384
+ when "0100"
385
+ lens_data = data[6, 7]
386
+
387
+ when "0101"
388
+ lens_data = data[11, 7]
389
+
390
+ when "0201", "0202", "0203"
391
+ decryptted = decrypt_data(data[4..(data.length - 1)], @@nikon_serial_no, @@release_count)
392
+ lens_data = decryptted[7, 7]
393
+
394
+ when "0204"
395
+ decryptted = decrypt_data(data[4..(data.length - 1)], @@nikon_serial_no, @@release_count)
396
+ lens_data = decryptted[8, 7]
397
+ end
398
+
399
+ return "" if lens_data.length == 0
400
+
401
+ self.extend NikonFmount
402
+ ret = Tag::NikonFmount::LensName[lens_data]
403
+ return ret != nil ? ret : ""
404
+
405
+ end
406
+
407
+ def decrypt_data(data, serial, count)
408
+ serialno = serial.to_i
409
+ if serialno == 0
410
+ if serial[0,3] == "D50"
411
+ serialno = 0x22
412
+ else
413
+ serialno = 0x60
414
+ end
415
+ end
416
+
417
+ key = 0
418
+ 4.times do |i|
419
+ key ^= ((count >> (i*8)) & 0xff)
420
+ end
421
+
422
+ ci = XLAT0[serialno & 0xff]
423
+ cj = XLAT1[key]
424
+ ck = 0x60;
425
+ pdata = []
426
+
427
+ data.each do |dat|
428
+ cj += ((ci * ck) & 0xff)
429
+ cj &= 0xff
430
+ ck += 1
431
+ pdata.push(dat ^= cj)
432
+ end
433
+
434
+ return pdata
435
+ end
436
+ end
437
+
438
+ #
439
+ # 0x00a7 - ReleaseCount
440
+ #
441
+ class ReleaseCount < NikonBase
442
+ def processData
443
+ super
444
+ @@release_count = @formatted # This value is used for LensParamaters tag.
445
+ end
446
+ end
447
+
448
+ #
449
+ # 0x00a9 - ImageOptimization
450
+ #
451
+ class ImageOptimization < Base
452
+ end
453
+
454
+ #
455
+ # 0x00aa - Saturation
456
+ #
457
+ class Saturation < Base
458
+ end
459
+
460
+ end
461
+
462
+
463
+ Nikon2IFDTable = {
464
+ 0x0001 => MakerNote::DataVersion,
465
+ # 0x0002 => MakerNote::ISOUsed,
466
+ 0x0003 => MakerNote::ColorMode,
467
+ 0x0004 => MakerNote::ImageQuality,
468
+ 0x0005 => MakerNote::Whitebalance,
469
+ 0x0006 => MakerNote::ImageSharpening,
470
+ 0x0007 => MakerNote::FocusingMode,
471
+ 0x0008 => MakerNote::FlashSetting,
472
+ 0x0009 => MakerNote::SpeedlightMode,
473
+ 0x000d => MakerNote::ProgramShift,
474
+ 0x000e => MakerNote::ExposureDifference,
475
+ 0x000f => MakerNote::ISOSelection,
476
+ 0x0010 => MakerNote::DataDump,
477
+ 0x0012 => MakerNote::SpeedlightBias,
478
+ 0x001d => MakerNote::NikonCameraSerialNumber,
479
+ 0x0022 => MakerNote::ActiveD_Lighting,
480
+ 0x0023 => MakerNote::PictureControl,
481
+ 0x0080 => MakerNote::ImageAdjustment,
482
+ 0x0081 => MakerNote::ToneCompensation,
483
+ 0x0082 => MakerNote::Adapter,
484
+ 0x0083 => MakerNote::LensType,
485
+ 0x0084 => MakerNote::LensSpecification,
486
+ 0x0085 => MakerNote::ManualForcusDistance,
487
+ 0x0086 => MakerNote::DigitalZoom,
488
+ 0x0088 => MakerNote::AFFocusPosition,
489
+ 0x008D => MakerNote::CameraColorMode,
490
+ 0x008F => MakerNote::SceneMode,
491
+ 0x0090 => MakerNote::LightSource,
492
+ 0x0095 => MakerNote::LongtimeExposureNR,
493
+ 0x0098 => MakerNote::LensParameters,
494
+ 0x00a7 => MakerNote::ReleaseCount,
495
+ 0x00a9 => MakerNote::ImageOptimization,
496
+ 0x00aa => MakerNote::Saturation
497
+
498
+ }
499
+
500
+ end
501
+
502
+ class Nikon2
503
+
504
+ def initialize(fin, tiff_origin, dataPos, byteOrder_module)
505
+ @fin = fin
506
+ @tiffHeader0 = tiff_origin
507
+ @dataPos = dataPos
508
+ @nikonOffset = 0
509
+
510
+ @fin.pos = dataPos
511
+ magic = fin_read_n(6)
512
+
513
+ if magic == "Nikon\000"
514
+ @nikonOffset = 18 # D100, E5700, etc..
515
+ fin_read_n(4)
516
+ @tiffHeader0 = @fin.pos
517
+ bo = @fin.read(2)
518
+ case bo
519
+ when "MM"
520
+ byteOrder_module = Utils::Decode::Motorola
521
+ when "II"
522
+ byteOrder_module = Utils::Decode::Intel
523
+ else
524
+ raise RuntimeError, "Unknown byte order"
525
+ end
526
+ end
527
+ @byteOrder_module = byteOrder_module
528
+ self.extend @byteOrder_module
529
+ end
530
+
531
+ def scan_IFD
532
+ #
533
+ # Nikon D1 series MakerNote starts from 0 byte from the origin.
534
+ #
535
+ @fin.pos = @dataPos + @nikonOffset
536
+
537
+ #
538
+ # get the number of tags
539
+ #
540
+ num_dirs = decode_ushort(fin_read_n(2))
541
+
542
+ #
543
+ # now scan them
544
+ #
545
+ 1.upto(num_dirs) {
546
+ curpos_tag = @fin.pos
547
+ tag = parseTagID(fin_read_n(2))
548
+ tagclass = Tag.find(tag.hex, Tag::Nikon2IFDTable)
549
+ unit, formatter = Tag::Format::Unit[decode_ushort(fin_read_n(2))]
550
+ count = decode_ulong(fin_read_n(4))
551
+ tagdata = fin_read_n(4)
552
+ obj = tagclass.new(tag, "MakerNote", count)
553
+ obj.extend formatter, @byteOrder_module
554
+ obj.pos = curpos_tag
555
+ if unit * count > 4
556
+ curpos = @fin.pos
557
+ begin
558
+ @fin.pos = @tiffHeader0 + decode_ulong(tagdata)
559
+ obj.dataPos = @fin.pos
560
+ obj.data = fin_read_n(unit*count)
561
+ ensure
562
+ @fin.pos = curpos
563
+ end
564
+ else
565
+ obj.dataPos = @fin.pos - 4
566
+ obj.data = tagdata
567
+ end
568
+ obj.processData
569
+ yield obj
570
+ }
571
+ end
572
+
573
+ private
574
+
575
+ def fin_read_n(n)
576
+ @fin.read(n)
577
+ end
578
+
579
+ end
580
+
581
+ end