1 package exifcommon
2
3 import (
4 "errors"
5 "io"
6
7 "encoding/binary"
8
9 "github.com/dsoprea/go-logging"
10 )
11
12 var (
13 parser *Parser
14 )
15
16 var (
17
18
19 ErrNotFarValue = errors.New("not a far value")
20 )
21
22
23
24 type ValueContext struct {
25 unitCount uint32
26 valueOffset uint32
27 rawValueOffset []byte
28 rs io.ReadSeeker
29
30 tagType TagTypePrimitive
31 byteOrder binary.ByteOrder
32
33
34
35 undefinedValueTagType TagTypePrimitive
36
37 ifdPath string
38 tagId uint16
39 }
40
41
42
43
44 func NewValueContext(ifdPath string, tagId uint16, unitCount, valueOffset uint32, rawValueOffset []byte, rs io.ReadSeeker, tagType TagTypePrimitive, byteOrder binary.ByteOrder) *ValueContext {
45 return &ValueContext{
46 unitCount: unitCount,
47 valueOffset: valueOffset,
48 rawValueOffset: rawValueOffset,
49 rs: rs,
50
51 tagType: tagType,
52 byteOrder: byteOrder,
53
54 ifdPath: ifdPath,
55 tagId: tagId,
56 }
57 }
58
59
60 func (vc *ValueContext) SetUndefinedValueType(tagType TagTypePrimitive) {
61 if vc.tagType != TypeUndefined {
62 log.Panicf("can not set effective type for unknown-type tag because this is *not* an unknown-type tag")
63 }
64
65 vc.undefinedValueTagType = tagType
66 }
67
68
69 func (vc *ValueContext) UnitCount() uint32 {
70 return vc.unitCount
71 }
72
73
74 func (vc *ValueContext) ValueOffset() uint32 {
75 return vc.valueOffset
76 }
77
78
79
80
81 func (vc *ValueContext) RawValueOffset() []byte {
82 return vc.rawValueOffset
83 }
84
85
86 func (vc *ValueContext) AddressableData() io.ReadSeeker {
87
88
89
90 return vc.rs
91 }
92
93
94 func (vc *ValueContext) ByteOrder() binary.ByteOrder {
95 return vc.byteOrder
96 }
97
98
99 func (vc *ValueContext) IfdPath() string {
100 return vc.ifdPath
101 }
102
103
104 func (vc *ValueContext) TagId() uint16 {
105 return vc.tagId
106 }
107
108
109
110
111 func (vc *ValueContext) isEmbedded() bool {
112 tagType := vc.effectiveValueType()
113
114 return (tagType.Size() * int(vc.unitCount)) <= 4
115 }
116
117
118
119
120 func (vc *ValueContext) SizeInBytes() int {
121 tagType := vc.effectiveValueType()
122
123 return tagType.Size() * int(vc.unitCount)
124 }
125
126
127
128 func (vc *ValueContext) effectiveValueType() (tagType TagTypePrimitive) {
129 if vc.tagType == TypeUndefined {
130 tagType = vc.undefinedValueTagType
131
132 if tagType == 0 {
133 log.Panicf("undefined-value type not set")
134 }
135 } else {
136 tagType = vc.tagType
137 }
138
139 return tagType
140 }
141
142
143 func (vc *ValueContext) readRawEncoded() (rawBytes []byte, err error) {
144 defer func() {
145 if state := recover(); state != nil {
146 err = log.Wrap(state.(error))
147 }
148 }()
149
150 tagType := vc.effectiveValueType()
151
152 unitSizeRaw := uint32(tagType.Size())
153
154 if vc.isEmbedded() == true {
155 byteLength := unitSizeRaw * vc.unitCount
156 return vc.rawValueOffset[:byteLength], nil
157 }
158
159 _, err = vc.rs.Seek(int64(vc.valueOffset), io.SeekStart)
160 log.PanicIf(err)
161
162 rawBytes = make([]byte, vc.unitCount*unitSizeRaw)
163
164 _, err = io.ReadFull(vc.rs, rawBytes)
165 log.PanicIf(err)
166
167 return rawBytes, nil
168 }
169
170
171
172 func (vc *ValueContext) GetFarOffset() (offset uint32, err error) {
173 if vc.isEmbedded() == true {
174 return 0, ErrNotFarValue
175 }
176
177 return vc.valueOffset, nil
178 }
179
180
181 func (vc *ValueContext) ReadRawEncoded() (rawBytes []byte, err error) {
182
183
184
185 return vc.readRawEncoded()
186 }
187
188
189
190
191
192
193
194
195
196
197 func (vc *ValueContext) Format() (value string, err error) {
198 defer func() {
199 if state := recover(); state != nil {
200 err = log.Wrap(state.(error))
201 }
202 }()
203
204 rawBytes, err := vc.readRawEncoded()
205 log.PanicIf(err)
206
207 phrase, err := FormatFromBytes(rawBytes, vc.effectiveValueType(), false, vc.byteOrder)
208 log.PanicIf(err)
209
210 return phrase, nil
211 }
212
213
214
215 func (vc *ValueContext) FormatFirst() (value string, err error) {
216 defer func() {
217 if state := recover(); state != nil {
218 err = log.Wrap(state.(error))
219 }
220 }()
221
222 rawBytes, err := vc.readRawEncoded()
223 log.PanicIf(err)
224
225 phrase, err := FormatFromBytes(rawBytes, vc.tagType, true, vc.byteOrder)
226 log.PanicIf(err)
227
228 return phrase, nil
229 }
230
231
232 func (vc *ValueContext) ReadBytes() (value []byte, err error) {
233 defer func() {
234 if state := recover(); state != nil {
235 err = log.Wrap(state.(error))
236 }
237 }()
238
239 rawValue, err := vc.readRawEncoded()
240 log.PanicIf(err)
241
242 value, err = parser.ParseBytes(rawValue, vc.unitCount)
243 log.PanicIf(err)
244
245 return value, nil
246 }
247
248
249
250 func (vc *ValueContext) ReadAscii() (value string, err error) {
251 defer func() {
252 if state := recover(); state != nil {
253 err = log.Wrap(state.(error))
254 }
255 }()
256
257 rawValue, err := vc.readRawEncoded()
258 log.PanicIf(err)
259
260 value, err = parser.ParseAscii(rawValue, vc.unitCount)
261 log.PanicIf(err)
262
263 return value, nil
264 }
265
266
267
268 func (vc *ValueContext) ReadAsciiNoNul() (value string, err error) {
269 defer func() {
270 if state := recover(); state != nil {
271 err = log.Wrap(state.(error))
272 }
273 }()
274
275 rawValue, err := vc.readRawEncoded()
276 log.PanicIf(err)
277
278 value, err = parser.ParseAsciiNoNul(rawValue, vc.unitCount)
279 log.PanicIf(err)
280
281 return value, nil
282 }
283
284
285 func (vc *ValueContext) ReadShorts() (value []uint16, err error) {
286 defer func() {
287 if state := recover(); state != nil {
288 err = log.Wrap(state.(error))
289 }
290 }()
291
292 rawValue, err := vc.readRawEncoded()
293 log.PanicIf(err)
294
295 value, err = parser.ParseShorts(rawValue, vc.unitCount, vc.byteOrder)
296 log.PanicIf(err)
297
298 return value, nil
299 }
300
301
302 func (vc *ValueContext) ReadLongs() (value []uint32, err error) {
303 defer func() {
304 if state := recover(); state != nil {
305 err = log.Wrap(state.(error))
306 }
307 }()
308
309 rawValue, err := vc.readRawEncoded()
310 log.PanicIf(err)
311
312 value, err = parser.ParseLongs(rawValue, vc.unitCount, vc.byteOrder)
313 log.PanicIf(err)
314
315 return value, nil
316 }
317
318
319 func (vc *ValueContext) ReadFloats() (value []float32, err error) {
320 defer func() {
321 if state := recover(); state != nil {
322 err = log.Wrap(state.(error))
323 }
324 }()
325
326 rawValue, err := vc.readRawEncoded()
327 log.PanicIf(err)
328
329 value, err = parser.ParseFloats(rawValue, vc.unitCount, vc.byteOrder)
330 log.PanicIf(err)
331
332 return value, nil
333 }
334
335
336 func (vc *ValueContext) ReadDoubles() (value []float64, err error) {
337 defer func() {
338 if state := recover(); state != nil {
339 err = log.Wrap(state.(error))
340 }
341 }()
342
343 rawValue, err := vc.readRawEncoded()
344 log.PanicIf(err)
345
346 value, err = parser.ParseDoubles(rawValue, vc.unitCount, vc.byteOrder)
347 log.PanicIf(err)
348
349 return value, nil
350 }
351
352
353
354 func (vc *ValueContext) ReadRationals() (value []Rational, err error) {
355 defer func() {
356 if state := recover(); state != nil {
357 err = log.Wrap(state.(error))
358 }
359 }()
360
361 rawValue, err := vc.readRawEncoded()
362 log.PanicIf(err)
363
364 value, err = parser.ParseRationals(rawValue, vc.unitCount, vc.byteOrder)
365 log.PanicIf(err)
366
367 return value, nil
368 }
369
370
371 func (vc *ValueContext) ReadSignedLongs() (value []int32, err error) {
372 defer func() {
373 if state := recover(); state != nil {
374 err = log.Wrap(state.(error))
375 }
376 }()
377
378 rawValue, err := vc.readRawEncoded()
379 log.PanicIf(err)
380
381 value, err = parser.ParseSignedLongs(rawValue, vc.unitCount, vc.byteOrder)
382 log.PanicIf(err)
383
384 return value, nil
385 }
386
387
388
389 func (vc *ValueContext) ReadSignedRationals() (value []SignedRational, err error) {
390 defer func() {
391 if state := recover(); state != nil {
392 err = log.Wrap(state.(error))
393 }
394 }()
395
396 rawValue, err := vc.readRawEncoded()
397 log.PanicIf(err)
398
399 value, err = parser.ParseSignedRationals(rawValue, vc.unitCount, vc.byteOrder)
400 log.PanicIf(err)
401
402 return value, nil
403 }
404
405
406
407
408
409
410
411 func (vc *ValueContext) Values() (values interface{}, err error) {
412 defer func() {
413 if state := recover(); state != nil {
414 err = log.Wrap(state.(error))
415 }
416 }()
417
418 if vc.tagType == TypeByte {
419 values, err = vc.ReadBytes()
420 log.PanicIf(err)
421 } else if vc.tagType == TypeAscii {
422 values, err = vc.ReadAscii()
423 log.PanicIf(err)
424 } else if vc.tagType == TypeAsciiNoNul {
425 values, err = vc.ReadAsciiNoNul()
426 log.PanicIf(err)
427 } else if vc.tagType == TypeShort {
428 values, err = vc.ReadShorts()
429 log.PanicIf(err)
430 } else if vc.tagType == TypeLong {
431 values, err = vc.ReadLongs()
432 log.PanicIf(err)
433 } else if vc.tagType == TypeRational {
434 values, err = vc.ReadRationals()
435 log.PanicIf(err)
436 } else if vc.tagType == TypeSignedLong {
437 values, err = vc.ReadSignedLongs()
438 log.PanicIf(err)
439 } else if vc.tagType == TypeSignedRational {
440 values, err = vc.ReadSignedRationals()
441 log.PanicIf(err)
442 } else if vc.tagType == TypeFloat {
443 values, err = vc.ReadFloats()
444 log.PanicIf(err)
445 } else if vc.tagType == TypeDouble {
446 values, err = vc.ReadDoubles()
447 log.PanicIf(err)
448 } else if vc.tagType == TypeUndefined {
449 log.Panicf("will not parse undefined-type value")
450
451
452 return nil, nil
453 } else {
454 log.Panicf("value of type [%s] is unparseable", vc.tagType)
455
456 return nil, nil
457 }
458
459 return values, nil
460 }
461
462 func init() {
463 parser = new(Parser)
464 }
465
View as plain text