lib/icns/reader.rb in icns-0.1.0 vs lib/icns/reader.rb in icns-0.2.0

- old
+ new

@@ -1,14 +1,15 @@ # frozen_string_literal: true require 'icns/errors' module Icns + # Read an ICNS file’s metadata and extract images. class Reader # Initialize with a path to a valid ICNS file def initialize(path) - throw FileNotFound unless File.exists?(path) + throw FileNotFound unless File.exist?(path) @path = path @parts = {} read_metadata @@ -18,12 +19,12 @@ def types @parts.keys end # Raw data for a type - def data_for_type(type) - return nil unless part = @parts[type.to_s] + def data(type:) + return nil unless (part = @parts[type.to_s]) File.open(@path) do |file| # Seek to the image data position file.pos = part[:offset] @@ -31,26 +32,26 @@ file.read(part[:length]) end end # PNG or JPEG-2000 data for a size - def image_for_size(size) - return nil unless types = SIZE_TO_TYPE[size.to_i] + def image(size:) + return nil unless (types = SIZE_TO_TYPE[size.to_i]) data = nil types.each do |type| - break if data = data_for_type(type) + break if (data = self.data(type: type)) end data end # Available image sizes def sizes types = SIZE_TO_TYPE.values.flatten - @parts.keys.select { |k| types.include?(k) }. - map { |k| TYPE_TO_SIZE[k] }.sort.uniq + @parts.keys.select { |k| types.include?(k) } + .map { |k| TYPE_TO_SIZE[k] }.sort.uniq end private # These types are just metadata and not images. @@ -72,26 +73,30 @@ # The next 4 bytes are the total length of the file. Skip ahead. file.pos += 4 # Keep reading until we hit the end - while true - # If we can't read the icon type and length, we’re at the end - break unless (type = file.read(4)) && (length = file.read(4)) + loop do + break unless read_part(file) + end + end + end - # Convert the length into an integer. The length includes the icon - # header. We just want the length of the image data. - length = length.unpack('N')[0] - 8 + def read_part(file) + # If we can't read the icon type and length, we’re at the end + return false unless (type = file.read(4)) && (length = file.read(4)) - unless TYPES_BLACKLIST.include?(type) - # Add to our hash of type name to image data locations - puts "WARNING: duplicate part '#{type}'" if @parts[type] - @parts[type] = { offset: file.pos, length: length } - end + # Convert the length into an integer. The length includes the icon + # header. We just want the length of the image data. + length = length.unpack1('N') - 8 - # Advance past the image data - file.pos += length - end + unless TYPES_BLACKLIST.include?(type) + # Add to our hash of type name to image data locations + puts "WARNING: duplicate part '#{type}'" if @parts[type] + @parts[type] = { offset: file.pos, length: length } end + + # Advance past the image data + file.pos += length end end end