OSDN Git Service

libgo: Update to current Go library.
[pf3gnuchains/gcc-fork.git] / libgo / go / image / png / reader_test.go
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.
4
5 package png
6
7 import (
8         "bufio"
9         "fmt"
10         "image"
11         "io"
12         "os"
13         "testing"
14 )
15
16 var filenames = []string{
17         "basn0g01",
18         "basn0g01-30",
19         "basn0g02",
20         "basn0g02-29",
21         "basn0g04",
22         "basn0g04-31",
23         "basn0g08",
24         "basn0g16",
25         "basn2c08",
26         "basn2c16",
27         "basn3p01",
28         "basn3p02",
29         "basn3p04",
30         "basn3p08",
31         "basn4a08",
32         "basn4a16",
33         "basn6a08",
34         "basn6a16",
35 }
36
37 var filenamesShort = []string{
38         "basn0g01",
39         "basn0g04-31",
40         "basn6a16",
41 }
42
43 func readPng(filename string) (image.Image, os.Error) {
44         f, err := os.Open(filename)
45         if err != nil {
46                 return nil, err
47         }
48         defer f.Close()
49         return Decode(f)
50 }
51
52 // An approximation of the sng command-line tool.
53 func sng(w io.WriteCloser, filename string, png image.Image) {
54         defer w.Close()
55         bounds := png.Bounds()
56         cm := png.ColorModel()
57         var bitdepth int
58         switch cm {
59         case image.RGBAColorModel, image.NRGBAColorModel, image.AlphaColorModel, image.GrayColorModel:
60                 bitdepth = 8
61         default:
62                 bitdepth = 16
63         }
64         cpm, _ := cm.(image.PalettedColorModel)
65         var paletted *image.Paletted
66         if cpm != nil {
67                 switch {
68                 case len(cpm) <= 2:
69                         bitdepth = 1
70                 case len(cpm) <= 4:
71                         bitdepth = 2
72                 case len(cpm) <= 16:
73                         bitdepth = 4
74                 default:
75                         bitdepth = 8
76                 }
77                 paletted = png.(*image.Paletted)
78         }
79
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)
83         switch {
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")
90         case cpm != nil:
91                 io.WriteString(w, "    using color palette;\n")
92         default:
93                 io.WriteString(w, "unknown PNG decoder color model\n")
94         }
95         io.WriteString(w, "}\n")
96
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")
100
101         // Write the PLTE (if applicable).
102         if cpm != nil {
103                 io.WriteString(w, "PLTE {\n")
104                 for i := 0; i < len(cpm); i++ {
105                         r, g, b, _ := cpm[i].RGBA()
106                         r >>= 8
107                         g >>= 8
108                         b >>= 8
109                         fmt.Fprintf(w, "    (%3d,%3d,%3d)     # rgb = (0x%02x,0x%02x,0x%02x)\n", r, g, b, r, g, b)
110                 }
111                 io.WriteString(w, "}\n")
112         }
113
114         // Write the IMAGE.
115         io.WriteString(w, "IMAGE {\n    pixels hex\n")
116         for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
117                 switch {
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)
122                         }
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)
127                         }
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)
132                         }
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)
137                         }
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)
142                         }
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)
147                         }
148                 case cpm != nil:
149                         var b, c int
150                         for x := bounds.Min.X; x < bounds.Max.X; x++ {
151                                 b = b<<uint(bitdepth) | int(paletted.ColorIndexAt(x, y))
152                                 c++
153                                 if c == 8/bitdepth {
154                                         fmt.Fprintf(w, "%02x", b)
155                                         b = 0
156                                         c = 0
157                                 }
158                         }
159                 }
160                 io.WriteString(w, "\n")
161         }
162         io.WriteString(w, "}\n")
163 }
164
165 func TestReader(t *testing.T) {
166         names := filenames
167         if testing.Short() {
168                 names = filenamesShort
169         }
170         for _, fn := range names {
171                 // Read the .png file.
172                 img, err := readPng("testdata/pngsuite/" + fn + ".png")
173                 if err != nil {
174                         t.Error(fn, err)
175                         continue
176                 }
177
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))
184                         }
185                         continue
186                 }
187
188                 piper, pipew := io.Pipe()
189                 pb := bufio.NewReader(piper)
190                 go sng(pipew, fn, img)
191                 defer piper.Close()
192
193                 // Read the .sng file.
194                 sf, err := os.Open("testdata/pngsuite/" + fn + ".sng")
195                 if err != nil {
196                         t.Error(fn, err)
197                         continue
198                 }
199                 defer sf.Close()
200                 sb := bufio.NewReader(sf)
201                 if err != nil {
202                         t.Error(fn, err)
203                         continue
204                 }
205
206                 // Compare the two, in SNG format, line by line.
207                 for {
208                         ps, perr := pb.ReadString('\n')
209                         ss, serr := sb.ReadString('\n')
210                         if perr == os.EOF && serr == os.EOF {
211                                 break
212                         }
213                         if perr != nil {
214                                 t.Error(fn, perr)
215                                 break
216                         }
217                         if serr != nil {
218                                 t.Error(fn, serr)
219                                 break
220                         }
221                         if ps != ss {
222                                 t.Errorf("%s: Mismatch\n%sversus\n%s\n", fn, ps, ss)
223                                 break
224                         }
225                 }
226         }
227 }