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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/exifparser.gemspec +23 -0
- data/lib/exifparser.rb +265 -0
- data/lib/exifparser/makernote/canon.rb +502 -0
- data/lib/exifparser/makernote/fujifilm.rb +415 -0
- data/lib/exifparser/makernote/minolta.rb +84 -0
- data/lib/exifparser/makernote/mk_nikonflensname.rb +39 -0
- data/lib/exifparser/makernote/nikon.rb +267 -0
- data/lib/exifparser/makernote/nikon2.rb +581 -0
- data/lib/exifparser/makernote/nikonflensname.rb +438 -0
- data/lib/exifparser/makernote/olympus.rb +225 -0
- data/lib/exifparser/makernote/prove.rb +84 -0
- data/lib/exifparser/makernote/sigma.rb +237 -0
- data/lib/exifparser/pre-setup.rb +1 -0
- data/lib/exifparser/scan.rb +278 -0
- data/lib/exifparser/tag.rb +2298 -0
- data/lib/exifparser/thumbnail.rb +76 -0
- data/lib/exifparser/utils.rb +88 -0
- data/lib/exifparser/version.rb +3 -0
- data/sample/exifview.rb +279 -0
- metadata +96 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
# exifparser/makernote/prove.rb -
|
4
|
+
#
|
5
|
+
# Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
6
|
+
#
|
7
|
+
# $Revision: 1.1.1.1 $
|
8
|
+
# $Date: 2002/12/16 07:59:00 $
|
9
|
+
#
|
10
|
+
require 'exifparser/makernote/fujifilm'
|
11
|
+
require 'exifparser/makernote/olympus'
|
12
|
+
require 'exifparser/makernote/canon'
|
13
|
+
require 'exifparser/makernote/nikon'
|
14
|
+
require 'exifparser/makernote/nikon2'
|
15
|
+
require 'exifparser/makernote/minolta'
|
16
|
+
require 'exifparser/makernote/sigma'
|
17
|
+
|
18
|
+
module Exif
|
19
|
+
|
20
|
+
module MakerNote
|
21
|
+
|
22
|
+
class NotSupportedError < RuntimeError; end
|
23
|
+
|
24
|
+
module_function
|
25
|
+
|
26
|
+
def prove(data, tag_make=nil, tag_model=nil)
|
27
|
+
|
28
|
+
make = tag_make == nil ? '' : tag_make.to_s.upcase
|
29
|
+
model = tag_model == nil ? '' : tag_model.to_s.upcase
|
30
|
+
|
31
|
+
#
|
32
|
+
# Identifier for OLYMPUS
|
33
|
+
#
|
34
|
+
if data[0..5] == "OLYMP\000"
|
35
|
+
return Olympus
|
36
|
+
#
|
37
|
+
# Identifier for FUJIFILM
|
38
|
+
#
|
39
|
+
elsif data[0..7] == "FUJIFILM"
|
40
|
+
return Fujifilm
|
41
|
+
|
42
|
+
#
|
43
|
+
# Identifier for Nikon
|
44
|
+
#
|
45
|
+
|
46
|
+
elsif make[0..4] == 'NIKON'
|
47
|
+
if data[0..5] == "Nikon\000"
|
48
|
+
if data[6] == 0x01 && data[7] == 0x00
|
49
|
+
return Nikon
|
50
|
+
end
|
51
|
+
end
|
52
|
+
return Nikon2
|
53
|
+
|
54
|
+
#
|
55
|
+
# Canon
|
56
|
+
#
|
57
|
+
elsif make[0..4] == 'CANON'
|
58
|
+
return Canon
|
59
|
+
|
60
|
+
#
|
61
|
+
# Minolta
|
62
|
+
#
|
63
|
+
elsif make[0..6] == 'MINOLTA'
|
64
|
+
return Minolta
|
65
|
+
|
66
|
+
#
|
67
|
+
# Sigma
|
68
|
+
#
|
69
|
+
elsif make[0..4] == 'SIGMA'
|
70
|
+
return Sigma
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# If none above is applied, raises exception,
|
76
|
+
# which will be caught by caller's rescue statement.
|
77
|
+
#
|
78
|
+
raise NotSupportedError
|
79
|
+
end
|
80
|
+
module_function :prove
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
#
|
2
|
+
# exifparser/makernote/sigma.rb
|
3
|
+
#
|
4
|
+
# $Revision: 1.1 $
|
5
|
+
# $Date: 2010/10/23 16:41:28 $
|
6
|
+
#
|
7
|
+
require 'exifparser/tag'
|
8
|
+
require 'exifparser/utils'
|
9
|
+
|
10
|
+
module Exif
|
11
|
+
|
12
|
+
module Tag
|
13
|
+
|
14
|
+
module MakerNote
|
15
|
+
#
|
16
|
+
# 0x0002 - SigmaSerialNo
|
17
|
+
#
|
18
|
+
# class SigmaSerialNo < Base
|
19
|
+
# end
|
20
|
+
|
21
|
+
#
|
22
|
+
# 0x0003 - DriveMode
|
23
|
+
#
|
24
|
+
class DriveMode < Base
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# 0x0004 - ImageSize
|
29
|
+
#
|
30
|
+
class ImageSize < Base
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# 0x0005 - AF_Mode
|
35
|
+
#
|
36
|
+
class AF_Mode < Base
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# 0x0006 - AF_Setting
|
41
|
+
#
|
42
|
+
class AF_Setting < Base
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# 0x0007 - White_Balance
|
47
|
+
#
|
48
|
+
class White_Balance < Base
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# 0x0008 - ExposureMode
|
53
|
+
#
|
54
|
+
class ExposureMode < Base
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# 0x0009 - MeteringMode
|
59
|
+
#
|
60
|
+
class MeteringMode < Base
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# 0x000a - FocalLength
|
65
|
+
#
|
66
|
+
class FocalLength < Base
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# 0x000b - ColorSpace
|
71
|
+
#
|
72
|
+
class ColorSpace < Base
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# 0x000c - ExposureBias
|
77
|
+
#
|
78
|
+
class ExposureBias < Base
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# 0x000d - Contrast
|
83
|
+
#
|
84
|
+
class Contrast < Base
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# 0x000e - Shadow
|
89
|
+
#
|
90
|
+
class Shadow < Base
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# 0x000f - HighLight
|
95
|
+
#
|
96
|
+
class HighLight < Base
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# 0x0010 - Saturation
|
101
|
+
#
|
102
|
+
class Saturation
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# 0x0011 - SharpnessBias
|
107
|
+
#
|
108
|
+
class SharpnessBias < Base
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# 0x0012 - X3FillLight
|
113
|
+
#
|
114
|
+
class X3FillLight < Base
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# 0x0014 - ColorControl
|
119
|
+
#
|
120
|
+
class ColorControl < Base
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# 0x0015 - SettingMode
|
125
|
+
#
|
126
|
+
class SettingMode < Base
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# 0x0017 - Firmware
|
131
|
+
#
|
132
|
+
class Firmware < Base
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# 0x0018 - SigmaSoftware
|
137
|
+
#
|
138
|
+
class SigmaSoftware < Base
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# 0x0019 - AutoBracket
|
143
|
+
#
|
144
|
+
class AutoBracket < Base
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
SigmaIFDTable = {
|
150
|
+
# 0x0002 => MakerNote::SigmaSerialNo,
|
151
|
+
0x0003 => MakerNote::DriveMode,
|
152
|
+
0x0004 => MakerNote::ImageSize,
|
153
|
+
0x0005 => MakerNote::AF_Mode,
|
154
|
+
0x0006 => MakerNote::AF_Setting,
|
155
|
+
0x0007 => MakerNote::White_Balance,
|
156
|
+
0x0008 => MakerNote::ExposureMode,
|
157
|
+
0x0009 => MakerNote::MeteringMode,
|
158
|
+
0x000a => MakerNote::FocalLength,
|
159
|
+
0x000b => MakerNote::ColorSpace,
|
160
|
+
0x000c => MakerNote::ExposureBias,
|
161
|
+
0x000d => MakerNote::Contrast,
|
162
|
+
0x000e => MakerNote::Shadow,
|
163
|
+
0x000f => MakerNote::HighLight,
|
164
|
+
0x0010 => MakerNote::Saturation,
|
165
|
+
0x0011 => MakerNote::SharpnessBias,
|
166
|
+
0x0012 => MakerNote::X3FillLight,
|
167
|
+
0x0014 => MakerNote::ColorControl,
|
168
|
+
0x0015 => MakerNote::SettingMode,
|
169
|
+
0x0017 => MakerNote::Firmware,
|
170
|
+
0x0018 => MakerNote::SigmaSoftware,
|
171
|
+
0x0019 => MakerNote::AutoBracket
|
172
|
+
}
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
class Sigma
|
177
|
+
|
178
|
+
def initialize(fin, tiff_origin, dataPos, byteOrder_module)
|
179
|
+
@fin = fin
|
180
|
+
@tiffHeader0 = tiff_origin
|
181
|
+
@dataPos = dataPos
|
182
|
+
@byteOrder_module = byteOrder_module
|
183
|
+
self.extend @byteOrder_module
|
184
|
+
end
|
185
|
+
|
186
|
+
def scan_IFD
|
187
|
+
#
|
188
|
+
# Sigma MakerNote starts from 10 byte from the origin
|
189
|
+
#
|
190
|
+
@fin.pos = @dataPos + 10
|
191
|
+
|
192
|
+
#
|
193
|
+
# get the number of tags
|
194
|
+
#
|
195
|
+
numDirs = decode_ushort(fin_read_n(2))
|
196
|
+
|
197
|
+
#
|
198
|
+
# now scan them
|
199
|
+
#
|
200
|
+
1.upto(numDirs) {
|
201
|
+
curpos_tag = @fin.pos
|
202
|
+
tag = parseTagID(fin_read_n(2))
|
203
|
+
tagclass = Tag.find(tag.hex, Tag::SigmaIFDTable)
|
204
|
+
unit, formatter = Tag::Format::Unit[decode_ushort(fin_read_n(2))]
|
205
|
+
count = decode_ulong(fin_read_n(4))
|
206
|
+
tagdata = fin_read_n(4)
|
207
|
+
|
208
|
+
obj = tagclass.new(tag, "MakerNote", count)
|
209
|
+
obj.extend formatter, @byteOrder_module
|
210
|
+
obj.pos = curpos_tag
|
211
|
+
if unit * count > 4
|
212
|
+
curpos = @fin.pos
|
213
|
+
begin
|
214
|
+
@fin.pos = @tiffHeader0 + decode_ulong(tagdata)
|
215
|
+
obj.dataPos = @fin.pos
|
216
|
+
obj.data = fin_read_n(unit*count)
|
217
|
+
ensure
|
218
|
+
@fin.pos = curpos
|
219
|
+
end
|
220
|
+
else
|
221
|
+
obj.dataPos = @fin.pos - 4
|
222
|
+
obj.data = tagdata
|
223
|
+
end
|
224
|
+
obj.processData
|
225
|
+
yield obj
|
226
|
+
}
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
def fin_read_n(n)
|
232
|
+
@fin.read(n)
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# pre-setup.rb - working with install.rb
|
@@ -0,0 +1,278 @@
|
|
1
|
+
#
|
2
|
+
# exifparser/scan.rb
|
3
|
+
#
|
4
|
+
# Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
5
|
+
#
|
6
|
+
# $Revision: 1.2 $
|
7
|
+
# $Date: 2003/04/20 19:58:31 $
|
8
|
+
#
|
9
|
+
#
|
10
|
+
require 'exifparser/utils'
|
11
|
+
require 'exifparser/tag'
|
12
|
+
require 'exifparser/makernote/prove'
|
13
|
+
|
14
|
+
module Exif
|
15
|
+
|
16
|
+
class Scanner
|
17
|
+
|
18
|
+
def initialize(fin)
|
19
|
+
@fin = fin.binmode
|
20
|
+
@result = {}
|
21
|
+
@tiffHeader0 = nil # origin at which TIFF header begins
|
22
|
+
@byteOrder_module = nil
|
23
|
+
end
|
24
|
+
attr_reader :result
|
25
|
+
|
26
|
+
def finish
|
27
|
+
@fin.close
|
28
|
+
end
|
29
|
+
|
30
|
+
def scan
|
31
|
+
tic = Time.now if $DEBUG
|
32
|
+
#
|
33
|
+
# check soi (start of image)
|
34
|
+
#
|
35
|
+
@fin.pos = 0
|
36
|
+
unless get_soi == 0xFFD8
|
37
|
+
raise RuntimeError, 'not JPEG format'
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# seek app1 (EXIF signature)
|
42
|
+
#
|
43
|
+
begin
|
44
|
+
marker = get_marker
|
45
|
+
break if (marker == 0xFFE1)
|
46
|
+
size = get_marker_datasize
|
47
|
+
@fin.seek(size - 2, IO::SEEK_CUR)
|
48
|
+
end while (!@fin.eof?)
|
49
|
+
|
50
|
+
if marker != 0xFFE1
|
51
|
+
raise RuntimeError, 'not EXIF format'
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# get app1 Data size
|
56
|
+
#
|
57
|
+
@result[:app1DataSize] = get_marker_datasize()
|
58
|
+
curpos = @fin.pos
|
59
|
+
@result[:app1Data] = fin_read_n(@result[:app1DataSize])
|
60
|
+
@fin.pos = curpos
|
61
|
+
|
62
|
+
#
|
63
|
+
# EXIF header must be exactly "Exif\000\000", but some model
|
64
|
+
# does not provide correct one. So we relax the condition.
|
65
|
+
#
|
66
|
+
if (h = exif_identifier()) !~ /\AExif\000/
|
67
|
+
raise RuntimeError, "Invalid EXIF header: #{h}"
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# examine TIFF header
|
72
|
+
#
|
73
|
+
@tiffHeader0, tiff_header = get_tiff_header()
|
74
|
+
|
75
|
+
#
|
76
|
+
# get byte order
|
77
|
+
#
|
78
|
+
case tiff_header[0,2]
|
79
|
+
when "MM"
|
80
|
+
@byteOrder_module = Utils::Decode::Motorola
|
81
|
+
when "II"
|
82
|
+
@byteOrder_module = Utils::Decode::Intel
|
83
|
+
else
|
84
|
+
raise RuntimeError, "Unknown byte order"
|
85
|
+
end
|
86
|
+
self.extend @byteOrder_module
|
87
|
+
@result[:offset_IFD0] = decode_ulong(tiff_header[4..-1])
|
88
|
+
|
89
|
+
#
|
90
|
+
# IFD0
|
91
|
+
#
|
92
|
+
@fin.pos = @tiffHeader0 + @result[:offset_IFD0]
|
93
|
+
@result[:IFD0] = []
|
94
|
+
scan_IFD(Tag::IFD0Table, Tag::IFD0Table.name) do |tag|
|
95
|
+
@result[:IFD0].push tag
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# IFD1
|
100
|
+
#
|
101
|
+
@result[:IFD1] = []
|
102
|
+
next_ifd = decode_ulong(fin_read_n(4))
|
103
|
+
if next_ifd > 0
|
104
|
+
@fin.pos = @tiffHeader0 + next_ifd
|
105
|
+
scan_IFD(Tag::IFD1Table, Tag::IFD1Table.name) do |tag|
|
106
|
+
@result[:IFD1].push tag
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# GPS IFD
|
112
|
+
#
|
113
|
+
@result[:GPS] = []
|
114
|
+
found = @result[:IFD0].find{ |e|
|
115
|
+
e.class == Tag::GPSIFDPointer
|
116
|
+
}
|
117
|
+
if found
|
118
|
+
@result[:offset_GPS] = found.processData
|
119
|
+
@fin.pos = @tiffHeader0 + @result[:offset_GPS]
|
120
|
+
scan_IFD(Tag::GPSIFDTable, Tag::GPSIFDTable.name) do |tag|
|
121
|
+
@result[:GPS].push tag
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Exif IFD
|
127
|
+
#
|
128
|
+
@result[:Exif] = []
|
129
|
+
found = @result[:IFD0].find{ |e|
|
130
|
+
e.class == Tag::ExifIFDPointer
|
131
|
+
}
|
132
|
+
if found
|
133
|
+
@result[:offset_Exif] = found.processData
|
134
|
+
@fin.pos = @tiffHeader0 + @result[:offset_Exif]
|
135
|
+
scan_IFD(Tag::ExifIFDTable, Tag::ExifIFDTable.name) do |tag|
|
136
|
+
@result[:Exif].push tag
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# Interoperability subIFD
|
142
|
+
#
|
143
|
+
@result[:Interoperability] = []
|
144
|
+
found = @result[:Exif].find {|e|
|
145
|
+
e.class == Tag::InteroperabilityIFDPointer
|
146
|
+
}
|
147
|
+
if found
|
148
|
+
@result[:offset_InteroperabilityIFD] = found.processData
|
149
|
+
@fin.pos = @tiffHeader0 + @result[:offset_InteroperabilityIFD]
|
150
|
+
scan_IFD(Tag::InteroperabilityIFDTable, Tag::InteroperabilityIFDTable.name) do |tag|
|
151
|
+
@result[:Interoperability].push tag
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# MakerNote subIFD
|
157
|
+
#
|
158
|
+
@result[:MakerNote]=[]
|
159
|
+
found = @result[:Exif].find {|e| e.class == Tag::Exif::MakerNote }
|
160
|
+
if (found)
|
161
|
+
begin
|
162
|
+
# Because some vendors do not put any identifier in the header,
|
163
|
+
# we try to find which model is by seeing Tag::TIFF::Make, Tag::TIFF::Model.
|
164
|
+
make = @result[:IFD0].find {|e| e.class == Tag::TIFF::Make}
|
165
|
+
model = @result[:IFD0].find {|e| e.class == Tag::TIFF::Model}
|
166
|
+
# prove the maker
|
167
|
+
makernote_class = Exif::MakerNote.prove(found.data, make, model)
|
168
|
+
# set file pointer to the position where the tag was found.
|
169
|
+
@fin.pos = found.pos
|
170
|
+
makernote = makernote_class.new(@fin, @tiffHeader0, found.dataPos, @byteOrder_module)
|
171
|
+
makernote.scan_IFD do |tag|
|
172
|
+
@result[:MakerNote].push tag
|
173
|
+
end
|
174
|
+
rescue MakerNote::NotSupportedError
|
175
|
+
rescue Exception # what to do?
|
176
|
+
if $DEBUG
|
177
|
+
raise $!
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# get thumbnail
|
184
|
+
#
|
185
|
+
if !@result[:IFD1].empty?
|
186
|
+
format = @result[:IFD1].find do |e|
|
187
|
+
e.class == Tag::TIFF::Compression
|
188
|
+
end.value
|
189
|
+
unless format == 6
|
190
|
+
raise NotImplementedError, "Sorry, thumbnail of other than JPEG format is not supported."
|
191
|
+
end
|
192
|
+
thumbStart = @result[:IFD1].find do |e|
|
193
|
+
e.class == Exif::Tag::TIFF::JpegInterchangeFormat
|
194
|
+
end.value
|
195
|
+
thumbLen = @result[:IFD1].find do |e|
|
196
|
+
e.class == Exif::Tag::TIFF::JpegInterchangeFormatLength
|
197
|
+
end.value
|
198
|
+
@fin.pos = @tiffHeader0 + thumbStart
|
199
|
+
# check JPEG soi maker
|
200
|
+
if get_soi != 0xFFD8
|
201
|
+
raise RuntimeError, 'not JPEG format'
|
202
|
+
end
|
203
|
+
@fin.pos = @fin.pos - 2
|
204
|
+
# now read thumbnail image
|
205
|
+
@result[:Thumbnail] = @fin.read(thumbLen)
|
206
|
+
end
|
207
|
+
|
208
|
+
# turn on if $DEBUG
|
209
|
+
toc = Time.now if $DEBUG
|
210
|
+
puts(sprintf("scan time: %1.4f sec.", toc-tic)) if $DEBUG
|
211
|
+
end
|
212
|
+
|
213
|
+
private
|
214
|
+
|
215
|
+
def fin_read_n(n)
|
216
|
+
@fin.read(n)
|
217
|
+
end
|
218
|
+
|
219
|
+
def scan_IFD(tagTable, ifdname)
|
220
|
+
num_dirs = decode_ushort(fin_read_n(2))
|
221
|
+
1.upto(num_dirs) {
|
222
|
+
curpos_tag = @fin.pos
|
223
|
+
tag = parseTagID(fin_read_n(2))
|
224
|
+
tagclass = Tag.find(tag.hex, tagTable)
|
225
|
+
unit, formatter = Tag::Format::Unit[decode_ushort(fin_read_n(2))]
|
226
|
+
count = decode_ulong(fin_read_n(4))
|
227
|
+
tagdata = fin_read_n(4)
|
228
|
+
next if formatter == nil
|
229
|
+
obj = tagclass.new(tag, ifdname, count)
|
230
|
+
obj.extend formatter, @byteOrder_module
|
231
|
+
obj.pos = curpos_tag
|
232
|
+
if unit * count > 4
|
233
|
+
curpos = @fin.pos
|
234
|
+
begin
|
235
|
+
@fin.pos = @tiffHeader0 + decode_ulong(tagdata)
|
236
|
+
obj.dataPos = @fin.pos
|
237
|
+
obj.data = fin_read_n(unit*count)
|
238
|
+
ensure
|
239
|
+
@fin.pos = curpos
|
240
|
+
end
|
241
|
+
else
|
242
|
+
obj.dataPos = @fin.pos - 4
|
243
|
+
obj.data = tagdata
|
244
|
+
end
|
245
|
+
obj.processData
|
246
|
+
yield obj
|
247
|
+
}
|
248
|
+
end
|
249
|
+
|
250
|
+
def get_soi
|
251
|
+
(@fin.read(1).unpack("C*")[0]) << 8 | (@fin.read(1).unpack("C*")[0])
|
252
|
+
end
|
253
|
+
|
254
|
+
def get_marker
|
255
|
+
(@fin.read(1).unpack("C*")[0]) << 8 | (@fin.read(1).unpack("C*")[0])
|
256
|
+
end
|
257
|
+
|
258
|
+
def get_marker_datasize
|
259
|
+
(@fin.read(1).unpack("C*")[0]) << 8 | (@fin.read(1).unpack("C*")[0])
|
260
|
+
end
|
261
|
+
|
262
|
+
def exif_identifier
|
263
|
+
@fin.read(6)
|
264
|
+
end
|
265
|
+
|
266
|
+
def get_tiff_header
|
267
|
+
pos = @fin.pos
|
268
|
+
[pos, fin_read_n(8)]
|
269
|
+
end
|
270
|
+
|
271
|
+
def eoi
|
272
|
+
@fin.seek(-2, IO::SEEK_END)
|
273
|
+
@fin.read(2)
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|