/*
 * Copyright 2010, 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.
 */

#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkColorPriv.h"
#include "SkDither.h"
#include "SkScaledBitmapSampler.h"
#include "SkStream.h"
#include "SkTemplates.h"
#include "SkUtils.h"

// A WebP decoder only, on top of (subset of) libwebp
// For more information on WebP image format, and libwebp library, see:
//   http://code.google.com/speed/webp/
//   http://www.webmproject.org/code/#libwebp_webp_image_decoder_library
//   http://review.webmproject.org/gitweb?p=libwebp.git

#include <stdio.h>
extern "C" {
// If moving libwebp out of skia source tree, path for webp headers must be updated accordingly.
// Here, we enforce using local copy in webp sub-directory.
#include "webp/decode.h"
#include "webp/decode_vp8.h"
#include "webp/encode.h"
}

/* If defined, work around missing padding byte in content generated by webpconv */
#define WEBPCONV_MISSING_PADDING 1

#ifdef ANDROID
#include <cutils/properties.h>

// Key to lookup the size of memory buffer set in system property
static const char KEY_MEM_CAP[] = "ro.media.dec.webp.memcap";
#endif

// this enables timing code to report milliseconds for a decode
//#define TIME_DECODE

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

// Define VP8 I/O on top of Skia stream

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

// An helper to extract a integer (little endian) from byte array. This is
// called only once per decoding, so no real need to optimize it in any way
static uint32_t getint32l(unsigned char *in) {
    int result;
    unsigned char *buffer = (unsigned char*) in;

    if (buffer == NULL) {
        return 0;
    }

    result = buffer[3];
    result = (result << 8) + buffer[2];
    result = (result << 8) + buffer[1];
    result = (result << 8) + buffer[0];

    return result;
}

static const size_t WEBP_VP8_HEADER_SIZE = 30;
static const size_t WEBP_IDECODE_BUFFER_SZ = (1 << 16);

// Parse headers of RIFF container, and check for valid Webp (VP8) content.
static bool webp_parse_header(SkStream* stream, int* width, int* height) {
    unsigned char buffer[WEBP_VP8_HEADER_SIZE];
    const size_t len = stream->read(buffer, WEBP_VP8_HEADER_SIZE);
    if (len != WEBP_VP8_HEADER_SIZE) {
        return false; // can't read enough
    }

    if (WebPGetInfo(buffer, WEBP_VP8_HEADER_SIZE, width, height) == 0) {
        return false; // Invalid WebP file.
    }

    // sanity check for image size that's about to be decoded.
    {
        Sk64 size;
        size.setMul(*width, *height);
        if (size.isNeg() || !size.is32()) {
            return false;
        }
        // now check that if we are 4-bytes per pixel, we also don't overflow
        if (size.get32() > (0x7FFFFFFF >> 2)) {
            return false;
        }
    }
    return true;
}

class SkWEBPImageDecoder: public SkImageDecoder {
public:
    virtual Format getFormat() const {
        return kWEBP_Format;
    }

protected:
    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);

private:
    bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height);
};

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

#include "SkTime.h"

class AutoTimeMillis {
public:
    AutoTimeMillis(const char label[]) :
        fLabel(label) {
        if (!fLabel) {
            fLabel = "";
        }
        fNow = SkTime::GetMSecs();
    }
    ~AutoTimeMillis() {
        SkDebugf("---- Time (ms): %s %d\n", fLabel, SkTime::GetMSecs() - fNow);
    }
private:
    const char* fLabel;
    SkMSec fNow;
};

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

// This guy exists just to aid in debugging, as it allows debuggers to just
// set a break-point in one place to see all error exists.
static bool return_false(const SkBitmap& bm, const char msg[]) {
#if 0
    SkDebugf("libwebp error %s [%d %d]", msg, bm.width(), bm.height());
#endif
    return false; // must always return false
}

typedef struct {
    SkBitmap* image;
    SkStream* stream;
} WEBPImage;

