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