exifr 1.3.6 → 1.3.10
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/Gemfile +1 -1
- data/Rakefile +1 -1
- data/lib/exifr/jpeg.rb +1 -1
- data/lib/exifr/tiff.rb +39 -23
- data/lib/exifr.rb +1 -1
- data/tests/data/bad_gps.exif +0 -0
- data/tests/data/ios-mspix-milliseconds.jpg +0 -0
- data/tests/data/truncated.exif +0 -0
- data/tests/jpeg_test.rb +2 -2
- data/tests/test_helper.rb +1 -1
- data/tests/tiff_test.rb +22 -4
- metadata +17 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97fa3270a4d14398a02e6bd725753980ae12b74c2f0a6e3c160b840c59c7febf
|
|
4
|
+
data.tar.gz: ec8ed547c94ad6dd83c0a07bb78530408d48637b18edfeb68dcb157a55c5c618
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d10126d25f29634c46c8b5dce11ebd9dbc373c02fc892a74cdb8cbf6aa3cef8086e2a6be2eaac2a65bc83fa64a6f517617e22dc47bc4ea56db631b678a3ee3a
|
|
7
|
+
data.tar.gz: b98ee638dc85ab51c1f86d5b9c34c417047a79d2abb920ee8a13e7decfaf8b66fb484d7d804461de276a3f87fd40f5e30c1a420e3b25e46db51e801f77acc9c3
|
data/Gemfile
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
source
|
|
1
|
+
source "https://rubygems.org"
|
|
2
2
|
gemspec
|
data/Rakefile
CHANGED
data/lib/exifr/jpeg.rb
CHANGED
data/lib/exifr/tiff.rb
CHANGED
|
@@ -331,7 +331,9 @@ module EXIFR
|
|
|
331
331
|
|
|
332
332
|
class Degrees < Array
|
|
333
333
|
def initialize(arr)
|
|
334
|
-
|
|
334
|
+
unless arr.length == 3 && arr.all?{|v| Rational === v}
|
|
335
|
+
raise "expected [degrees, minutes, seconds]; got #{arr.inspect}"
|
|
336
|
+
end
|
|
335
337
|
super
|
|
336
338
|
end
|
|
337
339
|
|
|
@@ -384,7 +386,12 @@ module EXIFR
|
|
|
384
386
|
@jpeg_thumbnails = @ifds.map do |v|
|
|
385
387
|
if v.jpeg_interchange_format && v.jpeg_interchange_format_length
|
|
386
388
|
start, length = v.jpeg_interchange_format, v.jpeg_interchange_format_length
|
|
387
|
-
|
|
389
|
+
if Integer === start && Integer === length
|
|
390
|
+
data[start..(start + length)]
|
|
391
|
+
else
|
|
392
|
+
EXIFR.logger.warn("Non numeric JpegInterchangeFormat data")
|
|
393
|
+
nil
|
|
394
|
+
end
|
|
388
395
|
end
|
|
389
396
|
end.compact
|
|
390
397
|
end
|
|
@@ -475,24 +482,26 @@ module EXIFR
|
|
|
475
482
|
end
|
|
476
483
|
|
|
477
484
|
class IFD # :nodoc:
|
|
478
|
-
attr_reader :type, :fields, :offset
|
|
485
|
+
attr_reader :type, :raw_fields, :fields, :offset
|
|
479
486
|
|
|
480
487
|
def initialize(data, offset = nil, type = :image)
|
|
481
|
-
@data, @offset, @type, @fields = data, offset, type, {}
|
|
488
|
+
@data, @offset, @type, @raw_fields, @fields = data, offset, type, {}, {}
|
|
482
489
|
|
|
483
490
|
pos = offset || @data.readlong(4)
|
|
484
491
|
num = @data.readshort(pos)
|
|
485
|
-
pos += 2
|
|
486
492
|
|
|
487
|
-
num
|
|
488
|
-
|
|
489
|
-
pos += 12
|
|
490
|
-
end
|
|
493
|
+
if pos && num
|
|
494
|
+
pos += 2
|
|
491
495
|
|
|
492
|
-
|
|
496
|
+
num.times do
|
|
497
|
+
add_field(Field.new(@data, pos))
|
|
498
|
+
pos += 12
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
@offset_next = @data.readlong(pos)
|
|
502
|
+
end
|
|
493
503
|
rescue => ex
|
|
494
504
|
EXIFR.logger.warn("Badly formed IFD: #{ex}")
|
|
495
|
-
@offset_next = 0
|
|
496
505
|
end
|
|
497
506
|
|
|
498
507
|
def method_missing(method, *args)
|
|
@@ -520,7 +529,7 @@ module EXIFR
|
|
|
520
529
|
end
|
|
521
530
|
|
|
522
531
|
def next?
|
|
523
|
-
@offset_next
|
|
532
|
+
@offset_next && @offset_next > 0 && @offset_next < @data.size
|
|
524
533
|
end
|
|
525
534
|
|
|
526
535
|
def next
|
|
@@ -537,15 +546,16 @@ module EXIFR
|
|
|
537
546
|
|
|
538
547
|
private
|
|
539
548
|
def add_field(field)
|
|
540
|
-
return
|
|
541
|
-
|
|
549
|
+
return if @raw_fields.include?(field.tag) # first encountered value wins
|
|
550
|
+
@raw_fields[field.tag] = field.value
|
|
542
551
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
552
|
+
return unless tag = TAG_MAPPING[@type][field.tag]
|
|
553
|
+
@fields[tag] = if IFD_TAGS.include?(tag)
|
|
554
|
+
IFD.new(@data, field.offset, tag)
|
|
555
|
+
else
|
|
556
|
+
value = ADAPTERS[tag][field.value]
|
|
557
|
+
value.kind_of?(Array) && value.size == 1 ? value.first : value
|
|
558
|
+
end
|
|
549
559
|
end
|
|
550
560
|
end
|
|
551
561
|
|
|
@@ -595,6 +605,12 @@ module EXIFR
|
|
|
595
605
|
end
|
|
596
606
|
rationals
|
|
597
607
|
end
|
|
608
|
+
when 11 # float
|
|
609
|
+
len, pack = count * 4, proc { |d| d.unpack(data.float + '*') }
|
|
610
|
+
when 12 # double
|
|
611
|
+
len, pack = count * 8, proc { |d| d.unpack(data.double + '*') }
|
|
612
|
+
else
|
|
613
|
+
return
|
|
598
614
|
end
|
|
599
615
|
|
|
600
616
|
if len && pack && @type != 7
|
|
@@ -627,7 +643,7 @@ module EXIFR
|
|
|
627
643
|
end
|
|
628
644
|
|
|
629
645
|
class Data #:nodoc:
|
|
630
|
-
attr_reader :short, :long, :file
|
|
646
|
+
attr_reader :short, :long, :float, :double, :file
|
|
631
647
|
|
|
632
648
|
def initialize(file)
|
|
633
649
|
@io = file.respond_to?(:read) ? file : (@file = File.open(file, 'rb'))
|
|
@@ -635,8 +651,8 @@ module EXIFR
|
|
|
635
651
|
@pos = 0
|
|
636
652
|
|
|
637
653
|
case self[0..1]
|
|
638
|
-
when 'II'; @short, @long = 'v', 'V'
|
|
639
|
-
when 'MM'; @short, @long = 'n', 'N'
|
|
654
|
+
when 'II'; @short, @long, @float, @double = 'v', 'V', 'e', 'E'
|
|
655
|
+
when 'MM'; @short, @long, @float, @double = 'n', 'N', 'g', 'G'
|
|
640
656
|
else
|
|
641
657
|
raise MalformedTIFF, "no byte order information found"
|
|
642
658
|
end
|
data/lib/exifr.rb
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/tests/jpeg_test.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
#
|
|
3
|
-
# Copyright (c) 2006-
|
|
3
|
+
# Copyright (c) 2006-2020 - R.W. van 't Veer
|
|
4
4
|
|
|
5
5
|
require 'test_helper'
|
|
6
6
|
|
|
@@ -107,7 +107,7 @@ class JPEGTest < TestCase
|
|
|
107
107
|
j = JPEG.new(f('exif.jpg'))
|
|
108
108
|
assert j.methods.include?(:date_time)
|
|
109
109
|
assert j.methods(true).include?(:date_time)
|
|
110
|
-
|
|
110
|
+
assert ! j.methods(false).include?(:date_time)
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
def test_multiple_app1
|
data/tests/test_helper.rb
CHANGED
data/tests/tiff_test.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
#
|
|
3
|
-
# Copyright (c) 2006-
|
|
3
|
+
# Copyright (c) 2006-2020 - R.W. van 't Veer
|
|
4
4
|
|
|
5
5
|
require 'test_helper'
|
|
6
6
|
|
|
@@ -55,7 +55,7 @@ class TIFFTest < TestCase
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def test_dates
|
|
58
|
-
(all_test_tiffs - [f('weird_date.exif'), f('plain.tif'), f('endless-loop.exif')]).each do |fname|
|
|
58
|
+
(all_test_tiffs - [f('weird_date.exif'), f('plain.tif'), f('endless-loop.exif'), f('truncated.exif')]).each do |fname|
|
|
59
59
|
assert_kind_of Time, TIFF.new(fname).date_time
|
|
60
60
|
end
|
|
61
61
|
assert_nil TIFF.new(f('weird_date.exif')).date_time
|
|
@@ -119,6 +119,10 @@ class TIFFTest < TestCase
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
def test_bad_gps
|
|
123
|
+
assert_nil TIFF.new(f('bad_gps.exif')).gps
|
|
124
|
+
end
|
|
125
|
+
|
|
122
126
|
def test_lens_model
|
|
123
127
|
t = TIFF.new(f('sony-a7ii.exif'))
|
|
124
128
|
assert_equal('FE 16-35mm F4 ZA OSS', t.lens_model)
|
|
@@ -161,7 +165,12 @@ class TIFFTest < TestCase
|
|
|
161
165
|
all_test_tiffs.each do |fname|
|
|
162
166
|
t = TIFF.new(fname)
|
|
163
167
|
y = YAML.dump(t)
|
|
164
|
-
|
|
168
|
+
v = if YAML.respond_to?(:unsafe_load)
|
|
169
|
+
YAML.unsafe_load(y)
|
|
170
|
+
else
|
|
171
|
+
YAML.load(y)
|
|
172
|
+
end
|
|
173
|
+
assert_literally_equal t.to_hash, v.to_hash
|
|
165
174
|
end
|
|
166
175
|
end
|
|
167
176
|
|
|
@@ -184,6 +193,11 @@ class TIFFTest < TestCase
|
|
|
184
193
|
assert true
|
|
185
194
|
end
|
|
186
195
|
|
|
196
|
+
def test_should_read_truncated
|
|
197
|
+
TIFF.new(f('truncated.exif'))
|
|
198
|
+
assert true
|
|
199
|
+
end
|
|
200
|
+
|
|
187
201
|
def test_user_comment
|
|
188
202
|
assert_equal("Manassas Battlefield", TIFF.new(f('user-comment.exif')).user_comment)
|
|
189
203
|
end
|
|
@@ -204,6 +218,10 @@ class TIFFTest < TestCase
|
|
|
204
218
|
t = TIFF.new(f('gopro_hd2.exif'))
|
|
205
219
|
assert t.methods.include?(:make)
|
|
206
220
|
assert t.methods(true).include?(:make)
|
|
207
|
-
|
|
221
|
+
assert ! t.methods(false).include?(:make)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def test_unknow_field
|
|
225
|
+
assert_equal [1, 1, 1, 1], TIFF.new(f('plain.tif')).first.raw_fields[0x0153] # TIFF Tag SampleFormat
|
|
208
226
|
end
|
|
209
227
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: exifr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- R.W. van 't Veer
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-10-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: test-unit
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '12'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '12'
|
|
41
41
|
description: EXIF Reader is a module to read EXIF from JPEG and TIFF images.
|
|
42
42
|
email: exifr@remworks.net
|
|
43
43
|
executables:
|
|
@@ -59,6 +59,7 @@ files:
|
|
|
59
59
|
- tests/data/Trust-DC3500_MINI.exif
|
|
60
60
|
- tests/data/apple-aperture-1.5.exif
|
|
61
61
|
- tests/data/bad-shutter_speed_value.exif
|
|
62
|
+
- tests/data/bad_gps.exif
|
|
62
63
|
- tests/data/canon-g3.exif
|
|
63
64
|
- tests/data/endless-loop.exif
|
|
64
65
|
- tests/data/exif.jpg
|
|
@@ -66,6 +67,7 @@ files:
|
|
|
66
67
|
- tests/data/gps-altitude.jpg
|
|
67
68
|
- tests/data/gps.exif
|
|
68
69
|
- tests/data/image.jpg
|
|
70
|
+
- tests/data/ios-mspix-milliseconds.jpg
|
|
69
71
|
- tests/data/multiple-app1.jpg
|
|
70
72
|
- tests/data/negative-exposure-bias-value.exif
|
|
71
73
|
- tests/data/nikon_d1x.tif
|
|
@@ -73,6 +75,7 @@ files:
|
|
|
73
75
|
- tests/data/plain.tif
|
|
74
76
|
- tests/data/samsung-sc-02b.jpg
|
|
75
77
|
- tests/data/sony-a7ii.exif
|
|
78
|
+
- tests/data/truncated.exif
|
|
76
79
|
- tests/data/user-comment.exif
|
|
77
80
|
- tests/data/weird_date.exif
|
|
78
81
|
- tests/jpeg_test.rb
|
|
@@ -81,8 +84,13 @@ files:
|
|
|
81
84
|
homepage: http://github.com/remvee/exifr/
|
|
82
85
|
licenses:
|
|
83
86
|
- MIT
|
|
84
|
-
metadata:
|
|
85
|
-
|
|
87
|
+
metadata:
|
|
88
|
+
bug_tracker_uri: https://github.com/remvee/exifr/issues
|
|
89
|
+
changelog_uri: https://github.com/remvee/exifr/blob/master/CHANGELOG
|
|
90
|
+
documentation_uri: https://remvee.github.io/exifr/api/
|
|
91
|
+
homepage_uri: https://remvee.github.io/exifr/
|
|
92
|
+
source_code_uri: https://github.com/remvee/exifr
|
|
93
|
+
post_install_message:
|
|
86
94
|
rdoc_options: []
|
|
87
95
|
require_paths:
|
|
88
96
|
- lib
|
|
@@ -97,9 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
97
105
|
- !ruby/object:Gem::Version
|
|
98
106
|
version: '0'
|
|
99
107
|
requirements: []
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
signing_key:
|
|
108
|
+
rubygems_version: 3.3.7
|
|
109
|
+
signing_key:
|
|
103
110
|
specification_version: 4
|
|
104
111
|
summary: Read EXIF from JPEG and TIFF images
|
|
105
112
|
test_files: []
|