// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../../include/fxcodec/fx_codec.h"
#include "../../../include/fxge/fx_dib.h"
#include "codec_int.h"
extern "C" {
    static void _JpegScanSOI(const FX_BYTE*& src_buf, FX_DWORD& src_size)
    {
        if (src_size == 0) {
            return;
        }
        FX_DWORD offset = 0;
        while (offset < src_size - 1) {
            if (src_buf[offset] == 0xff && src_buf[offset + 1] == 0xd8) {
                src_buf += offset;
                src_size -= offset;
                return;
            }
            offset ++;
        }
    }
};
extern "C" {
#undef FAR
#include "../../fx_jpeglib.h"
}
extern "C" {
    static void _src_do_nothing(struct jpeg_decompress_struct* cinfo) {}
};
extern "C" {
    static void _error_fatal(j_common_ptr cinfo)
    {
        longjmp(*(jmp_buf*)cinfo->client_data, -1);
    }
};
extern "C" {
    static void _src_skip_data(struct jpeg_decompress_struct* cinfo, long num)
    {
        if (num > (long)cinfo->src->bytes_in_buffer) {
            _error_fatal((j_common_ptr)cinfo);
        }
        cinfo->src->next_input_byte += num;
        cinfo->src->bytes_in_buffer -= num;
    }
};
extern "C" {
    static boolean _src_fill_buffer(j_decompress_ptr cinfo)
    {
        return 0;
    }
};
extern "C" {
    static boolean _src_resync(j_decompress_ptr cinfo, int desired)
    {
        return 0;
    }
};
extern "C" {
    static void _error_do_nothing(j_common_ptr cinfo) {}
};
extern "C" {
    static void _error_do_nothing1(j_common_ptr cinfo, int) {}
};
extern "C" {
    static void _error_do_nothing2(j_common_ptr cinfo, char*) {}
};
#define JPEG_MARKER_EXIF		(JPEG_APP0 + 1)
#define	JPEG_MARKER_ICC			(JPEG_APP0 + 2)
#define	JPEG_MARKER_AUTHORTIME	(JPEG_APP0 + 3)
#define	JPEG_MARKER_MAXSIZE	0xFFFF
#define	JPEG_OVERHEAD_LEN	14
static FX_BOOL _JpegIsIccMarker(jpeg_saved_marker_ptr marker)
{
    if (marker->marker == JPEG_MARKER_ICC &&
            marker->data_length >= JPEG_OVERHEAD_LEN &&
            (FXSYS_memcmp32(marker->data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00", 12) == 0)) {
        return TRUE;
    }
    return FALSE;
}
static	FX_BOOL _JpegLoadIccProfile(j_decompress_ptr cinfo, FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length)
{
    if(icc_buf_ptr == NULL || icc_length == NULL) {
        return FALSE;
    }
    *icc_buf_ptr = NULL;
    *icc_length = 0;
    FX_LPBYTE icc_data_ptr = NULL;
    FX_DWORD icc_data_len = 0;
    FX_BYTE count_icc_marker = 0;
    FX_BYTE num_icc_marker = 0;
    jpeg_saved_marker_ptr marker_list[256] = {NULL};
    for (jpeg_saved_marker_ptr cur_marker = cinfo->marker_list;
            cur_marker != NULL;
            cur_marker = cur_marker->next) {
        if(_JpegIsIccMarker(cur_marker)) {
            if(count_icc_marker == 0) {
                num_icc_marker = cur_marker->data[13];
            } else if(num_icc_marker != cur_marker->data[13]) {
                return FALSE;
            }
            int sn = cur_marker->data[12] - 1;
            if(sn < 0 || sn >= num_icc_marker) {
                return FALSE;
            }
            if(marker_list[sn] == NULL) {
                marker_list[sn] = cur_marker;
            } else {
                return FALSE;
            }
            count_icc_marker ++;
            icc_data_len +=	(cur_marker->data_length - JPEG_OVERHEAD_LEN);
        }
    }
    if(count_icc_marker != num_icc_marker) {
        return FALSE;
    }
    if(num_icc_marker == 0) {
        return TRUE;
    }
    icc_data_ptr = FX_Alloc(FX_BYTE, icc_data_len);
    if(icc_buf_ptr == NULL)	{
        return FALSE;
    }
    *icc_buf_ptr = icc_data_ptr;
    *icc_length = icc_data_len;
    for (int idx = 0; idx < num_icc_marker; idx++) {
        icc_data_len = marker_list[idx]->data_length - JPEG_OVERHEAD_LEN;
        FXSYS_memcpy32(icc_data_ptr, marker_list[idx]->data + JPEG_OVERHEAD_LEN, icc_data_len);
        icc_data_ptr += icc_data_len;
    }
    return TRUE;
}
static	FX_BOOL _JpegEmbedIccProfile(j_compress_ptr cinfo, FX_LPCBYTE icc_buf_ptr, FX_DWORD icc_length)
{
    if(icc_buf_ptr == NULL || icc_length == 0) {
        return FALSE;
    }
    FX_DWORD icc_segment_size = (JPEG_MARKER_MAXSIZE - 2 - JPEG_OVERHEAD_LEN);
    FX_DWORD icc_segment_num = (icc_length / icc_segment_size) + 1;
    if (icc_segment_num > 255)	{
        return FALSE;
    }
    FX_DWORD icc_data_length = JPEG_OVERHEAD_LEN + (icc_segment_num > 1 ? icc_segment_size : icc_length);
    FX_LPBYTE icc_data = FX_Alloc(FX_BYTE, icc_data_length);
    if (icc_data == NULL) {
        return FALSE;
    }
    FXSYS_memcpy32(icc_data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00", 12);
    icc_data[13] = (FX_BYTE)icc_segment_num;
    for (FX_BYTE i = 0; i < (icc_segment_num - 1); i++) {
        icc_data[12] = i + 1;
        FXSYS_memcpy32(icc_data + JPEG_OVERHEAD_LEN, icc_buf_ptr + i * icc_segment_size, icc_segment_size);
        jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data, icc_data_length);
    }
    icc_data[12] = (FX_BYTE)icc_segment_num;
    FX_DWORD icc_size = (icc_segment_num - 1) * icc_segment_size;
    FXSYS_memcpy32(icc_data + JPEG_OVERHEAD_LEN, icc_buf_ptr + icc_size, icc_length - icc_size);
    jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data, JPEG_OVERHEAD_LEN + icc_length - icc_size);
    FX_Free(icc_data);
    return TRUE;
}
extern "C" {
    static void _dest_do_nothing(j_compress_ptr cinfo) {}
};
extern "C" {
    static boolean _dest_empty(j_compress_ptr cinfo)
    {
        return FALSE;
    }
};
#define	JPEG_BLOCK_SIZE	1048576
static void _JpegEncode(const CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_STRSIZE& dest_size, int quality, FX_LPCBYTE icc_buf, FX_DWORD icc_length)
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    jerr.error_exit = _error_do_nothing;
    jerr.emit_message = _error_do_nothing1;
    jerr.output_message = _error_do_nothing;
    jerr.format_message = _error_do_nothing2;
    jerr.reset_error_mgr = _error_do_nothing;
    cinfo.err = &jerr;
    jpeg_create_compress(&cinfo);
    int Bpp = pSource->GetBPP() / 8;
    int nComponents = Bpp >= 3 ? (pSource->IsCmykImage() ? 4 : 3) : 1;
    int pitch = pSource->GetPitch();
    int width = pSource->GetWidth();
    int height = pSource->GetHeight();
    FX_DWORD dest_buf_length = width * height * nComponents + 1024 + (icc_length ? (icc_length + 255 * 18) : 0);
    dest_buf = FX_Alloc(FX_BYTE, dest_buf_length);
    while (dest_buf == NULL) {
        dest_buf_length >>= 1;
        dest_buf = FX_Alloc(FX_BYTE, dest_buf_length);
    }
    struct jpeg_destination_mgr dest;
    dest.init_destination = _dest_do_nothing;
    dest.term_destination = _dest_do_nothing;
    dest.empty_output_buffer = _dest_empty;
    dest.next_output_byte = dest_buf;
    dest.free_in_buffer = dest_buf_length;
    cinfo.dest = &dest;
    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = nComponents;
    if (nComponents == 1) {
        cinfo.in_color_space = JCS_GRAYSCALE;
    } else if (nComponents == 3) {
        cinfo.in_color_space = JCS_RGB;
    } else {
        cinfo.in_color_space = JCS_CMYK;
    }
    FX_LPBYTE line_buf = NULL;
    if (nComponents > 1) {
        line_buf = FX_Alloc(FX_BYTE, width * nComponents);
        if (line_buf == NULL) {
            return;
        }
    }
    jpeg_set_defaults(&cinfo);
    if(quality != 75) {
        jpeg_set_quality(&cinfo, quality, TRUE);
    }
    jpeg_start_compress(&cinfo, TRUE);
    _JpegEmbedIccProfile(&cinfo, icc_buf, icc_length);
    JSAMPROW row_pointer[1];
    JDIMENSION row;
    while (cinfo.next_scanline < cinfo.image_height) {
        FX_LPCBYTE src_scan = pSource->GetScanline(cinfo.next_scanline);
        if (nComponents > 1) {
            FX_LPBYTE dest_scan = line_buf;
            if (nComponents == 3) {
                for (int i = 0; i < width; i ++) {
                    dest_scan[0] = src_scan[2];
                    dest_scan[1] = src_scan[1];
                    dest_scan[2] = src_scan[0];
                    dest_scan += 3;
                    src_scan += Bpp;
                }
            } else {
                for (int i = 0; i < pitch; i ++) {
                    *dest_scan++ = ~*src_scan++;
                }
            }
            row_pointer[0] = line_buf;
        } else {
            row_pointer[0] = (FX_LPBYTE)src_scan;
        }
        row = cinfo.next_scanline;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
        if (cinfo.next_scanline == row) {
            dest_buf = FX_Realloc(FX_BYTE, dest_buf, dest_buf_length + JPEG_BLOCK_SIZE);
            if (dest_buf == NULL) {
                FX_Free(line_buf);
                return;
            }
            dest.next_output_byte = dest_buf + dest_buf_length - dest.free_in_buffer;
            dest_buf_length += JPEG_BLOCK_SIZE;
            dest.free_in_buffer += JPEG_BLOCK_SIZE;
        }
    }
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    if (line_buf) {
        FX_Free(line_buf);
    }
    dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer;
}
static FX_BOOL _JpegLoadInfo(FX_LPCBYTE src_buf, FX_DWORD src_size, int& width, int& height,
                             int& num_components, int& bits_per_components, FX_BOOL& color_transform,
                             FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length)
{
    _JpegScanSOI(src_buf, src_size);
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    jerr.error_exit = _error_fatal;
    jerr.emit_message = _error_do_nothing1;
    jerr.output_message = _error_do_nothing;
    jerr.format_message = _error_do_nothing2;
    jerr.reset_error_mgr = _error_do_nothing;
    jerr.trace_level = 0;
    cinfo.err = &jerr;
    jmp_buf mark;
    cinfo.client_data = &mark;
    if (setjmp(mark) == -1) {
        return FALSE;
    }
    jpeg_create_decompress(&cinfo);
    struct jpeg_source_mgr src;
    src.init_source = _src_do_nothing;
    src.term_source = _src_do_nothing;
    src.skip_input_data = _src_skip_data;
    src.fill_input_buffer = _src_fill_buffer;
    src.resync_to_restart = _src_resync;
    src.bytes_in_buffer = src_size;
    src.next_input_byte = src_buf;
    cinfo.src = &src;
    if (setjmp(mark) == -1) {
        jpeg_destroy_decompress(&cinfo);
        return FALSE;
    }
    if(icc_buf_ptr && icc_length) {
        jpeg_save_markers(&cinfo, JPEG_MARKER_ICC, JPEG_MARKER_MAXSIZE);
    }
    int ret = jpeg_read_header(&cinfo, TRUE);
    if (ret != JPEG_HEADER_OK) {
        jpeg_destroy_decompress(&cinfo);
        return FALSE;
    }
    width = cinfo.image_width;
    height = cinfo.image_height;
    num_components = cinfo.num_components;
    color_transform = cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_space == JCS_YCCK;
    bits_per_components = cinfo.data_precision;
    if(icc_buf_ptr != NULL) {
        *icc_buf_ptr = NULL;
    }
    if(icc_length != NULL) {
        *icc_length = 0;
    }
    jpeg_destroy_decompress(&cinfo);
    return TRUE;
}
class CCodec_JpegDecoder : public CCodec_ScanlineDecoder
{
public:
    CCodec_JpegDecoder();
    ~CCodec_JpegDecoder();
    FX_BOOL				Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, int nComps,
                               FX_BOOL ColorTransform, IFX_JpegProvider* pJP);
    virtual void		Destroy()
    {
        delete this;
    }
    virtual void		v_DownScale(int dest_width, int dest_height);
    virtual FX_BOOL		v_Rewind();
    virtual FX_LPBYTE	v_GetNextLine();
    virtual FX_DWORD	GetSrcOffset();
    jmp_buf		m_JmpBuf;
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    struct jpeg_source_mgr src;
    FX_LPCBYTE	m_SrcBuf;
    FX_DWORD	m_SrcSize;
    FX_LPBYTE	m_pScanlineBuf;
    FX_BOOL		InitDecode();
    FX_BOOL		m_bInited, m_bStarted, m_bJpegTransform;
