// toYCbCr converts the 8x8 region of m whose top-left corner is p to its // YCbCr values. func toYCbCr(m image.Image, 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++ { for i := 0; i < 8; i++ { r, g, b, _ := m.At(min(p.X+i, xmax), min(p.Y+j, ymax)).RGBA() yy, cb, cr := ycbcr.RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8)) yBlock[8*j+i] = int(yy) cbBlock[8*j+i] = int(cb) crBlock[8*j+i] = int(cr) } } }
// 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 } offset := (sj-b.Min.Y)*m.Stride - b.Min.X*4 for i := 0; i < 8; i++ { sx := p.X + i if sx > xmax { sx = xmax } pix := m.Pix[offset+sx*4:] yy, cb, cr := ycbcr.RGBToYCbCr(pix[0], pix[1], pix[2]) yBlock[8*j+i] = int(yy) cbBlock[8*j+i] = int(cb) crBlock[8*j+i] = int(cr) } } }
// 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) } } }