/*
 * 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/DataSource.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/JPEGSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.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(), (status_t)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(
        MediaBufferBase **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
        return UNKNOWN_ERROR;
    }

    MediaBufferBase *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;

    off64_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
