exifr 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|