/*
 * 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_NDEBUG   0
#define LOG_TAG "JPEGSource"
#include <utils/Log.h>

#include <media/stagefright/DataSource.h>
#include <media/stagefright/JPEGSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>

#define JPEG_SOF0  0xC0            /* nStart Of Frame N*/
#define JPEG_SOF1  0xC1            /* N indicates which compression process*/
#define JPEG_SOF2  0xC2            /* Only SOF0-SOF2 are now in common use*/
#define JPEG_SOF3  0xC3
#define JPEG_SOF5  0xC5            /* NB: codes C4 and CC are NOT SOF markers*/
#define JPEG_SOF6  0xC6
#define JPEG_SOF7  0xC7
#define JPEG_SOF9  0xC9
#define JPEG_SOF10 0xCA
#define JPEG_SOF11 0xCB
#define JPEG_SOF13 0xCD
#define JPEG_SOF14 0xCE
#define JPEG_SOF15 0xCF
#define JPEG_SOI   0xD8            /* nStart Of Image (beginning of datastream)*/
#define JPEG_EOI   0xD9            /* End Of Image (end of datastream)*/
#define JPEG_SOS   0xDA            /* nStart Of Scan (begins compressed data)*/
#define JPEG_JFIF  0xE0            /* Jfif marker*/
#define JPEG_EXIF  0xE1            /* Exif marker*/
#define JPEG_COM   0xFE            /* COMment */
#define JPEG_DQT   0xDB
#define JPEG_DHT   0xC4
#define JPEG_DRI   0xDD

namespace android {

JPEGSource::JPEGSource(const sp<DataSource> &source)
    : mSource(source),
      mGroup(NULL),
      mStarted(false),
      mSize(0),
      mWidth(0),
      mHeight(0),
      mOffset(0) {
    CHECK_EQ(parseJPEG(), OK);
    CHECK(mSource->getSize(&mSize) == OK);
}

JPEGSource::~JPEGSource() {
    if (mStarted) {
        stop();
    }
}

status_t JPEGSource::start(MetaData *) {
    if (mStarted) {
        return UNKNOWN_ERROR;
    }

    mGroup = new MediaBufferGroup;
    mGroup->add_buffer(new MediaBuffer(mSize));

    mOffset = 0;

    mStarted = true;

    return OK;
}

status_t JPEGSource::stop() {
    if (!mStarted) {
        return UNKNOWN_ERROR;
    }

    delete mGroup;
    mGroup = NULL;

    mStarted = false;

    return OK;
}

sp<MetaData> JPEGSource::getFormat() {
    sp<MetaData> meta = new MetaData;
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_IMAGE_JPEG);
    meta->setInt32(kKeyWidth, mWidth);
    meta->setInt32(kKeyHeight, mHeight);
    meta->setInt32(kKeyMaxInputSize, mSize);

    return meta;
}

status_t JPEGSource::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    if (options != NULL && options->getSeekTo(&seekTimeUs)) {
        return UNKNOWN_ERROR;
    }

    MediaBuffer *buffer;
    mGroup->acquire_buffer(&buffer);

    ssize_t n = mSource->readAt(mOffset, buffer->data(), mSize - mOffset);

    if (n <= 0) {
        buffer->release();
        buffer = NULL;

        return UNKNOWN_ERROR;
    }

    buffer->set_range(0, n);

    mOffset += n;

    *out = buffer;

    return OK;
}

status_t JPEGSource::parseJPEG() {
    mWidth = 0;
    mHeight = 0;

    off_t i = 0;

    uint16_t soi;
    if (!mSource->getUInt16(i, &soi)) {
        return ERROR_IO;
    }

    i += 2;

    if (soi != 0xffd8) {
        return UNKNOWN_ERROR;
    }

    for (;;) {
        uint8_t marker;
        if (mSource->readAt(i++, &marker, 1) != 1) {
            return ERROR_IO;
        }

        CHECK_EQ(marker, 0xff);

        if (mSource->readAt(i++, &marker, 1) != 1) {
            return ERROR_IO;
        }

        CHECK(marker != 0xff);

        uint16_t chunkSize;
        if (!mSource->getUInt16(i, &chunkSize)) {
            return ERROR_IO;
        }

        i += 2;

        if (chunkSize < 2) {
            return UNKNOWN_ERROR;
        }

        switch (marker) {
            case JPEG_SOS:
            {
                return (mWidth > 0 && mHeight > 0) ? OK : UNKNOWN_ERROR;
            }

            case JPEG_EOI:
            {
                return UNKNOWN_ERROR;
            }

            case JPEG_SOF0:
            case JPEG_SOF1:
            case JPEG_SOF3:
            case JPEG_SOF5:
            case JPEG_SOF6:
            case JPEG_SOF7:
            case JPEG_SOF9:
            case JPEG_SOF10:
            case JPEG_SOF11:
            case JPEG_SOF13:
            case JPEG_SOF14:
            case JPEG_SOF15:
            {
                uint16_t width, height;
                if (!mSource->getUInt16(i + 1, &height)
                    || !mSource->getUInt16(i + 3, &width)) {
                    return ERROR_IO;
                }

                mWidth = width;
                mHeight = height;

                i += chunkSize - 2;
                break;
            }

            default:
            {
                // Skip chunk

                i += chunkSize - 2;

                break;
            }
        }
    }

    return OK;
}

}  // namespace android
