mirror of https://github.com/golang/go.git
image/png: speed up PNG decoding for common color models: Gray, NRGBA,
Paletted, RGBA. benchmark old ns/op new ns/op delta BenchmarkDecodeGray 3681144 2536049 -31.11% BenchmarkDecodeNRGBAGradient 12108660 10020650 -17.24% BenchmarkDecodeNRGBAOpaque 10699230 8677165 -18.90% BenchmarkDecodePaletted 2562806 1458798 -43.08% BenchmarkDecodeRGB 8468175 7180730 -15.20% benchmark old MB/s new MB/s speedup BenchmarkDecodeGray 17.80 25.84 1.45x BenchmarkDecodeNRGBAGradient 21.65 26.16 1.21x BenchmarkDecodeNRGBAOpaque 24.50 30.21 1.23x BenchmarkDecodePaletted 25.57 44.92 1.76x BenchmarkDecodeRGB 30.96 36.51 1.18x $ file $GOROOT/src/pkg/image/png/testdata/bench* benchGray.png: PNG image, 256 x 256, 8-bit grayscale, non-interlaced benchNRGBA-gradient.png: PNG image, 256 x 256, 8-bit/color RGBA, non-interlaced benchNRGBA-opaque.png: PNG image, 256 x 256, 8-bit/color RGBA, non-interlaced benchPaletted.png: PNG image, 256 x 256, 8-bit colormap, non-interlaced benchRGB.png: PNG image, 256 x 256, 8-bit/color RGB, non-interlaced R=r CC=golang-dev https://golang.org/cl/6127051
This commit is contained in:
parent
9ce770afad
commit
dd294fbd5a
|
|
@ -301,6 +301,7 @@ func (d *decoder) decode() (image.Image, error) {
|
|||
defer r.Close()
|
||||
bitsPerPixel := 0
|
||||
maxPalette := uint8(0)
|
||||
pixOffset := 0
|
||||
var (
|
||||
gray *image.Gray
|
||||
rgba *image.RGBA
|
||||
|
|
@ -423,18 +424,24 @@ func (d *decoder) decode() (image.Image, error) {
|
|||
}
|
||||
}
|
||||
case cbG8:
|
||||
for x := 0; x < d.width; x++ {
|
||||
gray.SetGray(x, y, color.Gray{cdat[x]})
|
||||
}
|
||||
copy(gray.Pix[pixOffset:], cdat)
|
||||
pixOffset += gray.Stride
|
||||
case cbGA8:
|
||||
for x := 0; x < d.width; x++ {
|
||||
ycol := cdat[2*x+0]
|
||||
nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
|
||||
}
|
||||
case cbTC8:
|
||||
pix, i, j := rgba.Pix, pixOffset, 0
|
||||
for x := 0; x < d.width; x++ {
|
||||
rgba.SetRGBA(x, y, color.RGBA{cdat[3*x+0], cdat[3*x+1], cdat[3*x+2], 0xff})
|
||||
pix[i+0] = cdat[j+0]
|
||||
pix[i+1] = cdat[j+1]
|
||||
pix[i+2] = cdat[j+2]
|
||||
pix[i+3] = 0xff
|
||||
i += 4
|
||||
j += 3
|
||||
}
|
||||
pixOffset += rgba.Stride
|
||||
case cbP1:
|
||||
for x := 0; x < d.width; x += 8 {
|
||||
b := cdat[x/8]
|
||||
|
|
@ -472,16 +479,18 @@ func (d *decoder) decode() (image.Image, error) {
|
|||
}
|
||||
}
|
||||
case cbP8:
|
||||
for x := 0; x < d.width; x++ {
|
||||
if cdat[x] > maxPalette {
|
||||
return nil, FormatError("palette index out of range")
|
||||
if maxPalette != 255 {
|
||||
for x := 0; x < d.width; x++ {
|
||||
if cdat[x] > maxPalette {
|
||||
return nil, FormatError("palette index out of range")
|
||||
}
|
||||
}
|
||||
paletted.SetColorIndex(x, y, cdat[x])
|
||||
}
|
||||
copy(paletted.Pix[pixOffset:], cdat)
|
||||
pixOffset += paletted.Stride
|
||||
case cbTCA8:
|
||||
for x := 0; x < d.width; x++ {
|
||||
nrgba.SetNRGBA(x, y, color.NRGBA{cdat[4*x+0], cdat[4*x+1], cdat[4*x+2], cdat[4*x+3]})
|
||||
}
|
||||
copy(nrgba.Pix[pixOffset:], cdat)
|
||||
pixOffset += nrgba.Stride
|
||||
case cbG16:
|
||||
for x := 0; x < d.width; x++ {
|
||||
ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"image"
|
||||
"image/color"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
|
@ -267,3 +268,41 @@ func TestReaderError(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkDecode(b *testing.B, filename string, bytesPerPixel int) {
|
||||
b.StopTimer()
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
s := string(data)
|
||||
cfg, err := DecodeConfig(strings.NewReader(s))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(cfg.Width * cfg.Height * bytesPerPixel))
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(strings.NewReader(s))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecodeGray(b *testing.B) {
|
||||
benchmarkDecode(b, "testdata/benchGray.png", 1)
|
||||
}
|
||||
|
||||
func BenchmarkDecodeNRGBAGradient(b *testing.B) {
|
||||
benchmarkDecode(b, "testdata/benchNRGBA-gradient.png", 4)
|
||||
}
|
||||
|
||||
func BenchmarkDecodeNRGBAOpaque(b *testing.B) {
|
||||
benchmarkDecode(b, "testdata/benchNRGBA-opaque.png", 4)
|
||||
}
|
||||
|
||||
func BenchmarkDecodePaletted(b *testing.B) {
|
||||
benchmarkDecode(b, "testdata/benchPaletted.png", 1)
|
||||
}
|
||||
|
||||
func BenchmarkDecodeRGB(b *testing.B) {
|
||||
benchmarkDecode(b, "testdata/benchRGB.png", 4)
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Loading…
Reference in New Issue