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

#include "SkTextureCompressor.h"
#include "SkTextureCompressor_ASTC.h"
#include "SkTextureCompressor_LATC.h"
#include "SkTextureCompressor_R11EAC.h"

#include "SkBitmap.h"
#include "SkBitmapProcShader.h"
#include "SkData.h"
#include "SkEndian.h"

#include "SkTextureCompression_opts.h"

#ifndef SK_IGNORE_ETC1_SUPPORT
#  include "etc1.h"
#endif

// Convert ETC1 functions to our function signatures
static bool compress_etc1_565(uint8_t* dst, const uint8_t* src,
                              int width, int height, int rowBytes) {
#ifndef SK_IGNORE_ETC1_SUPPORT
    return 0 == etc1_encode_image(src, width, height, 2, rowBytes, dst);
#else
    return false;
#endif
}

////////////////////////////////////////////////////////////////////////////////

namespace SkTextureCompressor {

void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec) {
    if (NULL == dimX || NULL == dimY) {
        return;
    }

    if (!matchSpec && SkTextureCompressorGetPlatformDims(format, dimX, dimY)) {
        return;
    }

    // No specialized arguments, return the dimensions as they are in the spec.
    switch(format) {
        // These formats are 64 bits per 4x4 block.
        default:
            SkDEBUGFAIL("Unknown compression format!");
            // fall through
        case kLATC_Format:
        case kR11_EAC_Format:
        case kETC1_Format: 
            *dimX = 4;
            *dimY = 4;
            break;

        // This format is 12x12 blocks to 128 bits.
        case kASTC_12x12_Format:
            *dimX = 12;
            *dimY = 12;
            break;        
    }
}

int GetCompressedDataSize(Format fmt, int width, int height) {
    int dimX, dimY;
    GetBlockDimensions(fmt, &dimX, &dimY, true);

    int encodedBlockSize = 0;
            
    switch (fmt) {
        // These formats are 64 bits per 4x4 block.
        case kLATC_Format:
        case kR11_EAC_Format:
        case kETC1_Format:
            encodedBlockSize = 8;
            break;

        // This format is 12x12 blocks to 128 bits.
        case kASTC_12x12_Format:
            encodedBlockSize = 16;
            break;

        default:
            SkFAIL("Unknown compressed format!");
            return -1;
    }

    if(((width % dimX) == 0) && ((height % dimY) == 0)) {
        const int blocksX = width / dimX;
        const int blocksY = height / dimY;

        return blocksX * blocksY * encodedBlockSize;
    }

    return -1;
}

bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcColorType,
                            int width, int height, int rowBytes, Format format, bool opt) {
    CompressionProc proc = NULL;
    if (opt) {
        proc = SkTextureCompressorGetPlatformProc(srcColorType, format);
    }

    if (NULL == proc) {
        switch (srcColorType) {
            case kAlpha_8_SkColorType:
            {
                switch (format) {
                    case kLATC_Format:
                        proc = CompressA8ToLATC;
                        break;
                    case kR11_EAC_Format:
                        proc = CompressA8ToR11EAC;
                        break;
                    case kASTC_12x12_Format:
                        proc = CompressA8To12x12ASTC;
                        break;
                    default:
                        // Do nothing...
                        break;
                }
            }
            break;

            case kRGB_565_SkColorType:
            {
                switch (format) {
                    case kETC1_Format:
                        proc = compress_etc1_565;
                        break;
                    default:
                        // Do nothing...
                        break;
                }
            }
            break;

            default:
                // Do nothing...
                break;
        }
    }

    if (NULL != proc) {
        return proc(dst, src, width, height, rowBytes);
    }

    return false;
}

SkData *CompressBitmapToFormat(const SkBitmap &bitmap, Format format) {
    SkAutoLockPixels alp(bitmap);

    int compressedDataSize = GetCompressedDataSize(format, bitmap.width(), bitmap.height());
    if (compressedDataSize < 0) {
        return NULL;
    }

    const uint8_t* src = reinterpret_cast<const uint8_t*>(bitmap.getPixels());
    uint8_t* dst = reinterpret_cast<uint8_t*>(sk_malloc_throw(compressedDataSize));

    if (CompressBufferToFormat(dst, src, bitmap.colorType(), bitmap.width(), bitmap.height(),
                               bitmap.rowBytes(), format)) {
        return SkData::NewFromMalloc(dst, compressedDataSize);
    }

    sk_free(dst);
    return NULL;
}

SkBlitter* CreateBlitterForFormat(int width, int height, void* compressedBuffer,
                                  SkTBlitterAllocator *allocator, Format format) {
    switch(format) {
        case kLATC_Format:
            return CreateLATCBlitter(width, height, compressedBuffer, allocator);

        case kR11_EAC_Format:
            return CreateR11EACBlitter(width, height, compressedBuffer, allocator);

        case kASTC_12x12_Format:
            return CreateASTCBlitter(width, height, compressedBuffer, allocator);

        default:
            return NULL;
    }

    return NULL;
}

bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* src,
                                int width, int height, Format format) {
    int dimX, dimY;
    GetBlockDimensions(format, &dimX, &dimY, true);

    if (width < 0 || ((width % dimX) != 0) || height < 0 || ((height % dimY) != 0)) {
        return false;
    }

    switch(format) {
        case kLATC_Format:
            DecompressLATC(dst, dstRowBytes, src, width, height);
            return true;

        case kR11_EAC_Format:
            DecompressR11EAC(dst, dstRowBytes, src, width, height);
            return true;

#ifndef SK_IGNORE_ETC1_SUPPORT
        case kETC1_Format:
            return 0 == etc1_decode_image(src, dst, width, height, 3, dstRowBytes);
#endif
        case kASTC_12x12_Format:
            // TODO(krajcevski) .. right now just fall through and return false.
            return false;

        default:
            // Do nothing...
            break;
    }

    return false;
}

}  // namespace SkTextureCompressor
