exifr 1.3.4 → 1.3.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 761b2bd6bc3860282c9ccb81711700387f6c5ff9921c27bc1a5788b73d56a644
4
- data.tar.gz: a23be2354eb6a013b68b1b04356d1dd7a1c89adafb115dee7df69ed56d3e30c3
3
+ metadata.gz: 91531cf59588956e8b9675148197cdca2b8bcbe35edb42476bfe56f73959470b
4
+ data.tar.gz: ddd951e6773d11ce0a0db5214983774b8078e410451920cc441fdd55926c574e
5
5
  SHA512:
6
- metadata.gz: 4162bf20d1ccf018cbdd007a8ba9ec2d5144171d2f6a76e737066dd73fac6476638232b62d4deabfb06d27bf56a19c2fc59362e7f3bf5e06b3bef0ceb02c3f99
7
- data.tar.gz: 4992021fb7dbb28501e9c913fc54b0a3a3eaf58fca79c3303a6596c78b1c4daabcacd686ae44074470f491d42900c3250003f1059e5aa4b7192f71ed212352b4
6
+ metadata.gz: a8ebe84816409a77d19b67d1ac8a244ef63bd3a8046e08f7193e40f8bb01c2866320aa52a3664a43ed07dc6d30c2f17005d33d2408e69574987b2e5127425b0a
7
+ data.tar.gz: 296a144056ee9da865e663c9ef47dfc59811e24485c133a28a2b6978b62b37f7e8419a6c76e6e6aaacb52a03b599f04e18a9715e287f89c9fbff9fbac67a2c63
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
  gemspec
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2006-2017 - R.W. van 't Veer
1
+ # Copyright (c) 2006-2020 - R.W. van 't Veer
2
2
 
3
3
  require 'rake/testtask'
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2006-2017 - R.W. van 't Veer
1
+ # Copyright (c) 2006-2020 - R.W. van 't Veer
2
2
 
3
3
  require 'logger'
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2006-2017 - R.W. van 't Veer
1
+ # Copyright (c) 2006-2020 - R.W. van 't Veer
2
2
 
3
3
  require 'exifr'
4
4
  require 'exifr/tiff'
@@ -237,6 +237,7 @@ module EXIFR
237
237
  0x001c => :gps_area_information,
238
238
  0x001d => :gps_date_stamp,
239
239
  0x001e => :gps_differential,
240
+ 0x001f => :gps_h_positioning_error
240
241
  },
241
242
  })
242
243
  IFD_TAGS = [:image, :exif, :gps] # :nodoc:
@@ -249,9 +250,9 @@ module EXIFR
249
250
 
250
251
  time_proc = proc do |value|
251
252
  value.map do |v|
252
- if v =~ /^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/
253
+ if v =~ /^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)(?:\.(\d{3}))?$/
253
254
  begin
254
- mktime_proc.call($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i)
255
+ mktime_proc.call($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, $7.to_i * 1000)
255
256
  rescue => ex
256
257
  EXIFR.logger.warn("Bad date/time value #{v.inspect}: #{ex}")
257
258
  nil
@@ -330,7 +331,9 @@ module EXIFR
330
331
 
331
332
  class Degrees < Array
332
333
  def initialize(arr)
333
- raise "expected [degrees, minutes, seconds]" unless arr.length == 3
334
+ unless arr.length == 3 && arr.all?{|v| Rational === v}
335
+ raise "expected [degrees, minutes, seconds]; got #{arr.inspect}"
336
+ end
334
337
  super
335
338
  end
336
339
 
@@ -383,7 +386,12 @@ module EXIFR
383
386
  @jpeg_thumbnails = @ifds.map do |v|
384
387
  if v.jpeg_interchange_format && v.jpeg_interchange_format_length
385
388
  start, length = v.jpeg_interchange_format, v.jpeg_interchange_format_length
386
- data[start..(start + length)]
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
387
395
  end
388
396
  end.compact
389
397
  end
@@ -481,17 +489,19 @@ module EXIFR
481
489
 
482
490
  pos = offset || @data.readlong(4)
483
491
  num = @data.readshort(pos)
484
- pos += 2
485
492
 
