exifr 0.10.7 → 0.10.8
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 +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
|
|