tdiary-contrib 3.2.2.20130518 → 3.2.2.20130614
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -3
- data/doc/ja/plugin/image_gps.txt +56 -17
- data/doc/ja/plugin/playstore.txt +31 -0
- data/js/socialbutton.js +8 -2
- data/lib/exifparser/README +6 -12
- data/lib/tdiary-contrib.rb +7 -6
- data/plugin/brow_si.rb +32 -0
- data/plugin/image_gps.rb +110 -56
- data/plugin/instagr.rb +1 -0
- data/plugin/playstore.rb +161 -0
- data/plugin/tweet_quote.rb +102 -48
- data/plugin/twitter_badge.rb +1 -1
- data/util/estraier-search/estraier-register.rb +2 -1
- data/util/estraier-search/estraier-search.rb +2 -1
- data/util/image-gallery/misc/plugin/recent_image.rb +1 -1
- metadata +7 -27
- data/doc/ja/plugin/image_detail.txt +0 -69
- data/doc/ja/plugin/image_gps2.txt +0 -41
- data/lib/exifparser/BUGS +0 -1
- data/lib/exifparser/ChangeLog +0 -169
- data/lib/exifparser/install.rb +0 -1015
- data/lib/exifparser/lib/exifparser/makernote/canon.rb +0 -502
- data/lib/exifparser/lib/exifparser/makernote/fujifilm.rb +0 -415
- data/lib/exifparser/lib/exifparser/makernote/minolta.rb +0 -84
- data/lib/exifparser/lib/exifparser/makernote/mk_nikonflensname.rb +0 -39
- data/lib/exifparser/lib/exifparser/makernote/nikon.rb +0 -267
- data/lib/exifparser/lib/exifparser/makernote/nikon2.rb +0 -581
- data/lib/exifparser/lib/exifparser/makernote/nikonflensname.rb +0 -438
- data/lib/exifparser/lib/exifparser/makernote/olympus.rb +0 -225
- data/lib/exifparser/lib/exifparser/makernote/prove.rb +0 -84
- data/lib/exifparser/lib/exifparser/makernote/sigma.rb +0 -237
- data/lib/exifparser/lib/exifparser/pre-setup.rb +0 -1
- data/lib/exifparser/lib/exifparser/scan.rb +0 -278
- data/lib/exifparser/lib/exifparser/tag.rb +0 -2298
- data/lib/exifparser/lib/exifparser/thumbnail.rb +0 -76
- data/lib/exifparser/lib/exifparser/utils.rb +0 -88
- data/lib/exifparser/lib/exifparser.rb +0 -265
- data/lib/exifparser/sample/exifview.rb +0 -279
- data/plugin/image_detail.rb +0 -143
@@ -1,2298 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# exifparser/tag.rb
|
3
|
-
#
|
4
|
-
# Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
5
|
-
#
|
6
|
-
# $Revision: 1.3 $
|
7
|
-
# $Date: 2003/04/27 14:02:39 $
|
8
|
-
#
|
9
|
-
require 'exifparser/utils'
|
10
|
-
require 'rational'
|
11
|
-
|
12
|
-
module Exif
|
13
|
-
|
14
|
-
module Error
|
15
|
-
class TagNotFound < StandardError; end
|
16
|
-
end
|
17
|
-
|
18
|
-
module Tag
|
19
|
-
|
20
|
-
#
|
21
|
-
# modules under this module provides '_formatData()' method,
|
22
|
-
# which is invoked in Exif::Tag::Base#processData().
|
23
|
-
#
|
24
|
-
module Formatter
|
25
|
-
|
26
|
-
#
|
27
|
-
# convert data to unsigned byte(1 byte) value.
|
28
|
-
#
|
29
|
-
module UByte
|
30
|
-
|
31
|
-
def format
|
32
|
-
'Unsigned byte'
|
33
|
-
end
|
34
|
-
|
35
|
-
def _formatData(data)
|
36
|
-
decode_ubytes(data)
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
#
|
42
|
-
# convert data to ASCII(1 byte) values.
|
43
|
-
#
|
44
|
-
module Ascii
|
45
|
-
|
46
|
-
def format
|
47
|
-
'Ascii'
|
48
|
-
end
|
49
|
-
|
50
|
-
def _formatData(data)
|
51
|
-
data.delete("\000")
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
# convert data to unsigned short(2 byte) value.
|
58
|
-
#
|
59
|
-
module UShort
|
60
|
-
|
61
|
-
def format
|
62
|
-
'Unsigned short'
|
63
|
-
end
|
64
|
-
|
65
|
-
def _formatData(data)
|
66
|
-
decode_ushort(data)
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
# convert data to unsigned long(4 byte) value.
|
73
|
-
#
|
74
|
-
module ULong
|
75
|
-
|
76
|
-
def format
|
77
|
-
'Unsigned long'
|
78
|
-
end
|
79
|
-
|
80
|
-
def _formatData(data)
|
81
|
-
decode_ulong(data)
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
#
|
87
|
-
# convert data to unsigned rational(4+4 byte) value,
|
88
|
-
# which in turn is converted to Rational object.
|
89
|
-
#
|
90
|
-
module URational
|
91
|
-
|
92
|
-
def format
|
93
|
-
'Unsigned rational'
|
94
|
-
end
|
95
|
-
|
96
|
-
def _formatData(data)
|
97
|
-
a = decode_ulong(data[0,4])
|
98
|
-
b = decode_ulong(data[4,4])
|
99
|
-
return Rational(0,1) if b == 0
|
100
|
-
Rational(a, b)
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
#
|
106
|
-
# convert data to some value by user-supplied method.
|
107
|
-
# the client code should implement 'convert(data)' method.
|
108
|
-
#
|
109
|
-
module Undefined
|
110
|
-
|
111
|
-
def format
|
112
|
-
'Undefined'
|
113
|
-
end
|
114
|
-
|
115
|
-
def _formatData(data)
|
116
|
-
if self.respond_to?(:_format0)
|
117
|
-
_format0(data)
|
118
|
-
else
|
119
|
-
data.unpack("C*").collect{|e| e.to_i}
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
#
|
126
|
-
# convert data to signed short value.
|
127
|
-
#
|
128
|
-
module SShort
|
129
|
-
|
130
|
-
def format
|
131
|
-
'Signed short'
|
132
|
-
end
|
133
|
-
|
134
|
-
def _formatData(data)
|
135
|
-
decode_sshort(data)
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
#
|
141
|
-
# convert data to unsigned long(4 byte) value.
|
142
|
-
#
|
143
|
-
module SLong
|
144
|
-
|
145
|
-
def format
|
146
|
-
'Signed long'
|
147
|
-
end
|
148
|
-
|
149
|
-
def _formatData(data)
|
150
|
-
decode_slong(data)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
#
|
155
|
-
# convert data to signed rational (4+4 byte) value.
|
156
|
-
#
|
157
|
-
module SRational
|
158
|
-
|
159
|
-
def format
|
160
|
-
'Signed rational'
|
161
|
-
end
|
162
|
-
|
163
|
-
def _formatData(data)
|
164
|
-
a = decode_slong(data[0,4])
|
165
|
-
b = decode_slong(data[4,4])
|
166
|
-
return Rational(0,1) if b == 0
|
167
|
-
Rational(a, b)
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
|
173
|
-
end # module Formatter
|
174
|
-
|
175
|
-
#
|
176
|
-
# maps number to size of one unit and the
|
177
|
-
# corresponding formatter (defined below) module.
|
178
|
-
#
|
179
|
-
module Format
|
180
|
-
|
181
|
-
Unit = {
|
182
|
-
1 => [1, ::Exif::Tag::Formatter::UByte],
|
183
|
-
2 => [1, ::Exif::Tag::Formatter::Ascii],
|
184
|
-
3 => [2, ::Exif::Tag::Formatter::UShort],
|
185
|
-
4 => [4, ::Exif::Tag::Formatter::ULong],
|
186
|
-
5 => [8, ::Exif::Tag::Formatter::URational],
|
187
|
-
#6 => [1, ::Exif::Tag::Formatter::SByte],
|
188
|
-
7 => [1, ::Exif::Tag::Formatter::Undefined],
|
189
|
-
8 => [2, ::Exif::Tag::Formatter::SShort],
|
190
|
-
9 => [4, ::Exif::Tag::Formatter::SLong],
|
191
|
-
10 => [8, ::Exif::Tag::Formatter::SRational],
|
192
|
-
#11 => [4, Exif::Formatter::SFloat],
|
193
|
-
#12 => [8, Exif::Formatter::DFloat]
|
194
|
-
}
|
195
|
-
|
196
|
-
end
|
197
|
-
|
198
|
-
#
|
199
|
-
# The base class that specifies common operations for tag data.
|
200
|
-
# All the tag classes are derived from this, and client code
|
201
|
-
# shoude use the public methods as interface.
|
202
|
-
#
|
203
|
-
class Base
|
204
|
-
#
|
205
|
-
# the argument 'byteorder' is either :intel or :motorola.
|
206
|
-
# this is used when packing @data given after initialized.
|
207
|
-
#
|
208
|
-
def initialize(tagID, ifdname, count)
|
209
|
-
@tagID = tagID
|
210
|
-
@IFD = ifdname
|
211
|
-
@count = count
|
212
|
-
@data = nil
|
213
|
-
@formatted = nil
|
214
|
-
@pos = nil
|
215
|
-
@dataPos = nil
|
216
|
-
end
|
217
|
-
attr_writer :data
|
218
|
-
attr_accessor :pos, :dataPos
|
219
|
-
attr_reader :tagID, :IFD, :count
|
220
|
-
|
221
|
-
def processData
|
222
|
-
@formatted = _formatData(@data)
|
223
|
-
end
|
224
|
-
|
225
|
-
#
|
226
|
-
# return tag's value: simply returns @formatted as it is.
|
227
|
-
#
|
228
|
-
def value
|
229
|
-
@formatted
|
230
|
-
end
|
231
|
-
|
232
|
-
#
|
233
|
-
# String representation of tag's value
|
234
|
-
# this is the default method that simply
|
235
|
-
# sends Object#to_s to @formatted.
|
236
|
-
# Subclasses may override this so that
|
237
|
-
# it returns more human-readable form.
|
238
|
-
#
|
239
|
-
def to_s
|
240
|
-
if self.is_a? Formatter::Undefined
|
241
|
-
length = @formatted.length
|
242
|
-
data = length > 8 ? @formatted[0, 8] : @formatted
|
243
|
-
ret = ""
|
244
|
-
data.each do |dat|
|
245
|
-
ret += sprintf("%02X ", dat)
|
246
|
-
end
|
247
|
-
ret += %Q[...(#{length} bytes)] if length > data.length
|
248
|
-
return ret
|
249
|
-
else
|
250
|
-
@formatted.to_s
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
#
|
255
|
-
# return tag's name
|
256
|
-
#
|
257
|
-
def name
|
258
|
-
self.class.to_s.split("::")[-1]
|
259
|
-
end
|
260
|
-
|
261
|
-
#
|
262
|
-
# format focal length
|
263
|
-
#
|
264
|
-
def formatFocalLength(f)
|
265
|
-
if (f.abs < 10.0)
|
266
|
-
str = "%.1f"%[f]
|
267
|
-
else
|
268
|
-
str = "%.0f"%[f]
|
269
|
-
end
|
270
|
-
"#{str}mm"
|
271
|
-
end
|
272
|
-
|
273
|
-
#
|
274
|
-
# format exposure time
|
275
|
-
#
|
276
|
-
def formatExposureTime(ss)
|
277
|
-
rss = 1.0/ss
|
278
|
-
if (rss >= 3.0)
|
279
|
-
str = "1/%.0f"%[rss]
|
280
|
-
elsif (3.0 > rss && rss > 1.0)
|
281
|
-
str = "1/%.1f"%[rss]
|
282
|
-
elsif (ss == 1.0)
|
283
|
-
str = "1.0"
|
284
|
-
elsif (3.0 > ss && ss > 1.0)
|
285
|
-
str = "%.1f"%[ss]
|
286
|
-
else
|
287
|
-
str = "%.0f"%[ss]
|
288
|
-
end
|
289
|
-
"#{str}sec."
|
290
|
-
end
|
291
|
-
|
292
|
-
#
|
293
|
-
# format f number
|
294
|
-
#
|
295
|
-
def formatFNumber(f)
|
296
|
-
if (f.abs < 10.0)
|
297
|
-
str = "%.1f"%[f]
|
298
|
-
else
|
299
|
-
str = "%.0f"%[f]
|
300
|
-
end
|
301
|
-
"F#{str}"
|
302
|
-
end
|
303
|
-
|
304
|
-
#
|
305
|
-
# format Latitude and Longitude
|
306
|
-
#
|
307
|
-
def formatLatLon(f)
|
308
|
-
if f[2].to_f == 0.0
|
309
|
-
sprintf("%d deg %.2f'",f[0],f[1])
|
310
|
-
else
|
311
|
-
sprintf("%d deg %d' %.2f\"",f[0],f[1],f[2])
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
if not $DEBUG
|
316
|
-
|
317
|
-
def inspect
|
318
|
-
sprintf("#<%s ID=0x%04x, IFD=\"%s\" Name=\"%s\", Format=\"%s\", Count=\"%d\", Value=\"%s\">", self.class, @tagID, @IFD, self.name, self.format, self.count, self.value)
|
319
|
-
end
|
320
|
-
|
321
|
-
end
|
322
|
-
|
323
|
-
private
|
324
|
-
|
325
|
-
def partition_data(count)
|
326
|
-
i = 0
|
327
|
-
bytes = @data.size / count
|
328
|
-
while @data[i]
|
329
|
-
yield @data[i..i+bytes-1]
|
330
|
-
i = i + bytes
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
end
|
335
|
-
|
336
|
-
##
|
337
|
-
## the class for any unknown tags in
|
338
|
-
## IFD0, IFD1, GPSIFD, ExifIFD, InteroperabilityIFD
|
339
|
-
##
|
340
|
-
class Unknown < Base
|
341
|
-
end
|
342
|
-
|
343
|
-
|
344
|
-
##
|
345
|
-
## tags specific to Exif IFD.
|
346
|
-
## (see Exif standard 2.2 Section 4.6.3-A )
|
347
|
-
##
|
348
|
-
|
349
|
-
#
|
350
|
-
# 0x8769 - ExifIFDPointer
|
351
|
-
#
|
352
|
-
class ExifIFDPointer < Base
|
353
|
-
end
|
354
|
-
|
355
|
-
#
|
356
|
-
# 0x8825 - GPSIFDPointer
|
357
|
-
#
|
358
|
-
class GPSIFDPointer < Base
|
359
|
-
end
|
360
|
-
|
361
|
-
#
|
362
|
-
# 0xa005 - InteroperabilityIFDPointer
|
363
|
-
#
|
364
|
-
class InteroperabilityIFDPointer < Base
|
365
|
-
end
|
366
|
-
|
367
|
-
|
368
|
-
##
|
369
|
-
## tags related TIFF Rev. 6.0 Attribute Information.
|
370
|
-
## (see Exif standard 2.2 Section 4.6.4 Table 3)
|
371
|
-
##
|
372
|
-
|
373
|
-
module TIFF
|
374
|
-
|
375
|
-
#
|
376
|
-
# 0x0100 - ImageWidth
|
377
|
-
#
|
378
|
-
class ImageWidth < Base
|
379
|
-
end
|
380
|
-
|
381
|
-
#
|
382
|
-
# 0x0101 - ImageLength
|
383
|
-
#
|
384
|
-
class ImageLength < Base
|
385
|
-
end
|
386
|
-
|
387
|
-
#
|
388
|
-
# 0x0102 - BitsPerSample
|
389
|
-
#
|
390
|
-
class BitsPerSample < Base
|
391
|
-
|
392
|
-
def processData
|
393
|
-
@formatted = []
|
394
|
-
partition_data(@count) do |data|
|
395
|
-
@formatted.push _formatData(data)
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
def to_s
|
400
|
-
@formatted.join(",")
|
401
|
-
end
|
402
|
-
|
403
|
-
end
|
404
|
-
|
405
|
-
#
|
406
|
-
# 0x0103 - Compression
|
407
|
-
#
|
408
|
-
class Compression < Base
|
409
|
-
|
410
|
-
def to_s
|
411
|
-
case @formatted
|
412
|
-
when 1
|
413
|
-
'uncompressed'
|
414
|
-
when 6
|
415
|
-
'JPEG compression'
|
416
|
-
else
|
417
|
-
'Unknown'
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
end
|
422
|
-
|
423
|
-
#
|
424
|
-
# 0x0106 - PhotometricInterpretation
|
425
|
-
#
|
426
|
-
class PhotometricInterpretation < Base
|
427
|
-
|
428
|
-
def to_s
|
429
|
-
case @formatted
|
430
|
-
when 2
|
431
|
-
'RGB'
|
432
|
-
when 6
|
433
|
-
'YCbCr'
|
434
|
-
else
|
435
|
-
'Unknown'
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
end
|
440
|
-
|
441
|
-
#
|
442
|
-
# 0x0111 - StripOffsets
|
443
|
-
#
|
444
|
-
class StripOffsets < Base
|
445
|
-
end
|
446
|
-
|
447
|
-
#
|
448
|
-
# 0x0112 - Orientation
|
449
|
-
#
|
450
|
-
class Orientation < Base
|
451
|
-
end
|
452
|
-
|
453
|
-
#
|
454
|
-
# 0x0115 - SamplePerPixel
|
455
|
-
#
|
456
|
-
class SamplesPerPixel < Base
|
457
|
-
end
|
458
|
-
|
459
|
-
#
|
460
|
-
# 0x0116 - RowsPerStrip
|
461
|
-
#
|
462
|
-
class RowsPerStrip < Base
|
463
|
-
end
|
464
|
-
|
465
|
-
#
|
466
|
-
# 0x0117 - StripByteCounts
|
467
|
-
#
|
468
|
-
class StripByteCounts < Base
|
469
|
-
end
|
470
|
-
|
471
|
-
#
|
472
|
-
# 0x011a - XResolution
|
473
|
-
#
|
474
|
-
class XResolution < Base
|
475
|
-
end
|
476
|
-
|
477
|
-
#
|
478
|
-
# 0x011b - YResolution
|
479
|
-
#
|
480
|
-
class YResolution < Base
|
481
|
-
end
|
482
|
-
|
483
|
-
#
|
484
|
-
# 0x011c - PlanarConfiguration
|
485
|
-
#
|
486
|
-
class PlanarConfiguration < Base
|
487
|
-
|
488
|
-
def to_s
|
489
|
-
case @formatted
|
490
|
-
when 1
|
491
|
-
'chunky format'
|
492
|
-
when 2
|
493
|
-
'planar format'
|
494
|
-
else
|
495
|
-
'unknown'
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
|
-
end
|
500
|
-
|
501
|
-
#
|
502
|
-
# 0x0128 - ResolutionUnit
|
503
|
-
#
|
504
|
-
class ResolutionUnit < Base
|
505
|
-
|
506
|
-
def to_s
|
507
|
-
case @formatted
|
508
|
-
when 2
|
509
|
-
'inch'
|
510
|
-
when 3
|
511
|
-
'centimeter'
|
512
|
-
else
|
513
|
-
'unknown'
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|
517
|
-
end
|
518
|
-
|
519
|
-
#
|
520
|
-
# 0x0201 - JpegInterchangeFormat
|
521
|
-
#
|
522
|
-
class JpegInterchangeFormat < Base
|
523
|
-
end
|
524
|
-
|
525
|
-
#
|
526
|
-
# 0x0202 - JpegInterchangeFormatLength
|
527
|
-
#
|
528
|
-
class JpegInterchangeFormatLength < Base
|
529
|
-
end
|
530
|
-
|
531
|
-
#
|
532
|
-
# 0x0211 - YCbCrCoefficients
|
533
|
-
#
|
534
|
-
class YCbCrCoefficients < Base
|
535
|
-
|
536
|
-
def processData
|
537
|
-
@formatted = []
|
538
|
-
partition_data(@count) do |data|
|
539
|
-
@formatted.push _formatData(data)
|
540
|
-
end
|
541
|
-
end
|
542
|
-
|
543
|
-
def to_s
|
544
|
-
@formatted.join(",")
|
545
|
-
end
|
546
|
-
|
547
|
-
end
|
548
|
-
|
549
|
-
#
|
550
|
-
# 0x0212 - YCbCrSubSampling
|
551
|
-
#
|
552
|
-
class YCbCrSubSampling < Base
|
553
|
-
|
554
|
-
def processData
|
555
|
-
@formatted = []
|
556
|
-
partition_data(@count) do |data|
|
557
|
-
@formatted.push _formatData(data)
|
558
|
-
end
|
559
|
-
end
|
560
|
-
|
561
|
-
def to_s
|
562
|
-
case @formatted
|
563
|
-
when [2,1]
|
564
|
-
'YCbCr4:2:2'
|
565
|
-
when [2,2]
|
566
|
-
'YCbCr4:2:0'
|
567
|
-
else
|
568
|
-
'Unknown'
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
|
-
end
|
573
|
-
|
574
|
-
#
|
575
|
-
# 0x0213 - YCbCrPositioning
|
576
|
-
#
|
577
|
-
class YCbCrPositioning < Base
|
578
|
-
|
579
|
-
def to_s
|
580
|
-
case @formatted
|
581
|
-
when 1
|
582
|
-
'centered'
|
583
|
-
when 2
|
584
|
-
'co-sited'
|
585
|
-
else
|
586
|
-
'unknown'
|
587
|
-
end
|
588
|
-
end
|
589
|
-
|
590
|
-
end
|
591
|
-
|
592
|
-
#
|
593
|
-
# 0x0214 - ReferenceBlackWhite
|
594
|
-
#
|
595
|
-
class ReferenceBlackWhite < Base
|
596
|
-
end
|
597
|
-
|
598
|
-
#
|
599
|
-
# 0x010e - ImageDescription
|
600
|
-
#
|
601
|
-
class ImageDescription < Base
|
602
|
-
end
|
603
|
-
|
604
|
-
#
|
605
|
-
# 0x010f - Make
|
606
|
-
#
|
607
|
-
class Make < Base
|
608
|
-
end
|
609
|
-
|
610
|
-
#
|
611
|
-
# 0x0110 - Model
|
612
|
-
#
|
613
|
-
class Model < Base
|
614
|
-
end
|
615
|
-
|
616
|
-
#
|
617
|
-
# 0x0112 - Orientation
|
618
|
-
#
|
619
|
-
class Orientation < Base
|
620
|
-
|
621
|
-
def to_s
|
622
|
-
case @formatted
|
623
|
-
when 1
|
624
|
-
"top - left"
|
625
|
-
when 2
|
626
|
-
"top - right"
|
627
|
-
when 3
|
628
|
-
"bottom - right"
|
629
|
-
when 4
|
630
|
-
"bottom - left"
|
631
|
-
when 5
|
632
|
-
"left - top"
|
633
|
-
when 6
|
634
|
-
"right - top"
|
635
|
-
when 7
|
636
|
-
"right - bottom"
|
637
|
-
when 8
|
638
|
-
"left - bottom"
|
639
|
-
else
|
640
|
-
"unknown"
|
641
|
-
end
|
642
|
-
end
|
643
|
-
|
644
|
-
end
|
645
|
-
|
646
|
-
#
|
647
|
-
# 0x011a - XResolution
|
648
|
-
#
|
649
|
-
class XResolution < Base
|
650
|
-
end
|
651
|
-
|
652
|
-
#
|
653
|
-
# 0x011b - YResolution
|
654
|
-
#
|
655
|
-
class YResolution < Base
|
656
|
-
end
|
657
|
-
|
658
|
-
#
|
659
|
-
# 0x0128 - ResolutionUnit
|
660
|
-
#
|
661
|
-
class ResolutionUnit < Base
|
662
|
-
|
663
|
-
def to_s
|
664
|
-
case @formatted
|
665
|
-
when 1
|
666
|
-
"none"
|
667
|
-
when 2
|
668
|
-
"inch"
|
669
|
-
when 3
|
670
|
-
"centimeter"
|
671
|
-
else
|
672
|
-
"unknown"
|
673
|
-
end
|
674
|
-
end
|
675
|
-
|
676
|
-
end
|
677
|
-
|
678
|
-
#
|
679
|
-
# 0x012D - TransferFunction
|
680
|
-
#
|
681
|
-
class TransferFunction < Base
|
682
|
-
end
|
683
|
-
|
684
|
-
#
|
685
|
-
# 0x0131 - Software
|
686
|
-
#
|
687
|
-
class Software < Base
|
688
|
-
end
|
689
|
-
|
690
|
-
#
|
691
|
-
# 0x0132 - DateTime
|
692
|
-
#
|
693
|
-
class DateTime < Base
|
694
|
-
end
|
695
|
-
|
696
|
-
#
|
697
|
-
# 0x013B - Artist
|
698
|
-
#
|
699
|
-
class Artist < Base
|
700
|
-
end
|
701
|
-
|
702
|
-
#
|
703
|
-
# 0x013E - WhitePoint
|
704
|
-
#
|
705
|
-
class WhitePoint < Base
|
706
|
-
|
707
|
-
def processData
|
708
|
-
@formatted = []
|
709
|
-
partition_data(@count) do |data|
|
710
|
-
@formatted.push _formatData(data)
|
711
|
-
end
|
712
|
-
end
|
713
|
-
|
714
|
-
def to_s
|
715
|
-
@formatted.join(",")
|
716
|
-
end
|
717
|
-
|
718
|
-
end
|
719
|
-
|
720
|
-
#
|
721
|
-
# 0x013f - PrimaryChromaticities
|
722
|
-
#
|
723
|
-
class PrimaryChromaticities < Base
|
724
|
-
|
725
|
-
def processData
|
726
|
-
@formatted = []
|
727
|
-
partition_data(@count) do |data|
|
728
|
-
@formatted.push _formatData(data)
|
729
|
-
end
|
730
|
-
end
|
731
|
-
|
732
|
-
def to_s
|
733
|
-
@formatted.join(",")
|
734
|
-
end
|
735
|
-
|
736
|
-
end
|
737
|
-
|
738
|
-
#
|
739
|
-
# 0x0211 - YCbCrCoefficients
|
740
|
-
#
|
741
|
-
class YCbCrCoefficients < Base
|
742
|
-
|
743
|
-
def processData
|
744
|
-
@formatted = []
|
745
|
-
partition_data(@count) do |data|
|
746
|
-
@formatted.push _formatData(data)
|
747
|
-
end
|
748
|
-
end
|
749
|
-
|
750
|
-
def to_s
|
751
|
-
@formatted.join(",")
|
752
|
-
end
|
753
|
-
|
754
|
-
end
|
755
|
-
|
756
|
-
#
|
757
|
-
# 0x0213 - YCbCrPositioning
|
758
|
-
#
|
759
|
-
class YCbCrPositioning < Base
|
760
|
-
end
|
761
|
-
|
762
|
-
#
|
763
|
-
# 0x0214 - ReferenceBlackWhite
|
764
|
-
#
|
765
|
-
class ReferenceBlackWhite < Base
|
766
|
-
|
767
|
-
def processData
|
768
|
-
@formatted = []
|
769
|
-
partition_data(@count) do |data|
|
770
|
-
@formatted.push _formatData(data)
|
771
|
-
end
|
772
|
-
end
|
773
|
-
|
774
|
-
def to_s
|
775
|
-
@formatted.join(",")
|
776
|
-
end
|
777
|
-
|
778
|
-
end
|
779
|
-
|
780
|
-
#
|
781
|
-
# 0x8298 - Copyright
|
782
|
-
#
|
783
|
-
class Copyright < Base
|
784
|
-
|
785
|
-
def to_s
|
786
|
-
sep = @data.split("\0")
|
787
|
-
photographer = sep[0]
|
788
|
-
editor = sep[1]
|
789
|
-
"#{photographer} (Photographer) - #{editor} (Editor)"
|
790
|
-
end
|
791
|
-
|
792
|
-
end
|
793
|
-
|
794
|
-
end
|
795
|
-
|
796
|
-
##
|
797
|
-
## Exif IFD tags
|
798
|
-
##
|
799
|
-
|
800
|
-
module Exif
|
801
|
-
|
802
|
-
#
|
803
|
-
# 0x829a - ExposureTime
|
804
|
-
#
|
805
|
-
class ExposureTime < Base
|
806
|
-
|
807
|
-
def to_s
|
808
|
-
formatExposureTime(@formatted.to_f)
|
809
|
-
end
|
810
|
-
|
811
|
-
end
|
812
|
-
|
813
|
-
#
|
814
|
-
# 0x829d - FNumber
|
815
|
-
#
|
816
|
-
class FNumber < Base
|
817
|
-
|
818
|
-
def to_s
|
819
|
-
formatFNumber(@formatted.to_f)
|
820
|
-
end
|
821
|
-
|
822
|
-
end
|
823
|
-
|
824
|
-
#
|
825
|
-
# 0x8822 - ExposureProgram
|
826
|
-
#
|
827
|
-
class ExposureProgram < Base
|
828
|
-
|
829
|
-
def to_s
|
830
|
-
case @formatted
|
831
|
-
when 0
|
832
|
-
"Not defined"
|
833
|
-
when 1
|
834
|
-
"Manual"
|
835
|
-
when 2
|
836
|
-
"Normal program"
|
837
|
-
when 3
|
838
|
-
"Aperture priority"
|
839
|
-
when 4
|
840
|
-
"Shutter priority"
|
841
|
-
when 5
|
842
|
-
"Creative program (biased toward depth of field)"
|
843
|
-
when 6
|
844
|
-
"Action program (biased toward fast shutter speed)"
|
845
|
-
when 7
|
846
|
-
"Portrait mode (for closeup photos with the background out of focus)"
|
847
|
-
when 8
|
848
|
-
"Landscape mode (for landscape photos with the background in focus)"
|
849
|
-
else
|
850
|
-
"Unknown"
|
851
|
-
end
|
852
|
-
end
|
853
|
-
|
854
|
-
end
|
855
|
-
|
856
|
-
#
|
857
|
-
# 0x8824 - SpectralSensitivity
|
858
|
-
#
|
859
|
-
class SpectralSensitivity < Base
|
860
|
-
end
|
861
|
-
|
862
|
-
#
|
863
|
-
# 0x8828 - OECF
|
864
|
-
#
|
865
|
-
class OECF < Base
|
866
|
-
end
|
867
|
-
|
868
|
-
#
|
869
|
-
# 0x8827 - ISOSpeedRatings
|
870
|
-
#
|
871
|
-
class ISOSpeedRatings < Base
|
872
|
-
end
|
873
|
-
|
874
|
-
#
|
875
|
-
# 0x9000 - ExifVersion
|
876
|
-
#
|
877
|
-
class ExifVersion < Base
|
878
|
-
|
879
|
-
def _format0(data)
|
880
|
-
data
|
881
|
-
end
|
882
|
-
|
883
|
-
def to_s
|
884
|
-
case @formatted
|
885
|
-
when "0200"
|
886
|
-
"Exif Version 2.0"
|
887
|
-
when "0210"
|
888
|
-
"Exif Version 2.1"
|
889
|
-
when "0220"
|
890
|
-
"Exif Version 2.2"
|
891
|
-
when "0221"
|
892
|
-
"Exif Version 2.21"
|
893
|
-
else
|
894
|
-
"Unknown Exif Version"
|
895
|
-
end
|
896
|
-
end
|
897
|
-
|
898
|
-
end
|
899
|
-
|
900
|
-
#
|
901
|
-
# 0x9003 - DateTimeOriginal
|
902
|
-
#
|
903
|
-
class DateTimeOriginal < Base
|
904
|
-
end
|
905
|
-
|
906
|
-
#
|
907
|
-
# 0x9004 - DateTimeDigitized
|
908
|
-
#
|
909
|
-
class DateTimeDigitized < Base
|
910
|
-
end
|
911
|
-
|
912
|
-
#
|
913
|
-
# 0x9101 - ComponentsConfiguration
|
914
|
-
#
|
915
|
-
class ComponentsConfiguration < Base
|
916
|
-
|
917
|
-
def _format0(data)
|
918
|
-
data.unpack("C*").collect{|e| e.to_i}
|
919
|
-
end
|
920
|
-
|
921
|
-
def to_s
|
922
|
-
case @formatted
|
923
|
-
when [0x04,0x05,0x06,0x00]
|
924
|
-
'RGB'
|
925
|
-
when [0x01,0x02,0x03,0x00]
|
926
|
-
'YCbCr'
|
927
|
-
end
|
928
|
-
end
|
929
|
-
|
930
|
-
end
|
931
|
-
|
932
|
-
#
|
933
|
-
# 0x9102 - CompressedBitsPerPixel
|
934
|
-
#
|
935
|
-
class CompressedBitsPerPixel < Base
|
936
|
-
|
937
|
-
def to_s
|
938
|
-
"%.1fbits/pixel"%[@formatted.to_f]
|
939
|
-
end
|
940
|
-
|
941
|
-
end
|
942
|
-
|
943
|
-
#
|
944
|
-
# 0x9201 - ShutterSpeedValue
|
945
|
-
#
|
946
|
-
class ShutterSpeedValue < Base
|
947
|
-
|
948
|
-
def to_s
|
949
|
-
formatExposureTime(1.0/(2.0**(@formatted.to_f)))
|
950
|
-
end
|
951
|
-
|
952
|
-
end
|
953
|
-
|
954
|
-
#
|
955
|
-
# 0x9202 - ApertureValue
|
956
|
-
#
|
957
|
-
class ApertureValue < Base
|
958
|
-
|
959
|
-
def to_s
|
960
|
-
formatFNumber(Math.sqrt(2.0)**(@formatted.to_f))
|
961
|
-
end
|
962
|
-
|
963
|
-
end
|
964
|
-
|
965
|
-
#
|
966
|
-
# 0x9203 - BrightnessValue
|
967
|
-
#
|
968
|
-
class BrightnessValue < Base
|
969
|
-
|
970
|
-
def to_s
|
971
|
-
"%+.1f"%[@formatted.to_f]
|
972
|
-
end
|
973
|
-
|
974
|
-
end
|
975
|
-
|
976
|
-
#
|
977
|
-
# 0x9204 - ExposureBiasValue
|
978
|
-
#
|
979
|
-
class ExposureBiasValue < Base
|
980
|
-
|
981
|
-
def to_s
|
982
|
-
"%+.1f"%[@formatted.to_f]
|
983
|
-
end
|
984
|
-
|
985
|
-
end
|
986
|
-
|
987
|
-
#
|
988
|
-
# 0x9205 - MaxApertureValue
|
989
|
-
#
|
990
|
-
class MaxApertureValue < Base
|
991
|
-
|
992
|
-
def to_s
|
993
|
-
"F%.01f"%[Math.sqrt(2.0)**(@formatted.to_f)]
|
994
|
-
end
|
995
|
-
|
996
|
-
end
|
997
|
-
|
998
|
-
#
|
999
|
-
# 0x9206 - SubjectDistance
|
1000
|
-
#
|
1001
|
-
class SubjectDistance < Base
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
#
|
1005
|
-
# 0x9207 - MeteringMode
|
1006
|
-
#
|
1007
|
-
class MeteringMode < Base
|
1008
|
-
|
1009
|
-
def to_s
|
1010
|
-
case @formatted
|
1011
|
-
when 1
|
1012
|
-
'Average'
|
1013
|
-
when 2
|
1014
|
-
'CenterWeightedAverage'
|
1015
|
-
when 3
|
1016
|
-
'Spot'
|
1017
|
-
when 4
|
1018
|
-
'MultiSpot'
|
1019
|
-
when 5
|
1020
|
-
'Pattern'
|
1021
|
-
when 6
|
1022
|
-
'Partial'
|
1023
|
-
when 255
|
1024
|
-
'other'
|
1025
|
-
else
|
1026
|
-
'Unknown'
|
1027
|
-
end
|
1028
|
-
end
|
1029
|
-
|
1030
|
-
end
|
1031
|
-
|
1032
|
-
#
|
1033
|
-
# 0x9208 - LightSource
|
1034
|
-
#
|
1035
|
-
class LightSource < Base
|
1036
|
-
|
1037
|
-
def to_s
|
1038
|
-
case @formatted
|
1039
|
-
when 0
|
1040
|
-
'Unknown'
|
1041
|
-
when 1
|
1042
|
-
'Daylight'
|
1043
|
-
when 2
|
1044
|
-
'Fluorescent'
|
1045
|
-
when 3
|
1046
|
-
'Tungsten'
|
1047
|
-
when 4
|
1048
|
-
'Flash'
|
1049
|
-
when 9
|
1050
|
-
'Fine weather'
|
1051
|
-
when 10
|
1052
|
-
'Croudy weather'
|
1053
|
-
when 11
|
1054
|
-
'Shade'
|
1055
|
-
when 12
|
1056
|
-
'Daylight fluorescent'
|
1057
|
-
when 13
|
1058
|
-
'Day white fluorescent'
|
1059
|
-
when 14
|
1060
|
-
'Cool white fluorescent'
|
1061
|
-
when 15
|
1062
|
-
'White fluorescent'
|
1063
|
-
when 17
|
1064
|
-
'Standard light A'
|
1065
|
-
when 18
|
1066
|
-
'Standard light B'
|
1067
|
-
when 19
|
1068
|
-
'Standard light C'
|
1069
|
-
when 20
|
1070
|
-
'D55'
|
1071
|
-
when 21
|
1072
|
-
'D65'
|
1073
|
-
when 22
|
1074
|
-
'D75'
|
1075
|
-
when 23
|
1076
|
-
'D50'
|
1077
|
-
when 24
|
1078
|
-
'ISO studio tungsten'
|
1079
|
-
when 255
|
1080
|
-
'other light source'
|
1081
|
-
else
|
1082
|
-
'reserved'
|
1083
|
-
end
|
1084
|
-
end
|
1085
|
-
|
1086
|
-
end
|
1087
|
-
|
1088
|
-
#
|
1089
|
-
# 0x9209 - Flash
|
1090
|
-
#
|
1091
|
-
class Flash < Base
|
1092
|
-
|
1093
|
-
def to_s
|
1094
|
-
case @formatted
|
1095
|
-
when 0x0000
|
1096
|
-
'Flash did not fire.'
|
1097
|
-
when 0x0001
|
1098
|
-
'Flash fired.'
|
1099
|
-
when 0x0005
|
1100
|
-
'Strobe return light not detected.'
|
1101
|
-
when 0x0007
|
1102
|
-
'Strobe return light detected.'
|
1103
|
-
when 0x0009
|
1104
|
-
'Flash fired, compulsory flash mode.'
|
1105
|
-
when 0x000d
|
1106
|
-
'Flash fired, compulsory flash mode, return light not detected.'
|
1107
|
-
when 0x000f
|
1108
|
-
'Flash fired, compulsory flash mode, return light detected.'
|
1109
|
-
when 0x0010
|
1110
|
-
'Flash did not fire, compulsory flash mode.'
|
1111
|
-
when 0x0018
|
1112
|
-
'Flash did not fire, auto mode.'
|
1113
|
-
when 0x0019
|
1114
|
-
'Flash fired, auto mode.'
|
1115
|
-
when 0x001d
|
1116
|
-
'Flash fired, auto mode, return light not detected.'
|
1117
|
-
when 0x001f
|
1118
|
-
'Flash fired, auto mode, return light detected.'
|
1119
|
-
when 0x0020
|
1120
|
-
'No flash function.'
|
1121
|
-
when 0x0041
|
1122
|
-
'Flash fired, red-eye reduction mode.'
|
1123
|
-
when 0x0045
|
1124
|
-
'Flash fired, red-eye reduction mode, return light not detected.'
|
1125
|
-
when 0x0047
|
1126
|
-
'Flash fired, red-eye reduction mode, return light detected.'
|
1127
|
-
when 0x0049
|
1128
|
-
'Flash fired, compulsory flash mode.'
|
1129
|
-
when 0x004d
|
1130
|
-
'Flash fired, compulsory flash mode, return light not detected.'
|
1131
|
-
when 0x004f
|
1132
|
-
'Flash fired, compulsory flash mode, return light detected.'
|
1133
|
-
when 0x0059
|
1134
|
-
'Flash fired, auto mode, red-eye reduction mode.'
|
1135
|
-
when 0x005d
|
1136
|
-
'Flash fired, auto mode, return light not detected, red-eye reduction mode.'
|
1137
|
-
when 0x005f
|
1138
|
-
'Flash fired, auto mode, return light detected, red-eye reduction mode.'
|
1139
|
-
else
|
1140
|
-
"reserved"
|
1141
|
-
end
|
1142
|
-
end
|
1143
|
-
|
1144
|
-
end
|
1145
|
-
|
1146
|
-
#
|
1147
|
-
# 0x920a - FocalLength
|
1148
|
-
#
|
1149
|
-
class FocalLength < Base
|
1150
|
-
|
1151
|
-
def to_s
|
1152
|
-
formatFocalLength(@formatted.to_f)
|
1153
|
-
end
|
1154
|
-
|
1155
|
-
end
|
1156
|
-
|
1157
|
-
#
|
1158
|
-
# 0x9214 - SubjectArea
|
1159
|
-
#
|
1160
|
-
class SubjectArea < Base
|
1161
|
-
|
1162
|
-
def processData
|
1163
|
-
@formatted = []
|
1164
|
-
partition_data(@count) do |data|
|
1165
|
-
@formatted.push _formatData(data)
|
1166
|
-
end
|
1167
|
-
end
|
1168
|
-
|
1169
|
-
def to_s
|
1170
|
-
case @count
|
1171
|
-
when 2
|
1172
|
-
"Coordinate - [%d, %d]"%[*@formatted]
|
1173
|
-
when 3
|
1174
|
-
"Circle - Center: [%d, %d], Diameter: %d"%[*@formatted]
|
1175
|
-
when 4
|
1176
|
-
"Rectanglar - Center: [%d, %d], Width: %d, Height: %d"%[*@formatted]
|
1177
|
-
else
|
1178
|
-
'Unknown'
|
1179
|
-
end
|
1180
|
-
end
|
1181
|
-
|
1182
|
-
end
|
1183
|
-
|
1184
|
-
#
|
1185
|
-
# 0x927c - MakerNote
|
1186
|
-
#
|
1187
|
-
class MakerNote < Base
|
1188
|
-
|
1189
|
-
def data
|
1190
|
-
@data
|
1191
|
-
end
|
1192
|
-
|
1193
|
-
def _format0(data)
|
1194
|
-
@data
|
1195
|
-
end
|
1196
|
-
|
1197
|
-
def to_s
|
1198
|
-
sprintf("MakerNote data (%i bytes)", data.size)
|
1199
|
-
end
|
1200
|
-
|
1201
|
-
end
|
1202
|
-
|
1203
|
-
#
|
1204
|
-
# 0x9286 - UserComment
|
1205
|
-
#
|
1206
|
-
class UserComment < Base
|
1207
|
-
|
1208
|
-
def to_s
|
1209
|
-
case @data[0..7]
|
1210
|
-
# ASCII
|
1211
|
-
when [0x41,0x53,0x43,0x49,0x49,0x0,0x0,0x0]
|
1212
|
-
@data[8..-1].pack("C*")
|
1213
|
-
# JIS
|
1214
|
-
when [0x4a,0x59,0x53,0x0,0x0,0x0,0x0,0x0]
|
1215
|
-
@data[8..-1].pack("C*")
|
1216
|
-
# Unicode
|
1217
|
-
when [0x55,0x4e,0x49,0x43,0x4f,0x44,0x45,0x0]
|
1218
|
-
@data[8..-1].pack("U*")
|
1219
|
-
when [0x0]*8
|
1220
|
-
@data[8..-1].pack("C*")
|
1221
|
-
else
|
1222
|
-
"unknown"
|
1223
|
-
end
|
1224
|
-
end
|
1225
|
-
|
1226
|
-
end
|
1227
|
-
|
1228
|
-
#
|
1229
|
-
# 0x9290 - SubsecTime < Base
|
1230
|
-
#
|
1231
|
-
class SubsecTime < Base
|
1232
|
-
end
|
1233
|
-
|
1234
|
-
#
|
1235
|
-
# 0x9291 - SubsecTimeOriginal < Base
|
1236
|
-
#
|
1237
|
-
class SubsecTimeOriginal < Base
|
1238
|
-
end
|
1239
|
-
|
1240
|
-
#
|
1241
|
-
# 0x9292 - SubsecTimeDigitized < Base
|
1242
|
-
#
|
1243
|
-
class SubsecTimeDigitized < Base
|
1244
|
-
end
|
1245
|
-
|
1246
|
-
#
|
1247
|
-
# 0xa000 - FlashPixVersion
|
1248
|
-
#
|
1249
|
-
class FlashPixVersion < Base
|
1250
|
-
def _format0(data)
|
1251
|
-
data
|
1252
|
-
end
|
1253
|
-
|
1254
|
-
def to_s
|
1255
|
-
case @formatted
|
1256
|
-
when "0100"
|
1257
|
-
"FlashPix Version 1.0"
|
1258
|
-
else
|
1259
|
-
"Unknown FlashPix Version"
|
1260
|
-
end
|
1261
|
-
end
|
1262
|
-
|
1263
|
-
end
|
1264
|
-
|
1265
|
-
#
|
1266
|
-
# 0xa001 - ColorSpace
|
1267
|
-
#
|
1268
|
-
class ColorSpace < Base
|
1269
|
-
|
1270
|
-
def to_s
|
1271
|
-
case @formatted
|
1272
|
-
when 1
|
1273
|
-
'sRGB'
|
1274
|
-
when 65535
|
1275
|
-
'Uncalibrated'
|
1276
|
-
else
|
1277
|
-
'Unknown: #{@formatted}'
|
1278
|
-
end
|
1279
|
-
end
|
1280
|
-
|
1281
|
-
end
|
1282
|
-
|
1283
|
-
#
|
1284
|
-
# 0xa002 - PixelXDimension
|
1285
|
-
#
|
1286
|
-
class PixelXDimension < Base
|
1287
|
-
|
1288
|
-
def processData
|
1289
|
-
case self.byte_order
|
1290
|
-
when :intel
|
1291
|
-
@formatted = decode_ushort(@data[0,2])
|
1292
|
-
when :motorola
|
1293
|
-
@formatted = decode_ushort(@data[2,2])
|
1294
|
-
end
|
1295
|
-
end
|
1296
|
-
|
1297
|
-
end
|
1298
|
-
|
1299
|
-
#
|
1300
|
-
# 0xa003 - PixelYDimension
|
1301
|
-
#
|
1302
|
-
class PixelYDimension < Base
|
1303
|
-
|
1304
|
-
def processData
|
1305
|
-
case self.byte_order
|
1306
|
-
when :intel
|
1307
|
-
@formatted = decode_ushort(@data[0,2])
|
1308
|
-
when :motorola
|
1309
|
-
@formatted = decode_ushort(@data[2,2])
|
1310
|
-
end
|
1311
|
-
end
|
1312
|
-
|
1313
|
-
end
|
1314
|
-
|
1315
|
-
#
|
1316
|
-
# 0xa004 - RelatedSoundFile
|
1317
|
-
#
|
1318
|
-
class RelatedSoundFile < Base
|
1319
|
-
end
|
1320
|
-
|
1321
|
-
#
|
1322
|
-
# 0xa20b - FlashEnergy
|
1323
|
-
#
|
1324
|
-
class FlashEnergy < Base
|
1325
|
-
end
|
1326
|
-
|
1327
|
-
#
|
1328
|
-
# 0xa20c - SpatialFrequencyResponse
|
1329
|
-
#
|
1330
|
-
class SpatialFrequencyResponse < Base
|
1331
|
-
end
|
1332
|
-
|
1333
|
-
#
|
1334
|
-
# 0xa20e - FocalPlaneXResolution
|
1335
|
-
#
|
1336
|
-
class FocalPlaneXResolution < Base
|
1337
|
-
end
|
1338
|
-
|
1339
|
-
#
|
1340
|
-
# 0xa20f - FocalPlaneYResolution
|
1341
|
-
#
|
1342
|
-
class FocalPlaneYResolution < Base
|
1343
|
-
end
|
1344
|
-
|
1345
|
-
#
|
1346
|
-
# 0xa210 - FocalPlaneResolutionUnit
|
1347
|
-
#
|
1348
|
-
class FocalPlaneResolutionUnit < Base
|
1349
|
-
|
1350
|
-
def to_s
|
1351
|
-
case @formatted
|
1352
|
-
when 1
|
1353
|
-
'No unit'
|
1354
|
-
when 2
|
1355
|
-
'Inch'
|
1356
|
-
when 3
|
1357
|
-
'Centimeter'
|
1358
|
-
else
|
1359
|
-
'Unknown'
|
1360
|
-
end
|
1361
|
-
end
|
1362
|
-
|
1363
|
-
end
|
1364
|
-
|
1365
|
-
#
|
1366
|
-
# 0xa214 - SubjectLocation
|
1367
|
-
#
|
1368
|
-
class SubjectLocation < Base
|
1369
|
-
|
1370
|
-
def processData
|
1371
|
-
@formatted = []
|
1372
|
-
partition_data(@count) do |data|
|
1373
|
-
@formatted.push _formatData(data)
|
1374
|
-
end
|
1375
|
-
end
|
1376
|
-
|
1377
|
-
def to_s
|
1378
|
-
"[%d, %d]"%[*@formatted]
|
1379
|
-
end
|
1380
|
-
|
1381
|
-
end
|
1382
|
-
|
1383
|
-
#
|
1384
|
-
# 0xa215 - ExposureIndex
|
1385
|
-
#
|
1386
|
-
class ExposureIndex < Base
|
1387
|
-
end
|
1388
|
-
|
1389
|
-
#
|
1390
|
-
# 0xa217 - SensingMethod
|
1391
|
-
#
|
1392
|
-
class SensingMethod < Base
|
1393
|
-
|
1394
|
-
def to_s
|
1395
|
-
case @formatted
|
1396
|
-
when 2
|
1397
|
-
'One-chip color area sensor'
|
1398
|
-
else
|
1399
|
-
'Unknown'
|
1400
|
-
end
|
1401
|
-
end
|
1402
|
-
|
1403
|
-
end
|
1404
|
-
|
1405
|
-
#
|
1406
|
-
# 0xa300 - FileSource
|
1407
|
-
#
|
1408
|
-
class FileSource < Base
|
1409
|
-
def _format0(data)
|
1410
|
-
data[0]
|
1411
|
-
end
|
1412
|
-
|
1413
|
-
def to_s
|
1414
|
-
case @formatted
|
1415
|
-
when 0x03
|
1416
|
-
'Digital still camera'
|
1417
|
-
else
|
1418
|
-
'Unknown'
|
1419
|
-
end
|
1420
|
-
end
|
1421
|
-
|
1422
|
-
end
|
1423
|
-
|
1424
|
-
#
|
1425
|
-
# 0xa301 - SceneType
|
1426
|
-
#
|
1427
|
-
class SceneType < Base
|
1428
|
-
|
1429
|
-
def _format0(data)
|
1430
|
-
data[0]
|
1431
|
-
end
|
1432
|
-
|
1433
|
-
def to_s
|
1434
|
-
case @formatted
|
1435
|
-
when 0x01
|
1436
|
-
'Directory photographed'
|
1437
|
-
else
|
1438
|
-
'Unknown'
|
1439
|
-
end
|
1440
|
-
end
|
1441
|
-
|
1442
|
-
end
|
1443
|
-
|
1444
|
-
#
|
1445
|
-
# 0xa302 - CFAPattern
|
1446
|
-
#
|
1447
|
-
class CFAPattern < Base
|
1448
|
-
end
|
1449
|
-
|
1450
|
-
#
|
1451
|
-
# 0xa401 - CustomRendered
|
1452
|
-
#
|
1453
|
-
class CustomRendered < Base
|
1454
|
-
def to_s
|
1455
|
-
case @formatted
|
1456
|
-
when 0
|
1457
|
-
'Normal process'
|
1458
|
-
when 1
|
1459
|
-
'Custom process'
|
1460
|
-
else
|
1461
|
-
'reserved'
|
1462
|
-
end
|
1463
|
-
end
|
1464
|
-
end
|
1465
|
-
|
1466
|
-
#
|
1467
|
-
# 0xa402 - ExposureMode
|
1468
|
-
#
|
1469
|
-
class ExposureMode < Base
|
1470
|
-
def to_s
|
1471
|
-
case @formatted
|
1472
|
-
when 0
|
1473
|
-
'Auto exposure'
|
1474
|
-
when 1
|
1475
|
-
'Manual exposure'
|
1476
|
-
when 2
|
1477
|
-
'Auto bracket'
|
1478
|
-
else
|
1479
|
-
'reserved'
|
1480
|
-
end
|
1481
|
-
end
|
1482
|
-
end
|
1483
|
-
|
1484
|
-
#
|
1485
|
-
# 0xa403 - WhiteBalance
|
1486
|
-
#
|
1487
|
-
class WhiteBalance < Base
|
1488
|
-
def to_s
|
1489
|
-
case @formatted
|
1490
|
-
when 0
|
1491
|
-
'Auto white balance'
|
1492
|
-
when 1
|
1493
|
-
'Manual white balance'
|
1494
|
-
else
|
1495
|
-
'reserved'
|
1496
|
-
end
|
1497
|
-
end
|
1498
|
-
end
|
1499
|
-
|
1500
|
-
#
|
1501
|
-
# 0xa404 - DigitalZoomRatio
|
1502
|
-
#
|
1503
|
-
class DigitalZoomRatio < Base
|
1504
|
-
def to_s
|
1505
|
-
n = @formatted.numerator
|
1506
|
-
d = @formatted.denominator
|
1507
|
-
n == 0 ? 'None' : "%.1f"%[n.to_f/d.to_f]
|
1508
|
-
end
|
1509
|
-
end
|
1510
|
-
|
1511
|
-
#
|
1512
|
-
# 0xa405 - FocalLengthIn35mmFilm
|
1513
|
-
#
|
1514
|
-
class FocalLengthIn35mmFilm < Base
|
1515
|
-
def to_s
|
1516
|
-
@formatted == 0 ? 'Unknown' : formatFocalLength(@formatted)
|
1517
|
-
end
|
1518
|
-
end
|
1519
|
-
|
1520
|
-
#
|
1521
|
-
# 0xa406 - SceneCaptureType
|
1522
|
-
#
|
1523
|
-
class SceneCaptureType < Base
|
1524
|
-
def to_s
|
1525
|
-
case @formatted
|
1526
|
-
when 0
|
1527
|
-
'Standard'
|
1528
|
-
when 1
|
1529
|
-
'Landscape'
|
1530
|
-
when 2
|
1531
|
-
'Portrait'
|
1532
|
-
when 3
|
1533
|
-
'Nigit scene'
|
1534
|
-
else
|
1535
|
-
'reserved'
|
1536
|
-
end
|
1537
|
-
end
|
1538
|
-
end
|
1539
|
-
|
1540
|
-
#
|
1541
|
-
# 0xa407 - GaincControl
|
1542
|
-
#
|
1543
|
-
class GainControl < Base
|
1544
|
-
def to_s
|
1545
|
-
case @formatted
|
1546
|
-
when 0
|
1547
|
-
'None'
|
1548
|
-
when 1
|
1549
|
-
'Low gain up'
|
1550
|
-
when 2
|
1551
|
-
'High gain up'
|
1552
|
-
when 3
|
1553
|
-
'Low gain down'
|
1554
|
-
when 4
|
1555
|
-
'High gain down'
|
1556
|
-
else
|
1557
|
-
'reserved'
|
1558
|
-
end
|
1559
|
-
end
|
1560
|
-
end
|
1561
|
-
|
1562
|
-
#
|
1563
|
-
# 0xa408 - Contrast
|
1564
|
-
#
|
1565
|
-
class Contrast < Base
|
1566
|
-
def to_s
|
1567
|
-
case @formatted
|
1568
|
-
when 0
|
1569
|
-
'Normal'
|
1570
|
-
when 1
|
1571
|
-
'Soft'
|
1572
|
-
when 2
|
1573
|
-
'Hard'
|
1574
|
-
else
|
1575
|
-
'reserved'
|
1576
|
-
end
|
1577
|
-
end
|
1578
|
-
end
|
1579
|
-
|
1580
|
-
#
|
1581
|
-
# 0xa409 - Saturation
|
1582
|
-
#
|
1583
|
-
class Saturation < Base
|
1584
|
-
def to_s
|
1585
|
-
case @formatted
|
1586
|
-
when 0
|
1587
|
-
'Normal'
|
1588
|
-
when 1
|
1589
|
-
'Low saturation'
|
1590
|
-
when 2
|
1591
|
-
'High saturation'
|
1592
|
-
else
|
1593
|
-
'reserved'
|
1594
|
-
end
|
1595
|
-
end
|
1596
|
-
end
|
1597
|
-
|
1598
|
-
#
|
1599
|
-
# 0xa40a - Sharpness
|
1600
|
-
#
|
1601
|
-
class Sharpness < Base
|
1602
|
-
def to_s
|
1603
|
-
case @formatted
|
1604
|
-
when 0
|
1605
|
-
'Normal'
|
1606
|
-
when 1
|
1607
|
-
'Soft'
|
1608
|
-
when 2
|
1609
|
-
'Hard'
|
1610
|
-
else
|
1611
|
-
'reserved'
|
1612
|
-
end
|
1613
|
-
end
|
1614
|
-
end
|
1615
|
-
|
1616
|
-
#
|
1617
|
-
# 0xa40b - DeviceSettingDescription
|
1618
|
-
#
|
1619
|
-
class DeviceSettingDescription < Base
|
1620
|
-
end
|
1621
|
-
|
1622
|
-
#
|
1623
|
-
# 0xa40c - SubjectDistanceRange
|
1624
|
-
#
|
1625
|
-
class SubjectDistanceRange < Base
|
1626
|
-
def to_s
|
1627
|
-
case @formatted
|
1628
|
-
when 0
|
1629
|
-
'Unknown'
|
1630
|
-
when 1
|
1631
|
-
'Macro'
|
1632
|
-
when 2
|
1633
|
-
'Close view'
|
1634
|
-
when 3
|
1635
|
-
'Distant view'
|
1636
|
-
else
|
1637
|
-
'reserved'
|
1638
|
-
end
|
1639
|
-
end
|
1640
|
-
end
|
1641
|
-
|
1642
|
-
#
|
1643
|
-
# 0xa420 - ImageUniqueID
|
1644
|
-
#
|
1645
|
-
class ImageUniqueID < Base
|
1646
|
-
end
|
1647
|
-
|
1648
|
-
end
|
1649
|
-
|
1650
|
-
##
|
1651
|
-
## GPS IFD tags
|
1652
|
-
##
|
1653
|
-
|
1654
|
-
module GPS
|
1655
|
-
|
1656
|
-
#
|
1657
|
-
# 0x0000 - GPSVersionID
|
1658
|
-
#
|
1659
|
-
# type : byte
|
1660
|
-
# count: 4
|
1661
|
-
#
|
1662
|
-
class GPSVersionID < Base
|
1663
|
-
|
1664
|
-
def to_s
|
1665
|
-
case @formatted
|
1666
|
-
when [2,2,0,0]
|
1667
|
-
"Version 2.2"
|
1668
|
-
else
|
1669
|
-
"Unknown"
|
1670
|
-
end
|
1671
|
-
end
|
1672
|
-
|
1673
|
-
end
|
1674
|
-
|
1675
|
-
#
|
1676
|
-
# 0x0001 - GPSLatitudeRef
|
1677
|
-
#
|
1678
|
-
class GPSLatitudeRef < Base
|
1679
|
-
|
1680
|
-
def to_s
|
1681
|
-
case @formatted
|
1682
|
-
when 'N'
|
1683
|
-
'North latitude'
|
1684
|
-
when 'S'
|
1685
|
-
'South latitude'
|
1686
|
-
else
|
1687
|
-
'Unknown'
|
1688
|
-
end
|
1689
|
-
end
|
1690
|
-
|
1691
|
-
end
|
1692
|
-
|
1693
|
-
#
|
1694
|
-
# 0x0002 - GPSLatitude
|
1695
|
-
#
|
1696
|
-
class GPSLatitude < Base
|
1697
|
-
|
1698
|
-
def processData
|
1699
|
-
@formatted = []
|
1700
|
-
partition_data(@count) do |data|
|
1701
|
-
@formatted.push _formatData(data)
|
1702
|
-
end
|
1703
|
-
end
|
1704
|
-
|
1705
|
-
def to_s
|
1706
|
-
formatLatLon @formatted
|
1707
|
-
end
|
1708
|
-
|
1709
|
-
end
|
1710
|
-
|
1711
|
-
#
|
1712
|
-
# 0x0003 - GPSLongitudeRef
|
1713
|
-
#
|
1714
|
-
class GPSLongitudeRef < Base
|
1715
|
-
|
1716
|
-
def to_s
|
1717
|
-
case @formatted
|
1718
|
-
when 'E'
|
1719
|
-
'East longitude'
|
1720
|
-
when 'W'
|
1721
|
-
'West longitude'
|
1722
|
-
else
|
1723
|
-
'Unknown'
|
1724
|
-
end
|
1725
|
-
end
|
1726
|
-
|
1727
|
-
end
|
1728
|
-
|
1729
|
-
#
|
1730
|
-
# 0x0004 - GPSLongitude
|
1731
|
-
#
|
1732
|
-
class GPSLongitude < Base
|
1733
|
-
|
1734
|
-
def processData
|
1735
|
-
@formatted = []
|
1736
|
-
partition_data(@count) do |data|
|
1737
|
-
@formatted.push _formatData(data)
|
1738
|
-
end
|
1739
|
-
end
|
1740
|
-
|
1741
|
-
def to_s
|
1742
|
-
formatLatLon @formatted
|
1743
|
-
end
|
1744
|
-
|
1745
|
-
end
|
1746
|
-
|
1747
|
-
#
|
1748
|
-
# 0x0005 - GPSAltitudeRef
|
1749
|
-
#
|
1750
|
-
class GPSAltitudeRef < Base
|
1751
|
-
|
1752
|
-
def to_s
|
1753
|
-
case @formatted[0]
|
1754
|
-
when 0
|
1755
|
-
'Sea level'
|
1756
|
-
when 1
|
1757
|
-
'Sea level(negative value)'
|
1758
|
-
else
|
1759
|
-
'Unknown'
|
1760
|
-
end
|
1761
|
-
end
|
1762
|
-
|
1763
|
-
end
|
1764
|
-
|
1765
|
-
#
|
1766
|
-
# 0x0006 - GPSAltitude
|
1767
|
-
#
|
1768
|
-
class GPSAltitude < Base
|
1769
|
-
end
|
1770
|
-
|
1771
|
-
#
|
1772
|
-
# 0x0007 - GPSTimeStamp
|
1773
|
-
#
|
1774
|
-
class GPSTimeStamp < Base
|
1775
|
-
|
1776
|
-
def processData
|
1777
|
-
@formatted = []
|
1778
|
-
partition_data(@count) do |data|
|
1779
|
-
@formatted.push _formatData(data)
|
1780
|
-
end
|
1781
|
-
end
|
1782
|
-
|
1783
|
-
def to_s
|
1784
|
-
@formatted.join(",")
|
1785
|
-
end
|
1786
|
-
|
1787
|
-
end
|
1788
|
-
|
1789
|
-
#
|
1790
|
-
# 0x0008 - GPSSatelites
|
1791
|
-
#
|
1792
|
-
class GPSSatelites < Base
|
1793
|
-
end
|
1794
|
-
|
1795
|
-
#
|
1796
|
-
# 0x0009 - GPSStatus
|
1797
|
-
#
|
1798
|
-
class GPSStatus < Base
|
1799
|
-
|
1800
|
-
def to_s
|
1801
|
-
case @formatted
|
1802
|
-
when 'A'
|
1803
|
-
'Measurement in progress'
|
1804
|
-
when 'V'
|
1805
|
-
'Measurement in interoperability'
|
1806
|
-
else
|
1807
|
-
'Unknown'
|
1808
|
-
end
|
1809
|
-
end
|
1810
|
-
|
1811
|
-
end
|
1812
|
-
|
1813
|
-
#
|
1814
|
-
# 0x000A - GPSMeasureMode
|
1815
|
-
#
|
1816
|
-
class GPSMeasureMode < Base
|
1817
|
-
|
1818
|
-
def to_s
|
1819
|
-
case @formatted
|
1820
|
-
when '2'
|
1821
|
-
'2-dimensional measurement'
|
1822
|
-
when '3'
|
1823
|
-
'3-dimensional measurement'
|
1824
|
-
else
|
1825
|
-
'Unknown'
|
1826
|
-
end
|
1827
|
-
end
|
1828
|
-
|
1829
|
-
end
|
1830
|
-
|
1831
|
-
#
|
1832
|
-
# 0x000B - GPSDOP
|
1833
|
-
#
|
1834
|
-
class GPSDOP < Base
|
1835
|
-
end
|
1836
|
-
|
1837
|
-
#
|
1838
|
-
# 0x000C - GPSSpeedRef
|
1839
|
-
#
|
1840
|
-
class GPSSpeedRef < Base
|
1841
|
-
|
1842
|
-
def to_s
|
1843
|
-
case @formatted
|
1844
|
-
when 'K'
|
1845
|
-
'Kilometers per hour'
|
1846
|
-
when 'M'
|
1847
|
-
'Miles per hour'
|
1848
|
-
when 'N'
|
1849
|
-
'Knots'
|
1850
|
-
else
|
1851
|
-
'Unknown'
|
1852
|
-
end
|
1853
|
-
end
|
1854
|
-
|
1855
|
-
end
|
1856
|
-
|
1857
|
-
#
|
1858
|
-
# 0x000D - GPSSpeed
|
1859
|
-
#
|
1860
|
-
class GPSSpeed < Base
|
1861
|
-
end
|
1862
|
-
|
1863
|
-
#
|
1864
|
-
# 0x000E - GPSTrackRef
|
1865
|
-
#
|
1866
|
-
class GPSTrackRef < Base
|
1867
|
-
|
1868
|
-
def to_s
|
1869
|
-
case @formatted
|
1870
|
-
when 'T'
|
1871
|
-
'True direction'
|
1872
|
-
when 'M'
|
1873
|
-
'Magnetic direction'
|
1874
|
-
else
|
1875
|
-
'Unknown'
|
1876
|
-
end
|
1877
|
-
end
|
1878
|
-
|
1879
|
-
end
|
1880
|
-
|
1881
|
-
#
|
1882
|
-
# 0x000F - GPSTrack
|
1883
|
-
#
|
1884
|
-
class GPSTrack < Base
|
1885
|
-
end
|
1886
|
-
|
1887
|
-
#
|
1888
|
-
# 0x0010 - GPSImgDirectionRef
|
1889
|
-
#
|
1890
|
-
class GPSImgDirectionRef < Base
|
1891
|
-
|
1892
|
-
def to_s
|
1893
|
-
case @formatted
|
1894
|
-
when 'T'
|
1895
|
-
'True direction'
|
1896
|
-
when 'M'
|
1897
|
-
'Magnetic direction'
|
1898
|
-
else
|
1899
|
-
'Unknown'
|
1900
|
-
end
|
1901
|
-
end
|
1902
|
-
|
1903
|
-
end
|
1904
|
-
|
1905
|
-
#
|
1906
|
-
# 0x0011 - GPSImgDirection
|
1907
|
-
#
|
1908
|
-
class GPSImgDirection < Base
|
1909
|
-
end
|
1910
|
-
|
1911
|
-
#
|
1912
|
-
# 0x0012 - GPSMapDatum
|
1913
|
-
#
|
1914
|
-
class GPSMapDatum < Base
|
1915
|
-
end
|
1916
|
-
|
1917
|
-
#
|
1918
|
-
# 0x0013 - GPSDestLatitudeRef
|
1919
|
-
#
|
1920
|
-
class GPSDestLatitudeRef < Base
|
1921
|
-
|
1922
|
-
def to_s
|
1923
|
-
case @formatted
|
1924
|
-
when 'N'
|
1925
|
-
'North latitude'
|
1926
|
-
when 'S'
|
1927
|
-
'South latitude'
|
1928
|
-
else
|
1929
|
-
'Unknown'
|
1930
|
-
end
|
1931
|
-
end
|
1932
|
-
|
1933
|
-
end
|
1934
|
-
|
1935
|
-
#
|
1936
|
-
# 0x0014 - GPSDestLatitude
|
1937
|
-
#
|
1938
|
-
class GPSDestLatitude < Base
|
1939
|
-
|
1940
|
-
def processData
|
1941
|
-
@formatted = []
|
1942
|
-
partition_data(@count) do |data|
|
1943
|
-
@formatted.push _formatData(data)
|
1944
|
-
end
|
1945
|
-
end
|
1946
|
-
|
1947
|
-
def to_s
|
1948
|
-
formatLatLon @formatted
|
1949
|
-
end
|
1950
|
-
|
1951
|
-
end
|
1952
|
-
|
1953
|
-
#
|
1954
|
-
# 0x0015 - GPSDestLongitudeRef
|
1955
|
-
#
|
1956
|
-
class GPSDestLongitudeRef < Base
|
1957
|
-
|
1958
|
-
def to_s
|
1959
|
-
case @formatted
|
1960
|
-
when 'E'
|
1961
|
-
'East longitude'
|
1962
|
-
when 'W'
|
1963
|
-
'West longitude'
|
1964
|
-
else
|
1965
|
-
'Unknown'
|
1966
|
-
end
|
1967
|
-
end
|
1968
|
-
|
1969
|
-
end
|
1970
|
-
|
1971
|
-
#
|
1972
|
-
# 0x0016 - GPSDestLongitude
|
1973
|
-
#
|
1974
|
-
class GPSDestLongitude < Base
|
1975
|
-
|
1976
|
-
def processData
|
1977
|
-
@formatted = []
|
1978
|
-
partition_data(@count) do |data|
|
1979
|
-
@formatted.push _formatData(data)
|
1980
|
-
end
|
1981
|
-
end
|
1982
|
-
|
1983
|
-
def to_s
|
1984
|
-
formatLatLon @formatted
|
1985
|
-
end
|
1986
|
-
|
1987
|
-
end
|
1988
|
-
|
1989
|
-
#
|
1990
|
-
# 0x0017 - GPSDestBearingRef
|
1991
|
-
#
|
1992
|
-
class GPSDestBearingRef < Base
|
1993
|
-
|
1994
|
-
def to_s
|
1995
|
-
case @formatted
|
1996
|
-
when 'T'
|
1997
|
-
'True direction'
|
1998
|
-
when 'M'
|
1999
|
-
'Magnetic direction'
|
2000
|
-
else
|
2001
|
-
'Unknown'
|
2002
|
-
end
|
2003
|
-
end
|
2004
|
-
|
2005
|
-
end
|
2006
|
-
|
2007
|
-
#
|
2008
|
-
# 0x0018 - GPSDestBearing
|
2009
|
-
#
|
2010
|
-
class GPSDestBearing < Base
|
2011
|
-
end
|
2012
|
-
|
2013
|
-
#
|
2014
|
-
# 0x0019 - GPSDestDistanceRef
|
2015
|
-
#
|
2016
|
-
class GPSDestDistanceRef < Base
|
2017
|
-
|
2018
|
-
def to_s
|
2019
|
-
case @formatted
|
2020
|
-
when 'K'
|
2021
|
-
'Kilometers'
|
2022
|
-
when 'M'
|
2023
|
-
'Miles'
|
2024
|
-
when 'N'
|
2025
|
-
'Knots'
|
2026
|
-
else
|
2027
|
-
'Unknown'
|
2028
|
-
end
|
2029
|
-
end
|
2030
|
-
|
2031
|
-
end
|
2032
|
-
|
2033
|
-
#
|
2034
|
-
# 0x001A
|
2035
|
-
#
|
2036
|
-
class GPSDestDistance < Base
|
2037
|
-
end
|
2038
|
-
|
2039
|
-
#
|
2040
|
-
# 0x001B
|
2041
|
-
#
|
2042
|
-
class GPSProcessingMethod < Base
|
2043
|
-
end
|
2044
|
-
|
2045
|
-
#
|
2046
|
-
# 0x001C
|
2047
|
-
#
|
2048
|
-
class GPSAreaInformation < Base
|
2049
|
-
end
|
2050
|
-
|
2051
|
-
#
|
2052
|
-
# 0x001D
|
2053
|
-
#
|
2054
|
-
class GPSDateStamp < Base
|
2055
|
-
end
|
2056
|
-
|
2057
|
-
#
|
2058
|
-
# 0x001E
|
2059
|
-
#
|
2060
|
-
class GPSDifferential < Base
|
2061
|
-
def to_s
|
2062
|
-
case @formatted
|
2063
|
-
when 0
|
2064
|
-
'Measurement without differential correction'
|
2065
|
-
when 1
|
2066
|
-
'Differential correction applied'
|
2067
|
-
else
|
2068
|
-
'Unknown'
|
2069
|
-
end
|
2070
|
-
end
|
2071
|
-
end
|
2072
|
-
|
2073
|
-
end
|
2074
|
-
|
2075
|
-
##
|
2076
|
-
## Interoperability IFD tags
|
2077
|
-
##
|
2078
|
-
|
2079
|
-
module Interoperability
|
2080
|
-
|
2081
|
-
#
|
2082
|
-
# 0x0001 - InteroperabilityIndex
|
2083
|
-
#
|
2084
|
-
class InteroperabilityIndex < Base
|
2085
|
-
end
|
2086
|
-
|
2087
|
-
#
|
2088
|
-
# 0x0002 - InteroperabilityVersion
|
2089
|
-
#
|
2090
|
-
class InteroperabilityVersion < Base
|
2091
|
-
end
|
2092
|
-
|
2093
|
-
#
|
2094
|
-
# 0x1000 - RelatedImageFileFormat
|
2095
|
-
#
|
2096
|
-
class RelatedImageFileFormat
|
2097
|
-
end
|
2098
|
-
|
2099
|
-
#
|
2100
|
-
# 0x1001 - RelatedImageWidth
|
2101
|
-
#
|
2102
|
-
class RelatedImageWidth < Base
|
2103
|
-
end
|
2104
|
-
|
2105
|
-
#
|
2106
|
-
# 0x1002 - RelatedImageLength
|
2107
|
-
#
|
2108
|
-
class RelatedImageLength < Base
|
2109
|
-
end
|
2110
|
-
|
2111
|
-
end
|
2112
|
-
|
2113
|
-
|
2114
|
-
#
|
2115
|
-
# Hash tables that maps tag ID to the corresponding class.
|
2116
|
-
#
|
2117
|
-
|
2118
|
-
ExifSpecific = {
|
2119
|
-
0x8769 => ExifIFDPointer,
|
2120
|
-
0x8825 => GPSIFDPointer,
|
2121
|
-
0xa005 => InteroperabilityIFDPointer
|
2122
|
-
}
|
2123
|
-
|
2124
|
-
TIFFAttributes = {
|
2125
|
-
0x0100 => TIFF::ImageWidth,
|
2126
|
-
0x0101 => TIFF::ImageLength,
|
2127
|
-
0x0102 => TIFF::BitsPerSample,
|
2128
|
-
0x0103 => TIFF::Compression,
|
2129
|
-
0x0106 => TIFF::PhotometricInterpretation,
|
2130
|
-
0x010E => TIFF::ImageDescription,
|
2131
|
-
0x010F => TIFF::Make,
|
2132
|
-
0x0110 => TIFF::Model,
|
2133
|
-
0x0111 => TIFF::StripOffsets,
|
2134
|
-
0x0112 => TIFF::Orientation,
|
2135
|
-
0x0115 => TIFF::SamplesPerPixel,
|
2136
|
-
0x0116 => TIFF::RowsPerStrip,
|
2137
|
-
0x0117 => TIFF::StripByteCounts,
|
2138
|
-
0x011A => TIFF::XResolution,
|
2139
|
-
0x011B => TIFF::YResolution,
|
2140
|
-
0x011C => TIFF::PlanarConfiguration,
|
2141
|
-
0x0128 => TIFF::ResolutionUnit,
|
2142
|
-
0x012D => TIFF::TransferFunction,
|
2143
|
-
0x0131 => TIFF::Software,
|
2144
|
-
0x0132 => TIFF::DateTime,
|
2145
|
-
0x013B => TIFF::Artist,
|
2146
|
-
0x013E => TIFF::WhitePoint,
|
2147
|
-
0x013F => TIFF::PrimaryChromaticities,
|
2148
|
-
0x0201 => TIFF::JpegInterchangeFormat,
|
2149
|
-
0x0202 => TIFF::JpegInterchangeFormatLength,
|
2150
|
-
0x0211 => TIFF::YCbCrCoefficients,
|
2151
|
-
0x0212 => TIFF::YCbCrSubSampling,
|
2152
|
-
0x0213 => TIFF::YCbCrPositioning,
|
2153
|
-
0x0214 => TIFF::ReferenceBlackWhite,
|
2154
|
-
0x8298 => TIFF::Copyright,
|
2155
|
-
}
|
2156
|
-
|
2157
|
-
#
|
2158
|
-
# ExifStandard 2.2, Section 4.6.8-A
|
2159
|
-
#
|
2160
|
-
IFD0Table = TIFFAttributes.update ExifSpecific
|
2161
|
-
|
2162
|
-
def IFD0Table.name
|
2163
|
-
"IFD0"
|
2164
|
-
end
|
2165
|
-
|
2166
|
-
#
|
2167
|
-
# ExifStandard 2.2, Section 4.6.8-B
|
2168
|
-
#
|
2169
|
-
IFD1Table = IFD0Table.dup
|
2170
|
-
|
2171
|
-
def IFD1Table.name
|
2172
|
-
"IFD1"
|
2173
|
-
end
|
2174
|
-
|
2175
|
-
|
2176
|
-
ExifIFDTable = {
|
2177
|
-
0x829a => Exif::ExposureTime,
|
2178
|
-
0x829d => Exif::FNumber,
|
2179
|
-
0x8822 => Exif::ExposureProgram,
|
2180
|
-
0x8824 => Exif::SpectralSensitivity,
|
2181
|
-
0x8827 => Exif::ISOSpeedRatings,
|
2182
|
-
0x8828 => Exif::OECF,
|
2183
|
-
0x9000 => Exif::ExifVersion,
|
2184
|
-
0x9003 => Exif::DateTimeOriginal,
|
2185
|
-
0x9004 => Exif::DateTimeDigitized,
|
2186
|
-
0x9101 => Exif::ComponentsConfiguration,
|
2187
|
-
0x9102 => Exif::CompressedBitsPerPixel,
|
2188
|
-
0x9201 => Exif::ShutterSpeedValue,
|
2189
|
-
0x9202 => Exif::ApertureValue,
|
2190
|
-
0x9203 => Exif::BrightnessValue,
|
2191
|
-
0x9204 => Exif::ExposureBiasValue,
|
2192
|
-
0x9205 => Exif::MaxApertureValue,
|
2193
|
-
0x9206 => Exif::SubjectDistance,
|
2194
|
-
0x9207 => Exif::MeteringMode,
|
2195
|
-
0x9208 => Exif::LightSource,
|
2196
|
-
0x9209 => Exif::Flash,
|
2197
|
-
0x920a => Exif::FocalLength,
|
2198
|
-
0x9214 => Exif::SubjectArea,
|
2199
|
-
0x927c => Exif::MakerNote,
|
2200
|
-
0x9286 => Exif::UserComment,
|
2201
|
-
0x9290 => Exif::SubsecTime,
|
2202
|
-
0x9291 => Exif::SubsecTimeOriginal,
|
2203
|
-
0x9292 => Exif::SubsecTimeDigitized,
|
2204
|
-
0xa000 => Exif::FlashPixVersion,
|
2205
|
-
0xa001 => Exif::ColorSpace,
|
2206
|
-
0xa002 => Exif::PixelXDimension,
|
2207
|
-
0xa003 => Exif::PixelYDimension,
|
2208
|
-
0xa004 => Exif::RelatedSoundFile,
|
2209
|
-
0xa005 => InteroperabilityIFDPointer,
|
2210
|
-
0xa20b => Exif::FlashEnergy,
|
2211
|
-
0xa20c => Exif::SpatialFrequencyResponse,
|
2212
|
-
0xa20e => Exif::FocalPlaneXResolution,
|
2213
|
-
0xa20f => Exif::FocalPlaneYResolution,
|
2214
|
-
0xa210 => Exif::FocalPlaneResolutionUnit,
|
2215
|
-
0xa214 => Exif::SubjectLocation,
|
2216
|
-
0xa215 => Exif::ExposureIndex,
|
2217
|
-
0xa217 => Exif::SensingMethod,
|
2218
|
-
0xa300 => Exif::FileSource,
|
2219
|
-
0xa301 => Exif::SceneType,
|
2220
|
-
0xa302 => Exif::CFAPattern,
|
2221
|
-
0xa401 => Exif::CustomRendered,
|
2222
|
-
0xa402 => Exif::ExposureMode,
|
2223
|
-
0xa403 => Exif::WhiteBalance,
|
2224
|
-
0xa404 => Exif::DigitalZoomRatio,
|
2225
|
-
0xa405 => Exif::FocalLengthIn35mmFilm,
|
2226
|
-
0xa406 => Exif::SceneCaptureType,
|
2227
|
-
0xa407 => Exif::GainControl,
|
2228
|
-
0xa408 => Exif::Contrast,
|
2229
|
-
0xa409 => Exif::Saturation,
|
2230
|
-
0xa40a => Exif::Sharpness,
|
2231
|
-
0xa40b => Exif::DeviceSettingDescription,
|
2232
|
-
0xa40c => Exif::SubjectDistanceRange,
|
2233
|
-
0xa420 => Exif::ImageUniqueID
|
2234
|
-
}
|
2235
|
-
|
2236
|
-
def ExifIFDTable.name
|
2237
|
-
"Exif"
|
2238
|
-
end
|
2239
|
-
|
2240
|
-
GPSIFDTable = {
|
2241
|
-
0x0000 => GPS::GPSVersionID,
|
2242
|
-
0x0001 => GPS::GPSLatitudeRef,
|
2243
|
-
0x0002 => GPS::GPSLatitude,
|
2244
|
-
0x0003 => GPS::GPSLongitudeRef,
|
2245
|
-
0x0004 => GPS::GPSLongitude,
|
2246
|
-
0x0005 => GPS::GPSAltitudeRef,
|
2247
|
-
0x0006 => GPS::GPSAltitude,
|
2248
|
-
0x0007 => GPS::GPSTimeStamp,
|
2249
|
-
0x0008 => GPS::GPSSatelites,
|
2250
|
-
0x000a => GPS::GPSMeasureMode,
|
2251
|
-
0x000b => GPS::GPSDOP,
|
2252
|
-
0x000c => GPS::GPSSpeedRef,
|
2253
|
-
0x000d => GPS::GPSSpeed,
|
2254
|
-
0x000e => GPS::GPSTrackRef,
|
2255
|
-
0x000f => GPS::GPSTrack,
|
2256
|
-
0x0010 => GPS::GPSImgDirectionRef,
|
2257
|
-
0x0011 => GPS::GPSImgDirection,
|
2258
|
-
0x0012 => GPS::GPSMapDatum,
|
2259
|
-
0x0013 => GPS::GPSDestLatitudeRef,
|
2260
|
-
0x0014 => GPS::GPSDestLatitude,
|
2261
|
-
0x0015 => GPS::GPSDestLongitudeRef,
|
2262
|
-
0x0016 => GPS::GPSDestLongitude,
|
2263
|
-
0x0017 => GPS::GPSDestBearingRef,
|
2264
|
-
0x0018 => GPS::GPSDestBearing,
|
2265
|
-
0x0019 => GPS::GPSDestDistanceRef,
|
2266
|
-
0x001A => GPS::GPSDestDistance,
|
2267
|
-
0x001B => GPS::GPSProcessingMethod,
|
2268
|
-
0x001C => GPS::GPSAreaInformation,
|
2269
|
-
0x001D => GPS::GPSDateStamp,
|
2270
|
-
0x001E => GPS::GPSDifferential
|
2271
|
-
}
|
2272
|
-
|
2273
|
-
def GPSIFDTable.name
|
2274
|
-
"GPS"
|
2275
|
-
end
|
2276
|
-
|
2277
|
-
InteroperabilityIFDTable = {
|
2278
|
-
0x0001 => Interoperability::InteroperabilityIndex,
|
2279
|
-
0x0002 => Interoperability::InteroperabilityVersion,
|
2280
|
-
0x1000 => Interoperability::RelatedImageFileFormat,
|
2281
|
-
0x1001 => Interoperability::RelatedImageWidth,
|
2282
|
-
0x1002 => Interoperability::RelatedImageLength
|
2283
|
-
}
|
2284
|
-
|
2285
|
-
def InteroperabilityIFDTable.name
|
2286
|
-
"Interoperability"
|
2287
|
-
end
|
2288
|
-
|
2289
|
-
|
2290
|
-
module_function
|
2291
|
-
|
2292
|
-
def find(tagid, table)
|
2293
|
-
table[tagid] or ::Exif::Tag::Unknown
|
2294
|
-
end
|
2295
|
-
|
2296
|
-
end
|
2297
|
-
|
2298
|
-
end
|