// WebP library embeds its own YUV to RGB converter. However, High-level API doesn't take benefit
// of (U,v) clipped values being valid for up to 4 pixels, and so there is a significant improvement
// in performance in handling this on our own.
// TODO: use architecture-optimized (eventually hardware-accelerated) YUV converters
#define YUV_HALF (1 << (YUV_FIX - 1))
#define YUV_FIX 16                   // fixed-point precision
#define YUV_RANGE_MIN (-227)         // min value of r/g/b output
#define YUV_RANGE_MAX (256 + 226)    // max value of r/g/b output
static int16_t VP8kVToR[256], VP8kUToB[256];
static int32_t VP8kVToG[256], VP8kUToG[256];
static uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];

static void yuv_init_tables() {
    int i;

    for (i = 0; i < 256; ++i) {
        VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX;
        VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF;
        VP8kVToG[i] = -45773 * (i - 128);
        VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX;
    }
    for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
        const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX;
        VP8kClip[i - YUV_RANGE_MIN] = (k < 0) ? 0 : (k > 255) ? 255 : k;
    }
}

// Static global mutex to protect Webp initialization
static SkMutex gYUVMutex;
static bool gYUVReady = false;

static bool yuv_init() {
    if (!gYUVReady) {
        gYUVMutex.acquire();
        if (!gYUVReady) {
            yuv_init_tables();
            gYUVReady = true;
        }
        gYUVMutex.release();
    }

    return gYUVReady;
}

#define PutRGBA(p,r,g,b) (((SkPMColor*) (p))[0] = SkPackARGB32(0xff,(r),(g),(b)))
#define PutRGB565(p,r,g,b) (((SkPMColor16*) (p))[0] = SkPackRGB16((r)>>3,(g)>>2,(b)>>3))
#define PutRGBA4444(p,r,g,b) (((SkPMColor16*) (p))[0] = SkPackARGB4444(0xf,(r)>>4,(g)>>4,(b)>>4))

#define CRGBA(p,y,roff,goff,boff) PutRGBA(p,         \
          VP8kClip[(y) + (roff) - YUV_RANGE_MIN],    \
          VP8kClip[(y) + (goff) - YUV_RANGE_MIN],    \
          VP8kClip[(y) + (boff) - YUV_RANGE_MIN])
#define CRGB565(p,y,roff,goff,boff) PutRGB565(p,     \
          VP8kClip[(y) + (roff) - YUV_RANGE_MIN],    \
          VP8kClip[(y) + (goff) - YUV_RANGE_MIN],    \
          VP8kClip[(y) + (boff) - YUV_RANGE_MIN])
#define CRGBA4444(p,y,roff,goff,boff) PutRGBA4444(p, \
          VP8kClip[(y) + (roff) - YUV_RANGE_MIN],    \
          VP8kClip[(y) + (goff) - YUV_RANGE_MIN],    \
          VP8kClip[(y) + (boff) - YUV_RANGE_MIN])

