/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/core/SkCompressedDataUtils.h"

#include "include/core/SkBitmap.h"
#include "include/core/SkColor.h"
#include "include/core/SkData.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/private/base/SkTPin.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkMathPriv.h"
#include "src/core/SkColorData.h"
#include "src/core/SkColorPriv.h"
#include "src/core/SkMipmap.h"

#include <algorithm>
#include <cstdint>

using namespace skia_private;

struct ETC1Block {
    uint32_t fHigh;
    uint32_t fLow;
};

constexpr uint32_t kFlipBit = 0x1; // set -> T/B sub-blocks; not-set -> L/R sub-blocks
constexpr uint32_t kDiffBit = 0x2; // set -> differential; not-set -> individual

static inline int extend_4To8bits(int b) {
    int c = b & 0xf;
    return (c << 4) | c;
}

static inline int extend_5To8bits(int b) {
    int c = b & 0x1f;
    return (c << 3) | (c >> 2);
}

static inline int extend_5plus3To8Bits(int base, int diff) {
    static const int kLookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };

    return extend_5To8bits((0x1f & base) + kLookup[0x7 & diff]);
}

static const int kNumETC1ModifierTables = 8;
static const int kNumETC1PixelIndices = 4;

// The index of each row in this table is the ETC1 table codeword
// The index of each column in this table is the ETC1 pixel index value
static const int kETC1ModifierTables[kNumETC1ModifierTables][kNumETC1PixelIndices] = {
    /* 0 */ { 2,    8,  -2,   -8 },
    /* 1 */ { 5,   17,  -5,  -17 },
    /* 2 */ { 9,   29,  -9,  -29 },
    /* 3 */ { 13,  42, -13,  -42 },
    /* 4 */ { 18,  60, -18,  -60 },
    /* 5 */ { 24,  80, -24,  -80 },
    /* 6 */ { 33, 106, -33, -106 },
    /* 7 */ { 47, 183, -47, -183 }
};

static int num_4x4_blocks(int size) {
    return ((size + 3) & ~3) >> 2;
}

// Return which sub-block a given x,y location in the overall 4x4 block belongs to
static int xy_to_subblock_index(int x, int y, bool flip) {
    SkASSERT(x >= 0 && x < 4);
    SkASSERT(y >= 0 && y < 4);

    if (flip) {
        return y < 2 ? 0 : 1; // sub-block 1 is on top of sub-block 2
    } else {
        return x < 2 ? 0 : 1; // sub-block 1 is to the left of sub-block 2
    }
}

struct IColor {
    int fR, fG, fB;
};

static SkPMColor add_delta_and_clamp(const IColor& col, int delta) {
    int r8 = SkTPin(col.fR + delta, 0, 255);
    int g8 = SkTPin(col.fG + delta, 0, 255);
    int b8 = SkTPin(col.fB + delta, 0, 255);

    return SkPackARGB32(0xFF, r8, g8, b8);
}

