1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_SRC_FXCODEC_CODEC_CODEC_INT_H_ 8 #define CORE_SRC_FXCODEC_CODEC_CODEC_INT_H_ 9 10 #include <limits.h> 11 12 #include <list> 13 #include <map> 14 #include <memory> 15 16 #include "core/include/fxcodec/fx_codec.h" 17 #include "core/src/fxcodec/jbig2/JBig2_Context.h" 18 #include "third_party/libopenjpeg20/openjpeg.h" // For OPJ_SIZE_T. 19 20 class CFX_IccProfileCache; 21 class CFX_IccTransformCache; 22 class CPDF_ColorSpace; 23 24 class CCodec_BasicModule : public ICodec_BasicModule { 25 public: 26 // ICodec_BasicModule: 27 FX_BOOL RunLengthEncode(const uint8_t* src_buf, 28 FX_DWORD src_size, 29 uint8_t*& dest_buf, 30 FX_DWORD& dest_size) override; 31 FX_BOOL A85Encode(const uint8_t* src_buf, 32 FX_DWORD src_size, 33 uint8_t*& dest_buf, 34 FX_DWORD& dest_size) override; 35 ICodec_ScanlineDecoder* CreateRunLengthDecoder(const uint8_t* src_buf, 36 FX_DWORD src_size, 37 int width, 38 int height, 39 int nComps, 40 int bpc) override; 41 }; 42 43 class CCodec_ScanlineDecoder : public ICodec_ScanlineDecoder { 44 public: 45 CCodec_ScanlineDecoder(); 46 ~CCodec_ScanlineDecoder() override; 47 48 // ICodec_ScanlineDecoder GetSrcOffset()49 FX_DWORD GetSrcOffset() override { return -1; } 50 void DownScale(int dest_width, int dest_height) override; 51 const uint8_t* GetScanline(int line) override; 52 FX_BOOL SkipToScanline(int line, IFX_Pause* pPause) override; GetWidth()53 int GetWidth() override { return m_OutputWidth; } GetHeight()54 int GetHeight() override { return m_OutputHeight; } CountComps()55 int CountComps() override { return m_nComps; } GetBPC()56 int GetBPC() override { return m_bpc; } IsColorTransformed()57 FX_BOOL IsColorTransformed() override { return m_bColorTransformed; } ClearImageData()58 void ClearImageData() override { m_pDataCache.reset(); } 59 60 protected: 61 class ImageDataCache { 62 public: 63 ImageDataCache(int width, int height, FX_DWORD pitch); 64 ~ImageDataCache(); 65 66 bool AllocateCache(); 67 void AppendLine(const uint8_t* line); 68 NumLines()69 int NumLines() const { return m_nCachedLines; } 70 const uint8_t* GetLine(int line) const; IsSameDimensions(int width,int height)71 bool IsSameDimensions(int width, int height) const { 72 return width == m_Width && height == m_Height; 73 } 74 75 private: IsValid()76 bool IsValid() const { return m_Data.get() != nullptr; } 77 78 const int m_Width; 79 const int m_Height; 80 const FX_DWORD m_Pitch; 81 int m_nCachedLines; 82 std::unique_ptr<uint8_t, FxFreeDeleter> m_Data; 83 }; 84 85 virtual FX_BOOL v_Rewind() = 0; 86 virtual uint8_t* v_GetNextLine() = 0; 87 virtual void v_DownScale(int dest_width, int dest_height) = 0; 88 89 uint8_t* ReadNextLine(); 90 91 int m_OrigWidth; 92 int m_OrigHeight; 93 int m_DownScale; 94 int m_OutputWidth; 95 int m_OutputHeight; 96 int m_nComps; 97 int m_bpc; 98 FX_DWORD m_Pitch; 99 FX_BOOL m_bColorTransformed; 100 int m_NextLine; 101 uint8_t* m_pLastScanline; 102 std::unique_ptr<ImageDataCache> m_pDataCache; 103 }; 104 105 class CCodec_FaxModule : public ICodec_FaxModule { 106 public: 107 // ICodec_FaxModule: 108 ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf, 109 FX_DWORD src_size, 110 int width, 111 int height, 112 int K, 113 FX_BOOL EndOfLine, 114 FX_BOOL EncodedByteAlign, 115 FX_BOOL BlackIs1, 116 int Columns, 117 int Rows) override; 118 FX_BOOL Encode(const uint8_t* src_buf, 119 int width, 120 int height, 121 int pitch, 122 uint8_t*& dest_buf, 123 FX_DWORD& dest_size) override; 124 }; 125 126 class CCodec_FlateModule : public ICodec_FlateModule { 127 public: 128 virtual ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf, 129 FX_DWORD src_size, 130 int width, 131 int height, 132 int nComps, 133 int bpc, 134 int predictor, 135 int Colors, 136 int BitsPerComponent, 137 int Columns); 138 virtual FX_DWORD FlateOrLZWDecode(FX_BOOL bLZW, 139 const uint8_t* src_buf, 140 FX_DWORD src_size, 141 FX_BOOL bEarlyChange, 142 int predictor, 143 int Colors, 144 int BitsPerComponent, 145 int Columns, 146 FX_DWORD estimated_size, 147 uint8_t*& dest_buf, 148 FX_DWORD& dest_size); 149 virtual FX_BOOL Encode(const uint8_t* src_buf, 150 FX_DWORD src_size, 151 int predictor, 152 int Colors, 153 int BitsPerComponent, 154 int Columns, 155 uint8_t*& dest_buf, 156 FX_DWORD& dest_size); 157 virtual FX_BOOL Encode(const uint8_t* src_buf, 158 FX_DWORD src_size, 159 uint8_t*& dest_buf, 160 FX_DWORD& dest_size); 161 }; 162 163 class CCodec_JpegModule : public ICodec_JpegModule { 164 public: CCodec_JpegModule()165 CCodec_JpegModule() {} 166 ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf, 167 FX_DWORD src_size, 168 int width, 169 int height, 170 int nComps, 171 FX_BOOL ColorTransform) override; 172 FX_BOOL LoadInfo(const uint8_t* src_buf, 173 FX_DWORD src_size, 174 int& width, 175 int& height, 176 int& num_components, 177 int& bits_per_components, 178 FX_BOOL& color_transform, 179 uint8_t** icc_buf_ptr, 180 FX_DWORD* icc_length) override; 181 FX_BOOL Encode(const CFX_DIBSource* pSource, 182 uint8_t*& dest_buf, 183 FX_STRSIZE& dest_size, 184 int quality, 185 const uint8_t* icc_buf, 186 FX_DWORD icc_length) override; 187 void* Start() override; 188 void Finish(void* pContext) override; 189 void Input(void* pContext, 190 const uint8_t* src_buf, 191 FX_DWORD src_size) override; 192 #ifndef PDF_ENABLE_XFA 193 int ReadHeader(void* pContext, int* width, int* height, int* nComps) override; 194 #else // PDF_ENABLE_XFA 195 int ReadHeader(void* pContext, 196 int* width, 197 int* height, 198 int* nComps, 199 CFX_DIBAttribute* pAttribute) override; 200 #endif // PDF_ENABLE_XFA 201 int StartScanline(void* pContext, int down_scale) override; 202 FX_BOOL ReadScanline(void* pContext, uint8_t* dest_buf) override; 203 FX_DWORD GetAvailInput(void* pContext, uint8_t** avail_buf_ptr) override; 204 }; 205 206 #ifdef PDF_ENABLE_XFA 207 #define PNG_ERROR_SIZE 256 208 class CCodec_PngModule : public ICodec_PngModule { 209 public: CCodec_PngModule()210 CCodec_PngModule() { FXSYS_memset(m_szLastError, '\0', PNG_ERROR_SIZE); } 211 212 virtual void* Start(void* pModule); 213 virtual void Finish(void* pContext); 214 virtual FX_BOOL Input(void* pContext, 215 const uint8_t* src_buf, 216 FX_DWORD src_size, 217 CFX_DIBAttribute* pAttribute); 218 219 protected: 220 FX_CHAR m_szLastError[PNG_ERROR_SIZE]; 221 }; 222 class CCodec_GifModule : public ICodec_GifModule { 223 public: CCodec_GifModule()224 CCodec_GifModule() { FXSYS_memset(m_szLastError, '\0', 256); } 225 virtual void* Start(void* pModule); 226 virtual void Finish(void* pContext); 227 virtual FX_DWORD GetAvailInput(void* pContext, uint8_t** avail_buf_ptr); 228 virtual void Input(void* pContext, const uint8_t* src_buf, FX_DWORD src_size); 229 230 virtual int32_t ReadHeader(void* pContext, 231 int* width, 232 int* height, 233 int* pal_num, 234 void** pal_pp, 235 int* bg_index, 236 CFX_DIBAttribute* pAttribute); 237 238 virtual int32_t LoadFrameInfo(void* pContext, int* frame_num); 239 240 virtual int32_t LoadFrame(void* pContext, 241 int frame_num, 242 CFX_DIBAttribute* pAttribute); 243 244 protected: 245 FX_CHAR m_szLastError[256]; 246 }; 247 class CCodec_BmpModule : public ICodec_BmpModule { 248 public: CCodec_BmpModule()249 CCodec_BmpModule() { FXSYS_memset(m_szLastError, 0, sizeof(m_szLastError)); } 250 void* Start(void* pModule) override; 251 void Finish(void* pContext) override; 252 FX_DWORD GetAvailInput(void* pContext, uint8_t** avail_buf_ptr) override; 253 void Input(void* pContext, 254 const uint8_t* src_buf, 255 FX_DWORD src_size) override; 256 int32_t ReadHeader(void* pContext, 257 int32_t* width, 258 int32_t* height, 259 FX_BOOL* tb_flag, 260 int32_t* components, 261 int32_t* pal_num, 262 FX_DWORD** pal_pp, 263 CFX_DIBAttribute* pAttribute) override; 264 int32_t LoadImage(void* pContext) override; 265 266 protected: 267 FX_CHAR m_szLastError[256]; 268 }; 269 #endif // PDF_ENABLE_XFA 270 271 class CCodec_IccModule : public ICodec_IccModule { 272 public: 273 ~CCodec_IccModule() override; 274 275 // ICodec_IccModule: 276 IccCS GetProfileCS(const uint8_t* pProfileData, 277 unsigned int dwProfileSize) override; 278 IccCS GetProfileCS(IFX_FileRead* pFile) override; 279 void* CreateTransform(ICodec_IccModule::IccParam* pInputParam, 280 ICodec_IccModule::IccParam* pOutputParam, 281 ICodec_IccModule::IccParam* pProofParam = NULL, 282 FX_DWORD dwIntent = Icc_INTENT_PERCEPTUAL, 283 FX_DWORD dwFlag = Icc_FLAGS_DEFAULT, 284 FX_DWORD dwPrfIntent = Icc_INTENT_ABSOLUTE_COLORIMETRIC, 285 FX_DWORD dwPrfFlag = Icc_FLAGS_SOFTPROOFING) override; 286 void* CreateTransform_sRGB( 287 const uint8_t* pProfileData, 288 FX_DWORD dwProfileSize, 289 int32_t& nComponents, 290 int32_t intent = 0, 291 FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT) override; 292 void* CreateTransform_CMYK( 293 const uint8_t* pSrcProfileData, 294 FX_DWORD dwSrcProfileSize, 295 int32_t& nSrcComponents, 296 const uint8_t* pDstProfileData, 297 FX_DWORD dwDstProfileSize, 298 int32_t intent = 0, 299 FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT, 300 FX_DWORD dwDstFormat = Icc_FORMAT_DEFAULT) override; 301 void DestroyTransform(void* pTransform) override; 302 void Translate(void* pTransform, 303 FX_FLOAT* pSrcValues, 304 FX_FLOAT* pDestValues) override; 305 void TranslateScanline(void* pTransform, 306 uint8_t* pDest, 307 const uint8_t* pSrc, 308 int pixels) override; SetComponents(FX_DWORD nComponents)309 void SetComponents(FX_DWORD nComponents) override { 310 m_nComponents = nComponents; 311 } 312 313 protected: 314 enum Icc_CLASS { 315 Icc_CLASS_INPUT = 0, 316 Icc_CLASS_OUTPUT, 317 Icc_CLASS_PROOF, 318 Icc_CLASS_MAX 319 }; 320 void* CreateProfile(ICodec_IccModule::IccParam* pIccParam, 321 Icc_CLASS ic, 322 CFX_BinaryBuf* pTransformKey); 323 324 FX_DWORD m_nComponents; 325 std::map<CFX_ByteString, CFX_IccTransformCache*> m_MapTranform; 326 std::map<CFX_ByteString, CFX_IccProfileCache*> m_MapProfile; 327 }; 328 329 class CCodec_JpxModule : public ICodec_JpxModule { 330 public: 331 CCodec_JpxModule(); 332 ~CCodec_JpxModule() override; 333 334 // ICodec_JpxModule: 335 CJPX_Decoder* CreateDecoder(const uint8_t* src_buf, 336 FX_DWORD src_size, 337 CPDF_ColorSpace* cs) override; 338 void GetImageInfo(CJPX_Decoder* pDecoder, 339 FX_DWORD* width, 340 FX_DWORD* height, 341 FX_DWORD* components) override; 342 bool Decode(CJPX_Decoder* pDecoder, 343 uint8_t* dest_data, 344 int pitch, 345 const std::vector<uint8_t>& offsets) override; 346 void DestroyDecoder(CJPX_Decoder* pDecoder) override; 347 }; 348 349 #ifdef PDF_ENABLE_XFA 350 class CCodec_TiffModule : public ICodec_TiffModule { 351 public: 352 // ICodec_TiffModule 353 void* CreateDecoder(IFX_FileRead* file_ptr) override; 354 void GetFrames(void* ctx, int32_t& frames) override; 355 FX_BOOL LoadFrameInfo(void* ctx, 356 int32_t frame, 357 FX_DWORD& width, 358 FX_DWORD& height, 359 FX_DWORD& comps, 360 FX_DWORD& bpc, 361 CFX_DIBAttribute* pAttribute) override; 362 FX_BOOL Decode(void* ctx, class CFX_DIBitmap* pDIBitmap) override; 363 void DestroyDecoder(void* ctx) override; 364 365 protected: ~CCodec_TiffModule()366 ~CCodec_TiffModule() override {} 367 }; 368 #endif // PDF_ENABLE_XFA 369 370 class CCodec_Jbig2Context { 371 public: 372 CCodec_Jbig2Context(); ~CCodec_Jbig2Context()373 ~CCodec_Jbig2Context() {} 374 375 FX_DWORD m_width; 376 FX_DWORD m_height; 377 CPDF_StreamAcc* m_pGlobalStream; 378 CPDF_StreamAcc* m_pSrcStream; 379 uint8_t* m_dest_buf; 380 FX_DWORD m_dest_pitch; 381 IFX_Pause* m_pPause; 382 CJBig2_Context* m_pContext; 383 CJBig2_Image* m_dest_image; 384 }; 385 class CCodec_Jbig2Module : public ICodec_Jbig2Module { 386 public: CCodec_Jbig2Module()387 CCodec_Jbig2Module() {} 388 ~CCodec_Jbig2Module() override; 389 390 // ICodec_Jbig2Module 391 void* CreateJbig2Context() override; 392 FXCODEC_STATUS StartDecode(void* pJbig2Context, 393 CFX_PrivateData* pPrivateData, 394 FX_DWORD width, 395 FX_DWORD height, 396 CPDF_StreamAcc* src_stream, 397 CPDF_StreamAcc* global_stream, 398 uint8_t* dest_buf, 399 FX_DWORD dest_pitch, 400 IFX_Pause* pPause) override; 401 FXCODEC_STATUS ContinueDecode(void* pJbig2Context, 402 IFX_Pause* pPause) override; 403 void DestroyJbig2Context(void* pJbig2Context) override; 404 }; 405 406 struct DecodeData { 407 public: DecodeDataDecodeData408 DecodeData(unsigned char* src_data, OPJ_SIZE_T src_size) 409 : src_data(src_data), src_size(src_size), offset(0) {} 410 unsigned char* src_data; 411 OPJ_SIZE_T src_size; 412 OPJ_SIZE_T offset; 413 }; 414 415 void sycc420_to_rgb(opj_image_t* img); 416 417 /* Wrappers for C-style callbacks. */ 418 OPJ_SIZE_T opj_read_from_memory(void* p_buffer, 419 OPJ_SIZE_T nb_bytes, 420 void* p_user_data); 421 OPJ_SIZE_T opj_write_from_memory(void* p_buffer, 422 OPJ_SIZE_T nb_bytes, 423 void* p_user_data); 424 OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data); 425 OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data); 426 427 #endif // CORE_SRC_FXCODEC_CODEC_CODEC_INT_H_ 428