lib/tiff.rb in exifr-0.10.2 vs lib/tiff.rb in exifr-0.10.3
- old
+ new
@@ -10,32 +10,32 @@
# <tt>:date_time_digitized</tt> coerced into Time objects.
#
# == Orientation
# The property <tt>:orientation</tt> describes the subject rotated and/or
# mirrored in relation to the camera. It is translated to one of the following
- # modules:
+ # instances:
# * TopLeftOrientation
# * TopRightOrientation
# * BottomRightOrientation
# * BottomLeftOrientation
# * LeftTopOrientation
# * RightTopOrientation
# * RightBottomOrientation
# * LeftBottomOrientation
#
- # These modules have two methods:
+ # These instances of Orientation have two methods:
# * <tt>to_i</tt>; return the original integer
# * <tt>transform_rmagick(image)</tt>; transforms the given RMagick::Image
# to a viewable version
#
# == Examples
# EXIFR::TIFF.new('DSC_0218.TIF').width # => 3008
# EXIFR::TIFF.new('DSC_0218.TIF')[1].width # => 160
# EXIFR::TIFF.new('DSC_0218.TIF').model # => "NIKON D1X"
# EXIFR::TIFF.new('DSC_0218.TIF').date_time # => Tue May 23 19:15:32 +0200 2006
# EXIFR::TIFF.new('DSC_0218.TIF').exposure_time # => Rational(1, 100)
- # EXIFR::TIFF.new('DSC_0218.TIF').orientation # => EXIFR::TIFF::TopLeftOrientation
+ # EXIFR::TIFF.new('DSC_0218.TIF').orientation # => EXIFR::TIFF::Orientation
class TIFF
include Enumerable
TAG_MAPPING = {} # :nodoc:
TAG_MAPPING.merge!({
@@ -239,32 +239,55 @@
else
value
end
end
+ # The orientation of the image with respect to the rows and columns.
+ class Orientation
+ def initialize(value, type) # :nodoc:
+ @value, @type = value, type
+ end
+
+ # Field value.
+ def to_i
+ @value
+ end
+
+ # Rotate and/or flip for proper viewing.
+ def transform_rmagick(img)
+ case @type
+ when :TopRight : img.flop
+ when :BottomRight : img.rotate(180)
+ when :BottomLeft : img.flip
+ when :LeftTop : img.rotate(90).flop
+ when :RightTop : img.rotate(90)
+ when :RightBottom : img.rotate(270).flop
+ when :LeftBottom : img.rotate(270)
+ else
+ img
+ end
+ end
+
+ def ==(other) # :nodoc:
+ Orientation === other && to_i == other.to_i
+ end
+ end
+
ORIENTATIONS = [] # :nodoc:
[
nil,
- [:TopLeft, 'img'],
- [:TopRight, 'img.flop'],
- [:BottomRight, 'img.rotate(180)'],
- [:BottomLeft, 'img.flip'],
- [:LeftTop, 'img.rotate(90).flop'],
- [:RightTop, 'img.rotate(90)'],
- [:RightBottom, 'img.rotate(270).flop'],
- [:LeftBottom, 'img.rotate(270)'],
- ].each_with_index do |tuple,index|
- next unless tuple
- name, rmagic_code = *tuple
-
- eval <<-EOS
- module #{name}Orientation
- def self.to_i; #{index}; end
- def self.transform_rmagick(img); #{rmagic_code}; end
- end
- ORIENTATIONS[#{index}] = #{name}Orientation
- EOS
+ :TopLeft,
+ :TopRight,
+ :BottomRight,
+ :BottomLeft,
+ :LeftTop,
+ :RightTop,
+ :RightBottom,
+ :LeftBottom,
+ ].each_with_index do |type,index|
+ next unless type
+ const_set("#{type}Orientation", ORIENTATIONS[index] = Orientation.new(index, type))
end
ADAPTERS = Hash.new { proc { |v| v } } # :nodoc:
ADAPTERS.merge!({
:date_time_original => time_proc,
@@ -276,25 +299,25 @@
# Names for all recognized TIFF fields.
TAGS = [TAG_MAPPING.keys, TAG_MAPPING.values.map{|a|a.values}].flatten.uniq - IFD_TAGS
# +file+ is a filename or an IO object.
def initialize(file)
- @data = file.respond_to?(:read) ? file.read : File.open(file, 'rb') { |io| io.read }
+ data = file.respond_to?(:read) ? file.read : File.open(file, 'rb') { |io| io.read }
- class << @data
+ class << data
attr_accessor :short, :long
def readshort(pos); self[pos..(pos + 1)].unpack(@short)[0]; end
def readlong(pos); self[pos..(pos + 3)].unpack(@long)[0]; end
end
- case @data[0..1]
- when 'II'; @data.short, @data.long = 'v', 'V'
- when 'MM'; @data.short, @data.long = 'n', 'N'
+ case data[0..1]
+ when 'II'; data.short, data.long = 'v', 'V'
+ when 'MM'; data.short, data.long = 'n', 'N'
else; raise 'no II or MM marker found'
end
- @ifds = [IFD.new(@data)]
+ @ifds = [IFD.new(data)]
while ifd = @ifds.last.next; @ifds << ifd; end
end
# Number of images.
def size
@@ -382,9 +405,12 @@
def next
IFD.new(@data, @offset_next) unless @offset_next == 0 || @offset_next >= @data.size
end
+ def to_yaml_properties
+ '@fields'
+ end
private
def add_field(field)
return unless tag = TAG_MAPPING[@type][field.tag]
if IFD_TAGS.include? tag
@fields[tag] = IFD.new(@data, field.offset, tag)
\ No newline at end of file