static bool decompress_etc1(SkISize dimensions, const uint8_t* srcData, SkBitmap* dst) {
    const ETC1Block* srcBlocks = reinterpret_cast<const ETC1Block*>(srcData);

    int numXBlocks = num_4x4_blocks(dimensions.width());
    int numYBlocks = num_4x4_blocks(dimensions.height());

    for (int y = 0; y < numYBlocks; ++y) {
        for (int x = 0; x < numXBlocks; ++x) {
            const ETC1Block* curBlock1 = &srcBlocks[y * numXBlocks + x];
            uint32_t high = SkBSwap32(curBlock1->fHigh);
            uint32_t low = SkBSwap32(curBlock1->fLow);

            bool flipped = SkToBool(high & kFlipBit);
            bool differential = SkToBool(high & kDiffBit);

            IColor colors[2];

            if (differential) {
                colors[0].fR = extend_5To8bits(high >> 27);
                colors[1].fR = extend_5plus3To8Bits(high >> 27, high >> 24);
                colors[0].fG = extend_5To8bits(high >> 19);
                colors[1].fG = extend_5plus3To8Bits(high >> 19, high >> 16);
                colors[0].fB = extend_5To8bits(high >> 11);
                colors[1].fB = extend_5plus3To8Bits(high >> 11, high >> 8);
            } else {
                colors[0].fR = extend_4To8bits(high >> 28);
                colors[1].fR = extend_4To8bits(high >> 24);
                colors[0].fG = extend_4To8bits(high >> 20);
                colors[1].fG = extend_4To8bits(high >> 16);
                colors[0].fB = extend_4To8bits(high >> 12);
                colors[1].fB = extend_4To8bits(high >> 8);
            }

            int tableIndex0 = (high >> 5) & 0x7;
            int tableIndex1 = (high >> 2) & 0x7;
            const int* tables[2] = {
                kETC1ModifierTables[tableIndex0],
                kETC1ModifierTables[tableIndex1]
            };

            int baseShift = 0;
            int offsetX = 4 * x, offsetY = 4 * y;
            for (int i = 0; i < 4; ++i, ++baseShift) {
                for (int j = 0; j < 4; ++j) {
                    if (offsetX + j >= dst->width() || offsetY + i >= dst->height()) {
                        // This can happen for the topmost levels of a mipmap and for
                        // non-multiple of 4 textures
                        continue;
                    }

                    int subBlockIndex = xy_to_subblock_index(j, i, flipped);
                    int pixelIndex = ((low >> (baseShift+(j*4))) & 0x1) |
                                     (low >> (baseShift+(j*4)+15) & 0x2);

                    SkASSERT(subBlockIndex == 0 || subBlockIndex == 1);
                    SkASSERT(pixelIndex >= 0 && pixelIndex < 4);

                    int delta = tables[subBlockIndex][pixelIndex];
                    *dst->getAddr32(offsetX + j, offsetY + i) =
                                                add_delta_and_clamp(colors[subBlockIndex], delta);
                }
            }
        }
    }

    return true;
}

//------------------------------------------------------------------------------------------------
struct BC1Block {
    uint16_t fColor0;
    uint16_t fColor1;
    uint32_t fIndices;
};

static SkPMColor from565(uint16_t rgb565) {
    uint8_t r8 = SkR16ToR32((rgb565 >> 11) & 0x1F);
    uint8_t g8 = SkG16ToG32((rgb565 >> 5) & 0x3F);
    uint8_t b8 = SkB16ToB32(rgb565 & 0x1F);

    return SkPackARGB32(0xFF, r8, g8, b8);
}

// return t*col0 + (1-t)*col1
static SkPMColor lerp(float t, SkPMColor col0, SkPMColor col1) {
    SkASSERT(SkGetPackedA32(col0) == 0xFF && SkGetPackedA32(col1) == 0xFF);

    // TODO: given 't' is only either 1/3 or 2/3 this could be done faster
    uint8_t r8 = SkScalarRoundToInt(t * SkGetPackedR32(col0) + (1.0f - t) * SkGetPackedR32(col1));
    uint8_t g8 = SkScalarRoundToInt(t * SkGetPackedG32(col0) + (1.0f - t) * SkGetPackedG32(col1));
    uint8_t b8 = SkScalarRoundToInt(t * SkGetPackedB32(col0) + (1.0f - t) * SkGetPackedB32(col1));
    return SkPackARGB32(0xFF, r8, g8, b8);
}

