def apply_filters prev_filters = nil, filter_codecs = nil
      prev_filters = filter_types if prev_filters.nil?
      filter_codecs = [] if filter_codecs.nil?
      current_filters = []
      prev = nil
      line_sizes = []
      scanline_positions.push(@filtered_data.size).inject do |m, n|
        line_sizes << n - m - 1
        n
      end
      wrap_with_rewind(@filtered_data) do
        # decode all scanlines
        prev_filters.each_with_index do |type, i|
          byte = @filtered_data.read 1
          current_filters << byte.unpack('C').first
          line_size = line_sizes[i]
          line = @filtered_data.read line_size
          filter = Filter.new type, @sample_size
          if filter_codecs[i] && filter_codecs[i][:decoder]
            filter.decoder = filter_codecs[i][:decoder]
          end
          if !prev.nil? && @interlace_pass_count.include?(i + 1)  # make sure prev to be nil if interlace pass is changed
            prev = nil
          end
          decoded = filter.decode line, prev
          @filtered_data.pos -= line_size
          @filtered_data << decoded
          prev = decoded
        end
        # encode all
        filter_codecs.reverse!
        line_sizes.reverse!
        data_amount = @filtered_data.pos # should be eof
        ref = data_amount
        current_filters.reverse_each.with_index do |type, i|
          line_size = line_sizes[i]
          ref -= line_size + 1
          @filtered_data.pos = ref + 1
          line = @filtered_data.read line_size
          prev = nil
          if !line_sizes[i + 1].nil?
            @filtered_data.pos = ref - line_size
            prev = @filtered_data.read line_size
          end
          # make sure prev to be nil if interlace pass is changed
          if @interlace_pass_count.include?(current_filters.size - i)
            prev = nil
          end
          filter = Filter.new type, @sample_size
          if filter_codecs[i] && filter_codecs[i][:encoder]
            filter.encoder = filter_codecs[i][:encoder]
          end
          encoded = filter.encode line, prev
          @filtered_data.pos = ref + 1
          @filtered_data << encoded
        end
      end
    end
def apply_filters prev_filters = nil, filter_codecs = nil
      prev_filters = filter_types if prev_filters.nil?
      filter_codecs = [] if filter_codecs.nil?
      current_filters = []
      prev = nil
      line_sizes = []
      scanline_positions.push(@filtered_data.size).inject do |m, n|
        line_sizes << n - m - 1
        n
      end
      wrap_with_rewind(@filtered_data) do
        # decode all scanlines
        prev_filters.each_with_index do |type, i|
          byte = @filtered_data.read 1
          current_filters << byte.unpack('C').first
          line_size = line_sizes[i]
          line = @filtered_data.read line_size
          filter = Filter.new type, @sample_size
          if filter_codecs[i] && filter_codecs[i][:decoder]
            filter.decoder = filter_codecs[i][:decoder]
          end
          if !prev.nil? && @interlace_pass_count.include?(i + 1)  # make sure prev to be nil if interlace pass is changed
            prev = nil
          end
          decoded = filter.decode line, prev
          @filtered_data.pos -= line_size
          @filtered_data << decoded
          prev = decoded
        end
        # encode all
        filter_codecs.reverse!
        line_sizes.reverse!
        data_amount = @filtered_data.pos # should be eof
        ref = data_amount
        current_filters.reverse_each.with_index do |type, i|
          line_size = line_sizes[i]
          ref -= line_size + 1
          @filtered_data.pos = ref + 1
          line = @filtered_data.read line_size
          prev = nil
          if !line_sizes[i + 1].nil?
            @filtered_data.pos = ref - line_size
            prev = @filtered_data.read line_size
          end
          # make sure prev to be nil if interlace pass is changed
          if @interlace_pass_count.include?(current_filters.size - i)
            prev = nil
          end
          filter = Filter.new type, @sample_size
          if filter_codecs[i] && filter_codecs[i][:encoder]
            filter.encoder = filter_codecs[i][:encoder]
          end
          encoded = filter.encode line, prev
          @filtered_data.pos = ref + 1
          @filtered_data << encoded
        end
      end
    end
(Re-)computes the filtering methods on each scanline.