libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

box_content_decoder.cc (3109B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #include "lib/jxl/box_content_decoder.h"
      7 
      8 #include "lib/jxl/sanitizers.h"
      9 
     10 namespace jxl {
     11 
     12 JxlBoxContentDecoder::JxlBoxContentDecoder() = default;
     13 
     14 JxlBoxContentDecoder::~JxlBoxContentDecoder() {
     15   if (brotli_dec) {
     16     BrotliDecoderDestroyInstance(brotli_dec);
     17   }
     18 }
     19 
     20 void JxlBoxContentDecoder::StartBox(bool brob_decode, bool box_until_eof,
     21                                     size_t contents_size) {
     22   if (brotli_dec) {
     23     BrotliDecoderDestroyInstance(brotli_dec);
     24     brotli_dec = nullptr;
     25   }
     26   header_done_ = false;
     27   brob_decode_ = brob_decode;
     28   box_until_eof_ = box_until_eof;
     29   remaining_ = box_until_eof ? 0 : contents_size;
     30   pos_ = 0;
     31 }
     32 
     33 JxlDecoderStatus JxlBoxContentDecoder::Process(const uint8_t* next_in,
     34                                                size_t avail_in, size_t box_pos,
     35                                                uint8_t** next_out,
     36                                                size_t* avail_out) {
     37   next_in += pos_ - box_pos;
     38   avail_in -= pos_ - box_pos;
     39 
     40   if (brob_decode_) {
     41     if (!header_done_) {
     42       if (avail_in < 4) return JXL_DEC_NEED_MORE_INPUT;
     43       if (!box_until_eof_) {
     44         if (remaining_ < 4) return JXL_DEC_ERROR;
     45         remaining_ -= 4;
     46       }
     47       next_in += 4;
     48       avail_in -= 4;
     49       pos_ += 4;
     50       header_done_ = true;
     51     }
     52 
     53     if (!brotli_dec) {
     54       brotli_dec = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
     55     }
     56 
     57     const uint8_t* next_in_before = next_in;
     58     uint8_t* next_out_before = *next_out;
     59     msan::MemoryIsInitialized(next_in, avail_in);
     60     BrotliDecoderResult res = BrotliDecoderDecompressStream(
     61         brotli_dec, &avail_in, &next_in, avail_out, next_out, nullptr);
     62     size_t consumed = next_in - next_in_before;
     63     size_t produced = *next_out - next_out_before;
     64     if (res == BROTLI_DECODER_RESULT_ERROR) {
     65       return JXL_DEC_ERROR;
     66     }
     67     msan::UnpoisonMemory(next_out_before, produced);
     68     pos_ += consumed;
     69     if (!box_until_eof_) remaining_ -= consumed;
     70     if (res == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
     71       return JXL_DEC_NEED_MORE_INPUT;
     72     }
     73     if (res == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
     74       return JXL_DEC_BOX_NEED_MORE_OUTPUT;
     75     }
     76     if (res == BROTLI_DECODER_RESULT_SUCCESS) {
     77       return JXL_DEC_SUCCESS;
     78     }
     79     // unknown Brotli result
     80     return JXL_DEC_ERROR;
     81   } else {
     82     // remaining box bytes as seen from dec->file_pos
     83     size_t can_read = avail_in;
     84     if (!box_until_eof_) can_read = std::min<size_t>(can_read, remaining_);
     85     size_t to_write = std::min<size_t>(can_read, *avail_out);
     86     memcpy(*next_out, next_in, to_write);
     87 
     88     *next_out += to_write;
     89     *avail_out -= to_write;
     90     if (!box_until_eof_) remaining_ -= to_write;
     91     pos_ += to_write;
     92 
     93     if (to_write < can_read) return JXL_DEC_BOX_NEED_MORE_OUTPUT;
     94 
     95     if (!box_until_eof_ && remaining_ > 0) return JXL_DEC_NEED_MORE_INPUT;
     96 
     97     return JXL_DEC_SUCCESS;
     98   }
     99 }
    100 
    101 }  // namespace jxl