exifr 0.9.4 → 0.9.5
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.
- data/CHANGELOG +8 -0
- data/Rakefile +49 -0
- data/bin/exifr +2 -1
- data/lib/exif.rb +12 -10
- data/lib/jpeg.rb +9 -0
- data/tests/data/1x1.jpg +0 -0
- data/tests/data/Canon_PowerShot_A85.exif +0 -0
- data/tests/data/Casio-EX-S20.exif +0 -0
- data/tests/data/FUJIFILM-FinePix_S3000.exif +0 -0
- data/tests/data/Panasonic-DMC-LC33.exif +0 -0
- data/tests/data/Trust-DC3500_MINI.exif +0 -0
- data/tests/data/canon-g3.exif +0 -0
- data/tests/data/exif.jpg +0 -0
- data/tests/data/gps.exif +0 -0
- data/tests/data/image.jpg +0 -0
- data/tests/data/multiple-app1.jpg +0 -0
- data/tests/test_exif.rb +66 -0
- data/tests/test_helper.rb +22 -0
- data/tests/test_jpeg.rb +53 -0
- metadata +19 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
EXIF Reader 0.9.5
|
2
|
+
* patch calls to jpeg through to exif, i.e. jpeg., i.e. jpeg.model == jpeg.exif.model
|
3
|
+
* fix exifr commandline utility, needs require 'exifr' now
|
4
|
+
* improve test helper
|
5
|
+
* reduce size of test images
|
6
|
+
* include tests for tinderbox
|
7
|
+
|
1
8
|
EXIF Reader 0.9.4
|
2
9
|
* bug fix (thanks to Benjamin Storrier for providing me with sample date);
|
3
10
|
multiple app1 frames will potentially overwrite EXIF tag
|
@@ -5,6 +12,7 @@ EXIF Reader 0.9.4
|
|
5
12
|
EXIF Reader 0.9.3
|
6
13
|
* bug fix; "[#4876] Unable to extract gpsinfo"
|
7
14
|
* one-off bug in TiffHeader found and fixed
|
15
|
+
* make "InteroperabilityIndex" available
|
8
16
|
|
9
17
|
EXIF Reader 0.9.2
|
10
18
|
* bug fix; "[#4595] EXIFR::JPEG doesn't support multiple comments", the
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rake/rdoctask'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rcov/rcovtask'
|
5
|
+
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
spec = Gem::Specification.new do |s|
|
9
|
+
s.name = 'exifr'
|
10
|
+
s.version = '0.9.5'
|
11
|
+
s.author = "R.W. van 't Veer"
|
12
|
+
s.email = 'remco@remvee.net'
|
13
|
+
s.homepage = 'http://exifr.rubyforge.org/'
|
14
|
+
s.summary = 'EXIF Reader is a module to read EXIF from JPEG images.'
|
15
|
+
|
16
|
+
s.autorequire = 'exifr'
|
17
|
+
s.files = FileList['Rakefile', '{bin,lib,tests}/**/*'].exclude('rdoc').to_a
|
18
|
+
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.extra_rdoc_files = ['README', 'CHANGELOG']
|
21
|
+
|
22
|
+
s.bindir = 'bin'
|
23
|
+
s.executables = ['exifr']
|
24
|
+
end
|
25
|
+
|
26
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
27
|
+
pkg.need_tar = true
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::RDocTask.new do |rd|
|
31
|
+
rd.title = 'EXIF Reader for Ruby API Documentation'
|
32
|
+
rd.main = "README"
|
33
|
+
rd.rdoc_dir = "doc/api"
|
34
|
+
rd.rdoc_files.include("README", "lib/**/*.rb")
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
Rake::TestTask.new do |t|
|
39
|
+
t.libs << 'lib' << 'tests'
|
40
|
+
t.test_files = FileList['tests/test*.rb']
|
41
|
+
end
|
42
|
+
|
43
|
+
Rcov::RcovTask.new do |t|
|
44
|
+
t.libs << 'lib' << 'tests'
|
45
|
+
t.test_files = FileList['tests/test*.rb']
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'Remove all artifacts left by testing and packaging'
|
49
|
+
task :clean => [:clobber_package, :clobber_rdoc, :clobber_rcov]
|
data/bin/exifr
CHANGED
data/lib/exif.rb
CHANGED
@@ -220,16 +220,13 @@ module EXIFR
|
|
220
220
|
|
221
221
|
# +data+ the content of the JPEG APP1 frame without the EXIF marker
|
222
222
|
def initialize(data)
|
223
|
-
|
224
|
-
|
223
|
+
traverse(data)
|
224
|
+
pull_thumbnail(data)
|
225
225
|
freeze
|
226
226
|
end
|
227
227
|
|
228
|
-
#
|
229
|
-
|
230
|
-
start, length = self[:jpeg_interchange_format], self[:jpeg_interchange_format_length]
|
231
|
-
@data[start..(start + length)] if start && length
|
232
|
-
end
|
228
|
+
# thumbnail, if included
|
229
|
+
attr_reader :thumbnail
|
233
230
|
|
234
231
|
# convience; <tt>self[method]</tt>
|
235
232
|
def method_missing(method, *args)
|
@@ -237,17 +234,22 @@ module EXIFR
|
|
237
234
|
end
|
238
235
|
|
239
236
|
private
|
240
|
-
def traverse(
|
241
|
-
|
237
|
+
def traverse(data, offset = nil, ifd = :exif)
|
238
|
+
TiffHeader.new(data, offset).fields.each do |f|
|
242
239
|
tag = TAGS[ifd][f.tag]
|
243
240
|
value = f.value.map { |v| ADAPTERS[tag][v] } if f.value
|
244
241
|
value = (value.kind_of?(Array) && value.size == 1) ? value.first : value
|
245
242
|
if EXIF_HEADERS.include?(tag)
|
246
|
-
traverse(
|
243
|
+
traverse(data, f.offset, tag)
|
247
244
|
elsif tag
|
248
245
|
self[tag] = value
|
249
246
|
end
|
250
247
|
end
|
251
248
|
end
|
249
|
+
|
250
|
+
def pull_thumbnail(data)
|
251
|
+
start, length = self[:jpeg_interchange_format], self[:jpeg_interchange_format_length]
|
252
|
+
@thumbnail = data[start..(start + length)] if start && length
|
253
|
+
end
|
252
254
|
end
|
253
255
|
end
|
data/lib/jpeg.rb
CHANGED
@@ -35,6 +35,15 @@ module EXIFR
|
|
35
35
|
!exif.nil?
|
36
36
|
end
|
37
37
|
|
38
|
+
# patch through to exif
|
39
|
+
def method_missing(method, *args)
|
40
|
+
if args.empty?
|
41
|
+
exif[method] if exif?
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
38
47
|
private
|
39
48
|
def examine(io)
|
40
49
|
raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI
|
data/tests/data/1x1.jpg
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/tests/data/exif.jpg
ADDED
Binary file
|
data/tests/data/gps.exif
ADDED
Binary file
|
Binary file
|
Binary file
|
data/tests/test_exif.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
4
|
+
|
5
|
+
class TestEXIF < Test::Unit::TestCase
|
6
|
+
def test_initialize
|
7
|
+
[['canon-g3.exif', 'Canon PowerShot G3']].each do |fname,model|
|
8
|
+
data = open(f(fname)) { |rd| rd.read }
|
9
|
+
assert_equal EXIF.new(data).model, model
|
10
|
+
end
|
11
|
+
|
12
|
+
assert_raise RuntimeError, 'no II or MM marker found' do
|
13
|
+
EXIF.new('X' * 100)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_dates
|
18
|
+
all_test_exifs.each do |fname|
|
19
|
+
data = open(fname) { |rd| rd.read }
|
20
|
+
assert_kind_of Time, EXIF.new(data).date_time
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_orientation
|
25
|
+
all_test_exifs.each do |fname|
|
26
|
+
data = open(fname) { |rd| rd.read }
|
27
|
+
orientation = EXIF.new(data).orientation
|
28
|
+
assert_kind_of Module, orientation
|
29
|
+
assert orientation.respond_to?(:to_i)
|
30
|
+
assert orientation.respond_to?(:transform_rmagick)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_thumbnail
|
35
|
+
assert_not_nil JPEG.new(f('exif.jpg')).exif.thumbnail
|
36
|
+
|
37
|
+
all_test_exifs.each do |fname|
|
38
|
+
data = open(fname) { |rd| rd.read }
|
39
|
+
thumbnail = EXIF.new(data).thumbnail
|
40
|
+
assert_nothing_raised do
|
41
|
+
JPEG.new(StringIO.new(thumbnail))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_exif_offset
|
47
|
+
assert JPEG.new(f('exif.jpg')).exif.include?(:exif_version)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_gps
|
51
|
+
data = open(f('gps.exif')){|rd|rd.read}
|
52
|
+
exif = EXIF.new(data)
|
53
|
+
assert exif.include?(:gps_version_id)
|
54
|
+
assert_equal "\2\2\0\0", exif.gps_version_id
|
55
|
+
assert_equal 'N', exif.gps_latitude_ref
|
56
|
+
assert_equal 'W', exif.gps_longitude_ref
|
57
|
+
assert_equal [5355537.quo(100000), 0.quo(1), 0.quo(1)], exif.gps_latitude
|
58
|
+
assert_equal [678886.quo(100000), 0.quo(1), 0.quo(1)], exif.gps_longitude
|
59
|
+
assert_equal 'WGS84', exif.gps_map_datum
|
60
|
+
|
61
|
+
(all_test_exifs - [f('gps.exif')]).each do |fname|
|
62
|
+
data = open(fname) { |rd| rd.read }
|
63
|
+
assert EXIF.new(data).keys.map{|k|k.to_s}.grep(/gps/).empty?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'stringio'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
$:.unshift("#{File.dirname(__FILE__)}/../lib")
|
8
|
+
require 'exifr'
|
9
|
+
include EXIFR
|
10
|
+
|
11
|
+
|
12
|
+
def all_test_images
|
13
|
+
Dir[f('*.jpg')]
|
14
|
+
end
|
15
|
+
|
16
|
+
def all_test_exifs
|
17
|
+
Dir[f('*.exif')]
|
18
|
+
end
|
19
|
+
|
20
|
+
def f(fname)
|
21
|
+
"#{File.dirname(__FILE__)}/data/#{fname}"
|
22
|
+
end
|
data/tests/test_jpeg.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
4
|
+
|
5
|
+
class TestJPEG < Test::Unit::TestCase
|
6
|
+
def test_initialize
|
7
|
+
all_test_images.each do |fname|
|
8
|
+
assert_nothing_raised do
|
9
|
+
JPEG.new(fname)
|
10
|
+
end
|
11
|
+
assert_nothing_raised do
|
12
|
+
open(fname) { |rd| JPEG.new(rd) }
|
13
|
+
end
|
14
|
+
assert_nothing_raised do
|
15
|
+
open(fname) { |rd| JPEG.new(StringIO.new(rd.read)) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_size
|
21
|
+
j = JPEG.new(f('image.jpg'))
|
22
|
+
assert_equal j.width, 100
|
23
|
+
assert_equal j.height, 75
|
24
|
+
|
25
|
+
j = JPEG.new(f('exif.jpg'))
|
26
|
+
assert_equal j.width, 100
|
27
|
+
assert_equal j.height, 75
|
28
|
+
|
29
|
+
j = JPEG.new(f('1x1.jpg'))
|
30
|
+
assert_equal j.width, 1
|
31
|
+
assert_equal j.height, 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_comment
|
35
|
+
assert_equal JPEG.new(f('image.jpg')).comment, "Here's a comment!"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_exif
|
39
|
+
assert ! JPEG.new(f('image.jpg')).exif?
|
40
|
+
assert JPEG.new(f('exif.jpg')).exif?
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_multiple_app1
|
44
|
+
assert JPEG.new(f('multiple-app1.jpg')).exif?
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_patch_through
|
48
|
+
jpeg = JPEG.new(f('exif.jpg'))
|
49
|
+
jpeg.exif.each do |k,v|
|
50
|
+
assert_equal v, jpeg.send(k)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.1
|
3
3
|
specification_version: 1
|
4
4
|
name: exifr
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.
|
7
|
-
date:
|
6
|
+
version: 0.9.5
|
7
|
+
date: 2007-01-31 00:00:00 +01:00
|
8
8
|
summary: EXIF Reader is a module to read EXIF from JPEG images.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,11 +29,27 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- R.W. van 't Veer
|
31
31
|
files:
|
32
|
+
- Rakefile
|
32
33
|
- bin/exifr
|
33
34
|
- lib/exif.rb
|
34
35
|
- lib/exifr.rb
|
35
36
|
- lib/jpeg.rb
|
36
37
|
- lib/tiff_header.rb
|
38
|
+
- tests/data
|
39
|
+
- tests/test_exif.rb
|
40
|
+
- tests/test_helper.rb
|
41
|
+
- tests/test_jpeg.rb
|
42
|
+
- tests/data/1x1.jpg
|
43
|
+
- tests/data/canon-g3.exif
|
44
|
+
- tests/data/Canon_PowerShot_A85.exif
|
45
|
+
- tests/data/Casio-EX-S20.exif
|
46
|
+
- tests/data/exif.jpg
|
47
|
+
- tests/data/FUJIFILM-FinePix_S3000.exif
|
48
|
+
- tests/data/gps.exif
|
49
|
+
- tests/data/image.jpg
|
50
|
+
- tests/data/multiple-app1.jpg
|
51
|
+
- tests/data/Panasonic-DMC-LC33.exif
|
52
|
+
- tests/data/Trust-DC3500_MINI.exif
|
37
53
|
- README
|
38
54
|
- CHANGELOG
|
39
55
|
test_files: []
|