486
- num.times do
487
- add_field(Field.new(@data, pos))
488
- pos += 12
489
- end
493
+ if pos && num
494
+ pos += 2
490
495
 
491
- @offset_next = @data.readlong(pos)
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
492
503
  rescue => ex
493
504
  EXIFR.logger.warn("Badly formed IFD: #{ex}")
494
- @offset_next = 0
495
505
  end
496
506
 
497
507
  def method_missing(method, *args)
@@ -519,7 +529,7 @@ module EXIFR
519
529
  end
520
530
 
521
531
  def next?
522
- @offset_next != 0 && @offset_next < @data.size
532
+ @offset_next && @offset_next > 0 && @offset_next < @data.size
523
533
  end
524
534
 
525
535
  def next
@@ -594,6 +604,8 @@ module EXIFR
594
604
  end
595
605
  rationals
596
606
  end
607
+ else
608
+ return
597
609
  end
598
610
 
599
611
  if len && pack && @type != 7
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (c) 2006-2017 - R.W. van 't Veer
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
- refute j.methods(false).include?(:date_time)
110
+ assert ! j.methods(false).include?(:date_time)
111
111
  end
112
112
 
113
113
  def test_multiple_app1
@@ -133,4 +133,22 @@ class JPEGTest < TestCase
133
133
  assert_equal([Rational(230, 1), Rational(0, 1), Rational(0, 1)], t.gps_altitude)
134
134
  assert_equal(230, t.gps.altitude)
135
135
  end
136
+
137
+ def test_exif_datetime_milliseconds
138
+ if Time.now.strftime('%L') == '%L'
139
+ STDERR.puts("skipping milliseconds test; not supported on this platform")
140
+ return
141
+ end
142
+
143
+ j = JPEG.new(f('exif.jpg'))
144
+ assert_equal('000', j.date_time.strftime('%L'))
145
+ assert_equal('000', j.date_time_original.strftime('%L'))
146
+ assert_equal('000', j.date_time_digitized.strftime('%L'))
147
+
148
+ j = JPEG.new(f('ios-mspix-milliseconds.jpg'))
149
+ assert_equal('978', j.date_time.strftime('%L'))
150
+ assert_equal('978', j.date_time_original.strftime('%L'))
151
+ assert_equal('978', j.date_time_digitized.strftime('%L'))
152
+ end
153
+
136
154
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (c) 2006-2017 - R.W. van 't Veer
3
+ # Copyright (c) 2006-2020 - R.W. van 't Veer
4
4
 
5
5
  require 'stringio'
6
6
  require 'pp'
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (c) 2006-2017 - R.W. van 't Veer
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)
@@ -184,6 +188,11 @@ class TIFFTest < TestCase
184
188
  assert true
185
189
  end
186
190
 
191
+ def test_should_read_truncated
192
+ TIFF.new(f('truncated.exif'))
193
+ assert true
194
+ end
195
+
187
196
  def test_user_comment
188
197
  assert_equal("Manassas Battlefield", TIFF.new(f('user-comment.exif')).user_comment)
189
198
  end
@@ -204,6 +213,6 @@ class TIFFTest < TestCase
204
213
  t = TIFF.new(f('gopro_hd2.exif'))
205
214
  assert t.methods.include?(:make)
206
215
  assert t.methods(true).include?(:make)
207
- refute t.methods(false).include?(:make)
216
+ assert ! t.methods(false).include?(:make)
208
217
  end
209
218
  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
4
+ version: 1.3.9
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: 2018-05-07 00:00:00.000000000 Z
11
+ date: 2020-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -30,26 +30,22 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10'
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: '10'
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:
44
44
  - exifr
45
45
  extensions: []
46
- extra_rdoc_files:
47
- - README.rdoc
48
- - CHANGELOG
46
+ extra_rdoc_files: []
49
47
  files:
50
- - CHANGELOG
51
48
  - Gemfile
52
- - README.rdoc
53
49
  - Rakefile
54
50
  - bin/exifr
55
51
  - lib/exifr.rb
@@ -85,13 +81,14 @@ files:
85
81
  homepage: http://github.com/remvee/exifr/
86
82
  licenses:
87
83
  - MIT
