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

#include <array>
#include <cstring>
#include <cstdio>
#include <inttypes.h>
#include <memory.h>
#include <vector>

#include <setjmp.h>

#include <android/hardware/camera/device/3.2/types.h>

#include "core_jni_helpers.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>

#define CAMERA_PROCESSOR_CLASS_NAME "android/hardware/camera2/impl/CameraExtensionJpegProcessor"

extern "C" {
#include "jpeglib.h"
}

using namespace std;
using namespace android;

using android::hardware::camera::device::V3_2::CameraBlob;
using android::hardware::camera::device::V3_2::CameraBlobId;

class Transform;
struct Plane;

inline int sgn(int val) { return (0 < val) - (val < 0); }

inline int min(int a, int b) { return a < b ? a : b; }

inline int max(int a, int b) { return a > b ? a : b; }

/**
 * Represents a combined cropping and rotation transformation.
 *
 * The transformation maps the coordinates (mOrigX, mOrigY) and (mOneX, mOneY)
 * in the input image to the origin and (mOutputWidth, mOutputHeight)
 * respectively.
 */
class Transform {
    public:
        Transform(int origX, int origY, int oneX, int oneY);

        static Transform forCropFollowedByRotation(int cropLeft, int cropTop,
                int cropRight, int cropBottom, int rot90);

        inline int getOutputWidth() const { return mOutputWidth; }

        inline int getOutputHeight() const { return mOutputHeight; }

        bool operator==(const Transform& other) const;

        /**
         * Transforms the input coordinates.  Coordinates outside the cropped region
         * are clamped to valid values.
         */
        void map(int x, int y, int* outX, int* outY) const;

    private:
        int mOutputWidth;
        int mOutputHeight;

        // The coordinates of the point to map the origin to.
        const int mOrigX, mOrigY;
        // The coordinates of the point to map the point (getOutputWidth(),
        // getOutputHeight()) to.
        const int mOneX, mOneY;

        // A matrix for the rotational component.
        int mMat00, mMat01;
        int mMat10, mMat11;
};

/**
 * Represents a model for accessing pixel data for a single plane of an image.
 * Note that the actual data is not owned by this class, and the underlying
 * data does not need to be stored in separate planes.
 */
struct Plane {
    // The dimensions of this plane of the image
    int width;
    int height;

    // A pointer to raw pixel data
    const unsigned char* data;
    // The difference in address between consecutive pixels in the same row
    int pixelStride;
    // The difference in address between the start of consecutive rows
    int rowStride;
};

/**
 * Provides an interface for simultaneously reading a certain number of rows of
 * an image plane as contiguous arrays, suitable for use with libjpeg.
 */
template <unsigned int ROWS>
class RowIterator {
    public:
        /**
         * Creates a new RowIterator which will crop and rotate with the given
         * transform.
         *
         * @param plane the plane to iterate over
         * @param transform the transformation to map output values into the
         * coordinate space of the plane
         * @param rowLength the length of the rows returned via LoadAt().  If this is
         * longer than the width of the output (after applying the transform), then
         * the right-most value is repeated.
         */
        inline RowIterator(Plane plane, Transform transform, int rowLength);

        /**
         * Returns an array of pointers into consecutive rows of contiguous image
         * data starting at y.  That is, samples within each row are contiguous.
         * However, the individual arrays pointed-to may be separate.
         * When the end of the image is reached, the last row of the image is
         * repeated.
         * The returned pointers are valid until the next call to loadAt().
         */
        inline const std::array<unsigned char*, ROWS> loadAt(int baseY);

    private:
        Plane mPlane;
        Transform mTransform;
        // The length of a row, with padding to the next multiple of 64.
        int mPaddedRowLength;
        std::vector<unsigned char> mBuffer;
};

template <unsigned int ROWS>
RowIterator<ROWS>::RowIterator(Plane plane, Transform transform,
                                         int rowLength)
        : mPlane(plane), mTransform(transform) {
    mPaddedRowLength = rowLength;
    mBuffer = std::vector<unsigned char>(rowLength * ROWS);
}

