blob: ed4b2e20f20ae6a7f588c2a5b1fbad2ee89e5ee9 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package image
import (
"android.googlesource.com/platform/tools/gpu/framework/binary"
"android.googlesource.com/platform/tools/gpu/framework/math/sint"
"android.googlesource.com/platform/tools/gpu/gapid/image"
)
func init() {
image.RegisterConverter(image.ATC_RGB_AMD(), image.RGBA(),
func(src []byte, width, height int) ([]byte, error) {
dst, j := make([]byte, width*height*4), 0
blockWidth := sint.Max(width/4, 1)
blockHeight := sint.Max(height/4, 1)
bs := binary.BitStream{Data: src}
c := [4][3]uint32{
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
}
for by := 0; by < blockHeight; by++ {
for bx := 0; bx < blockWidth; bx++ {
c[0][2] = bs.Read(5) << 3
c[0][1] = bs.Read(5) << 3
c[0][0] = bs.Read(5) << 3
alt := bs.ReadBit() != 0
c[3][2] = bs.Read(5) << 3
c[3][1] = bs.Read(6) << 2
c[3][0] = bs.Read(5) << 3
for i := 0; i < 3; i++ {
if alt {
c[2][i] = c[0][i]
c[1][i] = c[0][i] - c[3][i]/4
c[0][i] = 0
} else {
c[1][i] = (c[0][i]*2 + c[3][i]*1) / 3
c[2][i] = (c[0][i]*1 + c[3][i]*2) / 3
}
}
for y := by * 4; y < (by+1)*4; y++ {
for x := bx * 4; x < (bx+1)*4; x++ {
idx := bs.Read(2)
if x < width && y < height {
j = 4 * (y*width + x)
dst[j+0] = uint8(c[idx][0])
dst[j+1] = uint8(c[idx][1])
dst[j+2] = uint8(c[idx][2])
dst[j+3] = 255
}
}
}
}
}
return dst, nil
})
image.RegisterConverter(image.ATC_RGBA_EXPLICIT_ALPHA_AMD(), image.RGBA(),
func(src []byte, width, height int) ([]byte, error) {
dst, j := make([]byte, width*height*4), 0
blockWidth := sint.Max(width/4, 1)
blockHeight := sint.Max(height/4, 1)
bs := binary.BitStream{Data: src}
a := [16]uint8{
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
}
c := [4][3]uint32{
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
}
for by := 0; by < blockHeight; by++ {
for bx := 0; bx < blockWidth; bx++ {
for i := 0; i < 16; i++ {
a[i] = uint8(bs.Read(4) << 4)
}
c[0][2] = bs.Read(5) << 3
c[0][1] = bs.Read(5) << 3
c[0][0] = bs.Read(5) << 3
bs.ReadBit()
c[3][2] = bs.Read(5) << 3
c[3][1] = bs.Read(6) << 2
c[3][0] = bs.Read(5) << 3
for i := 0; i < 3; i++ {
c[1][i] = (c[0][i]*2 + c[3][i]*1) / 3
c[2][i] = (c[0][i]*1 + c[3][i]*2) / 3
}
p := 0
for y := by * 4; y < (by+1)*4; y++ {
for x := bx * 4; x < (bx+1)*4; x++ {
idx := bs.Read(2)
if x < width && y < height {
j = 4 * (y*width + x)
dst[j+0] = uint8(c[idx][0])
dst[j+1] = uint8(c[idx][1])
dst[j+2] = uint8(c[idx][2])
dst[j+3] = a[p]
p++
}
}
}
}
}
return dst, nil
})
image.RegisterConverter(image.ATC_RGBA_INTERPOLATED_ALPHA_AMD(), image.RGBA(),
func(src []byte, width, height int) ([]byte, error) {
dst, j := make([]byte, width*height*4), 0
blockWidth := sint.Max(width/4, 1)
blockHeight := sint.Max(height/4, 1)
bs := binary.BitStream{Data: src}
t := [8]uint8{}
a := [16]uint8{
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
}
c := [4][3]uint32{
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
}
for by := 0; by < blockHeight; by++ {
for bx := 0; bx < blockWidth; bx++ {
t0 := uint(bs.Read(8))
t1 := uint(bs.Read(8))
t[0] = uint8(t0)
t[1] = uint8(t1)
if t0 > t1 {
t[2] = uint8((6*t0 + 1*t1) / 7)
t[3] = uint8((5*t0 + 2*t1) / 7)
t[4] = uint8((4*t0 + 3*t1) / 7)
t[5] = uint8((3*t0 + 4*t1) / 7)
t[6] = uint8((2*t0 + 5*t1) / 7)
t[7] = uint8((1*t0 + 6*t1) / 7)
} else {
t[2] = uint8((4*t0 + 1*t1) / 5)
t[3] = uint8((3*t0 + 2*t1) / 5)
t[4] = uint8((2*t0 + 3*t1) / 5)
t[5] = uint8((1*t0 + 3*t1) / 5)
t[6] = 0
t[7] = 255
}
for i := range a {
a[i] = t[bs.Read(3)]
}
c[0][2] = bs.Read(5) << 3
c[0][1] = bs.Read(5) << 3
c[0][0] = bs.Read(5) << 3
bs.ReadBit()
c[3][2] = bs.Read(5) << 3
c[3][1] = bs.Read(6) << 2
c[3][0] = bs.Read(5) << 3
for i := 0; i < 3; i++ {
c[1][i] = (c[0][i]*2 + c[3][i]*1) / 3
c[2][i] = (c[0][i]*1 + c[3][i]*2) / 3
}
p := 0
for y := by * 4; y < (by+1)*4; y++ {
for x := bx * 4; x < (bx+1)*4; x++ {
idx := bs.Read(2)
if x < width && y < height {
j = 4 * (y*width + x)
dst[j+0] = uint8(c[idx][0])
dst[j+1] = uint8(c[idx][1])
dst[j+2] = uint8(c[idx][2])
dst[j+3] = a[p]
p++
}
}
}
}
}
return dst, nil
})
}