| // Copyright 2014 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 | |
| #include "core/fxcodec/jbig2/jbig2_decoder.h" | |
| #include <algorithm> | |
| #include <utility> | |
| #include "core/fxcodec/jbig2/jbig2_context.h" | |
| #include "core/fxcodec/jbig2/jbig2_document_context.h" | |
| #include "core/fxcrt/fx_2d_size.h" | |
| #include "core/fxcrt/span_util.h" | |
| namespace fxcodec { | |
| namespace { | |
| FXCODEC_STATUS Decode(Jbig2Context* pJbig2Context, bool decode_success) { | |
| FXCODEC_STATUS status = pJbig2Context->context_->GetProcessingStatus(); | |
| if (status != FXCODEC_STATUS::kDecodeFinished) { | |
| return status; | |
| } | |
| pJbig2Context->context_.reset(); | |
| if (!decode_success) { | |
| return FXCODEC_STATUS::kError; | |
| } | |
| uint32_t byte_size = pJbig2Context->height_ * pJbig2Context->dest_pitch_; | |
| pdfium::span<uint8_t> nonraw_span(pJbig2Context->dest_buf_.first(byte_size)); | |
| auto dword_span = fxcrt::reinterpret_span<uint32_t>(nonraw_span); | |
| for (auto& pix : dword_span) { | |
| pix = ~pix; | |
| } | |
| return FXCODEC_STATUS::kDecodeFinished; | |
| } | |
| } // namespace | |
| Jbig2Context::Jbig2Context() = default; | |
| Jbig2Context::~Jbig2Context() = default; | |
| // static | |
| FXCODEC_STATUS Jbig2Decoder::StartDecode( | |
| Jbig2Context* pJbig2Context, | |
| JBig2_DocumentContext* pJBig2DocumentContext, | |
| uint32_t width, | |
| uint32_t height, | |
| pdfium::span<const uint8_t> src_span, | |
| uint64_t src_key, | |
| pdfium::span<const uint8_t> global_span, | |
| uint64_t global_key, | |
| pdfium::span<uint8_t> dest_buf, | |
| uint32_t dest_pitch, | |
| PauseIndicatorIface* pPause, | |
| bool reject_large_regions_when_fuzzing) { | |
| pJbig2Context->width_ = width; | |
| pJbig2Context->height_ = height; | |
| pJbig2Context->src_span_ = src_span; | |
| pJbig2Context->src_key_ = src_key; | |
| pJbig2Context->global_span_ = global_span; | |
| pJbig2Context->global_key_ = global_key; | |
| pJbig2Context->dest_buf_ = dest_buf; | |
| pJbig2Context->dest_pitch_ = dest_pitch; | |
| std::ranges::fill(dest_buf.first(Fx2DSizeOrDie(height, dest_pitch)), 0); | |
| pJbig2Context->context_ = | |
| CJBig2_Context::Create(global_span, global_key, src_span, src_key, | |
| pJBig2DocumentContext->GetSymbolDictCache()); | |
| if (reject_large_regions_when_fuzzing) { | |
| pJbig2Context->context_->RejectLargeRegionsWhenFuzzing(); | |
| } | |
| bool succeeded = pJbig2Context->context_->GetFirstPage( | |
| dest_buf, width, height, dest_pitch, pPause); | |
| return Decode(pJbig2Context, succeeded); | |
| } | |
| // static | |
| FXCODEC_STATUS Jbig2Decoder::ContinueDecode(Jbig2Context* pJbig2Context, | |
| PauseIndicatorIface* pPause) { | |
| bool succeeded = pJbig2Context->context_->Continue(pPause); | |
| return Decode(pJbig2Context, succeeded); | |
| } | |
| } // namespace fxcodec |