template <unsigned int ROWS>
const std::array<unsigned char*, ROWS> RowIterator<ROWS>::loadAt(int baseY) {
    std::array<unsigned char*, ROWS> bufPtrs;
    for (unsigned int i = 0; i < ROWS; i++) {
        bufPtrs[i] = &mBuffer[mPaddedRowLength * i];
    }

    if (mPlane.width == 0 || mPlane.height == 0) {
        return bufPtrs;
    }

    for (unsigned int i = 0; i < ROWS; i++) {
        int y = i + baseY;
        y = min(y, mTransform.getOutputHeight() - 1);

        int output_width = mPaddedRowLength;
        output_width = min(output_width, mTransform.getOutputWidth());
        output_width = min(output_width, mPlane.width);

        // Each row in the output image will be copied into buf_ by gathering pixels
        // along an axis-aligned line in the plane.
        // The line is defined by (startX, startY) -> (endX, endY), computed via the
        // current Transform.
        int startX;
        int startY;
        mTransform.map(0, y, &startX, &startY);

        int endX;
        int endY;
        mTransform.map(output_width - 1, y, &endX, &endY);

        // Clamp (startX, startY) and (endX, endY) to the valid bounds of the plane.
        startX = min(startX, mPlane.width - 1);
        startY = min(startY, mPlane.height - 1);
        endX = min(endX, mPlane.width - 1);
        endY = min(endY, mPlane.height - 1);
        startX = max(startX, 0);
        startY = max(startY, 0);
        endX = max(endX, 0);
        endY = max(endY, 0);

        // To reduce work inside the copy-loop, precompute the start, end, and
        // stride relating the values to be gathered from mPlane into buf
        // for this particular scan-line.
        int dx = sgn(endX - startX);
        int dy = sgn(endY - startY);
        if (!(dx == 0 || dy == 0)) {
            ALOGE("%s: Unexpected bounds: %dx%d %dx%d!", __FUNCTION__, startX, endX, startY, endY);
            return bufPtrs;
        }

        // The index into mPlane.data of (startX, startY)
        int plane_start = startX * mPlane.pixelStride + startY * mPlane.rowStride;
        // The index into mPlane.data of (endX, endY)
        int plane_end = endX * mPlane.pixelStride + endY * mPlane.rowStride;
        // The stride, in terms of indices in plane_data, required to enumerate the
        // samples between the start and end points.
        int stride = dx * mPlane.pixelStride + dy * mPlane.rowStride;
        // In the degenerate-case of a 1x1 plane, startX and endX are equal, so
        // stride would be 0, resulting in an infinite-loop.  To avoid this case,
        // use a stride of at-least 1.
        if (stride == 0) {
            stride = 1;
        }

        int outX = 0;
        for (int idx = plane_start; idx >= min(plane_start, plane_end) &&
                idx <= max(plane_start, plane_end); idx += stride) {
            bufPtrs[i][outX] = mPlane.data[idx];
            outX++;
        }

        // Fill the remaining right-edge of the buffer by extending the last
        // value.
        unsigned char right_padding_value = bufPtrs[i][outX - 1];
        for (; outX < mPaddedRowLength; outX++) {
            bufPtrs[i][outX] = right_padding_value;
        }
    }

    return bufPtrs;
}

template <typename T>
void safeDelete(T& t) {
    delete t;
    t = nullptr;
}

template <typename T>
void safeDeleteArray(T& t) {
    delete[] t;
    t = nullptr;
}

Transform::Transform(int origX, int origY, int oneX, int oneY)
    : mOrigX(origX), mOrigY(origY), mOneX(oneX), mOneY(oneY) {
    if (origX == oneX || origY == oneY) {
        // Handle the degenerate case of cropping to a 0x0 rectangle.
        mMat00 = 0;
        mMat01 = 0;
        mMat10 = 0;
        mMat11 = 0;
        return;
    }

    if (oneX > origX && oneY > origY) {
        // 0-degree rotation
        mMat00 = 1;
        mMat01 = 0;
        mMat10 = 0;
        mMat11 = 1;
        mOutputWidth = abs(oneX - origX);
        mOutputHeight = abs(oneY - origY);
    } else if (oneX < origX && oneY > origY) {
        // 90-degree CCW rotation
        mMat00 = 0;
        mMat01 = -1;
        mMat10 = 1;
        mMat11 = 0;
        mOutputWidth = abs(oneY - origY);
        mOutputHeight = abs(oneX - origX);
    } else if (oneX > origX && oneY < origY) {
        // 270-degree CCW rotation
        mMat00 = 0;
        mMat01 = 1;
        mMat10 = -1;
        mMat11 = 0;
        mOutputWidth = abs(oneY - origY);
        mOutputHeight = abs(oneX - origX);;
    } else if (oneX < origX && oneY < origY) {
        // 180-degree CCW rotation
        mMat00 = -1;
        mMat01 = 0;
        mMat10 = 0;
        mMat11 = -1;
        mOutputWidth = abs(oneX - origX);
        mOutputHeight = abs(oneY - origY);
    }
}

Transform Transform::forCropFollowedByRotation(int cropLeft, int cropTop, int cropRight,
        int cropBottom, int rot90) {
    // The input crop-region excludes cropRight and cropBottom, so transform the
    // crop rect such that it defines the entire valid region of pixels
    // inclusively.
    cropRight -= 1;
    cropBottom -= 1;

    int cropXLow = min(cropLeft, cropRight);
    int cropYLow = min(cropTop, cropBottom);
    int cropXHigh = max(cropLeft, cropRight);
    int cropYHigh = max(cropTop, cropBottom);
    rot90 %= 4;
    if (rot90 == 0) {
        return Transform(cropXLow, cropYLow, cropXHigh + 1, cropYHigh + 1);
    } else if (rot90 == 1) {
        return Transform(cropXHigh, cropYLow, cropXLow - 1, cropYHigh + 1);
    } else if (rot90 == 2) {
        return Transform(cropXHigh, cropYHigh, cropXLow - 1, cropYLow - 1);
    } else if (rot90 == 3) {
        return Transform(cropXLow, cropYHigh, cropXHigh + 1, cropYLow - 1);
    }
    // Impossible case.
    return Transform(cropXLow, cropYLow, cropXHigh + 1, cropYHigh + 1);
}

bool Transform::operator==(const Transform& other) const {
    return other.mOrigX == mOrigX &&  //
           other.mOrigY == mOrigY &&  //
           other.mOneX == mOneX &&    //
           other.mOneY == mOneY;
}

/**
 * Transforms the input coordinates.  Coordinates outside the cropped region
 * are clamped to valid values.
 */
void Transform::map(int x, int y, int* outX, int* outY) const {
    x = max(x, 0);
    y = max(y, 0);
    x = min(x, getOutputWidth() - 1);
    y = min(y, getOutputHeight() - 1);
    *outX = x * mMat00 + y * mMat01 + mOrigX;
    *outY = x * mMat10 + y * mMat11 + mOrigY;
}

int compress(int img_width, int img_height, RowIterator<16>& y_row_generator,
        RowIterator<8>& cb_row_generator, RowIterator<8>& cr_row_generator,
        unsigned char* out_buf, size_t out_buf_capacity, std::function<void(size_t)> flush,
        int quality) {
    // libjpeg requires the use of setjmp/longjmp to recover from errors.  Since
    // this doesn't play well with RAII, we must use pointers and manually call
    // delete. See POSIX documentation for longjmp() for details on why the
    // volatile keyword is necessary.
    volatile jpeg_compress_struct cinfov;

    jpeg_compress_struct& cinfo =
            *const_cast<struct jpeg_compress_struct*>(&cinfov);

    JSAMPROW* volatile yArr = nullptr;
    JSAMPROW* volatile cbArr = nullptr;
    JSAMPROW* volatile crArr = nullptr;

    JSAMPARRAY imgArr[3];

    // Error handling

    struct my_error_mgr {
        struct jpeg_error_mgr pub;
        jmp_buf setjmp_buffer;
    } err;

    cinfo.err = jpeg_std_error(&err.pub);

    // Default error_exit will call exit(), so override
    // to return control via setjmp/longjmp.
    err.pub.error_exit = [](j_common_ptr cinfo) {
        my_error_mgr* myerr = reinterpret_cast<my_error_mgr*>(cinfo->err);

        (*cinfo->err->output_message)(cinfo);

        // Return control to the setjmp point (see call to setjmp()).
        longjmp(myerr->setjmp_buffer, 1);
    };

    cinfo.err = (struct jpeg_error_mgr*)&err;

    // Set the setjmp point to return to in case of error.
    if (setjmp(err.setjmp_buffer)) {
        // If libjpeg hits an error, control will jump to this point (see call to
        // longjmp()).
        jpeg_destroy_compress(&cinfo);

        safeDeleteArray(yArr);
        safeDeleteArray(cbArr);
        safeDeleteArray(crArr);

        return -1;
    }

    // Create jpeg compression context
    jpeg_create_compress(&cinfo);

    // Stores data needed by our c-style callbacks into libjpeg
    struct ClientData {
        unsigned char* out_buf;
        size_t out_buf_capacity;
        std::function<void(size_t)> flush;
        int totalOutputBytes;
    } clientData{out_buf, out_buf_capacity, flush, 0};

    cinfo.client_data = &clientData;

    // Initialize destination manager
    jpeg_destination_mgr dest;

    dest.init_destination = [](j_compress_ptr cinfo) {
        ClientData& cdata = *reinterpret_cast<ClientData*>(cinfo->client_data);

        cinfo->dest->next_output_byte = cdata.out_buf;
        cinfo->dest->free_in_buffer = cdata.out_buf_capacity;
    };

    dest.empty_output_buffer = [](j_compress_ptr cinfo) -> boolean {
        ClientData& cdata = *reinterpret_cast<ClientData*>(cinfo->client_data);

        size_t numBytesInBuffer = cdata.out_buf_capacity;
        cdata.flush(numBytesInBuffer);
        cdata.totalOutputBytes += numBytesInBuffer;

        // Reset the buffer
        cinfo->dest->next_output_byte = cdata.out_buf;
        cinfo->dest->free_in_buffer = cdata.out_buf_capacity;

        return true;
    };

    dest.term_destination = [](j_compress_ptr cinfo __unused) {
        // do nothing to terminate the output buffer
    };

    cinfo.dest = &dest;

    // Set jpeg parameters
    cinfo.image_width = img_width;
    cinfo.image_height = img_height;
    cinfo.input_components = 3;

    // Set defaults based on the above values
    jpeg_set_defaults(&cinfo);

    jpeg_set_quality(&cinfo, quality, true);

    cinfo.dct_method = JDCT_IFAST;

    cinfo.raw_data_in = true;

    jpeg_set_colorspace(&cinfo, JCS_YCbCr);

    cinfo.comp_info[0].h_samp_factor = 2;
    cinfo.comp_info[0].v_samp_factor = 2;
    cinfo.comp_info[1].h_samp_factor = 1;
    cinfo.comp_info[1].v_samp_factor = 1;
    cinfo.comp_info[2].h_samp_factor = 1;
    cinfo.comp_info[2].v_samp_factor = 1;

    jpeg_start_compress(&cinfo, true);

    yArr = new JSAMPROW[cinfo.comp_info[0].v_samp_factor * DCTSIZE];
    cbArr = new JSAMPROW[cinfo.comp_info[1].v_samp_factor * DCTSIZE];
    crArr = new JSAMPROW[cinfo.comp_info[2].v_samp_factor * DCTSIZE];

    imgArr[0] = const_cast<JSAMPARRAY>(yArr);
    imgArr[1] = const_cast<JSAMPARRAY>(cbArr);
    imgArr[2] = const_cast<JSAMPARRAY>(crArr);

    for (int y = 0; y < img_height; y += DCTSIZE * 2) {
        std::array<unsigned char*, 16> yData = y_row_generator.loadAt(y);
        std::array<unsigned char*, 8> cbData = cb_row_generator.loadAt(y / 2);
        std::array<unsigned char*, 8> crData = cr_row_generator.loadAt(y / 2);

        for (int row = 0; row < DCTSIZE * 2; row++) {
            yArr[row] = yData[row];
        }
        for (int row = 0; row < DCTSIZE; row++) {
            cbArr[row] = cbData[row];
            crArr[row] = crData[row];
        }

        jpeg_write_raw_data(&cinfo, imgArr, DCTSIZE * 2);
    }

    jpeg_finish_compress(&cinfo);

    int numBytesInBuffer = cinfo.dest->next_output_byte - out_buf;

    flush(numBytesInBuffer);

    clientData.totalOutputBytes += numBytesInBuffer;

    safeDeleteArray(yArr);
    safeDeleteArray(cbArr);
    safeDeleteArray(crArr);

    jpeg_destroy_compress(&cinfo);

    return clientData.totalOutputBytes;
}

int compress(
        /** Input image dimensions */
        int width, int height,
        /** Y Plane */
        unsigned char* yBuf, int yPStride, int yRStride,
        /** Cb Plane */
        unsigned char* cbBuf, int cbPStride, int cbRStride,
        /** Cr Plane */
        unsigned char* crBuf, int crPStride, int crRStride,
        /** Output */
        unsigned char* outBuf, size_t outBufCapacity,
        /** Jpeg compression parameters */
        int quality,
        /** Crop */
        int cropLeft, int cropTop, int cropRight, int cropBottom,
        /** Rotation (multiple of 90).  For example, rot90 = 1 implies a 90 degree
         * rotation. */
        int rot90) {
    int finalWidth;
    int finalHeight;
    finalWidth = cropRight - cropLeft;
    finalHeight = cropBottom - cropTop;

    rot90 %= 4;
    // for 90 and 270-degree rotations, flip the final width and height
    if (rot90 == 1) {
        finalWidth = cropBottom - cropTop;
        finalHeight = cropRight - cropLeft;
    } else if (rot90 == 3) {
        finalWidth = cropBottom - cropTop;
        finalHeight = cropRight - cropLeft;
    }

    const Plane yP = {width, height, yBuf, yPStride, yRStride};
    const Plane cbP = {width / 2, height / 2, cbBuf, cbPStride, cbRStride};
    const Plane crP = {width / 2, height / 2, crBuf, crPStride, crRStride};

    auto flush = [](size_t numBytes __unused) {
        // do nothing
    };

    // Round up to the nearest multiple of 64.
    int y_row_length = (finalWidth + 16 + 63) & ~63;
    int cb_row_length = (finalWidth / 2 + 16 + 63) & ~63;
    int cr_row_length = (finalWidth / 2 + 16 + 63) & ~63;

    Transform yTrans = Transform::forCropFollowedByRotation(
            cropLeft, cropTop, cropRight, cropBottom, rot90);

    Transform chromaTrans = Transform::forCropFollowedByRotation(
            cropLeft / 2, cropTop / 2, cropRight / 2, cropBottom / 2, rot90);

    RowIterator<16> yIter(yP, yTrans, y_row_length);
    RowIterator<8> cbIter(cbP, chromaTrans, cb_row_length);
    RowIterator<8> crIter(crP, chromaTrans, cr_row_length);

    return compress(finalWidth, finalHeight, yIter, cbIter, crIter, outBuf, outBufCapacity, flush,
            quality);
}

extern "C" {

static jint CameraExtensionJpegProcessor_compressJpegFromYUV420p(
        JNIEnv* env, jclass clazz __unused,
        /** Input image dimensions */
        jint width, jint height,
        /** Y Plane */
        jobject yBuf, jint yPStride, jint yRStride,
        /** Cb Plane */
        jobject cbBuf, jint cbPStride, jint cbRStride,
        /** Cr Plane */
        jobject crBuf, jint crPStride, jint crRStride,
        /** Output */
        jobject outBuf, jint outBufCapacity,
        /** Jpeg compression parameters */
        jint quality,
        /** Crop */
        jint cropLeft, jint cropTop, jint cropRight, jint cropBottom,
        /** Rotation (multiple of 90).  For example, rot90 = 1 implies a 90 degree
         * rotation. */
        jint rot90) {
    jbyte* y = (jbyte*)env->GetDirectBufferAddress(yBuf);
    jbyte* cb = (jbyte*)env->GetDirectBufferAddress(cbBuf);
    jbyte* cr = (jbyte*)env->GetDirectBufferAddress(crBuf);
    jbyte* out = (jbyte*)env->GetDirectBufferAddress(outBuf);

    size_t actualJpegSize = compress(width, height,
            (unsigned char*)y, yPStride, yRStride,
            (unsigned char*)cb, cbPStride, cbRStride,
            (unsigned char*)cr, crPStride, crRStride,
            (unsigned char*)out, (size_t)outBufCapacity,
            quality, cropLeft, cropTop, cropRight, cropBottom, rot90);

    size_t finalJpegSize = actualJpegSize + sizeof(CameraBlob);
    if (finalJpegSize > outBufCapacity) {
        ALOGE("%s: Final jpeg buffer %zu not large enough for the jpeg blob header with "\
                "capacity %d", __FUNCTION__, finalJpegSize, outBufCapacity);
        return actualJpegSize;
    }

    int8_t* header = static_cast<int8_t *> (out) +
            (outBufCapacity - sizeof(CameraBlob));
    CameraBlob *blob = reinterpret_cast<CameraBlob *> (header);
    blob->blobId = CameraBlobId::JPEG;
    blob->blobSize = actualJpegSize;

    return actualJpegSize;
}

} // extern "C"

static const JNINativeMethod gCameraExtensionJpegProcessorMethods[] = {
    {"compressJpegFromYUV420pNative",
    "(IILjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IILjava/nio/ByteBuffer;IIIIIII)I",
    (void*)CameraExtensionJpegProcessor_compressJpegFromYUV420p}};

// Get all the required offsets in java class and register native functions
int register_android_hardware_camera2_impl_CameraExtensionJpegProcessor(JNIEnv* env) {
    // Register native functions
    return RegisterMethodsOrDie(env, CAMERA_PROCESSOR_CLASS_NAME,
            gCameraExtensionJpegProcessorMethods, NELEM(gCameraExtensionJpegProcessorMethods));
}
