Skip to content

Instantly share code, notes, and snippets.

@joshuaflanagan
Last active August 29, 2015 14:13
Show Gist options
  • Save joshuaflanagan/a39a2df20ced14ef04d0 to your computer and use it in GitHub Desktop.
Save joshuaflanagan/a39a2df20ced14ef04d0 to your computer and use it in GitHub Desktop.

Revisions

  1. joshuaflanagan revised this gist Jan 16, 2015. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions pngcheck.rb
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    # http://www.w3.org/TR/PNG/#5DataRep
    class PNGCheck
    def initialize(path)
    @path = path
  2. joshuaflanagan created this gist Jan 16, 2015.
    43 changes: 43 additions & 0 deletions pngcheck.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    class PNGCheck
    def initialize(path)
    @path = path
    end

    def check_all!
    expected_signature = [137, 80, 78, 71, 13, 10, 26, 10]
    file.seek 0
    signature_data = file.read(8)
    raise "unable to read signature, not enough bytes. found #{signature_data}" unless signature_data.length == 8
    signature = signature_data.unpack("C*")
    raise "invalid signature: #{signature.inspect} expected #{expected_signature.inspect}" unless signature == expected_signature

    chunks = 0
    loop do
    break unless process_chunk
    chunks += 1
    end
    puts "File is valid!"
    end

    def process_chunk
    length_data = file.read(4)
    return false if length_data.nil? || length_data == ""
    raise "expected 4 bytes for LENGTH, got '#{length_data}'" unless length_data.length == 4
    length = length_data.unpack("N").first
    type = file.read(4)
    raise "expected 4 bytes for TYPE, got '#{type}'" unless type.length == 4
    data = file.read(length)
    raise "expected #{length} bytes for DATA, got #{data.length}" unless data.length == length
    crc_data = file.read(4)
    raise "expected 4 bytes for CRC, got '#{crc_data}'" unless crc_data.length == 4
    crc = crc_data.unpack("N").first
    crc_check = Zlib.crc32(type + data)
    raise "CRC did not check" unless crc == crc_check
    puts "#{type} #{length} bytes CRC: #{crc} POS: #{file.pos}"
    true
    end

    def file
    @file ||= File.open(@path, "rb")
    end
    end