static int block_put(const VP8Io* io) {
    WEBPImage *p = (WEBPImage*) io->opaque;
    SkBitmap* decodedBitmap = p->image;

    const int w = io->width;
    const int mb_h = io->mb_h;

    const uint8_t *y, *y2, *u, *v;
    const uint8_t *py, *py2, *pu, *pv;

    uint8_t* pout;
    uint8_t* pout2;

    int i, j;
    const int ystride2 = io->y_stride * 2;
    int bpp;
    SkBitmap::Config config = decodedBitmap->config();

    //SkASSERT(!(io->mb_y & 1));

    y = io->y;
    u = io->u;
    v = io->v;

    switch (config) {
        case SkBitmap::kARGB_8888_Config:
            bpp = 4;
            break;
        case SkBitmap::kRGB_565_Config:
            bpp = 2;
            break;
        case SkBitmap::kARGB_4444_Config:
            bpp = 2;
            break;
        default:
            // Unsupported config
            return 0;
    }

    for (j = 0; j < mb_h;) {
        pout = decodedBitmap->getAddr8(0, io->mb_y + j);
        if (j + 1 < mb_h) {
            y2 = y + io->y_stride;
            pout2 = decodedBitmap->getAddr8(0, io->mb_y + j + 1);
        } else {
            y2 = NULL;
            pout2 = NULL;
        }

        // Copy YUV into target buffer
        py = y;
        pu = u;
        pv = v;

        py2 = y2;

        // Leave test for config out of inner loop. This implies some redundancy in code,
        // but help in supporting several configs without degrading performance.
        // As a reminder, one must *NOT* put py increment into parameters (i.e. *py++) in the hope to
        // improve performance or code readability. Since it is used as argument of a macro which uses it
        // several times in its expression, so this would end up in having it too much incremented
        switch (config) {
            case SkBitmap::kARGB_8888_Config:
                for (i = 0; i < w; i += 2) {
                    // U and V are common for up to 4 pixels
                    const int r_off = VP8kVToR[*pv];
                    const int g_off = (VP8kVToG[*pv] + VP8kUToG[*pu]) >> YUV_FIX;
                    const int b_off = VP8kUToB[*pu];

                    CRGBA(pout, *py, r_off, g_off, b_off);
                    pout += bpp;
                    py++;

                    // Width shouldn't be odd, so this should always be true
                    if (i + 1 < w) {
                        CRGBA(pout, *py, r_off, g_off, b_off);
                        pout += bpp;
                        py++;
                    }

                    if (pout2) {
                        CRGBA(pout2, *py2, r_off, g_off, b_off);
                        pout2 += bpp;
                        py2++;

                        // Width shouldn't be odd, so this should always be true
                        if (i + 1 < w) {
                            CRGBA(pout2, *py2, r_off, g_off, b_off);
                            pout2 += bpp;
                            py2++;
                        }
                    }

                    pu++;
                    pv++;
                }
                break;
            case SkBitmap::kRGB_565_Config:
                for (i = 0; i < w; i += 2) {
                    // U and V are common for up to 4 pixels
                    const int r_off = VP8kVToR[*pv];
                    const int g_off = (VP8kVToG[*pv] + VP8kUToG[*pu]) >> YUV_FIX;
                    const int b_off = VP8kUToB[*pu];

                    CRGB565(pout, *py, r_off, g_off, b_off);
                    pout += bpp;
                    py++;

                    // Width shouldn't be odd, so this should always be true
                    if (i + 1 < w) {
                        CRGB565(pout, *py, r_off, g_off, b_off);
                        pout += bpp;
                        py++;
                    }

                    if (pout2) {
                        CRGB565(pout2, *py2, r_off, g_off, b_off);
                        pout2 += bpp;
                        py2++;

                        // Width shouldn't be odd, so this should always be true
                        if (i + 1 < w) {
                            CRGB565(pout2, *py2, r_off, g_off, b_off);
                            pout2 += bpp;
                            py2++;
                        }
                    }

                    pu++;
                    pv++;
                }
                break;
            case SkBitmap::kARGB_4444_Config:
                for (i = 0; i < w; i += 2) {
                    // U and V are common for up to 4 pixels
                    const int r_off = VP8kVToR[*pv];
                    const int g_off = (VP8kVToG[*pv] + VP8kUToG[*pu]) >> YUV_FIX;
                    const int b_off = VP8kUToB[*pu];

                    CRGBA4444(pout, *py, r_off, g_off, b_off);
                    pout += bpp;
                    py++;

                    // Width shouldn't be odd, so this should always be true
                    if (i + 1 < w) {
                        CRGBA4444(pout, *py, r_off, g_off, b_off);
                        pout += bpp;
                        py++;
                    }

                    if (pout2) {
                        CRGBA4444(pout2, *py2, r_off, g_off, b_off);
                        pout2 += bpp;
                        py2++;

                        // Width shouldn't be odd, so this should always be true
                        if (i + 1 < w) {
                            CRGBA4444(pout2, *py2, r_off, g_off, b_off);
                            pout2 += bpp;
                            py2++;
                        }
                    }

                    pu++;
                    pv++;
                }
                break;
            default:
                // Unsupported config (can't happen, but prevents compiler warning)
                SkASSERT(0);
                break;
        }

        if (y2) {
            // Scanned and populated two rows
            y += ystride2;
            y2 += ystride2;
            j += 2;
        } else {
            // Skip to next row
            y += io->y_stride;
            j++;
        }

        u += io->uv_stride;
        v += io->uv_stride;
    }

    return 1;
}

static int block_setup(VP8Io* io) {
    yuv_init();
    return 1;
}

static void block_teardown(const VP8Io* io) {
}

