class Pixmap
  
  def convolute(kernel)
    newimg = Pixmap.new(@width, @height)
    pb = ProgressBar.new(@width) if $DEBUG
    @width.times do |x|
      @height.times do |y|
        apply_kernel(x, y, kernel, newimg)
      end
      pb.update(x) if $DEBUG
    end
    pb.close if $DEBUG
    newimg
  end

  
  def apply_kernel(x, y, kernel, newimg)
    x0 = x==0? 0: x-1
    y0 = y==0? 0: y-1
    x1 = x
    y1 = y
    x2 = x+1==@width ? x: x+1
    y2 = y+1==@height? y: y+1

    r = g = b = 0.0
    [x0, x1, x2].zip(kernel).each do |xx, kcol|
      [y0, y1, y2].zip(kcol).each do |yy, k|
        r += k * self[xx,yy].r
        g += k * self[xx,yy].g
        b += k * self[xx,yy].b
      end
    end
    newimg[x,y] = RGBColour.new(luma(r), luma(g), luma(b))
  end

  
  def luma(value)
    if value < 0
      0
    elsif value > 255
      255
    else
      value
    end
  end
end



teapot = Pixmap.open('teapot.ppm')
[ ['Emboss',  [[-2.0, -1.0, 0.0],  [-1.0, 1.0, 1.0],  [0.0, 1.0, 2.0]]], 
  ['Sharpen', [[-1.0, -1.0, -1.0], [-1.0, 9.0, -1.0], [-1.0, -1.0, -1.0]]], 
  ['Blur',    [[0.1111,0.1111,0.1111],[0.1111,0.1111,0.1111],[0.1111,0.1111,0.1111]]],
].each do |label, kernel|
  savefile = 'teapot_' + label.downcase + '.ppm'
  teapot.convolute(kernel).save(savefile)
end