From 764ec513eecbebd12781bcc96ce81ed5e736ee92 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Mon, 14 Mar 2016 13:35:12 -0400 Subject: Move core/src/ up to core/. This CL moves the core/src/ files up to core/ and fixes up the include guards, includes and build files. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1800523005 . --- core/src/fxcodec/codec/DEPS | 4 - core/src/fxcodec/codec/codec_int.h | 428 ---- core/src/fxcodec/codec/fx_codec.cpp | 490 ----- core/src/fxcodec/codec/fx_codec_bmp.cpp | 125 -- core/src/fxcodec/codec/fx_codec_fax.cpp | 830 -------- core/src/fxcodec/codec/fx_codec_flate.cpp | 1007 ---------- core/src/fxcodec/codec/fx_codec_gif.cpp | 187 -- core/src/fxcodec/codec/fx_codec_icc.cpp | 1986 ------------------- core/src/fxcodec/codec/fx_codec_jbig.cpp | 127 -- core/src/fxcodec/codec/fx_codec_jpeg.cpp | 692 ------- core/src/fxcodec/codec/fx_codec_jpx_opj.cpp | 888 --------- core/src/fxcodec/codec/fx_codec_jpx_unittest.cpp | 538 ----- core/src/fxcodec/codec/fx_codec_png.cpp | 254 --- core/src/fxcodec/codec/fx_codec_progress.cpp | 2299 ---------------------- core/src/fxcodec/codec/fx_codec_progress.h | 213 -- core/src/fxcodec/codec/fx_codec_tiff.cpp | 544 ----- 16 files changed, 10612 deletions(-) delete mode 100644 core/src/fxcodec/codec/DEPS delete mode 100644 core/src/fxcodec/codec/codec_int.h delete mode 100644 core/src/fxcodec/codec/fx_codec.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_bmp.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_fax.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_flate.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_gif.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_icc.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_jbig.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_jpeg.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_jpx_opj.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_jpx_unittest.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_png.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_progress.cpp delete mode 100644 core/src/fxcodec/codec/fx_codec_progress.h delete mode 100644 core/src/fxcodec/codec/fx_codec_tiff.cpp (limited to 'core/src/fxcodec/codec') diff --git a/core/src/fxcodec/codec/DEPS b/core/src/fxcodec/codec/DEPS deleted file mode 100644 index 495d288992..0000000000 --- a/core/src/fxcodec/codec/DEPS +++ /dev/null @@ -1,4 +0,0 @@ -include_rules = [ - '+third_party/libpng16/png.h', - '+third_party/libtiff/tiffiop.h', -] diff --git a/core/src/fxcodec/codec/codec_int.h b/core/src/fxcodec/codec/codec_int.h deleted file mode 100644 index 5c784adad6..0000000000 --- a/core/src/fxcodec/codec/codec_int.h +++ /dev/null @@ -1,428 +0,0 @@ -// 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 - -#ifndef CORE_SRC_FXCODEC_CODEC_CODEC_INT_H_ -#define CORE_SRC_FXCODEC_CODEC_CODEC_INT_H_ - -#include - -#include -#include -#include -#include - -#include "core/include/fxcodec/fx_codec.h" -#include "core/src/fxcodec/jbig2/JBig2_Context.h" -#include "third_party/libopenjpeg20/openjpeg.h" // For OPJ_SIZE_T. - -class CFX_IccProfileCache; -class CFX_IccTransformCache; -class CPDF_ColorSpace; - -class CCodec_BasicModule : public ICodec_BasicModule { - public: - // ICodec_BasicModule: - FX_BOOL RunLengthEncode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size) override; - FX_BOOL A85Encode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size) override; - ICodec_ScanlineDecoder* CreateRunLengthDecoder(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc) override; -}; - -class CCodec_ScanlineDecoder : public ICodec_ScanlineDecoder { - public: - CCodec_ScanlineDecoder(); - ~CCodec_ScanlineDecoder() override; - - // ICodec_ScanlineDecoder - FX_DWORD GetSrcOffset() override { return -1; } - void DownScale(int dest_width, int dest_height) override; - const uint8_t* GetScanline(int line) override; - FX_BOOL SkipToScanline(int line, IFX_Pause* pPause) override; - int GetWidth() override { return m_OutputWidth; } - int GetHeight() override { return m_OutputHeight; } - int CountComps() override { return m_nComps; } - int GetBPC() override { return m_bpc; } - FX_BOOL IsColorTransformed() override { return m_bColorTransformed; } - void ClearImageData() override { m_pDataCache.reset(); } - - protected: - class ImageDataCache { - public: - ImageDataCache(int width, int height, FX_DWORD pitch); - ~ImageDataCache(); - - bool AllocateCache(); - void AppendLine(const uint8_t* line); - - int NumLines() const { return m_nCachedLines; } - const uint8_t* GetLine(int line) const; - bool IsSameDimensions(int width, int height) const { - return width == m_Width && height == m_Height; - } - - private: - bool IsValid() const { return m_Data.get() != nullptr; } - - const int m_Width; - const int m_Height; - const FX_DWORD m_Pitch; - int m_nCachedLines; - std::unique_ptr m_Data; - }; - - virtual FX_BOOL v_Rewind() = 0; - virtual uint8_t* v_GetNextLine() = 0; - virtual void v_DownScale(int dest_width, int dest_height) = 0; - - uint8_t* ReadNextLine(); - - int m_OrigWidth; - int m_OrigHeight; - int m_DownScale; - int m_OutputWidth; - int m_OutputHeight; - int m_nComps; - int m_bpc; - FX_DWORD m_Pitch; - FX_BOOL m_bColorTransformed; - int m_NextLine; - uint8_t* m_pLastScanline; - std::unique_ptr m_pDataCache; -}; - -class CCodec_FaxModule : public ICodec_FaxModule { - public: - // ICodec_FaxModule: - ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int K, - FX_BOOL EndOfLine, - FX_BOOL EncodedByteAlign, - FX_BOOL BlackIs1, - int Columns, - int Rows) override; - FX_BOOL Encode(const uint8_t* src_buf, - int width, - int height, - int pitch, - uint8_t*& dest_buf, - FX_DWORD& dest_size) override; -}; - -class CCodec_FlateModule : public ICodec_FlateModule { - public: - virtual ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc, - int predictor, - int Colors, - int BitsPerComponent, - int Columns); - virtual FX_DWORD FlateOrLZWDecode(FX_BOOL bLZW, - const uint8_t* src_buf, - FX_DWORD src_size, - FX_BOOL bEarlyChange, - int predictor, - int Colors, - int BitsPerComponent, - int Columns, - FX_DWORD estimated_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); - virtual FX_BOOL Encode(const uint8_t* src_buf, - FX_DWORD src_size, - int predictor, - int Colors, - int BitsPerComponent, - int Columns, - uint8_t*& dest_buf, - FX_DWORD& dest_size); - virtual FX_BOOL Encode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -}; - -class CCodec_JpegModule : public ICodec_JpegModule { - public: - CCodec_JpegModule() {} - ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - FX_BOOL ColorTransform) override; - FX_BOOL 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) override; - FX_BOOL Encode(const CFX_DIBSource* pSource, - uint8_t*& dest_buf, - FX_STRSIZE& dest_size, - int quality, - const uint8_t* icc_buf, - FX_DWORD icc_length) override; - void* Start() override; - void Finish(void* pContext) override; - void Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size) override; -#ifndef PDF_ENABLE_XFA - int ReadHeader(void* pContext, int* width, int* height, int* nComps) override; -#else // PDF_ENABLE_XFA - int ReadHeader(void* pContext, - int* width, - int* height, - int* nComps, - CFX_DIBAttribute* pAttribute) override; -#endif // PDF_ENABLE_XFA - int StartScanline(void* pContext, int down_scale) override; - FX_BOOL ReadScanline(void* pContext, uint8_t* dest_buf) override; - FX_DWORD GetAvailInput(void* pContext, uint8_t** avail_buf_ptr) override; -}; - -#ifdef PDF_ENABLE_XFA -#define PNG_ERROR_SIZE 256 -class CCodec_PngModule : public ICodec_PngModule { - public: - CCodec_PngModule() { FXSYS_memset(m_szLastError, '\0', PNG_ERROR_SIZE); } - - virtual void* Start(void* pModule); - virtual void Finish(void* pContext); - virtual FX_BOOL Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size, - CFX_DIBAttribute* pAttribute); - - protected: - FX_CHAR m_szLastError[PNG_ERROR_SIZE]; -}; -class CCodec_GifModule : public ICodec_GifModule { - public: - CCodec_GifModule() { FXSYS_memset(m_szLastError, '\0', 256); } - virtual void* Start(void* pModule); - virtual void Finish(void* pContext); - virtual FX_DWORD GetAvailInput(void* pContext, uint8_t** avail_buf_ptr); - virtual void Input(void* pContext, const uint8_t* src_buf, FX_DWORD src_size); - - virtual int32_t ReadHeader(void* pContext, - int* width, - int* height, - int* pal_num, - void** pal_pp, - int* bg_index, - CFX_DIBAttribute* pAttribute); - - virtual int32_t LoadFrameInfo(void* pContext, int* frame_num); - - virtual int32_t LoadFrame(void* pContext, - int frame_num, - CFX_DIBAttribute* pAttribute); - - protected: - FX_CHAR m_szLastError[256]; -}; -class CCodec_BmpModule : public ICodec_BmpModule { - public: - CCodec_BmpModule() { FXSYS_memset(m_szLastError, 0, sizeof(m_szLastError)); } - void* Start(void* pModule) override; - void Finish(void* pContext) override; - FX_DWORD GetAvailInput(void* pContext, uint8_t** avail_buf_ptr) override; - void Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size) override; - int32_t ReadHeader(void* pContext, - int32_t* width, - int32_t* height, - FX_BOOL* tb_flag, - int32_t* components, - int32_t* pal_num, - FX_DWORD** pal_pp, - CFX_DIBAttribute* pAttribute) override; - int32_t LoadImage(void* pContext) override; - - protected: - FX_CHAR m_szLastError[256]; -}; -#endif // PDF_ENABLE_XFA - -class CCodec_IccModule : public ICodec_IccModule { - public: - ~CCodec_IccModule() override; - - // ICodec_IccModule: - IccCS GetProfileCS(const uint8_t* pProfileData, - unsigned int dwProfileSize) override; - IccCS GetProfileCS(IFX_FileRead* pFile) override; - void* CreateTransform(ICodec_IccModule::IccParam* pInputParam, - ICodec_IccModule::IccParam* pOutputParam, - ICodec_IccModule::IccParam* pProofParam = NULL, - FX_DWORD dwIntent = Icc_INTENT_PERCEPTUAL, - FX_DWORD dwFlag = Icc_FLAGS_DEFAULT, - FX_DWORD dwPrfIntent = Icc_INTENT_ABSOLUTE_COLORIMETRIC, - FX_DWORD dwPrfFlag = Icc_FLAGS_SOFTPROOFING) override; - void* CreateTransform_sRGB( - const uint8_t* pProfileData, - FX_DWORD dwProfileSize, - FX_DWORD& nComponents, - int32_t intent = 0, - FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT) override; - void* CreateTransform_CMYK( - const uint8_t* pSrcProfileData, - FX_DWORD dwSrcProfileSize, - FX_DWORD& nSrcComponents, - const uint8_t* pDstProfileData, - FX_DWORD dwDstProfileSize, - int32_t intent = 0, - FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT, - FX_DWORD dwDstFormat = Icc_FORMAT_DEFAULT) override; - void DestroyTransform(void* pTransform) override; - void Translate(void* pTransform, - FX_FLOAT* pSrcValues, - FX_FLOAT* pDestValues) override; - void TranslateScanline(void* pTransform, - uint8_t* pDest, - const uint8_t* pSrc, - int pixels) override; - void SetComponents(FX_DWORD nComponents) override { - m_nComponents = nComponents; - } - - protected: - enum Icc_CLASS { - Icc_CLASS_INPUT = 0, - Icc_CLASS_OUTPUT, - Icc_CLASS_PROOF, - Icc_CLASS_MAX - }; - void* CreateProfile(ICodec_IccModule::IccParam* pIccParam, - Icc_CLASS ic, - CFX_BinaryBuf* pTransformKey); - - FX_DWORD m_nComponents; - std::map m_MapTranform; - std::map m_MapProfile; -}; - -class CCodec_JpxModule : public ICodec_JpxModule { - public: - CCodec_JpxModule(); - ~CCodec_JpxModule() override; - - // ICodec_JpxModule: - CJPX_Decoder* CreateDecoder(const uint8_t* src_buf, - FX_DWORD src_size, - CPDF_ColorSpace* cs) override; - void GetImageInfo(CJPX_Decoder* pDecoder, - FX_DWORD* width, - FX_DWORD* height, - FX_DWORD* components) override; - bool Decode(CJPX_Decoder* pDecoder, - uint8_t* dest_data, - int pitch, - const std::vector& offsets) override; - void DestroyDecoder(CJPX_Decoder* pDecoder) override; -}; - -#ifdef PDF_ENABLE_XFA -class CCodec_TiffModule : public ICodec_TiffModule { - public: - // ICodec_TiffModule - void* CreateDecoder(IFX_FileRead* file_ptr) override; - void GetFrames(void* ctx, int32_t& frames) override; - FX_BOOL LoadFrameInfo(void* ctx, - int32_t frame, - FX_DWORD& width, - FX_DWORD& height, - FX_DWORD& comps, - FX_DWORD& bpc, - CFX_DIBAttribute* pAttribute) override; - FX_BOOL Decode(void* ctx, class CFX_DIBitmap* pDIBitmap) override; - void DestroyDecoder(void* ctx) override; - - protected: - ~CCodec_TiffModule() override {} -}; -#endif // PDF_ENABLE_XFA - -class CCodec_Jbig2Context { - public: - CCodec_Jbig2Context(); - ~CCodec_Jbig2Context() {} - - FX_DWORD m_width; - FX_DWORD m_height; - CPDF_StreamAcc* m_pGlobalStream; - CPDF_StreamAcc* m_pSrcStream; - uint8_t* m_dest_buf; - FX_DWORD m_dest_pitch; - IFX_Pause* m_pPause; - CJBig2_Context* m_pContext; - CJBig2_Image* m_dest_image; -}; -class CCodec_Jbig2Module : public ICodec_Jbig2Module { - public: - CCodec_Jbig2Module() {} - ~CCodec_Jbig2Module() override; - - // ICodec_Jbig2Module - void* CreateJbig2Context() override; - FXCODEC_STATUS StartDecode(void* pJbig2Context, - CFX_PrivateData* pPrivateData, - FX_DWORD width, - FX_DWORD height, - CPDF_StreamAcc* src_stream, - CPDF_StreamAcc* global_stream, - uint8_t* dest_buf, - FX_DWORD dest_pitch, - IFX_Pause* pPause) override; - FXCODEC_STATUS ContinueDecode(void* pJbig2Context, - IFX_Pause* pPause) override; - void DestroyJbig2Context(void* pJbig2Context) override; -}; - -struct DecodeData { - public: - DecodeData(unsigned char* src_data, OPJ_SIZE_T src_size) - : src_data(src_data), src_size(src_size), offset(0) {} - unsigned char* src_data; - OPJ_SIZE_T src_size; - OPJ_SIZE_T offset; -}; - -void sycc420_to_rgb(opj_image_t* img); - -/* Wrappers for C-style callbacks. */ -OPJ_SIZE_T opj_read_from_memory(void* p_buffer, - OPJ_SIZE_T nb_bytes, - void* p_user_data); -OPJ_SIZE_T opj_write_from_memory(void* p_buffer, - OPJ_SIZE_T nb_bytes, - void* p_user_data); -OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data); -OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data); - -#endif // CORE_SRC_FXCODEC_CODEC_CODEC_INT_H_ diff --git a/core/src/fxcodec/codec/fx_codec.cpp b/core/src/fxcodec/codec/fx_codec.cpp deleted file mode 100644 index 17e665d608..0000000000 --- a/core/src/fxcodec/codec/fx_codec.cpp +++ /dev/null @@ -1,490 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" - -#include -#include - -#include "core/include/fxcrt/fx_ext.h" -#include "core/include/fxcrt/fx_safe_types.h" -#include "core/src/fxcodec/codec/codec_int.h" -#include "third_party/base/logging.h" - -CCodec_ModuleMgr::CCodec_ModuleMgr() - : m_pBasicModule(new CCodec_BasicModule), - m_pFaxModule(new CCodec_FaxModule), - m_pJpegModule(new CCodec_JpegModule), - m_pJpxModule(new CCodec_JpxModule), - m_pJbig2Module(new CCodec_Jbig2Module), - m_pIccModule(new CCodec_IccModule), -#ifdef PDF_ENABLE_XFA - m_pPngModule(new CCodec_PngModule), - m_pGifModule(new CCodec_GifModule), - m_pBmpModule(new CCodec_BmpModule), - m_pTiffModule(new CCodec_TiffModule), -#endif // PDF_ENABLE_XFA - m_pFlateModule(new CCodec_FlateModule) { -} - -CCodec_ScanlineDecoder::ImageDataCache::ImageDataCache(int width, - int height, - FX_DWORD pitch) - : m_Width(width), m_Height(height), m_Pitch(pitch), m_nCachedLines(0) {} - -CCodec_ScanlineDecoder::ImageDataCache::~ImageDataCache() { -} - -bool CCodec_ScanlineDecoder::ImageDataCache::AllocateCache() { - if (m_Pitch == 0 || m_Height < 0) - return false; - - FX_SAFE_SIZE_T size = m_Pitch; - size *= m_Height; - if (!size.IsValid()) - return false; - - m_Data.reset(FX_TryAlloc(uint8_t, size.ValueOrDie())); - return IsValid(); -} - -void CCodec_ScanlineDecoder::ImageDataCache::AppendLine(const uint8_t* line) { - // If the callers adds more lines than there is room, fail. - if (m_Pitch == 0 || m_nCachedLines >= m_Height) { - NOTREACHED(); - return; - } - - size_t offset = m_Pitch; - FXSYS_memcpy(m_Data.get() + offset * m_nCachedLines, line, m_Pitch); - ++m_nCachedLines; -} - -const uint8_t* CCodec_ScanlineDecoder::ImageDataCache::GetLine(int line) const { - if (m_Pitch == 0 || line < 0 || line >= m_nCachedLines) - return nullptr; - - size_t offset = m_Pitch; - return m_Data.get() + offset * line; -} - -CCodec_ScanlineDecoder::CCodec_ScanlineDecoder() - : m_NextLine(-1), m_pLastScanline(nullptr) { -} - -CCodec_ScanlineDecoder::~CCodec_ScanlineDecoder() { -} - -const uint8_t* CCodec_ScanlineDecoder::GetScanline(int line) { - if (m_pDataCache && line < m_pDataCache->NumLines()) - return m_pDataCache->GetLine(line); - - if (m_NextLine == line + 1) - return m_pLastScanline; - - if (m_NextLine < 0 || m_NextLine > line) { - if (!v_Rewind()) - return nullptr; - m_NextLine = 0; - } - while (m_NextLine < line) { - ReadNextLine(); - m_NextLine++; - } - m_pLastScanline = ReadNextLine(); - m_NextLine++; - return m_pLastScanline; -} - -FX_BOOL CCodec_ScanlineDecoder::SkipToScanline(int line, IFX_Pause* pPause) { - if (m_pDataCache && line < m_pDataCache->NumLines()) - return FALSE; - - if (m_NextLine == line || m_NextLine == line + 1) - return FALSE; - - if (m_NextLine < 0 || m_NextLine > line) { - v_Rewind(); - m_NextLine = 0; - } - m_pLastScanline = nullptr; - while (m_NextLine < line) { - m_pLastScanline = ReadNextLine(); - m_NextLine++; - if (pPause && pPause->NeedToPauseNow()) { - return TRUE; - } - } - return FALSE; -} - -uint8_t* CCodec_ScanlineDecoder::ReadNextLine() { - uint8_t* pLine = v_GetNextLine(); - if (!pLine) - return nullptr; - - if (m_pDataCache && m_NextLine == m_pDataCache->NumLines()) - m_pDataCache->AppendLine(pLine); - return pLine; -} - -void CCodec_ScanlineDecoder::DownScale(int dest_width, int dest_height) { - dest_width = std::abs(dest_width); - dest_height = std::abs(dest_height); - v_DownScale(dest_width, dest_height); - - if (m_pDataCache && - m_pDataCache->IsSameDimensions(m_OutputWidth, m_OutputHeight)) { - return; - } - - std::unique_ptr cache( - new ImageDataCache(m_OutputWidth, m_OutputHeight, m_Pitch)); - if (!cache->AllocateCache()) - return; - - m_pDataCache = std::move(cache); -} - -FX_BOOL CCodec_BasicModule::RunLengthEncode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size) { - return FALSE; -} - -#define EXPONENT_DETECT(ptr) \ - for (;; ptr++) { \ - if (!std::isdigit(*ptr)) { \ - if (endptr) \ - *endptr = (char*)ptr; \ - break; \ - } else { \ - exp_ret *= 10; \ - exp_ret += FXSYS_toDecimalDigit(*ptr); \ - continue; \ - } \ - } - -extern "C" double FXstrtod(const char* nptr, char** endptr) { - double ret = 0.0; - const char* ptr = nptr; - const char* exp_ptr = NULL; - int e_number = 0, e_signal = 0, e_point = 0, is_negative = 0; - int exp_ret = 0, exp_sig = 1, fra_ret = 0, fra_count = 0, fra_base = 1; - if (!nptr) { - return 0.0; - } - for (;; ptr++) { - if (!e_number && !e_point && (*ptr == '\t' || *ptr == ' ')) - continue; - - if (std::isdigit(*ptr)) { - if (!e_number) - e_number = 1; - - if (!e_point) { - ret *= 10; - ret += FXSYS_toDecimalDigit(*ptr); - } else { - fra_count++; - fra_ret *= 10; - fra_ret += FXSYS_toDecimalDigit(*ptr); - } - continue; - } - if (!e_point && *ptr == '.') { - e_point = 1; - continue; - } - if (!e_number && !e_point && !e_signal) { - switch (*ptr) { - case '-': - is_negative = 1; - case '+': - e_signal = 1; - continue; - } - } - if (e_number && (*ptr == 'e' || *ptr == 'E')) { - exp_ptr = ptr++; - if (*ptr == '+' || *ptr == '-') { - exp_sig = (*ptr++ == '+') ? 1 : -1; - if (!std::isdigit(*ptr)) { - if (endptr) { - *endptr = (char*)exp_ptr; - } - break; - } - EXPONENT_DETECT(ptr); - } else if (std::isdigit(*ptr)) { - EXPONENT_DETECT(ptr); - } else { - if (endptr) { - *endptr = (char*)exp_ptr; - } - break; - } - break; - } - if (ptr != nptr && !e_number) { - if (endptr) { - *endptr = (char*)nptr; - } - break; - } - if (endptr) { - *endptr = (char*)ptr; - } - break; - } - while (fra_count--) { - fra_base *= 10; - } - ret += (double)fra_ret / (double)fra_base; - if (exp_sig == 1) { - while (exp_ret--) { - ret *= 10.0; - } - } else { - while (exp_ret--) { - ret /= 10.0; - } - } - return is_negative ? -ret : ret; -} -#undef EXPONENT_DETECT - -FX_BOOL CCodec_BasicModule::A85Encode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size) { - return FALSE; -} - -#ifdef PDF_ENABLE_XFA -CFX_DIBAttribute::CFX_DIBAttribute() - : m_nXDPI(-1), - m_nYDPI(-1), - m_fAspectRatio(-1.0f), - m_wDPIUnit(0), - m_nGifLeft(0), - m_nGifTop(0), - m_pGifLocalPalette(nullptr), - m_nGifLocalPalNum(0), - m_nBmpCompressType(0) { - FXSYS_memset(m_strTime, 0, sizeof(m_strTime)); -} -CFX_DIBAttribute::~CFX_DIBAttribute() { - for (const auto& pair : m_Exif) - FX_Free(pair.second); -} -#endif // PDF_ENABLE_XFA - -class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder { - public: - CCodec_RLScanlineDecoder(); - ~CCodec_RLScanlineDecoder() override; - - FX_BOOL Create(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc); - - // 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 { return m_SrcOffset; } - - protected: - FX_BOOL CheckDestSize(); - void GetNextOperator(); - void UpdateOperator(uint8_t used_bytes); - - uint8_t* m_pScanline; - const uint8_t* m_pSrcBuf; - FX_DWORD m_SrcSize; - FX_DWORD m_dwLineBytes; - FX_DWORD m_SrcOffset; - FX_BOOL m_bEOD; - uint8_t m_Operator; -}; -CCodec_RLScanlineDecoder::CCodec_RLScanlineDecoder() - : m_pScanline(NULL), - m_pSrcBuf(NULL), - m_SrcSize(0), - m_dwLineBytes(0), - m_SrcOffset(0), - m_bEOD(FALSE), - m_Operator(0) {} -CCodec_RLScanlineDecoder::~CCodec_RLScanlineDecoder() { - FX_Free(m_pScanline); -} -FX_BOOL CCodec_RLScanlineDecoder::CheckDestSize() { - FX_DWORD i = 0; - FX_DWORD old_size = 0; - FX_DWORD dest_size = 0; - while (i < m_SrcSize) { - if (m_pSrcBuf[i] < 128) { - old_size = dest_size; - dest_size += m_pSrcBuf[i] + 1; - if (dest_size < old_size) { - return FALSE; - } - i += m_pSrcBuf[i] + 2; - } else if (m_pSrcBuf[i] > 128) { - old_size = dest_size; - dest_size += 257 - m_pSrcBuf[i]; - if (dest_size < old_size) { - return FALSE; - } - i += 2; - } else { - break; - } - } - if (((FX_DWORD)m_OrigWidth * m_nComps * m_bpc * m_OrigHeight + 7) / 8 > - dest_size) { - return FALSE; - } - return TRUE; -} -FX_BOOL CCodec_RLScanlineDecoder::Create(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc) { - m_pSrcBuf = src_buf; - m_SrcSize = src_size; - m_OutputWidth = m_OrigWidth = width; - m_OutputHeight = m_OrigHeight = height; - m_nComps = nComps; - m_bpc = bpc; - m_bColorTransformed = FALSE; - m_DownScale = 1; - // Aligning the pitch to 4 bytes requires an integer overflow check. - FX_SAFE_DWORD pitch = width; - pitch *= nComps; - pitch *= bpc; - pitch += 31; - pitch /= 32; - pitch *= 4; - if (!pitch.IsValid()) { - return FALSE; - } - m_Pitch = pitch.ValueOrDie(); - // Overflow should already have been checked before this is called. - m_dwLineBytes = (static_cast(width) * nComps * bpc + 7) / 8; - m_pScanline = FX_Alloc(uint8_t, m_Pitch); - return CheckDestSize(); -} -FX_BOOL CCodec_RLScanlineDecoder::v_Rewind() { - FXSYS_memset(m_pScanline, 0, m_Pitch); - m_SrcOffset = 0; - m_bEOD = FALSE; - m_Operator = 0; - return TRUE; -} -uint8_t* CCodec_RLScanlineDecoder::v_GetNextLine() { - if (m_SrcOffset == 0) { - GetNextOperator(); - } else { - if (m_bEOD) { - return NULL; - } - } - FXSYS_memset(m_pScanline, 0, m_Pitch); - FX_DWORD col_pos = 0; - FX_BOOL eol = FALSE; - while (m_SrcOffset < m_SrcSize && !eol) { - if (m_Operator < 128) { - FX_DWORD copy_len = m_Operator + 1; - if (col_pos + copy_len >= m_dwLineBytes) { - copy_len = m_dwLineBytes - col_pos; - eol = TRUE; - } - if (copy_len >= m_SrcSize - m_SrcOffset) { - copy_len = m_SrcSize - m_SrcOffset; - m_bEOD = TRUE; - } - FXSYS_memcpy(m_pScanline + col_pos, m_pSrcBuf + m_SrcOffset, copy_len); - col_pos += copy_len; - UpdateOperator((uint8_t)copy_len); - } else if (m_Operator > 128) { - int fill = 0; - if (m_SrcOffset - 1 < m_SrcSize - 1) { - fill = m_pSrcBuf[m_SrcOffset]; - } - FX_DWORD duplicate_len = 257 - m_Operator; - if (col_pos + duplicate_len >= m_dwLineBytes) { - duplicate_len = m_dwLineBytes - col_pos; - eol = TRUE; - } - FXSYS_memset(m_pScanline + col_pos, fill, duplicate_len); - col_pos += duplicate_len; - UpdateOperator((uint8_t)duplicate_len); - } else { - m_bEOD = TRUE; - break; - } - } - return m_pScanline; -} -void CCodec_RLScanlineDecoder::GetNextOperator() { - if (m_SrcOffset >= m_SrcSize) { - m_Operator = 128; - return; - } - m_Operator = m_pSrcBuf[m_SrcOffset]; - m_SrcOffset++; -} -void CCodec_RLScanlineDecoder::UpdateOperator(uint8_t used_bytes) { - if (used_bytes == 0) { - return; - } - if (m_Operator < 128) { - FXSYS_assert((FX_DWORD)m_Operator + 1 >= used_bytes); - if (used_bytes == m_Operator + 1) { - m_SrcOffset += used_bytes; - GetNextOperator(); - return; - } - m_Operator -= used_bytes; - m_SrcOffset += used_bytes; - if (m_SrcOffset >= m_SrcSize) { - m_Operator = 128; - } - return; - } - uint8_t count = 257 - m_Operator; - FXSYS_assert((FX_DWORD)count >= used_bytes); - if (used_bytes == count) { - m_SrcOffset++; - GetNextOperator(); - return; - } - count -= used_bytes; - m_Operator = 257 - count; -} -ICodec_ScanlineDecoder* CCodec_BasicModule::CreateRunLengthDecoder( - const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc) { - CCodec_RLScanlineDecoder* pRLScanlineDecoder = new CCodec_RLScanlineDecoder; - if (!pRLScanlineDecoder->Create(src_buf, src_size, width, height, nComps, - bpc)) { - delete pRLScanlineDecoder; - return NULL; - } - return pRLScanlineDecoder; -} diff --git a/core/src/fxcodec/codec/fx_codec_bmp.cpp b/core/src/fxcodec/codec/fx_codec_bmp.cpp deleted file mode 100644 index 41a881d3ae..0000000000 --- a/core/src/fxcodec/codec/fx_codec_bmp.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "core/src/fxcodec/codec/codec_int.h" -#include "core/src/fxcodec/lbmp/fx_bmp.h" -struct FXBMP_Context { - bmp_decompress_struct_p bmp_ptr; - void* parent_ptr; - void* child_ptr; - - void* (*m_AllocFunc)(unsigned int); - void (*m_FreeFunc)(void*); -}; -extern "C" { -static void* bmp_alloc_func(unsigned int size) { - return FX_Alloc(char, size); -} -static void bmp_free_func(void* p) { - FX_Free(p); -} -}; -static void bmp_error_data(bmp_decompress_struct_p bmp_ptr, - const FX_CHAR* err_msg) { - FXSYS_strncpy((char*)bmp_ptr->err_ptr, err_msg, BMP_MAX_ERROR_SIZE - 1); - longjmp(bmp_ptr->jmpbuf, 1); -} -static void bmp_read_scanline(bmp_decompress_struct_p bmp_ptr, - int32_t row_num, - uint8_t* row_buf) { - FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; - CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; - pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf); -} -static FX_BOOL bmp_get_data_position(bmp_decompress_struct_p bmp_ptr, - FX_DWORD rcd_pos) { - FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; - CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; - return pModule->InputImagePositionBufCallback(p->child_ptr, rcd_pos); -} -void* CCodec_BmpModule::Start(void* pModule) { - FXBMP_Context* p = (FXBMP_Context*)FX_Alloc(uint8_t, sizeof(FXBMP_Context)); - if (p == NULL) { - return NULL; - } - FXSYS_memset(p, 0, sizeof(FXBMP_Context)); - if (p == NULL) { - return NULL; - } - p->m_AllocFunc = bmp_alloc_func; - p->m_FreeFunc = bmp_free_func; - p->bmp_ptr = NULL; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->bmp_ptr = bmp_create_decompress(); - if (p->bmp_ptr == NULL) { - FX_Free(p); - return NULL; - } - p->bmp_ptr->context_ptr = (void*)p; - p->bmp_ptr->err_ptr = m_szLastError; - p->bmp_ptr->bmp_error_fn = bmp_error_data; - p->bmp_ptr->bmp_get_row_fn = bmp_read_scanline; - p->bmp_ptr->bmp_get_data_position_fn = bmp_get_data_position; - return p; -} -void CCodec_BmpModule::Finish(void* pContext) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - if (p) { - bmp_destroy_decompress(&p->bmp_ptr); - p->m_FreeFunc(p); - } -} -int32_t CCodec_BmpModule::ReadHeader(void* pContext, - int32_t* width, - int32_t* height, - FX_BOOL* tb_flag, - int32_t* components, - int32_t* pal_num, - FX_DWORD** pal_pp, - CFX_DIBAttribute* pAttribute) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - if (setjmp(p->bmp_ptr->jmpbuf)) { - return 0; - } - int32_t ret = bmp_read_header(p->bmp_ptr); - if (ret != 1) { - return ret; - } - *width = p->bmp_ptr->width; - *height = p->bmp_ptr->height; - *tb_flag = p->bmp_ptr->imgTB_flag; - *components = p->bmp_ptr->components; - *pal_num = p->bmp_ptr->pal_num; - *pal_pp = p->bmp_ptr->pal_ptr; - if (pAttribute) { - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; - pAttribute->m_nXDPI = p->bmp_ptr->dpi_x; - pAttribute->m_nYDPI = p->bmp_ptr->dpi_y; - pAttribute->m_nBmpCompressType = p->bmp_ptr->compress_flag; - } - return 1; -} -int32_t CCodec_BmpModule::LoadImage(void* pContext) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - if (setjmp(p->bmp_ptr->jmpbuf)) { - return 0; - } - return bmp_decode_image(p->bmp_ptr); -} -FX_DWORD CCodec_BmpModule::GetAvailInput(void* pContext, - uint8_t** avial_buf_ptr) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - return bmp_get_avail_input(p->bmp_ptr, avial_buf_ptr); -} -void CCodec_BmpModule::Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size) { - FXBMP_Context* p = (FXBMP_Context*)pContext; - bmp_input_buffer(p->bmp_ptr, (uint8_t*)src_buf, src_size); -} diff --git a/core/src/fxcodec/codec/fx_codec_fax.cpp b/core/src/fxcodec/codec/fx_codec_fax.cpp deleted file mode 100644 index 36b92f06ff..0000000000 --- a/core/src/fxcodec/codec/fx_codec_fax.cpp +++ /dev/null @@ -1,830 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/src/fxcodec/codec/codec_int.h" - -namespace { - -const uint8_t OneLeadPos[256] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; -const uint8_t ZeroLeadPos[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, -}; - -int FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) { - if (start_pos >= max_pos) { - return max_pos; - } - const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; - if (start_pos % 8) { - uint8_t data = data_buf[start_pos / 8]; - if (bit) { - data &= 0xff >> (start_pos % 8); - } else { - data |= 0xff << (8 - start_pos % 8); - } - if (leading_pos[data] < 8) { - return start_pos / 8 * 8 + leading_pos[data]; - } - start_pos += 7; - } - uint8_t skip = bit ? 0x00 : 0xff; - int byte_pos = start_pos / 8; - int max_byte = (max_pos + 7) / 8; - while (byte_pos < max_byte) { - if (data_buf[byte_pos] != skip) { - break; - } - byte_pos++; - } - if (byte_pos == max_byte) { - return max_pos; - } - int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8; - if (pos > max_pos) { - pos = max_pos; - } - return pos; -} - -void FaxG4FindB1B2(const uint8_t* ref_buf, - int columns, - int a0, - bool a0color, - int& b1, - int& b2) { - uint8_t first_bit = - (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); - b1 = FindBit(ref_buf, columns, a0 + 1, !first_bit); - if (b1 >= columns) { - b1 = b2 = columns; - return; - } - if (first_bit == !a0color) { - b1 = FindBit(ref_buf, columns, b1 + 1, first_bit); - first_bit = !first_bit; - } - if (b1 >= columns) { - b1 = b2 = columns; - return; - } - b2 = FindBit(ref_buf, columns, b1 + 1, first_bit); -} - -void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { - if (startpos < 0) { - startpos = 0; - } - if (endpos < 0) { - endpos = 0; - } - if (endpos >= columns) { - endpos = columns; - } - if (startpos >= endpos) { - return; - } - int first_byte = startpos / 8; - int last_byte = (endpos - 1) / 8; - if (first_byte == last_byte) { - for (int i = startpos % 8; i <= (endpos - 1) % 8; i++) { - dest_buf[first_byte] -= 1 << (7 - i); - } - return; - } - int i; - for (i = startpos % 8; i < 8; i++) { - dest_buf[first_byte] -= 1 << (7 - i); - } - for (i = 0; i <= (endpos - 1) % 8; i++) { - dest_buf[last_byte] -= 1 << (7 - i); - } - if (last_byte > first_byte + 1) { - FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); - } -} - -#define NEXTBIT \ - src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \ - bitpos++; -#define ADDBIT(code, bit) \ - code = code << 1; \ - if (bit) \ - code++; -#define GETBIT(bitpos) src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)) - -const uint8_t FaxBlackRunIns[] = { - 0, 2, 0x02, 3, 0, 0x03, - 2, 0, 2, 0x02, 1, 0, - 0x03, 4, 0, 2, 0x02, 6, - 0, 0x03, 5, 0, 1, 0x03, - 7, 0, 2, 0x04, 9, 0, - 0x05, 8, 0, 3, 0x04, 10, - 0, 0x05, 11, 0, 0x07, 12, - 0, 2, 0x04, 13, 0, 0x07, - 14, 0, 1, 0x18, 15, 0, - 5, 0x08, 18, 0, 0x0f, 64, - 0, 0x17, 16, 0, 0x18, 17, - 0, 0x37, 0, 0, 10, 0x08, - 0x00, 0x07, 0x0c, 0x40, 0x07, 0x0d, - 0x80, 0x07, 0x17, 24, 0, 0x18, - 25, 0, 0x28, 23, 0, 0x37, - 22, 0, 0x67, 19, 0, 0x68, - 20, 0, 0x6c, 21, 0, 54, - 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, - 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, - 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, - 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, - 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, - 0x24, 52, 0, 0x27, 55, 0, - 0x28, 56, 0, 0x2b, 59, 0, - 0x2c, 60, 0, 0x33, 320 % 256, 320 / 256, - 0x34, 384 % 256, 384 / 256, 0x35, 448 % 256, 448 / 256, - 0x37, 53, 0, 0x38, 54, 0, - 0x52, 50, 0, 0x53, 51, 0, - 0x54, 44, 0, 0x55, 45, 0, - 0x56, 46, 0, 0x57, 47, 0, - 0x58, 57, 0, 0x59, 58, 0, - 0x5a, 61, 0, 0x5b, 256 % 256, 256 / 256, - 0x64, 48, 0, 0x65, 49, 0, - 0x66, 62, 0, 0x67, 63, 0, - 0x68, 30, 0, 0x69, 31, 0, - 0x6a, 32, 0, 0x6b, 33, 0, - 0x6c, 40, 0, 0x6d, 41, 0, - 0xc8, 128, 0, 0xc9, 192, 0, - 0xca, 26, 0, 0xcb, 27, 0, - 0xcc, 28, 0, 0xcd, 29, 0, - 0xd2, 34, 0, 0xd3, 35, 0, - 0xd4, 36, 0, 0xd5, 37, 0, - 0xd6, 38, 0, 0xd7, 39, 0, - 0xda, 42, 0, 0xdb, 43, 0, - 20, 0x4a, 640 % 256, 640 / 256, 0x4b, 704 % 256, - 704 / 256, 0x4c, 768 % 256, 768 / 256, 0x4d, 832 % 256, - 832 / 256, 0x52, 1280 % 256, 1280 / 256, 0x53, 1344 % 256, - 1344 / 256, 0x54, 1408 % 256, 1408 / 256, 0x55, 1472 % 256, - 1472 / 256, 0x5a, 1536 % 256, 1536 / 256, 0x5b, 1600 % 256, - 1600 / 256, 0x64, 1664 % 256, 1664 / 256, 0x65, 1728 % 256, - 1728 / 256, 0x6c, 512 % 256, 512 / 256, 0x6d, 576 % 256, - 576 / 256, 0x72, 896 % 256, 896 / 256, 0x73, 960 % 256, - 960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256, - 1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256, - 1216 / 256, 0xff}; - -const uint8_t FaxWhiteRunIns[] = { - 0, 0, 0, 6, 0x07, 2, - 0, 0x08, 3, 0, 0x0B, 4, - 0, 0x0C, 5, 0, 0x0E, 6, - 0, 0x0F, 7, 0, 6, 0x07, - 10, 0, 0x08, 11, 0, 0x12, - 128, 0, 0x13, 8, 0, 0x14, - 9, 0, 0x1b, 64, 0, 9, - 0x03, 13, 0, 0x07, 1, 0, - 0x08, 12, 0, 0x17, 192, 0, - 0x18, 1664 % 256, 1664 / 256, 0x2a, 16, 0, - 0x2B, 17, 0, 0x34, 14, 0, - 0x35, 15, 0, 12, 0x03, 22, - 0, 0x04, 23, 0, 0x08, 20, - 0, 0x0c, 19, 0, 0x13, 26, - 0, 0x17, 21, 0, 0x18, 28, - 0, 0x24, 27, 0, 0x27, 18, - 0, 0x28, 24, 0, 0x2B, 25, - 0, 0x37, 256 % 256, 256 / 256, 42, 0x02, - 29, 0, 0x03, 30, 0, 0x04, - 45, 0, 0x05, 46, 0, 0x0a, - 47, 0, 0x0b, 48, 0, 0x12, - 33, 0, 0x13, 34, 0, 0x14, - 35, 0, 0x15, 36, 0, 0x16, - 37, 0, 0x17, 38, 0, 0x1a, - 31, 0, 0x1b, 32, 0, 0x24, - 53, 0, 0x25, 54, 0, 0x28, - 39, 0, 0x29, 40, 0, 0x2a, - 41, 0, 0x2b, 42, 0, 0x2c, - 43, 0, 0x2d, 44, 0, 0x32, - 61, 0, 0x33, 62, 0, 0x34, - 63, 0, 0x35, 0, 0, 0x36, - 320 % 256, 320 / 256, 0x37, 384 % 256, 384 / 256, 0x4a, - 59, 0, 0x4b, 60, 0, 0x52, - 49, 0, 0x53, 50, 0, 0x54, - 51, 0, 0x55, 52, 0, 0x58, - 55, 0, 0x59, 56, 0, 0x5a, - 57, 0, 0x5b, 58, 0, 0x64, - 448 % 256, 448 / 256, 0x65, 512 % 256, 512 / 256, 0x67, - 640 % 256, 640 / 256, 0x68, 576 % 256, 576 / 256, 16, - 0x98, 1472 % 256, 1472 / 256, 0x99, 1536 % 256, 1536 / 256, - 0x9a, 1600 % 256, 1600 / 256, 0x9b, 1728 % 256, 1728 / 256, - 0xcc, 704 % 256, 704 / 256, 0xcd, 768 % 256, 768 / 256, - 0xd2, 832 % 256, 832 / 256, 0xd3, 896 % 256, 896 / 256, - 0xd4, 960 % 256, 960 / 256, 0xd5, 1024 % 256, 1024 / 256, - 0xd6, 1088 % 256, 1088 / 256, 0xd7, 1152 % 256, 1152 / 256, - 0xd8, 1216 % 256, 1216 / 256, 0xd9, 1280 % 256, 1280 / 256, - 0xda, 1344 % 256, 1344 / 256, 0xdb, 1408 % 256, 1408 / 256, - 0, 3, 0x08, 1792 % 256, 1792 / 256, 0x0c, - 1856 % 256, 1856 / 256, 0x0d, 1920 % 256, 1920 / 256, 10, - 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, - 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, - 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, - 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, - 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, - 0xff, -}; - -int FaxGetRun(const uint8_t* ins_array, - const uint8_t* src_buf, - int& bitpos, - int bitsize) { - FX_DWORD code = 0; - int ins_off = 0; - while (1) { - uint8_t ins = ins_array[ins_off++]; - if (ins == 0xff) { - return -1; - } - if (bitpos >= bitsize) { - return -1; - } - code <<= 1; - if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) { - code++; - } - bitpos++; - int next_off = ins_off + ins * 3; - for (; ins_off < next_off; ins_off += 3) { - if (ins_array[ins_off] == code) { - return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; - } - } - } -} - -FX_BOOL FaxG4GetRow(const uint8_t* src_buf, - int bitsize, - int& bitpos, - uint8_t* dest_buf, - const uint8_t* ref_buf, - int columns) { - int a0 = -1; - bool a0color = true; - while (1) { - if (bitpos >= bitsize) { - return FALSE; - } - int a1, a2, b1, b2; - FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2); - FX_BOOL bit = NEXTBIT; - int v_delta = 0; - if (bit) { - } else { - if (bitpos >= bitsize) { - return FALSE; - } - FX_BOOL bit1 = NEXTBIT; - if (bitpos >= bitsize) { - return FALSE; - } - FX_BOOL bit2 = NEXTBIT; - if (bit1 && bit2) { - v_delta = 1; - } else if (bit1) { - v_delta = -1; - } else if (bit2) { - int run_len1 = 0; - while (1) { - int run = FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, - src_buf, bitpos, bitsize); - run_len1 += run; - if (run < 64) { - break; - } - } - if (a0 < 0) { - run_len1++; - } - a1 = a0 + run_len1; - if (!a0color) { - FaxFillBits(dest_buf, columns, a0, a1); - } - int run_len2 = 0; - while (1) { - int run = FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, - src_buf, bitpos, bitsize); - run_len2 += run; - if (run < 64) { - break; - } - } - a2 = a1 + run_len2; - if (a0color) { - FaxFillBits(dest_buf, columns, a1, a2); - } - a0 = a2; - if (a0 < columns) { - continue; - } - return TRUE; - } else { - if (bitpos >= bitsize) { - return FALSE; - } - bit = NEXTBIT; - if (bit) { - if (!a0color) { - FaxFillBits(dest_buf, columns, a0, b2); - } - if (b2 >= columns) { - return TRUE; - } - a0 = b2; - continue; - } else { - if (bitpos >= bitsize) { - return FALSE; - } - FX_BOOL bit1 = NEXTBIT; - if (bitpos >= bitsize) { - return FALSE; - } - FX_BOOL bit2 = NEXTBIT; - if (bit1 && bit2) { - v_delta = 2; - } else if (bit1) { - v_delta = -2; - } else if (bit2) { - if (bitpos >= bitsize) { - return FALSE; - } - bit = NEXTBIT; - if (bit) { - v_delta = 3; - } else { - v_delta = -3; - } - } else { - if (bitpos >= bitsize) { - return FALSE; - } - bit = NEXTBIT; - if (bit) { - bitpos += 3; - continue; - } else { - bitpos += 5; - return TRUE; - } - } - } - } - } - a1 = b1 + v_delta; - if (!a0color) { - FaxFillBits(dest_buf, columns, a0, a1); - } - if (a1 >= columns) { - return TRUE; - } - a0 = a1; - a0color = !a0color; - } -} - -FX_BOOL FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) { - int startbit = bitpos; - while (bitpos < bitsize) { - int bit = NEXTBIT; - if (bit) { - if (bitpos - startbit <= 11) { - bitpos = startbit; - } - return TRUE; - } - } - return FALSE; -} - -FX_BOOL FaxGet1DLine(const uint8_t* src_buf, - int bitsize, - int& bitpos, - uint8_t* dest_buf, - int columns) { - bool color = true; - int startpos = 0; - while (1) { - if (bitpos >= bitsize) { - return FALSE; - } - int run_len = 0; - while (1) { - int run = FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, - bitpos, bitsize); - if (run < 0) { - while (bitpos < bitsize) { - int bit = NEXTBIT; - if (bit) { - return TRUE; - } - } - return FALSE; - } - run_len += run; - if (run < 64) { - break; - } - } - if (!color) { - FaxFillBits(dest_buf, columns, startpos, startpos + run_len); - } - startpos += run_len; - if (startpos >= columns) { - break; - } - color = !color; - } - return TRUE; -} - -const uint8_t BlackRunTerminator[128] = { - 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, - 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, - 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, - 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, - 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12, - 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12, - 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12, - 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12, - 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, - 0x67, 12, -}; - -const uint8_t BlackRunMarkup[80] = { - 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, - 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, - 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, - 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, - 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, - 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, -}; - -const uint8_t WhiteRunTerminator[128] = { - 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4, - 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6, - 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7, - 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8, - 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8, - 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8, - 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8, - 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8, -}; - -const uint8_t WhiteRunMarkup[80] = { - 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8, - 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9, - 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9, - 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11, - 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, - 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, -}; - -void AddBitStream(uint8_t* dest_buf, int& dest_bitpos, int data, int bitlen) { - for (int i = bitlen - 1; i >= 0; i--) { - if (data & (1 << i)) { - dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); - } - dest_bitpos++; - } -} - -void FaxEncodeRun(uint8_t* dest_buf, int& dest_bitpos, int run, bool bWhite) { - while (run >= 2560) { - AddBitStream(dest_buf, dest_bitpos, 0x1f, 12); - run -= 2560; - } - if (run >= 64) { - int markup = run - run % 64; - const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup; - p += (markup / 64 - 1) * 2; - AddBitStream(dest_buf, dest_bitpos, *p, p[1]); - } - run %= 64; - const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator; - p += run * 2; - AddBitStream(dest_buf, dest_bitpos, *p, p[1]); -} - -void FaxEncode2DLine(uint8_t* dest_buf, - int& dest_bitpos, - const uint8_t* src_buf, - const uint8_t* ref_buf, - int cols) { - int a0 = -1; - bool a0color = true; - while (1) { - int a1 = FindBit(src_buf, cols, a0 + 1, !a0color); - int b1, b2; - FaxG4FindB1B2(ref_buf, cols, a0, a0color, b1, b2); - if (b2 < a1) { - dest_bitpos += 3; - dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); - dest_bitpos++; - a0 = b2; - } else if (a1 - b1 <= 3 && b1 - a1 <= 3) { - int delta = a1 - b1; - switch (delta) { - case 0: - dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); - break; - case 1: - case 2: - case 3: - dest_bitpos += delta == 1 ? 1 : delta + 2; - dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); - dest_bitpos++; - dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); - break; - case -1: - case -2: - case -3: - dest_bitpos += delta == -1 ? 1 : -delta + 2; - dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); - dest_bitpos++; - break; - } - dest_bitpos++; - a0 = a1; - a0color = !a0color; - } else { - int a2 = FindBit(src_buf, cols, a1 + 1, a0color); - dest_bitpos++; - dest_bitpos++; - dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); - dest_bitpos++; - if (a0 < 0) { - a0 = 0; - } - FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color); - FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color); - a0 = a2; - } - if (a0 >= cols) { - return; - } - } -} - -} // namespace - -class CCodec_FaxDecoder : public CCodec_ScanlineDecoder { - public: - CCodec_FaxDecoder(); - ~CCodec_FaxDecoder() override; - - FX_BOOL Create(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int K, - FX_BOOL EndOfLine, - FX_BOOL EncodedByteAlign, - FX_BOOL BlackIs1, - int Columns, - int Rows); - - // 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; - - int m_Encoding, m_bEndOfLine, m_bByteAlign, m_bBlack; - int bitpos; - const uint8_t* m_pSrcBuf; - FX_DWORD m_SrcSize; - uint8_t* m_pScanlineBuf; - uint8_t* m_pRefBuf; -}; - -CCodec_FaxDecoder::CCodec_FaxDecoder() { - m_pScanlineBuf = NULL; - m_pRefBuf = NULL; -} -CCodec_FaxDecoder::~CCodec_FaxDecoder() { - FX_Free(m_pScanlineBuf); - FX_Free(m_pRefBuf); -} -FX_BOOL CCodec_FaxDecoder::Create(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int K, - FX_BOOL EndOfLine, - FX_BOOL EncodedByteAlign, - FX_BOOL BlackIs1, - int Columns, - int Rows) { - m_Encoding = K; - m_bEndOfLine = EndOfLine; - m_bByteAlign = EncodedByteAlign; - m_bBlack = BlackIs1; - m_OrigWidth = Columns; - m_OrigHeight = Rows; - if (m_OrigWidth == 0) { - m_OrigWidth = width; - } - if (m_OrigHeight == 0) { - m_OrigHeight = height; - } - // Should not overflow. Checked by FPDFAPI_CreateFaxDecoder. - m_Pitch = (static_cast(m_OrigWidth) + 31) / 32 * 4; - m_OutputWidth = m_OrigWidth; - m_OutputHeight = m_OrigHeight; - m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); - m_pRefBuf = FX_Alloc(uint8_t, m_Pitch); - m_pSrcBuf = src_buf; - m_SrcSize = src_size; - m_nComps = 1; - m_bpc = 1; - m_bColorTransformed = FALSE; - return TRUE; -} -FX_BOOL CCodec_FaxDecoder::v_Rewind() { - FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); - bitpos = 0; - return TRUE; -} -uint8_t* CCodec_FaxDecoder::v_GetNextLine() { - int bitsize = m_SrcSize * 8; - FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); - if (bitpos >= bitsize) { - return NULL; - } - FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); - if (m_Encoding < 0) { - FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, - m_OrigWidth); - FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); - } else if (m_Encoding == 0) { - FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); - } else { - FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8)); - bitpos++; - if (bNext1D) { - FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); - } else { - FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, - m_OrigWidth); - } - FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); - } - if (m_bEndOfLine) { - FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); - } - if (m_bByteAlign && bitpos < bitsize) { - int bitpos0 = bitpos; - int bitpos1 = (bitpos + 7) / 8 * 8; - while (m_bByteAlign && bitpos0 < bitpos1) { - int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); - if (bit != 0) { - m_bByteAlign = FALSE; - } else { - bitpos0++; - } - } - if (m_bByteAlign) { - bitpos = bitpos1; - } - } - if (m_bBlack) { - for (FX_DWORD i = 0; i < m_Pitch; i++) { - m_pScanlineBuf[i] = ~m_pScanlineBuf[i]; - } - } - return m_pScanlineBuf; -} -FX_DWORD CCodec_FaxDecoder::GetSrcOffset() { - FX_DWORD ret = (bitpos + 7) / 8; - if (ret > m_SrcSize) { - ret = m_SrcSize; - } - return ret; -} - -void FaxG4Decode(const uint8_t* src_buf, - FX_DWORD src_size, - int* pbitpos, - uint8_t* dest_buf, - int width, - int height, - int pitch) { - if (pitch == 0) { - pitch = (width + 7) / 8; - } - uint8_t* ref_buf = FX_Alloc(uint8_t, pitch); - FXSYS_memset(ref_buf, 0xff, pitch); - int bitpos = *pbitpos; - for (int iRow = 0; iRow < height; iRow++) { - uint8_t* line_buf = dest_buf + iRow * pitch; - FXSYS_memset(line_buf, 0xff, pitch); - FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width); - FXSYS_memcpy(ref_buf, line_buf, pitch); - } - FX_Free(ref_buf); - *pbitpos = bitpos; -} - -class CCodec_FaxEncoder { - public: - CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch); - ~CCodec_FaxEncoder(); - void Encode(uint8_t*& dest_buf, FX_DWORD& dest_size); - void Encode2DLine(const uint8_t* scan_line); - CFX_BinaryBuf m_DestBuf; - uint8_t* m_pRefLine; - uint8_t* m_pLineBuf; - int m_Cols, m_Rows, m_Pitch; - const uint8_t* m_pSrcBuf; -}; -CCodec_FaxEncoder::CCodec_FaxEncoder(const uint8_t* src_buf, - int width, - int height, - int pitch) { - m_pSrcBuf = src_buf; - m_Cols = width; - m_Rows = height; - m_Pitch = pitch; - m_pRefLine = FX_Alloc(uint8_t, m_Pitch); - FXSYS_memset(m_pRefLine, 0xff, m_Pitch); - m_pLineBuf = FX_Alloc2D(uint8_t, m_Pitch, 8); - m_DestBuf.EstimateSize(0, 10240); -} -CCodec_FaxEncoder::~CCodec_FaxEncoder() { - FX_Free(m_pRefLine); - FX_Free(m_pLineBuf); -} -void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size) { - int dest_bitpos = 0; - uint8_t last_byte = 0; - for (int i = 0; i < m_Rows; i++) { - const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch; - FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8); - m_pLineBuf[0] = last_byte; - FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols); - m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8); - last_byte = m_pLineBuf[dest_bitpos / 8]; - dest_bitpos %= 8; - FXSYS_memcpy(m_pRefLine, scan_line, m_Pitch); - } - if (dest_bitpos) { - m_DestBuf.AppendByte(last_byte); - } - dest_size = m_DestBuf.GetSize(); - dest_buf = m_DestBuf.DetachBuffer(); -} -FX_BOOL CCodec_FaxModule::Encode(const uint8_t* src_buf, - int width, - int height, - int pitch, - uint8_t*& dest_buf, - FX_DWORD& dest_size) { - CCodec_FaxEncoder encoder(src_buf, width, height, pitch); - encoder.Encode(dest_buf, dest_size); - return TRUE; -} -ICodec_ScanlineDecoder* CCodec_FaxModule::CreateDecoder( - const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int K, - FX_BOOL EndOfLine, - FX_BOOL EncodedByteAlign, - FX_BOOL BlackIs1, - int Columns, - int Rows) { - CCodec_FaxDecoder* pDecoder = new CCodec_FaxDecoder; - pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine, - EncodedByteAlign, BlackIs1, Columns, Rows); - return pDecoder; -} diff --git a/core/src/fxcodec/codec/fx_codec_flate.cpp b/core/src/fxcodec/codec/fx_codec_flate.cpp deleted file mode 100644 index faffebda28..0000000000 --- a/core/src/fxcodec/codec/fx_codec_flate.cpp +++ /dev/null @@ -1,1007 +0,0 @@ -// 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 "core/src/fxcodec/codec/codec_int.h" - -#include -#include - -#include "core/include/fxcodec/fx_codec.h" -#include "core/include/fxcodec/fx_codec_flate.h" -#include "third_party/zlib_v128/zlib.h" - -extern "C" { -static void* my_alloc_func(void* opaque, - unsigned int items, - unsigned int size) { - return FX_Alloc2D(uint8_t, items, size); -} -static void my_free_func(void* opaque, void* address) { - FX_Free(address); -} -static int FPDFAPI_FlateGetTotalOut(void* context) { - return ((z_stream*)context)->total_out; -} -static int FPDFAPI_FlateGetTotalIn(void* context) { - return ((z_stream*)context)->total_in; -} -static void FPDFAPI_FlateCompress(unsigned char* dest_buf, - unsigned long* dest_size, - const unsigned char* src_buf, - unsigned long src_size) { - compress(dest_buf, dest_size, src_buf, src_size); -} -void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int), - void (*free_func)(void*, void*)) { - z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream)); - if (!p) { - return NULL; - } - FXSYS_memset(p, 0, sizeof(z_stream)); - p->zalloc = alloc_func; - p->zfree = free_func; - inflateInit(p); - return p; -} -void FPDFAPI_FlateInput(void* context, - const unsigned char* src_buf, - unsigned int src_size) { - ((z_stream*)context)->next_in = (unsigned char*)src_buf; - ((z_stream*)context)->avail_in = src_size; -} -int FPDFAPI_FlateOutput(void* context, - unsigned char* dest_buf, - unsigned int dest_size) { - ((z_stream*)context)->next_out = dest_buf; - ((z_stream*)context)->avail_out = dest_size; - unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); - int ret = inflate((z_stream*)context, Z_SYNC_FLUSH); - unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context); - unsigned int written = post_pos - pre_pos; - if (written < dest_size) { - FXSYS_memset(dest_buf + written, '\0', dest_size - written); - } - return ret; -} -int FPDFAPI_FlateGetAvailIn(void* context) { - return ((z_stream*)context)->avail_in; -} -int FPDFAPI_FlateGetAvailOut(void* context) { - return ((z_stream*)context)->avail_out; -} -void FPDFAPI_FlateEnd(void* context) { - inflateEnd((z_stream*)context); - ((z_stream*)context)->zfree(0, context); -} -} // extern "C" - -namespace { - -class CLZWDecoder { - public: - int Decode(uint8_t* output, - FX_DWORD& outlen, - const uint8_t* input, - FX_DWORD& size, - FX_BOOL bEarlyChange); - - private: - void AddCode(FX_DWORD prefix_code, uint8_t append_char); - void DecodeString(FX_DWORD code); - - FX_DWORD m_InPos; - FX_DWORD m_OutPos; - uint8_t* m_pOutput; - const uint8_t* m_pInput; - FX_BOOL m_Early; - FX_DWORD m_CodeArray[5021]; - FX_DWORD m_nCodes; - uint8_t m_DecodeStack[4000]; - FX_DWORD m_StackLen; - int m_CodeLen; -}; -void CLZWDecoder::AddCode(FX_DWORD prefix_code, uint8_t append_char) { - if (m_nCodes + m_Early == 4094) { - return; - } - m_CodeArray[m_nCodes++] = (prefix_code << 16) | append_char; - if (m_nCodes + m_Early == 512 - 258) { - m_CodeLen = 10; - } else if (m_nCodes + m_Early == 1024 - 258) { - m_CodeLen = 11; - } else if (m_nCodes + m_Early == 2048 - 258) { - m_CodeLen = 12; - } -} -void CLZWDecoder::DecodeString(FX_DWORD code) { - while (1) { - int index = code - 258; - if (index < 0 || index >= (int)m_nCodes) { - break; - } - FX_DWORD data = m_CodeArray[index]; - if (m_StackLen >= sizeof(m_DecodeStack)) { - return; - } - m_DecodeStack[m_StackLen++] = (uint8_t)data; - code = data >> 16; - } - if (m_StackLen >= sizeof(m_DecodeStack)) { - return; - } - m_DecodeStack[m_StackLen++] = (uint8_t)code; -} -int CLZWDecoder::Decode(uint8_t* dest_buf, - FX_DWORD& dest_size, - const uint8_t* src_buf, - FX_DWORD& src_size, - FX_BOOL bEarlyChange) { - m_CodeLen = 9; - m_InPos = 0; - m_OutPos = 0; - m_pInput = src_buf; - m_pOutput = dest_buf; - m_Early = bEarlyChange ? 1 : 0; - m_nCodes = 0; - FX_DWORD old_code = (FX_DWORD)-1; - uint8_t last_char; - while (1) { - if (m_InPos + m_CodeLen > src_size * 8) { - break; - } - int byte_pos = m_InPos / 8; - int bit_pos = m_InPos % 8, bit_left = m_CodeLen; - FX_DWORD code = 0; - if (bit_pos) { - bit_left -= 8 - bit_pos; - code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; - } - if (bit_left < 8) { - code |= m_pInput[byte_pos] >> (8 - bit_left); - } else { - bit_left -= 8; - code |= m_pInput[byte_pos++] << bit_left; - if (bit_left) { - code |= m_pInput[byte_pos] >> (8 - bit_left); - } - } - m_InPos += m_CodeLen; - if (code < 256) { - if (m_OutPos == dest_size) { - return -5; - } - if (m_pOutput) { - m_pOutput[m_OutPos] = (uint8_t)code; - } - m_OutPos++; - last_char = (uint8_t)code; - if (old_code != (FX_DWORD)-1) { - AddCode(old_code, last_char); - } - old_code = code; - } else if (code == 256) { - m_CodeLen = 9; - m_nCodes = 0; - old_code = (FX_DWORD)-1; - } else if (code == 257) { - break; - } else { - if (old_code == (FX_DWORD)-1) { - return 2; - } - m_StackLen = 0; - if (code >= m_nCodes + 258) { - if (m_StackLen < sizeof(m_DecodeStack)) { - m_DecodeStack[m_StackLen++] = last_char; - } - DecodeString(old_code); - } else { - DecodeString(code); - } - if (m_OutPos + m_StackLen > dest_size) { - return -5; - } - if (m_pOutput) { - for (FX_DWORD i = 0; i < m_StackLen; i++) { - m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1]; - } - } - m_OutPos += m_StackLen; - last_char = m_DecodeStack[m_StackLen - 1]; - if (old_code < 256) { - AddCode(old_code, last_char); - } else if (old_code - 258 >= m_nCodes) { - dest_size = m_OutPos; - src_size = (m_InPos + 7) / 8; - return 0; - } else { - AddCode(old_code, last_char); - } - old_code = code; - } - } - dest_size = m_OutPos; - src_size = (m_InPos + 7) / 8; - return 0; -} - -uint8_t PaethPredictor(int a, int b, int c) { - int p = a + b - c; - int pa = FXSYS_abs(p - a); - int pb = FXSYS_abs(p - b); - int pc = FXSYS_abs(p - c); - if (pa <= pb && pa <= pc) { - return (uint8_t)a; - } - if (pb <= pc) { - return (uint8_t)b; - } - return (uint8_t)c; -} - -FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf, - FX_DWORD& data_size, - int predictor, - int Colors, - int BitsPerComponent, - int Columns) { - const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; - const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; - if (row_size <= 0) - return FALSE; - const int row_count = (data_size + row_size - 1) / row_size; - const int last_row_size = data_size % row_size; - uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count); - int byte_cnt = 0; - uint8_t* pSrcData = data_buf; - uint8_t* pDestData = dest_buf; - for (int row = 0; row < row_count; row++) { - if (predictor == 10) { - pDestData[0] = 0; - int move_size = row_size; - if (move_size * (row + 1) > (int)data_size) { - move_size = data_size - (move_size * row); - } - FXSYS_memmove(pDestData + 1, pSrcData, move_size); - pDestData += (move_size + 1); - pSrcData += move_size; - byte_cnt += move_size; - continue; - } - for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { - switch (predictor) { - case 11: { - pDestData[0] = 1; - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pSrcData[byte - BytesPerPixel]; - } - pDestData[byte + 1] = pSrcData[byte] - left; - } break; - case 12: { - pDestData[0] = 2; - uint8_t up = 0; - if (row) { - up = pSrcData[byte - row_size]; - } - pDestData[byte + 1] = pSrcData[byte] - up; - } break; - case 13: { - pDestData[0] = 3; - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pSrcData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (row) { - up = pSrcData[byte - row_size]; - } - pDestData[byte + 1] = pSrcData[byte] - (left + up) / 2; - } break; - case 14: { - pDestData[0] = 4; - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pSrcData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (row) { - up = pSrcData[byte - row_size]; - } - uint8_t upper_left = 0; - if (byte >= BytesPerPixel && row) { - upper_left = pSrcData[byte - row_size - BytesPerPixel]; - } - pDestData[byte + 1] = - pSrcData[byte] - PaethPredictor(left, up, upper_left); - } break; - default: { pDestData[byte + 1] = pSrcData[byte]; } break; - } - byte_cnt++; - } - pDestData += (row_size + 1); - pSrcData += row_size; - } - FX_Free(data_buf); - data_buf = dest_buf; - data_size = (row_size + 1) * row_count - - (last_row_size > 0 ? (row_size - last_row_size) : 0); - return TRUE; -} - -void PNG_PredictLine(uint8_t* pDestData, - const uint8_t* pSrcData, - const uint8_t* pLastLine, - int bpc, - int nColors, - int nPixels) { - int row_size = (nPixels * bpc * nColors + 7) / 8; - int BytesPerPixel = (bpc * nColors + 7) / 8; - uint8_t tag = pSrcData[0]; - if (tag == 0) { - FXSYS_memmove(pDestData, pSrcData + 1, row_size); - return; - } - for (int byte = 0; byte < row_size; byte++) { - uint8_t raw_byte = pSrcData[byte + 1]; - switch (tag) { - case 1: { - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pDestData[byte - BytesPerPixel]; - } - pDestData[byte] = raw_byte + left; - break; - } - case 2: { - uint8_t up = 0; - if (pLastLine) { - up = pLastLine[byte]; - } - pDestData[byte] = raw_byte + up; - break; - } - case 3: { - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pDestData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (pLastLine) { - up = pLastLine[byte]; - } - pDestData[byte] = raw_byte + (up + left) / 2; - break; - } - case 4: { - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pDestData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (pLastLine) { - up = pLastLine[byte]; - } - uint8_t upper_left = 0; - if (byte >= BytesPerPixel && pLastLine) { - upper_left = pLastLine[byte - BytesPerPixel]; - } - pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); - break; - } - default: - pDestData[byte] = raw_byte; - break; - } - } -} - -FX_BOOL PNG_Predictor(uint8_t*& data_buf, - FX_DWORD& data_size, - int Colors, - int BitsPerComponent, - int Columns) { - const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8; - const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; - if (row_size <= 0) - return FALSE; - const int row_count = (data_size + row_size) / (row_size + 1); - if (row_count <= 0) - return FALSE; - const int last_row_size = data_size % (row_size + 1); - uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count); - int byte_cnt = 0; - uint8_t* pSrcData = data_buf; - uint8_t* pDestData = dest_buf; - for (int row = 0; row < row_count; row++) { - uint8_t tag = pSrcData[0]; - byte_cnt++; - if (tag == 0) { - int move_size = row_size; - if ((row + 1) * (move_size + 1) > (int)data_size) { - move_size = last_row_size - 1; - } - FXSYS_memmove(pDestData, pSrcData + 1, move_size); - pSrcData += move_size + 1; - pDestData += move_size; - byte_cnt += move_size; - continue; - } - for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) { - uint8_t raw_byte = pSrcData[byte + 1]; - switch (tag) { - case 1: { - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pDestData[byte - BytesPerPixel]; - } - pDestData[byte] = raw_byte + left; - break; - } - case 2: { - uint8_t up = 0; - if (row) { - up = pDestData[byte - row_size]; - } - pDestData[byte] = raw_byte + up; - break; - } - case 3: { - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pDestData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (row) { - up = pDestData[byte - row_size]; - } - pDestData[byte] = raw_byte + (up + left) / 2; - break; - } - case 4: { - uint8_t left = 0; - if (byte >= BytesPerPixel) { - left = pDestData[byte - BytesPerPixel]; - } - uint8_t up = 0; - if (row) { - up = pDestData[byte - row_size]; - } - uint8_t upper_left = 0; - if (byte >= BytesPerPixel && row) { - upper_left = pDestData[byte - row_size - BytesPerPixel]; - } - pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left); - break; - } - default: - pDestData[byte] = raw_byte; - break; - } - byte_cnt++; - } - pSrcData += row_size + 1; - pDestData += row_size; - } - FX_Free(data_buf); - data_buf = dest_buf; - data_size = row_size * row_count - - (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0); - return TRUE; -} - -void TIFF_PredictorEncodeLine(uint8_t* dest_buf, - int row_size, - int BitsPerComponent, - int Colors, - int Columns) { - int BytesPerPixel = BitsPerComponent * Colors / 8; - if (BitsPerComponent < 8) { - uint8_t mask = 0x01; - if (BitsPerComponent == 2) { - mask = 0x03; - } else if (BitsPerComponent == 4) { - mask = 0x0F; - } - int row_bits = Colors * BitsPerComponent * Columns; - for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; - i -= BitsPerComponent) { - int col = i % 8; - int index = i / 8; - int col_pre = - (col == 0) ? (8 - BitsPerComponent) : (col - BitsPerComponent); - int index_pre = (col == 0) ? (index - 1) : index; - uint8_t cur = (dest_buf[index] >> (8 - col - BitsPerComponent)) & mask; - uint8_t left = - (dest_buf[index_pre] >> (8 - col_pre - BitsPerComponent)) & mask; - cur -= left; - cur &= mask; - cur <<= (8 - col - BitsPerComponent); - dest_buf[index] &= ~(mask << ((8 - col - BitsPerComponent))); - dest_buf[index] |= cur; - } - } else if (BitsPerComponent == 8) { - for (int i = row_size - 1; i >= BytesPerPixel; i--) { - dest_buf[i] -= dest_buf[i - BytesPerPixel]; - } - } else { - for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; - i -= BytesPerPixel) { - FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1]; - pixel -= - (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; - dest_buf[i] = pixel >> 8; - dest_buf[i + 1] = (uint8_t)pixel; - } - } -} - -FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf, - FX_DWORD& data_size, - int Colors, - int BitsPerComponent, - int Columns) { - int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; - if (row_size == 0) - return FALSE; - const int row_count = (data_size + row_size - 1) / row_size; - const int last_row_size = data_size % row_size; - for (int row = 0; row < row_count; row++) { - uint8_t* scan_line = data_buf + row * row_size; - if ((row + 1) * row_size > (int)data_size) { - row_size = last_row_size; - } - TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, - Columns); - } - return TRUE; -} - -void TIFF_PredictLine(uint8_t* dest_buf, - FX_DWORD row_size, - int BitsPerComponent, - int Colors, - int Columns) { - if (BitsPerComponent == 1) { - int row_bits = std::min(BitsPerComponent * Colors * Columns, - pdfium::base::checked_cast(row_size * 8)); - int index_pre = 0; - int col_pre = 0; - for (int i = 1; i < row_bits; i++) { - int col = i % 8; - int index = i / 8; - if (((dest_buf[index] >> (7 - col)) & 1) ^ - ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) { - dest_buf[index] |= 1 << (7 - col); - } else { - dest_buf[index] &= ~(1 << (7 - col)); - } - index_pre = index; - col_pre = col; - } - return; - } - int BytesPerPixel = BitsPerComponent * Colors / 8; - if (BitsPerComponent == 16) { - for (FX_DWORD i = BytesPerPixel; i < row_size; i += 2) { - FX_WORD pixel = - (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1]; - pixel += (dest_buf[i] << 8) | dest_buf[i + 1]; - dest_buf[i] = pixel >> 8; - dest_buf[i + 1] = (uint8_t)pixel; - } - } else { - for (FX_DWORD i = BytesPerPixel; i < row_size; i++) { - dest_buf[i] += dest_buf[i - BytesPerPixel]; - } - } -} - -FX_BOOL TIFF_Predictor(uint8_t*& data_buf, - FX_DWORD& data_size, - int Colors, - int BitsPerComponent, - int Columns) { - int row_size = (Colors * BitsPerComponent * Columns + 7) / 8; - if (row_size == 0) - return FALSE; - const int row_count = (data_size + row_size - 1) / row_size; - const int last_row_size = data_size % row_size; - for (int row = 0; row < row_count; row++) { - uint8_t* scan_line = data_buf + row * row_size; - if ((row + 1) * row_size > (int)data_size) { - row_size = last_row_size; - } - TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns); - } - return TRUE; -} - -void FlateUncompress(const uint8_t* src_buf, - FX_DWORD src_size, - FX_DWORD orig_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size, - FX_DWORD& offset) { - FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; - const FX_DWORD kStepSize = 10240; - FX_DWORD alloc_step = orig_size ? kStepSize : std::min(src_size, kStepSize); - static const FX_DWORD kMaxInitialAllocSize = 10000000; - if (guess_size > kMaxInitialAllocSize) { - guess_size = kMaxInitialAllocSize; - alloc_step = kMaxInitialAllocSize; - } - FX_DWORD buf_size = guess_size; - FX_DWORD last_buf_size = buf_size; - - dest_buf = nullptr; - dest_size = 0; - void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); - if (!context) - return; - - std::unique_ptr guess_buf( - FX_Alloc(uint8_t, guess_size + 1)); - guess_buf.get()[guess_size] = '\0'; - - FPDFAPI_FlateInput(context, src_buf, src_size); - - if (src_size < kStepSize) { - // This is the old implementation. - uint8_t* cur_buf = guess_buf.get(); - while (1) { - int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); - if (ret != Z_OK) - break; - int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); - if (avail_buf_size != 0) - break; - - FX_DWORD old_size = guess_size; - guess_size += alloc_step; - if (guess_size < old_size || guess_size + 1 < guess_size) { - FPDFAPI_FlateEnd(context); - return; - } - - { - uint8_t* new_buf = - FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1); - guess_buf.reset(new_buf); - } - guess_buf.get()[guess_size] = '\0'; - cur_buf = guess_buf.get() + old_size; - buf_size = guess_size - old_size; - } - dest_size = FPDFAPI_FlateGetTotalOut(context); - offset = FPDFAPI_FlateGetTotalIn(context); - if (guess_size / 2 > dest_size) { - { - uint8_t* new_buf = - FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1); - guess_buf.reset(new_buf); - } - guess_size = dest_size; - guess_buf.get()[guess_size] = '\0'; - } - dest_buf = guess_buf.release(); - } else { - CFX_ArrayTemplate result_tmp_bufs; - uint8_t* cur_buf = guess_buf.release(); - while (1) { - int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); - int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context); - if (ret != Z_OK) { - last_buf_size = buf_size - avail_buf_size; - result_tmp_bufs.Add(cur_buf); - break; - } - if (avail_buf_size != 0) { - last_buf_size = buf_size - avail_buf_size; - result_tmp_bufs.Add(cur_buf); - break; - } - - result_tmp_bufs.Add(cur_buf); - cur_buf = FX_Alloc(uint8_t, buf_size + 1); - cur_buf[buf_size] = '\0'; - } - dest_size = FPDFAPI_FlateGetTotalOut(context); - offset = FPDFAPI_FlateGetTotalIn(context); - if (result_tmp_bufs.GetSize() == 1) { - dest_buf = result_tmp_bufs[0]; - } else { - uint8_t* result_buf = FX_Alloc(uint8_t, dest_size); - FX_DWORD result_pos = 0; - for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) { - uint8_t* tmp_buf = result_tmp_bufs[i]; - FX_DWORD tmp_buf_size = buf_size; - if (i == result_tmp_bufs.GetSize() - 1) { - tmp_buf_size = last_buf_size; - } - FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size); - result_pos += tmp_buf_size; - FX_Free(result_tmp_bufs[i]); - } - dest_buf = result_buf; - } - } - FPDFAPI_FlateEnd(context); -} - -} // namespace - -class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder { - public: - CCodec_FlateScanlineDecoder(); - ~CCodec_FlateScanlineDecoder() override; - - void Create(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc, - int predictor, - int Colors, - int BitsPerComponent, - int Columns); - 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; - - void* m_pFlate; - const uint8_t* m_SrcBuf; - FX_DWORD m_SrcSize; - uint8_t* m_pScanline; - uint8_t* m_pLastLine; - uint8_t* m_pPredictBuffer; - uint8_t* m_pPredictRaw; - int m_Predictor; - int m_Colors; - int m_BitsPerComponent; - int m_Columns; - FX_DWORD m_PredictPitch; - size_t m_LeftOver; -}; - -CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() { - m_pFlate = NULL; - m_pScanline = NULL; - m_pLastLine = NULL; - m_pPredictBuffer = NULL; - m_pPredictRaw = NULL; - m_LeftOver = 0; -} -CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() { - FX_Free(m_pScanline); - FX_Free(m_pLastLine); - FX_Free(m_pPredictBuffer); - FX_Free(m_pPredictRaw); - if (m_pFlate) { - FPDFAPI_FlateEnd(m_pFlate); - } -} -void CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc, - int predictor, - int Colors, - int BitsPerComponent, - int Columns) { - m_SrcBuf = src_buf; - m_SrcSize = src_size; - m_OutputWidth = m_OrigWidth = width; - m_OutputHeight = m_OrigHeight = height; - m_nComps = nComps; - m_bpc = bpc; - m_bColorTransformed = FALSE; - m_Pitch = (static_cast(width) * nComps * bpc + 7) / 8; - m_pScanline = FX_Alloc(uint8_t, m_Pitch); - m_Predictor = 0; - if (predictor) { - if (predictor >= 10) { - m_Predictor = 2; - } else if (predictor == 2) { - m_Predictor = 1; - } - if (m_Predictor) { - if (BitsPerComponent * Colors * Columns == 0) { - BitsPerComponent = m_bpc; - Colors = m_nComps; - Columns = m_OrigWidth; - } - m_Colors = Colors; - m_BitsPerComponent = BitsPerComponent; - m_Columns = Columns; - m_PredictPitch = - (static_cast(m_BitsPerComponent) * m_Colors * m_Columns + - 7) / - 8; - m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch); - m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1); - m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch); - } - } -} -FX_BOOL CCodec_FlateScanlineDecoder::v_Rewind() { - if (m_pFlate) { - FPDFAPI_FlateEnd(m_pFlate); - } - m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func); - if (!m_pFlate) { - return FALSE; - } - FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize); - m_LeftOver = 0; - return TRUE; -} -uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() { - if (m_Predictor) { - if (m_Pitch == m_PredictPitch) { - if (m_Predictor == 2) { - FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); - PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, - m_BitsPerComponent, m_Colors, m_Columns); - FXSYS_memcpy(m_pLastLine, m_pScanline, m_PredictPitch); - } else { - FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); - TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps, - m_OutputWidth); - } - } else { - size_t bytes_to_go = m_Pitch; - size_t read_leftover = - m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver; - if (read_leftover) { - FXSYS_memcpy(m_pScanline, - m_pPredictBuffer + m_PredictPitch - m_LeftOver, - read_leftover); - m_LeftOver -= read_leftover; - bytes_to_go -= read_leftover; - } - while (bytes_to_go) { - if (m_Predictor == 2) { - FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1); - PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine, - m_BitsPerComponent, m_Colors, m_Columns); - FXSYS_memcpy(m_pLastLine, m_pPredictBuffer, m_PredictPitch); - } else { - FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch); - TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent, - m_Colors, m_Columns); - } - size_t read_bytes = - m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch; - FXSYS_memcpy(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, - read_bytes); - m_LeftOver += m_PredictPitch - read_bytes; - bytes_to_go -= read_bytes; - } - } - } else { - FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch); - } - return m_pScanline; -} -FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() { - return FPDFAPI_FlateGetTotalIn(m_pFlate); -} - -ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder( - const uint8_t* src_buf, - FX_DWORD src_size, - int width, - int height, - int nComps, - int bpc, - int predictor, - int Colors, - int BitsPerComponent, - int Columns) { - CCodec_FlateScanlineDecoder* pDecoder = new CCodec_FlateScanlineDecoder; - pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, - Colors, BitsPerComponent, Columns); - return pDecoder; -} -FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, - const uint8_t* src_buf, - FX_DWORD src_size, - FX_BOOL bEarlyChange, - int predictor, - int Colors, - int BitsPerComponent, - int Columns, - FX_DWORD estimated_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size) { - dest_buf = NULL; - FX_DWORD offset = 0; - int predictor_type = 0; - if (predictor) { - if (predictor >= 10) { - predictor_type = 2; - } else if (predictor == 2) { - predictor_type = 1; - } - } - if (bLZW) { - { - std::unique_ptr decoder(new CLZWDecoder); - dest_size = (FX_DWORD)-1; - offset = src_size; - int err = decoder->Decode(NULL, dest_size, src_buf, offset, bEarlyChange); - if (err || dest_size == 0 || dest_size + 1 < dest_size) { - return -1; - } - } - { - std::unique_ptr decoder(new CLZWDecoder); - dest_buf = FX_Alloc(uint8_t, dest_size + 1); - dest_buf[dest_size] = '\0'; - decoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange); - } - } else { - FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size, - offset); - } - if (predictor_type == 0) { - return offset; - } - FX_BOOL ret = TRUE; - if (predictor_type == 2) { - ret = PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); - } else if (predictor_type == 1) { - ret = - TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns); - } - return ret ? offset : -1; -} -FX_BOOL CCodec_FlateModule::Encode(const uint8_t* src_buf, - FX_DWORD src_size, - int predictor, - int Colors, - int BitsPerComponent, - int Columns, - uint8_t*& dest_buf, - FX_DWORD& dest_size) { - if (predictor != 2 && predictor < 10) { - return Encode(src_buf, src_size, dest_buf, dest_size); - } - uint8_t* pSrcBuf = NULL; - pSrcBuf = FX_Alloc(uint8_t, src_size); - FXSYS_memcpy(pSrcBuf, src_buf, src_size); - FX_BOOL ret = TRUE; - if (predictor == 2) { - ret = TIFF_PredictorEncode(pSrcBuf, src_size, Colors, BitsPerComponent, - Columns); - } else if (predictor >= 10) { - ret = PNG_PredictorEncode(pSrcBuf, src_size, predictor, Colors, - BitsPerComponent, Columns); - } - if (ret) - ret = Encode(pSrcBuf, src_size, dest_buf, dest_size); - FX_Free(pSrcBuf); - return ret; -} -FX_BOOL CCodec_FlateModule::Encode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size) { - dest_size = src_size + src_size / 1000 + 12; - dest_buf = FX_Alloc(uint8_t, dest_size); - unsigned long temp_size = dest_size; - FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size); - dest_size = (FX_DWORD)temp_size; - return TRUE; -} diff --git a/core/src/fxcodec/codec/fx_codec_gif.cpp b/core/src/fxcodec/codec/fx_codec_gif.cpp deleted file mode 100644 index 661732fb3f..0000000000 --- a/core/src/fxcodec/codec/fx_codec_gif.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "core/src/fxcodec/codec/codec_int.h" -#include "core/src/fxcodec/lgif/fx_gif.h" -struct FXGIF_Context { - gif_decompress_struct_p gif_ptr; - void* parent_ptr; - void* child_ptr; - - void* (*m_AllocFunc)(unsigned int); - void (*m_FreeFunc)(void*); -}; -extern "C" { -static void* gif_alloc_func(unsigned int size) { - return FX_Alloc(char, size); -} -static void gif_free_func(void* p) { - FX_Free(p); -} -}; -static void gif_error_data(gif_decompress_struct_p gif_ptr, - const FX_CHAR* err_msg) { - FXSYS_strncpy((char*)gif_ptr->err_ptr, err_msg, GIF_MAX_ERROR_SIZE - 1); - longjmp(gif_ptr->jmpbuf, 1); -} -static uint8_t* gif_ask_buf_for_pal(gif_decompress_struct_p gif_ptr, - int32_t pal_size) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - return pModule->AskLocalPaletteBufCallback( - p->child_ptr, gif_get_frame_num(gif_ptr), pal_size); -} -static void gif_record_current_position(gif_decompress_struct_p gif_ptr, - FX_DWORD* cur_pos_ptr) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - pModule->RecordCurrentPositionCallback(p->child_ptr, *cur_pos_ptr); -} -static void gif_read_scanline(gif_decompress_struct_p gif_ptr, - int32_t row_num, - uint8_t* row_buf) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf); -} -static FX_BOOL gif_get_record_position(gif_decompress_struct_p gif_ptr, - FX_DWORD cur_pos, - int32_t left, - int32_t top, - int32_t width, - int32_t height, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - FX_BOOL user_input, - int32_t trans_index, - int32_t disposal_method, - FX_BOOL interlace) { - FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; - CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - return pModule->InputRecordPositionBufCallback( - p->child_ptr, cur_pos, FX_RECT(left, top, left + width, top + height), - pal_num, pal_ptr, delay_time, user_input, trans_index, disposal_method, - interlace); -} -void* CCodec_GifModule::Start(void* pModule) { - FXGIF_Context* p = (FXGIF_Context*)FX_Alloc(uint8_t, sizeof(FXGIF_Context)); - if (p == NULL) { - return NULL; - } - FXSYS_memset(p, 0, sizeof(FXGIF_Context)); - p->m_AllocFunc = gif_alloc_func; - p->m_FreeFunc = gif_free_func; - p->gif_ptr = NULL; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->gif_ptr = gif_create_decompress(); - if (p->gif_ptr == NULL) { - FX_Free(p); - return NULL; - } - p->gif_ptr->context_ptr = (void*)p; - p->gif_ptr->err_ptr = m_szLastError; - p->gif_ptr->gif_error_fn = gif_error_data; - p->gif_ptr->gif_ask_buf_for_pal_fn = gif_ask_buf_for_pal; - p->gif_ptr->gif_record_current_position_fn = gif_record_current_position; - p->gif_ptr->gif_get_row_fn = gif_read_scanline; - p->gif_ptr->gif_get_record_position_fn = gif_get_record_position; - return p; -} -void CCodec_GifModule::Finish(void* pContext) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (p) { - gif_destroy_decompress(&p->gif_ptr); - p->m_FreeFunc(p); - } -} -int32_t CCodec_GifModule::ReadHeader(void* pContext, - int* width, - int* height, - int* pal_num, - void** pal_pp, - int* bg_index, - CFX_DIBAttribute* pAttribute) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (setjmp(p->gif_ptr->jmpbuf)) { - return 0; - } - int32_t ret = gif_read_header(p->gif_ptr); - if (ret != 1) { - return ret; - } - if (pAttribute) { - } - *width = p->gif_ptr->width; - *height = p->gif_ptr->height; - *pal_num = p->gif_ptr->global_pal_num; - *pal_pp = p->gif_ptr->global_pal_ptr; - *bg_index = p->gif_ptr->bc_index; - return 1; -} -int32_t CCodec_GifModule::LoadFrameInfo(void* pContext, int* frame_num) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (setjmp(p->gif_ptr->jmpbuf)) { - return 0; - } - int32_t ret = gif_get_frame(p->gif_ptr); - if (ret != 1) { - return ret; - } - *frame_num = gif_get_frame_num(p->gif_ptr); - return 1; -} -int32_t CCodec_GifModule::LoadFrame(void* pContext, - int frame_num, - CFX_DIBAttribute* pAttribute) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - if (setjmp(p->gif_ptr->jmpbuf)) { - return 0; - } - int32_t ret = gif_load_frame(p->gif_ptr, frame_num); - if (ret == 1) { - if (pAttribute) { - pAttribute->m_nGifLeft = - p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->left; - pAttribute->m_nGifTop = - p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->top; - pAttribute->m_fAspectRatio = p->gif_ptr->pixel_aspect; - if (p->gif_ptr->cmt_data_ptr) { - const uint8_t* buf = - (const uint8_t*)p->gif_ptr->cmt_data_ptr->GetBuffer(0); - FX_DWORD len = p->gif_ptr->cmt_data_ptr->GetLength(); - if (len > 21) { - uint8_t size = *buf++; - if (size) { - pAttribute->m_strAuthor = CFX_ByteString(buf, size); - } else { - pAttribute->m_strAuthor.Empty(); - } - buf += size; - size = *buf++; - if (size == 20) { - FXSYS_memcpy(pAttribute->m_strTime, buf, size); - } - } - } - } - } - return ret; -} -FX_DWORD CCodec_GifModule::GetAvailInput(void* pContext, - uint8_t** avial_buf_ptr) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - return gif_get_avail_input(p->gif_ptr, avial_buf_ptr); -} -void CCodec_GifModule::Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size) { - FXGIF_Context* p = (FXGIF_Context*)pContext; - gif_input_buffer(p->gif_ptr, (uint8_t*)src_buf, src_size); -} diff --git a/core/src/fxcodec/codec/fx_codec_icc.cpp b/core/src/fxcodec/codec/fx_codec_icc.cpp deleted file mode 100644 index ebec0b0a34..0000000000 --- a/core/src/fxcodec/codec/fx_codec_icc.cpp +++ /dev/null @@ -1,1986 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/src/fxcodec/codec/codec_int.h" -#include "third_party/lcms2-2.6/include/lcms2.h" - -const FX_DWORD N_COMPONENT_LAB = 3; -const FX_DWORD N_COMPONENT_GRAY = 1; -const FX_DWORD N_COMPONENT_RGB = 3; -const FX_DWORD N_COMPONENT_CMYK = 4; -const FX_DWORD N_COMPONENT_DEFAULT = 3; - -FX_BOOL MD5ComputeID(const void* buf, FX_DWORD dwSize, uint8_t ID[16]) { - return cmsMD5computeIDExt(buf, dwSize, ID); -} -struct CLcmsCmm { - cmsHTRANSFORM m_hTransform; - int m_nSrcComponents; - int m_nDstComponents; - FX_BOOL m_bLab; -}; -extern "C" { -int ourHandler(int ErrorCode, const char* ErrorText) { - return TRUE; -} -}; -FX_BOOL CheckComponents(cmsColorSpaceSignature cs, - int nComponents, - FX_BOOL bDst) { - if (nComponents <= 0 || nComponents > 15) { - return FALSE; - } - switch (cs) { - case cmsSigLabData: - if (nComponents < 3) { - return FALSE; - } - break; - case cmsSigGrayData: - if (bDst && nComponents != 1) { - return FALSE; - } - if (!bDst && nComponents > 2) { - return FALSE; - } - break; - case cmsSigRgbData: - if (bDst && nComponents != 3) { - return FALSE; - } - break; - case cmsSigCmykData: - if (bDst && nComponents != 4) { - return FALSE; - } - break; - default: - if (nComponents != 3) { - return FALSE; - } - break; - } - return TRUE; -} - -FX_DWORD GetCSComponents(cmsColorSpaceSignature cs) { - FX_DWORD components; - switch (cs) { - case cmsSigLabData: - components = N_COMPONENT_LAB; - break; - case cmsSigGrayData: - components = N_COMPONENT_GRAY; - break; - case cmsSigRgbData: - components = N_COMPONENT_RGB; - break; - case cmsSigCmykData: - components = N_COMPONENT_CMYK; - break; - default: - components = N_COMPONENT_DEFAULT; - break; - } - return components; -} - -void* IccLib_CreateTransform(const unsigned char* pSrcProfileData, - FX_DWORD dwSrcProfileSize, - FX_DWORD& nSrcComponents, - const unsigned char* pDstProfileData, - FX_DWORD dwDstProfileSize, - int32_t nDstComponents, - int intent, - FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT, - FX_DWORD dwDstFormat = Icc_FORMAT_DEFAULT) { - cmsHPROFILE srcProfile = NULL; - cmsHPROFILE dstProfile = NULL; - cmsHTRANSFORM hTransform = NULL; - CLcmsCmm* pCmm = NULL; - nSrcComponents = 0; - srcProfile = cmsOpenProfileFromMem((void*)pSrcProfileData, dwSrcProfileSize); - if (!srcProfile) { - return NULL; - } - if (!pDstProfileData && dwDstProfileSize == 0 && nDstComponents == 3) { - dstProfile = cmsCreate_sRGBProfile(); - } else { - dstProfile = - cmsOpenProfileFromMem((void*)pDstProfileData, dwDstProfileSize); - } - if (!dstProfile) { - cmsCloseProfile(srcProfile); - return NULL; - } - int srcFormat; - FX_BOOL bLab = FALSE; - cmsColorSpaceSignature srcCS = cmsGetColorSpace(srcProfile); - nSrcComponents = GetCSComponents(srcCS); - if (srcCS == cmsSigLabData) { - srcFormat = - COLORSPACE_SH(PT_Lab) | CHANNELS_SH(nSrcComponents) | BYTES_SH(0); - bLab = TRUE; - } else { - srcFormat = - COLORSPACE_SH(PT_ANY) | CHANNELS_SH(nSrcComponents) | BYTES_SH(1); - if (srcCS == cmsSigRgbData && T_DOSWAP(dwSrcFormat)) { - srcFormat |= DOSWAP_SH(1); - } - } - cmsColorSpaceSignature dstCS = cmsGetColorSpace(dstProfile); - if (!CheckComponents(dstCS, nDstComponents, TRUE)) { - cmsCloseProfile(srcProfile); - cmsCloseProfile(dstProfile); - return NULL; - } - switch (dstCS) { - case cmsSigGrayData: - hTransform = cmsCreateTransform(srcProfile, srcFormat, dstProfile, - TYPE_GRAY_8, intent, 0); - break; - case cmsSigRgbData: - hTransform = cmsCreateTransform(srcProfile, srcFormat, dstProfile, - TYPE_BGR_8, intent, 0); - break; - case cmsSigCmykData: - hTransform = cmsCreateTransform( - srcProfile, srcFormat, dstProfile, - T_DOSWAP(dwDstFormat) ? TYPE_KYMC_8 : TYPE_CMYK_8, intent, 0); - break; - default: - break; - } - if (!hTransform) { - cmsCloseProfile(srcProfile); - cmsCloseProfile(dstProfile); - return NULL; - } - pCmm = new CLcmsCmm; - pCmm->m_nSrcComponents = nSrcComponents; - pCmm->m_nDstComponents = nDstComponents; - pCmm->m_hTransform = hTransform; - pCmm->m_bLab = bLab; - cmsCloseProfile(srcProfile); - cmsCloseProfile(dstProfile); - return pCmm; -} -void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData, - FX_DWORD dwProfileSize, - FX_DWORD& nComponents, - int32_t intent, - FX_DWORD dwSrcFormat) { - return IccLib_CreateTransform(pProfileData, dwProfileSize, nComponents, NULL, - 0, 3, intent, dwSrcFormat); -} -void IccLib_DestroyTransform(void* pTransform) { - if (!pTransform) { - return; - } - cmsDeleteTransform(((CLcmsCmm*)pTransform)->m_hTransform); - delete (CLcmsCmm*)pTransform; -} -void IccLib_Translate(void* pTransform, - FX_DWORD nSrcComponents, - FX_FLOAT* pSrcValues, - FX_FLOAT* pDestValues) { - if (!pTransform) { - return; - } - CLcmsCmm* p = (CLcmsCmm*)pTransform; - uint8_t output[4]; - if (p->m_bLab) { - CFX_FixedBufGrow inputs(nSrcComponents); - double* input = inputs; - for (FX_DWORD i = 0; i < nSrcComponents; i++) { - input[i] = pSrcValues[i]; - } - cmsDoTransform(p->m_hTransform, input, output, 1); - } else { - CFX_FixedBufGrow inputs(nSrcComponents); - uint8_t* input = inputs; - for (FX_DWORD i = 0; i < nSrcComponents; i++) { - if (pSrcValues[i] > 1.0f) { - input[i] = 255; - } else if (pSrcValues[i] < 0) { - input[i] = 0; - } else { - input[i] = (int)(pSrcValues[i] * 255.0f); - } - } - cmsDoTransform(p->m_hTransform, input, output, 1); - } - switch (p->m_nDstComponents) { - case 1: - pDestValues[0] = output[0] / 255.0f; - break; - case 3: - pDestValues[0] = output[2] / 255.0f; - pDestValues[1] = output[1] / 255.0f; - pDestValues[2] = output[0] / 255.0f; - break; - case 4: - pDestValues[0] = output[0] / 255.0f; - pDestValues[1] = output[1] / 255.0f; - pDestValues[2] = output[2] / 255.0f; - pDestValues[3] = output[3] / 255.0f; - break; - } -} -void IccLib_TranslateImage(void* pTransform, - unsigned char* pDest, - const unsigned char* pSrc, - int32_t pixels) { - cmsDoTransform(((CLcmsCmm*)pTransform)->m_hTransform, (void*)pSrc, pDest, - pixels); -} -void* CreateProfile_Gray(double gamma) { - cmsCIExyY* D50 = (cmsCIExyY*)cmsD50_xyY(); - if (!cmsWhitePointFromTemp(D50, 6504)) { - return NULL; - } - cmsToneCurve* curve = cmsBuildGamma(NULL, gamma); - if (!curve) { - return NULL; - } - void* profile = cmsCreateGrayProfile(D50, curve); - cmsFreeToneCurve(curve); - return profile; -} -ICodec_IccModule::IccCS GetProfileCSFromHandle(void* pProfile) { - if (!pProfile) { - return ICodec_IccModule::IccCS_Unknown; - } - switch (cmsGetColorSpace(pProfile)) { - case cmsSigXYZData: - return ICodec_IccModule::IccCS_XYZ; - case cmsSigLabData: - return ICodec_IccModule::IccCS_Lab; - case cmsSigLuvData: - return ICodec_IccModule::IccCS_Luv; - case cmsSigYCbCrData: - return ICodec_IccModule::IccCS_YCbCr; - case cmsSigYxyData: - return ICodec_IccModule::IccCS_Yxy; - case cmsSigRgbData: - return ICodec_IccModule::IccCS_Rgb; - case cmsSigGrayData: - return ICodec_IccModule::IccCS_Gray; - case cmsSigHsvData: - return ICodec_IccModule::IccCS_Hsv; - case cmsSigHlsData: - return ICodec_IccModule::IccCS_Hls; - case cmsSigCmykData: - return ICodec_IccModule::IccCS_Cmyk; - case cmsSigCmyData: - return ICodec_IccModule::IccCS_Cmy; - default: - return ICodec_IccModule::IccCS_Unknown; - } -} -ICodec_IccModule::IccCS CCodec_IccModule::GetProfileCS( - const uint8_t* pProfileData, - FX_DWORD dwProfileSize) { - ICodec_IccModule::IccCS cs; - cmsHPROFILE hProfile = - cmsOpenProfileFromMem((void*)pProfileData, dwProfileSize); - if (!hProfile) { - return IccCS_Unknown; - } - cs = GetProfileCSFromHandle(hProfile); - if (hProfile) { - cmsCloseProfile(hProfile); - } - return cs; -} -ICodec_IccModule::IccCS CCodec_IccModule::GetProfileCS(IFX_FileRead* pFile) { - if (!pFile) { - return IccCS_Unknown; - } - ICodec_IccModule::IccCS cs; - FX_DWORD dwSize = (FX_DWORD)pFile->GetSize(); - uint8_t* pBuf = FX_Alloc(uint8_t, dwSize); - pFile->ReadBlock(pBuf, 0, dwSize); - cs = GetProfileCS(pBuf, dwSize); - FX_Free(pBuf); - return cs; -} -FX_DWORD TransferProfileType(void* pProfile, FX_DWORD dwFormat) { - cmsColorSpaceSignature cs = cmsGetColorSpace(pProfile); - switch (cs) { - case cmsSigXYZData: - return TYPE_XYZ_16; - case cmsSigLabData: - return TYPE_Lab_DBL; - case cmsSigLuvData: - return TYPE_YUV_8; - case cmsSigYCbCrData: - return TYPE_YCbCr_8; - case cmsSigYxyData: - return TYPE_Yxy_16; - case cmsSigRgbData: - return T_DOSWAP(dwFormat) ? TYPE_RGB_8 : TYPE_BGR_8; - case cmsSigGrayData: - return TYPE_GRAY_8; - case cmsSigHsvData: - return TYPE_HSV_8; - case cmsSigHlsData: - return TYPE_HLS_8; - case cmsSigCmykData: - return T_DOSWAP(dwFormat) ? TYPE_KYMC_8 : TYPE_CMYK_8; - case cmsSigCmyData: - return TYPE_CMY_8; - case cmsSigMCH5Data: - return T_DOSWAP(dwFormat) ? TYPE_KYMC5_8 : TYPE_CMYK5_8; - case cmsSigMCH6Data: - return TYPE_CMYK6_8; - case cmsSigMCH7Data: - return T_DOSWAP(dwFormat) ? TYPE_KYMC7_8 : TYPE_CMYK7_8; - case cmsSigMCH8Data: - return T_DOSWAP(dwFormat) ? TYPE_KYMC8_8 : TYPE_CMYK8_8; - case cmsSigMCH9Data: - return T_DOSWAP(dwFormat) ? TYPE_KYMC9_8 : TYPE_CMYK9_8; - case cmsSigMCHAData: - return T_DOSWAP(dwFormat) ? TYPE_KYMC10_8 : TYPE_CMYK10_8; - case cmsSigMCHBData: - return T_DOSWAP(dwFormat) ? TYPE_KYMC11_8 : TYPE_CMYK11_8; - case cmsSigMCHCData: - return T_DOSWAP(dwFormat) ? TYPE_KYMC12_8 : TYPE_CMYK12_8; - default: - return 0; - } -} -class CFX_IccProfileCache { - public: - CFX_IccProfileCache(); - ~CFX_IccProfileCache(); - void* m_pProfile; - FX_DWORD m_dwRate; - - protected: - void Purge(); -}; -CFX_IccProfileCache::CFX_IccProfileCache() { - m_pProfile = NULL; - m_dwRate = 1; -} -CFX_IccProfileCache::~CFX_IccProfileCache() { - if (m_pProfile) { - cmsCloseProfile(m_pProfile); - } -} -void CFX_IccProfileCache::Purge() {} -class CFX_IccTransformCache { - public: - CFX_IccTransformCache(CLcmsCmm* pCmm = NULL); - ~CFX_IccTransformCache(); - void* m_pIccTransform; - FX_DWORD m_dwRate; - CLcmsCmm* m_pCmm; - - protected: - void Purge(); -}; -CFX_IccTransformCache::CFX_IccTransformCache(CLcmsCmm* pCmm) { - m_pIccTransform = NULL; - m_dwRate = 1; - m_pCmm = pCmm; -} -CFX_IccTransformCache::~CFX_IccTransformCache() { - if (m_pIccTransform) { - cmsDeleteTransform(m_pIccTransform); - } - FX_Free(m_pCmm); -} -void CFX_IccTransformCache::Purge() {} -class CFX_ByteStringKey : public CFX_BinaryBuf { - public: - CFX_ByteStringKey() : CFX_BinaryBuf() {} - CFX_ByteStringKey& operator<<(FX_DWORD i); -}; -CFX_ByteStringKey& CFX_ByteStringKey::operator<<(FX_DWORD i) { - AppendBlock(&i, sizeof(FX_DWORD)); - return *this; -} -void* CCodec_IccModule::CreateProfile(ICodec_IccModule::IccParam* pIccParam, - Icc_CLASS ic, - CFX_BinaryBuf* pTransformKey) { - CFX_IccProfileCache* pCache = NULL; - CFX_ByteStringKey key; - CFX_ByteString text; - key << pIccParam->ColorSpace << (pIccParam->dwProfileType | ic << 8); - uint8_t ID[16]; - switch (pIccParam->dwProfileType) { - case Icc_PARAMTYPE_NONE: - return NULL; - case Icc_PARAMTYPE_BUFFER: - MD5ComputeID(pIccParam->pProfileData, pIccParam->dwProfileSize, ID); - break; - case Icc_PARAMTYPE_PARAM: - FXSYS_memset(ID, 0, 16); - switch (pIccParam->ColorSpace) { - case IccCS_Gray: - text.Format("%lf", pIccParam->Gamma); - break; - default: - break; - } - MD5ComputeID(text.GetBuffer(0), text.GetLength(), ID); - break; - default: - break; - } - key.AppendBlock(ID, 16); - CFX_ByteString ProfileKey(key.GetBuffer(), key.GetSize()); - ASSERT(pTransformKey); - pTransformKey->AppendBlock(ProfileKey.GetBuffer(0), ProfileKey.GetLength()); - auto it = m_MapProfile.find(ProfileKey); - if (it == m_MapProfile.end()) { - pCache = new CFX_IccProfileCache; - switch (pIccParam->dwProfileType) { - case Icc_PARAMTYPE_BUFFER: - pCache->m_pProfile = cmsOpenProfileFromMem(pIccParam->pProfileData, - pIccParam->dwProfileSize); - break; - case Icc_PARAMTYPE_PARAM: - switch (pIccParam->ColorSpace) { - case IccCS_Rgb: - pCache->m_pProfile = cmsCreate_sRGBProfile(); - break; - case IccCS_Gray: - pCache->m_pProfile = CreateProfile_Gray(pIccParam->Gamma); - break; - default: - break; - } - break; - default: - break; - } - m_MapProfile[ProfileKey] = pCache; - } else { - pCache = it->second; - pCache->m_dwRate++; - } - return pCache->m_pProfile; -} -void* CCodec_IccModule::CreateTransform( - ICodec_IccModule::IccParam* pInputParam, - ICodec_IccModule::IccParam* pOutputParam, - ICodec_IccModule::IccParam* pProofParam, - FX_DWORD dwIntent, - FX_DWORD dwFlag, - FX_DWORD dwPrfIntent, - FX_DWORD dwPrfFlag) { - CLcmsCmm* pCmm = NULL; - ASSERT(pInputParam && pOutputParam); - CFX_ByteStringKey key; - void* pInputProfile = CreateProfile(pInputParam, Icc_CLASS_INPUT, &key); - if (!pInputProfile) { - return NULL; - } - void* pOutputProfile = CreateProfile(pOutputParam, Icc_CLASS_OUTPUT, &key); - if (!pOutputProfile) { - return NULL; - } - FX_DWORD dwInputProfileType = - TransferProfileType(pInputProfile, pInputParam->dwFormat); - FX_DWORD dwOutputProfileType = - TransferProfileType(pOutputProfile, pOutputParam->dwFormat); - if (dwInputProfileType == 0 || dwOutputProfileType == 0) { - return NULL; - } - void* pProofProfile = NULL; - if (pProofParam) { - pProofProfile = CreateProfile(pProofParam, Icc_CLASS_PROOF, &key); - } - key << dwInputProfileType << dwOutputProfileType << dwIntent << dwFlag - << (pProofProfile != NULL) << dwPrfIntent << dwPrfFlag; - CFX_ByteStringC TransformKey(key.GetBuffer(), key.GetSize()); - CFX_IccTransformCache* pTransformCache; - auto it = m_MapTranform.find(TransformKey); - if (it == m_MapTranform.end()) { - pCmm = FX_Alloc(CLcmsCmm, 1); - pCmm->m_nSrcComponents = T_CHANNELS(dwInputProfileType); - pCmm->m_nDstComponents = T_CHANNELS(dwOutputProfileType); - pCmm->m_bLab = T_COLORSPACE(pInputParam->dwFormat) == PT_Lab; - pTransformCache = new CFX_IccTransformCache(pCmm); - if (pProofProfile) { - pTransformCache->m_pIccTransform = cmsCreateProofingTransform( - pInputProfile, dwInputProfileType, pOutputProfile, - dwOutputProfileType, pProofProfile, dwIntent, dwPrfIntent, dwPrfFlag); - } else { - pTransformCache->m_pIccTransform = - cmsCreateTransform(pInputProfile, dwInputProfileType, pOutputProfile, - dwOutputProfileType, dwIntent, dwFlag); - } - pCmm->m_hTransform = pTransformCache->m_pIccTransform; - m_MapTranform[TransformKey] = pTransformCache; - } else { - pTransformCache = it->second; - pTransformCache->m_dwRate++; - } - return pTransformCache->m_pCmm; -} -CCodec_IccModule::~CCodec_IccModule() { - for (const auto& pair : m_MapProfile) { - delete pair.second; - } - m_MapProfile.clear(); - for (const auto& pair : m_MapTranform) { - delete pair.second; - } - m_MapTranform.clear(); -} -void* CCodec_IccModule::CreateTransform_sRGB(const uint8_t* pProfileData, - FX_DWORD dwProfileSize, - FX_DWORD& nComponents, - int32_t intent, - FX_DWORD dwSrcFormat) { - return IccLib_CreateTransform_sRGB(pProfileData, dwProfileSize, nComponents, - intent, dwSrcFormat); -} - -void* CCodec_IccModule::CreateTransform_CMYK(const uint8_t* pSrcProfileData, - FX_DWORD dwSrcProfileSize, - FX_DWORD& nSrcComponents, - const uint8_t* pDstProfileData, - FX_DWORD dwDstProfileSize, - int32_t intent, - FX_DWORD dwSrcFormat, - FX_DWORD dwDstFormat) { - return IccLib_CreateTransform( - pSrcProfileData, dwSrcProfileSize, nSrcComponents, pDstProfileData, - dwDstProfileSize, 4, intent, dwSrcFormat, dwDstFormat); -} - -void CCodec_IccModule::DestroyTransform(void* pTransform) { - IccLib_DestroyTransform(pTransform); -} -void CCodec_IccModule::Translate(void* pTransform, - FX_FLOAT* pSrcValues, - FX_FLOAT* pDestValues) { - IccLib_Translate(pTransform, m_nComponents, pSrcValues, pDestValues); -} -void CCodec_IccModule::TranslateScanline(void* pTransform, - uint8_t* pDest, - const uint8_t* pSrc, - int32_t pixels) { - IccLib_TranslateImage(pTransform, pDest, pSrc, pixels); -} -const uint8_t g_CMYKSamples[81 * 81 * 3] = { - 255, 255, 255, 225, 226, 228, 199, 200, 202, 173, 174, 178, 147, 149, 152, - 123, 125, 128, 99, 99, 102, 69, 70, 71, 34, 30, 31, 255, 253, 229, - 226, 224, 203, 200, 199, 182, 173, 173, 158, 149, 148, 135, 125, 124, 113, - 99, 99, 90, 70, 69, 63, 33, 29, 24, 255, 251, 204, 228, 223, 182, - 201, 198, 163, 174, 172, 142, 150, 147, 122, 125, 123, 101, 99, 98, 80, - 70, 68, 54, 32, 28, 16, 255, 249, 179, 230, 222, 160, 203, 197, 144, - 174, 170, 124, 150, 145, 105, 125, 122, 88, 99, 97, 69, 70, 68, 46, - 31, 28, 6, 255, 247, 154, 229, 220, 138, 203, 195, 122, 176, 169, 107, - 150, 145, 91, 125, 121, 74, 100, 96, 57, 70, 67, 35, 29, 26, 0, - 255, 246, 128, 231, 217, 114, 205, 194, 101, 176, 167, 88, 150, 144, 75, - 125, 120, 60, 100, 96, 44, 70, 66, 24, 28, 26, 0, 255, 244, 96, - 231, 217, 87, 203, 192, 78, 175, 167, 66, 150, 143, 56, 125, 119, 43, - 100, 95, 29, 69, 66, 7, 26, 26, 0, 255, 243, 51, 232, 215, 51, - 204, 191, 43, 176, 165, 38, 150, 142, 28, 125, 118, 17, 99, 94, 0, - 68, 65, 0, 24, 25, 0, 255, 241, 0, 231, 215, 0, 203, 190, 0, - 176, 164, 0, 150, 141, 0, 126, 117, 0, 99, 93, 0, 68, 65, 0, - 24, 25, 0, 252, 228, 238, 222, 201, 211, 197, 180, 190, 171, 156, 166, - 147, 133, 143, 123, 111, 119, 99, 88, 94, 71, 61, 66, 34, 22, 26, - 254, 226, 213, 224, 201, 191, 199, 179, 171, 172, 155, 148, 147, 133, 128, - 123, 110, 106, 98, 87, 83, 70, 59, 57, 33, 21, 18, 254, 224, 191, - 224, 199, 172, 200, 177, 153, 173, 154, 133, 147, 132, 115, 123, 109, 94, - 98, 86, 74, 70, 59, 49, 32, 21, 9, 255, 222, 168, 227, 198, 150, - 200, 175, 135, 173, 153, 118, 148, 130, 99, 123, 109, 82, 98, 86, 64, - 69, 58, 40, 31, 19, 0, 255, 221, 145, 227, 196, 129, 201, 174, 115, - 173, 151, 99, 148, 129, 85, 124, 108, 69, 98, 85, 52, 69, 58, 30, - 30, 19, 0, 255, 219, 121, 227, 195, 109, 201, 174, 97, 174, 150, 83, - 148, 129, 70, 124, 107, 55, 98, 84, 40, 69, 58, 19, 28, 18, 0, - 255, 218, 92, 229, 194, 82, 202, 173, 75, 174, 150, 63, 149, 128, 51, - 124, 106, 39, 98, 84, 24, 68, 57, 3, 26, 18, 0, 255, 217, 54, - 228, 193, 52, 201, 172, 46, 174, 148, 36, 148, 127, 27, 123, 105, 14, - 98, 83, 0, 68, 56, 0, 25, 18, 0, 255, 216, 0, 229, 192, 2, - 202, 171, 4, 173, 148, 0, 148, 126, 0, 124, 105, 0, 98, 83, 0, - 68, 56, 0, 24, 17, 0, 249, 204, 223, 219, 181, 199, 195, 160, 178, - 170, 140, 156, 146, 119, 134, 123, 99, 112, 98, 77, 88, 70, 52, 61, - 34, 11, 20, 250, 201, 200, 221, 180, 178, 197, 159, 161, 171, 139, 139, - 147, 119, 120, 123, 98, 99, 98, 77, 78, 69, 51, 52, 34, 11, 10, - 252, 201, 180, 223, 179, 162, 197, 159, 144, 170, 138, 125, 146, 117, 107, - 122, 97, 89, 98, 76, 69, 69, 50, 44, 32, 11, 2, 252, 199, 158, - 222, 177, 143, 199, 158, 127, 171, 137, 110, 147, 117, 93, 122, 96, 76, - 97, 75, 58, 69, 50, 36, 32, 10, 0, 253, 198, 137, 223, 177, 123, - 198, 156, 110, 171, 136, 95, 146, 116, 80, 122, 96, 65, 97, 75, 47, - 69, 50, 25, 30, 10, 0, 254, 197, 115, 225, 175, 104, 198, 156, 92, - 172, 135, 79, 147, 115, 66, 123, 95, 52, 98, 74, 37, 69, 49, 15, - 29, 10, 0, 254, 196, 89, 224, 175, 80, 199, 154, 70, 172, 134, 59, - 146, 114, 48, 122, 95, 36, 97, 74, 21, 68, 49, 0, 27, 9, 0, - 255, 195, 57, 225, 173, 52, 198, 154, 44, 172, 133, 36, 147, 113, 26, - 123, 94, 14, 98, 74, 0, 68, 49, 0, 26, 10, 0, 254, 194, 15, - 225, 172, 12, 198, 153, 7, 172, 132, 3, 146, 113, 0, 123, 93, 0, - 98, 73, 0, 68, 49, 0, 26, 9, 0, 246, 178, 209, 218, 159, 186, - 194, 140, 166, 168, 122, 145, 144, 104, 125, 121, 85, 103, 97, 65, 81, - 69, 41, 55, 34, 0, 12, 248, 176, 186, 219, 157, 166, 195, 139, 149, - 168, 121, 130, 144, 103, 111, 121, 85, 91, 97, 65, 71, 69, 41, 46, - 34, 0, 4, 249, 175, 168, 220, 156, 150, 196, 139, 135, 169, 121, 116, - 144, 103, 100, 122, 84, 83, 98, 65, 63, 70, 41, 39, 33, 0, 0, - 249, 175, 148, 220, 155, 133, 196, 138, 119, 169, 120, 103, 145, 101, 87, - 121, 83, 71, 97, 65, 54, 69, 41, 31, 32, 0, 0, 249, 173, 128, - 222, 154, 115, 195, 137, 102, 170, 119, 88, 145, 101, 74, 122, 83, 59, - 97, 64, 43, 68, 40, 20, 30, 0, 0, 250, 172, 108, 221, 154, 98, - 195, 136, 86, 170, 118, 73, 145, 100, 61, 122, 82, 48, 97, 63, 32, - 69, 40, 11, 28, 0, 0, 250, 171, 85, 221, 153, 76, 196, 136, 67, - 170, 117, 56, 145, 99, 44, 121, 82, 33, 97, 63, 17, 68, 40, 0, - 28, 0, 0, 251, 171, 58, 222, 152, 50, 197, 135, 43, 169, 117, 34, - 146, 99, 25, 121, 81, 10, 96, 63, 0, 68, 40, 0, 27, 0, 0, - 250, 170, 26, 222, 151, 19, 196, 134, 13, 169, 116, 4, 145, 99, 0, - 122, 81, 0, 97, 63, 0, 67, 40, 0, 26, 0, 0, 244, 153, 194, - 215, 136, 173, 192, 121, 155, 167, 104, 135, 143, 89, 115, 121, 72, 96, - 97, 54, 75, 70, 31, 49, 34, 0, 6, 245, 153, 173, 216, 136, 155, - 192, 120, 138, 167, 104, 121, 144, 88, 103, 121, 71, 85, 97, 54, 66, - 69, 31, 42, 34, 0, 0, 246, 152, 157, 217, 135, 140, 193, 120, 126, - 167, 103, 109, 143, 88, 92, 121, 72, 76, 97, 54, 58, 69, 31, 35, - 33, 0, 0, 245, 150, 139, 218, 134, 125, 193, 119, 111, 167, 103, 96, - 144, 87, 80, 121, 71, 66, 96, 53, 49, 68, 31, 26, 32, 0, 0, - 246, 151, 122, 218, 133, 108, 194, 118, 96, 168, 102, 81, 144, 86, 69, - 120, 71, 55, 95, 53, 39, 68, 30, 17, 31, 0, 0, 248, 150, 103, - 218, 133, 91, 193, 118, 81, 168, 102, 69, 143, 86, 56, 120, 70, 43, - 96, 53, 28, 68, 31, 6, 29, 0, 0, 247, 149, 81, 218, 132, 72, - 194, 117, 62, 168, 101, 52, 144, 86, 42, 121, 70, 29, 96, 52, 13, - 68, 30, 0, 28, 0, 0, 247, 148, 55, 219, 131, 50, 194, 117, 43, - 167, 101, 32, 144, 85, 22, 120, 69, 8, 96, 52, 0, 67, 30, 0, - 27, 0, 0, 247, 147, 29, 218, 131, 24, 194, 116, 20, 168, 100, 11, - 144, 85, 0, 120, 69, 0, 96, 52, 0, 67, 30, 0, 26, 0, 0, - 242, 130, 179, 214, 114, 160, 190, 101, 143, 166, 87, 125, 143, 72, 107, - 120, 58, 88, 96, 42, 68, 69, 17, 44, 35, 0, 0, 243, 129, 161, - 215, 114, 143, 191, 101, 128, 166, 87, 113, 143, 73, 96, 120, 58, 79, - 96, 41, 60, 69, 18, 37, 33, 0, 0, 243, 129, 146, 216, 114, 130, - 192, 101, 117, 166, 87, 101, 143, 72, 86, 121, 58, 69, 96, 42, 52, - 69, 18, 29, 31, 0, 0, 243, 128, 130, 216, 114, 115, 191, 101, 102, - 165, 86, 88, 142, 72, 75, 120, 58, 60, 95, 42, 43, 68, 19, 21, - 30, 0, 0, 244, 127, 112, 217, 113, 101, 192, 99, 89, 166, 85, 75, - 142, 72, 63, 119, 57, 50, 96, 41, 35, 68, 19, 13, 30, 0, 0, - 244, 127, 96, 216, 112, 86, 191, 99, 75, 166, 86, 64, 143, 72, 52, - 120, 57, 40, 95, 41, 24, 67, 20, 1, 29, 0, 0, 245, 126, 77, - 216, 113, 68, 191, 100, 59, 166, 85, 49, 142, 71, 38, 119, 57, 26, - 95, 41, 10, 67, 20, 0, 28, 0, 0, 244, 126, 55, 216, 112, 48, - 191, 99, 40, 166, 85, 31, 143, 71, 20, 119, 57, 6, 95, 42, 0, - 67, 20, 0, 28, 0, 0, 245, 126, 33, 217, 112, 26, 192, 99, 22, - 166, 84, 11, 142, 70, 0, 119, 57, 0, 95, 41, 0, 66, 20, 0, - 27, 0, 0, 241, 102, 167, 213, 90, 149, 189, 79, 133, 165, 66, 115, - 141, 54, 98, 119, 41, 81, 96, 25, 63, 69, 0, 38, 30, 0, 0, - 241, 102, 149, 213, 90, 133, 189, 79, 119, 165, 66, 103, 142, 55, 88, - 119, 41, 71, 96, 25, 53, 69, 0, 31, 28, 0, 0, 241, 102, 135, - 214, 90, 121, 190, 79, 108, 165, 66, 92, 141, 55, 78, 119, 42, 63, - 96, 26, 46, 69, 0, 24, 28, 0, 0, 241, 101, 120, 214, 90, 107, - 189, 79, 95, 165, 67, 83, 141, 54, 68, 118, 41, 54, 95, 27, 39, - 68, 0, 16, 27, 0, 0, 241, 102, 106, 213, 90, 93, 189, 78, 82, - 164, 67, 70, 141, 55, 58, 118, 42, 45, 94, 27, 29, 67, 2, 6, - 27, 0, 0, 242, 101, 90, 214, 89, 79, 190, 79, 69, 166, 67, 59, - 141, 55, 47, 118, 41, 35, 95, 27, 19, 67, 3, 0, 26, 0, 0, - 242, 102, 72, 213, 89, 63, 191, 79, 56, 164, 67, 45, 141, 55, 34, - 118, 42, 22, 94, 28, 6, 67, 3, 0, 26, 0, 0, 242, 100, 51, - 214, 89, 45, 190, 78, 38, 164, 67, 30, 141, 55, 18, 118, 42, 3, - 95, 28, 0, 66, 4, 0, 26, 0, 0, 243, 100, 33, 214, 90, 27, - 190, 78, 22, 165, 67, 13, 141, 55, 0, 118, 43, 0, 94, 29, 0, - 66, 5, 0, 26, 0, 0, 237, 69, 153, 211, 58, 135, 187, 51, 121, - 163, 41, 105, 141, 28, 90, 118, 15, 73, 96, 0, 56, 68, 0, 33, - 25, 0, 0, 239, 67, 137, 212, 60, 123, 189, 50, 110, 163, 41, 94, - 141, 29, 79, 118, 17, 65, 95, 0, 48, 69, 0, 26, 25, 0, 0, - 240, 69, 124, 211, 60, 111, 188, 50, 98, 163, 42, 85, 141, 31, 72, - 118, 18, 57, 94, 0, 41, 68, 0, 19, 25, 0, 0, 240, 70, 112, - 212, 61, 99, 188, 52, 87, 163, 41, 74, 140, 31, 62, 118, 20, 48, - 94, 2, 32, 68, 0, 11, 24, 0, 0, 239, 70, 98, 212, 62, 86, - 188, 53, 77, 164, 42, 64, 140, 32, 52, 118, 20, 40, 94, 3, 24, - 67, 0, 3, 23, 0, 0, 239, 71, 85, 212, 61, 74, 187, 53, 65, - 163, 44, 54, 140, 34, 43, 118, 22, 30, 95, 3, 14, 67, 0, 0, - 23, 0, 0, 239, 70, 67, 212, 62, 59, 188, 53, 51, 163, 45, 42, - 141, 34, 31, 117, 22, 17, 94, 5, 2, 66, 0, 0, 23, 0, 0, - 239, 71, 50, 213, 62, 43, 188, 54, 37, 164, 45, 28, 139, 34, 16, - 117, 22, 2, 94, 7, 0, 65, 0, 0, 23, 0, 0, 240, 71, 34, - 212, 63, 29, 189, 54, 24, 163, 46, 15, 139, 36, 2, 117, 25, 0, - 94, 8, 0, 66, 0, 0, 23, 0, 0, 237, 0, 140, 209, 0, 124, - 186, 0, 112, 162, 0, 97, 141, 0, 82, 118, 0, 67, 95, 0, 49, - 68, 0, 27, 20, 0, 0, 237, 0, 126, 210, 0, 113, 187, 0, 99, - 163, 0, 86, 139, 0, 72, 118, 0, 58, 95, 0, 42, 67, 0, 20, - 20, 0, 0, 237, 1, 114, 209, 1, 102, 187, 0, 90, 163, 0, 78, - 139, 0, 64, 118, 0, 50, 95, 0, 35, 67, 0, 13, 20, 0, 0, - 236, 16, 102, 209, 7, 91, 186, 0, 80, 162, 0, 68, 139, 0, 56, - 117, 0, 43, 94, 0, 27, 67, 0, 6, 20, 0, 0, 238, 15, 89, - 209, 13, 79, 186, 6, 69, 162, 0, 58, 139, 0, 47, 117, 0, 34, - 93, 0, 20, 66, 0, 2, 20, 0, 0, 237, 20, 78, 210, 12, 68, - 187, 4, 59, 163, 0, 49, 139, 0, 38, 116, 0, 26, 94, 0, 11, - 66, 0, 0, 20, 0, 0, 237, 25, 64, 210, 18, 56, 186, 11, 48, - 162, 4, 39, 138, 0, 27, 117, 0, 14, 93, 0, 0, 66, 0, 0, - 20, 0, 0, 238, 25, 48, 210, 22, 43, 186, 15, 35, 162, 8, 26, - 140, 0, 14, 117, 0, 0, 93, 0, 0, 65, 0, 0, 20, 0, 0, - 238, 28, 35, 210, 21, 30, 187, 15, 24, 162, 8, 16, 139, 1, 2, - 117, 0, 0, 93, 0, 0, 65, 0, 0, 22, 0, 0, 219, 242, 252, - 195, 214, 225, 172, 191, 201, 148, 165, 175, 127, 142, 150, 106, 119, 126, - 84, 95, 101, 58, 66, 72, 24, 27, 32, 222, 239, 226, 196, 213, 202, - 173, 189, 180, 150, 165, 158, 129, 141, 135, 107, 118, 113, 85, 94, 90, - 58, 66, 63, 21, 26, 24, 223, 237, 203, 198, 211, 182, 175, 188, 163, - 152, 164, 141, 129, 140, 121, 107, 117, 101, 85, 93, 80, 58, 64, 54, - 21, 26, 18, 226, 236, 179, 201, 210, 160, 177, 187, 143, 153, 162, 125, - 130, 139, 106, 108, 116, 89, 85, 92, 69, 58, 64, 45, 20, 25, 8, - 227, 234, 153, 201, 208, 139, 178, 185, 124, 154, 161, 107, 131, 138, 91, - 108, 115, 75, 85, 91, 58, 58, 63, 35, 17, 25, 0, 229, 233, 130, - 203, 207, 116, 178, 184, 104, 154, 160, 90, 131, 137, 76, 109, 114, 62, - 85, 90, 46, 58, 63, 25, 16, 24, 0, 230, 231, 100, 202, 205, 90, - 179, 183, 80, 154, 159, 69, 131, 136, 57, 109, 113, 46, 86, 90, 32, - 58, 63, 10, 14, 24, 0, 230, 230, 65, 204, 204, 58, 180, 182, 52, - 155, 157, 44, 132, 135, 35, 110, 113, 24, 86, 89, 9, 57, 62, 0, - 11, 24, 0, 232, 230, 19, 204, 204, 19, 180, 181, 17, 155, 157, 10, - 131, 134, 2, 109, 112, 0, 85, 89, 0, 57, 62, 0, 10, 23, 0, - 218, 216, 236, 194, 192, 211, 172, 171, 188, 149, 149, 164, 128, 127, 141, - 106, 106, 119, 84, 84, 94, 59, 57, 66, 25, 18, 26, 221, 214, 211, - 196, 191, 190, 174, 170, 170, 150, 148, 148, 128, 126, 127, 107, 105, 106, - 85, 83, 84, 59, 56, 58, 23, 17, 18, 222, 213, 190, 197, 189, 170, - 175, 169, 153, 151, 147, 133, 129, 126, 113, 108, 105, 94, 85, 82, 74, - 59, 56, 49, 22, 17, 11, 224, 211, 168, 199, 188, 151, 175, 168, 135, - 152, 146, 117, 129, 124, 99, 107, 103, 82, 84, 82, 64, 59, 55, 41, - 21, 17, 1, 224, 210, 145, 199, 187, 130, 176, 166, 117, 152, 145, 101, - 129, 123, 86, 107, 103, 70, 85, 81, 53, 58, 55, 31, 19, 17, 0, - 227, 208, 123, 200, 186, 110, 177, 165, 98, 153, 143, 84, 130, 122, 70, - 108, 102, 57, 85, 80, 41, 58, 54, 20, 18, 16, 0, 227, 208, 97, - 202, 185, 86, 177, 164, 77, 153, 142, 65, 130, 122, 54, 108, 101, 42, - 85, 80, 27, 58, 54, 7, 16, 16, 0, 228, 206, 66, 202, 184, 58, - 178, 163, 50, 154, 141, 42, 131, 121, 33, 109, 101, 21, 86, 79, 5, - 58, 54, 0, 13, 16, 0, 228, 206, 29, 202, 183, 25, 178, 163, 20, - 154, 141, 15, 131, 121, 5, 108, 100, 0, 85, 79, 0, 58, 53, 0, - 13, 16, 0, 217, 193, 221, 193, 172, 198, 172, 153, 178, 149, 133, 154, - 128, 114, 132, 107, 94, 111, 85, 74, 89, 59, 49, 61, 25, 8, 22, - 219, 191, 198, 195, 171, 178, 173, 153, 159, 149, 132, 139, 128, 113, 119, - 107, 94, 100, 85, 73, 79, 59, 48, 52, 25, 7, 14, 221, 191, 180, - 196, 170, 160, 174, 152, 144, 150, 132, 125, 129, 113, 107, 107, 93, 89, - 85, 73, 69, 59, 48, 45, 23, 7, 4, 222, 189, 159, 197, 169, 142, - 174, 151, 127, 151, 131, 110, 129, 112, 94, 108, 93, 78, 85, 72, 60, - 58, 47, 37, 22, 7, 0, 223, 188, 138, 197, 168, 123, 175, 150, 109, - 151, 130, 95, 130, 111, 81, 108, 92, 65, 85, 72, 49, 59, 47, 27, - 21, 7, 0, 224, 187, 118, 198, 167, 105, 176, 149, 93, 152, 129, 79, - 130, 110, 68, 108, 91, 54, 85, 71, 38, 59, 47, 17, 18, 7, 0, - 224, 187, 93, 199, 166, 83, 176, 148, 73, 152, 128, 62, 129, 109, 51, - 108, 90, 39, 85, 71, 25, 58, 46, 3, 16, 8, 0, 226, 186, 64, - 200, 165, 57, 177, 147, 50, 153, 127, 40, 130, 108, 31, 108, 90, 19, - 85, 70, 3, 58, 46, 0, 16, 8, 0, 227, 185, 35, 200, 165, 30, - 176, 146, 25, 152, 127, 18, 130, 108, 7, 108, 89, 0, 85, 70, 0, - 57, 46, 0, 14, 8, 0, 216, 169, 205, 192, 150, 184, 171, 134, 164, - 149, 116, 144, 128, 99, 124, 107, 81, 103, 85, 63, 81, 60, 39, 55, - 26, 0, 15, 217, 168, 186, 193, 150, 165, 172, 134, 149, 150, 116, 130, - 128, 99, 111, 107, 81, 92, 85, 62, 72, 59, 39, 47, 25, 0, 6, - 219, 168, 168, 194, 149, 150, 173, 133, 135, 150, 116, 117, 128, 98, 99, - 107, 80, 82, 86, 62, 63, 59, 38, 39, 24, 0, 0, 219, 166, 148, - 195, 149, 133, 173, 133, 119, 150, 115, 103, 128, 98, 88, 107, 80, 72, - 85, 61, 54, 59, 38, 32, 23, 0, 0, 220, 166, 129, 196, 148, 116, - 174, 132, 103, 151, 114, 89, 129, 97, 75, 107, 79, 60, 85, 61, 44, - 59, 38, 22, 21, 0, 0, 222, 164, 110, 197, 147, 99, 175, 131, 87, - 151, 113, 75, 129, 96, 63, 107, 79, 49, 85, 61, 33, 58, 38, 12, - 19, 0, 0, 222, 164, 88, 197, 146, 79, 174, 130, 69, 151, 113, 58, - 129, 95, 47, 107, 78, 35, 85, 60, 20, 58, 38, 0, 18, 0, 0, - 223, 164, 63, 198, 145, 55, 175, 129, 48, 151, 112, 39, 129, 95, 29, - 107, 78, 16, 85, 60, 1, 58, 38, 0, 17, 0, 0, 223, 163, 36, - 198, 145, 32, 174, 129, 26, 151, 111, 17, 129, 95, 7, 107, 78, 0, - 84, 60, 0, 57, 37, 0, 15, 0, 0, 215, 147, 192, 191, 130, 172, - 170, 116, 153, 148, 100, 133, 127, 85, 115, 107, 69, 96, 85, 51, 75, - 60, 28, 50, 25, 0, 8, 217, 146, 173, 192, 130, 154, 171, 115, 138, - 149, 100, 121, 128, 84, 103, 107, 68, 85, 85, 51, 66, 60, 28, 42, - 25, 0, 0, 217, 145, 157, 193, 129, 140, 173, 115, 125, 149, 100, 109, - 128, 84, 92, 107, 68, 76, 85, 51, 58, 59, 28, 35, 23, 0, 0, - 218, 145, 140, 193, 129, 125, 172, 114, 110, 149, 99, 96, 128, 83, 81, - 107, 67, 65, 84, 51, 49, 59, 29, 27, 22, 0, 0, 219, 144, 121, - 194, 128, 108, 172, 113, 96, 149, 98, 83, 128, 83, 69, 107, 68, 55, - 85, 50, 40, 59, 28, 18, 20, 0, 0, 220, 143, 104, 195, 128, 93, - 173, 114, 82, 150, 98, 69, 127, 82, 58, 107, 67, 45, 85, 50, 30, - 59, 28, 7, 19, 0, 0, 220, 143, 84, 195, 127, 74, 173, 113, 65, - 149, 97, 55, 128, 82, 44, 106, 67, 32, 84, 50, 16, 58, 28, 0, - 18, 0, 0, 221, 142, 62, 196, 126, 53, 173, 112, 46, 150, 97, 37, - 128, 82, 26, 107, 66, 14, 84, 50, 0, 58, 28, 0, 16, 0, 0, - 222, 142, 38, 196, 126, 34, 174, 112, 27, 150, 96, 17, 128, 82, 6, - 106, 66, 0, 84, 50, 0, 57, 29, 0, 16, 0, 0, 214, 123, 179, - 191, 110, 159, 169, 98, 143, 147, 84, 124, 126, 70, 106, 107, 55, 88, - 85, 39, 69, 60, 15, 45, 23, 0, 2, 216, 123, 161, 192, 110, 144, - 170, 98, 129, 148, 84, 112, 127, 70, 95, 107, 55, 79, 85, 39, 61, - 60, 15, 37, 20, 0, 0, 217, 122, 145, 192, 110, 130, 170, 97, 116, - 149, 84, 101, 127, 70, 85, 106, 55, 70, 85, 39, 53, 59, 16, 30, - 19, 0, 0, 217, 123, 131, 192, 109, 116, 171, 96, 103, 149, 83, 89, - 127, 70, 75, 106, 55, 60, 85, 40, 45, 59, 16, 23, 17, 0, 0, - 217, 122, 114, 193, 109, 101, 172, 96, 91, 149, 82, 77, 128, 69, 64, - 106, 55, 50, 84, 39, 35, 59, 17, 14, 17, 0, 0, 218, 122, 98, - 194, 108, 87, 171, 96, 77, 149, 82, 65, 127, 69, 52, 106, 55, 40, - 84, 40, 25, 59, 18, 3, 15, 0, 0, 219, 122, 80, 193, 108, 70, - 172, 95, 61, 149, 82, 51, 127, 69, 40, 106, 55, 28, 84, 39, 12, - 58, 17, 0, 13, 0, 0, 219, 121, 59, 194, 108, 52, 172, 96, 44, - 149, 82, 35, 127, 68, 24, 106, 55, 11, 84, 40, 0, 57, 18, 0, - 13, 0, 0, 219, 121, 40, 193, 108, 33, 172, 95, 26, 149, 81, 19, - 128, 68, 6, 106, 54, 0, 84, 39, 0, 57, 18, 0, 13, 0, 0, - 213, 99, 165, 189, 87, 148, 169, 76, 132, 147, 64, 115, 126, 52, 98, - 106, 39, 81, 85, 23, 63, 60, 0, 39, 16, 0, 0, 214, 98, 149, - 191, 87, 133, 170, 76, 119, 148, 65, 103, 127, 53, 88, 106, 39, 72, - 85, 24, 55, 60, 0, 32, 15, 0, 0, 215, 99, 136, 191, 87, 121, - 170, 77, 108, 148, 65, 93, 126, 53, 79, 106, 40, 64, 85, 24, 47, - 59, 0, 25, 14, 0, 0, 215, 99, 121, 192, 87, 108, 170, 77, 96, - 148, 65, 82, 126, 53, 69, 106, 40, 55, 85, 25, 39, 59, 0, 18, - 13, 0, 0, 216, 99, 106, 191, 87, 95, 170, 76, 83, 148, 65, 71, - 126, 53, 58, 106, 41, 45, 85, 26, 30, 59, 0, 8, 11, 0, 0, - 216, 98, 91, 192, 88, 82, 170, 77, 71, 148, 65, 60, 127, 53, 48, - 105, 41, 36, 83, 26, 21, 58, 1, 2, 11, 0, 0, 217, 99, 75, - 192, 87, 66, 170, 76, 57, 148, 65, 47, 126, 53, 36, 105, 41, 24, - 83, 26, 8, 57, 2, 0, 9, 0, 0, 217, 98, 57, 192, 87, 49, - 171, 77, 41, 147, 65, 32, 126, 53, 21, 105, 41, 8, 84, 27, 0, - 57, 3, 0, 9, 0, 0, 217, 98, 40, 193, 87, 34, 171, 76, 27, - 148, 65, 19, 126, 53, 6, 105, 41, 0, 83, 27, 0, 57, 4, 0, - 9, 0, 0, 211, 67, 152, 189, 58, 136, 168, 50, 122, 147, 39, 105, - 127, 28, 89, 106, 14, 74, 85, 0, 56, 59, 0, 33, 9, 0, 0, - 213, 68, 138, 190, 59, 123, 169, 51, 109, 148, 40, 95, 126, 30, 80, - 106, 16, 65, 85, 0, 48, 59, 0, 27, 9, 0, 0, 214, 69, 125, - 190, 59, 111, 168, 51, 99, 148, 41, 86, 126, 31, 72, 106, 18, 58, - 85, 0, 41, 59, 0, 20, 7, 0, 0, 215, 70, 112, 190, 61, 100, - 169, 52, 88, 147, 42, 76, 126, 32, 63, 106, 19, 49, 84, 1, 34, - 58, 0, 13, 7, 0, 0, 214, 70, 99, 190, 62, 88, 169, 53, 77, - 147, 43, 65, 125, 32, 53, 106, 20, 40, 84, 3, 26, 58, 0, 4, - 7, 0, 0, 214, 71, 86, 190, 61, 75, 169, 53, 65, 146, 43, 54, - 126, 33, 44, 105, 21, 31, 83, 4, 17, 57, 0, 0, 7, 0, 0, - 215, 71, 71, 191, 62, 62, 169, 53, 53, 147, 44, 44, 126, 34, 33, - 105, 22, 20, 83, 5, 4, 57, 0, 0, 7, 0, 0, 215, 71, 54, - 191, 62, 47, 169, 54, 39, 147, 44, 30, 126, 35, 20, 105, 23, 6, - 83, 6, 0, 56, 0, 0, 5, 0, 0, 215, 71, 41, 191, 63, 34, - 170, 54, 27, 147, 45, 17, 126, 35, 6, 105, 23, 0, 83, 8, 0, - 56, 0, 0, 5, 0, 0, 210, 13, 140, 189, 1, 125, 167, 0, 110, - 146, 0, 96, 126, 0, 81, 106, 0, 67, 85, 0, 51, 59, 0, 28, - 4, 0, 0, 212, 18, 126, 190, 7, 113, 168, 0, 100, 146, 0, 86, - 126, 0, 73, 106, 0, 59, 84, 0, 43, 59, 0, 22, 4, 0, 0, - 212, 21, 115, 190, 13, 103, 168, 3, 91, 146, 0, 78, 125, 0, 65, - 105, 0, 52, 84, 0, 36, 58, 0, 16, 4, 0, 0, 213, 24, 103, - 189, 19, 91, 168, 9, 82, 146, 0, 69, 125, 0, 57, 105, 0, 44, - 84, 0, 29, 58, 0, 7, 4, 0, 0, 213, 27, 92, 188, 21, 81, - 168, 14, 71, 146, 1, 59, 125, 0, 48, 105, 0, 36, 84, 0, 21, - 58, 0, 4, 4, 0, 0, 213, 30, 80, 189, 22, 69, 168, 17, 61, - 146, 5, 50, 125, 0, 39, 104, 0, 27, 83, 0, 12, 57, 0, 0, - 4, 0, 0, 214, 30, 67, 189, 25, 57, 168, 20, 50, 146, 9, 40, - 125, 0, 29, 104, 0, 17, 83, 0, 2, 56, 0, 0, 4, 0, 0, - 214, 32, 53, 189, 27, 44, 169, 20, 38, 146, 13, 28, 124, 2, 17, - 104, 0, 4, 83, 0, 0, 56, 0, 0, 4, 0, 0, 214, 33, 41, - 190, 27, 33, 168, 23, 27, 146, 13, 18, 125, 3, 5, 105, 0, 0, - 83, 0, 0, 56, 0, 0, 4, 0, 0, 185, 229, 250, 164, 204, 223, - 146, 182, 199, 127, 158, 174, 108, 136, 149, 89, 113, 125, 70, 90, 100, - 46, 62, 71, 10, 25, 33, 189, 227, 225, 168, 202, 201, 148, 181, 179, - 129, 157, 156, 109, 135, 134, 90, 113, 113, 70, 89, 90, 46, 62, 62, - 8, 24, 25, 192, 226, 202, 170, 202, 182, 151, 179, 162, 130, 156, 141, - 110, 133, 121, 91, 112, 101, 71, 89, 80, 46, 61, 54, 7, 24, 19, - 194, 224, 179, 173, 200, 160, 153, 178, 144, 132, 155, 125, 112, 133, 107, - 92, 111, 89, 71, 88, 69, 46, 61, 45, 6, 23, 10, 196, 223, 155, - 174, 198, 139, 154, 176, 124, 132, 153, 107, 113, 131, 91, 92, 110, 75, - 72, 87, 58, 47, 60, 37, 4, 23, 0, 198, 221, 131, 175, 197, 117, - 155, 175, 105, 133, 152, 91, 113, 130, 76, 92, 109, 63, 72, 86, 47, - 46, 60, 26, 3, 23, 0, 200, 220, 104, 176, 196, 94, 156, 175, 84, - 134, 151, 72, 113, 129, 59, 93, 108, 47, 72, 85, 33, 46, 59, 13, - 0, 23, 0, 201, 219, 73, 179, 195, 65, 157, 173, 57, 135, 150, 48, - 114, 129, 39, 94, 108, 28, 72, 85, 15, 47, 59, 0, 0, 22, 0, - 203, 219, 42, 178, 195, 37, 157, 173, 32, 135, 150, 26, 114, 128, 16, - 94, 107, 6, 73, 85, 0, 46, 58, 0, 0, 22, 0, 186, 205, 233, - 165, 183, 209, 148, 163, 187, 128, 142, 163, 109, 121, 140, 91, 101, 118, - 71, 80, 94, 48, 54, 66, 12, 15, 27, 189, 204, 211, 169, 182, 189, - 151, 163, 169, 131, 141, 147, 111, 121, 126, 92, 101, 105, 72, 79, 84, - 48, 54, 58, 11, 15, 19, 192, 202, 190, 171, 181, 170, 152, 161, 152, - 131, 141, 133, 112, 120, 113, 93, 100, 94, 72, 79, 74, 48, 53, 50, - 10, 15, 11, 195, 201, 169, 172, 179, 151, 153, 160, 135, 132, 139, 117, - 113, 119, 100, 93, 99, 82, 72, 78, 64, 48, 53, 41, 9, 14, 3, - 195, 200, 146, 174, 179, 131, 154, 159, 117, 133, 138, 101, 113, 118, 86, - 93, 98, 70, 73, 77, 53, 48, 52, 32, 8, 15, 0, 198, 199, 125, - 175, 177, 111, 155, 158, 100, 133, 137, 85, 113, 117, 71, 93, 97, 57, - 72, 77, 42, 47, 52, 22, 5, 14, 0, 199, 198, 101, 176, 177, 89, - 155, 157, 79, 134, 136, 68, 113, 116, 56, 94, 97, 44, 73, 76, 30, - 47, 52, 10, 2, 15, 0, 200, 197, 72, 178, 176, 63, 157, 156, 56, - 135, 136, 46, 114, 116, 37, 94, 96, 26, 73, 76, 11, 47, 51, 0, - 0, 14, 0, 201, 197, 45, 177, 175, 38, 156, 155, 31, 135, 135, 25, - 114, 115, 17, 94, 96, 5, 73, 75, 0, 46, 51, 0, 0, 14, 0, - 187, 183, 218, 167, 165, 197, 149, 147, 176, 129, 127, 153, 111, 109, 132, - 92, 90, 111, 73, 70, 89, 49, 46, 62, 15, 4, 22, 190, 183, 197, - 170, 164, 177, 151, 146, 159, 130, 127, 139, 112, 109, 119, 93, 90, 99, - 72, 70, 78, 49, 45, 53, 14, 4, 15, 192, 182, 179, 171, 163, 161, - 153, 145, 144, 132, 126, 125, 113, 108, 107, 93, 89, 88, 73, 70, 69, - 49, 45, 45, 13, 5, 6, 195, 181, 159, 172, 162, 142, 152, 145, 127, - 132, 125, 111, 113, 107, 94, 93, 88, 77, 73, 69, 59, 48, 45, 37, - 11, 5, 0, 195, 180, 139, 173, 161, 124, 153, 143, 110, 133, 125, 96, - 113, 106, 81, 94, 88, 66, 73, 68, 49, 49, 44, 28, 9, 6, 0, - 196, 179, 118, 174, 160, 106, 154, 142, 94, 133, 124, 81, 113, 105, 68, - 94, 87, 54, 73, 68, 39, 48, 44, 18, 5, 5, 0, 197, 178, 96, - 176, 159, 86, 155, 141, 75, 134, 123, 64, 114, 105, 53, 94, 87, 40, - 73, 68, 26, 48, 44, 5, 2, 6, 0, 199, 178, 70, 176, 158, 62, - 156, 141, 54, 134, 122, 44, 114, 104, 35, 94, 86, 23, 73, 67, 8, - 47, 44, 0, 2, 6, 0, 199, 177, 45, 178, 158, 40, 156, 140, 32, - 135, 122, 26, 114, 104, 16, 94, 86, 4, 73, 67, 0, 47, 44, 0, - 0, 7, 0, 188, 161, 204, 168, 144, 183, 149, 129, 164, 130, 112, 144, - 112, 95, 123, 93, 78, 103, 74, 60, 81, 50, 36, 56, 16, 0, 16, - 190, 160, 185, 170, 144, 165, 151, 128, 148, 132, 111, 130, 112, 95, 110, - 93, 78, 92, 74, 59, 72, 50, 36, 48, 16, 0, 8, 192, 160, 167, - 171, 143, 150, 153, 128, 134, 132, 111, 117, 112, 94, 100, 94, 77, 82, - 74, 59, 63, 50, 36, 40, 14, 0, 0, 193, 159, 149, 172, 143, 134, - 153, 127, 119, 133, 110, 103, 113, 94, 87, 93, 77, 72, 73, 59, 54, - 50, 36, 32, 12, 0, 0, 195, 159, 131, 173, 142, 117, 153, 127, 104, - 132, 110, 90, 113, 93, 76, 93, 76, 61, 74, 59, 45, 49, 36, 23, - 9, 0, 0, 196, 158, 113, 174, 141, 101, 155, 126, 89, 133, 109, 76, - 113, 93, 64, 94, 76, 51, 74, 58, 35, 49, 36, 14, 6, 0, 0, - 197, 157, 92, 174, 141, 80, 154, 125, 71, 134, 108, 60, 114, 92, 50, - 94, 75, 37, 73, 58, 22, 48, 36, 1, 5, 0, 0, 197, 157, 68, - 175, 140, 59, 155, 124, 51, 134, 108, 41, 113, 91, 32, 94, 75, 21, - 73, 57, 5, 48, 35, 0, 5, 0, 0, 198, 156, 46, 176, 140, 40, - 155, 124, 32, 134, 107, 24, 114, 91, 14, 94, 75, 2, 73, 57, 0, - 48, 36, 0, 3, 0, 0, 189, 140, 191, 168, 126, 172, 150, 112, 154, - 131, 97, 134, 112, 82, 115, 94, 66, 96, 74, 49, 75, 51, 25, 50, - 12, 0, 10, 191, 139, 173, 170, 125, 154, 152, 111, 138, 132, 96, 121, - 113, 81, 103, 94, 66, 85, 74, 48, 66, 50, 26, 42, 12, 0, 1, - 192, 139, 157, 171, 125, 140, 152, 111, 125, 132, 96, 109, 113, 81, 92, - 94, 65, 76, 74, 48, 58, 50, 26, 35, 9, 0, 0, 193, 139, 140, - 172, 124, 125, 153, 110, 112, 133, 95, 96, 113, 80, 82, 94, 65, 66, - 74, 49, 50, 50, 26, 28, 7, 0, 0, 194, 138, 123, 172, 123, 109, - 153, 110, 97, 133, 95, 84, 113, 80, 70, 94, 65, 56, 74, 48, 40, - 50, 26, 20, 6, 0, 0, 194, 138, 105, 173, 123, 94, 153, 109, 83, - 133, 94, 70, 112, 79, 59, 94, 64, 46, 74, 48, 31, 50, 26, 9, - 4, 0, 0, 196, 138, 87, 174, 122, 77, 153, 109, 67, 133, 93, 56, - 113, 79, 46, 94, 64, 34, 73, 48, 18, 49, 27, 0, 4, 0, 0, - 196, 137, 65, 174, 122, 57, 154, 108, 49, 133, 93, 39, 113, 79, 29, - 94, 64, 18, 74, 48, 3, 49, 27, 0, 2, 0, 0, 197, 137, 47, - 175, 122, 40, 155, 108, 32, 133, 93, 23, 114, 79, 14, 94, 64, 1, - 73, 48, 0, 48, 27, 0, 2, 0, 0, 189, 119, 177, 168, 106, 159, - 150, 94, 142, 131, 81, 124, 113, 67, 107, 94, 53, 89, 74, 37, 69, - 51, 11, 45, 6, 0, 3, 191, 119, 161, 170, 106, 144, 152, 94, 129, - 132, 81, 112, 113, 67, 96, 94, 53, 79, 74, 37, 61, 51, 13, 38, - 6, 0, 0, 192, 119, 146, 170, 106, 131, 152, 94, 117, 132, 80, 101, - 112, 67, 85, 94, 53, 70, 74, 37, 53, 50, 14, 31, 4, 0, 0, - 192, 119, 131, 171, 106, 117, 153, 94, 105, 132, 80, 89, 113, 67, 75, - 94, 54, 61, 74, 38, 45, 51, 14, 23, 3, 0, 0, 193, 118, 114, - 171, 106, 102, 153, 93, 90, 132, 80, 78, 113, 67, 65, 94, 53, 52, - 74, 37, 36, 50, 15, 16, 1, 0, 0, 194, 118, 99, 172, 105, 89, - 153, 93, 78, 132, 80, 66, 113, 67, 54, 94, 53, 42, 74, 38, 27, - 50, 16, 5, 1, 0, 0, 194, 118, 82, 173, 105, 72, 153, 93, 63, - 132, 79, 53, 113, 67, 42, 94, 53, 30, 74, 38, 15, 49, 16, 0, - 0, 0, 0, 195, 117, 63, 173, 105, 55, 154, 93, 47, 133, 79, 37, - 113, 66, 27, 94, 53, 15, 73, 38, 0, 48, 16, 0, 0, 0, 0, - 195, 117, 46, 173, 104, 39, 154, 92, 32, 133, 79, 22, 113, 66, 13, - 94, 53, 0, 73, 38, 0, 48, 17, 0, 0, 0, 0, 189, 96, 166, - 168, 85, 147, 150, 74, 132, 131, 62, 115, 113, 51, 99, 94, 38, 82, - 74, 21, 63, 51, 0, 40, 1, 0, 0, 190, 96, 150, 170, 85, 133, - 152, 75, 119, 132, 63, 104, 113, 51, 88, 94, 38, 72, 75, 22, 55, - 51, 0, 33, 1, 0, 0, 192, 96, 137, 170, 85, 121, 152, 74, 108, - 132, 64, 94, 113, 52, 79, 94, 39, 64, 74, 23, 48, 50, 0, 26, - 0, 0, 0, 192, 96, 122, 171, 86, 109, 152, 75, 96, 132, 63, 83, - 113, 52, 69, 94, 39, 56, 74, 24, 41, 50, 0, 19, 0, 0, 0, - 193, 96, 107, 171, 85, 96, 152, 75, 84, 132, 64, 72, 113, 52, 60, - 94, 39, 47, 74, 24, 32, 50, 1, 10, 0, 0, 0, 193, 96, 93, - 172, 85, 82, 152, 75, 72, 133, 63, 61, 113, 51, 49, 94, 39, 37, - 73, 25, 23, 49, 2, 2, 0, 0, 0, 194, 96, 78, 172, 85, 68, - 152, 75, 59, 132, 63, 49, 113, 52, 39, 94, 40, 26, 73, 25, 11, - 48, 3, 0, 0, 0, 0, 194, 96, 60, 173, 85, 52, 153, 75, 44, - 132, 64, 35, 112, 52, 25, 94, 40, 12, 73, 26, 0, 48, 4, 0, - 0, 0, 0, 195, 96, 46, 173, 85, 38, 154, 74, 31, 133, 63, 22, - 113, 52, 11, 93, 40, 0, 73, 26, 0, 47, 5, 0, 0, 0, 0, - 188, 67, 153, 168, 58, 137, 151, 49, 122, 131, 39, 106, 113, 28, 90, - 94, 13, 75, 75, 0, 57, 51, 0, 35, 0, 0, 0, 190, 68, 138, - 170, 59, 123, 152, 50, 110, 132, 41, 96, 113, 29, 80, 94, 16, 66, - 75, 0, 49, 50, 0, 27, 0, 0, 0, 191, 69, 126, 170, 59, 112, - 151, 52, 100, 132, 42, 86, 113, 30, 73, 95, 17, 58, 75, 0, 42, - 50, 0, 21, 0, 0, 0, 192, 70, 113, 170, 61, 100, 151, 52, 89, - 132, 42, 77, 113, 31, 64, 94, 19, 50, 74, 1, 35, 50, 0, 14, - 0, 0, 0, 192, 70, 100, 170, 62, 89, 151, 53, 77, 131, 43, 66, - 112, 32, 54, 94, 20, 42, 74, 2, 27, 49, 0, 5, 0, 0, 0, - 192, 71, 87, 171, 61, 77, 152, 53, 67, 131, 44, 57, 112, 33, 45, - 94, 21, 33, 74, 4, 19, 49, 0, 1, 0, 0, 0, 193, 71, 74, - 171, 62, 64, 152, 53, 55, 132, 44, 45, 113, 34, 34, 94, 22, 23, - 73, 5, 7, 48, 0, 0, 0, 0, 0, 193, 70, 58, 172, 62, 50, - 152, 54, 42, 132, 44, 32, 112, 35, 22, 93, 23, 10, 73, 6, 0, - 47, 0, 0, 0, 0, 0, 193, 70, 45, 172, 62, 38, 153, 54, 31, - 132, 44, 21, 112, 35, 9, 94, 23, 0, 73, 7, 0, 47, 0, 0, - 0, 0, 0, 189, 26, 141, 169, 15, 126, 150, 2, 112, 131, 0, 97, - 113, 0, 82, 94, 0, 67, 75, 0, 51, 50, 0, 29, 0, 0, 0, - 190, 28, 128, 170, 18, 114, 151, 8, 101, 132, 0, 88, 113, 0, 74, - 94, 0, 60, 75, 0, 44, 50, 0, 23, 0, 0, 0, 191, 30, 117, - 170, 23, 104, 152, 11, 92, 132, 1, 79, 113, 0, 67, 95, 0, 53, - 75, 0, 37, 50, 0, 17, 0, 0, 0, 191, 33, 105, 170, 26, 93, - 151, 18, 83, 132, 6, 70, 112, 0, 58, 94, 0, 45, 75, 0, 30, - 49, 0, 8, 0, 0, 0, 191, 34, 93, 170, 27, 82, 151, 20, 72, - 131, 8, 61, 112, 0, 49, 94, 0, 38, 74, 0, 23, 49, 0, 4, - 0, 0, 0, 191, 36, 82, 170, 29, 71, 151, 22, 63, 131, 11, 52, - 112, 0, 41, 93, 0, 29, 74, 0, 14, 48, 0, 1, 0, 0, 0, - 191, 38, 69, 170, 31, 60, 151, 24, 51, 131, 14, 41, 112, 1, 31, - 93, 0, 19, 73, 0, 3, 48, 0, 0, 0, 0, 0, 192, 37, 56, - 171, 31, 47, 152, 25, 40, 131, 17, 30, 112, 4, 19, 93, 0, 7, - 73, 0, 0, 47, 0, 0, 0, 0, 0, 192, 38, 45, 171, 33, 36, - 152, 26, 30, 131, 18, 21, 111, 7, 9, 93, 0, 0, 73, 0, 0, - 47, 0, 0, 0, 0, 0, 149, 218, 248, 133, 194, 222, 119, 173, 198, - 102, 151, 173, 86, 130, 148, 70, 108, 125, 53, 85, 100, 32, 59, 71, - 0, 22, 33, 154, 216, 223, 137, 193, 200, 122, 172, 178, 106, 150, 156, - 89, 128, 133, 73, 107, 112, 54, 85, 89, 31, 59, 63, 0, 22, 26, - 159, 215, 202, 141, 192, 181, 126, 171, 161, 108, 149, 141, 90, 128, 121, - 74, 107, 100, 55, 85, 80, 32, 58, 55, 0, 22, 19, 161, 213, 179, - 144, 190, 160, 126, 170, 143, 109, 148, 125, 92, 127, 107, 74, 106, 89, - 56, 84, 69, 32, 58, 46, 0, 21, 11, 163, 211, 156, 144, 189, 139, - 129, 168, 125, 110, 147, 108, 93, 126, 92, 75, 105, 76, 57, 83, 58, - 33, 58, 37, 0, 21, 1, 167, 211, 133, 147, 188, 120, 130, 167, 105, - 110, 145, 92, 93, 125, 78, 76, 104, 64, 58, 83, 48, 33, 57, 27, - 0, 21, 0, 169, 210, 108, 149, 187, 96, 131, 166, 86, 112, 144, 74, - 94, 124, 62, 77, 103, 49, 58, 82, 35, 33, 57, 15, 0, 21, 0, - 170, 209, 80, 151, 186, 71, 133, 165, 62, 114, 143, 52, 95, 123, 42, - 77, 103, 32, 58, 81, 18, 33, 56, 0, 0, 21, 0, 173, 208, 55, - 152, 186, 49, 134, 165, 41, 114, 143, 34, 95, 122, 25, 77, 102, 14, - 58, 81, 0, 33, 56, 0, 0, 21, 0, 154, 195, 232, 137, 174, 207, - 122, 156, 185, 105, 136, 163, 89, 116, 140, 73, 97, 117, 56, 76, 94, - 35, 51, 66, 0, 13, 28, 158, 194, 209, 141, 174, 187, 125, 155, 167, - 109, 135, 146, 91, 116, 125, 75, 96, 105, 57, 75, 83, 35, 50, 57, - 0, 12, 21, 161, 193, 189, 144, 173, 169, 128, 154, 151, 110, 134, 132, - 93, 115, 113, 77, 95, 94, 58, 75, 74, 35, 50, 50, 0, 12, 13, - 164, 192, 168, 145, 171, 151, 129, 153, 134, 111, 133, 117, 94, 114, 100, - 76, 95, 82, 58, 75, 64, 36, 50, 42, 0, 12, 5, 165, 191, 147, - 147, 170, 131, 130, 152, 117, 113, 132, 102, 95, 113, 86, 77, 94, 71, - 58, 74, 54, 35, 50, 33, 0, 13, 0, 167, 189, 126, 148, 169, 113, - 132, 151, 100, 113, 131, 86, 96, 112, 73, 77, 93, 59, 59, 73, 43, - 35, 49, 23, 0, 12, 0, 170, 189, 104, 150, 168, 91, 133, 150, 81, - 114, 130, 69, 96, 111, 57, 78, 92, 46, 59, 73, 31, 35, 49, 11, - 0, 13, 0, 171, 188, 78, 152, 168, 68, 134, 149, 60, 115, 130, 50, - 96, 111, 41, 78, 92, 29, 60, 73, 15, 35, 49, 0, 0, 12, 0, - 173, 187, 55, 153, 167, 47, 134, 149, 39, 115, 129, 33, 97, 110, 24, - 79, 92, 13, 60, 72, 0, 35, 48, 0, 0, 12, 0, 157, 175, 217, - 139, 157, 196, 125, 141, 175, 109, 122, 153, 92, 104, 132, 76, 86, 110, - 59, 67, 88, 37, 43, 61, 1, 1, 23, 161, 174, 196, 144, 156, 176, - 127, 140, 158, 110, 121, 137, 94, 104, 118, 77, 85, 98, 59, 67, 78, - 37, 43, 53, 0, 2, 16, 163, 174, 178, 146, 156, 160, 130, 139, 143, - 112, 121, 124, 95, 103, 106, 78, 85, 88, 60, 66, 69, 37, 42, 46, - 0, 2, 7, 166, 173, 159, 147, 154, 142, 130, 138, 127, 113, 120, 111, - 96, 103, 95, 78, 84, 77, 60, 66, 59, 37, 43, 37, 0, 2, 0, - 166, 172, 139, 148, 154, 125, 131, 137, 112, 113, 120, 96, 96, 102, 81, - 78, 84, 66, 60, 65, 50, 37, 42, 29, 0, 3, 0, 167, 171, 120, - 149, 153, 107, 133, 137, 95, 114, 118, 81, 97, 101, 69, 79, 84, 56, - 60, 65, 40, 37, 42, 19, 0, 3, 0, 170, 170, 99, 151, 152, 87, - 134, 136, 77, 115, 118, 66, 97, 101, 55, 79, 83, 42, 61, 65, 28, - 37, 42, 7, 0, 3, 0, 172, 170, 75, 152, 151, 65, 134, 135, 57, - 115, 117, 48, 97, 100, 38, 79, 83, 27, 61, 64, 12, 36, 42, 0, - 0, 3, 0, 172, 169, 55, 154, 151, 46, 135, 134, 40, 116, 116, 32, - 97, 99, 21, 80, 82, 10, 61, 64, 0, 36, 41, 0, 0, 3, 0, - 160, 154, 203, 143, 139, 182, 127, 124, 164, 111, 107, 143, 95, 91, 122, - 78, 75, 103, 60, 57, 81, 39, 33, 56, 1, 0, 18, 163, 154, 184, - 146, 138, 165, 130, 123, 148, 113, 107, 129, 96, 90, 110, 79, 74, 92, - 61, 56, 72, 39, 34, 48, 2, 0, 9, 165, 154, 167, 147, 137, 149, - 131, 122, 134, 114, 106, 117, 96, 90, 100, 79, 74, 82, 61, 56, 64, - 39, 33, 40, 2, 0, 1, 166, 153, 150, 149, 137, 133, 132, 122, 119, - 114, 106, 104, 97, 90, 88, 79, 74, 72, 61, 56, 55, 39, 34, 33, - 0, 0, 0, 168, 152, 132, 149, 136, 117, 132, 121, 104, 114, 105, 90, - 97, 89, 76, 79, 73, 62, 61, 56, 46, 38, 34, 25, 0, 0, 0, - 169, 151, 114, 150, 135, 101, 133, 121, 90, 114, 104, 77, 97, 89, 65, - 80, 73, 51, 61, 56, 36, 38, 34, 16, 0, 0, 0, 170, 150, 94, - 151, 135, 83, 134, 120, 73, 115, 104, 62, 98, 88, 51, 80, 72, 39, - 61, 56, 24, 38, 34, 3, 0, 0, 0, 172, 150, 72, 153, 134, 63, - 135, 119, 55, 115, 103, 45, 98, 88, 36, 80, 72, 24, 61, 55, 9, - 38, 34, 0, 0, 0, 0, 172, 150, 54, 153, 134, 47, 135, 119, 38, - 116, 103, 30, 98, 87, 21, 80, 72, 8, 62, 55, 0, 37, 34, 0, - 0, 0, 0, 162, 134, 190, 145, 120, 171, 129, 108, 153, 113, 93, 134, - 97, 78, 115, 80, 63, 96, 62, 46, 75, 41, 23, 51, 0, 0, 11, - 165, 134, 173, 147, 120, 154, 131, 107, 138, 114, 92, 120, 97, 78, 103, - 80, 63, 85, 62, 46, 66, 40, 23, 43, 0, 0, 2, 166, 134, 157, - 148, 120, 140, 132, 106, 125, 114, 92, 109, 97, 77, 93, 81, 63, 77, - 62, 46, 58, 40, 24, 36, 0, 0, 0, 168, 133, 140, 149, 119, 125, - 132, 106, 112, 115, 92, 97, 98, 77, 82, 81, 62, 67, 62, 46, 50, - 40, 24, 29, 0, 0, 0, 168, 133, 123, 150, 119, 110, 133, 106, 97, - 115, 91, 84, 98, 77, 70, 81, 62, 57, 62, 46, 41, 40, 24, 20, - 0, 0, 0, 169, 132, 107, 150, 118, 94, 133, 105, 84, 115, 91, 72, - 98, 76, 60, 80, 62, 47, 62, 46, 32, 39, 25, 11, 0, 0, 0, - 171, 132, 89, 152, 118, 79, 135, 105, 69, 115, 90, 58, 98, 76, 47, - 80, 62, 36, 62, 46, 21, 39, 25, 0, 0, 0, 0, 171, 132, 69, - 153, 117, 60, 135, 104, 52, 116, 90, 42, 98, 76, 33, 81, 61, 21, - 62, 46, 6, 38, 25, 0, 0, 0, 0, 172, 132, 54, 153, 118, 45, - 135, 104, 38, 116, 90, 28, 98, 76, 18, 81, 61, 6, 62, 46, 0, - 38, 25, 0, 0, 0, 0, 164, 115, 177, 146, 103, 159, 130, 91, 143, - 114, 78, 125, 97, 65, 107, 81, 51, 89, 63, 34, 69, 41, 9, 46, - 0, 0, 4, 166, 115, 161, 148, 103, 144, 132, 91, 129, 115, 78, 112, - 98, 65, 96, 81, 51, 79, 63, 35, 61, 41, 11, 38, 0, 0, 0, - 167, 115, 146, 150, 102, 131, 132, 91, 117, 115, 78, 101, 98, 65, 86, - 81, 51, 71, 63, 35, 54, 41, 12, 32, 0, 0, 0, 168, 114, 132, - 150, 103, 118, 133, 91, 105, 116, 78, 91, 98, 64, 76, 82, 51, 61, - 63, 36, 46, 41, 13, 24, 0, 0, 0, 169, 114, 116, 150, 102, 103, - 134, 90, 91, 116, 78, 79, 98, 65, 66, 81, 51, 53, 63, 36, 37, - 40, 14, 17, 0, 0, 0, 169, 114, 101, 151, 101, 89, 134, 90, 79, - 116, 77, 67, 98, 64, 56, 81, 51, 44, 63, 36, 29, 40, 15, 7, - 0, 0, 0, 170, 114, 85, 152, 101, 75, 135, 90, 65, 116, 77, 54, - 98, 64, 44, 81, 51, 32, 63, 36, 17, 39, 15, 0, 0, 0, 0, - 172, 113, 66, 152, 101, 58, 135, 89, 49, 116, 77, 40, 99, 64, 30, - 81, 51, 18, 62, 36, 3, 38, 16, 0, 0, 0, 0, 171, 113, 51, - 153, 101, 44, 136, 89, 36, 116, 77, 28, 99, 64, 18, 81, 51, 5, - 62, 36, 0, 38, 16, 0, 0, 0, 0, 165, 94, 166, 147, 82, 147, - 132, 72, 132, 115, 61, 115, 98, 49, 99, 82, 36, 82, 64, 19, 64, - 42, 0, 41, 0, 0, 0, 167, 93, 150, 150, 83, 134, 133, 73, 120, - 116, 62, 104, 99, 49, 88, 82, 36, 72, 64, 20, 55, 41, 0, 33, - 0, 0, 0, 169, 93, 137, 150, 83, 122, 134, 73, 109, 116, 61, 94, - 99, 50, 80, 82, 37, 65, 64, 21, 49, 41, 0, 27, 0, 0, 0, - 169, 94, 123, 150, 83, 110, 133, 73, 97, 116, 61, 83, 99, 50, 70, - 82, 38, 57, 63, 23, 42, 41, 0, 20, 0, 0, 0, 169, 94, 109, - 150, 84, 97, 134, 73, 85, 116, 62, 73, 99, 51, 61, 81, 38, 48, - 63, 23, 33, 41, 1, 11, 0, 0, 0, 170, 94, 96, 150, 83, 84, - 134, 73, 74, 116, 61, 62, 99, 50, 51, 82, 38, 39, 64, 23, 24, - 40, 3, 4, 0, 0, 0, 171, 93, 79, 152, 82, 70, 135, 73, 61, - 116, 62, 51, 98, 51, 40, 81, 38, 28, 63, 24, 14, 39, 4, 0, - 0, 0, 0, 171, 94, 64, 152, 83, 55, 135, 73, 47, 116, 62, 37, - 98, 50, 27, 81, 38, 15, 63, 24, 1, 39, 4, 0, 0, 0, 0, - 172, 93, 51, 153, 82, 42, 135, 73, 35, 117, 62, 26, 99, 51, 16, - 81, 39, 3, 63, 25, 0, 38, 5, 0, 0, 0, 0, 166, 68, 153, - 148, 59, 137, 133, 49, 121, 115, 39, 106, 99, 28, 91, 82, 13, 75, - 65, 0, 58, 42, 0, 36, 0, 0, 0, 168, 68, 139, 150, 59, 124, - 134, 50, 110, 116, 40, 96, 99, 30, 81, 82, 16, 66, 64, 0, 50, - 41, 0, 29, 0, 0, 0, 169, 69, 126, 150, 59, 113, 134, 51, 101, - 117, 42, 87, 100, 30, 73, 82, 17, 59, 65, 0, 43, 41, 0, 23, - 0, 0, 0, 169, 70, 115, 150, 61, 102, 134, 52, 89, 116, 42, 77, - 99, 32, 65, 82, 19, 52, 64, 0, 36, 41, 0, 15, 0, 0, 0, - 169, 70, 101, 150, 61, 90, 134, 52, 79, 116, 43, 68, 99, 32, 55, - 82, 21, 43, 64, 2, 28, 41, 0, 6, 0, 0, 0, 170, 70, 89, - 151, 62, 79, 134, 53, 69, 116, 44, 58, 99, 33, 46, 81, 21, 34, - 64, 3, 20, 41, 0, 2, 0, 0, 0, 170, 71, 76, 152, 62, 66, - 134, 53, 57, 116, 43, 46, 99, 33, 36, 82, 22, 24, 64, 5, 10, - 40, 0, 0, 0, 0, 0, 171, 70, 61, 152, 62, 52, 135, 53, 44, - 116, 44, 35, 99, 34, 24, 82, 22, 12, 63, 6, 0, 39, 0, 0, - 0, 0, 0, 171, 71, 49, 153, 62, 41, 135, 54, 33, 117, 45, 25, - 98, 34, 13, 81, 23, 0, 63, 7, 0, 39, 0, 0, 0, 0, 0, - 167, 33, 142, 149, 24, 127, 134, 10, 113, 116, 0, 97, 100, 0, 83, - 83, 0, 68, 65, 0, 52, 40, 0, 30, 0, 0, 0, 169, 33, 129, - 150, 26, 115, 134, 17, 102, 116, 3, 89, 100, 0, 75, 83, 0, 60, - 65, 0, 45, 40, 0, 24, 0, 0, 0, 169, 36, 118, 151, 27, 104, - 134, 19, 93, 116, 7, 80, 100, 0, 67, 83, 0, 54, 65, 0, 38, - 41, 0, 17, 0, 0, 0, 169, 39, 107, 150, 30, 94, 134, 22, 84, - 116, 11, 71, 99, 0, 59, 83, 0, 46, 64, 0, 31, 40, 0, 9, - 0, 0, 0, 169, 39, 95, 151, 31, 83, 134, 24, 73, 116, 15, 62, - 100, 1, 51, 83, 0, 38, 64, 0, 24, 40, 0, 5, 0, 0, 0, - 169, 41, 83, 151, 33, 73, 134, 26, 64, 117, 17, 54, 99, 4, 42, - 82, 0, 30, 64, 0, 16, 40, 0, 1, 0, 0, 0, 170, 42, 71, - 152, 34, 62, 134, 28, 53, 117, 19, 44, 99, 6, 33, 82, 0, 21, - 63, 0, 4, 39, 0, 0, 0, 0, 0, 171, 42, 59, 152, 35, 50, - 134, 29, 42, 117, 21, 32, 99, 9, 22, 82, 0, 9, 63, 0, 0, - 38, 0, 0, 0, 0, 0, 172, 42, 48, 152, 36, 40, 135, 29, 32, - 117, 21, 23, 99, 10, 12, 82, 0, 0, 63, 0, 0, 38, 0, 0, - 0, 0, 0, 107, 207, 246, 96, 185, 220, 86, 165, 196, 73, 144, 171, - 60, 123, 147, 46, 103, 125, 32, 82, 100, 9, 56, 71, 0, 20, 33, - 115, 206, 221, 104, 184, 198, 92, 164, 178, 78, 143, 154, 64, 123, 133, - 51, 102, 111, 34, 81, 89, 10, 56, 63, 0, 20, 27, 122, 204, 200, - 108, 183, 180, 95, 163, 161, 82, 142, 140, 68, 122, 120, 54, 102, 101, - 36, 81, 79, 11, 56, 55, 0, 20, 20, 125, 203, 179, 111, 181, 160, - 97, 162, 143, 85, 141, 124, 70, 121, 107, 55, 101, 89, 38, 80, 69, - 14, 55, 46, 0, 19, 10, 128, 202, 156, 113, 180, 140, 102, 161, 125, - 87, 140, 108, 71, 120, 92, 56, 100, 76, 39, 79, 59, 14, 55, 38, - 0, 20, 3, 132, 200, 135, 117, 179, 121, 103, 159, 106, 88, 139, 93, - 73, 119, 79, 57, 100, 65, 41, 79, 49, 15, 54, 28, 0, 19, 0, - 134, 200, 111, 119, 178, 98, 105, 158, 87, 89, 138, 76, 74, 118, 64, - 58, 99, 51, 41, 78, 37, 16, 54, 17, 0, 19, 0, 137, 199, 85, - 122, 177, 75, 108, 158, 66, 91, 137, 56, 75, 118, 46, 59, 98, 35, - 42, 78, 22, 16, 54, 3, 0, 19, 0, 140, 198, 62, 125, 177, 55, - 109, 158, 47, 92, 137, 40, 76, 117, 32, 59, 98, 21, 42, 78, 6, - 16, 54, 0, 0, 18, 0, 118, 186, 231, 106, 167, 206, 93, 149, 184, - 81, 130, 161, 67, 111, 139, 54, 92, 117, 39, 72, 93, 17, 48, 66, - 0, 10, 29, 123, 185, 207, 110, 166, 186, 98, 148, 167, 85, 129, 145, - 71, 111, 125, 56, 92, 104, 40, 72, 83, 18, 48, 57, 0, 10, 22, - 128, 184, 188, 113, 165, 168, 102, 147, 151, 88, 128, 131, 73, 110, 113, - 58, 91, 94, 42, 71, 74, 19, 48, 50, 0, 9, 15, 131, 183, 168, - 116, 164, 151, 104, 146, 134, 89, 127, 117, 73, 109, 100, 58, 90, 83, - 42, 71, 65, 20, 48, 42, 0, 9, 5, 134, 182, 148, 120, 163, 131, - 105, 145, 118, 90, 126, 102, 75, 108, 86, 59, 90, 72, 43, 71, 55, - 19, 47, 34, 0, 9, 0, 136, 181, 128, 122, 162, 115, 107, 144, 102, - 92, 125, 87, 76, 107, 74, 61, 89, 60, 44, 70, 45, 20, 47, 24, - 0, 8, 0, 139, 180, 106, 124, 161, 95, 109, 144, 83, 93, 124, 71, - 77, 107, 60, 61, 89, 47, 44, 70, 33, 20, 47, 13, 0, 8, 0, - 142, 179, 82, 125, 160, 72, 111, 143, 63, 94, 124, 54, 77, 106, 44, - 61, 88, 32, 44, 69, 18, 20, 46, 0, 0, 8, 0, 143, 179, 62, - 127, 160, 54, 111, 142, 47, 94, 124, 39, 78, 106, 29, 62, 88, 18, - 45, 69, 3, 20, 46, 0, 0, 8, 0, 124, 167, 216, 112, 150, 194, - 99, 134, 174, 87, 117, 153, 73, 100, 131, 58, 82, 110, 43, 64, 88, - 23, 40, 61, 0, 0, 24, 129, 166, 195, 116, 150, 175, 103, 134, 158, - 89, 116, 137, 75, 99, 118, 60, 82, 98, 44, 63, 78, 23, 40, 53, - 0, 0, 17, 132, 166, 177, 119, 149, 160, 106, 133, 143, 90, 115, 124, - 76, 99, 107, 61, 81, 88, 45, 63, 69, 24, 40, 46, 0, 0, 9, - 136, 166, 159, 121, 148, 143, 107, 132, 126, 92, 115, 111, 77, 98, 94, - 62, 81, 78, 46, 63, 60, 23, 40, 38, 0, 0, 0, 138, 164, 140, - 122, 147, 125, 108, 131, 111, 93, 114, 97, 79, 98, 82, 63, 80, 67, - 46, 62, 50, 24, 40, 29, 0, 0, 0, 139, 163, 122, 124, 146, 109, - 110, 131, 96, 94, 114, 83, 79, 97, 70, 63, 81, 57, 46, 62, 41, - 24, 40, 21, 0, 0, 0, 141, 163, 101, 126, 145, 90, 111, 130, 79, - 95, 113, 68, 79, 96, 56, 63, 80, 44, 47, 62, 30, 23, 40, 10, - 0, 0, 0, 144, 162, 79, 127, 145, 70, 112, 129, 60, 95, 112, 51, - 79, 96, 41, 64, 79, 30, 47, 61, 15, 23, 40, 0, 0, 0, 0, - 145, 162, 60, 129, 145, 52, 113, 129, 46, 96, 112, 37, 79, 95, 27, - 64, 79, 16, 47, 61, 1, 23, 39, 0, 0, 0, 0, 131, 147, 202, - 117, 133, 181, 105, 119, 162, 91, 103, 142, 77, 87, 122, 62, 71, 102, - 47, 54, 81, 26, 31, 56, 0, 0, 18, 135, 147, 183, 120, 132, 164, - 107, 118, 147, 93, 102, 128, 78, 87, 110, 63, 71, 92, 47, 54, 72, - 26, 31, 48, 0, 0, 10, 138, 147, 166, 123, 131, 149, 108, 118, 133, - 94, 102, 116, 79, 86, 100, 64, 71, 82, 48, 54, 64, 27, 31, 41, - 0, 0, 2, 139, 146, 149, 124, 131, 134, 111, 117, 119, 94, 101, 103, - 79, 86, 88, 64, 70, 72, 48, 53, 55, 27, 31, 33, 0, 0, 0, - 141, 146, 132, 125, 131, 117, 111, 117, 104, 95, 101, 91, 80, 86, 77, - 65, 70, 62, 48, 53, 46, 26, 31, 25, 0, 0, 0, 143, 145, 115, - 126, 130, 101, 112, 116, 90, 96, 100, 78, 80, 85, 65, 65, 70, 52, - 49, 53, 37, 27, 32, 17, 0, 0, 0, 144, 144, 96, 128, 129, 85, - 112, 115, 75, 97, 100, 64, 81, 85, 52, 65, 69, 40, 49, 53, 26, - 26, 31, 5, 0, 0, 0, 146, 144, 76, 129, 129, 67, 114, 115, 58, - 97, 99, 48, 82, 84, 38, 66, 69, 27, 49, 53, 12, 26, 32, 0, - 0, 0, 0, 146, 144, 59, 130, 128, 51, 114, 114, 43, 98, 99, 35, - 82, 84, 25, 66, 69, 13, 49, 53, 0, 26, 32, 0, 0, 0, 0, - 135, 129, 189, 122, 115, 170, 107, 103, 152, 94, 89, 133, 79, 74, 114, - 64, 60, 95, 49, 43, 75, 29, 20, 51, 0, 0, 12, 138, 129, 171, - 124, 115, 153, 110, 103, 138, 95, 89, 120, 81, 74, 103, 66, 60, 86, - 50, 44, 67, 28, 21, 43, 0, 0, 3, 140, 129, 156, 125, 115, 140, - 111, 103, 125, 96, 89, 109, 81, 74, 93, 67, 60, 76, 50, 44, 59, - 29, 22, 36, 0, 0, 0, 142, 128, 140, 127, 115, 125, 112, 102, 112, - 97, 88, 97, 82, 74, 83, 67, 60, 67, 50, 44, 51, 29, 22, 29, - 0, 0, 0, 142, 128, 124, 127, 114, 111, 113, 102, 98, 98, 88, 85, - 82, 74, 71, 66, 60, 58, 50, 44, 42, 29, 22, 21, 0, 0, 0, - 144, 127, 108, 128, 114, 96, 113, 101, 85, 98, 87, 73, 82, 74, 61, - 67, 60, 48, 50, 44, 33, 28, 23, 12, 0, 0, 0, 145, 127, 91, - 129, 114, 81, 115, 101, 71, 98, 87, 60, 82, 73, 48, 67, 59, 37, - 50, 44, 22, 29, 23, 1, 0, 0, 0, 147, 127, 73, 130, 113, 63, - 115, 101, 55, 98, 87, 45, 83, 73, 35, 67, 59, 24, 50, 44, 10, - 28, 24, 0, 0, 0, 0, 147, 127, 58, 131, 113, 49, 115, 100, 42, - 99, 86, 33, 83, 73, 23, 67, 59, 10, 50, 44, 0, 27, 24, 0, - 0, 0, 0, 138, 110, 177, 124, 99, 159, 110, 88, 142, 96, 75, 125, - 82, 62, 107, 66, 48, 89, 51, 33, 70, 30, 8, 46, 0, 0, 5, - 142, 111, 160, 127, 99, 144, 113, 88, 130, 98, 75, 112, 82, 62, 96, - 68, 49, 80, 51, 33, 61, 30, 10, 39, 0, 0, 0, 143, 111, 146, - 128, 99, 131, 114, 88, 118, 98, 75, 101, 83, 62, 86, 68, 49, 71, - 52, 33, 54, 30, 11, 32, 0, 0, 0, 144, 111, 132, 128, 99, 118, - 113, 88, 106, 99, 75, 91, 83, 62, 77, 68, 49, 62, 52, 34, 46, - 30, 12, 25, 0, 0, 0, 144, 111, 117, 129, 98, 104, 114, 87, 92, - 99, 75, 80, 83, 62, 67, 68, 49, 53, 51, 34, 38, 30, 13, 18, - 0, 0, 0, 145, 111, 103, 130, 98, 91, 114, 87, 80, 99, 75, 68, - 83, 63, 57, 68, 50, 45, 51, 34, 30, 30, 14, 8, 0, 0, 0, - 146, 110, 87, 131, 98, 76, 115, 87, 67, 99, 75, 56, 83, 62, 45, - 68, 49, 33, 52, 35, 19, 30, 15, 2, 0, 0, 0, 148, 110, 70, - 131, 98, 60, 116, 86, 52, 99, 74, 43, 84, 62, 33, 69, 49, 21, - 52, 35, 6, 29, 15, 0, 0, 0, 0, 148, 110, 56, 132, 97, 48, - 117, 87, 40, 100, 75, 31, 84, 62, 22, 68, 49, 9, 51, 35, 0, - 28, 15, 0, 0, 0, 0, 142, 91, 166, 126, 80, 148, 113, 71, 132, - 98, 59, 115, 83, 47, 99, 69, 34, 82, 53, 17, 64, 32, 0, 41, - 0, 0, 0, 143, 91, 150, 128, 81, 135, 114, 71, 120, 99, 60, 104, - 85, 48, 89, 69, 35, 73, 53, 19, 56, 32, 0, 34, 0, 0, 0, - 145, 91, 137, 129, 81, 122, 115, 71, 109, 100, 60, 94, 85, 48, 81, - 69, 35, 65, 53, 19, 49, 32, 0, 28, 0, 0, 0, 146, 92, 124, - 130, 81, 110, 115, 71, 98, 100, 60, 84, 85, 49, 71, 69, 36, 57, - 53, 21, 42, 32, 0, 21, 0, 0, 0, 147, 91, 110, 130, 81, 97, - 115, 71, 86, 100, 60, 74, 84, 49, 62, 69, 36, 48, 53, 22, 34, - 32, 0, 13, 0, 0, 0, 147, 92, 97, 130, 81, 85, 116, 72, 76, - 100, 60, 63, 85, 49, 52, 69, 37, 40, 53, 22, 26, 31, 1, 5, - 0, 0, 0, 148, 92, 82, 131, 81, 71, 116, 71, 62, 100, 60, 53, - 84, 49, 42, 69, 37, 30, 52, 23, 16, 31, 2, 0, 0, 0, 0, - 148, 91, 67, 132, 81, 57, 117, 71, 49, 100, 60, 39, 84, 49, 30, - 69, 37, 18, 52, 23, 2, 30, 2, 0, 0, 0, 0, 149, 91, 54, - 132, 81, 46, 118, 71, 39, 101, 60, 29, 85, 49, 19, 69, 37, 6, - 52, 23, 0, 29, 3, 0, 0, 0, 0, 143, 68, 153, 128, 59, 137, - 115, 49, 122, 99, 39, 107, 85, 28, 91, 70, 13, 75, 54, 0, 58, - 32, 0, 36, 0, 0, 0, 146, 68, 140, 131, 59, 125, 116, 51, 111, - 100, 40, 97, 85, 29, 82, 70, 15, 67, 54, 0, 50, 32, 0, 29, - 0, 0, 0, 147, 68, 127, 131, 59, 114, 117, 51, 102, 101, 41, 88, - 86, 30, 74, 70, 17, 60, 54, 0, 44, 32, 0, 23, 0, 0, 0, - 147, 70, 115, 131, 60, 103, 116, 52, 91, 100, 42, 78, 85, 32, 65, - 70, 19, 53, 54, 1, 38, 32, 0, 17, 0, 0, 0, 147, 70, 103, - 131, 61, 91, 117, 53, 81, 101, 43, 69, 86, 32, 57, 70, 20, 44, - 54, 2, 30, 32, 0, 7, 0, 0, 0, 148, 70, 91, 132, 61, 80, - 117, 52, 70, 101, 43, 59, 85, 33, 48, 70, 21, 36, 53, 4, 22, - 32, 0, 3, 0, 0, 0, 148, 70, 78, 132, 62, 68, 117, 53, 58, - 101, 43, 48, 85, 34, 38, 70, 22, 26, 53, 6, 12, 31, 0, 0, - 0, 0, 0, 149, 71, 64, 132, 62, 54, 118, 54, 46, 101, 44, 37, - 85, 34, 27, 69, 23, 15, 53, 7, 1, 30, 0, 0, 0, 0, 0, - 150, 70, 53, 134, 61, 44, 118, 54, 36, 101, 44, 28, 85, 35, 17, - 69, 23, 4, 52, 8, 0, 30, 0, 0, 0, 0, 0, 145, 38, 143, - 130, 29, 128, 117, 18, 114, 101, 3, 98, 87, 0, 84, 72, 0, 69, - 54, 0, 53, 30, 0, 31, 0, 0, 0, 147, 38, 130, 132, 30, 116, - 117, 22, 103, 101, 8, 89, 87, 0, 76, 72, 0, 62, 54, 0, 46, - 30, 0, 24, 0, 0, 0, 148, 40, 119, 132, 31, 105, 117, 23, 94, - 101, 13, 81, 87, 0, 68, 71, 0, 55, 54, 0, 39, 30, 0, 18, - 0, 0, 0, 148, 42, 108, 132, 34, 96, 117, 25, 85, 102, 15, 73, - 86, 2, 60, 71, 0, 47, 54, 0, 33, 30, 0, 11, 0, 0, 0, - 148, 43, 96, 133, 35, 85, 117, 28, 75, 102, 18, 64, 87, 5, 52, - 71, 0, 40, 54, 0, 25, 30, 0, 5, 0, 0, 0, 149, 44, 85, - 132, 36, 75, 118, 29, 66, 101, 20, 55, 86, 8, 44, 70, 0, 32, - 53, 0, 18, 29, 0, 2, 0, 0, 0, 149, 45, 74, 133, 37, 64, - 118, 31, 55, 102, 21, 45, 85, 10, 34, 70, 0, 22, 53, 0, 6, - 28, 0, 0, 0, 0, 0, 150, 46, 61, 133, 39, 52, 118, 31, 44, - 102, 23, 34, 85, 12, 24, 70, 0, 12, 52, 0, 0, 28, 0, 0, - 0, 0, 0, 150, 46, 51, 133, 40, 42, 119, 32, 35, 102, 24, 25, - 85, 13, 14, 70, 0, 1, 52, 0, 0, 27, 0, 0, 0, 0, 0, - 53, 198, 244, 49, 177, 218, 41, 158, 195, 32, 138, 171, 22, 118, 147, - 11, 98, 124, 0, 78, 100, 0, 54, 71, 0, 18, 34, 69, 196, 220, - 64, 175, 196, 54, 157, 176, 45, 137, 154, 32, 117, 133, 19, 98, 111, - 0, 78, 89, 0, 53, 63, 0, 17, 27, 80, 195, 198, 69, 175, 179, - 60, 156, 159, 50, 136, 139, 38, 116, 120, 25, 98, 101, 4, 77, 80, - 0, 53, 55, 0, 17, 21, 84, 193, 177, 75, 173, 159, 64, 155, 142, - 55, 135, 124, 41, 116, 107, 27, 97, 89, 9, 76, 70, 0, 53, 47, - 0, 17, 11, 89, 193, 157, 79, 172, 140, 70, 154, 125, 57, 134, 109, - 44, 115, 92, 32, 96, 76, 13, 76, 59, 0, 52, 39, 0, 16, 4, - 94, 191, 135, 85, 171, 121, 72, 152, 108, 60, 133, 94, 47, 114, 80, - 32, 95, 65, 15, 76, 49, 0, 52, 29, 0, 16, 0, 98, 190, 113, - 87, 170, 100, 76, 152, 89, 62, 132, 77, 49, 113, 65, 35, 95, 52, - 18, 75, 37, 0, 52, 18, 0, 15, 0, 103, 190, 89, 90, 169, 80, - 78, 151, 70, 64, 132, 60, 51, 113, 49, 37, 94, 38, 20, 75, 25, - 0, 52, 5, 0, 15, 0, 106, 189, 69, 93, 169, 61, 80, 151, 53, - 66, 131, 45, 52, 113, 36, 37, 94, 25, 19, 74, 11, 0, 51, 0, - 0, 15, 0, 76, 178, 229, 68, 159, 205, 61, 142, 183, 50, 124, 160, - 40, 106, 138, 28, 88, 116, 12, 69, 93, 0, 45, 66, 0, 5, 29, - 86, 177, 207, 78, 158, 184, 67, 142, 166, 56, 123, 145, 45, 106, 125, - 31, 88, 105, 16, 69, 83, 0, 45, 58, 0, 6, 22, 93, 176, 187, - 81, 158, 168, 71, 141, 150, 61, 123, 131, 47, 105, 113, 35, 87, 94, - 20, 68, 74, 0, 45, 51, 0, 5, 16, 98, 175, 168, 84, 157, 150, - 75, 140, 134, 63, 122, 117, 50, 104, 100, 37, 87, 83, 21, 68, 65, - 0, 45, 42, 0, 4, 7, 100, 174, 149, 89, 155, 132, 76, 139, 117, - 65, 121, 102, 53, 104, 87, 39, 86, 72, 23, 67, 55, 0, 45, 34, - 0, 3, 0, 103, 173, 130, 92, 155, 115, 80, 138, 102, 68, 120, 88, - 53, 103, 75, 40, 86, 61, 24, 67, 45, 0, 45, 25, 0, 3, 0, - 107, 172, 108, 95, 154, 96, 82, 137, 85, 70, 119, 73, 55, 102, 61, - 42, 85, 49, 25, 67, 34, 0, 45, 14, 0, 3, 0, 110, 172, 86, - 97, 153, 76, 85, 137, 67, 70, 119, 57, 56, 102, 46, 42, 84, 35, - 26, 66, 21, 0, 44, 1, 0, 3, 0, 112, 171, 67, 98, 153, 59, - 86, 137, 52, 71, 119, 44, 58, 102, 34, 44, 85, 22, 27, 66, 7, - 0, 44, 0, 0, 3, 0, 90, 160, 215, 81, 144, 193, 70, 129, 173, - 61, 112, 151, 49, 95, 131, 37, 79, 109, 22, 61, 87, 0, 38, 61, - 0, 0, 25, 96, 160, 194, 86, 143, 174, 75, 128, 157, 65, 112, 137, - 53, 95, 117, 40, 78, 98, 25, 60, 78, 0, 38, 53, 0, 0, 17, - 100, 159, 177, 89, 143, 159, 79, 128, 143, 67, 111, 124, 55, 95, 107, - 42, 78, 89, 27, 60, 70, 2, 38, 46, 0, 0, 9, 104, 158, 159, - 92, 142, 143, 81, 127, 127, 69, 110, 110, 56, 94, 94, 43, 78, 78, - 28, 60, 60, 2, 38, 38, 0, 0, 1, 107, 157, 140, 94, 141, 125, - 82, 126, 112, 71, 110, 97, 59, 94, 82, 45, 77, 67, 29, 59, 51, - 4, 37, 30, 0, 0, 0, 110, 156, 122, 97, 140, 109, 85, 125, 97, - 72, 109, 83, 58, 93, 71, 45, 77, 57, 29, 60, 42, 5, 38, 22, - 0, 0, 0, 111, 156, 103, 99, 139, 91, 87, 125, 81, 73, 108, 69, - 60, 92, 58, 46, 77, 45, 30, 59, 31, 5, 38, 12, 0, 0, 0, - 115, 156, 82, 101, 140, 73, 88, 124, 63, 74, 108, 53, 60, 92, 44, - 46, 76, 32, 31, 59, 18, 6, 37, 0, 0, 0, 0, 116, 155, 65, - 102, 139, 58, 89, 124, 49, 75, 108, 41, 61, 92, 32, 48, 76, 21, - 31, 59, 6, 5, 37, 0, 0, 0, 0, 100, 141, 201, 88, 127, 181, - 79, 114, 162, 69, 99, 142, 57, 83, 122, 44, 68, 102, 30, 51, 81, - 7, 28, 56, 0, 0, 19, 105, 141, 182, 94, 127, 163, 83, 114, 146, - 71, 98, 128, 59, 83, 110, 46, 68, 91, 31, 51, 72, 10, 28, 48, - 0, 0, 11, 108, 141, 166, 96, 127, 149, 85, 113, 133, 73, 98, 116, - 60, 83, 99, 46, 68, 82, 32, 51, 64, 11, 29, 41, 0, 0, 2, - 111, 141, 149, 98, 126, 134, 88, 112, 119, 74, 97, 103, 61, 83, 88, - 48, 67, 72, 33, 51, 56, 11, 29, 34, 0, 0, 0, 112, 140, 132, - 100, 125, 118, 89, 112, 105, 75, 97, 91, 62, 82, 77, 49, 68, 62, - 33, 51, 47, 12, 29, 26, 0, 0, 0, 115, 140, 116, 102, 125, 103, - 90, 111, 91, 76, 96, 78, 62, 82, 65, 49, 67, 52, 34, 51, 38, - 13, 29, 18, 0, 0, 0, 117, 139, 97, 103, 124, 87, 91, 111, 77, - 78, 96, 65, 63, 81, 54, 49, 67, 41, 34, 51, 27, 12, 29, 7, - 0, 0, 0, 119, 138, 78, 105, 124, 69, 92, 110, 60, 78, 95, 50, - 65, 81, 40, 50, 67, 29, 34, 51, 15, 13, 30, 0, 0, 0, 0, - 120, 138, 64, 106, 124, 54, 93, 110, 47, 78, 95, 38, 65, 81, 29, - 50, 66, 17, 34, 50, 2, 13, 29, 0, 0, 0, 0, 107, 124, 189, - 96, 111, 169, 85, 99, 152, 73, 85, 132, 61, 71, 114, 48, 57, 95, - 34, 41, 75, 14, 18, 51, 0, 0, 13, 111, 124, 171, 100, 111, 153, - 88, 99, 137, 75, 85, 120, 63, 72, 103, 50, 58, 85, 36, 41, 66, - 15, 19, 43, 0, 0, 4, 113, 124, 156, 101, 111, 139, 90, 99, 125, - 77, 85, 109, 64, 71, 93, 51, 57, 77, 36, 42, 59, 17, 20, 37, - 0, 0, 0, 115, 124, 140, 103, 111, 125, 90, 99, 112, 78, 85, 97, - 64, 71, 82, 52, 57, 67, 36, 42, 50, 16, 20, 30, 0, 0, 0, - 117, 123, 125, 104, 110, 111, 92, 98, 99, 79, 85, 86, 65, 71, 72, - 51, 58, 59, 37, 42, 43, 17, 21, 22, 0, 0, 0, 118, 123, 110, - 105, 110, 97, 93, 98, 86, 78, 84, 74, 66, 71, 62, 52, 57, 49, - 37, 42, 34, 17, 22, 14, 0, 0, 0, 120, 123, 93, 106, 109, 82, - 94, 97, 72, 80, 84, 61, 66, 71, 50, 52, 57, 38, 37, 42, 24, - 17, 22, 2, 0, 0, 0, 121, 122, 75, 108, 109, 66, 95, 97, 58, - 80, 84, 48, 66, 71, 37, 52, 57, 26, 37, 42, 12, 16, 22, 0, - 0, 0, 0, 122, 123, 62, 108, 109, 52, 95, 97, 45, 81, 84, 36, - 67, 70, 26, 52, 57, 14, 37, 42, 0, 15, 22, 0, 0, 0, 0, - 113, 107, 177, 102, 96, 159, 89, 85, 141, 78, 72, 124, 65, 60, 107, - 52, 46, 89, 37, 30, 70, 18, 5, 46, 0, 0, 6, 116, 107, 160, - 104, 96, 144, 92, 85, 129, 80, 72, 112, 67, 60, 96, 53, 47, 80, - 38, 31, 62, 19, 7, 39, 0, 0, 0, 118, 107, 147, 105, 96, 131, - 93, 85, 118, 80, 72, 101, 67, 60, 87, 54, 47, 71, 39, 31, 54, - 19, 8, 32, 0, 0, 0, 119, 107, 132, 106, 96, 118, 94, 85, 106, - 81, 73, 91, 67, 60, 77, 54, 47, 63, 39, 32, 47, 20, 9, 25, - 0, 0, 0, 119, 107, 118, 106, 95, 105, 94, 85, 93, 81, 72, 80, - 68, 60, 68, 54, 47, 54, 39, 32, 39, 20, 11, 18, 0, 0, 0, - 121, 107, 104, 107, 96, 92, 95, 84, 80, 81, 72, 69, 68, 61, 58, - 54, 48, 46, 39, 33, 31, 20, 12, 9, 0, 0, 0, 123, 107, 88, - 108, 95, 77, 96, 84, 68, 82, 72, 57, 68, 60, 46, 54, 47, 35, - 39, 33, 20, 19, 13, 2, 0, 0, 0, 123, 106, 72, 110, 95, 63, - 96, 84, 54, 82, 72, 45, 69, 60, 35, 55, 48, 23, 39, 33, 9, - 18, 14, 0, 0, 0, 0, 125, 106, 60, 110, 94, 50, 98, 84, 42, - 83, 72, 34, 69, 60, 25, 55, 48, 12, 39, 33, 0, 17, 13, 0, - 0, 0, 0, 118, 89, 165, 105, 79, 148, 93, 69, 132, 81, 57, 115, - 68, 45, 99, 55, 32, 82, 41, 15, 64, 21, 0, 41, 0, 0, 0, - 120, 89, 150, 107, 79, 135, 96, 69, 121, 82, 58, 105, 70, 46, 89, - 56, 34, 73, 41, 17, 56, 21, 0, 34, 0, 0, 0, 121, 89, 137, - 108, 79, 123, 96, 69, 109, 82, 58, 95, 70, 47, 81, 56, 34, 66, - 41, 18, 49, 21, 0, 28, 0, 0, 0, 122, 90, 124, 109, 79, 110, - 96, 69, 99, 83, 58, 85, 70, 47, 72, 56, 35, 58, 41, 19, 42, - 21, 0, 22, 0, 0, 0, 123, 90, 111, 110, 79, 98, 97, 69, 87, - 83, 59, 75, 70, 47, 63, 56, 35, 50, 41, 20, 35, 21, 0, 14, - 0, 0, 0, 123, 90, 98, 110, 79, 87, 97, 70, 76, 84, 58, 64, - 70, 48, 53, 56, 36, 41, 40, 21, 26, 21, 0, 5, 0, 0, 0, - 125, 89, 84, 111, 79, 73, 97, 69, 64, 84, 59, 54, 70, 48, 43, - 56, 36, 31, 40, 22, 17, 20, 1, 1, 0, 0, 0, 125, 89, 69, - 112, 79, 60, 98, 70, 51, 84, 59, 42, 70, 48, 32, 56, 36, 20, - 41, 22, 5, 19, 2, 0, 0, 0, 0, 126, 89, 57, 112, 79, 49, - 99, 70, 41, 84, 59, 32, 70, 48, 22, 56, 36, 10, 40, 22, 0, - 18, 2, 0, 0, 0, 0, 121, 67, 154, 108, 58, 138, 97, 50, 124, - 84, 39, 107, 71, 28, 92, 58, 12, 76, 43, 0, 59, 20, 0, 37, - 0, 0, 0, 124, 68, 140, 111, 59, 126, 98, 50, 112, 84, 40, 98, - 71, 29, 83, 58, 15, 67, 42, 0, 51, 20, 0, 30, 0, 0, 0, - 124, 68, 129, 111, 59, 114, 99, 51, 102, 86, 41, 88, 71, 30, 75, - 58, 17, 60, 42, 0, 45, 20, 0, 24, 0, 0, 0, 125, 70, 116, - 111, 60, 103, 99, 51, 92, 85, 41, 79, 71, 31, 66, 58, 19, 53, - 42, 3, 38, 20, 0, 17, 0, 0, 0, 125, 70, 104, 111, 61, 93, - 99, 52, 81, 85, 43, 69, 72, 32, 58, 58, 20, 45, 42, 4, 31, - 20, 0, 8, 0, 0, 0, 126, 70, 92, 111, 61, 81, 99, 52, 71, - 85, 42, 60, 71, 33, 49, 57, 21, 37, 42, 6, 23, 20, 0, 3, - 0, 0, 0, 126, 70, 79, 112, 61, 70, 99, 53, 60, 85, 43, 50, - 71, 33, 39, 57, 22, 28, 41, 7, 13, 19, 0, 0, 0, 0, 0, - 127, 71, 66, 113, 62, 56, 100, 53, 48, 86, 44, 39, 71, 34, 29, - 57, 23, 18, 41, 8, 2, 18, 0, 0, 0, 0, 0, 128, 70, 55, - 114, 62, 46, 100, 54, 39, 86, 44, 30, 71, 34, 20, 57, 23, 7, - 41, 9, 0, 18, 0, 0, 0, 0, 0, 124, 41, 145, 111, 32, 128, - 99, 23, 114, 86, 10, 100, 73, 0, 85, 60, 0, 71, 43, 0, 54, - 17, 0, 32, 0, 0, 0, 126, 42, 131, 113, 33, 117, 100, 25, 104, - 86, 14, 90, 73, 0, 77, 60, 0, 63, 44, 0, 47, 18, 0, 25, - 0, 0, 0, 127, 43, 120, 113, 34, 106, 101, 26, 95, 86, 17, 82, - 73, 2, 69, 59, 0, 56, 43, 0, 41, 18, 0, 19, 0, 0, 0, - 127, 45, 109, 113, 37, 97, 101, 28, 85, 86, 19, 74, 73, 5, 61, - 59, 0, 48, 43, 0, 34, 19, 0, 11, 0, 0, 0, 127, 46, 98, - 114, 38, 86, 100, 30, 76, 87, 21, 65, 73, 9, 54, 59, 0, 41, - 43, 0, 26, 18, 0, 5, 0, 0, 0, 127, 47, 87, 113, 39, 76, - 101, 31, 67, 86, 22, 56, 72, 11, 45, 59, 0, 33, 43, 0, 19, - 18, 0, 2, 0, 0, 0, 128, 48, 75, 114, 39, 65, 101, 33, 56, - 86, 23, 46, 72, 12, 36, 58, 0, 24, 42, 0, 9, 17, 0, 0, - 0, 0, 0, 129, 48, 63, 114, 41, 54, 102, 33, 46, 87, 24, 36, - 72, 14, 26, 58, 1, 14, 42, 0, 2, 16, 0, 0, 0, 0, 0, - 128, 48, 53, 114, 41, 44, 102, 34, 37, 87, 25, 27, 72, 15, 17, - 58, 1, 3, 41, 0, 0, 15, 0, 0, 0, 0, 0, 0, 189, 242, - 0, 169, 217, 0, 151, 194, 0, 132, 170, 0, 113, 147, 0, 94, 123, - 0, 74, 99, 0, 51, 71, 0, 15, 34, 1, 187, 219, 1, 167, 195, - 0, 150, 175, 0, 131, 153, 0, 113, 132, 0, 94, 111, 0, 74, 89, - 0, 50, 63, 0, 13, 28, 1, 186, 198, 1, 167, 178, 0, 149, 158, - 0, 130, 139, 0, 111, 119, 0, 93, 100, 0, 74, 80, 0, 50, 55, - 0, 13, 22, 1, 185, 176, 1, 165, 159, 1, 148, 142, 0, 129, 123, - 0, 111, 106, 0, 93, 89, 0, 73, 70, 0, 50, 47, 0, 13, 13, - 1, 184, 157, 1, 164, 141, 1, 147, 125, 0, 128, 110, 0, 110, 93, - 0, 92, 77, 0, 73, 60, 0, 50, 39, 0, 12, 5, 25, 182, 137, - 25, 163, 122, 17, 146, 109, 0, 128, 96, 0, 110, 81, 0, 92, 66, - 0, 73, 51, 0, 50, 30, 0, 10, 0, 42, 181, 114, 35, 163, 102, - 30, 145, 91, 14, 127, 80, 0, 109, 67, 0, 91, 53, 0, 72, 39, - 0, 50, 19, 0, 10, 0, 52, 181, 92, 43, 162, 83, 32, 145, 73, - 19, 126, 63, 0, 108, 52, 0, 90, 40, 0, 72, 27, 0, 50, 7, - 0, 10, 0, 57, 181, 74, 48, 162, 66, 37, 144, 57, 24, 126, 49, - 7, 108, 40, 0, 90, 29, 0, 72, 15, 0, 49, 0, 0, 10, 0, - 1, 170, 227, 1, 152, 203, 0, 136, 182, 0, 119, 159, 0, 101, 137, - 0, 84, 115, 0, 65, 92, 0, 43, 66, 0, 1, 29, 1, 169, 206, - 1, 151, 184, 1, 136, 165, 0, 118, 144, 0, 102, 125, 0, 84, 105, - 0, 65, 83, 0, 43, 58, 0, 0, 22, 29, 168, 186, 21, 151, 167, - 14, 135, 150, 4, 118, 131, 0, 101, 112, 0, 83, 94, 0, 65, 75, - 0, 43, 51, 0, 0, 16, 41, 167, 167, 33, 150, 150, 31, 134, 134, - 19, 117, 117, 4, 100, 100, 0, 83, 83, 0, 65, 65, 0, 42, 43, - 0, 0, 8, 48, 167, 149, 41, 149, 133, 33, 133, 118, 25, 116, 103, - 13, 99, 88, 0, 83, 73, 0, 65, 56, 0, 42, 35, 0, 0, 0, - 58, 165, 130, 49, 148, 115, 42, 132, 103, 31, 115, 89, 18, 99, 75, - 0, 82, 61, 0, 64, 46, 0, 42, 26, 0, 0, 0, 62, 164, 110, - 55, 147, 97, 45, 132, 87, 35, 115, 75, 22, 98, 63, 5, 82, 50, - 0, 64, 36, 0, 42, 16, 0, 0, 0, 69, 164, 89, 60, 147, 78, - 50, 131, 70, 37, 114, 59, 26, 98, 49, 10, 81, 37, 0, 64, 24, - 0, 42, 4, 0, 0, 0, 71, 164, 71, 63, 147, 63, 53, 131, 55, - 40, 114, 47, 28, 98, 38, 13, 81, 26, 0, 64, 12, 0, 42, 0, - 0, 0, 0, 28, 153, 214, 24, 138, 193, 23, 123, 171, 16, 107, 150, - 0, 91, 130, 0, 75, 109, 0, 58, 87, 0, 35, 61, 0, 0, 25, - 48, 153, 194, 41, 138, 174, 34, 123, 156, 27, 107, 136, 16, 91, 117, - 1, 75, 98, 0, 57, 78, 0, 35, 53, 0, 0, 17, 55, 153, 177, - 47, 137, 158, 42, 122, 142, 33, 107, 124, 22, 91, 106, 6, 75, 88, - 0, 57, 70, 0, 35, 46, 0, 0, 9, 61, 152, 158, 53, 136, 143, - 45, 122, 127, 36, 106, 111, 24, 90, 94, 10, 74, 78, 0, 57, 61, - 0, 35, 39, 0, 0, 2, 67, 151, 141, 59, 135, 126, 49, 121, 112, - 39, 105, 98, 29, 90, 83, 14, 74, 68, 0, 57, 52, 0, 35, 31, - 0, 0, 0, 71, 150, 123, 62, 135, 110, 54, 120, 98, 42, 105, 84, - 31, 89, 71, 16, 74, 58, 0, 57, 43, 0, 35, 22, 0, 0, 0, - 74, 150, 105, 64, 134, 92, 55, 120, 83, 45, 104, 71, 34, 89, 59, - 20, 73, 47, 0, 57, 32, 0, 35, 13, 0, 0, 0, 78, 149, 84, - 69, 134, 75, 59, 120, 66, 47, 103, 56, 34, 88, 46, 22, 73, 34, - 1, 57, 20, 0, 35, 1, 0, 0, 0, 80, 149, 69, 70, 133, 61, - 60, 119, 53, 49, 103, 44, 36, 88, 35, 23, 73, 24, 2, 56, 10, - 0, 35, 0, 0, 0, 0, 58, 136, 200, 50, 122, 180, 45, 109, 162, - 38, 94, 141, 27, 80, 121, 15, 65, 102, 0, 48, 81, 0, 26, 56, - 0, 0, 19, 66, 136, 182, 59, 122, 163, 52, 109, 146, 42, 94, 128, - 32, 80, 109, 20, 65, 91, 2, 48, 72, 0, 26, 49, 0, 0, 11, - 70, 136, 165, 62, 122, 149, 55, 108, 133, 46, 94, 116, 35, 80, 99, - 21, 65, 82, 4, 49, 64, 0, 26, 41, 0, 0, 3, 76, 135, 149, - 66, 121, 133, 58, 108, 119, 48, 94, 103, 36, 79, 88, 23, 65, 73, - 7, 49, 56, 0, 27, 34, 0, 0, 0, 78, 135, 133, 69, 120, 118, - 60, 107, 106, 50, 93, 92, 39, 79, 77, 26, 65, 63, 8, 49, 47, - 0, 27, 26, 0, 0, 0, 82, 134, 117, 71, 120, 104, 62, 107, 92, - 51, 93, 79, 39, 78, 66, 27, 64, 53, 10, 48, 39, 0, 27, 18, - 0, 0, 0, 84, 134, 99, 73, 119, 87, 64, 106, 77, 53, 92, 66, - 42, 78, 55, 28, 64, 42, 11, 48, 29, 0, 28, 9, 0, 0, 0, - 87, 133, 81, 76, 119, 72, 66, 106, 62, 55, 92, 52, 43, 78, 42, - 29, 64, 31, 12, 48, 17, 0, 28, 0, 0, 0, 0, 88, 134, 67, - 77, 119, 58, 68, 106, 51, 56, 92, 42, 44, 78, 32, 30, 64, 20, - 12, 48, 6, 0, 28, 0, 0, 0, 0, 73, 120, 189, 64, 107, 168, - 57, 96, 151, 47, 82, 133, 38, 69, 114, 26, 55, 95, 11, 39, 75, - 0, 16, 51, 0, 0, 14, 78, 120, 171, 69, 107, 153, 62, 95, 137, - 51, 82, 119, 40, 69, 102, 29, 55, 85, 15, 39, 66, 0, 17, 44, - 0, 0, 4, 81, 120, 156, 71, 107, 140, 64, 95, 125, 53, 82, 109, - 42, 69, 93, 31, 55, 77, 16, 39, 59, 0, 18, 37, 0, 0, 0, - 85, 120, 141, 74, 107, 126, 65, 95, 112, 54, 82, 97, 43, 69, 82, - 32, 55, 67, 17, 39, 51, 0, 19, 30, 0, 0, 0, 86, 119, 126, - 76, 106, 112, 66, 95, 100, 56, 81, 85, 45, 69, 72, 33, 55, 59, - 18, 40, 43, 0, 19, 22, 0, 0, 0, 89, 119, 110, 78, 106, 98, - 69, 94, 87, 56, 81, 75, 46, 68, 62, 33, 55, 49, 18, 40, 35, - 0, 20, 15, 0, 0, 0, 89, 119, 95, 80, 106, 83, 70, 94, 73, - 58, 81, 63, 46, 68, 51, 34, 55, 39, 19, 40, 25, 0, 20, 4, - 0, 0, 0, 92, 118, 78, 82, 106, 68, 70, 93, 59, 59, 81, 49, - 47, 68, 39, 34, 55, 28, 19, 40, 14, 0, 20, 0, 0, 0, 0, - 93, 118, 65, 82, 105, 55, 72, 93, 48, 60, 81, 39, 47, 68, 29, - 34, 55, 18, 20, 40, 2, 0, 20, 0, 0, 0, 0, 83, 104, 177, - 74, 93, 159, 65, 82, 142, 56, 70, 124, 45, 57, 106, 33, 44, 89, - 20, 28, 70, 1, 4, 46, 0, 0, 8, 86, 104, 161, 78, 93, 145, - 68, 82, 128, 58, 70, 112, 48, 58, 96, 35, 45, 80, 21, 29, 62, - 1, 6, 40, 0, 0, 0, 89, 104, 147, 79, 93, 131, 69, 82, 118, - 59, 70, 102, 47, 58, 87, 36, 45, 72, 23, 29, 55, 3, 7, 33, - 0, 0, 0, 90, 104, 132, 80, 93, 119, 71, 82, 106, 60, 70, 91, - 48, 58, 77, 37, 45, 62, 23, 30, 47, 4, 7, 26, 0, 0, 0, - 92, 104, 118, 82, 93, 105, 72, 82, 93, 61, 69, 80, 50, 58, 68, - 37, 45, 55, 23, 30, 39, 4, 8, 18, 0, 0, 0, 94, 104, 105, - 82, 92, 93, 72, 82, 82, 61, 70, 70, 50, 58, 58, 38, 46, 46, - 23, 31, 31, 6, 10, 11, 0, 0, 0, 95, 104, 90, 84, 92, 79, - 74, 82, 70, 62, 70, 58, 50, 58, 48, 37, 46, 36, 23, 31, 22, - 4, 11, 3, 0, 0, 0, 96, 103, 74, 85, 92, 65, 75, 81, 56, - 63, 70, 47, 50, 58, 37, 38, 46, 25, 24, 31, 11, 3, 11, 0, - 0, 0, 0, 97, 103, 62, 86, 92, 53, 76, 81, 45, 63, 69, 36, - 51, 58, 27, 38, 46, 15, 23, 31, 0, 3, 11, 0, 0, 0, 0, - 90, 87, 165, 81, 77, 148, 72, 67, 132, 62, 55, 116, 50, 44, 99, - 39, 31, 82, 25, 14, 64, 1, 0, 42, 0, 0, 1, 93, 87, 150, - 83, 77, 135, 74, 67, 121, 63, 56, 105, 52, 45, 90, 40, 32, 74, - 25, 16, 57, 3, 0, 35, 0, 0, 0, 95, 87, 138, 85, 77, 123, - 75, 67, 109, 63, 57, 95, 53, 45, 81, 41, 33, 66, 26, 17, 50, - 4, 0, 28, 0, 0, 0, 95, 88, 124, 85, 77, 111, 75, 67, 99, - 63, 57, 86, 53, 45, 72, 41, 33, 58, 26, 18, 43, 5, 1, 22, - 0, 0, 0, 97, 88, 112, 87, 77, 100, 76, 68, 88, 64, 57, 76, - 53, 46, 63, 41, 34, 50, 26, 19, 35, 5, 2, 14, 0, 0, 0, - 99, 87, 99, 87, 78, 88, 76, 68, 77, 65, 57, 65, 53, 46, 54, - 41, 35, 42, 27, 20, 27, 6, 2, 5, 0, 0, 0, 100, 87, 85, - 88, 77, 75, 77, 68, 65, 65, 57, 54, 53, 46, 44, 41, 35, 32, - 27, 21, 19, 5, 3, 2, 0, 0, 0, 100, 88, 71, 89, 77, 61, - 78, 68, 53, 66, 57, 44, 53, 47, 33, 41, 35, 22, 27, 21, 7, - 5, 3, 0, 0, 0, 0, 101, 87, 60, 90, 77, 52, 79, 68, 44, - 66, 58, 34, 53, 47, 25, 41, 35, 13, 26, 22, 0, 5, 3, 0, - 0, 0, 0, 97, 67, 155, 86, 58, 138, 77, 50, 125, 66, 39, 108, - 55, 28, 92, 43, 12, 76, 29, 0, 59, 2, 0, 37, 0, 0, 0, - 99, 67, 141, 88, 59, 127, 78, 50, 113, 68, 40, 98, 56, 29, 83, - 44, 15, 68, 29, 0, 52, 3, 0, 30, 0, 0, 0, 100, 68, 129, - 89, 59, 115, 80, 51, 103, 68, 41, 89, 56, 30, 75, 44, 16, 61, - 30, 0, 45, 4, 0, 24, 0, 0, 0, 100, 69, 118, 90, 60, 104, - 80, 51, 92, 67, 41, 79, 56, 31, 66, 44, 18, 53, 29, 2, 38, - 4, 0, 18, 0, 0, 0, 101, 69, 104, 90, 61, 93, 79, 51, 82, - 67, 42, 70, 56, 32, 59, 44, 20, 46, 29, 4, 31, 6, 0, 9, - 0, 0, 0, 102, 69, 93, 90, 61, 83, 80, 52, 72, 68, 42, 61, - 56, 33, 50, 43, 20, 38, 29, 5, 23, 7, 0, 4, 0, 0, 0, - 102, 70, 80, 91, 61, 71, 80, 52, 61, 68, 43, 51, 56, 32, 40, - 44, 21, 29, 30, 6, 14, 7, 0, 0, 0, 0, 0, 103, 70, 68, - 92, 61, 58, 81, 53, 50, 69, 43, 41, 56, 34, 31, 43, 22, 19, - 29, 7, 3, 7, 0, 0, 0, 0, 0, 104, 70, 57, 92, 61, 48, - 82, 53, 40, 69, 43, 32, 56, 34, 22, 43, 23, 10, 29, 8, 0, - 6, 0, 0, 0, 0, 0, 101, 45, 145, 91, 35, 129, 80, 26, 116, - 69, 15, 101, 59, 0, 86, 46, 0, 71, 31, 0, 55, 0, 0, 33, - 0, 0, 0, 104, 44, 132, 92, 36, 118, 82, 28, 105, 71, 17, 91, - 58, 3, 77, 46, 0, 63, 31, 0, 48, 2, 0, 26, 0, 0, 0, - 104, 46, 121, 93, 37, 107, 82, 30, 96, 70, 20, 83, 58, 6, 70, - 46, 0, 57, 32, 0, 41, 4, 0, 20, 0, 0, 0, 104, 48, 110, - 93, 40, 98, 82, 31, 87, 70, 22, 74, 59, 9, 62, 45, 0, 49, - 31, 0, 35, 6, 0, 13, 0, 0, 0, 104, 48, 99, 92, 41, 88, - 82, 32, 77, 70, 23, 65, 58, 11, 54, 46, 0, 42, 32, 0, 27, - 7, 0, 5, 0, 0, 0, 105, 50, 88, 93, 41, 77, 82, 34, 68, - 71, 24, 57, 58, 13, 46, 45, 1, 35, 31, 0, 21, 7, 0, 2, - 0, 0, 0, 105, 50, 76, 94, 41, 66, 83, 34, 57, 71, 25, 47, - 58, 15, 37, 45, 2, 25, 32, 0, 11, 7, 0, 0, 0, 0, 0, - 106, 50, 64, 94, 42, 55, 83, 35, 47, 71, 26, 38, 58, 16, 27, - 45, 4, 17, 31, 0, 4, 7, 0, 0, 0, 0, 0, 106, 51, 54, - 95, 42, 45, 83, 35, 38, 71, 27, 30, 58, 16, 19, 45, 5, 7, - 30, 0, 0, 6, 0, 0, 0, 0, 0, 0, 181, 240, 0, 162, 216, - 0, 144, 193, 0, 126, 168, 0, 109, 146, 0, 91, 123, 0, 71, 98, - 0, 48, 71, 0, 9, 34, 0, 179, 218, 0, 161, 195, 0, 144, 174, - 0, 126, 153, 0, 108, 132, 0, 90, 110, 0, 71, 88, 0, 48, 63, - 0, 8, 29, 0, 178, 197, 0, 159, 177, 0, 143, 159, 0, 125, 139, - 0, 107, 119, 0, 90, 99, 0, 71, 79, 0, 48, 55, 0, 8, 22, - 0, 177, 177, 0, 158, 158, 0, 142, 141, 0, 124, 123, 0, 107, 106, - 0, 89, 88, 0, 71, 70, 0, 48, 47, 0, 8, 14, 0, 176, 157, - 0, 158, 141, 0, 141, 126, 0, 123, 109, 0, 106, 93, 0, 89, 78, - 0, 70, 60, 0, 47, 39, 0, 7, 5, 0, 175, 138, 0, 157, 123, - 0, 141, 110, 0, 123, 96, 0, 105, 81, 0, 88, 67, 0, 70, 51, - 0, 48, 30, 0, 6, 0, 0, 173, 115, 0, 155, 104, 0, 140, 92, - 0, 122, 80, 0, 105, 67, 0, 88, 55, 0, 69, 40, 0, 47, 20, - 0, 6, 0, 0, 173, 94, 0, 155, 85, 0, 139, 75, 0, 121, 64, - 0, 104, 53, 0, 88, 42, 0, 70, 28, 0, 47, 9, 0, 6, 0, - 0, 173, 76, 0, 155, 70, 0, 138, 61, 0, 122, 53, 0, 104, 44, - 0, 87, 32, 0, 69, 18, 0, 47, 0, 0, 6, 0, 0, 164, 226, - 0, 147, 203, 0, 131, 181, 0, 114, 158, 0, 97, 136, 0, 80, 115, - 0, 63, 92, 0, 40, 65, 0, 0, 30, 0, 162, 205, 0, 145, 184, - 0, 130, 164, 0, 114, 143, 0, 97, 124, 0, 81, 104, 0, 63, 83, - 0, 40, 58, 0, 0, 23, 0, 162, 187, 0, 145, 167, 0, 130, 150, - 0, 113, 131, 0, 96, 112, 0, 80, 93, 0, 62, 74, 0, 40, 50, - 0, 0, 16, 0, 160, 167, 0, 144, 150, 0, 129, 134, 0, 112, 116, - 0, 96, 100, 0, 80, 82, 0, 62, 65, 0, 40, 43, 0, 0, 7, - 0, 160, 148, 0, 143, 133, 0, 128, 118, 0, 111, 103, 0, 96, 88, - 0, 80, 73, 0, 62, 56, 0, 40, 35, 0, 0, 0, 0, 158, 130, - 0, 142, 117, 0, 127, 104, 0, 111, 89, 0, 95, 76, 0, 79, 62, - 0, 62, 46, 0, 40, 26, 0, 0, 0, 0, 158, 111, 0, 141, 99, - 0, 127, 88, 0, 111, 76, 0, 95, 63, 0, 79, 51, 0, 62, 37, - 0, 40, 18, 0, 0, 0, 0, 158, 91, 0, 141, 81, 0, 126, 72, - 0, 110, 62, 0, 94, 50, 0, 79, 39, 0, 62, 25, 0, 40, 5, - 0, 0, 0, 0, 157, 74, 0, 141, 66, 0, 126, 59, 0, 110, 49, - 0, 94, 40, 0, 78, 29, 0, 61, 15, 0, 40, 0, 0, 0, 0, - 0, 148, 214, 0, 133, 192, 0, 119, 171, 0, 103, 150, 0, 87, 129, - 0, 72, 108, 0, 55, 86, 0, 32, 61, 0, 0, 25, 0, 147, 193, - 0, 132, 173, 0, 118, 155, 0, 103, 136, 0, 87, 116, 0, 72, 98, - 0, 55, 78, 0, 32, 53, 0, 0, 17, 0, 147, 176, 0, 132, 158, - 0, 118, 142, 0, 102, 124, 0, 87, 106, 0, 72, 88, 0, 55, 69, - 0, 33, 46, 0, 0, 9, 0, 146, 159, 0, 131, 142, 0, 117, 127, - 0, 102, 111, 0, 87, 95, 0, 71, 79, 0, 55, 61, 0, 33, 39, - 0, 0, 2, 0, 145, 140, 0, 130, 126, 0, 117, 112, 0, 101, 98, - 0, 86, 83, 0, 71, 68, 0, 55, 52, 0, 33, 31, 0, 0, 0, - 0, 144, 124, 0, 130, 111, 0, 116, 99, 0, 101, 84, 0, 86, 72, - 0, 71, 59, 0, 55, 43, 0, 33, 23, 0, 0, 0, 0, 144, 106, - 0, 129, 94, 0, 115, 83, 0, 101, 72, 0, 85, 60, 0, 71, 48, - 0, 55, 34, 0, 33, 14, 0, 0, 0, 3, 143, 86, 0, 129, 77, - 0, 115, 68, 0, 100, 58, 0, 85, 48, 0, 70, 36, 0, 54, 22, - 0, 33, 3, 0, 0, 0, 18, 143, 72, 13, 128, 63, 0, 115, 57, - 0, 100, 47, 0, 85, 37, 0, 70, 26, 0, 54, 13, 0, 33, 0, - 0, 0, 0, 0, 132, 200, 0, 118, 179, 0, 105, 161, 0, 91, 140, - 0, 76, 121, 0, 62, 101, 0, 46, 81, 0, 24, 56, 0, 0, 19, - 0, 131, 182, 0, 118, 163, 0, 105, 146, 0, 91, 128, 0, 77, 110, - 0, 62, 91, 0, 46, 72, 0, 25, 48, 0, 0, 11, 0, 131, 165, - 0, 117, 149, 0, 104, 133, 0, 91, 116, 0, 77, 99, 0, 62, 82, - 0, 46, 64, 0, 25, 41, 0, 0, 4, 0, 131, 149, 0, 116, 134, - 0, 104, 119, 0, 91, 104, 0, 77, 89, 0, 62, 73, 0, 46, 56, - 0, 25, 34, 0, 0, 0, 10, 130, 133, 2, 116, 119, 0, 104, 106, - 0, 90, 91, 0, 76, 78, 0, 62, 64, 0, 46, 48, 0, 26, 27, - 0, 0, 0, 23, 130, 118, 20, 116, 104, 13, 103, 93, 3, 89, 79, - 0, 76, 67, 0, 62, 54, 0, 46, 39, 0, 26, 19, 0, 0, 0, - 33, 129, 101, 27, 115, 89, 19, 103, 79, 9, 89, 67, 0, 75, 56, - 0, 61, 43, 0, 46, 29, 0, 26, 10, 0, 0, 0, 41, 128, 83, - 35, 115, 73, 27, 102, 64, 15, 89, 55, 0, 76, 45, 0, 62, 33, - 0, 46, 18, 0, 26, 0, 0, 0, 0, 43, 129, 69, 38, 115, 61, - 30, 102, 54, 17, 89, 45, 2, 75, 34, 0, 61, 23, 0, 46, 9, - 0, 26, 0, 0, 0, 0, 1, 116, 188, 1, 104, 168, 0, 92, 151, - 0, 79, 132, 0, 66, 113, 0, 52, 94, 0, 36, 75, 0, 14, 52, - 0, 0, 14, 17, 116, 171, 16, 104, 153, 14, 92, 137, 8, 79, 119, - 0, 67, 102, 0, 53, 85, 0, 37, 67, 0, 16, 44, 0, 0, 4, - 31, 116, 155, 27, 104, 140, 21, 92, 125, 13, 79, 109, 3, 66, 93, - 0, 53, 77, 0, 37, 59, 0, 16, 38, 0, 0, 0, 37, 115, 141, - 30, 103, 126, 26, 92, 112, 16, 79, 98, 5, 66, 83, 0, 53, 67, - 0, 38, 51, 0, 17, 31, 0, 0, 0, 41, 115, 126, 37, 103, 112, - 31, 92, 100, 22, 79, 86, 10, 66, 72, 0, 53, 59, 0, 38, 44, - 0, 17, 23, 0, 0, 0, 48, 115, 111, 41, 102, 99, 34, 91, 88, - 24, 78, 76, 14, 66, 63, 0, 53, 50, 0, 38, 36, 0, 18, 15, - 0, 0, 0, 51, 115, 95, 46, 102, 85, 37, 91, 74, 26, 78, 63, - 16, 66, 52, 0, 53, 40, 0, 38, 26, 0, 18, 5, 0, 0, 0, - 55, 114, 80, 47, 102, 69, 40, 90, 60, 30, 78, 51, 19, 66, 41, - 3, 53, 29, 0, 38, 15, 0, 17, 0, 0, 0, 0, 56, 114, 66, - 50, 102, 58, 40, 91, 50, 32, 78, 41, 18, 66, 32, 4, 53, 21, - 0, 38, 5, 0, 17, 0, 0, 0, 0, 39, 102, 178, 37, 90, 159, - 30, 79, 142, 21, 68, 124, 14, 55, 106, 0, 42, 89, 0, 26, 70, - 0, 4, 46, 0, 0, 8, 48, 102, 161, 42, 90, 145, 35, 79, 128, - 26, 68, 112, 19, 55, 96, 3, 43, 79, 0, 27, 62, 0, 6, 40, - 0, 0, 0, 50, 102, 147, 44, 90, 132, 37, 79, 118, 30, 68, 102, - 20, 56, 87, 7, 43, 72, 0, 28, 55, 0, 6, 34, 0, 0, 0, - 53, 101, 133, 47, 90, 118, 41, 79, 106, 32, 68, 91, 21, 56, 78, - 9, 43, 63, 0, 28, 47, 0, 6, 26, 0, 0, 0, 57, 101, 119, - 50, 89, 106, 42, 79, 94, 34, 67, 81, 24, 56, 68, 9, 44, 55, - 0, 29, 40, 0, 6, 19, 0, 0, 0, 60, 100, 105, 50, 90, 94, - 45, 80, 83, 36, 68, 71, 24, 56, 59, 11, 44, 46, 0, 29, 32, - 0, 7, 12, 0, 0, 0, 63, 101, 91, 55, 90, 80, 46, 79, 70, - 37, 68, 59, 26, 56, 49, 12, 44, 37, 1, 29, 23, 0, 7, 3, - 0, 0, 0, 64, 101, 75, 56, 89, 67, 48, 79, 57, 37, 68, 48, - 27, 56, 37, 15, 44, 26, 0, 29, 12, 0, 7, 0, 0, 0, 0, - 66, 101, 64, 58, 89, 55, 49, 79, 47, 39, 68, 38, 27, 56, 29, - 14, 44, 18, 1, 30, 2, 0, 7, 0, 0, 0, 0, 57, 86, 165, - 51, 75, 148, 45, 65, 133, 38, 54, 116, 28, 43, 100, 16, 29, 83, - 0, 13, 64, 0, 0, 42, 0, 0, 3, 60, 86, 151, 55, 75, 135, - 47, 66, 121, 39, 55, 105, 30, 44, 90, 18, 31, 74, 3, 16, 57, - 0, 1, 35, 0, 0, 0, 62, 86, 139, 56, 75, 123, 49, 66, 110, - 40, 55, 95, 30, 44, 81, 19, 31, 66, 4, 17, 51, 0, 1, 29, - 0, 0, 0, 65, 86, 125, 56, 76, 112, 49, 66, 99, 39, 55, 86, - 31, 44, 72, 19, 32, 59, 5, 18, 44, 0, 1, 23, 0, 0, 0, - 67, 86, 113, 58, 75, 100, 51, 66, 88, 41, 56, 77, 31, 45, 64, - 20, 32, 51, 6, 18, 35, 0, 1, 14, 0, 0, 0, 69, 86, 99, - 61, 76, 88, 52, 66, 78, 43, 56, 66, 32, 45, 55, 20, 33, 42, - 7, 19, 27, 0, 1, 6, 0, 0, 0, 69, 86, 86, 61, 76, 75, - 53, 67, 66, 43, 56, 55, 33, 45, 45, 21, 34, 34, 8, 20, 20, - 0, 2, 2, 0, 0, 0, 71, 86, 72, 63, 75, 62, 54, 66, 55, - 45, 56, 45, 33, 45, 35, 22, 34, 23, 7, 20, 8, 0, 2, 0, - 0, 0, 0, 71, 86, 62, 64, 75, 53, 55, 66, 46, 45, 56, 36, - 33, 46, 27, 22, 34, 15, 8, 20, 0, 0, 2, 0, 0, 0, 0, - 69, 67, 156, 61, 58, 140, 53, 50, 125, 45, 39, 108, 35, 28, 93, - 25, 12, 77, 12, 0, 59, 0, 0, 37, 0, 0, 0, 71, 68, 142, - 63, 59, 126, 56, 50, 114, 47, 40, 98, 37, 28, 84, 26, 15, 68, - 12, 0, 53, 0, 0, 30, 0, 0, 0, 72, 68, 130, 63, 59, 116, - 56, 50, 104, 47, 40, 90, 38, 30, 75, 27, 16, 61, 13, 0, 46, - 0, 0, 24, 0, 0, 0, 73, 69, 118, 65, 59, 105, 57, 51, 92, - 47, 41, 80, 37, 30, 67, 26, 18, 53, 14, 1, 39, 0, 0, 18, - 0, 0, 0, 74, 69, 106, 65, 60, 93, 57, 51, 82, 48, 41, 70, - 38, 31, 59, 26, 19, 46, 13, 2, 32, 0, 0, 10, 0, 0, 0, - 76, 69, 95, 66, 61, 84, 58, 52, 73, 48, 42, 61, 37, 32, 50, - 26, 20, 38, 14, 4, 24, 0, 0, 4, 0, 0, 0, 76, 69, 81, - 68, 60, 72, 58, 52, 62, 48, 42, 51, 38, 32, 41, 27, 21, 30, - 14, 4, 16, 0, 0, 1, 0, 0, 0, 76, 69, 68, 68, 61, 60, - 60, 52, 51, 49, 43, 41, 38, 33, 32, 27, 21, 20, 14, 5, 5, - 0, 0, 0, 0, 0, 0, 78, 70, 59, 69, 61, 50, 60, 52, 42, - 49, 43, 34, 39, 33, 24, 27, 22, 13, 14, 7, 1, 0, 0, 0, - 0, 0, 0, 75, 46, 146, 68, 38, 131, 60, 30, 117, 50, 19, 102, - 41, 4, 87, 29, 0, 72, 13, 0, 55, 0, 0, 33, 0, 0, 0, - 78, 47, 132, 70, 39, 119, 61, 30, 105, 53, 20, 92, 42, 5, 78, - 30, 0, 64, 13, 0, 49, 0, 0, 27, 0, 0, 0, 79, 48, 122, - 70, 40, 108, 62, 32, 96, 52, 22, 84, 42, 9, 71, 30, 0, 58, - 14, 0, 42, 0, 0, 20, 0, 0, 0, 79, 50, 111, 70, 42, 99, - 62, 33, 88, 52, 23, 74, 41, 11, 63, 29, 0, 50, 14, 0, 36, - 0, 0, 14, 0, 0, 0, 80, 50, 99, 70, 42, 89, 61, 34, 78, - 52, 25, 67, 41, 14, 55, 30, 0, 42, 15, 0, 28, 0, 0, 6, - 0, 0, 0, 81, 51, 89, 71, 43, 78, 62, 35, 69, 52, 25, 58, - 42, 15, 47, 30, 3, 36, 15, 0, 22, 0, 0, 3, 0, 0, 0, - 81, 51, 77, 71, 44, 68, 63, 36, 59, 53, 26, 49, 41, 16, 38, - 31, 4, 27, 16, 0, 12, 0, 0, 0, 0, 0, 0, 81, 52, 65, - 72, 43, 56, 63, 36, 48, 53, 27, 39, 41, 17, 29, 30, 4, 18, - 14, 0, 3, 0, 0, 0, 0, 0, 0, 81, 52, 55, 73, 44, 47, - 64, 36, 39, 53, 28, 32, 42, 18, 21, 31, 6, 9, 14, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 174, 239, 0, 156, 214, 0, 139, 192, - 0, 121, 168, 0, 105, 145, 0, 87, 123, 0, 68, 98, 0, 46, 70, - 0, 3, 35, 0, 172, 217, 0, 155, 194, 0, 139, 173, 0, 121, 152, - 0, 104, 130, 0, 87, 110, 0, 69, 88, 0, 46, 63, 0, 4, 28, - 0, 171, 197, 0, 153, 175, 0, 138, 158, 0, 121, 139, 0, 103, 118, - 0, 86, 100, 0, 68, 79, 0, 46, 55, 0, 4, 22, 0, 170, 177, - 0, 152, 158, 0, 136, 141, 0, 119, 124, 0, 103, 106, 0, 86, 88, - 0, 68, 70, 0, 45, 47, 0, 3, 14, 0, 169, 157, 0, 152, 141, - 0, 136, 126, 0, 119, 109, 0, 102, 94, 0, 86, 78, 0, 68, 60, - 0, 46, 39, 0, 3, 5, 0, 167, 138, 0, 150, 124, 0, 135, 111, - 0, 118, 97, 0, 102, 82, 0, 85, 68, 0, 68, 52, 0, 46, 31, - 0, 3, 0, 0, 167, 118, 0, 150, 104, 0, 135, 94, 0, 118, 81, - 0, 101, 69, 0, 84, 56, 0, 67, 41, 0, 45, 21, 0, 3, 0, - 0, 166, 97, 0, 149, 87, 0, 134, 77, 0, 117, 67, 0, 101, 56, - 0, 85, 44, 0, 67, 30, 0, 45, 10, 0, 3, 0, 0, 165, 79, - 0, 149, 73, 0, 133, 64, 0, 117, 56, 0, 101, 46, 0, 85, 34, - 0, 68, 21, 0, 46, 1, 0, 3, 0, 0, 158, 225, 0, 141, 201, - 0, 126, 180, 0, 109, 158, 0, 94, 136, 0, 78, 114, 0, 60, 91, - 0, 38, 66, 0, 0, 30, 0, 156, 203, 0, 140, 183, 0, 125, 164, - 0, 109, 143, 0, 94, 124, 0, 78, 104, 0, 61, 83, 0, 38, 57, - 0, 0, 23, 0, 156, 186, 0, 140, 166, 0, 125, 150, 0, 109, 130, - 0, 93, 111, 0, 77, 93, 0, 60, 74, 0, 38, 50, 0, 0, 17, - 0, 155, 167, 0, 138, 149, 0, 124, 134, 0, 109, 117, 0, 93, 100, - 0, 76, 83, 0, 60, 65, 0, 38, 43, 0, 0, 9, 0, 153, 147, - 0, 138, 134, 0, 124, 120, 0, 107, 103, 0, 92, 88, 0, 77, 73, - 0, 60, 56, 0, 38, 35, 0, 0, 0, 0, 153, 131, 0, 137, 118, - 0, 122, 105, 0, 107, 90, 0, 91, 76, 0, 76, 63, 0, 60, 47, - 0, 39, 28, 0, 0, 0, 0, 153, 111, 0, 136, 100, 0, 123, 90, - 0, 107, 77, 0, 92, 65, 0, 76, 52, 0, 60, 37, 0, 38, 18, - 0, 0, 0, 0, 152, 93, 0, 136, 82, 0, 122, 74, 0, 106, 63, - 0, 91, 52, 0, 76, 40, 0, 59, 26, 0, 38, 6, 0, 0, 0, - 0, 151, 78, 0, 136, 69, 0, 121, 61, 0, 106, 52, 0, 91, 43, - 0, 76, 32, 0, 59, 17, 0, 38, 0, 0, 0, 0, 0, 143, 213, - 0, 128, 191, 0, 115, 171, 0, 100, 149, 0, 84, 128, 0, 69, 108, - 0, 52, 86, 0, 30, 61, 0, 0, 25, 0, 142, 193, 0, 127, 173, - 0, 114, 154, 0, 99, 134, 0, 84, 116, 0, 69, 98, 0, 52, 77, - 0, 31, 53, 0, 0, 18, 0, 141, 176, 0, 127, 158, 0, 114, 141, - 0, 98, 122, 0, 84, 105, 0, 69, 88, 0, 53, 69, 0, 31, 46, - 0, 0, 9, 0, 141, 159, 0, 126, 142, 0, 113, 127, 0, 98, 110, - 0, 83, 95, 0, 69, 78, 0, 53, 60, 0, 32, 39, 0, 0, 2, - 0, 140, 140, 0, 126, 126, 0, 112, 112, 0, 98, 98, 0, 83, 83, - 0, 68, 69, 0, 52, 52, 0, 31, 31, 0, 0, 0, 0, 140, 124, - 0, 125, 112, 0, 112, 100, 0, 97, 86, 0, 83, 72, 0, 68, 59, - 0, 52, 44, 0, 31, 23, 0, 0, 0, 0, 139, 106, 0, 125, 96, - 0, 111, 85, 0, 97, 72, 0, 83, 62, 0, 68, 49, 0, 52, 35, - 0, 31, 15, 0, 0, 0, 0, 138, 88, 0, 124, 79, 0, 111, 70, - 0, 96, 59, 0, 82, 48, 0, 68, 38, 0, 52, 24, 0, 31, 4, - 0, 0, 0, 0, 139, 76, 0, 124, 66, 0, 111, 58, 0, 96, 50, - 0, 82, 40, 0, 68, 29, 0, 52, 15, 0, 31, 0, 0, 0, 0, - 0, 129, 200, 0, 114, 179, 0, 102, 160, 0, 87, 139, 0, 74, 120, - 0, 60, 101, 0, 44, 81, 0, 22, 56, 0, 0, 19, 0, 127, 181, - 0, 114, 163, 0, 102, 146, 0, 88, 127, 0, 74, 109, 0, 60, 91, - 0, 44, 72, 0, 23, 48, 0, 0, 11, 0, 127, 166, 0, 113, 148, - 0, 101, 133, 0, 87, 115, 0, 74, 99, 0, 60, 82, 0, 44, 64, - 0, 23, 42, 0, 0, 4, 0, 127, 150, 0, 113, 134, 0, 101, 119, - 0, 87, 104, 0, 74, 89, 0, 60, 73, 0, 44, 56, 0, 23, 35, - 0, 0, 0, 0, 125, 134, 0, 112, 118, 0, 100, 106, 0, 87, 92, - 0, 73, 78, 0, 60, 64, 0, 44, 48, 0, 23, 27, 0, 0, 0, - 0, 125, 118, 0, 112, 105, 0, 100, 94, 0, 86, 80, 0, 73, 68, - 0, 60, 54, 0, 44, 39, 0, 23, 20, 0, 0, 0, 0, 125, 101, - 0, 111, 90, 0, 99, 80, 0, 86, 69, 0, 73, 58, 0, 59, 45, - 0, 44, 30, 0, 23, 11, 0, 0, 0, 0, 124, 85, 0, 111, 75, - 0, 99, 66, 0, 86, 56, 0, 73, 45, 0, 59, 34, 0, 44, 20, - 0, 23, 1, 0, 0, 0, 0, 125, 72, 0, 111, 62, 0, 99, 56, - 0, 86, 46, 0, 73, 36, 0, 60, 26, 0, 44, 12, 0, 23, 0, - 0, 0, 0, 0, 114, 188, 0, 101, 167, 0, 89, 150, 0, 77, 131, - 0, 64, 113, 0, 50, 95, 0, 34, 75, 0, 12, 52, 0, 0, 14, - 0, 113, 170, 0, 101, 153, 0, 89, 137, 0, 77, 120, 0, 64, 102, - 0, 50, 85, 0, 35, 67, 0, 12, 44, 0, 0, 4, 0, 113, 156, - 0, 100, 139, 0, 89, 125, 0, 77, 109, 0, 64, 92, 0, 51, 77, - 0, 35, 60, 0, 12, 38, 0, 0, 0, 0, 112, 141, 0, 100, 126, - 0, 89, 113, 0, 77, 98, 0, 64, 83, 0, 51, 68, 0, 35, 51, - 0, 12, 30, 0, 0, 0, 0, 112, 127, 0, 100, 112, 0, 89, 100, - 0, 76, 87, 0, 64, 74, 0, 51, 59, 0, 35, 44, 0, 13, 24, - 0, 0, 0, 0, 112, 111, 0, 100, 100, 0, 88, 88, 0, 76, 76, - 0, 64, 64, 0, 51, 52, 0, 36, 37, 0, 13, 17, 0, 0, 0, - 0, 111, 96, 0, 99, 85, 0, 88, 76, 0, 76, 64, 0, 64, 53, - 0, 51, 41, 0, 36, 27, 0, 13, 6, 0, 0, 0, 0, 111, 81, - 0, 99, 71, 0, 88, 62, 0, 76, 52, 0, 64, 43, 0, 51, 31, - 0, 36, 17, 0, 13, 0, 0, 0, 0, 0, 111, 69, 0, 99, 60, - 0, 88, 52, 0, 75, 43, 0, 63, 34, 0, 51, 21, 0, 36, 7, - 0, 13, 0, 0, 0, 0, 0, 99, 177, 0, 88, 158, 0, 77, 141, - 0, 66, 123, 0, 53, 106, 0, 40, 89, 0, 25, 71, 0, 5, 47, - 0, 0, 8, 0, 99, 160, 0, 88, 144, 0, 77, 129, 0, 66, 112, - 0, 54, 97, 0, 41, 80, 0, 26, 62, 0, 5, 40, 0, 0, 0, - 0, 99, 147, 0, 87, 132, 0, 78, 117, 0, 66, 102, 0, 54, 87, - 0, 42, 72, 0, 26, 55, 0, 5, 34, 0, 0, 0, 0, 99, 134, - 0, 88, 119, 0, 77, 107, 0, 66, 92, 0, 54, 78, 0, 42, 64, - 0, 27, 48, 0, 5, 27, 0, 0, 0, 0, 99, 120, 0, 87, 107, - 0, 78, 94, 0, 66, 81, 0, 54, 68, 0, 42, 55, 0, 27, 40, - 0, 6, 20, 0, 0, 0, 0, 98, 105, 0, 87, 94, 0, 77, 84, - 0, 65, 71, 0, 55, 59, 0, 42, 47, 0, 28, 33, 0, 6, 12, - 0, 0, 0, 0, 98, 93, 0, 87, 81, 0, 77, 72, 0, 66, 61, - 0, 54, 49, 0, 42, 37, 0, 28, 24, 0, 6, 4, 0, 0, 0, - 0, 98, 77, 0, 87, 68, 0, 77, 59, 0, 65, 49, 0, 54, 39, - 0, 42, 27, 0, 29, 14, 0, 6, 0, 0, 0, 0, 1, 98, 65, - 7, 87, 56, 0, 77, 49, 0, 66, 41, 0, 54, 30, 0, 42, 19, - 0, 29, 3, 0, 6, 0, 0, 0, 0, 0, 84, 166, 0, 74, 149, - 0, 64, 134, 0, 53, 117, 0, 41, 100, 0, 28, 83, 0, 11, 64, - 0, 0, 42, 0, 0, 3, 0, 84, 151, 0, 74, 135, 0, 64, 121, - 0, 53, 105, 0, 42, 90, 0, 30, 75, 0, 14, 58, 0, 0, 36, - 0, 0, 0, 0, 84, 138, 0, 74, 124, 1, 64, 110, 0, 54, 95, - 0, 43, 81, 0, 30, 67, 0, 15, 51, 0, 1, 29, 0, 0, 0, - 14, 84, 126, 12, 74, 112, 2, 65, 99, 0, 54, 85, 0, 44, 73, - 0, 31, 59, 0, 16, 44, 0, 1, 23, 0, 0, 0, 16, 84, 113, - 13, 74, 100, 6, 65, 89, 0, 54, 77, 0, 44, 65, 0, 31, 51, - 0, 17, 36, 0, 1, 16, 0, 0, 0, 24, 84, 100, 18, 74, 88, - 13, 65, 78, 2, 55, 68, 0, 44, 55, 0, 32, 43, 0, 18, 28, - 0, 1, 6, 0, 0, 0, 26, 84, 87, 24, 74, 76, 17, 65, 67, - 7, 54, 57, 0, 44, 46, 0, 32, 35, 0, 19, 21, 0, 2, 3, - 0, 0, 0, 30, 84, 74, 28, 74, 64, 20, 65, 55, 12, 55, 46, - 0, 44, 35, 0, 32, 24, 0, 18, 9, 0, 1, 0, 0, 0, 0, - 32, 84, 63, 28, 74, 54, 21, 65, 47, 13, 54, 38, 0, 44, 28, - 0, 32, 16, 0, 18, 1, 0, 1, 0, 0, 0, 0, 30, 67, 155, - 20, 58, 139, 20, 49, 126, 12, 39, 110, 0, 27, 94, 0, 13, 77, - 0, 0, 60, 0, 0, 37, 0, 0, 0, 35, 67, 142, 30, 58, 126, - 23, 50, 114, 16, 40, 99, 7, 29, 85, 0, 15, 69, 0, 0, 52, - 0, 0, 30, 0, 0, 0, 35, 68, 131, 30, 59, 116, 27, 50, 104, - 18, 40, 90, 9, 29, 76, 0, 17, 62, 0, 2, 46, 0, 0, 24, - 0, 0, 0, 37, 69, 119, 33, 59, 106, 27, 51, 94, 21, 41, 80, - 9, 30, 67, 0, 18, 54, 0, 3, 39, 0, 0, 18, 0, 0, 0, - 40, 69, 107, 36, 59, 94, 28, 51, 84, 18, 41, 72, 10, 31, 60, - 0, 19, 47, 0, 4, 32, 0, 0, 10, 0, 0, 0, 42, 69, 95, - 36, 59, 84, 29, 51, 74, 19, 41, 63, 10, 31, 52, 0, 20, 39, - 0, 4, 25, 0, 0, 4, 0, 0, 0, 43, 69, 83, 38, 60, 73, - 32, 51, 62, 23, 42, 53, 11, 31, 42, 0, 20, 31, 0, 5, 17, - 0, 0, 1, 0, 0, 0, 45, 69, 70, 39, 60, 60, 33, 51, 52, - 24, 42, 43, 13, 32, 33, 0, 21, 21, 0, 5, 6, 0, 0, 0, - 0, 0, 0, 47, 69, 59, 41, 60, 51, 34, 51, 43, 24, 42, 35, - 12, 33, 26, 1, 22, 14, 0, 5, 1, 0, 0, 0, 0, 0, 0, - 46, 48, 146, 42, 40, 131, 36, 32, 118, 27, 22, 103, 17, 6, 88, - 5, 0, 73, 0, 0, 55, 0, 0, 33, 0, 0, 0, 48, 48, 133, - 44, 40, 119, 37, 32, 107, 28, 22, 93, 20, 8, 79, 7, 0, 65, - 0, 0, 49, 0, 0, 27, 0, 0, 0, 48, 50, 123, 44, 41, 109, - 37, 33, 97, 30, 23, 83, 21, 11, 71, 8, 0, 58, 0, 0, 42, - 0, 0, 21, 0, 0, 0, 49, 51, 111, 45, 42, 99, 38, 34, 87, - 29, 25, 75, 20, 13, 63, 8, 0, 51, 0, 0, 36, 0, 0, 14, - 0, 0, 0, 52, 52, 100, 44, 43, 89, 38, 35, 79, 29, 26, 68, - 19, 15, 56, 10, 1, 43, 0, 0, 28, 0, 0, 6, 0, 0, 0, - 52, 52, 90, 47, 44, 79, 39, 36, 70, 30, 27, 59, 20, 16, 47, - 9, 2, 36, 0, 0, 22, 0, 0, 2, 0, 0, 0, 52, 53, 78, - 46, 44, 68, 39, 37, 60, 32, 27, 49, 22, 17, 39, 10, 3, 28, - 0, 0, 12, 0, 0, 0, 0, 0, 0, 53, 53, 66, 47, 44, 57, - 40, 36, 48, 32, 27, 39, 22, 18, 30, 9, 4, 18, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 54, 53, 57, 48, 45, 49, 41, 37, 41, - 33, 28, 32, 22, 19, 23, 11, 6, 10, 1, 0, 0, 0, 0, 0, - 0, 0, 0, -}; -void AdobeCMYK_to_sRGB1(uint8_t c, - uint8_t m, - uint8_t y, - uint8_t k, - uint8_t& R, - uint8_t& G, - uint8_t& B) { - int fix_c = c << 8; - int fix_m = m << 8; - int fix_y = y << 8; - int fix_k = k << 8; - int c_index = (fix_c + 4096) >> 13; - int m_index = (fix_m + 4096) >> 13; - int y_index = (fix_y + 4096) >> 13; - int k_index = (fix_k + 4096) >> 13; - int pos = (c_index * 9 * 9 * 9 + m_index * 9 * 9 + y_index * 9 + k_index) * 3; - int fix_r = g_CMYKSamples[pos] << 8; - int fix_g = g_CMYKSamples[pos + 1] << 8; - int fix_b = g_CMYKSamples[pos + 2] << 8; - int c1_index = fix_c >> 13; - if (c1_index == c_index) { - c1_index = c1_index == 8 ? c1_index - 1 : c1_index + 1; - } - int m1_index = fix_m >> 13; - if (m1_index == m_index) { - m1_index = m1_index == 8 ? m1_index - 1 : m1_index + 1; - } - int y1_index = fix_y >> 13; - if (y1_index == y_index) { - y1_index = y1_index == 8 ? y1_index - 1 : y1_index + 1; - } - int k1_index = fix_k >> 13; - if (k1_index == k_index) { - k1_index = k1_index == 8 ? k1_index - 1 : k1_index + 1; - } - int c1_pos = pos + (c1_index - c_index) * 9 * 9 * 9 * 3; - int m1_pos = pos + (m1_index - m_index) * 9 * 9 * 3; - int y1_pos = pos + (y1_index - y_index) * 9 * 3; - int k1_pos = pos + (k1_index - k_index) * 3; - int c_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[c1_pos]; - int c_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[c1_pos + 1]; - int c_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[c1_pos + 2]; - int m_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[m1_pos]; - int m_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[m1_pos + 1]; - int m_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[m1_pos + 2]; - int y_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[y1_pos]; - int y_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[y1_pos + 1]; - int y_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[y1_pos + 2]; - int k_r_delta = g_CMYKSamples[pos] - g_CMYKSamples[k1_pos]; - int k_g_delta = g_CMYKSamples[pos + 1] - g_CMYKSamples[k1_pos + 1]; - int k_b_delta = g_CMYKSamples[pos + 2] - g_CMYKSamples[k1_pos + 2]; - int c_rate = (fix_c - (c_index << 13)) * (c_index - c1_index); - fix_r += c_r_delta * c_rate / 32; - fix_g += c_g_delta * c_rate / 32; - fix_b += c_b_delta * c_rate / 32; - int m_rate = (fix_m - (m_index << 13)) * (m_index - m1_index); - fix_r += m_r_delta * m_rate / 32; - fix_g += m_g_delta * m_rate / 32; - fix_b += m_b_delta * m_rate / 32; - int y_rate = (fix_y - (y_index << 13)) * (y_index - y1_index); - fix_r += y_r_delta * y_rate / 32; - fix_g += y_g_delta * y_rate / 32; - fix_b += y_b_delta * y_rate / 32; - int k_rate = (fix_k - (k_index << 13)) * (k_index - k1_index); - fix_r += k_r_delta * k_rate / 32; - fix_g += k_g_delta * k_rate / 32; - fix_b += k_b_delta * k_rate / 32; - if (fix_r < 0) { - fix_r = 0; - } - if (fix_g < 0) { - fix_g = 0; - } - if (fix_b < 0) { - fix_b = 0; - } - R = fix_r >> 8; - G = fix_g >> 8; - B = fix_b >> 8; -} -void AdobeCMYK_to_sRGB(FX_FLOAT c, - FX_FLOAT m, - FX_FLOAT y, - FX_FLOAT k, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) { - uint8_t c1 = FXSYS_round(c * 255); - uint8_t m1 = FXSYS_round(m * 255); - uint8_t y1 = FXSYS_round(y * 255); - uint8_t k1 = FXSYS_round(k * 255); - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(c1, m1, y1, k1, r, g, b); - R = 1.0f * r / 255; - G = 1.0f * g / 255; - B = 1.0f * b / 255; -} diff --git a/core/src/fxcodec/codec/fx_codec_jbig.cpp b/core/src/fxcodec/codec/fx_codec_jbig.cpp deleted file mode 100644 index 44e30aa953..0000000000 --- a/core/src/fxcodec/codec/fx_codec_jbig.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/src/fxcodec/codec/codec_int.h" - -// Holds per-document JBig2 related data. -class JBig2DocumentContext : public CFX_DestructObject { - public: - std::list* GetSymbolDictCache() { - return &m_SymbolDictCache; - } - - ~JBig2DocumentContext() override { - for (auto it : m_SymbolDictCache) { - delete it.second; - } - } - - private: - std::list m_SymbolDictCache; -}; - -JBig2DocumentContext* GetJBig2DocumentContext(CCodec_Jbig2Module* pModule, - CFX_PrivateData* pPrivateData) { - void* pModulePrivateData = pPrivateData->GetPrivateData(pModule); - if (pModulePrivateData) { - CFX_DestructObject* pDestructObject = - reinterpret_cast(pModulePrivateData); - return static_cast(pDestructObject); - } - JBig2DocumentContext* pJBig2DocumentContext = new JBig2DocumentContext(); - pPrivateData->SetPrivateObj(pModule, pJBig2DocumentContext); - return pJBig2DocumentContext; -} - -CCodec_Jbig2Context::CCodec_Jbig2Context() { - FXSYS_memset(this, 0, sizeof(CCodec_Jbig2Context)); -} - -CCodec_Jbig2Module::~CCodec_Jbig2Module() { -} - -void* CCodec_Jbig2Module::CreateJbig2Context() { - return new CCodec_Jbig2Context(); -} -void CCodec_Jbig2Module::DestroyJbig2Context(void* pJbig2Content) { - if (pJbig2Content) { - CJBig2_Context::DestroyContext( - ((CCodec_Jbig2Context*)pJbig2Content)->m_pContext); - delete (CCodec_Jbig2Context*)pJbig2Content; - } - pJbig2Content = NULL; -} -FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context, - CFX_PrivateData* pPrivateData, - FX_DWORD width, - FX_DWORD height, - CPDF_StreamAcc* src_stream, - CPDF_StreamAcc* global_stream, - uint8_t* dest_buf, - FX_DWORD dest_pitch, - IFX_Pause* pPause) { - if (!pJbig2Context) { - return FXCODEC_STATUS_ERR_PARAMS; - } - JBig2DocumentContext* pJBig2DocumentContext = - GetJBig2DocumentContext(this, pPrivateData); - CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context; - m_pJbig2Context->m_width = width; - m_pJbig2Context->m_height = height; - m_pJbig2Context->m_pSrcStream = src_stream; - m_pJbig2Context->m_pGlobalStream = global_stream; - m_pJbig2Context->m_dest_buf = dest_buf; - m_pJbig2Context->m_dest_pitch = dest_pitch; - m_pJbig2Context->m_pPause = pPause; - FXSYS_memset(dest_buf, 0, height * dest_pitch); - m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext( - global_stream, src_stream, pJBig2DocumentContext->GetSymbolDictCache(), - pPause); - if (!m_pJbig2Context->m_pContext) { - return FXCODEC_STATUS_ERROR; - } - int ret = m_pJbig2Context->m_pContext->getFirstPage(dest_buf, width, height, - dest_pitch, pPause); - if (m_pJbig2Context->m_pContext->GetProcessingStatus() == - FXCODEC_STATUS_DECODE_FINISH) { - CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext); - m_pJbig2Context->m_pContext = NULL; - if (ret != JBIG2_SUCCESS) { - return FXCODEC_STATUS_ERROR; - } - int dword_size = height * dest_pitch / 4; - FX_DWORD* dword_buf = (FX_DWORD*)dest_buf; - for (int i = 0; i < dword_size; i++) { - dword_buf[i] = ~dword_buf[i]; - } - return FXCODEC_STATUS_DECODE_FINISH; - } - return m_pJbig2Context->m_pContext->GetProcessingStatus(); -} -FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(void* pJbig2Context, - IFX_Pause* pPause) { - CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context; - int ret = m_pJbig2Context->m_pContext->Continue(pPause); - if (m_pJbig2Context->m_pContext->GetProcessingStatus() != - FXCODEC_STATUS_DECODE_FINISH) { - return m_pJbig2Context->m_pContext->GetProcessingStatus(); - } - CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext); - m_pJbig2Context->m_pContext = NULL; - if (ret != JBIG2_SUCCESS) { - return FXCODEC_STATUS_ERROR; - } - int dword_size = - m_pJbig2Context->m_height * m_pJbig2Context->m_dest_pitch / 4; - FX_DWORD* dword_buf = (FX_DWORD*)m_pJbig2Context->m_dest_buf; - for (int i = 0; i < dword_size; i++) { - dword_buf[i] = ~dword_buf[i]; - } - return FXCODEC_STATUS_DECODE_FINISH; -} diff --git a/core/src/fxcodec/codec/fx_codec_jpeg.cpp b/core/src/fxcodec/codec/fx_codec_jpeg.cpp deleted file mode 100644 index 14cc194db4..0000000000 --- a/core/src/fxcodec/codec/fx_codec_jpeg.cpp +++ /dev/null @@ -1,692 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/include/fxcrt/fx_safe_types.h" -#include "core/include/fxge/fx_dib.h" -#include "core/src/fxcodec/codec/codec_int.h" - -extern "C" { -#undef FAR -#if defined(USE_SYSTEM_LIBJPEG) -#include -#elif defined(USE_LIBJPEG_TURBO) -#include "third_party/libjpeg_turbo/jpeglib.h" -#else -#include "third_party/libjpeg/jpeglib.h" -#endif -} - -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 || 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(pSource->GetWidth()); - FX_DWORD height = pdfium::base::checked_cast(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 (FX_DWORD 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 (FX_DWORD 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; -} - -#ifdef PDF_ENABLE_XFA -static void _JpegLoadAttribute(struct jpeg_decompress_struct* pInfo, - CFX_DIBAttribute* pAttribute) { - if (pInfo == NULL || pAttribute == NULL) { - return; - } - if (pAttribute) { - pAttribute->m_nXDPI = pInfo->X_density; - pAttribute->m_nYDPI = pInfo->Y_density; - pAttribute->m_wDPIUnit = pInfo->density_unit; - } -} -#endif // PDF_ENABLE_XFA - -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) { - *icc_buf_ptr = NULL; - } - if (icc_length) { - *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); - 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: - FX_DWORD m_nDefaultScaleDenom; -}; - -CCodec_JpegDecoder::CCodec_JpegDecoder() { - m_pScanlineBuf = NULL; - m_DownScale = 1; - m_bStarted = FALSE; - m_bInited = FALSE; - 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() { - 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) { - _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(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) { - 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(m_OutputWidth) * m_nComps + 3) / 4 * 4; - if (old_scale != m_DownScale) { - m_NextLine = -1; - } -} -FX_BOOL CCodec_JpegDecoder::v_Rewind() { - 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 (setjmp(m_JmpBuf) == -1) - return nullptr; - - int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1); - if (nlines < 1) { - return nullptr; - } - return m_pScanlineBuf; -} -FX_DWORD CCodec_JpegDecoder::GetSrcOffset() { - 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 || src_size == 0) { - return NULL; - } - CCodec_JpegDecoder* pDecoder = new CCodec_JpegDecoder; - if (!pDecoder->Create(src_buf, src_size, width, height, nComps, - ColorTransform)) { - 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) { - 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 (pSource->GetBPP() < 8 || pSource->GetPalette()) - 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() { - 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) { - 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) { - 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; -} - -#ifdef PDF_ENABLE_XFA -int CCodec_JpegModule::ReadHeader(void* pContext, - int* width, - int* height, - int* nComps, - CFX_DIBAttribute* pAttribute) { -#else // PDF_ENABLE_XFA -int CCodec_JpegModule::ReadHeader(void* pContext, - int* width, - int* height, - int* nComps) { -#endif // PDF_ENABLE_XFA - 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; -#ifdef PDF_ENABLE_XFA - _JpegLoadAttribute(&p->m_Info, pAttribute); -#endif - return 0; -} -int CCodec_JpegModule::StartScanline(void* pContext, int 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) { - 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 (avail_buf_ptr) { - *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; -} diff --git a/core/src/fxcodec/codec/fx_codec_jpx_opj.cpp b/core/src/fxcodec/codec/fx_codec_jpx_opj.cpp deleted file mode 100644 index 4ace3ad220..0000000000 --- a/core/src/fxcodec/codec/fx_codec_jpx_opj.cpp +++ /dev/null @@ -1,888 +0,0 @@ -// 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 -#include - -#include "core/include/fpdfapi/fpdf_resource.h" -#include "core/include/fxcodec/fx_codec.h" -#include "core/include/fxcrt/fx_safe_types.h" -#include "core/src/fxcodec/codec/codec_int.h" -#include "third_party/lcms2-2.6/include/lcms2.h" -#include "third_party/libopenjpeg20/openjpeg.h" - -static void fx_error_callback(const char* msg, void* client_data) { - (void)client_data; -} -static void fx_warning_callback(const char* msg, void* client_data) { - (void)client_data; -} -static void fx_info_callback(const char* msg, void* client_data) { - (void)client_data; -} -OPJ_SIZE_T opj_read_from_memory(void* p_buffer, - OPJ_SIZE_T nb_bytes, - void* p_user_data) { - DecodeData* srcData = static_cast(p_user_data); - if (!srcData || !srcData->src_data || srcData->src_size == 0) { - return -1; - } - // Reads at EOF return an error code. - if (srcData->offset >= srcData->src_size) { - return -1; - } - OPJ_SIZE_T bufferLength = srcData->src_size - srcData->offset; - OPJ_SIZE_T readlength = nb_bytes < bufferLength ? nb_bytes : bufferLength; - memcpy(p_buffer, &srcData->src_data[srcData->offset], readlength); - srcData->offset += readlength; - return readlength; -} -OPJ_SIZE_T opj_write_from_memory(void* p_buffer, - OPJ_SIZE_T nb_bytes, - void* p_user_data) { - DecodeData* srcData = static_cast(p_user_data); - if (!srcData || !srcData->src_data || srcData->src_size == 0) { - return -1; - } - // Writes at EOF return an error code. - if (srcData->offset >= srcData->src_size) { - return -1; - } - OPJ_SIZE_T bufferLength = srcData->src_size - srcData->offset; - OPJ_SIZE_T writeLength = nb_bytes < bufferLength ? nb_bytes : bufferLength; - memcpy(&srcData->src_data[srcData->offset], p_buffer, writeLength); - srcData->offset += writeLength; - return writeLength; -} -OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) { - DecodeData* srcData = static_cast(p_user_data); - if (!srcData || !srcData->src_data || srcData->src_size == 0) { - return -1; - } - // Offsets are signed and may indicate a negative skip. Do not support this - // because of the strange return convention where either bytes skipped or - // -1 is returned. Following that convention, a successful relative seek of - // -1 bytes would be required to to give the same result as the error case. - if (nb_bytes < 0) { - return -1; - } - // FIXME: use std::make_unsigned::type once c++11 lib is OK'd. - uint64_t unsignedNbBytes = static_cast(nb_bytes); - // Additionally, the offset may take us beyond the range of a size_t (e.g. - // 32-bit platforms). If so, just clamp at EOF. - if (unsignedNbBytes > - std::numeric_limits::max() - srcData->offset) { - srcData->offset = srcData->src_size; - } else { - OPJ_SIZE_T checkedNbBytes = static_cast(unsignedNbBytes); - // Otherwise, mimic fseek() semantics to always succeed, even past EOF, - // clamping at EOF. We can get away with this since we don't actually - // provide negative relative skips from beyond EOF back to inside the - // data, which would be the only reason to need to know exactly how far - // beyond EOF we are. - srcData->offset = - std::min(srcData->offset + checkedNbBytes, srcData->src_size); - } - return nb_bytes; -} -OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data) { - DecodeData* srcData = static_cast(p_user_data); - if (!srcData || !srcData->src_data || srcData->src_size == 0) { - return OPJ_FALSE; - } - // Offsets are signed and may indicate a negative position, which would - // be before the start of the file. Do not support this. - if (nb_bytes < 0) { - return OPJ_FALSE; - } - // FIXME: use std::make_unsigned::type once c++11 lib is OK'd. - uint64_t unsignedNbBytes = static_cast(nb_bytes); - // Additionally, the offset may take us beyond the range of a size_t (e.g. - // 32-bit platforms). If so, just clamp at EOF. - if (unsignedNbBytes > std::numeric_limits::max()) { - srcData->offset = srcData->src_size; - } else { - OPJ_SIZE_T checkedNbBytes = static_cast(nb_bytes); - // Otherwise, mimic fseek() semantics to always succeed, even past EOF, - // again clamping at EOF. - srcData->offset = std::min(checkedNbBytes, srcData->src_size); - } - return OPJ_TRUE; -} -opj_stream_t* fx_opj_stream_create_memory_stream(DecodeData* data, - OPJ_SIZE_T p_size, - OPJ_BOOL p_is_read_stream) { - opj_stream_t* l_stream = 00; - if (!data || !data->src_data || data->src_size <= 0) { - return NULL; - } - l_stream = opj_stream_create(p_size, p_is_read_stream); - if (!l_stream) { - return NULL; - } - opj_stream_set_user_data(l_stream, data, NULL); - opj_stream_set_user_data_length(l_stream, data->src_size); - opj_stream_set_read_function(l_stream, opj_read_from_memory); - opj_stream_set_write_function(l_stream, opj_write_from_memory); - opj_stream_set_skip_function(l_stream, opj_skip_from_memory); - opj_stream_set_seek_function(l_stream, opj_seek_from_memory); - return l_stream; -} -static void sycc_to_rgb(int offset, - int upb, - int y, - int cb, - int cr, - int* out_r, - int* out_g, - int* out_b) { - int r, g, b; - cb -= offset; - cr -= offset; - r = y + (int)(1.402 * (float)cr); - if (r < 0) { - r = 0; - } else if (r > upb) { - r = upb; - } - *out_r = r; - g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr); - if (g < 0) { - g = 0; - } else if (g > upb) { - g = upb; - } - *out_g = g; - b = y + (int)(1.772 * (float)cb); - if (b < 0) { - b = 0; - } else if (b > upb) { - b = upb; - } - *out_b = b; -} -static void sycc444_to_rgb(opj_image_t* img) { - int prec = img->comps[0].prec; - int offset = 1 << (prec - 1); - int upb = (1 << prec) - 1; - OPJ_UINT32 maxw = - std::min(std::min(img->comps[0].w, img->comps[1].w), img->comps[2].w); - OPJ_UINT32 maxh = - std::min(std::min(img->comps[0].h, img->comps[1].h), img->comps[2].h); - FX_SAFE_SIZE_T max_size = maxw; - max_size *= maxh; - if (!max_size.IsValid()) - return; - - const int* y = img->comps[0].data; - const int* cb = img->comps[1].data; - const int* cr = img->comps[2].data; - int *d0, *d1, *d2, *r, *g, *b; - d0 = r = FX_Alloc(int, max_size.ValueOrDie()); - d1 = g = FX_Alloc(int, max_size.ValueOrDie()); - d2 = b = FX_Alloc(int, max_size.ValueOrDie()); - for (size_t i = 0; i < max_size.ValueOrDie(); ++i) { - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++cb; - ++cr; - ++r; - ++g; - ++b; - } - FX_Free(img->comps[0].data); - img->comps[0].data = d0; - FX_Free(img->comps[1].data); - img->comps[1].data = d1; - FX_Free(img->comps[2].data); - img->comps[2].data = d2; -} -static void sycc422_to_rgb(opj_image_t* img) { - int prec = img->comps[0].prec; - int offset = 1 << (prec - 1); - int upb = (1 << prec) - 1; - OPJ_UINT32 maxw = - std::min(std::min(img->comps[0].w, img->comps[1].w), img->comps[2].w); - OPJ_UINT32 maxh = - std::min(std::min(img->comps[0].h, img->comps[1].h), img->comps[2].h); - FX_SAFE_SIZE_T max_size = maxw; - max_size *= maxh; - if (!max_size.IsValid()) - return; - - const int* y = img->comps[0].data; - const int* cb = img->comps[1].data; - const int* cr = img->comps[2].data; - int *d0, *d1, *d2, *r, *g, *b; - d0 = r = FX_Alloc(int, max_size.ValueOrDie()); - d1 = g = FX_Alloc(int, max_size.ValueOrDie()); - d2 = b = FX_Alloc(int, max_size.ValueOrDie()); - for (uint32_t i = 0; i < maxh; ++i) { - OPJ_UINT32 j; - for (j = 0; j < (maxw & ~static_cast(1)); j += 2) { - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - ++cb; - ++cr; - } - if (j < maxw) { - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - ++cb; - ++cr; - } - } - FX_Free(img->comps[0].data); - img->comps[0].data = d0; - FX_Free(img->comps[1].data); - img->comps[1].data = d1; - FX_Free(img->comps[2].data); - img->comps[2].data = d2; - img->comps[1].w = maxw; - img->comps[1].h = maxh; - img->comps[2].w = maxw; - img->comps[2].h = maxh; - img->comps[1].dx = img->comps[0].dx; - img->comps[2].dx = img->comps[0].dx; - img->comps[1].dy = img->comps[0].dy; - img->comps[2].dy = img->comps[0].dy; -} -static bool sycc420_size_is_valid(OPJ_UINT32 y, OPJ_UINT32 cbcr) { - if (!y || !cbcr) - return false; - - return (cbcr == y / 2) || ((y & 1) && (cbcr == y / 2 + 1)); -} -static bool sycc420_must_extend_cbcr(OPJ_UINT32 y, OPJ_UINT32 cbcr) { - return (y & 1) && (cbcr == y / 2); -} -void sycc420_to_rgb(opj_image_t* img) { - OPJ_UINT32 prec = img->comps[0].prec; - if (!prec) - return; - OPJ_UINT32 offset = 1 << (prec - 1); - OPJ_UINT32 upb = (1 << prec) - 1; - OPJ_UINT32 yw = img->comps[0].w; - OPJ_UINT32 yh = img->comps[0].h; - OPJ_UINT32 cbw = img->comps[1].w; - OPJ_UINT32 cbh = img->comps[1].h; - OPJ_UINT32 crw = img->comps[2].w; - OPJ_UINT32 crh = img->comps[2].h; - if (cbw != crw || cbh != crh) - return; - if (!sycc420_size_is_valid(yw, cbw) || !sycc420_size_is_valid(yh, cbh)) - return; - bool extw = sycc420_must_extend_cbcr(yw, cbw); - bool exth = sycc420_must_extend_cbcr(yh, cbh); - FX_SAFE_DWORD safeSize = yw; - safeSize *= yh; - if (!safeSize.IsValid()) - return; - int* r = FX_Alloc(int, safeSize.ValueOrDie()); - int* g = FX_Alloc(int, safeSize.ValueOrDie()); - int* b = FX_Alloc(int, safeSize.ValueOrDie()); - int* d0 = r; - int* d1 = g; - int* d2 = b; - const int* y = img->comps[0].data; - const int* cb = img->comps[1].data; - const int* cr = img->comps[2].data; - const int* ny = nullptr; - int* nr = nullptr; - int* ng = nullptr; - int* nb = nullptr; - OPJ_UINT32 i = 0; - OPJ_UINT32 j = 0; - for (i = 0; i < (yh & ~(OPJ_UINT32)1); i += 2) { - ny = y + yw; - nr = r + yw; - ng = g + yw; - nb = b + yw; - for (j = 0; j < (yw & ~(OPJ_UINT32)1); j += 2) { - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb); - ++ny; - ++nr; - ++ng; - ++nb; - sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb); - ++ny; - ++nr; - ++ng; - ++nb; - ++cb; - ++cr; - } - if (j < yw) { - if (extw) { - --cb; - --cr; - } - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb); - ++ny; - ++nr; - ++ng; - ++nb; - ++cb; - ++cr; - } - y += yw; - r += yw; - g += yw; - b += yw; - } - if (i < yh) { - if (exth) { - cb -= cbw; - cr -= crw; - } - for (j = 0; j < (yw & ~(OPJ_UINT32)1); j += 2) { - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - ++y; - ++r; - ++g; - ++b; - ++cb; - ++cr; - } - if (j < yw) { - if (extw) { - --cb; - --cr; - } - sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); - } - } - - FX_Free(img->comps[0].data); - img->comps[0].data = d0; - FX_Free(img->comps[1].data); - img->comps[1].data = d1; - FX_Free(img->comps[2].data); - img->comps[2].data = d2; - img->comps[1].w = yw; - img->comps[1].h = yh; - img->comps[2].w = yw; - img->comps[2].h = yh; - img->comps[1].w = yw; - img->comps[1].h = yh; - img->comps[2].w = yw; - img->comps[2].h = yh; - img->comps[1].dx = img->comps[0].dx; - img->comps[2].dx = img->comps[0].dx; - img->comps[1].dy = img->comps[0].dy; - img->comps[2].dy = img->comps[0].dy; -} -void color_sycc_to_rgb(opj_image_t* img) { - if (img->numcomps < 3) { - img->color_space = OPJ_CLRSPC_GRAY; - return; - } - if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) && - (img->comps[2].dx == 2) && (img->comps[0].dy == 1) && - (img->comps[1].dy == 2) && (img->comps[2].dy == 2)) { - sycc420_to_rgb(img); - } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) && - (img->comps[2].dx == 2) && (img->comps[0].dy == 1) && - (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) { - sycc422_to_rgb(img); - } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 1) && - (img->comps[2].dx == 1) && (img->comps[0].dy == 1) && - (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) { - sycc444_to_rgb(img); - } else { - return; - } - img->color_space = OPJ_CLRSPC_SRGB; -} -void color_apply_icc_profile(opj_image_t* image) { - cmsHPROFILE out_prof; - cmsUInt32Number in_type; - cmsUInt32Number out_type; - int* r; - int* g; - int* b; - int max; - cmsHPROFILE in_prof = - cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len); - if (!in_prof) { - return; - } - cmsColorSpaceSignature out_space = cmsGetColorSpace(in_prof); - cmsUInt32Number intent = cmsGetHeaderRenderingIntent(in_prof); - int max_w = (int)image->comps[0].w; - int max_h = (int)image->comps[0].h; - int prec = (int)image->comps[0].prec; - OPJ_COLOR_SPACE oldspace = image->color_space; - if (out_space == cmsSigRgbData) { - if (prec <= 8) { - in_type = TYPE_RGB_8; - out_type = TYPE_RGB_8; - } else { - in_type = TYPE_RGB_16; - out_type = TYPE_RGB_16; - } - out_prof = cmsCreate_sRGBProfile(); - image->color_space = OPJ_CLRSPC_SRGB; - } else if (out_space == cmsSigGrayData) { - if (prec <= 8) { - in_type = TYPE_GRAY_8; - out_type = TYPE_RGB_8; - } else { - in_type = TYPE_GRAY_16; - out_type = TYPE_RGB_16; - } - out_prof = cmsCreate_sRGBProfile(); - image->color_space = OPJ_CLRSPC_SRGB; - } else if (out_space == cmsSigYCbCrData) { - in_type = TYPE_YCbCr_16; - out_type = TYPE_RGB_16; - out_prof = cmsCreate_sRGBProfile(); - image->color_space = OPJ_CLRSPC_SRGB; - } else { - return; - } - cmsHTRANSFORM transform = - cmsCreateTransform(in_prof, in_type, out_prof, out_type, intent, 0); - cmsCloseProfile(in_prof); - cmsCloseProfile(out_prof); - if (!transform) { - image->color_space = oldspace; - return; - } - if (image->numcomps > 2) { - if (prec <= 8) { - unsigned char *inbuf, *outbuf, *in, *out; - max = max_w * max_h; - cmsUInt32Number nr_samples = max * 3 * sizeof(unsigned char); - in = inbuf = FX_Alloc(unsigned char, nr_samples); - out = outbuf = FX_Alloc(unsigned char, nr_samples); - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - for (int i = 0; i < max; ++i) { - *in++ = (unsigned char)*r++; - *in++ = (unsigned char)*g++; - *in++ = (unsigned char)*b++; - } - cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - for (int i = 0; i < max; ++i) { - *r++ = (int)*out++; - *g++ = (int)*out++; - *b++ = (int)*out++; - } - FX_Free(inbuf); - FX_Free(outbuf); - } else { - unsigned short *inbuf, *outbuf, *in, *out; - max = max_w * max_h; - cmsUInt32Number nr_samples = max * 3 * sizeof(unsigned short); - in = inbuf = FX_Alloc(unsigned short, nr_samples); - out = outbuf = FX_Alloc(unsigned short, nr_samples); - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - for (int i = 0; i < max; ++i) { - *in++ = (unsigned short)*r++; - *in++ = (unsigned short)*g++; - *in++ = (unsigned short)*b++; - } - cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - for (int i = 0; i < max; ++i) { - *r++ = (int)*out++; - *g++ = (int)*out++; - *b++ = (int)*out++; - } - FX_Free(inbuf); - FX_Free(outbuf); - } - } else { - unsigned char *in, *inbuf, *out, *outbuf; - max = max_w * max_h; - cmsUInt32Number nr_samples = - (cmsUInt32Number)max * 3 * sizeof(unsigned char); - in = inbuf = FX_Alloc(unsigned char, nr_samples); - out = outbuf = FX_Alloc(unsigned char, nr_samples); - image->comps = (opj_image_comp_t*)realloc( - image->comps, (image->numcomps + 2) * sizeof(opj_image_comp_t)); - if (image->numcomps == 2) { - image->comps[3] = image->comps[1]; - } - image->comps[1] = image->comps[0]; - image->comps[2] = image->comps[0]; - image->comps[1].data = FX_Alloc(int, (size_t)max); - FXSYS_memset(image->comps[1].data, 0, sizeof(int) * (size_t)max); - image->comps[2].data = FX_Alloc(int, (size_t)max); - FXSYS_memset(image->comps[2].data, 0, sizeof(int) * (size_t)max); - image->numcomps += 2; - r = image->comps[0].data; - for (int i = 0; i < max; ++i) { - *in++ = (unsigned char)*r++; - } - cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - for (int i = 0; i < max; ++i) { - *r++ = (int)*out++; - *g++ = (int)*out++; - *b++ = (int)*out++; - } - FX_Free(inbuf); - FX_Free(outbuf); - } - cmsDeleteTransform(transform); -} -void color_apply_conversion(opj_image_t* image) { - int* row; - int enumcs, numcomps; - numcomps = image->numcomps; - if (numcomps < 3) { - return; - } - row = (int*)image->icc_profile_buf; - enumcs = row[0]; - if (enumcs == 14) { - int *L, *a, *b, *red, *green, *blue, *src0, *src1, *src2; - double rl, ol, ra, oa, rb, ob, prec0, prec1, prec2; - double minL, maxL, mina, maxa, minb, maxb; - unsigned int default_type; - unsigned int i, max; - cmsHPROFILE in, out; - cmsHTRANSFORM transform; - cmsUInt16Number RGB[3]; - cmsCIELab Lab; - in = cmsCreateLab4Profile(NULL); - out = cmsCreate_sRGBProfile(); - transform = cmsCreateTransform(in, TYPE_Lab_DBL, out, TYPE_RGB_16, - INTENT_PERCEPTUAL, 0); - cmsCloseProfile(in); - cmsCloseProfile(out); - if (!transform) { - return; - } - prec0 = (double)image->comps[0].prec; - prec1 = (double)image->comps[1].prec; - prec2 = (double)image->comps[2].prec; - default_type = row[1]; - if (default_type == 0x44454600) { - rl = 100; - ra = 170; - rb = 200; - ol = 0; - oa = pow(2, prec1 - 1); - ob = pow(2, prec2 - 2) + pow(2, prec2 - 3); - } else { - rl = row[2]; - ra = row[4]; - rb = row[6]; - ol = row[3]; - oa = row[5]; - ob = row[7]; - } - L = src0 = image->comps[0].data; - a = src1 = image->comps[1].data; - b = src2 = image->comps[2].data; - max = image->comps[0].w * image->comps[0].h; - red = FX_Alloc(int, max); - image->comps[0].data = red; - green = FX_Alloc(int, max); - image->comps[1].data = green; - blue = FX_Alloc(int, max); - image->comps[2].data = blue; - minL = -(rl * ol) / (pow(2, prec0) - 1); - maxL = minL + rl; - mina = -(ra * oa) / (pow(2, prec1) - 1); - maxa = mina + ra; - minb = -(rb * ob) / (pow(2, prec2) - 1); - maxb = minb + rb; - for (i = 0; i < max; ++i) { - Lab.L = minL + (double)(*L) * (maxL - minL) / (pow(2, prec0) - 1); - ++L; - Lab.a = mina + (double)(*a) * (maxa - mina) / (pow(2, prec1) - 1); - ++a; - Lab.b = minb + (double)(*b) * (maxb - minb) / (pow(2, prec2) - 1); - ++b; - cmsDoTransform(transform, &Lab, RGB, 1); - *red++ = RGB[0]; - *green++ = RGB[1]; - *blue++ = RGB[2]; - } - cmsDeleteTransform(transform); - FX_Free(src0); - FX_Free(src1); - FX_Free(src2); - image->color_space = OPJ_CLRSPC_SRGB; - image->comps[0].prec = 16; - image->comps[1].prec = 16; - image->comps[2].prec = 16; - return; - } -} -class CJPX_Decoder { - public: - explicit CJPX_Decoder(CPDF_ColorSpace* cs); - ~CJPX_Decoder(); - FX_BOOL Init(const unsigned char* src_data, FX_DWORD src_size); - void GetInfo(FX_DWORD* width, FX_DWORD* height, FX_DWORD* components); - bool Decode(uint8_t* dest_buf, - int pitch, - const std::vector& offsets); - - private: - const uint8_t* m_SrcData; - FX_DWORD m_SrcSize; - opj_image_t* image; - opj_codec_t* l_codec; - opj_stream_t* l_stream; - const CPDF_ColorSpace* const m_ColorSpace; -}; - -CJPX_Decoder::CJPX_Decoder(CPDF_ColorSpace* cs) - : image(nullptr), l_codec(nullptr), l_stream(nullptr), m_ColorSpace(cs) {} - -CJPX_Decoder::~CJPX_Decoder() { - if (l_codec) { - opj_destroy_codec(l_codec); - } - if (l_stream) { - opj_stream_destroy(l_stream); - } - if (image) { - opj_image_destroy(image); - } -} - -FX_BOOL CJPX_Decoder::Init(const unsigned char* src_data, FX_DWORD src_size) { - static const unsigned char szJP2Header[] = { - 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a}; - if (!src_data || src_size < sizeof(szJP2Header)) - return FALSE; - - image = NULL; - m_SrcData = src_data; - m_SrcSize = src_size; - DecodeData srcData(const_cast(src_data), src_size); - l_stream = fx_opj_stream_create_memory_stream(&srcData, - OPJ_J2K_STREAM_CHUNK_SIZE, 1); - if (!l_stream) { - return FALSE; - } - opj_dparameters_t parameters; - opj_set_default_decoder_parameters(¶meters); - parameters.decod_format = 0; - parameters.cod_format = 3; - if (FXSYS_memcmp(m_SrcData, szJP2Header, sizeof(szJP2Header)) == 0) { - l_codec = opj_create_decompress(OPJ_CODEC_JP2); - parameters.decod_format = 1; - } else { - l_codec = opj_create_decompress(OPJ_CODEC_J2K); - } - if (!l_codec) { - return FALSE; - } - if (m_ColorSpace && m_ColorSpace->GetFamily() == PDFCS_INDEXED) - parameters.flags |= OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG; - opj_set_info_handler(l_codec, fx_info_callback, 00); - opj_set_warning_handler(l_codec, fx_warning_callback, 00); - opj_set_error_handler(l_codec, fx_error_callback, 00); - if (!opj_setup_decoder(l_codec, ¶meters)) { - return FALSE; - } - if (!opj_read_header(l_stream, l_codec, &image)) { - image = NULL; - return FALSE; - } - image->pdfium_use_colorspace = !!m_ColorSpace; - - if (!parameters.nb_tile_to_decode) { - if (!opj_set_decode_area(l_codec, image, parameters.DA_x0, parameters.DA_y0, - parameters.DA_x1, parameters.DA_y1)) { - opj_image_destroy(image); - image = NULL; - return FALSE; - } - if (!(opj_decode(l_codec, l_stream, image) && - opj_end_decompress(l_codec, l_stream))) { - opj_image_destroy(image); - image = NULL; - return FALSE; - } - } else { - if (!opj_get_decoded_tile(l_codec, l_stream, image, - parameters.tile_index)) { - return FALSE; - } - } - opj_stream_destroy(l_stream); - l_stream = NULL; - if (image->color_space != OPJ_CLRSPC_SYCC && image->numcomps == 3 && - image->comps[0].dx == image->comps[0].dy && image->comps[1].dx != 1) { - image->color_space = OPJ_CLRSPC_SYCC; - } else if (image->numcomps <= 2) { - image->color_space = OPJ_CLRSPC_GRAY; - } - if (image->color_space == OPJ_CLRSPC_SYCC) { - color_sycc_to_rgb(image); - } - if (image->icc_profile_buf) { - FX_Free(image->icc_profile_buf); - image->icc_profile_buf = NULL; - image->icc_profile_len = 0; - } - if (!image) { - return FALSE; - } - return TRUE; -} - -void CJPX_Decoder::GetInfo(FX_DWORD* width, - FX_DWORD* height, - FX_DWORD* components) { - *width = (FX_DWORD)image->x1; - *height = (FX_DWORD)image->y1; - *components = (FX_DWORD)image->numcomps; -} - -bool CJPX_Decoder::Decode(uint8_t* dest_buf, - int pitch, - const std::vector& offsets) { - if (image->comps[0].w != image->x1 || image->comps[0].h != image->y1) - return false; - - if (pitch<(int)(image->comps[0].w * 8 * image->numcomps + 31)>> 5 << 2) - return false; - - FXSYS_memset(dest_buf, 0xff, image->y1 * pitch); - std::vector channel_bufs(image->numcomps); - std::vector adjust_comps(image->numcomps); - for (uint32_t i = 0; i < image->numcomps; i++) { - channel_bufs[i] = dest_buf + offsets[i]; - adjust_comps[i] = image->comps[i].prec - 8; - if (i > 0) { - if (image->comps[i].dx != image->comps[i - 1].dx || - image->comps[i].dy != image->comps[i - 1].dy || - image->comps[i].prec != image->comps[i - 1].prec) { - return false; - } - } - } - int width = image->comps[0].w; - int height = image->comps[0].h; - for (uint32_t channel = 0; channel < image->numcomps; ++channel) { - uint8_t* pChannel = channel_bufs[channel]; - if (adjust_comps[channel] < 0) { - for (int row = 0; row < height; ++row) { - uint8_t* pScanline = pChannel + row * pitch; - for (int col = 0; col < width; ++col) { - uint8_t* pPixel = pScanline + col * image->numcomps; - int src = image->comps[channel].data[row * width + col]; - src += image->comps[channel].sgnd - ? 1 << (image->comps[channel].prec - 1) - : 0; - if (adjust_comps[channel] > 0) { - *pPixel = 0; - } else { - *pPixel = (uint8_t)(src << -adjust_comps[channel]); - } - } - } - } else { - for (int row = 0; row < height; ++row) { - uint8_t* pScanline = pChannel + row * pitch; - for (int col = 0; col < width; ++col) { - uint8_t* pPixel = pScanline + col * image->numcomps; - if (!image->comps[channel].data) { - continue; - } - int src = image->comps[channel].data[row * width + col]; - src += image->comps[channel].sgnd - ? 1 << (image->comps[channel].prec - 1) - : 0; - if (adjust_comps[channel] - 1 < 0) { - *pPixel = (uint8_t)((src >> adjust_comps[channel])); - } else { - int tmpPixel = (src >> adjust_comps[channel]) + - ((src >> (adjust_comps[channel] - 1)) % 2); - if (tmpPixel > 255) { - tmpPixel = 255; - } else if (tmpPixel < 0) { - tmpPixel = 0; - } - *pPixel = (uint8_t)tmpPixel; - } - } - } - } - } - return true; -} - -CCodec_JpxModule::CCodec_JpxModule() {} -CCodec_JpxModule::~CCodec_JpxModule() { -} - -CJPX_Decoder* CCodec_JpxModule::CreateDecoder(const uint8_t* src_buf, - FX_DWORD src_size, - CPDF_ColorSpace* cs) { - std::unique_ptr decoder(new CJPX_Decoder(cs)); - return decoder->Init(src_buf, src_size) ? decoder.release() : nullptr; -} - -void CCodec_JpxModule::GetImageInfo(CJPX_Decoder* pDecoder, - FX_DWORD* width, - FX_DWORD* height, - FX_DWORD* components) { - pDecoder->GetInfo(width, height, components); -} - -bool CCodec_JpxModule::Decode(CJPX_Decoder* pDecoder, - uint8_t* dest_data, - int pitch, - const std::vector& offsets) { - return pDecoder->Decode(dest_data, pitch, offsets); -} - -void CCodec_JpxModule::DestroyDecoder(CJPX_Decoder* pDecoder) { - delete pDecoder; -} diff --git a/core/src/fxcodec/codec/fx_codec_jpx_unittest.cpp b/core/src/fxcodec/codec/fx_codec_jpx_unittest.cpp deleted file mode 100644 index c472ef18c6..0000000000 --- a/core/src/fxcodec/codec/fx_codec_jpx_unittest.cpp +++ /dev/null @@ -1,538 +0,0 @@ -// 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. - -#include - -#include - -#include "core/src/fxcodec/codec/codec_int.h" -#include "testing/fx_string_testhelpers.h" -#include "testing/gtest/include/gtest/gtest.h" - -static const OPJ_OFF_T kSkipError = static_cast(-1); -static const OPJ_SIZE_T kReadError = static_cast(-1); -static const OPJ_SIZE_T kWriteError = static_cast(-1); - -static unsigned char stream_data[] = { - 0x00, 0x01, 0x02, 0x03, - 0x84, 0x85, 0x86, 0x87, // Include some hi-bytes, too. -}; - -TEST(fxcodec, DecodeDataNullDecodeData) { - unsigned char buffer[16]; - DecodeData* ptr = nullptr; - - // Error codes, not segvs, should callers pass us a NULL pointer. - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), ptr)); - EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, sizeof(buffer), ptr)); - EXPECT_EQ(kSkipError, opj_skip_from_memory(1, ptr)); - EXPECT_FALSE(opj_seek_from_memory(1, ptr)); -} - -TEST(fxcodec, DecodeDataNullStream) { - DecodeData dd(nullptr, 0); - unsigned char buffer[16]; - - // Reads of size 0 do nothing but return an error code. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - - // Reads of nonzero size do nothing but return an error code. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd)); - EXPECT_EQ(0xbd, buffer[0]); - - // writes of size 0 do nothing but return an error code. - EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, 0, &dd)); - - // writes of nonzero size do nothing but return an error code. - EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, sizeof(buffer), &dd)); - - // Skips of size 0 always return an error code. - EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd)); - - // Skips of nonzero size always return an error code. - EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd)); - - // Seeks to 0 offset return in error. - EXPECT_FALSE(opj_seek_from_memory(0, &dd)); - - // Seeks to non-zero offsets return in error. - EXPECT_FALSE(opj_seek_from_memory(1, &dd)); -} - -TEST(fxcodec, DecodeDataZeroSize) { - DecodeData dd(stream_data, 0); - unsigned char buffer[16]; - - // Reads of size 0 do nothing but return an error code. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - - // Reads of nonzero size do nothing but return an error code. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd)); - EXPECT_EQ(0xbd, buffer[0]); - - // writes of size 0 do nothing but return an error code. - EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, 0, &dd)); - - // writes of nonzero size do nothing but return an error code. - EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, sizeof(buffer), &dd)); - - // Skips of size 0 always return an error code. - EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd)); - - // Skips of nonzero size always return an error code. - EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd)); - - // Seeks to 0 offset return in error. - EXPECT_FALSE(opj_seek_from_memory(0, &dd)); - - // Seeks to non-zero offsets return in error. - EXPECT_FALSE(opj_seek_from_memory(1, &dd)); -} - -TEST(fxcodec, DecodeDataReadInBounds) { - unsigned char buffer[16]; - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Exact sized read in a single call. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer), &dd)); - EXPECT_EQ(0x00, buffer[0]); - EXPECT_EQ(0x01, buffer[1]); - EXPECT_EQ(0x02, buffer[2]); - EXPECT_EQ(0x03, buffer[3]); - EXPECT_EQ(0x84, buffer[4]); - EXPECT_EQ(0x85, buffer[5]); - EXPECT_EQ(0x86, buffer[6]); - EXPECT_EQ(0x87, buffer[7]); - EXPECT_EQ(0xbd, buffer[8]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Simple read. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(2u, opj_read_from_memory(buffer, 2, &dd)); - EXPECT_EQ(0x00, buffer[0]); - EXPECT_EQ(0x01, buffer[1]); - EXPECT_EQ(0xbd, buffer[2]); - - // Read of size 0 doesn't affect things. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(0u, opj_read_from_memory(buffer, 0, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - - // Read exactly up to end of data. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd)); - EXPECT_EQ(0x02, buffer[0]); - EXPECT_EQ(0x03, buffer[1]); - EXPECT_EQ(0x84, buffer[2]); - EXPECT_EQ(0x85, buffer[3]); - EXPECT_EQ(0x86, buffer[4]); - EXPECT_EQ(0x87, buffer[5]); - EXPECT_EQ(0xbd, buffer[6]); - - // Read of size 0 at EOF is still an error. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - } -} - -TEST(fxcodec, DecodeDataReadBeyondBounds) { - unsigned char buffer[16]; - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Read beyond bounds in a single step. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer) + 1, &dd)); - EXPECT_EQ(0x00, buffer[0]); - EXPECT_EQ(0x01, buffer[1]); - EXPECT_EQ(0x02, buffer[2]); - EXPECT_EQ(0x03, buffer[3]); - EXPECT_EQ(0x84, buffer[4]); - EXPECT_EQ(0x85, buffer[5]); - EXPECT_EQ(0x86, buffer[6]); - EXPECT_EQ(0x87, buffer[7]); - EXPECT_EQ(0xbd, buffer[8]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Read well beyond bounds in a single step. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(8u, opj_read_from_memory( - buffer, std::numeric_limits::max(), &dd)); - EXPECT_EQ(0x00, buffer[0]); - EXPECT_EQ(0x01, buffer[1]); - EXPECT_EQ(0x02, buffer[2]); - EXPECT_EQ(0x03, buffer[3]); - EXPECT_EQ(0x84, buffer[4]); - EXPECT_EQ(0x85, buffer[5]); - EXPECT_EQ(0x86, buffer[6]); - EXPECT_EQ(0x87, buffer[7]); - EXPECT_EQ(0xbd, buffer[8]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Read of size 6 gets first 6 bytes. - // rest of buffer intact. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd)); - EXPECT_EQ(0x00, buffer[0]); - EXPECT_EQ(0x01, buffer[1]); - EXPECT_EQ(0x02, buffer[2]); - EXPECT_EQ(0x03, buffer[3]); - EXPECT_EQ(0x84, buffer[4]); - EXPECT_EQ(0x85, buffer[5]); - EXPECT_EQ(0xbd, buffer[6]); - - // Read of size 6 gets remaining two bytes. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(2u, opj_read_from_memory(buffer, 6, &dd)); - EXPECT_EQ(0x86, buffer[0]); - EXPECT_EQ(0x87, buffer[1]); - EXPECT_EQ(0xbd, buffer[2]); - - // Read of 6 more gets nothing and leaves rest of buffer intact. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 6, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - } -} - -TEST(fxcodec, DecodeDataWriteInBounds) { - unsigned char stream[16]; - static unsigned char buffer_data[] = { - 0x00, 0x01, 0x02, 0x03, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84, - }; - { - // Pretend the stream can only hold 4 bytes. - DecodeData dd(stream, 4); - - memset(stream, 0xbd, sizeof(stream)); - EXPECT_EQ(4u, opj_write_from_memory(buffer_data, 4, &dd)); - EXPECT_EQ(0x00, stream[0]); - EXPECT_EQ(0x01, stream[1]); - EXPECT_EQ(0x02, stream[2]); - EXPECT_EQ(0x03, stream[3]); - EXPECT_EQ(0xbd, stream[4]); - } - { - // Pretend the stream can only hold 4 bytes. - DecodeData dd(stream, 4); - - memset(stream, 0xbd, sizeof(stream)); - EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 2, &dd)); - EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 2, &dd)); - EXPECT_EQ(0x00, stream[0]); - EXPECT_EQ(0x01, stream[1]); - EXPECT_EQ(0x00, stream[2]); - EXPECT_EQ(0x01, stream[3]); - EXPECT_EQ(0xbd, stream[4]); - } -} - -TEST(fxcodec, DecodeDataWriteBeyondBounds) { - unsigned char stream[16]; - static unsigned char buffer_data[] = { - 0x10, 0x11, 0x12, 0x13, 0x94, 0x95, 0x96, 0x97, - }; - { - // Pretend the stream can only hold 4 bytes. - DecodeData dd(stream, 4); - - // Write ending past EOF transfers up til EOF. - memset(stream, 0xbd, sizeof(stream)); - EXPECT_EQ(4u, opj_write_from_memory(buffer_data, 5, &dd)); - EXPECT_EQ(0x10, stream[0]); - EXPECT_EQ(0x11, stream[1]); - EXPECT_EQ(0x12, stream[2]); - EXPECT_EQ(0x13, stream[3]); - EXPECT_EQ(0xbd, stream[4]); - - // Subsequent writes fail. - memset(stream, 0xbd, sizeof(stream)); - EXPECT_EQ(kWriteError, opj_write_from_memory(buffer_data, 5, &dd)); - EXPECT_EQ(0xbd, stream[0]); - } - { - // Pretend the stream can only hold 4 bytes. - DecodeData dd(stream, 4); - - // Write ending past EOF (two steps) transfers up til EOF. - memset(stream, 0xbd, sizeof(stream)); - EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 2, &dd)); - EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 4, &dd)); - EXPECT_EQ(0x10, stream[0]); - EXPECT_EQ(0x11, stream[1]); - EXPECT_EQ(0x10, stream[2]); - EXPECT_EQ(0x11, stream[3]); - EXPECT_EQ(0xbd, stream[4]); - - // Subsequent writes fail. - memset(stream, 0xbd, sizeof(stream)); - EXPECT_EQ(kWriteError, opj_write_from_memory(buffer_data, 5, &dd)); - EXPECT_EQ(0xbd, stream[0]); - } -} - -// Note: Some care needs to be taken here because the skip/seek functions -// take OPJ_OFF_T's as arguments, which are typically a signed type. -TEST(fxcodec, DecodeDataSkip) { - unsigned char buffer[16]; - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Skiping within buffer is allowed. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(1, opj_skip_from_memory(1, &dd)); - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x01, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Skiping 0 bytes changes nothing. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(0, opj_skip_from_memory(0, &dd)); - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x02, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Skiping to EOS-1 is possible. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(4, opj_skip_from_memory(4, &dd)); - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x87, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Next read fails. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Skiping directly to EOS is allowed. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(8, opj_skip_from_memory(8, &dd)); - - // Next read fails. - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Skipping beyond end of stream is allowed and returns full distance. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(9, opj_skip_from_memory(9, &dd)); - - // Next read fails. - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Skipping way beyond EOS is allowd, doesn't wrap, and returns - // full distance. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(4, opj_skip_from_memory(4, &dd)); - EXPECT_EQ(std::numeric_limits::max(), - opj_skip_from_memory(std::numeric_limits::max(), &dd)); - - // Next read fails. If it succeeds, it may mean we wrapped. - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Negative skip within buffer not is allowed, position unchanged. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(4, opj_skip_from_memory(4, &dd)); - EXPECT_EQ(kSkipError, opj_skip_from_memory(-2, &dd)); - - // Next read succeeds as if nothing has happenned. - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x84, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Negative skip before buffer is not allowed, position unchanged. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd)); - - // Next read succeeds as if nothing has happenned. - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x85, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Negative skip way before buffer is not allowed, doesn't wrap - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(4, opj_skip_from_memory(4, &dd)); - EXPECT_EQ(kSkipError, - opj_skip_from_memory(std::numeric_limits::min(), &dd)); - - // Next read succeeds. If it fails, it may mean we wrapped. - EXPECT_EQ(1, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x84, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - } - { - DecodeData dd(stream_data, sizeof(stream_data)); - - // Negative skip after EOS isn't alowed, still EOS. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_EQ(8, opj_skip_from_memory(8, &dd)); - EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd)); - - // Next read fails. - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - } -} - -TEST(fxcodec, DecodeDataSeek) { - unsigned char buffer[16]; - DecodeData dd(stream_data, sizeof(stream_data)); - - // Seeking within buffer is allowed and read succeeds - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_TRUE(opj_seek_from_memory(1, &dd)); - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x01, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Seeking before start returns error leaving position unchanged. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_FALSE(opj_seek_from_memory(-1, &dd)); - EXPECT_EQ(1, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x02, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Seeking way before start returns error leaving position unchanged. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_FALSE( - opj_seek_from_memory(std::numeric_limits::min(), &dd)); - EXPECT_EQ(1, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x03, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Seeking exactly to EOS is allowed but read fails. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_TRUE(opj_seek_from_memory(8, &dd)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - - // Seeking back to zero offset is allowed and read succeeds. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_TRUE(opj_seek_from_memory(0, &dd)); - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x00, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Seeking beyond end of stream is allowed but read fails. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_TRUE(opj_seek_from_memory(16, &dd)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); - - // Seeking within buffer after seek past EOF restores good state. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_TRUE(opj_seek_from_memory(4, &dd)); - EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0x84, buffer[0]); - EXPECT_EQ(0xbd, buffer[1]); - - // Seeking way beyond EOS is allowed, doesn't wrap, and read fails. - memset(buffer, 0xbd, sizeof(buffer)); - EXPECT_TRUE(opj_seek_from_memory(std::numeric_limits::max(), &dd)); - EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd)); - EXPECT_EQ(0xbd, buffer[0]); -} - -TEST(fxcodec, YUV420ToRGB) { - opj_image_comp_t u; - memset(&u, 0, sizeof(u)); - u.dx = 1; - u.dy = 1; - u.w = 16; - u.h = 16; - u.prec = 8; - u.bpp = 8; - opj_image_comp_t v; - memset(&v, 0, sizeof(v)); - v.dx = 1; - v.dy = 1; - v.w = 16; - v.h = 16; - v.prec = 8; - v.bpp = 8; - opj_image_comp_t y; - memset(&y, 0, sizeof(y)); - y.dx = 1; - y.dy = 1; - y.prec = 8; - y.bpp = 8; - opj_image_t img; - memset(&img, 0, sizeof(img)); - img.numcomps = 3; - img.color_space = OPJ_CLRSPC_SYCC; - img.comps = FX_Alloc(opj_image_comp_t, 3); - const struct { - OPJ_UINT32 w; - bool expected; - } cases[] = {{0, false}, - {1, false}, - {30, false}, - {31, true}, - {32, true}, - {33, true}, - {34, false}, - {UINT_MAX, false}}; - for (int i = 0; i < sizeof(cases) / sizeof(cases[0]); ++i) { - y.w = cases[i].w; - y.h = y.w; - img.x1 = y.w; - img.y1 = y.h; - y.data = FX_Alloc(OPJ_INT32, y.w * y.h); - memset(y.data, 1, y.w * y.h * sizeof(OPJ_INT32)); - u.data = FX_Alloc(OPJ_INT32, u.w * u.h); - memset(u.data, 0, u.w * u.h * sizeof(OPJ_INT32)); - v.data = FX_Alloc(OPJ_INT32, v.w * v.h); - memset(v.data, 0, v.w * v.h * sizeof(OPJ_INT32)); - img.comps[0] = y; - img.comps[1] = u; - img.comps[2] = v; - sycc420_to_rgb(&img); - if (cases[i].expected) { - EXPECT_EQ(img.comps[0].w, img.comps[1].w); - EXPECT_EQ(img.comps[0].h, img.comps[1].h); - EXPECT_EQ(img.comps[0].w, img.comps[2].w); - EXPECT_EQ(img.comps[0].h, img.comps[2].h); - } else { - EXPECT_NE(img.comps[0].w, img.comps[1].w); - EXPECT_NE(img.comps[0].h, img.comps[1].h); - EXPECT_NE(img.comps[0].w, img.comps[2].w); - EXPECT_NE(img.comps[0].h, img.comps[2].h); - } - FX_Free(img.comps[0].data); - FX_Free(img.comps[1].data); - FX_Free(img.comps[2].data); - } - FX_Free(img.comps); -} diff --git a/core/src/fxcodec/codec/fx_codec_png.cpp b/core/src/fxcodec/codec/fx_codec_png.cpp deleted file mode 100644 index c8cb1b8a6a..0000000000 --- a/core/src/fxcodec/codec/fx_codec_png.cpp +++ /dev/null @@ -1,254 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "core/src/fxcodec/codec/codec_int.h" - -extern "C" { -#undef FAR -#include "third_party/libpng16/png.h" -} - -static void _png_error_data(png_structp png_ptr, png_const_charp error_msg) { - if (png_get_error_ptr(png_ptr)) { - FXSYS_strncpy((char*)png_get_error_ptr(png_ptr), error_msg, - PNG_ERROR_SIZE - 1); - } - longjmp(png_jmpbuf(png_ptr), 1); -} -static void _png_warning_data(png_structp png_ptr, png_const_charp error_msg) {} -static void _png_load_bmp_attribute(png_structp png_ptr, - png_infop info_ptr, - CFX_DIBAttribute* pAttribute) { - if (pAttribute) { -#if defined(PNG_pHYs_SUPPORTED) - pAttribute->m_nXDPI = png_get_x_pixels_per_meter(png_ptr, info_ptr); - pAttribute->m_nYDPI = png_get_y_pixels_per_meter(png_ptr, info_ptr); - png_uint_32 res_x, res_y; - int unit_type; - png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type); - switch (unit_type) { - case PNG_RESOLUTION_METER: - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER; - break; - default: - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_NONE; - } -#endif -#if defined(PNG_iCCP_SUPPORTED) - png_charp icc_name; - png_bytep icc_profile; - png_uint_32 icc_proflen; - int compress_type; - png_get_iCCP(png_ptr, info_ptr, &icc_name, &compress_type, &icc_profile, - &icc_proflen); -#endif - int bTime = 0; -#if defined(PNG_tIME_SUPPORTED) - png_timep t = NULL; - png_get_tIME(png_ptr, info_ptr, &t); - if (t) { - FXSYS_memset(pAttribute->m_strTime, 0, sizeof(pAttribute->m_strTime)); - FXSYS_snprintf((FX_CHAR*)pAttribute->m_strTime, - sizeof(pAttribute->m_strTime), "%4d:%2d:%2d %2d:%2d:%2d", - t->year, t->month, t->day, t->hour, t->minute, t->second); - pAttribute->m_strTime[sizeof(pAttribute->m_strTime) - 1] = 0; - bTime = 1; - } -#endif -#if defined(PNG_TEXT_SUPPORTED) - int i; - FX_STRSIZE len; - const FX_CHAR* buf; - int num_text; - png_textp text = NULL; - png_get_text(png_ptr, info_ptr, &text, &num_text); - for (i = 0; i < num_text; i++) { - len = FXSYS_strlen(text[i].key); - buf = "Time"; - if (!FXSYS_memcmp(buf, text[i].key, std::min(len, FXSYS_strlen(buf)))) { - if (!bTime) { - FXSYS_memset(pAttribute->m_strTime, 0, sizeof(pAttribute->m_strTime)); - FXSYS_memcpy( - pAttribute->m_strTime, text[i].text, - std::min(sizeof(pAttribute->m_strTime) - 1, text[i].text_length)); - } - } else { - buf = "Author"; - if (!FXSYS_memcmp(buf, text[i].key, std::min(len, FXSYS_strlen(buf)))) { - pAttribute->m_strAuthor.Empty(); - pAttribute->m_strAuthor.Load((uint8_t*)text[i].text, - (FX_STRSIZE)text[i].text_length); - } - } - } -#endif - } -} -struct FXPNG_Context { - png_structp png_ptr; - png_infop info_ptr; - void* parent_ptr; - void* child_ptr; - - void* (*m_AllocFunc)(unsigned int); - void (*m_FreeFunc)(void*); -}; -extern "C" { -static void* _png_alloc_func(unsigned int size) { - return FX_Alloc(char, size); -} -static void _png_free_func(void* p) { - FX_Free(p); -} -}; -static void _png_get_header_func(png_structp png_ptr, png_infop info_ptr) { - FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr); - if (p == NULL) { - return; - } - CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; - if (pModule == NULL) { - return; - } - png_uint_32 width = 0, height = 0; - int bpc = 0, color_type = 0, color_type1 = 0, pass = 0; - double gamma = 1.0; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bpc, &color_type, NULL, - NULL, NULL); - color_type1 = color_type; - if (bpc > 8) { - png_set_strip_16(png_ptr); - } else if (bpc < 8) { - png_set_expand_gray_1_2_4_to_8(png_ptr); - } - bpc = 8; - if (color_type == PNG_COLOR_TYPE_PALETTE) { - png_set_palette_to_rgb(png_ptr); - } - pass = png_set_interlace_handling(png_ptr); - if (!pModule->ReadHeaderCallback(p->child_ptr, width, height, bpc, pass, - &color_type, &gamma)) { - png_error(p->png_ptr, "Read Header Callback Error"); - } - int intent; - if (png_get_sRGB(png_ptr, info_ptr, &intent)) { - png_set_gamma(png_ptr, gamma, 0.45455); - } else { - double image_gamma; - if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) { - png_set_gamma(png_ptr, gamma, image_gamma); - } else { - png_set_gamma(png_ptr, gamma, 0.45455); - } - } - switch (color_type) { - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_GRAY_ALPHA: { - if (color_type1 & PNG_COLOR_MASK_COLOR) { - png_set_rgb_to_gray(png_ptr, 1, 0.299, 0.587); - } - } break; - case PNG_COLOR_TYPE_PALETTE: - if (color_type1 != PNG_COLOR_TYPE_PALETTE) { - png_error(p->png_ptr, "Not Support Output Palette Now"); - } - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - if (!(color_type1 & PNG_COLOR_MASK_COLOR)) { - png_set_gray_to_rgb(png_ptr); - } - png_set_bgr(png_ptr); - break; - } - if (!(color_type & PNG_COLOR_MASK_ALPHA)) { - png_set_strip_alpha(png_ptr); - } - if (color_type & PNG_COLOR_MASK_ALPHA && - !(color_type1 & PNG_COLOR_MASK_ALPHA)) { - png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); - } - png_read_update_info(png_ptr, info_ptr); -} -static void _png_get_end_func(png_structp png_ptr, png_infop info_ptr) {} -static void _png_get_row_func(png_structp png_ptr, - png_bytep new_row, - png_uint_32 row_num, - int pass) { - FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr); - if (p == NULL) { - return; - } - CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; - uint8_t* src_buf = NULL; - if (!pModule->AskScanlineBufCallback(p->child_ptr, row_num, src_buf)) { - png_error(png_ptr, "Ask Scanline buffer Callback Error"); - } - if (src_buf) { - png_progressive_combine_row(png_ptr, src_buf, new_row); - } - pModule->FillScanlineBufCompletedCallback(p->child_ptr, pass, row_num); -} -void* CCodec_PngModule::Start(void* pModule) { - FXPNG_Context* p = (FXPNG_Context*)FX_Alloc(uint8_t, sizeof(FXPNG_Context)); - if (p == NULL) { - return NULL; - } - p->m_AllocFunc = _png_alloc_func; - p->m_FreeFunc = _png_free_func; - p->png_ptr = NULL; - p->info_ptr = NULL; - p->parent_ptr = (void*)this; - p->child_ptr = pModule; - p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (p->png_ptr == NULL) { - FX_Free(p); - return NULL; - } - p->info_ptr = png_create_info_struct(p->png_ptr); - if (p->info_ptr == NULL) { - png_destroy_read_struct(&(p->png_ptr), (png_infopp)NULL, (png_infopp)NULL); - FX_Free(p); - return NULL; - } - if (setjmp(png_jmpbuf(p->png_ptr))) { - if (p) { - png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL); - FX_Free(p); - } - return NULL; - } - png_set_progressive_read_fn(p->png_ptr, p, _png_get_header_func, - _png_get_row_func, _png_get_end_func); - png_set_error_fn(p->png_ptr, m_szLastError, (png_error_ptr)_png_error_data, - (png_error_ptr)_png_warning_data); - return p; -} -void CCodec_PngModule::Finish(void* pContext) { - FXPNG_Context* p = (FXPNG_Context*)pContext; - if (p) { - png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL); - p->m_FreeFunc(p); - } -} -FX_BOOL CCodec_PngModule::Input(void* pContext, - const uint8_t* src_buf, - FX_DWORD src_size, - CFX_DIBAttribute* pAttribute) { - FXPNG_Context* p = (FXPNG_Context*)pContext; - if (setjmp(png_jmpbuf(p->png_ptr))) { - if (pAttribute && - 0 == FXSYS_strcmp(m_szLastError, "Read Header Callback Error")) { - _png_load_bmp_attribute(p->png_ptr, p->info_ptr, pAttribute); - } - return FALSE; - } - png_process_data(p->png_ptr, p->info_ptr, (uint8_t*)src_buf, src_size); - return TRUE; -} diff --git a/core/src/fxcodec/codec/fx_codec_progress.cpp b/core/src/fxcodec/codec/fx_codec_progress.cpp deleted file mode 100644 index 5d8502a87a..0000000000 --- a/core/src/fxcodec/codec/fx_codec_progress.cpp +++ /dev/null @@ -1,2299 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "core/src/fxcodec/codec/fx_codec_progress.h" -void CFXCODEC_WeightTable::Calc(int dest_len, - int dest_min, - int dest_max, - int src_len, - int src_min, - int src_max, - FX_BOOL bInterpol) { - if (m_pWeightTables) { - FX_Free(m_pWeightTables); - } - double scale, base; - scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len; - if (dest_len < 0) { - base = (FX_FLOAT)(src_len); - } else { - base = 0.0f; - } - m_ItemSize = - (int)(sizeof(int) * 2 + - sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1)); - m_DestMin = dest_min; - m_pWeightTables = FX_Alloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); - if (m_pWeightTables == NULL) { - return; - } - if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { - for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { - PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); - double src_pos = dest_pixel * scale + scale / 2 + base; - if (bInterpol) { - pixel_weights.m_SrcStart = - (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); - pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); - if (pixel_weights.m_SrcStart < src_min) { - pixel_weights.m_SrcStart = src_min; - } - if (pixel_weights.m_SrcEnd >= src_max) { - pixel_weights.m_SrcEnd = src_max - 1; - } - if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { - pixel_weights.m_Weights[0] = 65536; - } else { - pixel_weights.m_Weights[1] = FXSYS_round( - (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * - 65536); - pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; - } - } else { - pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = - (int)FXSYS_floor((FX_FLOAT)src_pos); - pixel_weights.m_Weights[0] = 65536; - } - } - return; - } - for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { - PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); - double src_start = dest_pixel * scale + base; - double src_end = src_start + scale; - int start_i, end_i; - if (src_start < src_end) { - start_i = (int)FXSYS_floor((FX_FLOAT)src_start); - end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); - } else { - start_i = (int)FXSYS_floor((FX_FLOAT)src_end); - end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); - } - if (start_i < src_min) { - start_i = src_min; - } - if (end_i >= src_max) { - end_i = src_max - 1; - } - if (start_i > end_i) { - pixel_weights.m_SrcStart = start_i; - pixel_weights.m_SrcEnd = start_i; - continue; - } - pixel_weights.m_SrcStart = start_i; - pixel_weights.m_SrcEnd = end_i; - for (int j = start_i; j <= end_i; j++) { - double dest_start = ((FX_FLOAT)j - base) / scale; - double dest_end = ((FX_FLOAT)(j + 1) - base) / scale; - if (dest_start > dest_end) { - double temp = dest_start; - dest_start = dest_end; - dest_end = temp; - } - double area_start = dest_start > (FX_FLOAT)(dest_pixel) - ? dest_start - : (FX_FLOAT)(dest_pixel); - double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) - ? (FX_FLOAT)(dest_pixel + 1) - : dest_end; - double weight = area_start >= area_end ? 0.0f : area_end - area_start; - if (weight == 0 && j == end_i) { - pixel_weights.m_SrcEnd--; - break; - } - pixel_weights.m_Weights[j - start_i] = - FXSYS_round((FX_FLOAT)(weight * 65536)); - } - } -} -void CFXCODEC_HorzTable::Calc(int dest_len, int src_len, FX_BOOL bInterpol) { - if (m_pWeightTables) { - FX_Free(m_pWeightTables); - } - double scale = (double)dest_len / (double)src_len; - m_ItemSize = sizeof(int) * 4; - int size = dest_len * m_ItemSize + 4; - m_pWeightTables = FX_Alloc(uint8_t, size); - if (m_pWeightTables == NULL) { - return; - } - FXSYS_memset(m_pWeightTables, 0, size); - if (scale > 1) { - int pre_des_col = 0; - for (int src_col = 0; src_col < src_len; src_col++) { - double des_col_f = src_col * scale; - int des_col = FXSYS_round((FX_FLOAT)des_col_f); - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); - pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - if (src_col == src_len - 1 && des_col < dest_len - 1) { - for (int des_col_index = pre_des_col + 1; des_col_index < dest_len; - des_col_index++) { - pWeight = - (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); - pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - return; - } - int des_col_len = des_col - pre_des_col; - for (int des_col_index = pre_des_col + 1; des_col_index < des_col; - des_col_index++) { - pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize); - pWeight->m_SrcStart = src_col - 1; - pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = - bInterpol ? FXSYS_round((FX_FLOAT)( - ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index) / - (FX_FLOAT)des_col_len * 65536)) - : 65536; - pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; - } - pre_des_col = des_col; - } - return; - } - for (int des_col = 0; des_col < dest_len; des_col++) { - double src_col_f = des_col / scale; - int src_col = FXSYS_round((FX_FLOAT)src_col_f); - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize); - pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } -} -void CFXCODEC_VertTable::Calc(int dest_len, int src_len) { - if (m_pWeightTables) { - FX_Free(m_pWeightTables); - } - double scale = (double)dest_len / (double)src_len; - m_ItemSize = sizeof(int) * 4; - int size = dest_len * m_ItemSize + 4; - m_pWeightTables = FX_Alloc(uint8_t, size); - if (m_pWeightTables == NULL) { - return; - } - FXSYS_memset(m_pWeightTables, 0, size); - if (scale > 1) { - double step = 0.0; - int src_row = 0; - while (step < (double)dest_len) { - int start_step = (int)step; - step = scale * (++src_row); - int end_step = (int)step; - if (end_step >= dest_len) { - end_step = dest_len; - for (int des_row = start_step; des_row < end_step; des_row++) { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); - pWeight->m_SrcStart = start_step; - pWeight->m_SrcEnd = start_step; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - return; - } - int length = end_step - start_step; - { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize); - pWeight->m_SrcStart = start_step; - pWeight->m_SrcEnd = start_step; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - for (int des_row = start_step + 1; des_row < end_step; des_row++) { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); - pWeight->m_SrcStart = start_step; - pWeight->m_SrcEnd = end_step; - pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / - (FX_FLOAT)length * 65536); - pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; - } - } - } else { - for (int des_row = 0; des_row < dest_len; des_row++) { - PixelWeight* pWeight = - (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); - pWeight->m_SrcStart = des_row; - pWeight->m_SrcEnd = des_row; - pWeight->m_Weights[0] = 65536; - pWeight->m_Weights[1] = 0; - } - } -} -CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder( - CCodec_ModuleMgr* pCodecMgr) { - m_pFile = NULL; - m_pJpegContext = NULL; - m_pPngContext = NULL; - m_pGifContext = NULL; - m_pBmpContext = NULL; - m_pTiffContext = NULL; - m_pCodecMgr = NULL; - m_pSrcBuf = NULL; - m_pDecodeBuf = NULL; - m_pDeviceBitmap = NULL; - m_pSrcPalette = NULL; - m_pCodecMgr = pCodecMgr; - m_offSet = 0; - m_SrcSize = 0; - m_ScanlineSize = 0; - m_SrcWidth = m_SrcHeight = 0; - m_SrcComponents = 0; - m_SrcBPC = 0; - m_SrcPassNumber = 0; - m_clipBox = FX_RECT(0, 0, 0, 0); - m_imagType = FXCODEC_IMAGE_UNKNOWN; - m_status = FXCODEC_STATUS_DECODE_FINISH; - m_TransMethod = -1; - m_SrcRow = 0; - m_SrcFormat = FXCodec_Invalid; - m_bInterpol = TRUE; - m_FrameNumber = 0; - m_FrameCur = 0; - m_SrcPaletteNumber = 0; - m_GifPltNumber = 0; - m_GifBgIndex = 0; - m_pGifPalette = NULL; - m_GifTransIndex = -1; - m_GifFrameRect = FX_RECT(0, 0, 0, 0); - m_BmpIsTopBottom = FALSE; -} -CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { - m_pFile = NULL; - if (m_pJpegContext) { - m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); - } - if (m_pPngContext) { - m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); - } - if (m_pGifContext) { - m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); - } - if (m_pBmpContext) { - m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); - } - if (m_pTiffContext) { - m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); - } - FX_Free(m_pSrcBuf); - FX_Free(m_pDecodeBuf); - FX_Free(m_pSrcPalette); -} -FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData( - ICodec_JpegModule* pJpegModule, - FXCODEC_STATUS& err_status) { - FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); - if (dwSize <= m_offSet) { - return FALSE; - } - dwSize = dwSize - m_offSet; - FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL); - if (dwAvail == m_SrcSize) { - if (dwSize > FXCODEC_BLOCK_SIZE) { - dwSize = FXCODEC_BLOCK_SIZE; - } - m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / - FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; - m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); - if (!m_pSrcBuf) { - err_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - } else { - FX_DWORD dwConsume = m_SrcSize - dwAvail; - if (dwAvail) { - FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); - } - if (dwSize > dwConsume) { - dwSize = dwConsume; - } - } - if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { - err_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += dwSize; - pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail); - return TRUE; -} -FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, - int width, - int height, - int bpc, - int pass, - int* color_type, - double* gamma) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - if (pCodec->m_pDeviceBitmap == NULL) { - pCodec->m_SrcWidth = width; - pCodec->m_SrcHeight = height; - pCodec->m_SrcBPC = bpc; - pCodec->m_SrcPassNumber = pass; - pCodec->m_SrcComponents = - *color_type == 0 ? 1 : *color_type == 2 - ? 3 - : *color_type == 3 - ? 4 - : *color_type == 4 - ? 2 - : *color_type == 6 ? 4 : 0; - pCodec->m_clipBox = FX_RECT(0, 0, width, height); - return FALSE; - } - FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat(); - switch (format) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - ASSERT(FALSE); - return FALSE; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: - *color_type = 0; - break; - case FXDIB_Rgb: - *color_type = 2; - break; - case FXDIB_Rgb32: - case FXDIB_Argb: - *color_type = 6; - break; - default: - ASSERT(FALSE); - return FALSE; - } - *gamma = FXCODEC_PNG_GAMMA; - return TRUE; -} -FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, - int line, - uint8_t*& src_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - if (!pDIBitmap) { - ASSERT(false); - return FALSE; - } - if (line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) { - double scale_y = - (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height(); - int32_t row = - (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY; - uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row); - uint8_t* des_scan = pCodec->m_pDecodeBuf; - src_buf = pCodec->m_pDecodeBuf; - int32_t src_Bpp = pDIBitmap->GetBPP() >> 3; - int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3; - int32_t src_left = pCodec->m_startX; - int32_t des_left = pCodec->m_clipBox.left; - src_scan += src_left * src_Bpp; - des_scan += des_left * des_Bpp; - for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) { - PixelWeight* pPixelWeights = - pCodec->m_WeightHorzOO.GetPixelWeight(src_col); - if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) { - continue; - } - switch (pDIBitmap->GetFormat()) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - ASSERT(FALSE); - return FALSE; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDIBitmap->GetPalette()) { - return FALSE; - } - FX_DWORD des_g = 0; - des_g += pPixelWeights->m_Weights[0] * src_scan[src_col]; - des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - const uint8_t* p = src_scan + src_col * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p); - uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; - *pDes++ = (uint8_t)((des_b) >> 16); - *pDes++ = (uint8_t)((des_g) >> 16); - *pDes = (uint8_t)((des_r) >> 16); - } break; - case FXDIB_Argb: { - FX_DWORD des_r = 0, des_g = 0, des_b = 0; - const uint8_t* p = src_scan + src_col * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p++); - uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; - *pDes++ = (uint8_t)((des_b) >> 16); - *pDes++ = (uint8_t)((des_g) >> 16); - *pDes++ = (uint8_t)((des_r) >> 16); - *pDes = *p; - } break; - default: - return FALSE; - } - } - } - return TRUE; -} -void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz( - CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format) { - uint8_t* des_scan = (uint8_t*)pDeviceBitmap->GetScanline(des_line); - int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3; - int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3; - int32_t src_left = m_clipBox.left; - int32_t des_left = m_startX; - src_scan += src_left * src_Bpp; - des_scan += des_left * des_Bpp; - for (int32_t des_col = 0; des_col < m_sizeX; des_col++) { - PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col); - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - ASSERT(FALSE); - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette()) { - return; - } - FX_DWORD des_g = 0; - des_g += - pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart]; - des_g += - pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd]; - *des_scan++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - const uint8_t* p = src_scan; - p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p); - p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; - des_b += pPixelWeights->m_Weights[1] * (*p++); - des_g += pPixelWeights->m_Weights[1] * (*p++); - des_r += pPixelWeights->m_Weights[1] * (*p); - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - const uint8_t* p = src_scan; - p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; - des_b += pPixelWeights->m_Weights[0] * (*p++); - des_g += pPixelWeights->m_Weights[0] * (*p++); - des_r += pPixelWeights->m_Weights[0] * (*p++); - des_a += pPixelWeights->m_Weights[0] * (*p); - p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; - des_b += pPixelWeights->m_Weights[1] * (*p++); - des_g += pPixelWeights->m_Weights[1] * (*p++); - des_r += pPixelWeights->m_Weights[1] * (*p++); - des_a += pPixelWeights->m_Weights[1] * (*p); - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } -} -void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, - int pass, - int line) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - ASSERT(pDIBitmap); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; - if (line >= src_top && line < src_bottom) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = line - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - pCodec->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - return; - } - if (pass == 6 && scale_y > 1.0) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - } - } -} -FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, - FXCODEC_STATUS& err_status) { - FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); - if (dwSize <= m_offSet) { - return FALSE; - } - dwSize = dwSize - m_offSet; - FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL); - if (dwAvail == m_SrcSize) { - if (dwSize > FXCODEC_BLOCK_SIZE) { - dwSize = FXCODEC_BLOCK_SIZE; - } - m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / - FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; - m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); - if (!m_pSrcBuf) { - err_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - } else { - FX_DWORD dwConsume = m_SrcSize - dwAvail; - if (dwAvail) { - FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); - } - if (dwSize > dwConsume) { - dwSize = dwConsume; - } - } - if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { - err_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += dwSize; - pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail); - return TRUE; -} -void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback( - void* pModule, - FX_DWORD& cur_pos) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - FX_DWORD remain_size = - pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext); - cur_pos = pCodec->m_offSet - remain_size; -} -uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback( - void* pModule, - int32_t frame_num, - int32_t pal_size) { - return FX_Alloc(uint8_t, pal_size); -} -FX_BOOL CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback( - void* pModule, - FX_DWORD rcd_pos, - const FX_RECT& img_rc, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - FX_BOOL user_input, - int32_t trans_index, - int32_t disposal_method, - FX_BOOL interlace) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - pCodec->m_offSet = rcd_pos; - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - if (!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), - error_status)) { - return FALSE; - } - uint8_t* pPalette = NULL; - if (pal_num != 0 && pal_ptr) { - pPalette = (uint8_t*)pal_ptr; - } else { - pal_num = pCodec->m_GifPltNumber; - pPalette = pCodec->m_pGifPalette; - } - if (pCodec->m_pSrcPalette == NULL) { - pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); - } else if (pal_num > pCodec->m_SrcPaletteNumber) { - pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num); - } - if (pCodec->m_pSrcPalette == NULL) { - return FALSE; - } - pCodec->m_SrcPaletteNumber = pal_num; - for (int i = 0; i < pal_num; i++) { - FX_DWORD j = i * 3; - pCodec->m_pSrcPalette[i] = - ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]); - } - pCodec->m_GifTransIndex = trans_index; - pCodec->m_GifFrameRect = img_rc; - pCodec->m_SrcPassNumber = interlace ? 4 : 1; - int32_t pal_index = pCodec->m_GifBgIndex; - CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap; - if (trans_index >= pal_num) { - trans_index = -1; - } - if (trans_index != -1) { - pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff; - if (pDevice->HasAlpha()) { - pal_index = trans_index; - } - } - int startX = pCodec->m_startX; - int startY = pCodec->m_startY; - int sizeX = pCodec->m_sizeX; - int sizeY = pCodec->m_sizeY; - int Bpp = pDevice->GetBPP() / 8; - FX_ARGB argb = pCodec->m_pSrcPalette[pal_index]; - for (int row = 0; row < sizeY; row++) { - uint8_t* pScanline = - (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp; - switch (pCodec->m_TransMethod) { - case 3: { - uint8_t gray = - FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); - FXSYS_memset(pScanline, gray, sizeX); - break; - } - case 8: { - for (int col = 0; col < sizeX; col++) { - *pScanline++ = FXARGB_B(argb); - *pScanline++ = FXARGB_G(argb); - *pScanline++ = FXARGB_R(argb); - pScanline += Bpp - 3; - } - break; - } - case 12: { - for (int col = 0; col < sizeX; col++) { - FXARGB_SETDIB(pScanline, argb); - pScanline += 4; - } - break; - } - } - } - return TRUE; -} -void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - ASSERT(pDIBitmap); - int32_t img_width = pCodec->m_GifFrameRect.Width(); - if (!pDIBitmap->HasAlpha()) { - uint8_t* byte_ptr = row_buf; - for (int i = 0; i < img_width; i++) { - if (*byte_ptr == pCodec->m_GifTransIndex) { - *byte_ptr = pCodec->m_GifBgIndex; - } - byte_ptr++; - } - } - int32_t pal_index = pCodec->m_GifBgIndex; - if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) { - pal_index = pCodec->m_GifTransIndex; - } - FXSYS_memset(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth); - bool bLastPass = (row_num % 2) == 1; - int32_t line = row_num + pCodec->m_GifFrameRect.top; - int32_t left = pCodec->m_GifFrameRect.left; - FXSYS_memcpy(pCodec->m_pDecodeBuf + left, row_buf, img_width); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; - if (line >= src_top && line < src_bottom) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = line - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (scale_y > 1.0 && - (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - return; - } - if (scale_y > 1.0) { - int des_bottom = des_top + pCodec->m_sizeY; - int des_Bpp = pDIBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = pCodec->m_startX * des_Bpp; - if (des_row + (int)scale_y >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet; - int cur_row = des_row; - while (++cur_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet; - FX_DWORD size = pCodec->m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } - if (bLastPass) { - pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row); - } - } - } -} -void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert( - CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row) { - int des_Bpp = pDeviceBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = m_startX * des_Bpp; - int des_top = m_startY; - int des_row_1 = des_row - int(2 * scale_y); - if (des_row_1 < des_top) { - des_row_1 = des_top; - } - for (; des_row_1 < des_row; des_row_1++) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; - PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); - const uint8_t* scan_src1 = - pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + - des_ScanOffet; - const uint8_t* scan_src2 = - pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_Invalid: - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette()) { - return; - } - int des_g = 0; - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - scan_src1 += des_Bpp - 3; - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - scan_src2 += des_Bpp - 3; - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - scan_des += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - des_a += pWeight->m_Weights[0] * (*scan_src1++); - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - des_a += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - *scan_des++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } - } - int des_bottom = des_top + m_sizeY - 1; - if (des_row + (int)(2 * scale_y) >= des_bottom && - des_row + (int)scale_y < des_bottom) { - GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y); - } -} -FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, - FXCODEC_STATUS& err_status) { - FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); - if (dwSize <= m_offSet) { - return FALSE; - } - dwSize = dwSize - m_offSet; - FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL); - if (dwAvail == m_SrcSize) { - if (dwSize > FXCODEC_BLOCK_SIZE) { - dwSize = FXCODEC_BLOCK_SIZE; - } - m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / - FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; - m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); - if (!m_pSrcBuf) { - err_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - } else { - FX_DWORD dwConsume = m_SrcSize - dwAvail; - if (dwAvail) { - FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); - } - if (dwSize > dwConsume) { - dwSize = dwConsume; - } - } - if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { - err_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += dwSize; - pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail); - return TRUE; -} -FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback( - void* pModule, - FX_DWORD rcd_pos) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - pCodec->m_offSet = rcd_pos; - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - if (!pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(), - error_status)) { - return FALSE; - } - return TRUE; -} -void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; - ASSERT(pDIBitmap); - FXSYS_memcpy(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; - if (row_num >= src_top && row_num < src_bottom) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = row_num - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (scale_y > 1.0) { - if (pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); - return; - } else { - pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row); - } - } - } -} -void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row) { - int des_Bpp = pDeviceBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = m_startX * des_Bpp; - int des_top = m_startY; - int des_bottom = m_startY + m_sizeY; - int des_row_1 = des_row + int(scale_y); - if (des_row_1 >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - while (++des_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - return; - } - for (; des_row_1 > des_row; des_row_1--) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; - PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); - const uint8_t* scan_src1 = - pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + - des_ScanOffet; - const uint8_t* scan_src2 = - pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_Invalid: - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette()) { - return; - } - int des_g = 0; - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - scan_src1 += des_Bpp - 3; - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - scan_src2 += des_Bpp - 3; - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - scan_des += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - des_a += pWeight->m_Weights[0] * (*scan_src1++); - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - des_a += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - *scan_des++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } - } -} -FX_BOOL CCodec_ProgressiveDecoder::DetectImageType( - FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute) { - m_offSet = 0; - FX_DWORD size = (FX_DWORD)m_pFile->GetSize(); - if (size > FXCODEC_BLOCK_SIZE) { - size = FXCODEC_BLOCK_SIZE; - } - FX_Free(m_pSrcBuf); - m_pSrcBuf = FX_Alloc(uint8_t, size); - FXSYS_memset(m_pSrcBuf, 0, size); - m_SrcSize = size; - switch (imageType) { - case FXCODEC_IMAGE_BMP: { - ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); - if (pBmpModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - pBmpModule->InputImagePositionBufCallback = - BmpInputImagePositionBufCallback; - pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback; - m_pBmpContext = pBmpModule->Start((void*)this); - if (m_pBmpContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size); - FX_DWORD* pPalette = NULL; - int32_t readResult = pBmpModule->ReadHeader( - m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, - &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; - if (!BmpReadMoreData(pBmpModule, error_status)) { - m_status = error_status; - return FALSE; - } - readResult = pBmpModule->ReadHeader( - m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, - &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); - } - if (readResult == 1) { - m_SrcBPC = 8; - m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); - FX_Free(m_pSrcPalette); - if (m_SrcPaletteNumber) { - m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber); - FXSYS_memcpy(m_pSrcPalette, pPalette, - m_SrcPaletteNumber * sizeof(FX_DWORD)); - } else { - m_pSrcPalette = nullptr; - } - return TRUE; - } - if (m_pBmpContext) { - pBmpModule->Finish(m_pBmpContext); - m_pBmpContext = NULL; - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } break; - case FXCODEC_IMAGE_JPG: { - ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); - if (pJpegModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - m_pJpegContext = pJpegModule->Start(); - if (m_pJpegContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size); - int32_t readResult = - pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, - &m_SrcComponents, pAttribute); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; - if (!JpegReadMoreData(pJpegModule, error_status)) { - m_status = error_status; - return FALSE; - } - readResult = - pJpegModule->ReadHeader(m_pJpegContext, &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 = NULL; - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } break; - case FXCODEC_IMAGE_PNG: { - ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); - if (pPngModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - pPngModule->ReadHeaderCallback = - CCodec_ProgressiveDecoder::PngReadHeaderFunc; - pPngModule->AskScanlineBufCallback = - CCodec_ProgressiveDecoder::PngAskScanlineBufFunc; - pPngModule->FillScanlineBufCompletedCallback = - CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc; - m_pPngContext = pPngModule->Start((void*)this); - if (m_pPngContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute); - while (bResult) { - FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; - FX_DWORD input_size = - remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; - if (input_size == 0) { - if (m_pPngContext) { - pPngModule->Finish(m_pPngContext); - } - m_pPngContext = NULL; - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - if (m_pSrcBuf && input_size > m_SrcSize) { - FX_Free(m_pSrcBuf); - m_pSrcBuf = FX_Alloc(uint8_t, input_size); - FXSYS_memset(m_pSrcBuf, 0, input_size); - m_SrcSize = input_size; - } - bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += input_size; - bResult = - pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute); - } - ASSERT(!bResult); - if (m_pPngContext) { - pPngModule->Finish(m_pPngContext); - m_pPngContext = NULL; - } - if (m_SrcPassNumber == 0) { - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - } break; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - if (pGifModule == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - pGifModule->RecordCurrentPositionCallback = - CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback; - pGifModule->AskLocalPaletteBufCallback = - CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback; - pGifModule->InputRecordPositionBufCallback = - CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback; - pGifModule->ReadScanlineCallback = - CCodec_ProgressiveDecoder::GifReadScanlineCallback; - m_pGifContext = pGifModule->Start((void*)this); - if (m_pGifContext == NULL) { - m_status = FXCODEC_STATUS_ERR_MEMORY; - return FALSE; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); - if (!bResult) { - m_status = FXCODEC_STATUS_ERR_READ; - return FALSE; - } - m_offSet += size; - pGifModule->Input(m_pGifContext, m_pSrcBuf, size); - m_SrcComponents = 1; - int32_t readResult = pGifModule->ReadHeader( - m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, - (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; - if (!GifReadMoreData(pGifModule, error_status)) { - m_status = error_status; - return FALSE; - } - readResult = pGifModule->ReadHeader( - m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, - (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); - } - if (readResult == 1) { - m_SrcBPC = 8; - m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); - return TRUE; - } - if (m_pGifContext) { - pGifModule->Finish(m_pGifContext); - m_pGifContext = NULL; - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } break; - case FXCODEC_IMAGE_TIF: { - ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); - if (pTiffModule == NULL) { - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - m_pTiffContext = pTiffModule->CreateDecoder(m_pFile); - if (m_pTiffContext == NULL) { - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - int32_t frames = 0; - pTiffModule->GetFrames(m_pTiffContext, frames); - FX_DWORD bpc; - FX_BOOL ret = pTiffModule->LoadFrameInfo( - m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, - (FX_DWORD&)m_SrcComponents, bpc, pAttribute); - m_SrcComponents = 4; - m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); - if (!ret) { - pTiffModule->DestroyDecoder(m_pTiffContext); - (m_pTiffContext = NULL); - (m_status = FXCODEC_STATUS_ERR_FORMAT); - return FALSE; - } - } break; - default: - m_status = FXCODEC_STATUS_ERR_FORMAT; - return FALSE; - } - return TRUE; -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo( - IFX_FileRead* pFile, - FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute) { - switch (m_status) { - case FXCODEC_STATUS_FRAME_READY: - case FXCODEC_STATUS_FRAME_TOBECONTINUE: - case FXCODEC_STATUS_DECODE_READY: - case FXCODEC_STATUS_DECODE_TOBECONTINUE: - return FXCODEC_STATUS_ERROR; - default: - break; - } - if (pFile == NULL) { - m_status = FXCODEC_STATUS_ERR_PARAMS; - m_pFile = NULL; - return m_status; - } - m_pFile = pFile; - m_offSet = 0; - m_SrcWidth = m_SrcHeight = 0; - m_SrcComponents = m_SrcBPC = 0; - m_clipBox = FX_RECT(0, 0, 0, 0); - m_startX = m_startY = 0; - m_sizeX = m_sizeY = 0; - m_SrcPassNumber = 0; - if (imageType != FXCODEC_IMAGE_UNKNOWN && - DetectImageType(imageType, pAttribute)) { - m_imagType = imageType; - m_status = FXCODEC_STATUS_FRAME_READY; - return m_status; - } - for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) { - if (DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) { - m_imagType = (FXCODEC_IMAGE_TYPE)type; - m_status = FXCODEC_STATUS_FRAME_READY; - return m_status; - } - } - m_status = FXCODEC_STATUS_ERR_FORMAT; - m_pFile = NULL; - return m_status; -} -void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) { - if (m_status != FXCODEC_STATUS_FRAME_READY) { - return; - } - if (clip->IsEmpty()) { - m_clipBox = FX_RECT(0, 0, 0, 0); - return; - } - if (clip->left < 0) { - clip->left = 0; - } - if (clip->right > m_SrcWidth) { - clip->right = m_SrcWidth; - } - if (clip->top < 0) { - clip->top = 0; - } - if (clip->bottom > m_SrcHeight) { - clip->bottom = m_SrcHeight; - } - if (clip->IsEmpty()) { - m_clipBox = FX_RECT(0, 0, 0, 0); - return; - } - m_clipBox = *clip; -} -void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale) { - down_scale = 1; - int ratio_w = m_clipBox.Width() / m_sizeX; - int ratio_h = m_clipBox.Height() / m_sizeY; - int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w; - if (ratio >= 8) { - down_scale = 8; - } else if (ratio >= 4) { - down_scale = 4; - } else if (ratio >= 2) { - down_scale = 2; - } - m_clipBox.left /= down_scale; - m_clipBox.right /= down_scale; - m_clipBox.top /= down_scale; - m_clipBox.bottom /= down_scale; - if (m_clipBox.right == m_clipBox.left) { - m_clipBox.right = m_clipBox.left + 1; - } - if (m_clipBox.bottom == m_clipBox.top) { - m_clipBox.bottom = m_clipBox.top + 1; - } -} -void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, - FXCodec_Format src_format) { - switch (des_format) { - case FXDIB_1bppMask: - case FXDIB_1bppRgb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 0; - break; - default: - m_TransMethod = -1; - } - } break; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 1; - break; - case FXCodec_8bppGray: - m_TransMethod = 2; - break; - case FXCodec_1bppRgb: - case FXCodec_8bppRgb: - m_TransMethod = 3; - break; - case FXCodec_Rgb: - case FXCodec_Rgb32: - case FXCodec_Argb: - m_TransMethod = 4; - break; - case FXCodec_Cmyk: - m_TransMethod = 5; - break; - default: - m_TransMethod = -1; - } - } break; - case FXDIB_Rgb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 6; - break; - case FXCodec_8bppGray: - m_TransMethod = 7; - break; - case FXCodec_1bppRgb: - case FXCodec_8bppRgb: - m_TransMethod = 8; - break; - case FXCodec_Rgb: - case FXCodec_Rgb32: - case FXCodec_Argb: - m_TransMethod = 9; - break; - case FXCodec_Cmyk: - m_TransMethod = 10; - break; - default: - m_TransMethod = -1; - } - } break; - case FXDIB_Rgb32: - case FXDIB_Argb: { - switch (src_format) { - case FXCodec_1bppGray: - m_TransMethod = 6; - break; - case FXCodec_8bppGray: - m_TransMethod = 7; - break; - case FXCodec_1bppRgb: - case FXCodec_8bppRgb: - if (des_format == FXDIB_Argb) { - m_TransMethod = 12; - } else { - m_TransMethod = 8; - } - break; - case FXCodec_Rgb: - case FXCodec_Rgb32: - m_TransMethod = 9; - break; - case FXCodec_Cmyk: - m_TransMethod = 10; - break; - case FXCodec_Argb: - m_TransMethod = 11; - break; - default: - m_TransMethod = -1; - } - } break; - default: - m_TransMethod = -1; - } -} -void _RGB2BGR(uint8_t* buffer, int width = 1) { - if (buffer && width > 0) { - uint8_t temp; - int i = 0; - int j = 0; - for (; i < width; i++, j += 3) { - temp = buffer[j]; - buffer[j] = buffer[j + 2]; - buffer[j + 2] = temp; - } - } -} -void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, - int des_line, - uint8_t* src_scan, - FXCodec_Format src_format) { - int src_left = m_clipBox.left; - int des_left = m_startX; - uint8_t* des_scan = - pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch(); - int src_bpp = src_format & 0xff; - int des_bpp = pDeviceBitmap->GetBPP(); - int src_Bpp = src_bpp >> 3; - int des_Bpp = des_bpp >> 3; - src_scan += src_left * src_Bpp; - des_scan += des_left * des_Bpp; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col); - switch (m_TransMethod) { - case -1: - return; - case 0: - return; - case 1: - return; - case 2: { - FX_DWORD des_g = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - des_g += pixel_weight * src_scan[j]; - } - *des_scan++ = (uint8_t)(des_g >> 16); - } break; - case 3: { - int des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = - (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); - } break; - case 4: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - des_b += pixel_weight * (*src_pixel++); - des_g += pixel_weight * (*src_pixel++); - des_r += pixel_weight * (*src_pixel); - } - *des_scan++ = - (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); - } break; - case 5: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - uint8_t src_b = 0, src_g = 0, src_r = 0; - AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], - 255 - src_pixel[2], 255 - src_pixel[3], src_r, - src_g, src_b); - des_b += pixel_weight * src_b; - des_g += pixel_weight * src_g; - des_r += pixel_weight * src_r; - } - *des_scan++ = - (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); - } break; - case 6: - return; - case 7: { - FX_DWORD des_g = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - des_g += pixel_weight * src_scan[j]; - } - FXSYS_memset(des_scan, (uint8_t)(des_g >> 16), 3); - des_scan += des_Bpp; - } break; - case 8: { - int des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case 12: { - if (m_pBmpContext) { - int des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = 0xFF; - } else { - int des_a = 0, des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb = m_pSrcPalette[src_scan[j]]; - des_a += pixel_weight * (uint8_t)(argb >> 24); - des_r += pixel_weight * (uint8_t)(argb >> 16); - des_g += pixel_weight * (uint8_t)(argb >> 8); - des_b += pixel_weight * (uint8_t)argb; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = (uint8_t)((des_a) >> 16); - } - } break; - case 9: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - des_b += pixel_weight * (*src_pixel++); - des_g += pixel_weight * (*src_pixel++); - des_r += pixel_weight * (*src_pixel); - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case 10: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - uint8_t src_b = 0, src_g = 0, src_r = 0; - AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], - 255 - src_pixel[2], 255 - src_pixel[3], src_r, - src_g, src_b); - des_b += pixel_weight * src_b; - des_g += pixel_weight * src_g; - des_r += pixel_weight * src_r; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - des_scan += des_Bpp - 3; - } break; - case 11: { - FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; - j++) { - int pixel_weight = - pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * src_Bpp; - pixel_weight = pixel_weight * src_pixel[3] / 255; - des_b += pixel_weight * (*src_pixel++); - des_g += pixel_weight * (*src_pixel++); - des_r += pixel_weight * (*src_pixel); - des_alpha += pixel_weight; - } - *des_scan++ = (uint8_t)((des_b) >> 16); - *des_scan++ = (uint8_t)((des_g) >> 16); - *des_scan++ = (uint8_t)((des_r) >> 16); - *des_scan++ = (uint8_t)((des_alpha * 255) >> 16); - } break; - default: - return; - } - } -} -void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row) { - int des_Bpp = pDeviceBitmap->GetBPP() >> 3; - FX_DWORD des_ScanOffet = m_startX * des_Bpp; - if (m_bInterpol) { - int des_top = m_startY; - int des_row_1 = des_row - int(scale_y); - if (des_row_1 < des_top) { - int des_bottom = des_top + m_sizeY; - if (des_row + (int)scale_y >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - while (++des_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } - return; - } - for (; des_row_1 < des_row; des_row_1++) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; - PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); - const uint8_t* scan_src1 = - pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + - des_ScanOffet; - const uint8_t* scan_src2 = - pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + - des_ScanOffet; - for (int des_col = 0; des_col < m_sizeX; des_col++) { - switch (pDeviceBitmap->GetFormat()) { - case FXDIB_Invalid: - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - return; - case FXDIB_8bppMask: - case FXDIB_8bppRgb: { - if (pDeviceBitmap->GetPalette()) { - return; - } - int des_g = 0; - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)(des_g >> 16); - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - FX_DWORD des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - scan_src1 += des_Bpp - 3; - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - scan_src2 += des_Bpp - 3; - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - scan_des += des_Bpp - 3; - } break; - case FXDIB_Argb: { - FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; - des_b += pWeight->m_Weights[0] * (*scan_src1++); - des_g += pWeight->m_Weights[0] * (*scan_src1++); - des_r += pWeight->m_Weights[0] * (*scan_src1++); - des_a += pWeight->m_Weights[0] * (*scan_src1++); - des_b += pWeight->m_Weights[1] * (*scan_src2++); - des_g += pWeight->m_Weights[1] * (*scan_src2++); - des_r += pWeight->m_Weights[1] * (*scan_src2++); - des_a += pWeight->m_Weights[1] * (*scan_src2++); - *scan_des++ = (uint8_t)((des_b) >> 16); - *scan_des++ = (uint8_t)((des_g) >> 16); - *scan_des++ = (uint8_t)((des_r) >> 16); - *scan_des++ = (uint8_t)((des_a) >> 16); - } break; - default: - return; - } - } - } - int des_bottom = des_top + m_sizeY; - if (des_row + (int)scale_y >= des_bottom - 1) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - while (++des_row < des_bottom) { - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } - return; - } - int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1); - if (multiple > 0) { - uint8_t* scan_src = - (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; - for (int i = 1; i <= multiple; i++) { - if (des_row + i >= m_startY + m_sizeY) { - return; - } - uint8_t* scan_des = - (uint8_t*)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet; - FX_DWORD size = m_sizeX * des_Bpp; - FXSYS_memcpy(scan_des, scan_src, size); - } - } -} -void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, - int32_t src_line, - uint8_t* src_scan, - FXCodec_Format src_format) { - int src_top = m_clipBox.top; - int des_top = m_startY; - int src_hei = m_clipBox.Height(); - int des_hei = m_sizeY; - if (src_line >= src_top) { - double scale_y = (double)des_hei / (double)src_hei; - int src_row = src_line - src_top; - int des_row = (int)(src_row * scale_y) + des_top; - if (des_row >= des_top + des_hei) { - return; - } - ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format); - if (scale_y > 1.0) { - ResampleVert(pDeviceBitmap, scale_y, des_row); - } - } -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, - IFX_Pause* pPause) { - if (!(m_status == FXCODEC_STATUS_FRAME_READY || - m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) { - return FXCODEC_STATUS_ERROR; - } - switch (m_imagType) { - case FXCODEC_IMAGE_BMP: - case FXCODEC_IMAGE_JPG: - case FXCODEC_IMAGE_PNG: - case FXCODEC_IMAGE_TIF: - frames = m_FrameNumber = 1; - return m_status = FXCODEC_STATUS_DECODE_READY; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - while (TRUE) { - int32_t readResult = - pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); - while (readResult == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ; - if (!GifReadMoreData(pGifModule, error_status)) { - return error_status; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE; - } - readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); - } - if (readResult == 1) { - frames = m_FrameNumber; - return m_status = FXCODEC_STATUS_DECODE_READY; - } - if (m_pGifContext) { - pGifModule->Finish(m_pGifContext); - m_pGifContext = NULL; - } - return m_status = FXCODEC_STATUS_ERROR; - } - } break; - default: - break; - } - return FXCODEC_STATUS_ERROR; -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, - int start_x, - int start_y, - int size_x, - int size_y, - int32_t frames, - FX_BOOL bInterpol) { - if (m_status != FXCODEC_STATUS_DECODE_READY) { - return FXCODEC_STATUS_ERROR; - } - if (pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 || frames < 0 || - frames >= m_FrameNumber) { - return FXCODEC_STATUS_ERR_PARAMS; - } - m_pDeviceBitmap = pDIBitmap; - if (m_clipBox.IsEmpty()) { - return FXCODEC_STATUS_ERR_PARAMS; - } - if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535) { - return FXCODEC_STATUS_ERR_PARAMS; - } - FX_RECT device_rc = - FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y); - int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth(); - int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight(); - device_rc.Intersect( - FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight())); - if (device_rc.IsEmpty()) { - return FXCODEC_STATUS_ERR_PARAMS; - } - m_startX = device_rc.left; - m_startY = device_rc.top; - m_sizeX = device_rc.Width(); - m_sizeY = device_rc.Height(); - m_bInterpol = bInterpol; - m_FrameCur = 0; - if (start_x < 0 || out_range_x > 0) { - FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x; - if (start_x < 0) { - m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX); - } - if (out_range_x > 0) { - m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX); - } - } - if (start_y < 0 || out_range_y > 0) { - FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y; - if (start_y < 0) { - m_clipBox.top -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY); - } - if (out_range_y > 0) { - m_clipBox.bottom -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY); - } - } - if (m_clipBox.IsEmpty()) { - return FXCODEC_STATUS_ERR_PARAMS; - } - switch (m_imagType) { - case FXCODEC_IMAGE_JPG: { - ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); - int down_scale = 1; - GetDownScale(down_scale); - FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); - while (!bStart) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - if (!JpegReadMoreData(pJpegModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); - } - int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale; - scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4; - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); - FXSYS_memset(m_pDecodeBuf, 0, scanline_size); - m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, - m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - switch (m_SrcComponents) { - case 1: - m_SrcFormat = FXCodec_8bppGray; - break; - case 3: - m_SrcFormat = FXCodec_Rgb; - break; - case 4: - m_SrcFormat = FXCodec_Cmyk; - break; - } - GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat); - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_PNG: { - ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); - if (pPngModule == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - if (m_pPngContext) { - pPngModule->Finish(m_pPngContext); - m_pPngContext = NULL; - } - m_pPngContext = pPngModule->Start((void*)this); - if (m_pPngContext == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - m_offSet = 0; - switch (m_pDeviceBitmap->GetFormat()) { - case FXDIB_8bppMask: - case FXDIB_8bppRgb: - m_SrcComponents = 1; - m_SrcFormat = FXCodec_8bppGray; - break; - case FXDIB_Rgb: - m_SrcComponents = 3; - m_SrcFormat = FXCodec_Rgb; - break; - case FXDIB_Rgb32: - case FXDIB_Argb: - m_SrcComponents = 4; - m_SrcFormat = FXCodec_Argb; - break; - default: { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_PARAMS; - } - } - GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); - int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); - FXSYS_memset(m_pDecodeBuf, 0, scanline_size); - m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - if (pGifModule == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - m_SrcFormat = FXCodec_8bppRgb; - GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); - int scanline_size = (m_SrcWidth + 3) / 4 * 4; - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); - FXSYS_memset(m_pDecodeBuf, 0, scanline_size); - m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, - m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - m_FrameCur = frames; - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_BMP: { - ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); - if (pBmpModule == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - switch (m_SrcComponents) { - case 1: - m_SrcFormat = FXCodec_8bppRgb; - break; - case 3: - m_SrcFormat = FXCodec_Rgb; - break; - case 4: - m_SrcFormat = FXCodec_Rgb32; - break; - } - GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); - m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; - FX_Free(m_pDecodeBuf); - m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize); - FXSYS_memset(m_pDecodeBuf, 0, m_ScanlineSize); - m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, - m_clipBox.Width(), m_bInterpol); - m_WeightVert.Calc(m_sizeY, m_clipBox.Height()); - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } break; - case FXCODEC_IMAGE_TIF: - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - default: - break; - } - return FXCODEC_STATUS_ERROR; -} -FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { - if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) { - return FXCODEC_STATUS_ERROR; - } - switch (m_imagType) { - case FXCODEC_IMAGE_JPG: { - ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); - while (TRUE) { - FX_BOOL readRes = - pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); - while (!readRes) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; - if (!JpegReadMoreData(pJpegModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); - } - if (m_SrcFormat == FXCodec_Rgb) { - int src_Bpp = (m_SrcFormat & 0xff) >> 3; - _RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width()); - } - if (m_SrcRow >= m_clipBox.bottom) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat); - m_SrcRow++; - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - } - } break; - case FXCODEC_IMAGE_PNG: { - ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); - while (TRUE) { - FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; - FX_DWORD input_size = - remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; - if (input_size == 0) { - if (m_pPngContext) { - pPngModule->Finish(m_pPngContext); - } - m_pPngContext = NULL; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - if (m_pSrcBuf && input_size > m_SrcSize) { - FX_Free(m_pSrcBuf); - m_pSrcBuf = FX_Alloc(uint8_t, input_size); - FXSYS_memset(m_pSrcBuf, 0, input_size); - m_SrcSize = input_size; - } - FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); - if (!bResult) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_READ; - } - m_offSet += input_size; - bResult = - pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, nullptr); - if (!bResult) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - } - } break; - case FXCODEC_IMAGE_GIF: { - ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); - while (TRUE) { - int32_t readRes = - pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); - while (readRes == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; - if (!GifReadMoreData(pGifModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); - } - if (readRes == 1) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - } break; - case FXCODEC_IMAGE_BMP: { - ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); - while (TRUE) { - int32_t readRes = pBmpModule->LoadImage(m_pBmpContext); - while (readRes == 2) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; - if (!BmpReadMoreData(pBmpModule, error_status)) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = error_status; - } - if (pPause && pPause->NeedToPauseNow()) { - return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; - } - readRes = pBmpModule->LoadImage(m_pBmpContext); - } - if (readRes == 1) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - } break; - case FXCODEC_IMAGE_TIF: { - ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); - FX_BOOL ret = FALSE; - if (m_pDeviceBitmap->GetBPP() == 32 && - m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX && - m_pDeviceBitmap->GetHeight() == m_SrcHeight && - m_SrcHeight == m_sizeY && m_startX == 0 && m_startY == 0 && - m_clipBox.left == 0 && m_clipBox.top == 0 && - m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) { - ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap); - m_pDeviceBitmap = NULL; - m_pFile = NULL; - if (!ret) { - return m_status = FXCODEC_STATUS_ERROR; - } - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } else { - CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; - pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb); - if (pDIBitmap->GetBuffer() == NULL) { - delete pDIBitmap; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap); - if (!ret) { - delete pDIBitmap; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERROR; - } - CFX_DIBitmap* pClipBitmap = - (m_clipBox.left == 0 && m_clipBox.top == 0 && - m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) - ? pDIBitmap - : pDIBitmap->Clone(&m_clipBox); - if (pDIBitmap != pClipBitmap) { - delete pDIBitmap; - } - if (pClipBitmap == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - CFX_DIBitmap* pFormatBitmap = NULL; - switch (m_pDeviceBitmap->GetFormat()) { - case FXDIB_8bppRgb: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_8bppRgb); - break; - case FXDIB_8bppMask: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_8bppMask); - break; - case FXDIB_Rgb: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_Rgb); - break; - case FXDIB_Rgb32: - pFormatBitmap = new CFX_DIBitmap; - pFormatBitmap->Create(pClipBitmap->GetWidth(), - pClipBitmap->GetHeight(), FXDIB_Rgb32); - break; - case FXDIB_Argb: - pFormatBitmap = pClipBitmap; - break; - default: - break; - } - switch (m_pDeviceBitmap->GetFormat()) { - case FXDIB_8bppRgb: - case FXDIB_8bppMask: { - for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { - uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); - uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); - for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { - uint8_t _a = 255 - src_line[3]; - uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; - uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; - uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; - *des_line++ = FXRGB2GRAY(r, g, b); - src_line += 4; - } - } - } break; - case FXDIB_Rgb: - case FXDIB_Rgb32: { - int32_t desBpp = - (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4; - for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { - uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); - uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); - for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { - uint8_t _a = 255 - src_line[3]; - uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; - uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; - uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; - *des_line++ = b; - *des_line++ = g; - *des_line++ = r; - des_line += desBpp - 3; - src_line += 4; - } - } - } break; - default: - break; - } - if (pClipBitmap != pFormatBitmap) { - delete pClipBitmap; - } - if (pFormatBitmap == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo( - m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE); - delete pFormatBitmap; - pFormatBitmap = NULL; - if (pStrechBitmap == NULL) { - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_ERR_MEMORY; - } - m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, - pStrechBitmap, 0, 0); - delete pStrechBitmap; - pStrechBitmap = NULL; - m_pDeviceBitmap = NULL; - m_pFile = NULL; - return m_status = FXCODEC_STATUS_DECODE_FINISH; - } - } break; - default: - break; - } - return FXCODEC_STATUS_ERROR; -} -ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { - return new CCodec_ProgressiveDecoder(this); -} diff --git a/core/src/fxcodec/codec/fx_codec_progress.h b/core/src/fxcodec/codec/fx_codec_progress.h deleted file mode 100644 index 4fb13640ff..0000000000 --- a/core/src/fxcodec/codec/fx_codec_progress.h +++ /dev/null @@ -1,213 +0,0 @@ -// 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 - -#ifndef CORE_SRC_FXCODEC_CODEC_FX_CODEC_PROGRESS_H_ -#define CORE_SRC_FXCODEC_CODEC_FX_CODEC_PROGRESS_H_ - -#define FXCODEC_BLOCK_SIZE 4096 -#define FXCODEC_PNG_GAMMA 2.2 -#if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ -#undef FXCODEC_PNG_GAMMA -#define FXCODEC_PNG_GAMMA 1.7 -#endif -struct PixelWeight { - int m_SrcStart; - int m_SrcEnd; - int m_Weights[1]; -}; -class CFXCODEC_WeightTable { - public: - CFXCODEC_WeightTable() { m_pWeightTables = NULL; } - ~CFXCODEC_WeightTable() { FX_Free(m_pWeightTables); } - - void Calc(int dest_len, - int dest_min, - int dest_max, - int src_len, - int src_min, - int src_max, - FX_BOOL bInterpol); - PixelWeight* GetPixelWeight(int pixel) { - return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize); - } - - int m_DestMin, m_ItemSize; - uint8_t* m_pWeightTables; -}; -class CFXCODEC_HorzTable { - public: - CFXCODEC_HorzTable() { m_pWeightTables = NULL; } - ~CFXCODEC_HorzTable() { FX_Free(m_pWeightTables); } - - void Calc(int dest_len, int src_len, FX_BOOL bInterpol); - PixelWeight* GetPixelWeight(int pixel) { - return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize); - } - - int m_ItemSize; - uint8_t* m_pWeightTables; -}; -class CFXCODEC_VertTable { - public: - CFXCODEC_VertTable() { m_pWeightTables = NULL; } - ~CFXCODEC_VertTable() { FX_Free(m_pWeightTables); } - void Calc(int dest_len, int src_len); - PixelWeight* GetPixelWeight(int pixel) { - return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize); - } - int m_ItemSize; - uint8_t* m_pWeightTables; -}; -enum FXCodec_Format { - FXCodec_Invalid = 0, - FXCodec_1bppGray = 0x101, - FXCodec_1bppRgb = 0x001, - FXCodec_8bppGray = 0x108, - FXCodec_8bppRgb = 0x008, - FXCodec_Rgb = 0x018, - FXCodec_Rgb32 = 0x020, - FXCodec_Argb = 0x220, - FXCodec_Cmyk = 0x120 -}; -class CCodec_ProgressiveDecoder : public ICodec_ProgressiveDecoder { - public: - CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr); - ~CCodec_ProgressiveDecoder() override; - - FXCODEC_STATUS LoadImageInfo(IFX_FileRead* pFile, - FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute) override; - - FXCODEC_IMAGE_TYPE GetType() const override { return m_imagType; } - int32_t GetWidth() const override { return m_SrcWidth; } - int32_t GetHeight() const override { return m_SrcHeight; } - int32_t GetNumComponents() const override { return m_SrcComponents; } - int32_t GetBPC() const override { return m_SrcBPC; } - void SetClipBox(FX_RECT* clip) override; - - FXCODEC_STATUS GetFrames(int32_t& frames, IFX_Pause* pPause) override; - FXCODEC_STATUS StartDecode(CFX_DIBitmap* pDIBitmap, - int start_x, - int start_y, - int size_x, - int size_y, - int32_t frames, - FX_BOOL bInterpol) override; - - FXCODEC_STATUS ContinueDecode(IFX_Pause* pPause) override; - - protected: - static FX_BOOL PngReadHeaderFunc(void* pModule, - int width, - int height, - int bpc, - int pass, - int* color_type, - double* gamma); - static FX_BOOL PngAskScanlineBufFunc(void* pModule, - int line, - uint8_t*& src_buf); - static void PngFillScanlineBufCompletedFunc(void* pModule, - int pass, - int line); - static void GifRecordCurrentPositionCallback(void* pModule, - FX_DWORD& cur_pos); - static uint8_t* GifAskLocalPaletteBufCallback(void* pModule, - int32_t frame_num, - int32_t pal_size); - static FX_BOOL GifInputRecordPositionBufCallback(void* pModule, - FX_DWORD rcd_pos, - const FX_RECT& img_rc, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - FX_BOOL user_input, - int32_t trans_index, - int32_t disposal_method, - FX_BOOL interlace); - static void GifReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf); - static FX_BOOL BmpInputImagePositionBufCallback(void* pModule, - FX_DWORD rcd_pos); - static void BmpReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf); - - FX_BOOL DetectImageType(FXCODEC_IMAGE_TYPE imageType, - CFX_DIBAttribute* pAttribute); - void GetDownScale(int& down_scale); - void GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format); - void ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format); - void Resample(CFX_DIBitmap* pDeviceBitmap, - int32_t src_line, - uint8_t* src_scan, - FXCodec_Format src_format); - void ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); - FX_BOOL JpegReadMoreData(ICodec_JpegModule* pJpegModule, - FXCODEC_STATUS& err_status); - void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format); - FX_BOOL GifReadMoreData(ICodec_GifModule* pGifModule, - FXCODEC_STATUS& err_status); - void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row); - FX_BOOL BmpReadMoreData(ICodec_BmpModule* pBmpModule, - FXCODEC_STATUS& err_status); - void ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); - - public: - IFX_FileRead* m_pFile; - CCodec_ModuleMgr* m_pCodecMgr; - void* m_pJpegContext; - void* m_pPngContext; - void* m_pGifContext; - void* m_pBmpContext; - void* m_pTiffContext; - FXCODEC_IMAGE_TYPE m_imagType; - FX_DWORD m_offSet; - uint8_t* m_pSrcBuf; - FX_DWORD m_SrcSize; - uint8_t* m_pDecodeBuf; - int m_ScanlineSize; - CFX_DIBitmap* m_pDeviceBitmap; - FX_BOOL m_bInterpol; - CFXCODEC_WeightTable m_WeightHorz; - CFXCODEC_VertTable m_WeightVert; - CFXCODEC_HorzTable m_WeightHorzOO; - int m_SrcWidth; - int m_SrcHeight; - int m_SrcComponents; - int m_SrcBPC; - FX_RECT m_clipBox; - int m_startX; - int m_startY; - int m_sizeX; - int m_sizeY; - int m_TransMethod; - FX_ARGB* m_pSrcPalette; - int m_SrcPaletteNumber; - int m_SrcRow; - FXCodec_Format m_SrcFormat; - int m_SrcPassNumber; - int m_FrameNumber; - int m_FrameCur; - int m_GifBgIndex; - uint8_t* m_pGifPalette; - int32_t m_GifPltNumber; - int m_GifTransIndex; - FX_RECT m_GifFrameRect; - FX_BOOL m_BmpIsTopBottom; - FXCODEC_STATUS m_status; -}; - -#endif // CORE_SRC_FXCODEC_CODEC_FX_CODEC_PROGRESS_H_ diff --git a/core/src/fxcodec/codec/fx_codec_tiff.cpp b/core/src/fxcodec/codec/fx_codec_tiff.cpp deleted file mode 100644 index 38c2af6287..0000000000 --- a/core/src/fxcodec/codec/fx_codec_tiff.cpp +++ /dev/null @@ -1,544 +0,0 @@ -// 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 "core/include/fxcodec/fx_codec.h" -#include "core/include/fxge/fx_dib.h" -#include "core/src/fxcodec/codec/codec_int.h" - -extern "C" { -#include "third_party/libtiff/tiffiop.h" -} - -void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData, - unsigned int dwProfileSize, - int nComponents, - int intent, - FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT); -void IccLib_TranslateImage(void* pTransform, - unsigned char* pDest, - const unsigned char* pSrc, - int pixels); -void IccLib_DestroyTransform(void* pTransform); -class CCodec_TiffContext { - public: - CCodec_TiffContext(); - ~CCodec_TiffContext(); - - FX_BOOL InitDecoder(IFX_FileRead* file_ptr); - void GetFrames(int32_t& frames); - FX_BOOL LoadFrameInfo(int32_t frame, - FX_DWORD& width, - FX_DWORD& height, - FX_DWORD& comps, - FX_DWORD& bpc, - CFX_DIBAttribute* pAttribute); - FX_BOOL Decode(CFX_DIBitmap* pDIBitmap); - - union { - IFX_FileRead* in; - IFX_FileStream* out; - } io; - - FX_DWORD offset; - - TIFF* tif_ctx; - void* icc_ctx; - int32_t frame_num; - int32_t frame_cur; - FX_BOOL isDecoder; - - private: - FX_BOOL isSupport(CFX_DIBitmap* pDIBitmap); - void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps); - FX_BOOL Decode1bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); - FX_BOOL Decode8bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); - FX_BOOL Decode24bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp); -}; -CCodec_TiffContext::CCodec_TiffContext() { - offset = 0; - frame_num = 0; - frame_cur = 0; - io.in = NULL; - tif_ctx = NULL; - icc_ctx = NULL; - isDecoder = TRUE; -} -CCodec_TiffContext::~CCodec_TiffContext() { - if (icc_ctx) { - IccLib_DestroyTransform(icc_ctx); - icc_ctx = NULL; - } - if (tif_ctx) { - TIFFClose(tif_ctx); - } -} -static tsize_t _tiff_read(thandle_t context, tdata_t buf, tsize_t length) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - FX_BOOL ret = FALSE; - if (pTiffContext->isDecoder) { - ret = pTiffContext->io.in->ReadBlock(buf, pTiffContext->offset, length); - } else { - ret = pTiffContext->io.out->ReadBlock(buf, pTiffContext->offset, length); - } - if (!ret) { - return 0; - } - pTiffContext->offset += (FX_DWORD)length; - return length; -} -static tsize_t _tiff_write(thandle_t context, tdata_t buf, tsize_t length) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - ASSERT(!pTiffContext->isDecoder); - if (!pTiffContext->io.out->WriteBlock(buf, pTiffContext->offset, length)) { - return 0; - } - pTiffContext->offset += (FX_DWORD)length; - return length; -} -static toff_t _tiff_seek(thandle_t context, toff_t offset, int whence) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - switch (whence) { - case 0: - pTiffContext->offset = (FX_DWORD)offset; - break; - case 1: - pTiffContext->offset += (FX_DWORD)offset; - break; - case 2: - if (pTiffContext->isDecoder) { - if (pTiffContext->io.in->GetSize() < (FX_FILESIZE)offset) { - return -1; - } - pTiffContext->offset = - (FX_DWORD)(pTiffContext->io.in->GetSize() - offset); - } else { - if (pTiffContext->io.out->GetSize() < (FX_FILESIZE)offset) { - return -1; - } - pTiffContext->offset = - (FX_DWORD)(pTiffContext->io.out->GetSize() - offset); - } - break; - default: - return -1; - } - ASSERT(pTiffContext->isDecoder ? (pTiffContext->offset <= - (FX_DWORD)pTiffContext->io.in->GetSize()) - : TRUE); - return pTiffContext->offset; -} -static int _tiff_close(thandle_t context) { - return 0; -} -static toff_t _tiff_get_size(thandle_t context) { - CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context; - return pTiffContext->isDecoder ? (toff_t)pTiffContext->io.in->GetSize() - : (toff_t)pTiffContext->io.out->GetSize(); -} -static int _tiff_map(thandle_t context, tdata_t*, toff_t*) { - return 0; -} -static void _tiff_unmap(thandle_t context, tdata_t, toff_t) {} -TIFF* _tiff_open(void* context, const char* mode) { - TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, _tiff_read, - _tiff_write, _tiff_seek, _tiff_close, - _tiff_get_size, _tiff_map, _tiff_unmap); - if (tif) { - tif->tif_fd = (int)(intptr_t)context; - } - return tif; -} -void* _TIFFmalloc(tmsize_t size) { - return FXMEM_DefaultAlloc(size, 0); -} -void _TIFFfree(void* ptr) { - FXMEM_DefaultFree(ptr, 0); -} -void* _TIFFrealloc(void* ptr, tmsize_t size) { - return FXMEM_DefaultRealloc(ptr, size, 0); -} -void _TIFFmemset(void* ptr, int val, tmsize_t size) { - FXSYS_memset(ptr, val, (size_t)size); -} -void _TIFFmemcpy(void* des, const void* src, tmsize_t size) { - FXSYS_memcpy(des, src, (size_t)size); -} -int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size) { - return FXSYS_memcmp(ptr1, ptr2, (size_t)size); -} - -TIFFErrorHandler _TIFFwarningHandler = nullptr; -TIFFErrorHandler _TIFFerrorHandler = nullptr; - -int TIFFCmyk2Rgb(thandle_t context, - uint8 c, - uint8 m, - uint8 y, - uint8 k, - uint8* r, - uint8* g, - uint8* b) { - if (context == NULL) { - return 0; - } - CCodec_TiffContext* p = (CCodec_TiffContext*)context; - if (p->icc_ctx) { - unsigned char cmyk[4], bgr[3]; - cmyk[0] = c, cmyk[1] = m, cmyk[2] = y, cmyk[3] = k; - IccLib_TranslateImage(p->icc_ctx, bgr, cmyk, 1); - *r = bgr[2], *g = bgr[1], *b = bgr[0]; - } else { - AdobeCMYK_to_sRGB1(c, m, y, k, *r, *g, *b); - } - return 1; -} -FX_BOOL CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr) { - io.in = file_ptr; - tif_ctx = _tiff_open(this, "r"); - if (tif_ctx == NULL) { - return FALSE; - } - return TRUE; -} -void CCodec_TiffContext::GetFrames(int32_t& frames) { - frames = frame_num = TIFFNumberOfDirectories(tif_ctx); -} -#define TIFF_EXIF_GETINFO(key, T, tag) \ - { \ - T val = (T)0; \ - TIFFGetField(tif_ctx, tag, &val); \ - if (val) { \ - (key) = FX_Alloc(uint8_t, sizeof(T)); \ - if ((key)) { \ - T* ptr = (T*)(key); \ - *ptr = val; \ - pExif->m_TagVal.SetAt(tag, (key)); \ - } \ - } \ - } \ - (key) = NULL; -#define TIFF_EXIF_GETSTRINGINFO(key, tag) \ - { \ - FX_DWORD size = 0; \ - uint8_t* buf = NULL; \ - TIFFGetField(tif_ctx, tag, &size, &buf); \ - if (size && buf) { \ - (key) = FX_Alloc(uint8_t, size); \ - if ((key)) { \ - FXSYS_memcpy((key), buf, size); \ - pExif->m_TagVal.SetAt(tag, (key)); \ - } \ - } \ - } \ - (key) = NULL; - -namespace { - -template -FX_BOOL Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttribute* pAttr) { - T val = 0; - TIFFGetField(tif_ctx, tag, &val); - if (!val) - return FALSE; - T* ptr = FX_Alloc(T, 1); - *ptr = val; - pAttr->m_Exif[tag] = (void*)ptr; - return TRUE; -} -void Tiff_Exif_GetStringInfo(TIFF* tif_ctx, - ttag_t tag, - CFX_DIBAttribute* pAttr) { - FX_CHAR* buf = nullptr; - TIFFGetField(tif_ctx, tag, &buf); - if (!buf) - return; - FX_STRSIZE size = FXSYS_strlen(buf); - uint8_t* ptr = FX_Alloc(uint8_t, size + 1); - FXSYS_memcpy(ptr, buf, size); - ptr[size] = 0; - pAttr->m_Exif[tag] = ptr; -} - -} // namespace - -FX_BOOL CCodec_TiffContext::LoadFrameInfo(int32_t frame, - FX_DWORD& width, - FX_DWORD& height, - FX_DWORD& comps, - FX_DWORD& bpc, - CFX_DIBAttribute* pAttribute) { - if (!TIFFSetDirectory(tif_ctx, (uint16)frame)) { - return FALSE; - } - FX_WORD tif_cs; - FX_DWORD tif_icc_size = 0; - uint8_t* tif_icc_buf = NULL; - FX_WORD tif_bpc = 0; - FX_WORD tif_cps; - FX_DWORD tif_rps; - width = height = comps = 0; - TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height); - TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &comps); - TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc); - TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &tif_cs); - TIFFGetField(tif_ctx, TIFFTAG_COMPRESSION, &tif_cps); - TIFFGetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps); - TIFFGetField(tif_ctx, TIFFTAG_ICCPROFILE, &tif_icc_size, &tif_icc_buf); - if (pAttribute) { - pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH; - if (TIFFGetField(tif_ctx, TIFFTAG_RESOLUTIONUNIT, - &pAttribute->m_wDPIUnit)) { - pAttribute->m_wDPIUnit -= 1; - } - Tiff_Exif_GetInfo(tif_ctx, TIFFTAG_ORIENTATION, pAttribute); - if (Tiff_Exif_GetInfo(tif_ctx, TIFFTAG_XRESOLUTION, pAttribute)) { - void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION]; - FX_FLOAT fDpi = val ? *reinterpret_cast(val) : 0; - pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f); - } - if (Tiff_Exif_GetInfo(tif_ctx, TIFFTAG_YRESOLUTION, pAttribute)) { - void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION]; - FX_FLOAT fDpi = val ? *reinterpret_cast(val) : 0; - pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f); - } - Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute); - Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MAKE, pAttribute); - Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MODEL, pAttribute); - } - bpc = tif_bpc; - if (tif_rps > height) { - TIFFSetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps = height); - } - return TRUE; -} -void _TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) { - for (int32_t n = 0; n < pixel; n++) { - uint8_t tmp = pBuf[0]; - pBuf[0] = pBuf[2]; - pBuf[2] = tmp; - pBuf += spp; - } -} -FX_BOOL CCodec_TiffContext::isSupport(CFX_DIBitmap* pDIBitmap) { - if (TIFFIsTiled(tif_ctx)) { - return FALSE; - } - uint16_t photometric; - if (!TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric)) { - return FALSE; - } - switch (pDIBitmap->GetBPP()) { - case 1: - case 8: - if (photometric != PHOTOMETRIC_PALETTE) { - return FALSE; - } - break; - case 24: - if (photometric != PHOTOMETRIC_RGB) { - return FALSE; - } - break; - default: - return FALSE; - } - uint16_t planarconfig; - if (!TIFFGetFieldDefaulted(tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) { - return FALSE; - } - if (planarconfig == PLANARCONFIG_SEPARATE) { - return FALSE; - } - return TRUE; -} -void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) { - uint16_t *red_orig, *green_orig, *blue_orig; - TIFFGetField(tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig); - for (int32_t i = (1L << bps) - 1; i >= 0; i--) { -#define CVT(x) ((uint16_t)((x) >> 8)) - red_orig[i] = CVT(red_orig[i]); - green_orig[i] = CVT(green_orig[i]); - blue_orig[i] = CVT(blue_orig[i]); -#undef CVT - } - int32_t len = 1 << bps; - for (int32_t index = 0; index < len; index++) { - FX_DWORD r = red_orig[index] & 0xFF; - FX_DWORD g = green_orig[index] & 0xFF; - FX_DWORD b = blue_orig[index] & 0xFF; - FX_DWORD color = (uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16) | - (((uint32)0xffL) << 24); - pDIBitmap->SetPaletteEntry(index, color); - } -} -FX_BOOL CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp) { - if (pDIBitmap->GetBPP() != 1 || spp != 1 || bps != 1 || - !isSupport(pDIBitmap)) { - return FALSE; - } - SetPalette(pDIBitmap, bps); - int32_t size = (int32_t)TIFFScanlineSize(tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (buf == NULL) { - TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); - return FALSE; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - FX_DWORD pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(tif_ctx, buf, row, 0); - for (int32_t j = 0; j < size; j++) { - bitMapbuffer[row * pitch + j] = buf[j]; - } - } - _TIFFfree(buf); - return TRUE; -} -FX_BOOL CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp) { - if (pDIBitmap->GetBPP() != 8 || spp != 1 || (bps != 4 && bps != 8) || - !isSupport(pDIBitmap)) { - return FALSE; - } - SetPalette(pDIBitmap, bps); - int32_t size = (int32_t)TIFFScanlineSize(tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (buf == NULL) { - TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); - return FALSE; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - FX_DWORD pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(tif_ctx, buf, row, 0); - for (int32_t j = 0; j < size; j++) { - switch (bps) { - case 4: - bitMapbuffer[row * pitch + 2 * j + 0] = (buf[j] & 0xF0) >> 4; - bitMapbuffer[row * pitch + 2 * j + 1] = (buf[j] & 0x0F) >> 0; - break; - case 8: - bitMapbuffer[row * pitch + j] = buf[j]; - break; - } - } - } - _TIFFfree(buf); - return TRUE; -} -FX_BOOL CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap, - int32_t height, - int32_t width, - uint16_t bps, - uint16_t spp) { - if (pDIBitmap->GetBPP() != 24 || !isSupport(pDIBitmap)) { - return FALSE; - } - int32_t size = (int32_t)TIFFScanlineSize(tif_ctx); - uint8_t* buf = (uint8_t*)_TIFFmalloc(size); - if (buf == NULL) { - TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer"); - return FALSE; - } - uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); - FX_DWORD pitch = pDIBitmap->GetPitch(); - for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(tif_ctx, buf, row, 0); - for (int32_t j = 0; j < size - 2; j += 3) { - bitMapbuffer[row * pitch + j + 0] = buf[j + 2]; - bitMapbuffer[row * pitch + j + 1] = buf[j + 1]; - bitMapbuffer[row * pitch + j + 2] = buf[j + 0]; - } - } - _TIFFfree(buf); - return TRUE; -} -FX_BOOL CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) { - FX_DWORD img_wid = pDIBitmap->GetWidth(); - FX_DWORD img_hei = pDIBitmap->GetHeight(); - FX_DWORD width = 0; - FX_DWORD height = 0; - TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height); - if (img_wid != width || img_hei != height) { - return FALSE; - } - if (pDIBitmap->GetBPP() == 32) { - FX_WORD rotation = ORIENTATION_TOPLEFT; - TIFFGetField(tif_ctx, TIFFTAG_ORIENTATION, &rotation); - if (TIFFReadRGBAImageOriented(tif_ctx, img_wid, img_hei, - (uint32*)pDIBitmap->GetBuffer(), rotation, - 1)) { - for (FX_DWORD row = 0; row < img_hei; row++) { - uint8_t* row_buf = (uint8_t*)pDIBitmap->GetScanline(row); - _TiffBGRA2RGBA(row_buf, img_wid, 4); - } - return TRUE; - } - } - uint16_t spp, bps; - TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp); - TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps); - FX_DWORD bpp = bps * spp; - if (bpp == 1) { - return Decode1bppRGB(pDIBitmap, height, width, bps, spp); - } else if (bpp <= 8) { - return Decode8bppRGB(pDIBitmap, height, width, bps, spp); - } else if (bpp <= 24) { - return Decode24bppRGB(pDIBitmap, height, width, bps, spp); - } - return FALSE; -} -void* CCodec_TiffModule::CreateDecoder(IFX_FileRead* file_ptr) { - CCodec_TiffContext* pDecoder = new CCodec_TiffContext; - if (!pDecoder->InitDecoder(file_ptr)) { - delete pDecoder; - return NULL; - } - return pDecoder; -} -void CCodec_TiffModule::GetFrames(void* ctx, int32_t& frames) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - pDecoder->GetFrames(frames); -} -FX_BOOL CCodec_TiffModule::LoadFrameInfo(void* ctx, - int32_t frame, - FX_DWORD& width, - FX_DWORD& height, - FX_DWORD& comps, - FX_DWORD& bpc, - CFX_DIBAttribute* pAttribute) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - return pDecoder->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute); -} -FX_BOOL CCodec_TiffModule::Decode(void* ctx, class CFX_DIBitmap* pDIBitmap) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - return pDecoder->Decode(pDIBitmap); -} -void CCodec_TiffModule::DestroyDecoder(void* ctx) { - CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx; - delete pDecoder; -} -- cgit v1.2.3