static bool webp_init_custom_io(WebPIDecoder* idec, SkBitmap* decodedBitmap) {
    if (idec == NULL) {
        return false;
    }

    WEBPImage pSrc;
    // Custom Put callback need reference to target image.
    pSrc.image = decodedBitmap;

    if (!WebPISetIOHooks(idec, block_put, block_setup, block_teardown,
                         (void*)&pSrc)) {
        return false;
    }

    return true;
}

// Incremental WebP image decoding. Reads input buffer of 64K size iteratively
// and decodes this block to appropriate color-space as per config object.
static bool webp_idecode(SkStream* stream, SkBitmap* decodedBitmap) {
    SkAutoLockPixels alp(*decodedBitmap);

    stream->rewind();
    const uint32_t contentSize = stream->getLength();

    WebPIDecoder* idec = WebPINew(MODE_YUV);
    if (idec == NULL) {
        return false;
    }

    if (!webp_init_custom_io(idec, decodedBitmap)) {
        WebPIDelete(idec);
        return false;
    }

    uint32_t read_buffer_size = contentSize;
    if (read_buffer_size > WEBP_IDECODE_BUFFER_SZ) {
        read_buffer_size = WEBP_IDECODE_BUFFER_SZ;
    }
    SkAutoMalloc srcStorage(read_buffer_size);
    unsigned char* input = (uint8_t*)srcStorage.get();
    if (input == NULL) {
        WebPIDelete(idec);
        return false;
    }

    uint32_t bytes_remaining = contentSize;
    while (bytes_remaining > 0) {
        const uint32_t bytes_to_read =
            (bytes_remaining > WEBP_IDECODE_BUFFER_SZ) ?
                WEBP_IDECODE_BUFFER_SZ : bytes_remaining;

        const size_t bytes_read = stream->read(input, bytes_to_read);
        if (bytes_read == 0) {
            break;
        }

        VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
        if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
            bytes_remaining -= bytes_read;
        } else {
            break;
        }
    }
    srcStorage.free();
    WebPIDelete(idec);

    if (bytes_remaining > 0) {
        return false;
    } else {
        return true;
    }
}

bool SkWEBPImageDecoder::setDecodeConfig(SkBitmap* decodedBitmap,
                                         int origWidth, int origHeight) {
    bool hasAlpha = false;
    SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, hasAlpha);

    // only accept prefConfig if it makes sense for us. YUV converter
    // supports output in RGB565, RGBA4444 and RGBA8888 formats.
    if (hasAlpha) {
        if (config != SkBitmap::kARGB_4444_Config) {
            config = SkBitmap::kARGB_8888_Config;
        }
    } else {
        if (config != SkBitmap::kRGB_565_Config &&
            config != SkBitmap::kARGB_4444_Config) {
            config = SkBitmap::kARGB_8888_Config;
        }
    }


    if (!this->chooseFromOneChoice(config, origWidth, origHeight)) {
        return false;
    }

    decodedBitmap->setConfig(config, origWidth, origHeight, 0);

    // Current WEBP specification has no support for alpha layer.
    decodedBitmap->setIsOpaque(true);

    return true;
}


bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
                                  Mode mode) {
#ifdef TIME_DECODE
    AutoTimeMillis atm("WEBP Decode");
#endif

    int origWidth, origHeight;
    if (!webp_parse_header(stream, &origWidth, &origHeight)) {
        return false;
    }

    if (!setDecodeConfig(decodedBitmap, origWidth, origHeight)) {
        return false;
    }

    // If only bounds are requested, done
    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
        return true;
    }

    if (!this->allocPixelRef(decodedBitmap, NULL)) {
        return return_false(*decodedBitmap, "allocPixelRef");
    }

    // Decode the WebP image data stream using WebP incremental decoding.
    if (!webp_idecode(stream, decodedBitmap)) {
        return false;
    }

    return true;
}

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

typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width,
                                 const SkPMColor* SK_RESTRICT ctable);

static void ARGB_8888_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
                             const SkPMColor*) {
  const uint32_t* SK_RESTRICT src = (const uint32_t*)in;
  for (int i = 0; i < width; ++i) {
      const uint32_t c = *src++;
      rgb[0] = SkGetPackedR32(c);
      rgb[1] = SkGetPackedG32(c);
      rgb[2] = SkGetPackedB32(c);
      rgb += 3;
  }
}