protected:
    IFX_JpegProvider*	m_pExtProvider;
    void*				m_pExtContext;
    FX_DWORD			m_nDefaultScaleDenom;
};
CCodec_JpegDecoder::CCodec_JpegDecoder()
{
    m_pScanlineBuf = NULL;
    m_DownScale = 1;
    m_bStarted = FALSE;
    m_bInited = FALSE;
    m_pExtProvider = NULL;
    m_pExtContext = NULL;
    FXSYS_memset32(&cinfo, 0, sizeof(cinfo));
    FXSYS_memset32(&jerr, 0, sizeof(jerr));
    FXSYS_memset32(&src, 0, sizeof(src));
    m_nDefaultScaleDenom = 1;
}
CCodec_JpegDecoder::~CCodec_JpegDecoder()
{
    if (m_pExtProvider) {
        m_pExtProvider->DestroyDecoder(m_pExtContext);
        return;
    }
    if (m_pScanlineBuf) {
        FX_Free(m_pScanlineBuf);
    }
    if (m_bInited) {
        jpeg_destroy_decompress(&cinfo);
    }
}
FX_BOOL CCodec_JpegDecoder::InitDecode()
{
    cinfo.err = &jerr;
    cinfo.client_data = &m_JmpBuf;
    if (setjmp(m_JmpBuf) == -1) {
        return FALSE;
    }
    jpeg_create_decompress(&cinfo);
    m_bInited = TRUE;
    cinfo.src = &src;
    src.bytes_in_buffer = m_SrcSize;
    src.next_input_byte = m_SrcBuf;
    if (setjmp(m_JmpBuf) == -1) {
        jpeg_destroy_decompress(&cinfo);
        m_bInited = FALSE;
        return FALSE;
    }
    cinfo.image_width = m_OrigWidth;
    cinfo.image_height = m_OrigHeight;
    int ret = jpeg_read_header(&cinfo, TRUE);
    if (ret != JPEG_HEADER_OK) {
        return FALSE;
    }
    if (cinfo.saw_Adobe_marker) {
        m_bJpegTransform = TRUE;
    }
    if (cinfo.num_components == 3 && !m_bJpegTransform) {
        cinfo.out_color_space = cinfo.jpeg_color_space;
    }
    m_OrigWidth = cinfo.image_width;
    m_OrigHeight = cinfo.image_height;
    m_OutputWidth = m_OrigWidth;
    m_OutputHeight = m_OrigHeight;
    m_nDefaultScaleDenom = cinfo.scale_denom;
    return TRUE;
}
FX_BOOL CCodec_JpegDecoder::Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
                                   int nComps, FX_BOOL ColorTransform, IFX_JpegProvider* pJP)
{
    if (pJP) {
        m_pExtProvider = pJP;
        m_pExtContext = m_pExtProvider->CreateDecoder(src_buf, src_size, width, height, nComps, ColorTransform);
        return m_pExtContext != NULL;
    }
    _JpegScanSOI(src_buf, src_size);
    m_SrcBuf = src_buf;
    m_SrcSize = src_size;
    jerr.error_exit = _error_fatal;
    jerr.emit_message = _error_do_nothing1;
    jerr.output_message = _error_do_nothing;
    jerr.format_message = _error_do_nothing2;
    jerr.reset_error_mgr = _error_do_nothing;
    src.init_source = _src_do_nothing;
    src.term_source = _src_do_nothing;
    src.skip_input_data = _src_skip_data;
    src.fill_input_buffer = _src_fill_buffer;
    src.resync_to_restart = _src_resync;
    m_bJpegTransform = ColorTransform;
    if(src_size > 1 && FXSYS_memcmp32(src_buf + src_size - 2, "\xFF\xD9", 2) != 0) {
        ((FX_LPBYTE)src_buf)[src_size - 2] = 0xFF;
        ((FX_LPBYTE)src_buf)[src_size - 1] = 0xD9;
    }
    m_OutputWidth = m_OrigWidth = width;
    m_OutputHeight = m_OrigHeight = height;
    if (!InitDecode()) {
        return FALSE;
    }
    if (cinfo.num_components < nComps) {
        return FALSE;
    }
    if ((int)cinfo.image_width < width) {
        return FALSE;
    }
    m_Pitch = (cinfo.image_width * cinfo.num_components + 3) / 4 * 4;
    m_pScanlineBuf = FX_Alloc(FX_BYTE, m_Pitch);
    if (m_pScanlineBuf == NULL) {
        return FALSE;
    }
    m_nComps = cinfo.num_components;
    m_bpc = 8;
    m_bColorTransformed = FALSE;
    m_bStarted = FALSE;
    return TRUE;
}
extern "C" {
    FX_INT32 FX_GetDownsampleRatio(FX_INT32 originWidth, FX_INT32 originHeight, FX_INT32 downsampleWidth, FX_INT32 downsampleHeight)
    {
        int iratio_w = originWidth / downsampleWidth;
        int iratio_h = originHeight / downsampleHeight;
        int ratio = (iratio_w > iratio_h) ? iratio_h : iratio_w;
        if (ratio >= 8) {
            return 8;
        } else if (ratio >= 4) {
            return 4;
        } else if (ratio >= 2) {
            return 2;
        }
        return 1;
    }
}
void CCodec_JpegDecoder::v_DownScale(int dest_width, int dest_height)
{
    if (m_pExtProvider) {
        m_pExtProvider->DownScale(m_pExtContext, dest_width, dest_height);
        return;
    }
    int old_scale = m_DownScale;
    m_DownScale = FX_GetDownsampleRatio(m_OrigWidth, m_OrigHeight, dest_width, dest_height);
    m_OutputWidth = (m_OrigWidth + m_DownScale - 1) / m_DownScale;
    m_OutputHeight = (m_OrigHeight + m_DownScale - 1) / m_DownScale;
    m_Pitch = (m_OutputWidth * m_nComps + 3) / 4 * 4;
    if (old_scale != m_DownScale) {
        m_NextLine = -1;
    }
}
FX_BOOL CCodec_JpegDecoder::v_Rewind()
{
    if (m_pExtProvider) {
        return m_pExtProvider->Rewind(m_pExtContext);
    }
    if (m_bStarted) {
        jpeg_destroy_decompress(&cinfo);
        if (!InitDecode()) {
            return FALSE;
        }
    }
    if (setjmp(m_JmpBuf) == -1) {
        return FALSE;
    }
    cinfo.scale_denom = m_nDefaultScaleDenom * m_DownScale;
    m_OutputWidth = (m_OrigWidth + m_DownScale - 1) / m_DownScale;
    m_OutputHeight = (m_OrigHeight + m_DownScale - 1) / m_DownScale;
    if (!jpeg_start_decompress(&cinfo)) {
        jpeg_destroy_decompress(&cinfo);
        return FALSE;
    }
    if ((int)cinfo.output_width > m_OrigWidth) {
        FXSYS_assert(FALSE);
        return FALSE;
    }
    m_bStarted = TRUE;
    return TRUE;
}
FX_LPBYTE CCodec_JpegDecoder::v_GetNextLine()
{
    if (m_pExtProvider) {
        return m_pExtProvider->GetNextLine(m_pExtContext);
    }
    int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1);
    if (nlines < 1) {
        return NULL;
    }
    return m_pScanlineBuf;
}
FX_DWORD CCodec_JpegDecoder::GetSrcOffset()
{
    if (m_pExtProvider) {
        return m_pExtProvider->GetSrcOffset(m_pExtContext);
    }
    return (FX_DWORD)(m_SrcSize - src.bytes_in_buffer);
}
ICodec_ScanlineDecoder*	CCodec_JpegModule::CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size,
        int width, int height, int nComps, FX_BOOL ColorTransform)
{
    if (src_buf == NULL || src_size == 0) {
        return NULL;
    }
    CCodec_JpegDecoder* pDecoder = FX_NEW CCodec_JpegDecoder;
    if (pDecoder == NULL) {
        return NULL;
    }
    if (!pDecoder->Create(src_buf, src_size, width, height, nComps, ColorTransform, m_pExtProvider)) {
        delete pDecoder;
        return NULL;
    }
    return pDecoder;
}
FX_BOOL CCodec_JpegModule::LoadInfo(FX_LPCBYTE src_buf, FX_DWORD src_size, int& width, int& height,
                                    int& num_components, int& bits_per_components, FX_BOOL& color_transform,
                                    FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length)
{
    if (m_pExtProvider) {
        return m_pExtProvider->LoadInfo(src_buf, src_size, width, height,
                                        num_components, bits_per_components, color_transform,
                                        icc_buf_ptr, icc_length);
    }
    return _JpegLoadInfo(src_buf, src_size, width, height, num_components, bits_per_components, color_transform, icc_buf_ptr, icc_length);
}
FX_BOOL CCodec_JpegModule::Encode(const CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_STRSIZE& dest_size, int quality, FX_LPCBYTE icc_buf, FX_DWORD icc_length)
{
    if (m_pExtProvider) {
        return m_pExtProvider->Encode(pSource, dest_buf, dest_size, quality, icc_buf, icc_length);
    }
    if(pSource->GetBPP() < 8 || pSource->GetPalette() != NULL) {
        ASSERT(pSource->GetBPP() >= 8 && pSource->GetPalette() == NULL);
        return FALSE;
    }
    _JpegEncode(pSource, dest_buf, dest_size, quality, icc_buf, icc_length);
    return TRUE;
}
struct FXJPEG_Context {
    jmp_buf			m_JumpMark;
    jpeg_decompress_struct m_Info;
    jpeg_error_mgr	m_ErrMgr;
    jpeg_source_mgr	m_SrcMgr;
    unsigned int	m_SkipSize;
    void*		(*m_AllocFunc)(unsigned int);
    void		(*m_FreeFunc)(void*);
};
extern "C" {
    static void _error_fatal1(j_common_ptr cinfo)
    {
        longjmp(((FXJPEG_Context*)cinfo->client_data)->m_JumpMark, -1);
    }
};
extern "C" {
    static void _src_skip_data1(struct jpeg_decompress_struct* cinfo, long num)
    {
        if (cinfo->src->bytes_in_buffer < (size_t)num) {
            ((FXJPEG_Context*)cinfo->client_data)->m_SkipSize = (unsigned int)(num - cinfo->src->bytes_in_buffer);
            cinfo->src->bytes_in_buffer = 0;
        } else {
            cinfo->src->next_input_byte += num;
            cinfo->src->bytes_in_buffer -= num;
        }
    }
};
static void* jpeg_alloc_func(unsigned int size)
{
    return FX_Alloc(char, size);
}
static void jpeg_free_func(void* p)
{
    FX_Free(p);
}
void* CCodec_JpegModule::Start()
{
    if (m_pExtProvider) {
        return m_pExtProvider->Start();
    }
    FXJPEG_Context* p = (FXJPEG_Context*)FX_Alloc(FX_BYTE, sizeof(FXJPEG_Context));
    if (p == NULL) {
        return NULL;
    }
    p->m_AllocFunc = jpeg_alloc_func;
    p->m_FreeFunc = jpeg_free_func;
    p->m_ErrMgr.error_exit = _error_fatal1;
    p->m_ErrMgr.emit_message = _error_do_nothing1;
    p->m_ErrMgr.output_message = _error_do_nothing;
    p->m_ErrMgr.format_message = _error_do_nothing2;
    p->m_ErrMgr.reset_error_mgr = _error_do_nothing;
    p->m_SrcMgr.init_source = _src_do_nothing;
    p->m_SrcMgr.term_source = _src_do_nothing;
    p->m_SrcMgr.skip_input_data = _src_skip_data1;
    p->m_SrcMgr.fill_input_buffer = _src_fill_buffer;
    p->m_SrcMgr.resync_to_restart = _src_resync;
    p->m_Info.client_data = p;
    p->m_Info.err = &p->m_ErrMgr;
    if (setjmp(p->m_JumpMark) == -1) {
        return 0;
    }
    jpeg_create_decompress(&p->m_Info);
    p->m_Info.src = &p->m_SrcMgr;
    p->m_SkipSize = 0;
    return p;
}
void CCodec_JpegModule::Finish(void* pContext)
{
    if (m_pExtProvider) {
        m_pExtProvider->Finish(pContext);
        return;
    }
    FXJPEG_Context* p = (FXJPEG_Context*)pContext;
    jpeg_destroy_decompress(&p->m_Info);
    p->m_FreeFunc(p);
}
void CCodec_JpegModule::Input(void* pContext, const unsigned char* src_buf, FX_DWORD src_size)
{
    if (m_pExtProvider) {
        m_pExtProvider->Input(pContext, src_buf, src_size);
        return;
    }
    FXJPEG_Context* p = (FXJPEG_Context*)pContext;
    if (p->m_SkipSize) {
        if (p->m_SkipSize > src_size) {
            p->m_SrcMgr.bytes_in_buffer = 0;
            p->m_SkipSize -= src_size;
            return;
        }
        src_size -= p->m_SkipSize;
        src_buf += p->m_SkipSize;
        p->m_SkipSize = 0;
    }
    p->m_SrcMgr.next_input_byte = src_buf;
    p->m_SrcMgr.bytes_in_buffer = src_size;
}
int CCodec_JpegModule::ReadHeader(void* pContext, int* width, int* height, int* nComps)
{
    if (m_pExtProvider) {
        return m_pExtProvider->ReadHeader(pContext, width, height, nComps);
    }
    FXJPEG_Context* p = (FXJPEG_Context*)pContext;
    if (setjmp(p->m_JumpMark) == -1) {
        return 1;
    }
    int ret = jpeg_read_header(&p->m_Info, true);
    if (ret == JPEG_SUSPENDED) {
        return 2;
    }
    if (ret != JPEG_HEADER_OK) {
        return 1;
    }
    *width = p->m_Info.image_width;
    *height = p->m_Info.image_height;
    *nComps = p->m_Info.num_components;
    return 0;
}
FX_BOOL CCodec_JpegModule::StartScanline(void* pContext, int down_scale)
{
    if (m_pExtProvider) {
        return m_pExtProvider->StartScanline(pContext, down_scale);
    }
    FXJPEG_Context* p = (FXJPEG_Context*)pContext;
    if (setjmp(p->m_JumpMark) == -1) {
        return FALSE;
    }
    p->m_Info.scale_denom = down_scale;
    return jpeg_start_decompress(&p->m_Info);
}
FX_BOOL CCodec_JpegModule::ReadScanline(void* pContext, unsigned char* dest_buf)
{
    if (m_pExtProvider) {
        return m_pExtProvider->ReadScanline(pContext, dest_buf);
    }
    FXJPEG_Context* p = (FXJPEG_Context*)pContext;
    if (setjmp(p->m_JumpMark) == -1) {
        return FALSE;
    }
    int nlines = jpeg_read_scanlines(&p->m_Info, &dest_buf, 1);
    return nlines == 1;
}
FX_DWORD CCodec_JpegModule::GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr)
{
    if (m_pExtProvider) {
        return m_pExtProvider->GetAvailInput(pContext, avail_buf_ptr);
    }
    if(avail_buf_ptr != NULL) {
        *avail_buf_ptr = NULL;
        if(((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer > 0) {
            *avail_buf_ptr = (FX_LPBYTE)((FXJPEG_Context*)pContext)->m_SrcMgr.next_input_byte;
        }
    }
    return (FX_DWORD)((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer;
}
