exifr 0.10.7 → 0.10.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/lib/exifr.rb +1 -1
- data/lib/jpeg.rb +9 -2
- data/lib/tiff.rb +61 -17
- data/tests/jpeg_test.rb +13 -1
- data/tests/test_helper.rb +1 -1
- data/tests/tiff_test.rb +6 -2
- metadata +6 -4
data/CHANGELOG
CHANGED
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
data/lib/exifr.rb
CHANGED
data/lib/jpeg.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2006, 2007, 2008 - R.W. van 't Veer
|
1
|
+
# Copyright (c) 2006, 2007, 2008, 2009 - R.W. van 't Veer
|
2
2
|
|
3
3
|
require 'stringio'
|
4
4
|
|
@@ -21,7 +21,7 @@ module EXIFR
|
|
21
21
|
# EXIF data if available
|
22
22
|
attr_reader :exif
|
23
23
|
|
24
|
-
# +file+ is a filename or an IO object.
|
24
|
+
# +file+ is a filename or an IO object. Hint: use StringIO when working with slurped data like blobs.
|
25
25
|
def initialize(file)
|
26
26
|
if file.kind_of? String
|
27
27
|
File.open(file, 'rb') { |io| examine(io) }
|
@@ -40,6 +40,13 @@ module EXIFR
|
|
40
40
|
@exif && @exif.jpeg_thumbnails && @exif.jpeg_thumbnails.first
|
41
41
|
end
|
42
42
|
|
43
|
+
# Get a hash presentation of the image.
|
44
|
+
def to_hash
|
45
|
+
h = {:width => width, :height => height, :bits => bits, :comment => comment}
|
46
|
+
h.merge!(exif) if exif?
|
47
|
+
h
|
48
|
+
end
|
49
|
+
|
43
50
|
# Dispatch to EXIF. When no EXIF data is available but the
|
44
51
|
# +method+ does exist for EXIF data +nil+ will be returned.
|
45
52
|
def method_missing(method, *args)
|
data/lib/tiff.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007, 2008 - R.W. van 't Veer
|
1
|
+
# Copyright (c) 2007, 2008, 2009 - R.W. van 't Veer
|
2
2
|
|
3
3
|
require 'rational'
|
4
4
|
|
@@ -302,21 +302,9 @@ module EXIFR
|
|
302
302
|
# Names for all recognized TIFF fields.
|
303
303
|
TAGS = ([TAG_MAPPING.keys, TAG_MAPPING.values.map{|v|v.values}].flatten.uniq - IFD_TAGS).map{|v|v.to_s}
|
304
304
|
|
305
|
-
# +file+ is a filename or an IO object.
|
305
|
+
# +file+ is a filename or an IO object. Hint: use StringIO when working with slurped data like blobs.
|
306
306
|
def initialize(file)
|
307
|
-
data =
|
308
|
-
|
309
|
-
class << data
|
310
|
-
attr_accessor :short, :long
|
311
|
-
def readshort(pos); self[pos..(pos + 1)].unpack(@short)[0]; end
|
312
|
-
def readlong(pos); self[pos..(pos + 3)].unpack(@long)[0]; end
|
313
|
-
end
|
314
|
-
|
315
|
-
case data[0..1]
|
316
|
-
when 'II'; data.short, data.long = 'v', 'V'
|
317
|
-
when 'MM'; data.short, data.long = 'n', 'N'
|
318
|
-
else; raise 'no II or MM marker found'
|
319
|
-
end
|
307
|
+
data = Data.new(file)
|
320
308
|
|
321
309
|
@ifds = [IFD.new(data)]
|
322
310
|
while ifd = @ifds.last.next
|
@@ -464,8 +452,9 @@ module EXIFR
|
|
464
452
|
|
465
453
|
def initialize(data, pos)
|
466
454
|
@tag, count, @offset = data.readshort(pos), data.readlong(pos + 4), data.readlong(pos + 8)
|
455
|
+
@type = data.readshort(pos + 2)
|
467
456
|
|
468
|
-
case
|
457
|
+
case @type
|
469
458
|
when 1, 6 # byte, signed byte
|
470
459
|
# TODO handle signed bytes
|
471
460
|
len, pack = count, proc { |d| d }
|
@@ -477,6 +466,14 @@ module EXIFR
|
|
477
466
|
when 4, 9 # long, signed long
|
478
467
|
# TODO handle signed
|
479
468
|
len, pack = count * 4, proc { |d| d.unpack(data.long + '*') }
|
469
|
+
when 7 # undefined
|
470
|
+
# UserComment
|
471
|
+
if @tag == 0x9286
|
472
|
+
len, pack = count, proc { |d| d.strip }
|
473
|
+
len -= 8 # reduce to account for first 8 bytes
|
474
|
+
start = len > 4 ? @offset + 8 : (pos + 8) # UserComment first 8-bytes is char code
|
475
|
+
@value = [pack[data[start..(start + len - 1)]]].flatten
|
476
|
+
end
|
480
477
|
when 5, 10
|
481
478
|
len, pack = count * 8, proc do |d|
|
482
479
|
r = []
|
@@ -493,11 +490,58 @@ module EXIFR
|
|
493
490
|
end
|
494
491
|
end
|
495
492
|
|
496
|
-
if len && pack
|
493
|
+
if len && pack && @type != 7
|
497
494
|
start = len > 4 ? @offset : (pos + 8)
|
498
495
|
@value = [pack[data[start..(start + len - 1)]]].flatten
|
499
496
|
end
|
500
497
|
end
|
501
498
|
end
|
499
|
+
|
500
|
+
class Data #:nodoc:
|
501
|
+
attr_reader :short, :long
|
502
|
+
|
503
|
+
def initialize(file)
|
504
|
+
@file = file.respond_to?(:read) ? file : File.open(file, 'rb')
|
505
|
+
@buffer = ''
|
506
|
+
@pos = 0
|
507
|
+
|
508
|
+
case self[0..1]
|
509
|
+
when 'II'; @short, @long = 'v', 'V'
|
510
|
+
when 'MM'; @short, @long = 'n', 'N'
|
511
|
+
else; raise 'no II or MM marker found'
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
def [](pos)
|
516
|
+
unless pos.respond_to?(:begin) && pos.respond_to?(:end)
|
517
|
+
pos = pos..pos
|
518
|
+
end
|
519
|
+
|
520
|
+
if pos.begin < @pos || pos.end >= @pos + @buffer.size
|
521
|
+
read_for(pos)
|
522
|
+
end
|
523
|
+
|
524
|
+
@buffer[(pos.begin - @pos)..(pos.end - @pos)]
|
525
|
+
end
|
526
|
+
|
527
|
+
def readshort(pos)
|
528
|
+
self[pos..(pos + 1)].unpack(@short)[0]
|
529
|
+
end
|
530
|
+
|
531
|
+
def readlong(pos)
|
532
|
+
self[pos..(pos + 3)].unpack(@long)[0]
|
533
|
+
end
|
534
|
+
|
535
|
+
def size
|
536
|
+
@file.seek(0, IO::SEEK_END)
|
537
|
+
@file.pos
|
538
|
+
end
|
539
|
+
|
540
|
+
private
|
541
|
+
def read_for(pos)
|
542
|
+
@file.seek(@pos = pos.begin)
|
543
|
+
@buffer = @file.read([pos.end - pos.begin, 4096].max)
|
544
|
+
end
|
545
|
+
end
|
502
546
|
end
|
503
547
|
end
|
data/tests/jpeg_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#
|
3
|
-
# Copyright (c) 2006, 2007, 2008 - R.W. van 't Veer
|
3
|
+
# Copyright (c) 2006, 2007, 2008, 2009 - R.W. van 't Veer
|
4
4
|
|
5
5
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
6
6
|
|
@@ -44,6 +44,18 @@ class JPEGTest < Test::Unit::TestCase
|
|
44
44
|
assert_not_nil JPEG.new(f('exif.jpg')).exif.f_number
|
45
45
|
end
|
46
46
|
|
47
|
+
def test_to_hash
|
48
|
+
h = JPEG.new(f('image.jpg')).to_hash
|
49
|
+
assert_equal 100, h[:width]
|
50
|
+
assert_equal 75, h[:height]
|
51
|
+
assert_equal "Here's a comment!", h[:comment]
|
52
|
+
|
53
|
+
h = JPEG.new(f('exif.jpg')).to_hash
|
54
|
+
assert_equal 100, h[:width]
|
55
|
+
assert_equal 75, h[:height]
|
56
|
+
assert_kind_of Time, h[:date_time]
|
57
|
+
end
|
58
|
+
|
47
59
|
def test_exif_dispatch
|
48
60
|
j = JPEG.new(f('exif.jpg'))
|
49
61
|
|
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, 2007, 2008 - R.W. van 't Veer
|
3
|
+
# Copyright (c) 2006, 2007, 2008, 2009 - R.W. van 't Veer
|
4
4
|
|
5
5
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
6
6
|
|
@@ -91,7 +91,7 @@ class TIFFTest < Test::Unit::TestCase
|
|
91
91
|
assert_equal [678886.quo(100000), 0.quo(1), 0.quo(1)], t.gps_longitude
|
92
92
|
assert_equal 'WGS84', t.gps_map_datum
|
93
93
|
|
94
|
-
(all_test_exifs - [f('gps.exif')]).each do |fname|
|
94
|
+
(all_test_exifs - [f('gps.exif'), f('user-comment.exif')]).each do |fname|
|
95
95
|
assert_nil TIFF.new(fname).gps_version_id
|
96
96
|
end
|
97
97
|
end
|
@@ -162,4 +162,8 @@ class TIFFTest < Test::Unit::TestCase
|
|
162
162
|
TIFF.new(f('endless-loop.exif'))
|
163
163
|
assert true
|
164
164
|
end
|
165
|
+
|
166
|
+
def test_user_comment
|
167
|
+
assert_equal "Manassas Battlefield", TIFF.new(f('user-comment.exif')).user_comment
|
168
|
+
end
|
165
169
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exifr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- R.W. van 't Veer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-10-01 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -51,6 +51,8 @@ files:
|
|
51
51
|
- CHANGELOG
|
52
52
|
has_rdoc: true
|
53
53
|
homepage: http://github.com/remvee/exifr/
|
54
|
+
licenses: []
|
55
|
+
|
54
56
|
post_install_message:
|
55
57
|
rdoc_options:
|
56
58
|
- --title
|
@@ -74,9 +76,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
76
|
requirements: []
|
75
77
|
|
76
78
|
rubyforge_project:
|
77
|
-
rubygems_version: 1.
|
79
|
+
rubygems_version: 1.3.4
|
78
80
|
signing_key:
|
79
|
-
specification_version:
|
81
|
+
specification_version: 3
|
80
82
|
summary: EXIF Reader is a module to read EXIF from JPEG images.
|
81
83
|
test_files: []
|
82
84
|
|