1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 var filenames = []string{
37 var filenamesShort = []string{
43 func readPng(filename string) (image.Image, os.Error) {
44 f, err := os.Open(filename)
52 // An approximation of the sng command-line tool.
53 func sng(w io.WriteCloser, filename string, png image.Image) {
55 bounds := png.Bounds()
56 cm := png.ColorModel()
59 case image.RGBAColorModel, image.NRGBAColorModel, image.AlphaColorModel, image.GrayColorModel:
64 cpm, _ := cm.(image.PalettedColorModel)
65 var paletted *image.Paletted
77 paletted = png.(*image.Paletted)
80 // Write the filename and IHDR.
81 io.WriteString(w, "#SNG: from "+filename+".png\nIHDR {\n")
82 fmt.Fprintf(w, " width: %d; height: %d; bitdepth: %d;\n", bounds.Dx(), bounds.Dy(), bitdepth)
84 case cm == image.RGBAColorModel, cm == image.RGBA64ColorModel:
85 io.WriteString(w, " using color;\n")
86 case cm == image.NRGBAColorModel, cm == image.NRGBA64ColorModel:
87 io.WriteString(w, " using color alpha;\n")
88 case cm == image.GrayColorModel, cm == image.Gray16ColorModel:
89 io.WriteString(w, " using grayscale;\n")
91 io.WriteString(w, " using color palette;\n")
93 io.WriteString(w, "unknown PNG decoder color model\n")
95 io.WriteString(w, "}\n")
97 // We fake a gAMA output. The test files have a gAMA chunk but the go PNG parser ignores it
98 // (the PNG spec section 11.3 says "Ancillary chunks may be ignored by a decoder").
99 io.WriteString(w, "gAMA {1.0000}\n")
101 // Write the PLTE (if applicable).
103 io.WriteString(w, "PLTE {\n")
104 for i := 0; i < len(cpm); i++ {
105 r, g, b, _ := cpm[i].RGBA()
109 fmt.Fprintf(w, " (%3d,%3d,%3d) # rgb = (0x%02x,0x%02x,0x%02x)\n", r, g, b, r, g, b)
111 io.WriteString(w, "}\n")
115 io.WriteString(w, "IMAGE {\n pixels hex\n")
116 for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
118 case cm == image.GrayColorModel:
119 for x := bounds.Min.X; x < bounds.Max.X; x++ {
120 gray := png.At(x, y).(image.GrayColor)
121 fmt.Fprintf(w, "%02x", gray.Y)
123 case cm == image.Gray16ColorModel:
124 for x := bounds.Min.X; x < bounds.Max.X; x++ {
125 gray16 := png.At(x, y).(image.Gray16Color)
126 fmt.Fprintf(w, "%04x ", gray16.Y)
128 case cm == image.RGBAColorModel:
129 for x := bounds.Min.X; x < bounds.Max.X; x++ {
130 rgba := png.At(x, y).(image.RGBAColor)
131 fmt.Fprintf(w, "%02x%02x%02x ", rgba.R, rgba.G, rgba.B)
133 case cm == image.RGBA64ColorModel:
134 for x := bounds.Min.X; x < bounds.Max.X; x++ {
135 rgba64 := png.At(x, y).(image.RGBA64Color)
136 fmt.Fprintf(w, "%04x%04x%04x ", rgba64.R, rgba64.G, rgba64.B)
138 case cm == image.NRGBAColorModel:
139 for x := bounds.Min.X; x < bounds.Max.X; x++ {
140 nrgba := png.At(x, y).(image.NRGBAColor)
141 fmt.Fprintf(w, "%02x%02x%02x%02x ", nrgba.R, nrgba.G, nrgba.B, nrgba.A)
143 case cm == image.NRGBA64ColorModel:
144 for x := bounds.Min.X; x < bounds.Max.X; x++ {
145 nrgba64 := png.At(x, y).(image.NRGBA64Color)
146 fmt.Fprintf(w, "%04x%04x%04x%04x ", nrgba64.R, nrgba64.G, nrgba64.B, nrgba64.A)
150 for x := bounds.Min.X; x < bounds.Max.X; x++ {
151 b = b<<uint(bitdepth) | int(paletted.ColorIndexAt(x, y))
154 fmt.Fprintf(w, "%02x", b)
160 io.WriteString(w, "\n")
162 io.WriteString(w, "}\n")
165 func TestReader(t *testing.T) {
168 names = filenamesShort
170 for _, fn := range names {
171 // Read the .png file.
172 img, err := readPng("testdata/pngsuite/" + fn + ".png")
178 if fn == "basn4a16" {
179 // basn4a16.sng is gray + alpha but sng() will produce true color + alpha
180 // so we just check a single random pixel.
181 c := img.At(2, 1).(image.NRGBA64Color)
182 if c.R != 0x11a7 || c.G != 0x11a7 || c.B != 0x11a7 || c.A != 0x1085 {
183 t.Error(fn, fmt.Errorf("wrong pixel value at (2, 1): %x", c))
188 piper, pipew := io.Pipe()
189 pb := bufio.NewReader(piper)
190 go sng(pipew, fn, img)
193 // Read the .sng file.
194 sf, err := os.Open("testdata/pngsuite/" + fn + ".sng")
200 sb := bufio.NewReader(sf)
206 // Compare the two, in SNG format, line by line.
208 ps, perr := pb.ReadString('\n')
209 ss, serr := sb.ReadString('\n')
210 if perr == os.EOF && serr == os.EOF {
222 t.Errorf("%s: Mismatch\n%sversus\n%s\n", fn, ps, ss)