if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
the image you've created is compressed using dynamic huffman tables.
when uncompressing, the code fills in the first table (h1) but the
second table (h2) contains only one element: 0 (nlit=257, ndist=1).
h2's init code short-circuits when it sees only zeroes and you get the
error.
I can confirm that commenting out the check for max == 0 in init()
circumvents the particular issue. writing out an image thus read
results in an identical to the original PNG file.
to test comment out lines 98-100 of pkg/compress/flate/inflate.go and
try reading back the image which previously resulted in an error.
I don't know enough about huffman coding to say what exactly is
causing the issue. It seems that the png image is correct as created
because it can be opened without visible warnings by photoshop, osx's
"Preview", plan9's png and the netpbm library. The issue only appears
with sufficiently small images (4x4, 4x5) -- anything smaller switches
to a static encoding table (flate type 1), anything bigger has enough
bits for the second table.
http://zlib.net/feldspar.html has more information, saying "if the
last elements of an alphabet are of 0 codelengths, they can and
probably should be left out"
I suspect that deflate could trim off that bit from the end and
inflate could be more accepting, but that's not an educated guess.
To answer your question: you can file an issue with "this png image is
accepted by everybody else without warning but fails with go's
image/png library" or you can use this program that exhibits the
behaviour without involving png:
---snip---
package main
import (
"compress/flate"
"os"
)
func main() {
b := []byte{0, 0, 1, 0, 4, 4, 2, 4, 1, 2, 0, 3, 4, 2, 1, 4, 0}
r, w, _ := os.Pipe()
fw := flate.NewWriter(w, -1)
fr := flate.NewReader(r)
n, err := fw.Write(b)
if err != nil {
panic(err)
}
fw.Close()
nn, err := fr.Read(b)
if err != nil {
panic(err)
}
if n != nn {
panic("different r/w sizes")
}
}
$ 6g t.go; 6l t.6; ./6.out
# debug messages from compress/flate
typ: 2
nlit, ndist+nlit: 257 258
panic: flate: corrupt input before offset 13
The zlib bug seems more generic than this, and easy to reproduce with
simple textual data:
http://code.google.com/p/go/issues/detail?id=1833
--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/blog
http://niemeyer.net/twitter
Not a decoding problem then if python doesn't like the compressed
data. This sample decoder from zlib.net also chokes on output from
deflate: