/* Copyright (C) 2011 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

#include "android/jpeg-compress.h"

#include "android/utils/panic.h"

#include "jinclude.h"
#include "jpeglib.h"

/* Implements JPEG destination manager's init_destination routine. */
static void _on_init_destination(j_compress_ptr cinfo);
/* Implements JPEG destination manager's empty_output_buffer routine. */
static boolean _on_empty_output_buffer(j_compress_ptr cinfo);
/* Implements JPEG destination manager's term_destination routine. */
static void _on_term_destination(j_compress_ptr cinfo);

/* JPEG compression descriptor. */
struct AJPEGDesc {
    /* Common JPEG compression destination manager header. */
    struct jpeg_destination_mgr     common;
    /* Buffer where to save compressed output. */
    uint8_t*                        jpeg_buf;
    /* Byte size of the 'jpeg_buf' */
    int                             size;
    /* Chunk size to increment the 'jpeg_buf' with on each allocation request. */
    int                             chunk_size;
    /* Size of the header to put in front of the compressed data. */
    int                             header_size;
};

/********************************************************************************
 *                      jpeglib callbacks.
 *******************************************************************************/

/* Implements JPEG destination manager's init_destination routine. */
static void
_on_init_destination(j_compress_ptr cinfo)
{
    AJPEGDesc* const dst = (AJPEGDesc*)cinfo->dest;
    if (dst->jpeg_buf == NULL) {
        /* This is the first time our destination manager is initialized.
         * Allocate minimal buffer. */
        dst->size = dst->chunk_size;
        dst->jpeg_buf = malloc(dst->size);
        if (dst->jpeg_buf == NULL) {
            APANIC("Unable to allocate %d bytes for JPEG compression", dst->size);
        }
    }
    /* Initialize common header with entire destination buffer. */
    dst->common.next_output_byte = dst->jpeg_buf + dst->header_size;
    dst->common.free_in_buffer = dst->size - dst->header_size;
}

/* Implements JPEG destination manager's empty_output_buffer routine.
 * Name is a bit misleading here. This routine is called by the compressor when
 * output buffer doesn't have enough free space to contain the next chunk of the
 * compressed data. So, here we should reallocate the output buffer, rather than
 * "empty" it.
 */
static boolean
_on_empty_output_buffer(j_compress_ptr cinfo)
{
    AJPEGDesc* const dst = (AJPEGDesc*)cinfo->dest;
    /* Save already compressed data size. */
    const int accumulated = jpeg_compressor_get_jpeg_size(dst);

    /* Reallocate output buffer. */
    dst->size += dst->chunk_size;
    dst->jpeg_buf = realloc(dst->jpeg_buf, dst->size);
    if (dst->jpeg_buf == NULL) {
        APANIC("Unable to allocate %d bytes for JPEG compression", dst->size);
    }

    /* Update common header. */
    dst->common.next_output_byte = dst->jpeg_buf + accumulated + dst->header_size;
    dst->common.free_in_buffer = dst->size - accumulated - dst->header_size;

    return TRUE;
}

/* Implements JPEG destination manager's term_destination routine.
 * We don't do anything here. All the cleanup will be performed when the user
 * calls jpeg_compressor_destroy. */
static void
_on_term_destination(j_compress_ptr cinfo)
{
}

/********************************************************************************
 *                      JPEG compressor API.
 *******************************************************************************/

AJPEGDesc*
jpeg_compressor_create(int header_size, int chunk_size)
{
    AJPEGDesc* dsc = (AJPEGDesc*)malloc(sizeof(AJPEGDesc));
    if (dsc == NULL) {
        APANIC("Unable to allocate JPEG compression descriptor.");
    }

    dsc->common.next_output_byte    = NULL;
    dsc->common.free_in_buffer      = 0;
    dsc->common.init_destination    = _on_init_destination;
    dsc->common.empty_output_buffer = _on_empty_output_buffer;
    dsc->common.term_destination    = _on_term_destination;
    dsc->jpeg_buf                   = NULL;
    dsc->size                       = 0;
    dsc->chunk_size                 = chunk_size;
    dsc->header_size                = header_size;
    return dsc;
}

void
jpeg_compressor_destroy(AJPEGDesc* dsc)
{
    if (dsc != NULL) {
        if (dsc->jpeg_buf != NULL) {
            free(dsc->jpeg_buf);
        }
        free(dsc);
    }
}

int
jpeg_compressor_get_jpeg_size(const AJPEGDesc* dsc)
{
    return (dsc->jpeg_buf == NULL) ? 0 :
        (uint8_t*)dsc->common.next_output_byte - dsc->jpeg_buf - dsc->header_size;
}

void*
jpeg_compressor_get_buffer(const AJPEGDesc* dsc)
{
     return dsc->jpeg_buf;
}

int
jpeg_compressor_get_header_size(const AJPEGDesc* dsc)
{
     return dsc->header_size;
}

void
jpeg_compressor_compress_fb(AJPEGDesc* dsc,
                            int x, int y, int w, int h, int num_lines,
                            int bpp, int bpl,
                            const uint8_t* fb,
                            int jpeg_quality,
                            int ydir){
    struct jpeg_compress_struct cinfo = {0};
    struct jpeg_error_mgr err_mgr;
    const int x_shift = x * bpp;

    /*
     * Initialize compressin information structure, and start compression
     */

    cinfo.err = jpeg_std_error(&err_mgr);
    jpeg_create_compress(&cinfo);
    cinfo.dest = &dsc->common;
    cinfo.image_width = w;
    cinfo.image_height = h;

    /* Decode framebuffer's pixel format. There can be only three:
     * - RGB565,
     * - RGBA8888,
     * - RGBX8888 */
    if (bpp == 2) {
        /* This is RGB565 - most commonly used pixel format for framebuffer. */
        cinfo.input_components = 2;
        cinfo.in_color_space = JCS_RGB_565;
    } else {
        /* RGBA8888, or RGBX8888 - makes no difference here. */
        cinfo.input_components = 4;
        cinfo.in_color_space = JCS_RGBA_8888;
    }
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, jpeg_quality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    /* Line by line compress the region. */
    if (ydir >= 0) {
        while (cinfo.next_scanline < cinfo.image_height) {
            JSAMPROW rgb = (JSAMPROW)(fb + (cinfo.next_scanline + y) * bpl + x_shift);
            jpeg_write_scanlines(&cinfo, (JSAMPARRAY)&rgb, 1);
        }
    } else {
        const int y_shift = num_lines - y - 1;
        while (cinfo.next_scanline < cinfo.image_height) {
            JSAMPROW rgb = (JSAMPROW)(fb + (y_shift - cinfo.next_scanline) * bpl + x_shift);
            jpeg_write_scanlines(&cinfo, (JSAMPARRAY)&rgb, 1);
        }
    }

    /* Complete the compression. */
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
}
