diff options
Diffstat (limited to 'core/fxcodec')
-rw-r--r-- | core/fxcodec/codec/ccodec_jpegmodule.h | 25 | ||||
-rw-r--r-- | core/fxcodec/codec/ccodec_progressivedecoder.h | 5 | ||||
-rw-r--r-- | core/fxcodec/codec/fx_codec_jpeg.cpp | 123 | ||||
-rw-r--r-- | core/fxcodec/codec/fx_codec_progress.cpp | 33 |
4 files changed, 101 insertions, 85 deletions
diff --git a/core/fxcodec/codec/ccodec_jpegmodule.h b/core/fxcodec/codec/ccodec_jpegmodule.h index 7782b5fad1..276e46a55f 100644 --- a/core/fxcodec/codec/ccodec_jpegmodule.h +++ b/core/fxcodec/codec/ccodec_jpegmodule.h @@ -9,11 +9,11 @@ #include <memory> +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_system.h" class CCodec_ScanlineDecoder; class CFX_DIBSource; -struct FXJPEG_Context; #ifdef PDF_ENABLE_XFA class CFX_DIBAttribute; @@ -21,7 +21,7 @@ class CFX_DIBAttribute; class CCodec_JpegModule { public: - CCodec_JpegModule() {} + class Context; std::unique_ptr<CCodec_ScanlineDecoder> CreateDecoder(const uint8_t* src_buf, uint32_t src_size, @@ -36,28 +36,23 @@ class CCodec_JpegModule { int* num_components, int* bits_per_components, bool* color_transform); - FXJPEG_Context* Start(); - void Finish(FXJPEG_Context* pContext); - void Input(FXJPEG_Context* pContext, - const uint8_t* src_buf, - uint32_t src_size); + Context* Start(); + void Finish(Context* pContext); + void Input(Context* pContext, const uint8_t* src_buf, uint32_t src_size); #ifndef PDF_ENABLE_XFA - int ReadHeader(FXJPEG_Context* pContext, - int* width, - int* height, - int* nComps); + int ReadHeader(Context* pContext, int* width, int* height, int* nComps); #else // PDF_ENABLE_XFA - int ReadHeader(FXJPEG_Context* pContext, + int ReadHeader(Context* pContext, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute); #endif // PDF_ENABLE_XFA - bool StartScanline(FXJPEG_Context* pContext, int down_scale); - bool ReadScanline(FXJPEG_Context* pContext, uint8_t* dest_buf); - uint32_t GetAvailInput(FXJPEG_Context* pContext, uint8_t** avail_buf_ptr); + bool StartScanline(Context* pContext, int down_scale); + bool ReadScanline(Context* pContext, uint8_t* dest_buf); + uint32_t GetAvailInput(Context* pContext, uint8_t** avail_buf_ptr); #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ static bool JpegEncode(const CFX_RetainPtr<CFX_DIBSource>& pSource, diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h index 5ebb32397d..33ac558fc9 100644 --- a/core/fxcodec/codec/ccodec_progressivedecoder.h +++ b/core/fxcodec/codec/ccodec_progressivedecoder.h @@ -12,6 +12,7 @@ #include "core/fxcodec/codec/ccodec_bmpmodule.h" #include "core/fxcodec/codec/ccodec_gifmodule.h" +#include "core/fxcodec/codec/ccodec_jpegmodule.h" #include "core/fxcodec/codec/ccodec_pngmodule.h" #include "core/fxcodec/codec/ccodec_tiffmodule.h" #include "core/fxcodec/fx_codec_def.h" @@ -21,11 +22,9 @@ #include "core/fxcrt/fx_system.h" #include "core/fxge/fx_dib.h" -class CCodec_JpegModule; class CCodec_ModuleMgr; class CFX_DIBAttribute; class IFX_SeekableReadStream; -struct FXJPEG_Context; class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate, public CCodec_GifModule::Delegate, @@ -131,7 +130,7 @@ class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate, CFX_UnownedPtr<CCodec_ModuleMgr> m_pCodecMgr; // TODO(tsepez): All these contexts probably should be unique_ptrs. - FXJPEG_Context* m_pJpegContext; + CFX_UnownedPtr<CCodec_JpegModule::Context> m_pJpegContext; CFX_UnownedPtr<CCodec_PngModule::Context> m_pPngContext; std::unique_ptr<CGifContext> m_pGifContext; CCodec_BmpModule::Context* m_pBmpContext; diff --git a/core/fxcodec/codec/fx_codec_jpeg.cpp b/core/fxcodec/codec/fx_codec_jpeg.cpp index 2211e79522..741d43d4f2 100644 --- a/core/fxcodec/codec/fx_codec_jpeg.cpp +++ b/core/fxcodec/codec/fx_codec_jpeg.cpp @@ -9,7 +9,7 @@ #include <memory> #include <utility> -#include "core/fxcodec/codec/codec_int.h" +#include "core/fxcodec/codec/ccodec_jpegmodule.h" #include "core/fxcodec/fx_codec.h" #include "core/fxcrt/fx_safe_types.h" #include "core/fxge/dib/cfx_dibsource.h" @@ -26,7 +26,21 @@ extern "C" { #else #include "third_party/libjpeg/jpeglib.h" #endif -} +} // extern "C" + +class CCodec_JpegModule::Context { + public: + Context(); + ~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" { @@ -80,7 +94,7 @@ static boolean _dest_empty(j_compress_ptr cinfo) { return false; } #endif -}; +} // extern "C" #define JPEG_MARKER_ICC (JPEG_APP0 + 2) #define JPEG_MARKER_MAXSIZE 0xFFFF @@ -346,69 +360,77 @@ bool CCodec_JpegModule::LoadInfo(const uint8_t* src_buf, bits_per_components, color_transform); } -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); + auto* pContext = + reinterpret_cast<CCodec_JpegModule::Context*>(cinfo->client_data); + longjmp(pContext->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); + auto* pContext = + reinterpret_cast<CCodec_JpegModule::Context*>(cinfo->client_data); + pContext->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); } -FXJPEG_Context* CCodec_JpegModule::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; + +} // extern "C" + +CCodec_JpegModule::Context::Context() + : m_SkipSize(0), m_AllocFunc(jpeg_alloc_func), m_FreeFunc(jpeg_free_func) { + memset(&m_Info, 0, sizeof(m_Info)); + m_Info.client_data = this; + m_Info.err = &m_ErrMgr; + + memset(&m_ErrMgr, 0, sizeof(m_ErrMgr)); + m_ErrMgr.error_exit = _error_fatal1; + m_ErrMgr.emit_message = _error_do_nothing1; + m_ErrMgr.output_message = _error_do_nothing; + m_ErrMgr.format_message = _error_do_nothing2; + m_ErrMgr.reset_error_mgr = _error_do_nothing; + + memset(&m_SrcMgr, 0, sizeof(m_SrcMgr)); + m_SrcMgr.init_source = _src_do_nothing; + m_SrcMgr.term_source = _src_do_nothing; + m_SrcMgr.skip_input_data = _src_skip_data1; + m_SrcMgr.fill_input_buffer = _src_fill_buffer; + m_SrcMgr.resync_to_restart = _src_resync; +} + +CCodec_JpegModule::Context::~Context() { + jpeg_destroy_decompress(&m_Info); +} + +CCodec_JpegModule::Context* CCodec_JpegModule::Start() { + auto* pContext = new CCodec_JpegModule::Context(); + if (setjmp(pContext->m_JumpMark) == -1) + return nullptr; + + jpeg_create_decompress(&pContext->m_Info); + pContext->m_Info.src = &pContext->m_SrcMgr; + pContext->m_SkipSize = 0; + return pContext; } -void CCodec_JpegModule::Finish(FXJPEG_Context* ctx) { - jpeg_destroy_decompress(&ctx->m_Info); - ctx->m_FreeFunc(ctx); +void CCodec_JpegModule::Finish(Context* ctx) { + delete ctx; } -void CCodec_JpegModule::Input(FXJPEG_Context* ctx, +void CCodec_JpegModule::Input(Context* ctx, const unsigned char* src_buf, uint32_t src_size) { if (ctx->m_SkipSize) { @@ -426,13 +448,13 @@ void CCodec_JpegModule::Input(FXJPEG_Context* ctx, } #ifdef PDF_ENABLE_XFA -int CCodec_JpegModule::ReadHeader(FXJPEG_Context* ctx, +int CCodec_JpegModule::ReadHeader(Context* ctx, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute) { #else // PDF_ENABLE_XFA -int CCodec_JpegModule::ReadHeader(FXJPEG_Context* ctx, +int CCodec_JpegModule::ReadHeader(Context* ctx, int* width, int* height, int* nComps) { @@ -455,7 +477,7 @@ int CCodec_JpegModule::ReadHeader(FXJPEG_Context* ctx, return 0; } -bool CCodec_JpegModule::StartScanline(FXJPEG_Context* ctx, int down_scale) { +bool CCodec_JpegModule::StartScanline(Context* ctx, int down_scale) { if (setjmp(ctx->m_JumpMark) == -1) return false; @@ -463,8 +485,7 @@ bool CCodec_JpegModule::StartScanline(FXJPEG_Context* ctx, int down_scale) { return !!jpeg_start_decompress(&ctx->m_Info); } -bool CCodec_JpegModule::ReadScanline(FXJPEG_Context* ctx, - unsigned char* dest_buf) { +bool CCodec_JpegModule::ReadScanline(Context* ctx, unsigned char* dest_buf) { if (setjmp(ctx->m_JumpMark) == -1) return false; @@ -472,7 +493,7 @@ bool CCodec_JpegModule::ReadScanline(FXJPEG_Context* ctx, return nlines == 1; } -uint32_t CCodec_JpegModule::GetAvailInput(FXJPEG_Context* ctx, +uint32_t CCodec_JpegModule::GetAvailInput(Context* ctx, uint8_t** avail_buf_ptr) { if (avail_buf_ptr) { *avail_buf_ptr = nullptr; diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp index 638141bc92..1691a31cbe 100644 --- a/core/fxcodec/codec/fx_codec_progress.cpp +++ b/core/fxcodec/codec/fx_codec_progress.cpp @@ -296,7 +296,7 @@ CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder( CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { m_pFile = nullptr; if (m_pJpegContext) - m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); + m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext.Release()); if (m_pBmpContext) m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); if (m_pPngContext) @@ -315,7 +315,7 @@ bool CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule, return false; } dwSize = dwSize - m_offSet; - uint32_t dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, nullptr); + uint32_t dwAvail = pJpegModule->GetAvailInput(m_pJpegContext.Get(), nullptr); if (dwAvail == m_SrcSize) { if (dwSize > FXCODEC_BLOCK_SIZE) { dwSize = FXCODEC_BLOCK_SIZE; @@ -341,7 +341,7 @@ bool CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule, return false; } m_offSet += dwSize; - pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail); + pJpegModule->Input(m_pJpegContext.Get(), m_pSrcBuf, dwSize + dwAvail); return true; } @@ -1079,10 +1079,10 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, return false; } m_offSet += size; - pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size); + pJpegModule->Input(m_pJpegContext.Get(), m_pSrcBuf, size); int32_t readResult = - pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, - &m_SrcComponents, pAttribute); + pJpegModule->ReadHeader(m_pJpegContext.Get(), &m_SrcWidth, + &m_SrcHeight, &m_SrcComponents, pAttribute); while (readResult == 2) { FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; if (!JpegReadMoreData(pJpegModule, error_status)) { @@ -1090,18 +1090,16 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, return false; } readResult = - pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, - &m_SrcComponents, pAttribute); + pJpegModule->ReadHeader(m_pJpegContext.Get(), &m_SrcWidth, + &m_SrcHeight, &m_SrcComponents, pAttribute); } if (!readResult) { m_SrcBPC = 8; m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); return true; } - if (m_pJpegContext) { - pJpegModule->Finish(m_pJpegContext); - m_pJpegContext = nullptr; - } + if (m_pJpegContext) + pJpegModule->Finish(m_pJpegContext.Release()); m_status = FXCODEC_STATUS_ERR_FORMAT; return false; } @@ -1867,7 +1865,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode( int down_scale = 1; GetDownScale(down_scale); CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); - bool bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); + bool bStart = + pJpegModule->StartScanline(m_pJpegContext.Get(), down_scale); while (!bStart) { FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; if (!JpegReadMoreData(pJpegModule, error_status)) { @@ -1876,7 +1875,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode( m_status = error_status; return m_status; } - bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); + bStart = pJpegModule->StartScanline(m_pJpegContext.Get(), down_scale); } int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale; scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4; @@ -2018,7 +2017,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() { case FXCODEC_IMAGE_JPG: { CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); while (true) { - bool readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); + bool readRes = + pJpegModule->ReadScanline(m_pJpegContext.Get(), m_pDecodeBuf); while (!readRes) { FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; if (!JpegReadMoreData(pJpegModule, error_status)) { @@ -2027,7 +2027,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() { m_status = error_status; return m_status; } - readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); + readRes = + pJpegModule->ReadScanline(m_pJpegContext.Get(), m_pDecodeBuf); } if (m_SrcFormat == FXCodec_Rgb) { int src_Bpp = (m_SrcFormat & 0xff) >> 3; |