static void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
                           const SkPMColor*) {
  const uint16_t* SK_RESTRICT src = (const uint16_t*)in;
  for (int i = 0; i < width; ++i) {
      const uint16_t c = *src++;
      rgb[0] = SkPacked16ToR32(c);
      rgb[1] = SkPacked16ToG32(c);
      rgb[2] = SkPacked16ToB32(c);
      rgb += 3;
  }
}

static void ARGB_4444_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
                             const SkPMColor*) {
  const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in;
  for (int i = 0; i < width; ++i) {
      const SkPMColor16 c = *src++;
      rgb[0] = SkPacked4444ToR32(c);
      rgb[1] = SkPacked4444ToG32(c);
      rgb[2] = SkPacked4444ToB32(c);
      rgb += 3;
  }
}

static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
                          const SkPMColor* SK_RESTRICT ctable) {
  const uint8_t* SK_RESTRICT src = (const uint8_t*)in;
  for (int i = 0; i < width; ++i) {
      const uint32_t c = ctable[*src++];
      rgb[0] = SkGetPackedR32(c);
      rgb[1] = SkGetPackedG32(c);
      rgb[2] = SkGetPackedB32(c);
      rgb += 3;
  }
}

static ScanlineImporter ChooseImporter(const SkBitmap::Config& config) {
    switch (config) {
        case SkBitmap::kARGB_8888_Config:
            return ARGB_8888_To_RGB;
        case SkBitmap::kRGB_565_Config:
            return RGB_565_To_RGB;
        case SkBitmap::kARGB_4444_Config:
            return ARGB_4444_To_RGB;
        case SkBitmap::kIndex8_Config:
            return Index8_To_RGB;
        default:
            return NULL;
    }
}

static int StreamWriter(const uint8_t* data, size_t data_size,
                        const WebPPicture* const picture) {
  SkWStream* const stream = (SkWStream*)picture->custom_ptr;
  return stream->write(data, data_size) ? 1 : 0;
}

class SkWEBPImageEncoder : public SkImageEncoder {
protected:
    virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality);
};

bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm,
                                  int quality) {
    const SkBitmap::Config config = bm.getConfig();
    const ScanlineImporter scanline_import = ChooseImporter(config);
    if (NULL == scanline_import) {
        return false;
    }

    SkAutoLockPixels alp(bm);
    SkAutoLockColors ctLocker;
    if (NULL == bm.getPixels()) {
        return false;
    }

    WebPConfig webp_config;
    if (!WebPConfigPreset(&webp_config, WEBP_PRESET_DEFAULT, quality)) {
        return false;
    }

    WebPPicture pic;
    WebPPictureInit(&pic);
    pic.width = bm.width();
    pic.height = bm.height();
    pic.writer = StreamWriter;
    pic.custom_ptr = (void*)stream;

    const SkPMColor* colors = ctLocker.lockColors(bm);
    const uint8_t* src = (uint8_t*)bm.getPixels();
    const int rgb_stride = pic.width * 3;

    // Import (for each scanline) the bit-map image (in appropriate color-space)
    // to RGB color space.
    uint8_t* rgb = new uint8_t[rgb_stride * pic.height];
    for (int y = 0; y < pic.height; ++y) {
        scanline_import(src + y * bm.rowBytes(), rgb + y * rgb_stride,
                        pic.width, colors);
    }

    bool ok = WebPPictureImportRGB(&pic, rgb, rgb_stride);
    delete[] rgb;

    ok = ok && WebPEncode(&webp_config, &pic);
    WebPPictureFree(&pic);

    return ok;
}


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

#include "SkTRegistry.h"

static SkImageDecoder* DFactory(SkStream* stream) {
    int width, height;
    if (!webp_parse_header(stream, &width, &height)) {
        return false;
    }

    // Magic matches, call decoder
    return SkNEW(SkWEBPImageDecoder);
}

SkImageDecoder* sk_libwebp_dfactory(SkStream* stream) {
    return DFactory(stream);
}

static SkImageEncoder* EFactory(SkImageEncoder::Type t) {
      return (SkImageEncoder::kWEBP_Type == t) ? SkNEW(SkWEBPImageEncoder) : NULL;
}

SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) {
    return EFactory(t);
}

static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libwebp_dfactory);
static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libwebp_efactory);
