/*
 * Copyright (C) 2009 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.
 */

#define LOG_TAG "OmxJpegDecoder"
#include <sys/time.h>
#include <utils/Log.h>

#include <binder/ProcessState.h>

#include "SkBitmap.h"
#include "SkImageDecoder.h"
#include "SkStream.h"
#include "omx_jpeg_decoder.h"

class SkJPEGImageDecoder : public SkImageDecoder {
public:
    virtual Format getFormat() const {
        return kJPEG_Format;
    }

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

int nullObjectReturn(const char msg[]) {
    if (msg) {
        SkDebugf("--- %s\n", msg);
    }
    return -1;
}

static int64_t getNowUs() {
    struct timeval tv;
    gettimeofday(&tv, NULL);

    return tv.tv_usec + (int64_t) tv.tv_sec * 1000000;
}

int testDecodeBounds(SkImageDecoder* decoder, SkStream* stream,
        SkBitmap* bitmap) {
    int64_t startTime = getNowUs();
    SkColorType prefColorType = kN32_SkColorType;
    SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodeBounds_Mode;

    // Decode the input stream and then use the bitmap.
    if (!decoder->decode(stream, bitmap, prefColorType, decodeMode)) {
        return nullObjectReturn("decoder->decode returned false");
    } else {
        int64_t delay = getNowUs() - startTime;
        printf("WidthxHeight: %dx%d\n", bitmap->width(), bitmap->height());
        printf("Decoding Time in BoundsMode %.1f msec.\n", delay / 1000.0f);
        return 0;
    }
}

int testDecodePixels(SkImageDecoder* decoder, SkStream* stream,
        SkBitmap* bitmap) {
    int64_t startTime = getNowUs();
    SkColorType prefColorType = kN32_SkColorType;
    SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodePixels_Mode;

    // Decode the input stream and then use the bitmap.
    if (!decoder->decode(stream, bitmap, prefColorType, decodeMode)) {
        return nullObjectReturn("decoder->decode returned false");
    } else {
        int64_t delay = getNowUs() - startTime;
        printf("Decoding Time in PixelsMode %.1f msec.\n", delay / 1000.0f);
        const char* filename = "/sdcard/omxJpegDecodedBitmap.rgba";
        return storeBitmapToFile(bitmap, filename);
    }
}

int testDecoder(SkImageDecoder* decoder, char* filename) {
    // test DecodeMode == Pixels
    SkStream* stream = new SkFILEStream(filename);
    SkBitmap* bitmap = new SkBitmap;
    testDecodePixels(decoder, stream, bitmap);
    delete bitmap;

    // test DecodeMode == Bounds
    stream = new SkFILEStream(filename);
    bitmap = new SkBitmap;
    testDecodeBounds(decoder, stream, bitmap);
    delete bitmap;

    delete decoder;
    return 0;
}

int main(int argc, char** argv) {
    android::ProcessState::self()->startThreadPool();

    printf("Decoding jpeg with libjpeg...\n");
    SkJPEGImageDecoder* libjpeg = new SkJPEGImageDecoder;
    testDecoder(libjpeg, argv[1]);

    printf("\nDecoding jpeg with OMX...\n");
    OmxJpegImageDecoder* omx = new OmxJpegImageDecoder;
    testDecoder(omx, argv[1]);
    return 0;
}
