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

#ifndef SkTextureCompressor_DEFINED
#define SkTextureCompressor_DEFINED

#include "SkBitmapProcShader.h"
#include "SkImageInfo.h"

class SkBitmap;
class SkBlitter;
class SkData;

namespace SkTextureCompressor {
    // Various texture compression formats that we support.
    enum Format {
        // Alpha only formats.
        kLATC_Format,       // 4x4 blocks, (de)compresses A8
        kR11_EAC_Format,    // 4x4 blocks, (de)compresses A8

        // RGB only formats
        kETC1_Format,       // 4x4 blocks, compresses RGB 565, decompresses 8-bit RGB
                            //    NOTE: ETC1 supports 8-bit RGB compression, but we
                            //    currently don't have any RGB8 SkColorTypes. We could
                            //    support 8-bit RGBA but we would have to preprocess the
                            //    bitmap to insert alphas.

        // Multi-purpose formats
        kASTC_4x4_Format,   // 4x4 blocks, no compression, decompresses RGBA
        kASTC_5x4_Format,   // 5x4 blocks, no compression, decompresses RGBA
        kASTC_5x5_Format,   // 5x5 blocks, no compression, decompresses RGBA
        kASTC_6x5_Format,   // 6x5 blocks, no compression, decompresses RGBA
        kASTC_6x6_Format,   // 6x6 blocks, no compression, decompresses RGBA
        kASTC_8x5_Format,   // 8x5 blocks, no compression, decompresses RGBA
        kASTC_8x6_Format,   // 8x6 blocks, no compression, decompresses RGBA
        kASTC_8x8_Format,   // 8x8 blocks, no compression, decompresses RGBA
        kASTC_10x5_Format,  // 10x5 blocks, no compression, decompresses RGBA
        kASTC_10x6_Format,  // 10x6 blocks, no compression, decompresses RGBA
        kASTC_10x8_Format,  // 10x8 blocks, no compression, decompresses RGBA
        kASTC_10x10_Format, // 10x10 blocks, no compression, decompresses RGBA
        kASTC_12x10_Format, // 12x10 blocks, no compression, decompresses RGBA
        kASTC_12x12_Format, // 12x12 blocks, compresses A8, decompresses RGBA

        kLast_Format = kASTC_12x12_Format
    };
    static const int kFormatCnt = kLast_Format + 1;

    // Returns the size of the compressed data given the width, height, and
    // desired compression format. If the width and height are not an appropriate
    // multiple of the block size, then this function returns an error (-1).
    int GetCompressedDataSize(Format fmt, int width, int height);

    // Returns an SkData holding a blob of compressed data that corresponds
    // to the pixmap. If the pixmap colorType cannot be compressed using the
    // associated format, then we return nullptr.
    sk_sp<SkData> CompressBitmapToFormat(const SkPixmap&, Format format);

    // Compresses the given src data into dst. The src data is assumed to be
    // large enough to hold width*height pixels. The dst data is expected to
    // be large enough to hold the compressed data according to the format.
    bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcColorType,
                                int width, int height, size_t rowBytes, Format format);

    // Decompresses the given src data from the format specified into the
    // destination buffer. The width and height of the data passed corresponds
    // to the width and height of the uncompressed image. The destination buffer (dst)
    // is assumed to be large enough to hold the entire decompressed image. The
    // decompressed image colors are determined based on the passed format.
    //
    // Note, CompressBufferToFormat compresses A8 data into ASTC. However,
    // general ASTC data encodes RGBA data, so that is what the decompressor
    // operates on.
    //
    // Returns true if successfully decompresses the src data.
    bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* src,
                                    int width, int height, Format format);

    // Returns true if there exists a blitter for the specified format.
    inline bool ExistsBlitterForFormat(Format format) {
        switch (format) {
            case kLATC_Format:
            case kR11_EAC_Format:
            case kASTC_12x12_Format:
                return true;

            default:
                return false;
        }
    }

    // Returns the blitter for the given compression format. Note, the blitter
    // is intended to be used with the proper input. I.e. if you try to blit
    // RGB source data into an R11 EAC texture, you're gonna have a bad time.
    SkBlitter* CreateBlitterForFormat(int width, int height, void* compressedBuffer,
                                      SkTBlitterAllocator *allocator, Format format);

    // Returns the desired dimensions of the block size for the given format. These dimensions
    // don't necessarily correspond to the specification's dimensions, since there may
    // be specialized algorithms that operate on multiple blocks at once. If the
    // flag 'matchSpec' is true, then the actual dimensions from the specification are
    // returned. If the flag is false, then these dimensions reflect the appropriate operable
    // dimensions of the compression functions.
    void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec = false);
}

#endif
