github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/image/png/writer_test.go (about) 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 "bytes" 9 "fmt" 10 "image" 11 "image/color" 12 "io/ioutil" 13 "testing" 14 ) 15 16 func diff(m0, m1 image.Image) error { 17 b0, b1 := m0.Bounds(), m1.Bounds() 18 if !b0.Size().Eq(b1.Size()) { 19 return fmt.Errorf("dimensions differ: %v vs %v", b0, b1) 20 } 21 dx := b1.Min.X - b0.Min.X 22 dy := b1.Min.Y - b0.Min.Y 23 for y := b0.Min.Y; y < b0.Max.Y; y++ { 24 for x := b0.Min.X; x < b0.Max.X; x++ { 25 c0 := m0.At(x, y) 26 c1 := m1.At(x+dx, y+dy) 27 r0, g0, b0, a0 := c0.RGBA() 28 r1, g1, b1, a1 := c1.RGBA() 29 if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 { 30 return fmt.Errorf("colors differ at (%d, %d): %v vs %v", x, y, c0, c1) 31 } 32 } 33 } 34 return nil 35 } 36 37 func encodeDecode(m image.Image) (image.Image, error) { 38 var b bytes.Buffer 39 err := Encode(&b, m) 40 if err != nil { 41 return nil, err 42 } 43 return Decode(&b) 44 } 45 46 func TestWriter(t *testing.T) { 47 // The filenames variable is declared in reader_test.go. 48 names := filenames 49 if testing.Short() { 50 names = filenamesShort 51 } 52 for _, fn := range names { 53 qfn := "testdata/pngsuite/" + fn + ".png" 54 // Read the image. 55 m0, err := readPNG(qfn) 56 if err != nil { 57 t.Error(fn, err) 58 continue 59 } 60 // Read the image again, encode it, and decode it. 61 m1, err := readPNG(qfn) 62 if err != nil { 63 t.Error(fn, err) 64 return 65 } 66 m2, err := encodeDecode(m1) 67 if err != nil { 68 t.Error(fn, err) 69 return 70 } 71 // Compare the two. 72 err = diff(m0, m2) 73 if err != nil { 74 t.Error(fn, err) 75 continue 76 } 77 } 78 } 79 80 func TestWriterLevels(t *testing.T) { 81 m := image.NewNRGBA(image.Rect(0, 0, 100, 100)) 82 83 var b1, b2 bytes.Buffer 84 if err := (&Encoder{}).Encode(&b1, m); err != nil { 85 t.Fatal(err) 86 } 87 noenc := &Encoder{CompressionLevel: NoCompression} 88 if err := noenc.Encode(&b2, m); err != nil { 89 t.Fatal(err) 90 } 91 92 if b2.Len() <= b1.Len() { 93 t.Error("DefaultCompression encoding was larger than NoCompression encoding") 94 } 95 if _, err := Decode(&b1); err != nil { 96 t.Error("cannot decode DefaultCompression") 97 } 98 if _, err := Decode(&b2); err != nil { 99 t.Error("cannot decode NoCompression") 100 } 101 } 102 103 func TestSubImage(t *testing.T) { 104 m0 := image.NewRGBA(image.Rect(0, 0, 256, 256)) 105 for y := 0; y < 256; y++ { 106 for x := 0; x < 256; x++ { 107 m0.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255}) 108 } 109 } 110 m0 = m0.SubImage(image.Rect(50, 30, 250, 130)).(*image.RGBA) 111 m1, err := encodeDecode(m0) 112 if err != nil { 113 t.Error(err) 114 return 115 } 116 err = diff(m0, m1) 117 if err != nil { 118 t.Error(err) 119 return 120 } 121 } 122 123 func BenchmarkEncodeGray(b *testing.B) { 124 b.StopTimer() 125 img := image.NewGray(image.Rect(0, 0, 640, 480)) 126 b.SetBytes(640 * 480 * 1) 127 b.StartTimer() 128 for i := 0; i < b.N; i++ { 129 Encode(ioutil.Discard, img) 130 } 131 } 132 133 func BenchmarkEncodeNRGBOpaque(b *testing.B) { 134 b.StopTimer() 135 img := image.NewNRGBA(image.Rect(0, 0, 640, 480)) 136 // Set all pixels to 0xFF alpha to force opaque mode. 137 bo := img.Bounds() 138 for y := bo.Min.Y; y < bo.Max.Y; y++ { 139 for x := bo.Min.X; x < bo.Max.X; x++ { 140 img.Set(x, y, color.NRGBA{0, 0, 0, 255}) 141 } 142 } 143 if !img.Opaque() { 144 b.Fatal("expected image to be opaque") 145 } 146 b.SetBytes(640 * 480 * 4) 147 b.StartTimer() 148 for i := 0; i < b.N; i++ { 149 Encode(ioutil.Discard, img) 150 } 151 } 152 153 func BenchmarkEncodeNRGBA(b *testing.B) { 154 b.StopTimer() 155 img := image.NewNRGBA(image.Rect(0, 0, 640, 480)) 156 if img.Opaque() { 157 b.Fatal("expected image not to be opaque") 158 } 159 b.SetBytes(640 * 480 * 4) 160 b.StartTimer() 161 for i := 0; i < b.N; i++ { 162 Encode(ioutil.Discard, img) 163 } 164 } 165 166 func BenchmarkEncodePaletted(b *testing.B) { 167 b.StopTimer() 168 img := image.NewPaletted(image.Rect(0, 0, 640, 480), color.Palette{ 169 color.RGBA{0, 0, 0, 255}, 170 color.RGBA{255, 255, 255, 255}, 171 }) 172 b.SetBytes(640 * 480 * 1) 173 b.StartTimer() 174 for i := 0; i < b.N; i++ { 175 Encode(ioutil.Discard, img) 176 } 177 } 178 179 func BenchmarkEncodeRGBOpaque(b *testing.B) { 180 b.StopTimer() 181 img := image.NewRGBA(image.Rect(0, 0, 640, 480)) 182 // Set all pixels to 0xFF alpha to force opaque mode. 183 bo := img.Bounds() 184 for y := bo.Min.Y; y < bo.Max.Y; y++ { 185 for x := bo.Min.X; x < bo.Max.X; x++ { 186 img.Set(x, y, color.RGBA{0, 0, 0, 255}) 187 } 188 } 189 if !img.Opaque() { 190 b.Fatal("expected image to be opaque") 191 } 192 b.SetBytes(640 * 480 * 4) 193 b.StartTimer() 194 for i := 0; i < b.N; i++ { 195 Encode(ioutil.Discard, img) 196 } 197 } 198 199 func BenchmarkEncodeRGBA(b *testing.B) { 200 b.StopTimer() 201 img := image.NewRGBA(image.Rect(0, 0, 640, 480)) 202 if img.Opaque() { 203 b.Fatal("expected image not to be opaque") 204 } 205 b.SetBytes(640 * 480 * 4) 206 b.StartTimer() 207 for i := 0; i < b.N; i++ { 208 Encode(ioutil.Discard, img) 209 } 210 }