Skip to content

Commit

Permalink
phase 2 interlacing working
Browse files Browse the repository at this point in the history
  • Loading branch information
tjennings committed Jan 1, 2010
1 parent 00c80e8 commit 8f8fc6e
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 25 deletions.
1 change: 1 addition & 0 deletions lib/spittle.rb
Expand Up @@ -16,3 +16,4 @@
require 'spittle/processor'
require 'spittle/mtime_tracker'
require 'spittle/image_data'
require 'spittle/deinterlacer'
77 changes: 77 additions & 0 deletions lib/spittle/deinterlacer.rb
@@ -0,0 +1,77 @@
class DeInterlacer
def initialize(height, width, pixel_width, raw, decoder)
@height, @width, @decoder = height, width, decoder
@pixel_width = pixel_width
@raw = raw.dup
@out = Spittle::ImageData.new :scanline_width => width, :pixel_width => pixel_width
end

def process
pass1
pass2
@out
end

def pass1_height
@height / 8
end

def pass1_width
end

def pass1
sub_width = ((@width / 8) * @pixel_width) + 1
sub_height = pass1_height
scanline_width = @width / 8

sub_image = Spittle::ImageData.new(:scanline_width => scanline_width,
:pixel_width => @pixel_width,
:data => [])
sub_height.times do |line_idx|
row = @raw.slice!(0, sub_width)
l = @decoder.decode(line_idx, row, sub_image, @pixel_width)
sub_image << l
end
sub_image

#FUck!
idxes = [0, (1..scanline_width - 1).to_a.map{ |i| (i * 8)}.map{|i| i - 1}].flatten
rows = [0, (1..sub_height - 1).to_a.map{ |i| i * 8 }.map{|i| i - 1}].flatten

input = sub_image.to_a
rows.each do |row|
idxes.each do |idx|
pixel = input.take(@pixel_width)
@out.set_pixel(row, idx, pixel)
end
end
end

def pass2
sub_width = ((@width / 8) * @pixel_width) + 1
sub_height = pass1_height
scanline_width = @width / 8

sub_image = Spittle::ImageData.new(:scanline_width => scanline_width,
:pixel_width => @pixel_width,
:data => [])
offset = 0
sub_height.times do |line_idx|
row = @raw.slice!(0, sub_width)
sub_image << @decoder.decode(line_idx, row, sub_image, @pixel_width)
end
sub_image

#FUck!
idxes = (0..scanline_width - 1).to_a.map{ |i| (i * 8) + 4}.map{|i| i - 1}
rows = [0, (1..sub_height - 1).to_a.map{ |i| i * 8 }.map{|i| i - 1}].flatten

input = sub_image.to_a
rows.each do |row|
idxes.each do |idx|
pixel = input.take(@pixel_width)
@out.set_pixel(row, idx, pixel)
end
end
end
end
24 changes: 24 additions & 0 deletions lib/spittle/image_data.rb
Expand Up @@ -13,6 +13,26 @@ def scanline_width; @properties[:scanline_width]; end
def width; scanline_width / pixel_width; end
def pixel_width; @properties[:pixel_width]; end

def to_a
@data.flatten
end

def set_pixel(row, idx, pixel)
return unless pixel
@data[row] = [] unless @data[row]
row = @data[row]
offset = idx * pixel_width

pixel.each_with_index do |v, pidx|
row[offset + pidx] = v
end
end

def fetch_pixel(idx, row = 0)
offset = idx * pixel_width
@data[row].slice(offset, pixel_width)
end

# need better checks, because currently compatible is
# similar color type, or depth.. maybe it doesn't matter...
def compatible?(image)
Expand Down Expand Up @@ -73,6 +93,10 @@ def last
@data.last
end

def rows
size
end

def <<(row)
@data << row
self
Expand Down
27 changes: 15 additions & 12 deletions lib/spittle/png/image.rb
Expand Up @@ -99,20 +99,23 @@ def to_image
def inspect
"#{@name} (#{height} x #{width}) [color type: #{color_type}, depth: #{depth}]"
end
private

# spike spikey spike
def decode_interlaced_image( uncompressed )
subimage1 = Spittle::ImageData.new(:scanline_width => sub_image_1_width - 1,
:pixel_width => pixel_width,
:data => Array.new(sub_image_1_height))
offset = 0
sub_image_1_height.times do |scanline|
end_row = sub_image_1_width + offset
row = uncompressed.slice(offset, sub_image_1_width)
subimage1[scanline] = decode(scanline, row, subimage1, pixel_width)
offset = end_row
end
subimage1
#subimage1 = Spittle::ImageData.new(:scanline_width => sub_image_1_width - 1,
#:pixel_width => pixel_width,
#:data => Array.new(sub_image_1_height))
#offset = 0
#sub_image_1_height.times do |scanline|
#end_row = sub_image_1_width + offset
#row = uncompressed.slice(offset, sub_image_1_width)
#subimage1[scanline] = decode(scanline, row, subimage1, pixel_width)
#offset = end_row
#end
#subimage1

deinterlacer = DeInterlacer.new(height, width, pixel_width, uncompressed, self)
deinterlacer.process
end

def sub_image_1_width
Expand Down
53 changes: 40 additions & 13 deletions spec/integration/interlace_spec.rb
@@ -1,26 +1,53 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')


#Interlaced Image color breakdown
#
# pass 1: (1,1,1)
# pass 2: (42,42,42)
# pass 3: (103, 103, 0)
# pass 4: (104, 0, 0)
# pass 5: (0, 105, 0)
# pass 6: (0, 0, 106)
# pass 6: (207, 207)

describe "reading interlaced images" do
before :all do
@image_dir = File.join( File.dirname( __FILE__ ), "interlaced_images" )
end

before :each do
@image = PNG::Image.open( @image_dir + "/interlaced-16x16-first-image.png" )
before do
begin
@image_dir = File.join( File.dirname( __FILE__ ), "interlaced_images" )
@image = PNG::Image.open( @image_dir + "/interlaced-16x16.png" )
@result = @image.to_image
rescue Exception => e
puts e.backtrace.join("\n")
raise e
end
end

describe "sanity checks" do
it "knows the images width" do
@image.width.should == 16
end

it "knows the images height" do
@image.height.should == 16
end
end

it "can read the first sub-image from an interlaced image" do
# should be the only colored pixels in the image.. with four different colors
@image.to_image.should == [[255, 127, 63, 63, 127, 255], [33, 66, 99, 192, 255, 127]]

describe "pass extraction" do
it "can read the first sub-image from an interlaced image" do
@result.fetch_pixel(0).should == [1,1,1]
@result.fetch_pixel(7).should == [1,1,1]

@result.fetch_pixel(0, 7).should == [1,1,1]
@result.fetch_pixel(7, 7).should == [1,1,1]
end

it "can read the second sub-image" do
@result.fetch_pixel(3).should == [42,42,42]
@result.fetch_pixel(11).should == [42,42,42]

@result.fetch_pixel(3, 7).should == [42,42,42]
@result.fetch_pixel(11, 7).should == [42,42,42]
end
end
end
end
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions spec/lib/image_data_spec.rb
Expand Up @@ -46,4 +46,13 @@
it "will return the last scanline given a current index" do
@id.last_scanline(1).should == [1,2,3]
end

describe "fetch_pixel" do
it "can fetch a given pixel" do
@id.fetch_pixel(0).should == [1,2,3]
end
it "can fetch across all rows" do
@id.fetch_pixel(0, 1).should == [4,5,6]
end
end
end

0 comments on commit 8f8fc6e

Please sign in to comment.