mirror of
https://github.com/golang/go
synced 2024-11-25 01:08:02 -07:00
jpeg: speed up RGBA encoding ~%50
Avoids image.At(), color.RGBA(), opposing 8 bit shifts, and min function calls in a loop. Not as pretty as before, but the pure version is still there to revert back to later if/when the compiler gets better. before (best of 5) jpeg.BenchmarkEncodeRGBOpaque 50 64781360 ns/op 18.97 MB/s after (best of 5) jpeg.BenchmarkEncodeRGBOpaque 50 42044300 ns/op 29.23 MB/s (benchmarked on an HP z600; 16 core Xeon E5520 @ 2.27Ghz) R=r, r2, nigeltao CC=golang-dev https://golang.org/cl/4433088
This commit is contained in:
parent
437015bbed
commit
807ce2719c
@ -391,6 +391,31 @@ func toYCbCr(m image.Image, p image.Point, yBlock, cbBlock, crBlock *block) {
|
||||
}
|
||||
}
|
||||
|
||||
// rgbaToYCbCr is a specialized version of toYCbCr for image.RGBA images.
|
||||
func rgbaToYCbCr(m *image.RGBA, p image.Point, yBlock, cbBlock, crBlock *block) {
|
||||
b := m.Bounds()
|
||||
xmax := b.Max.X - 1
|
||||
ymax := b.Max.Y - 1
|
||||
for j := 0; j < 8; j++ {
|
||||
sj := p.Y + j
|
||||
if sj > ymax {
|
||||
sj = ymax
|
||||
}
|
||||
yoff := sj * m.Stride
|
||||
for i := 0; i < 8; i++ {
|
||||
sx := p.X + i
|
||||
if sx > xmax {
|
||||
sx = xmax
|
||||
}
|
||||
col := &m.Pix[yoff+sx]
|
||||
yy, cb, cr := ycbcr.RGBToYCbCr(col.R, col.G, col.B)
|
||||
yBlock[8*j+i] = int(yy)
|
||||
cbBlock[8*j+i] = int(cb)
|
||||
crBlock[8*j+i] = int(cr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scale scales the 16x16 region represented by the 4 src blocks to the 8x8
|
||||
// dst block.
|
||||
func scale(dst *block, src *[4]block) {
|
||||
@ -431,13 +456,18 @@ func (e *encoder) writeSOS(m image.Image) {
|
||||
prevDCY, prevDCCb, prevDCCr int
|
||||
)
|
||||
bounds := m.Bounds()
|
||||
rgba, _ := m.(*image.RGBA)
|
||||
for y := bounds.Min.Y; y < bounds.Max.Y; y += 16 {
|
||||
for x := bounds.Min.X; x < bounds.Max.X; x += 16 {
|
||||
for i := 0; i < 4; i++ {
|
||||
xOff := (i & 1) * 8
|
||||
yOff := (i & 2) * 4
|
||||
p := image.Point{x + xOff, y + yOff}
|
||||
if rgba != nil {
|
||||
rgbaToYCbCr(rgba, p, &yBlock, &cbBlock[i], &crBlock[i])
|
||||
} else {
|
||||
toYCbCr(m, p, &yBlock, &cbBlock[i], &crBlock[i])
|
||||
}
|
||||
prevDCY = e.writeBlock(&yBlock, 0, prevDCY)
|
||||
}
|
||||
scale(&cBlock, &cbBlock)
|
||||
|
Loading…
Reference in New Issue
Block a user