88
- metadata: {}
89
- post_install_message:
90
- rdoc_options:
91
- - "--title"
92
- - EXIF Reader for Ruby API Documentation
93
- - "--main"
94
- - README.rdoc
84
+ metadata:
85
+ bug_tracker_uri: https://github.com/remvee/exifr/issues
86
+ changelog_uri: https://github.com/remvee/exifr/blob/master/CHANGELOG
87
+ documentation_uri: https://remvee.github.io/exifr/api/
88
+ homepage_uri: https://remvee.github.io/exifr/
89
+ source_code_uri: https://github.com/remvee/exifr
90
+ post_install_message:
91
+ rdoc_options: []
95
92
  require_paths:
96
93
  - lib
97
94
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -105,9 +102,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
102
  - !ruby/object:Gem::Version
106
103
  version: '0'
107
104
  requirements: []
108
- rubyforge_project:
109
- rubygems_version: 2.7.6
110
- signing_key:
105
+ rubygems_version: 3.1.4
106
+ signing_key:
111
107
  specification_version: 4
112
108
  summary: Read EXIF from JPEG and TIFF images
113
109
  test_files: []
data/CHANGELOG DELETED
@@ -1,151 +0,0 @@
1
- EXIF Reader 1.3.4
2
- * bug fix; "Modernize #methods method signatures for delegate.rb"; thanks Julik Tarkhanov
3
-
4
- EXIF Reader 1.3.3
5
- * bug fix; "Using first gps altitude value in case 'gps_altitude' is an Array"; thanks Antonio Marques
6
-
7
- EXIF Reader 1.3.2
8
- * enhancement; "Add EXIF 2.3 lens information tags"; thanks Clay Gregory
9
-
10
- EXIF Reader 1.3.1
11
- * fix executable bin/exifr
12
-
13
- EXIF Reader 1.3.0
14
- * workaround warnings when using the ruby "-w" option
15
- * NOTE: requiring only 'exifr' will nolonger provide EXIFR::JPEG or EXIFR::TIFF, require 'exifr/jpeg' or 'exifr/tiff' instead
16
-
17
- EXIF Reader 1.2.6
18
- * bug fix; "[GH#48] handle empty file as malformed jpeg"; thanks Hoàng Xuân Phú
19
-
20
- EXIF Reader 1.2.5
21
- * bug fix; "[GH#46] Having stringified methods is not a good idea"; thanks Filipe Costa
22
- * bug fix; "Fix typo in subsec_time_original key"; thanks Filipe Costa
23
-
24
- EXIF Reader 1.2.4
25
- * bug fix; "[GH#43] Fix `respond_to?` signature"; thanks Pete Johns
26
-
27
- EXIF Reader 1.2.3.1
28
- * bug fix; "[GH#41] gopro_hd2.exif is not included in the gem"; thanks Peter Wilmott
29
-
30
- EXIF Reader 1.2.3
31
- * bug fix; "[GH#40] Handle NUL-terminated ASCII strings"; thanks Malte Rohde
32
-
33
- EXIF Reader 1.2.2
34
- * bug fix; "use Reader delegator instead of adding method to File instance"; thanks Ivan Kuchin
35
-
36
- EXIF Reader 1.2.1
37
- * bug fix: Value of infinity yields division by zero error
38
-
39
- EXIF Reader 1.2.0
40
- * enhancement; "log warnings when EXIF data is malformed"
41
- * enhancement; "allow alternative Time adapter"
42
- * enhancement; "[GH#33] add reader for orientation type"; thanks Damir Svrtan
43
-
44
- EXIF Reader 1.1.3
45
- * bug fix; "[GH#27] some error when :shutter_speed_value is too big"; thanks to zamia
46
-
47
- EXIF Reader 1.1.2
48
- * bug fix; "[GH#25] Incorrect values being extracted for a number of fields"; thanks to Matthew McEachen
49
-
50
- EXIF Reader 1.1.1
51
- * feature; "added gps convenience method to make accessing location data easier (degrees to float conversion)"
52
- * bug fix; "[GH#22] Fix warnings about uninitialized @comment"; thanks to Ryan Greenberg"
53
-
54
- EXIF Reader 1.0.6
55
- * bug fix: "[GH#20] `readlong': undefined method `unpack' for nil:NilClass (NoMethodError)"
56
-
57
- EXIF Reader 1.0.5
58
- * bug fix: "[GH#19] files opened by TIFF initialize were not being closed"; thanks to Joe Van Overberghe
59
-
60
- EXIF Reader 1.0.4
61
- * bug fix: "[GH#17] avoid library search path pollution"
62
- * enhancement: "[GH#18] add EXIFR::JPEG#app1s method"
63
-
64
- EXIF Reader 1.0.3
65
- * enhancement; "raise specific exception to allow better error handling"; thanks to James Miller
66
-
67
- EXIF Reader 1.0.2
68
- * bug fix; "[GH#9/12] no block given"; thanks to Ian Leitch
69
-
70
- EXIF Reader 1.0.1
71
- * bug fix; "[GH#7] Unable to properly display exposure_bias_value"; thanks to John Krueger
72
-
73
- EXIF Reader 1.0.0
74
- * bug fix; "ArgumentError: invalid byte sequence in UTF-8" when reading messy field using Ruby 1.9+
75
- * enhancement; "[GH#4] more informative inspect for EXIFR::TIFF::Orientation instance"
76
- * bug fix; "[GH#6] ERROR RuntimeError: can't add a new key into hash during iteration"; thanks to KISHIMOTO, Makoto
77
-
78
- EXIF Reader 0.10.9
79
- * bug fix; "[GH#1] user_comment returns nil for jpeg with UserComment"; thanks to Mark Lundquist
80
- * bug fix; "[GH#2] Nil pointer in tiff.rb"
81
- * enhancement; "don't read entire files into memory"; thanks to Victor Bogado
82
-
83
- EXIF Reader 0.10.8
84
- * feature request; "[#23694] The object interface of JPEG is different from the TIFF one."
85
-
86
- EXIF Reader 0.10.7
87
- * bug fix; "[#22403] Wrong file size reported"
88
-
89
- EXIF Reader 0.10.6.1
90
- * moved to GitHub
91
-
92
- EXIF Reader 0.10.6
93
- * bug fix (thanks to Forian Munz for reporting it); endless loop when reading a malformed EXIF/TIFF
94
-
95
- EXIF Reader 0.10.5
96
- * bug fix; "[#15421] duplicate orientation field behavior", first field (of any type) is leading now
97
- * Ruby 1.9 compatible
98
-
99
- EXIF Reader 0.10.4
100
- * Thumbnail extraction; [#15317] Please add thumbnail extraction
101
-
102
- EXIF Reader 0.10.3
103
- * YAML friendly; can now safely (de)serialize
104
-
105
- EXIF Reader 0.10.2
106
- * bug fix (thanks to Alexander Staubo for providing me with sample data);
107
- don't fail on out-of-range IFD offsets for Apple Aperture generated JPGs
108
-
109
- EXIF Reader 0.10.1
110
- * old style exif access
111
-
112
- EXIF Reader 0.10
113
- * TIFF support
114
-
115
- EXIF Reader 0.9.6
116
- * bug fix; "[#8458] Conversion from string to Time fails", weird dates will now reflect nil
117
-
118
- EXIF Reader 0.9.5.1
119
- * make tinderbox happy by hiding rcov task
120
-
121
- EXIF Reader 0.9.5
122
- * patch calls to jpeg through to exif, i.e. jpeg., i.e. jpeg.model == jpeg.exif.model
123
- * fix exifr commandline utility, needs require 'exifr' now
124
- * improve test helper
125
- * reduce size of test images
126
- * include tests for tinderbox
127
-
128
- EXIF Reader 0.9.4
129
- * bug fix (thanks to Benjamin Storrier for providing me with sample date);
130
- multiple app1 frames will potentially overwrite EXIF tag
131
-
132
- EXIF Reader 0.9.3
133
- * bug fix; "[#4876] Unable to extract gpsinfo"
134
- * one-off bug in TiffHeader found and fixed
135
- * make "InteroperabilityIndex" available
136
-
137
- EXIF Reader 0.9.2
138
- * bug fix; "[#4595] EXIFR::JPEG doesn't support multiple comments", the
139
- comment property of a JPEG object now contains an array instead of a string
140
- when multiple COM frames are found
141
- * EXIF orientation modules including RMagick code to rotate to viewable state
142
- * access to thumbnail included in EXIF
143
- * simple commandline utility, "exifr", to view image properties
144
- * overall code improvements including documentation and tests
145
-
146
- EXIF Reader 0.9.1
147
- * bug fix; "4321 Can't create object", division by zero when
148
- denominator of rational value is zero
149
-
150
- EXIF Reader 0.9
151
- * 1st release
@@ -1,62 +0,0 @@
1
- = EXIF Reader
2
- {<img src="https://badge.fury.io/rb/exifr.svg" alt="Gem Version" />}[https://badge.fury.io/rb/exifr]
3
- {<img src="https://circleci.com/gh/remvee/exifr/tree/master.svg?style=shield&circle-token=7d957be2d7195f5d07a7c1962926ee626b050c2e" alt="Circle CI" />}[https://circleci.com/gh/remvee/exifr]
4
-
5
- EXIF Reader is a module to read metadata from JPEG and TIFF images.
6
-
7
- == Examples
8
- require 'exifr/jpeg'
9
- EXIFR::JPEG.new('IMG_6841.JPG').width # => 2272
10
- EXIFR::JPEG.new('IMG_6841.JPG').height # => 1704
11
- EXIFR::JPEG.new('IMG_6841.JPG').exif? # => true
12
- EXIFR::JPEG.new('IMG_6841.JPG').model # => "Canon PowerShot G3"
13
- EXIFR::JPEG.new('IMG_6841.JPG').date_time # => Fri Feb 09 16:48:54 +0100 2007
14
- EXIFR::JPEG.new('IMG_6841.JPG').exposure_time.to_s # => "1/15"
15
- EXIFR::JPEG.new('IMG_6841.JPG').f_number.to_f # => 2.0
16
- EXIFR::JPEG.new('enkhuizen.jpg').gps.latitude # => 52.7197888888889
17
- EXIFR::JPEG.new('enkhuizen.jpg').gps.longitude # => 5.28397777777778
18
-
19
- require 'exifr/tiff'
20
- EXIFR::TIFF.new('DSC_0218.TIF').width # => 3008
21
- EXIFR::TIFF.new('DSC_0218.TIF')[1].width # => 160
22
- EXIFR::TIFF.new('DSC_0218.TIF').model # => "NIKON D1X"
23
- EXIFR::TIFF.new('DSC_0218.TIF').date_time # => Tue May 23 19:15:32 +0200 2006
24
- EXIFR::TIFF.new('DSC_0218.TIF').exposure_time.to_s # => "1/100"
25
- EXIFR::TIFF.new('DSC_0218.TIF').f_number.to_f # => 5.0
26
-
27
- == Logging warnings
28
- When EXIF information is malformed, a warning is logged to STDERR with
29
- the standard Ruby logger. Log to some other location by supplying an
30
- alternative implementation:
31
-
32
- EXIFR.logger = SyslogLogger.new
33
-
34
- == Time zone support
35
- EXIF does not support time zones so this code does not support time
36
- zones. All time stamps are created in the local time zone with:
37
-
38
- Time.local(..)
39
-
40
- It is possible to change this behavior by supplying an alternative
41
- implementation. For those who prefer UTC:
42
-
43
- EXIFR::TIFF.mktime_proc = proc{|*args| Time.utc(*args)}
44
-
45
- Or when the application depends on ActiveSupport for time zone handling:
46
-
47
- EXIFR::TIFF.mktime_proc = proc{|*args| Time.zone.local(*args)}
48
-
49
- == XMP data access
50
- If you need to access XMP data you can use the xmp gem. More info and
51
- examples at https://github.com/amberbit/xmp
52
-
53
- == Development and running tests
54
-
55
- On a fresh checkout of the repository, run `bundle install` and then
56
- `bundle exec rake test`
57
-
58
- == Author
59
- R.W. van 't Veer
60
-
61
- == Copyright
62
- Copyright (c) 2006-2017 - R.W. van 't Veer