#include "SkImageDecoder.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkDither.h"
#include "SkMath.h"
#include "SkStream.h"
#include "SkTemplates.h"
#include "SkUtils.h"

extern void ValidateHeap();

class SkPVJPEGImageDecoder : public SkImageDecoder {
protected:
    virtual bool onDecode(SkStream* stream, SkBitmap* bm,
                          SkBitmap::Config pref, Mode);

private:
    enum {
        STORAGE_SIZE = 8 * 1024
    };
    char    fStorage[STORAGE_SIZE];
};

SkImageDecoder* SkImageDecoder_PVJPEG_Factory(SkStream* stream)
{
    return SkNEW(SkPVJPEGImageDecoder);
}

#include "pvjpgdecoderinterface.h"
#include "pvjpgdecoder_factory.h"

class AutoPVDelete {
public:
    AutoPVDelete(PVJpgDecoderInterface* codec) : fCodec(codec) {}
    ~AutoPVDelete() {
        fCodec->Reset();
        PVJpgDecoderFactory::DeletePVJpgDecoder(fCodec);
    }
private:    
    PVJpgDecoderInterface* fCodec;
};

class MyObserver : public MPVJpegDecObserver {
public:
    MyObserver() : fCount(0) {}
    ~MyObserver() {
        if (fCount != 0) {
            SkDebugf("--- pvjpeg left %d allocations\n", fCount);
        }
    }

	virtual void allocateBuffer(uint8* &buffer, int32 buffersize) {
        ++fCount;
        // we double the allocation to work around bug when height is odd
        buffer = (uint8*)sk_malloc_throw(buffersize << 1);
        SkDebugf("---  pvjpeg alloc [%d] %d addr=%p\n", fCount, buffersize, buffer);
    }
    
	virtual void deallocateBuffer(uint8 *buffer) {
        SkDebugf("--- pvjpeg free [%d] addr=%p\n", fCount, buffer);
        --fCount;
        sk_free(buffer);
    }

private:
    int fCount;
};

static void check_status(TPvJpgDecStatus status) {
    if (TPVJPGDEC_SUCCESS != status) {
        SkDEBUGF(("--- pvjpeg status %d\n", status));
    }
}

static bool getFrame(PVJpgDecoderInterface* codec, SkBitmap* bitmap,
                     SkBitmap::Config prefConfig, SkImageDecoder::Mode mode) {
    TPvJpgDecInfo info;
    TPvJpgDecStatus status = codec->GetInfo(&info);
    if (status != TPVJPGDEC_SUCCESS)
        return false;

    int width = info.iWidth[0];
    int height = info.iHeight[0];

    bitmap->setConfig(SkBitmap::kRGB_565_Config, width, height);
    bitmap->setIsOpaque(true);

    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
        return true;
    }
    
    SkASSERT(info.iNumComponent == 3);

    TPvJpgDecOutputFmt  format;
    format.iColorFormat = TPV_COLORFMT_RGB16;
    format.iCropped.topLeftX = 0;
    format.iCropped.topLeftY = 0;
    format.iCropped.bottomRightX = width - 1;
    format.iCropped.bottomRightY = height - 1;
    format.iOutputPitch = bitmap->rowBytes() >> 1;
    status = codec->SetOutput(&format);
    if (status != TPVJPGDEC_SUCCESS) {
        SkDebugf("--- PV SetOutput failed %d\n", status);
        return false;
    }

    TPvJpgDecFrame frame;
    uint8*         ptrs[3];
    int32          widths[3], heights[3];
    sk_bzero(ptrs, sizeof(ptrs));
    frame.ptr = ptrs;
    frame.iWidth = widths;
    frame.iHeight = heights;
    
    status = codec->GetFrame(&frame);
    if (status != TPVJPGDEC_SUCCESS) {
        SkDebugf("--- PV GetFrame failed %d\n", status);
        return false;
    }

    bitmap->allocPixels();
    memcpy(bitmap->getPixels(), ptrs[0], bitmap->getSize());
    return true;
}

class OsclCleanupper {
public:
    OsclCleanupper() {
        OsclBase::Init();
        OsclErrorTrap::Init();
        OsclMem::Init();
    }
    ~OsclCleanupper() {
        OsclMem::Cleanup();
        OsclErrorTrap::Cleanup();
        OsclBase::Cleanup();
    }
};

bool SkPVJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
                                    SkBitmap::Config prefConfig, Mode mode)
{
    // do I need this guy?
    OsclCleanupper oc;
    
    PVJpgDecoderInterface*  codec = PVJpgDecoderFactory::CreatePVJpgDecoder();
    TPvJpgDecStatus         status = codec->Init();
    check_status(status);

    MyObserver      observer;   // must create before autopvdelete
    AutoPVDelete    ad(codec);
    
    status = codec->SetObserver(&observer);
    check_status(status);
    
    char*   storage = fStorage;
    int32   bytesInStorage = 0;
    for (;;)
    {
        int32 bytesRead = stream->read(storage + bytesInStorage,
                                       STORAGE_SIZE - bytesInStorage);
        if (bytesRead <= 0) {
            SkDEBUGF(("SkPVJPEGImageDecoder: stream read returned %d\n", bytesRead));
            return false;
        }
        
        // update bytesInStorage to account for the read()
        bytesInStorage += bytesRead;
        SkASSERT(bytesInStorage <= STORAGE_SIZE);
        
        // now call Decode to eat some of the bytes
        int32 consumed = bytesInStorage;
        status = codec->Decode((uint8*)storage, &consumed);

        SkASSERT(bytesInStorage >= consumed);
        bytesInStorage -= consumed;
        // now bytesInStorage is the remaining unread bytes
        if (bytesInStorage > 0) { // slide the leftovers to the beginning
            SkASSERT(storage == fStorage);
            SkASSERT(consumed >= 0 && bytesInStorage >= 0);
            SkASSERT((size_t)(consumed + bytesInStorage) <= sizeof(fStorage));
            SkASSERT(sizeof(fStorage) == STORAGE_SIZE);
       //     SkDebugf("-- memmov srcOffset=%d, numBytes=%d\n", consumed, bytesInStorage);
            memmove(storage, storage + consumed, bytesInStorage);
        }
        
        switch (status) {
        case TPVJPGDEC_SUCCESS:
            SkDEBUGF(("SkPVJPEGImageDecoder::Decode returned success?\n");)
            return false;
        case TPVJPGDEC_FRAME_READY:
        case TPVJPGDEC_DONE:
            return getFrame(codec, decodedBitmap, prefConfig, mode);
        case TPVJPGDEC_FAIL:
        case TPVJPGDEC_INVALID_MEMORY:
        case TPVJPGDEC_INVALID_PARAMS:
        case TPVJPGDEC_NO_IMAGE_DATA:
            SkDEBUGF(("SkPVJPEGImageDecoder: failed to decode err=%d\n", status);)
            return false;
        case TPVJPGDEC_WAITING_FOR_INPUT:
            break;  // loop around and eat more from the stream
        }
    }
    return false;
}

