// Copyright (C) 2015 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/binary"

type fmtETC1_RGB8_OES struct{ binary.Generate }

func (*fmtETC1_RGB8_OES) String() string { return "ETC1_RGB8_OES" }
func (*fmtETC1_RGB8_OES) Check(d []byte, w, h int) error {
	return checkSize(d, max(w, 4), max(h, 4), 4)
}

// ETC1_RGB8_OES returns a format representing the texture compression format
// with the same name.
func ETC1_RGB8_OES() Format { return &fmtETC1_RGB8_OES{} }

func init() {
	RegisterConverter(ETC1_RGB8_OES(), RGBA(), func(src []byte, width, height int) ([]byte, error) {
		dst := make([]byte, width*height*4)

		block_width := max(width/4, 1)
		block_height := max(height/4, 1)

		c := [2][3]int32{}
		codes := [2][4]int32{}
		modTbl := [8][4]int32{
			{2, 8, -2, -8},
			{5, 17, -5, -17},
			{9, 29, -9, -29},
			{13, 42, -13, -42},
			{18, 60, -18, -60},
			{24, 80, -24, -80},
			{33, 106, -33, -106},
			{47, 183, -47, -183},
		}
		diffTbl := [8]int32{0, 1, 2, 3, -4, -3, -2, -1}
		flipTbl := [2][16]int32{
			{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
			{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
		}
		for by := 0; by < block_height; by++ {
			for bx := 0; bx < block_width; bx++ {
				u64 := uint64(src[0])
				u64 = (u64 << 8) | uint64(src[1])
				u64 = (u64 << 8) | uint64(src[2])
				u64 = (u64 << 8) | uint64(src[3])
				u64 = (u64 << 8) | uint64(src[4])
				u64 = (u64 << 8) | uint64(src[5])
				u64 = (u64 << 8) | uint64(src[6])
				u64 = (u64 << 8) | uint64(src[7])
				src = src[8:]
				flip := (u64 >> 32) & 1
				diff := (u64 >> 33) & 1

				codes[0] = modTbl[(u64>>37)&7]
				codes[1] = modTbl[(u64>>34)&7]

				for i := uint(0); i < 3; i++ {
					if diff == 0 {
						a := (u64 >> (44 + i*8)) & 15
						b := (u64 >> (40 + i*8)) & 15
						c[0][i] = int32((a << 4) | a)
						c[1][i] = int32((b << 4) | b)
					} else {
						a := (u64 >> (43 + i*8)) & 31
						b := (u64 >> (40 + i*8)) & 7
						d := int32(int32(a) + diffTbl[b])
						c[0][i] = int32((a << 3) | (a >> 2))
						c[1][i] = int32((d << 3) | (d >> 2))
					}
				}

				blockTbl := flipTbl[flip]

				i := uint(0)
				for x := bx * 4; x < (bx+1)*4; x++ {
					for y := by * 4; y < (by+1)*4; y++ {
						if x < width && y < height {
							block := blockTbl[i]
							base := c[block]
							k := 4 * (y*width + x)
							idx := ((u64 >> i) & 1) | ((u64 >> (15 + i)) & 2)
							shift := codes[block][idx]
							dst[k+0] = toByte(base[2] + shift)
							dst[k+1] = toByte(base[1] + shift)
							dst[k+2] = toByte(base[0] + shift)
							dst[k+3] = 255
							i++
						}
					}
				}
			}
		}

		return dst, nil
	})
}
