| // Copyright 2017 The PDFium Authors | |
| // 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_FXCODEC_JPX_CJPX_DECODER_H_ | |
| #define CORE_FXCODEC_JPX_CJPX_DECODER_H_ | |
| #include <stdint.h> | |
| #include <memory> | |
| #include "core/fxcrt/raw_span.h" | |
| #include "core/fxcrt/span.h" | |
| #if defined(USE_SYSTEM_LIBOPENJPEG2) | |
| #include <openjpeg.h> | |
| #else | |
| #include "third_party/libopenjpeg/openjpeg.h" | |
| #endif | |
| namespace fxcodec { | |
| struct DecodeData; | |
| class CJPX_Decoder { | |
| public: | |
| // Calculated as log2(2^32 / 1), where 2^32 is the largest image dimension and | |
| // 1 is the smallest required size. | |
| static constexpr uint8_t kMaxResolutionsToSkip = 32; | |
| enum class ColorSpaceOption { | |
| kNone, | |
| kNormal, | |
| kIndexed, | |
| }; | |
| struct JpxImageInfo { | |
| uint32_t width; | |
| uint32_t height; | |
| uint32_t channels; | |
| COLOR_SPACE colorspace; | |
| }; | |
| static std::unique_ptr<CJPX_Decoder> Create( | |
| pdfium::span<const uint8_t> src_span, | |
| CJPX_Decoder::ColorSpaceOption option, | |
| uint8_t resolution_levels_to_skip, | |
| bool strict_mode); | |
| static void Sycc420ToRgbForTesting(opj_image_t* img); | |
| ~CJPX_Decoder(); | |
| JpxImageInfo GetInfo() const; | |
| bool StartDecode(); | |
| // `swap_rgb` can only be set when an image's color space type contains at | |
| // least 3 color components. Note that this `component_count` is not | |
| // equivalent to `JpxImageInfo::channels`. The JpxImageInfo channels can | |
| // contain extra information for rendering the image besides the color | |
| // component information. Therefore the `JpxImageInfo::channels` must be no | |
| // less than the component count. | |
| // | |
| // Example: If a JPX image's color space type is OPJ_CLRSPC_SRGB, the | |
| // component count for this color space is 3, and the channel count of its | |
| // JpxImageInfo can be 4. This is because the extra channel might contain | |
| // extra information, such as the transparency level of the image. | |
| bool Decode(pdfium::span<uint8_t> dest_buf, | |
| uint32_t pitch, | |
| bool swap_rgb, | |
| uint32_t component_count); | |
| private: | |
| struct CodecDeleter { | |
| inline void operator()(opj_codec_t* ptr) const { opj_destroy_codec(ptr); } | |
| }; | |
| struct ImageDeleter { | |
| inline void operator()(opj_image_t* ptr) const { opj_image_destroy(ptr); } | |
| }; | |
| struct StreamDeleter { | |
| inline void operator()(opj_stream_t* ptr) const { opj_stream_destroy(ptr); } | |
| }; | |
| // Use Create() to instantiate. | |
| explicit CJPX_Decoder(ColorSpaceOption option); | |
| // TODO(crbug.com/42270564): Remove `strict_mode` once all the bugs have been | |
| // worked out in OpenJPEG. | |
| bool Init(pdfium::span<const uint8_t> src_data, | |
| uint8_t resolution_levels_to_skip, | |
| bool strict_mode); | |
| const ColorSpaceOption color_space_option_; | |
| pdfium::raw_span<const uint8_t> src_data_; | |
| std::unique_ptr<DecodeData> decode_data_; | |
| std::unique_ptr<opj_codec_t, CodecDeleter> codec_; | |
| std::unique_ptr<opj_stream_t, StreamDeleter> stream_; | |
| std::unique_ptr<opj_image_t, ImageDeleter> image_; | |
| opj_dparameters_t parameters_ = {}; | |
| }; | |
| } // namespace fxcodec | |
| using fxcodec::CJPX_Decoder; | |
| #endif // CORE_FXCODEC_JPX_CJPX_DECODER_H_ |