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
func readPng(filename string) (image.Image, os.Error) {
38
f, err := os.Open(filename, os.O_RDONLY, 0444)
46
// An approximation of the sng command-line tool.
47
func sng(w io.WriteCloser, filename string, png image.Image) {
49
bounds := png.Bounds()
50
cm := png.ColorModel()
53
case image.RGBAColorModel, image.NRGBAColorModel, image.AlphaColorModel, image.GrayColorModel:
58
cpm, _ := cm.(image.PalettedColorModel)
59
var paletted *image.Paletted
71
paletted = png.(*image.Paletted)
74
// Write the filename and IHDR.
75
io.WriteString(w, "#SNG: from "+filename+".png\nIHDR {\n")
76
fmt.Fprintf(w, " width: %d; height: %d; bitdepth: %d;\n", bounds.Dx(), bounds.Dy(), bitdepth)
78
case cm == image.RGBAColorModel, cm == image.RGBA64ColorModel:
79
io.WriteString(w, " using color;\n")
80
case cm == image.NRGBAColorModel, cm == image.NRGBA64ColorModel:
81
io.WriteString(w, " using color alpha;\n")
82
case cm == image.GrayColorModel, cm == image.Gray16ColorModel:
83
io.WriteString(w, " using grayscale;\n")
85
io.WriteString(w, " using color palette;\n")
87
io.WriteString(w, "unknown PNG decoder color model\n")
89
io.WriteString(w, "}\n")
91
// We fake a gAMA output. The test files have a gAMA chunk but the go PNG parser ignores it
92
// (the PNG spec section 11.3 says "Ancillary chunks may be ignored by a decoder").
93
io.WriteString(w, "gAMA {1.0000}\n")
95
// Write the PLTE (if applicable).
97
io.WriteString(w, "PLTE {\n")
98
for i := 0; i < len(cpm); i++ {
99
r, g, b, _ := cpm[i].RGBA()
103
fmt.Fprintf(w, " (%3d,%3d,%3d) # rgb = (0x%02x,0x%02x,0x%02x)\n", r, g, b, r, g, b)
105
io.WriteString(w, "}\n")
109
io.WriteString(w, "IMAGE {\n pixels hex\n")
110
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
112
case cm == image.GrayColorModel:
113
for x := bounds.Min.X; x < bounds.Max.X; x++ {
114
gray := png.At(x, y).(image.GrayColor)
115
fmt.Fprintf(w, "%02x", gray.Y)
117
case cm == image.Gray16ColorModel:
118
for x := bounds.Min.X; x < bounds.Max.X; x++ {
119
gray16 := png.At(x, y).(image.Gray16Color)
120
fmt.Fprintf(w, "%04x ", gray16.Y)
122
case cm == image.RGBAColorModel:
123
for x := bounds.Min.X; x < bounds.Max.X; x++ {
124
rgba := png.At(x, y).(image.RGBAColor)
125
fmt.Fprintf(w, "%02x%02x%02x ", rgba.R, rgba.G, rgba.B)
127
case cm == image.RGBA64ColorModel:
128
for x := bounds.Min.X; x < bounds.Max.X; x++ {
129
rgba64 := png.At(x, y).(image.RGBA64Color)
130
fmt.Fprintf(w, "%04x%04x%04x ", rgba64.R, rgba64.G, rgba64.B)
132
case cm == image.NRGBAColorModel:
133
for x := bounds.Min.X; x < bounds.Max.X; x++ {
134
nrgba := png.At(x, y).(image.NRGBAColor)
135
fmt.Fprintf(w, "%02x%02x%02x%02x ", nrgba.R, nrgba.G, nrgba.B, nrgba.A)
137
case cm == image.NRGBA64ColorModel:
138
for x := bounds.Min.X; x < bounds.Max.X; x++ {
139
nrgba64 := png.At(x, y).(image.NRGBA64Color)
140
fmt.Fprintf(w, "%04x%04x%04x%04x ", nrgba64.R, nrgba64.G, nrgba64.B, nrgba64.A)
144
for x := bounds.Min.X; x < bounds.Max.X; x++ {
145
b = b<<uint(bitdepth) | int(paletted.ColorIndexAt(x, y))
148
fmt.Fprintf(w, "%02x", b)
154
io.WriteString(w, "\n")
156
io.WriteString(w, "}\n")
159
func TestReader(t *testing.T) {
160
for _, fn := range filenames {
161
// Read the .png file.
162
img, err := readPng("testdata/pngsuite/" + fn + ".png")
168
if fn == "basn4a16" {
169
// basn4a16.sng is gray + alpha but sng() will produce true color + alpha
170
// so we just check a single random pixel.
171
c := img.At(2, 1).(image.NRGBA64Color)
172
if c.R != 0x11a7 || c.G != 0x11a7 || c.B != 0x11a7 || c.A != 0x1085 {
173
t.Error(fn, fmt.Errorf("wrong pixel value at (2, 1): %x", c))
178
piper, pipew := io.Pipe()
179
pb := bufio.NewReader(piper)
180
go sng(pipew, fn, img)
183
// Read the .sng file.
184
sf, err := os.Open("testdata/pngsuite/"+fn+".sng", os.O_RDONLY, 0444)
190
sb := bufio.NewReader(sf)
196
// Compare the two, in SNG format, line by line.
198
ps, perr := pb.ReadString('\n')
199
ss, serr := sb.ReadString('\n')
200
if perr == os.EOF && serr == os.EOF {
212
t.Errorf("%s: Mismatch\n%sversus\n%s\n", fn, ps, ss)