static bool decompress_bc1(SkISize dimensions, const uint8_t* srcData,
                           bool isOpaque, SkBitmap* dst) {
    const BC1Block* srcBlocks = reinterpret_cast<const BC1Block*>(srcData);

    int numXBlocks = num_4x4_blocks(dimensions.width());
    int numYBlocks = num_4x4_blocks(dimensions.height());

    SkPMColor colors[4];

    for (int y = 0; y < numYBlocks; ++y) {
        for (int x = 0; x < numXBlocks; ++x) {
            const BC1Block* curBlock = &srcBlocks[y * numXBlocks + x];

            colors[0] = from565(curBlock->fColor0);
            colors[1] = from565(curBlock->fColor1);
            if (curBlock->fColor0 <= curBlock->fColor1) {        // signal for a transparent block
                colors[2] = SkPackARGB32(
                    0xFF,
                    (SkGetPackedR32(colors[0]) + SkGetPackedR32(colors[1])) >> 1,
                    (SkGetPackedG32(colors[0]) + SkGetPackedG32(colors[1])) >> 1,
                    (SkGetPackedB32(colors[0]) + SkGetPackedB32(colors[1])) >> 1);
                // The opacity of the overall texture trumps the per-block transparency
                colors[3] = SkPackARGB32(isOpaque ? 0xFF : 0, 0, 0, 0);
            } else {
                colors[2] = lerp(2.0f/3.0f, colors[0], colors[1]);
                colors[3] = lerp(1.0f/3.0f, colors[0], colors[1]);
            }

            int shift = 0;
            int offsetX = 4 * x, offsetY = 4 * y;
            for (int i = 0; i < 4; ++i) {
                for (int j = 0; j < 4; ++j, shift += 2) {
                    if (offsetX + j >= dst->width() || offsetY + i >= dst->height()) {
                        // This can happen for the topmost levels of a mipmap and for
                        // non-multiple of 4 textures
                        continue;
                    }

                    int index = (curBlock->fIndices >> shift) & 0x3;
                    *dst->getAddr32(offsetX + j, offsetY + i) = colors[index];
                }
            }
        }
    }

    return true;
}

bool SkDecompress(sk_sp<SkData> data,
                  SkISize dimensions,
                  SkTextureCompressionType compressionType,
                  SkBitmap* dst) {
    using Type = SkTextureCompressionType;

    const uint8_t* bytes = data->bytes();
    switch (compressionType) {
        case Type::kNone:            return false;
        case Type::kETC2_RGB8_UNORM: return decompress_etc1(dimensions, bytes, dst);
        case Type::kBC1_RGB8_UNORM:  return decompress_bc1(dimensions, bytes, true, dst);
        case Type::kBC1_RGBA8_UNORM: return decompress_bc1(dimensions, bytes, false, dst);
    }

    SkUNREACHABLE;
}

size_t SkCompressedDataSize(SkTextureCompressionType type, SkISize dimensions,
                            TArray<size_t>* individualMipOffsets, bool mipmapped) {
    SkASSERT(!individualMipOffsets || individualMipOffsets->empty());

    int numMipLevels = 1;
    if (mipmapped) {
        numMipLevels = SkMipmap::ComputeLevelCount(dimensions) + 1;
    }

    size_t totalSize = 0;
    switch (type) {
        case SkTextureCompressionType::kNone:
            break;
        case SkTextureCompressionType::kETC2_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGBA8_UNORM: {
            for (int i = 0; i < numMipLevels; ++i) {
                int numBlocks = num_4x4_blocks(dimensions.width()) *
                                num_4x4_blocks(dimensions.height());

                if (individualMipOffsets) {
                    individualMipOffsets->push_back(totalSize);
                }

                static_assert(sizeof(ETC1Block) == sizeof(BC1Block));
                totalSize += numBlocks * sizeof(ETC1Block);

                dimensions = {std::max(1, dimensions.width()/2), std::max(1, dimensions.height()/2)};
            }
            break;
        }
    }

    return totalSize;
}

size_t SkCompressedBlockSize(SkTextureCompressionType type) {
    switch (type) {
        case SkTextureCompressionType::kNone:
            return 0;
        case SkTextureCompressionType::kETC2_RGB8_UNORM:
            return sizeof(ETC1Block);
        case SkTextureCompressionType::kBC1_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGBA8_UNORM:
            return sizeof(BC1Block);
    }
    SkUNREACHABLE;
}

size_t SkCompressedFormatDataSize(SkTextureCompressionType compressionType,
                                  SkISize dimensions, bool mipmapped) {
    return SkCompressedDataSize(compressionType, dimensions, nullptr, mipmapped);
}
