Class: Flipbook::GIF::Reader
- Inherits:
-
Object
- Object
- Flipbook::GIF::Reader
- Defined in:
- lib/flipbook/gif/reader.rb,
sig/flipbook.rbs
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(bytes, max_pixels: 16_384 * 16_384, max_frames: 10_000, max_total_pixels: 100_000_000) ⇒ Reader
constructor
A new instance of Reader.
- #read ⇒ Array[Tessel::Image]
Constructor Details
#initialize(bytes, max_pixels: 16_384 * 16_384, max_frames: 10_000, max_total_pixels: 100_000_000) ⇒ Reader
Returns a new instance of Reader.
10 11 12 13 14 15 16 17 |
# File 'lib/flipbook/gif/reader.rb', line 10 def initialize(bytes, max_pixels: 16_384 * 16_384, max_frames: 10_000, max_total_pixels: 100_000_000) @bytes = String(bytes).b @offset = 0 @max_pixels = Integer(max_pixels) @max_frames = Integer(max_frames) @max_total_pixels = Integer(max_total_pixels) raise ArgumentError, "limits must be positive" unless @max_pixels.positive? && @max_frames.positive? && @max_total_pixels.positive? end |
Class Method Details
.read(path, max_pixels: 16_384 * 16_384, max_frames: 10_000, max_total_pixels: 100_000_000) ⇒ Array[Tessel::Image]
6 7 8 |
# File 'lib/flipbook/gif/reader.rb', line 6 def self.read(path, max_pixels: 16_384 * 16_384, max_frames: 10_000, max_total_pixels: 100_000_000) new(File.binread(path), max_pixels:, max_frames:, max_total_pixels:).read end |
Instance Method Details
#read ⇒ Array[Tessel::Image]
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/flipbook/gif/reader.rb', line 19 def read signature = take(6) raise Error, "invalid GIF signature" unless %w[GIF87a GIF89a].include?(signature) @width, @height, packed, background_index, = take(7).unpack("v2C3") raise Error, "invalid GIF dimensions" if @width.zero? || @height.zero? || @width * @height > @max_pixels @global_palette = read_palette(1 << ((packed & 7) + 1)) if (packed & 0x80).positive? @background_index = background_index @background = palette_color(@global_palette, background_index) @frames = [] @canvas = Tessel::Image.new(@width, @height, fill: @background) @control = default_control @previous_disposal = nil @finished = false until @finished marker = byte case marker when 0x21 then read_extension when 0x2c then read_image when 0x3b then @finished = true else raise Error, "invalid GIF block marker 0x#{marker.to_s(16)}" end end raise Error, "GIF contains no frames" if @frames.empty? @frames end |