| // 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_test |
| |
| import ( |
| "testing" |
| |
| "android.googlesource.com/platform/tools/gpu/framework/assert" |
| "android.googlesource.com/platform/tools/gpu/gapid/image" |
| ) |
| |
| func TestRGB1010102Conversion(t *testing.T) { |
| ctx := assert.Context(t) |
| |
| // Generate a 10bit by 2bit image. |
| in := make([]byte, 4*0x400*4) |
| for o, a := 0, 0; a < 4; a++ { |
| for c := 0; c < 0x400; c, o = c+1, o+4 { |
| abgr := gen10BitColor(c, a) |
| in[o+0], in[o+1], in[o+2], in[o+3] = |
| uint8(abgr&0xff), uint8((abgr>>8)&0xff), uint8((abgr>>16)&0xff), uint8((abgr>>24)&0xff) |
| } |
| } |
| |
| out, err := image.Convert(in, 0x400, 4, image.RGBA1010102(), image.RGBA()) |
| assert.With(ctx).ThatError(err).Succeeded() |
| assert.With(ctx).ThatSlice(out).IsLength(len(in)) |
| |
| rc, ac := make(intmap), make(intmap) |
| for o, y := 0, 0; y < 4; y++ { |
| for x := 0; x < 0x400; x, o = x+1, o+4 { |
| r, g, b, a := decompose8BitColor(y, out[o:]) |
| |
| assert.With(ctx).ThatInteger(r).Equals(g) |
| assert.With(ctx).ThatInteger(r).Equals(b) |
| |
| rc[r]++ |
| ac[a]++ |
| } |
| } |
| |
| assertHasEvenDistribution(ctx, rc, 256) |
| assertHasEvenDistribution(ctx, ac, 4) |
| } |
| |
| // Shift amounts used by gen10BitColor and decompose8BitColor. |
| const ( |
| off_10b = 0xd0 |
| off_8b = off_10b / 4 |
| ) |
| |
| // Generates a rgba1010102 color given c (0..0x400) and a (0..4) |
| // r = c, and g and b are c shifted by an amount dependent on a. |
| func gen10BitColor(c, a int) int { |
| r, g, b := c, (off_10b*(a+1)+c)%0x400, (off_10b*(a+3)+c)%0x400 |
| return a << 30 | (b << 20) | (g << 10) | r |
| } |
| |
| // Undoes what gen10BitColor did, but in 8 bit space. If the conversion was |
| // done correctly, r = g = b |
| func decompose8BitColor(y int, in []byte) (int, int, int, int) { |
| return int(in[0]), |
| (0x200 - off_8b*(y+1) + int(in[1])) % 0x100, |
| (0x200 - off_8b*(y+3) + int(in[2])) % 0x100, |
| int(in[3]) |
| } |