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