// 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 <setjmp.h>

#include "../../../include/fxcodec/fx_codec.h"
#include "../../../include/fxcrt/fx_safe_types.h"
#include "../../../include/fxge/fx_dib.h"
#include "codec_int.h"

extern "C" {
    static void _JpegScanSOI(const uint8_t*& 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 _JpegEmbedIccProfile(j_compress_ptr cinfo, const uint8_t* 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);
    uint8_t* icc_data = FX_Alloc(uint8_t, icc_data_length);
    FXSYS_memcpy(icc_data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00", 12);
    icc_data[13] = (uint8_t)icc_segment_num;
    for (uint8_t i = 0; i < (icc_segment_num - 1); i++) {
        icc_data[12] = i + 1;
        FXSYS_memcpy(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] = (uint8_t)icc_segment_num;
    FX_DWORD icc_size = (icc_segment_num - 1) * icc_segment_size;
    FXSYS_memcpy(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, uint8_t*& dest_buf, FX_STRSIZE& dest_size, int quality, const uint8_t* icc_buf, FX_DWORD icc_length)
{
    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;

    struct jpeg_compress_struct cinfo;
    memset(&cinfo, 0, sizeof(cinfo));
    cinfo.err = &jerr;
    jpeg_create_compress(&cinfo);
    int Bpp = pSource->GetBPP() / 8;
    FX_DWORD nComponents = Bpp >= 3 ? (pSource->IsCmykImage() ? 4 : 3) : 1;
    FX_DWORD pitch = pSource->GetPitch();
    FX_DWORD width = pdfium::base::checked_cast<FX_DWORD>(pSource->GetWidth());
    FX_DWORD height = pdfium::base::checked_cast<FX_DWORD>(pSource->GetHeight());
    FX_SAFE_DWORD safe_buf_len = width;
    safe_buf_len *= height;
    safe_buf_len *= nComponents;
    safe_buf_len += 1024;
    if (icc_length) {
        safe_buf_len += 255 * 18;
        safe_buf_len += icc_length;
    }
    FX_DWORD dest_buf_length = 0;
    if (!safe_buf_len.IsValid()) {
        dest_buf = nullptr;
    } else {
        dest_buf_length = safe_buf_len.ValueOrDie();
        dest_buf = FX_TryAlloc(uint8_t, dest_buf_length);
        const int MIN_TRY_BUF_LEN = 1024;
        while (!dest_buf && dest_buf_length > MIN_TRY_BUF_LEN) {
            dest_buf_length >>= 1;
            dest_buf = FX_TryAlloc(uint8_t, dest_buf_length);
        }
    }
    if (!dest_buf) {
        FX_OutOfMemoryTerminate(); 
    }
    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;
    }
    uint8_t* line_buf = NULL;
    if (nComponents > 1) {
        line_buf = FX_Alloc2D(uint8_t, width, nComponents);
    }
    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) {
        const uint8_t* src_scan = pSource->GetScanline(cinfo.next_scanline);
        if (nComponents > 1) {
            uint8_t* 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] = (uint8_t*)src_scan;
        }
        row = cinfo.next_scanline;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
        if (cinfo.next_scanline == row) {
            dest_buf = FX_Realloc(uint8_t, dest_buf, dest_buf_length + JPEG_BLOCK_SIZE);
            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(const uint8_t* src_buf, FX_DWORD src_size, int& width, int& height,
                             int& num_components, int& bits_per_components, FX_BOOL& color_transform,
                             uint8_t** 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(const uint8_t* 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 uint8_t*	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;
    const uint8_t*	m_SrcBuf;
    FX_DWORD	m_SrcSize;
    uint8_t*	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_memset(&cinfo, 0, sizeof(cinfo));
    FXSYS_memset(&jerr, 0, sizeof(jerr));
    FXSYS_memset(&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(const uint8_t* 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_memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0) {
        ((uint8_t*)src_buf)[src_size - 2] = 0xFF;
        ((uint8_t*)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(uint8_t, m_Pitch);
    m_nComps = cinfo.num_components;
    m_bpc = 8;
    m_bColorTransformed = FALSE;
    m_bStarted = FALSE;
    return TRUE;
}
extern "C" {
    int32_t FX_GetDownsampleRatio(int32_t originWidth, int32_t originHeight, int32_t downsampleWidth, int32_t 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;
}
uint8_t* 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(const uint8_t* 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 = new CCodec_JpegDecoder;
    if (!pDecoder->Create(src_buf, src_size, width, height, nComps, ColorTransform, m_pExtProvider)) {
        delete pDecoder;
        return NULL;
    }
    return pDecoder;
}
FX_BOOL CCodec_JpegModule::LoadInfo(const uint8_t* src_buf, FX_DWORD src_size, int& width, int& height,
                                    int& num_components, int& bits_per_components, FX_BOOL& color_transform,
                                    uint8_t** 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, uint8_t*& dest_buf, FX_STRSIZE& dest_size, int quality, const uint8_t* 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(uint8_t, sizeof(FXJPEG_Context));
    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, uint8_t** 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 = (uint8_t*)((FXJPEG_Context*)pContext)->m_SrcMgr.next_input_byte;
        }
    }
    return (FX_DWORD)((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer;
}
