1 // Copyright 2017 The PDFium Authors 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_FXCODEC_JPX_CJPX_DECODER_H_ 8 #define CORE_FXCODEC_JPX_CJPX_DECODER_H_ 9 10 #include <stdint.h> 11 12 #include <memory> 13 14 #include "core/fxcrt/raw_span.h" 15 #include "core/fxcrt/span.h" 16 17 #if defined(USE_SYSTEM_LIBOPENJPEG2) 18 #include <openjpeg.h> 19 #else 20 #include "third_party/libopenjpeg/openjpeg.h" 21 #endif 22 23 namespace fxcodec { 24 25 struct DecodeData; 26 27 class CJPX_Decoder { 28 public: 29 // Calculated as log2(2^32 / 1), where 2^32 is the largest image dimension and 30 // 1 is the smallest required size. 31 static constexpr uint8_t kMaxResolutionsToSkip = 32; 32 33 enum class ColorSpaceOption { 34 kNone, 35 kNormal, 36 kIndexed, 37 }; 38 39 struct JpxImageInfo { 40 uint32_t width; 41 uint32_t height; 42 uint32_t channels; 43 COLOR_SPACE colorspace; 44 }; 45 46 static std::unique_ptr<CJPX_Decoder> Create( 47 pdfium::span<const uint8_t> src_span, 48 CJPX_Decoder::ColorSpaceOption option, 49 uint8_t resolution_levels_to_skip, 50 bool strict_mode); 51 52 static void Sycc420ToRgbForTesting(opj_image_t* img); 53 54 ~CJPX_Decoder(); 55 56 JpxImageInfo GetInfo() const; 57 bool StartDecode(); 58 59 // `swap_rgb` can only be set when an image's color space type contains at 60 // least 3 color components. Note that this `component_count` is not 61 // equivalent to `JpxImageInfo::channels`. The JpxImageInfo channels can 62 // contain extra information for rendering the image besides the color 63 // component information. Therefore the `JpxImageInfo::channels` must be no 64 // less than the component count. 65 // 66 // Example: If a JPX image's color space type is OPJ_CLRSPC_SRGB, the 67 // component count for this color space is 3, and the channel count of its 68 // JpxImageInfo can be 4. This is because the extra channel might contain 69 // extra information, such as the transparency level of the image. 70 bool Decode(pdfium::span<uint8_t> dest_buf, 71 uint32_t pitch, 72 bool swap_rgb, 73 uint32_t component_count); 74 75 private: 76 struct CodecDeleter { operatorCodecDeleter77 inline void operator()(opj_codec_t* ptr) const { opj_destroy_codec(ptr); } 78 }; 79 80 struct ImageDeleter { operatorImageDeleter81 inline void operator()(opj_image_t* ptr) const { opj_image_destroy(ptr); } 82 }; 83 84 struct StreamDeleter { operatorStreamDeleter85 inline void operator()(opj_stream_t* ptr) const { opj_stream_destroy(ptr); } 86 }; 87 88 // Use Create() to instantiate. 89 explicit CJPX_Decoder(ColorSpaceOption option); 90 91 // TODO(crbug.com/42270564): Remove `strict_mode` once all the bugs have been 92 // worked out in OpenJPEG. 93 bool Init(pdfium::span<const uint8_t> src_data, 94 uint8_t resolution_levels_to_skip, 95 bool strict_mode); 96 97 const ColorSpaceOption m_ColorSpaceOption; 98 pdfium::raw_span<const uint8_t> m_SrcData; 99 std::unique_ptr<DecodeData> m_DecodeData; 100 std::unique_ptr<opj_codec_t, CodecDeleter> m_Codec; 101 std::unique_ptr<opj_stream_t, StreamDeleter> m_Stream; 102 std::unique_ptr<opj_image_t, ImageDeleter> m_Image; 103 opj_dparameters_t m_Parameters = {}; 104 }; 105 106 } // namespace fxcodec 107 108 using fxcodec::CJPX_Decoder; 109 110 #endif // CORE_FXCODEC_JPX_CJPX_DECODER_H_ 111