// 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" {
#undef FAR
#include "../../../../third_party/libjpeg/jpeglib.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" {
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);
  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() override;

  FX_BOOL Create(const uint8_t* src_buf,
                 FX_DWORD src_size,
                 int width,
                 int height,
                 int nComps,
                 FX_BOOL ColorTransform,
                 IFX_JpegProvider* pJP);
  void Destroy() { delete this; }

  // CCodec_ScanlineDecoder
  void v_DownScale(int dest_width, int dest_height) override;
  FX_BOOL v_Rewind() override;
  uint8_t* v_GetNextLine() override;
  FX_DWORD GetSrcOffset() override;

  FX_BOOL InitDecode();

  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 m_bInited;
  FX_BOOL m_bStarted;
  FX_BOOL 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;
  }
  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 =
      (static_cast<FX_DWORD>(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;
  }
  if (ratio >= 4) {
    return 4;
  }
  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 = (static_cast<FX_DWORD>(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 = FX_Alloc(FXJPEG_Context, 1);
  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;
}
int 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 0;
  }
  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;
}
