/*
 * Copyright (C) 2012 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_NDEBUG 0
#define LOG_TAG "Camera2-JpegCompressor"

#include <utils/Log.h>
#include <ui/GraphicBufferMapper.h>

#include "JpegCompressor.h"

namespace android {
namespace camera2 {

JpegCompressor::JpegCompressor():
        Thread(false),
        mIsBusy(false),
        mCaptureTime(0) {
}

JpegCompressor::~JpegCompressor() {
    ALOGV("%s", __FUNCTION__);
    Mutex::Autolock lock(mMutex);
}

status_t JpegCompressor::start(Vector<CpuConsumer::LockedBuffer*> buffers,
        nsecs_t captureTime) {
    ALOGV("%s", __FUNCTION__);
    Mutex::Autolock busyLock(mBusyMutex);

    if (mIsBusy) {
        ALOGE("%s: Already processing a buffer!", __FUNCTION__);
        return INVALID_OPERATION;
    }

    mIsBusy = true;

    mBuffers = buffers;
    mCaptureTime = captureTime;

    status_t res;
    res = run("JpegCompressor");
    if (res != OK) {
        ALOGE("%s: Unable to start up compression thread: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        //delete mBuffers;  // necessary?
    }
    return res;
}

status_t JpegCompressor::cancel() {
    ALOGV("%s", __FUNCTION__);
    requestExitAndWait();
    return OK;
}

status_t JpegCompressor::readyToRun() {
    ALOGV("%s", __FUNCTION__);
    return OK;
}

bool JpegCompressor::threadLoop() {
    ALOGV("%s", __FUNCTION__);

    mAuxBuffer = mBuffers[0];    // input
    mJpegBuffer = mBuffers[1];    // output

    // Set up error management
    mJpegErrorInfo = NULL;
    JpegError error;
    error.parent = this;

    mCInfo.err = jpeg_std_error(&error);
    mCInfo.err->error_exit = jpegErrorHandler;

    jpeg_create_compress(&mCInfo);
    if (checkError("Error initializing compression")) return false;

    // Route compressed data straight to output stream buffer
    JpegDestination jpegDestMgr;
    jpegDestMgr.parent = this;
    jpegDestMgr.init_destination = jpegInitDestination;
    jpegDestMgr.empty_output_buffer = jpegEmptyOutputBuffer;
    jpegDestMgr.term_destination = jpegTermDestination;

    mCInfo.dest = &jpegDestMgr;

    // Set up compression parameters
    mCInfo.image_width = mAuxBuffer->width;
    mCInfo.image_height = mAuxBuffer->height;
    mCInfo.input_components = 1; // 3;
    mCInfo.in_color_space = JCS_GRAYSCALE; // JCS_RGB

    ALOGV("%s: image_width = %d, image_height = %d", __FUNCTION__, mCInfo.image_width, mCInfo.image_height);

    jpeg_set_defaults(&mCInfo);
    if (checkError("Error configuring defaults")) return false;

    // Do compression
    jpeg_start_compress(&mCInfo, TRUE);
    if (checkError("Error starting compression")) return false;

    size_t rowStride = mAuxBuffer->stride;// * 3;
    const size_t kChunkSize = 32;
    while (mCInfo.next_scanline < mCInfo.image_height) {
        JSAMPROW chunk[kChunkSize];
        for (size_t i = 0 ; i < kChunkSize; i++) {
            chunk[i] = (JSAMPROW)
                    (mAuxBuffer->data + (i + mCInfo.next_scanline) * rowStride);
        }
        jpeg_write_scanlines(&mCInfo, chunk, kChunkSize);
        if (checkError("Error while compressing")) return false;
        if (exitPending()) {
            ALOGV("%s: Cancel called, exiting early", __FUNCTION__);
            cleanUp();
            return false;
        }
    }

    jpeg_finish_compress(&mCInfo);
    if (checkError("Error while finishing compression")) return false;

    cleanUp();
    return false;
}

bool JpegCompressor::isBusy() {
    ALOGV("%s", __FUNCTION__);
    Mutex::Autolock busyLock(mBusyMutex);
    return mIsBusy;
}

// old function -- TODO: update for new buffer type
bool JpegCompressor::isStreamInUse(uint32_t /*id*/) {
    ALOGV("%s", __FUNCTION__);
    Mutex::Autolock lock(mBusyMutex);

    if (mBuffers.size() && mIsBusy) {
        for (size_t i = 0; i < mBuffers.size(); i++) {
//            if ( mBuffers[i].streamId == (int)id ) return true;
        }
    }
    return false;
}

bool JpegCompressor::waitForDone(nsecs_t timeout) {
    ALOGV("%s", __FUNCTION__);
    Mutex::Autolock lock(mBusyMutex);
    status_t res = OK;
    if (mIsBusy) {
        res = mDone.waitRelative(mBusyMutex, timeout);
    }
    return (res == OK);
}

bool JpegCompressor::checkError(const char *msg) {
    ALOGV("%s", __FUNCTION__);
    if (mJpegErrorInfo) {
        char errBuffer[JMSG_LENGTH_MAX];
        mJpegErrorInfo->err->format_message(mJpegErrorInfo, errBuffer);
        ALOGE("%s: %s: %s",
                __FUNCTION__, msg, errBuffer);
        cleanUp();
        mJpegErrorInfo = NULL;
        return true;
    }
    return false;
}

void JpegCompressor::cleanUp() {
    ALOGV("%s", __FUNCTION__);
    jpeg_destroy_compress(&mCInfo);
    Mutex::Autolock lock(mBusyMutex);
    mIsBusy = false;
    mDone.signal();
}

void JpegCompressor::jpegErrorHandler(j_common_ptr cinfo) {
    ALOGV("%s", __FUNCTION__);
    JpegError *error = static_cast<JpegError*>(cinfo->err);
    error->parent->mJpegErrorInfo = cinfo;
}

void JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) {
    ALOGV("%s", __FUNCTION__);
    JpegDestination *dest= static_cast<JpegDestination*>(cinfo->dest);
    ALOGV("%s: Setting destination to %p, size %zu",
            __FUNCTION__, dest->parent->mJpegBuffer->data, kMaxJpegSize);
    dest->next_output_byte = (JOCTET*)(dest->parent->mJpegBuffer->data);
    dest->free_in_buffer = kMaxJpegSize;
}

boolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr /*cinfo*/) {
    ALOGV("%s", __FUNCTION__);
    ALOGE("%s: JPEG destination buffer overflow!",
            __FUNCTION__);
    return true;
}

void JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) {
    (void) cinfo; // TODO: clean up
    ALOGV("%s", __FUNCTION__);
    ALOGV("%s: Done writing JPEG data. %zu bytes left in buffer",
            __FUNCTION__, cinfo->dest->free_in_buffer);
}

}; // namespace camera2
}; // namespace android
