tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

box_content_decoder.cc (3203B)


      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 <algorithm>
      9 #include <cstddef>
     10 #include <cstdint>
     11 #include <cstring>
     12 
     13 #include "lib/jxl/base/sanitizers.h"
     14 
     15 namespace jxl {
     16 
     17 JxlBoxContentDecoder::JxlBoxContentDecoder() = default;
     18 
     19 JxlBoxContentDecoder::~JxlBoxContentDecoder() {
     20  if (brotli_dec) {
     21    BrotliDecoderDestroyInstance(brotli_dec);
     22  }
     23 }
     24 
     25 void JxlBoxContentDecoder::StartBox(bool brob_decode, bool box_until_eof,
     26                                    size_t contents_size) {
     27  if (brotli_dec) {
     28    BrotliDecoderDestroyInstance(brotli_dec);
     29    brotli_dec = nullptr;
     30  }
     31  header_done_ = false;
     32  brob_decode_ = brob_decode;
     33  box_until_eof_ = box_until_eof;
     34  remaining_ = box_until_eof ? 0 : contents_size;
     35  pos_ = 0;
     36 }
     37 
     38 JxlDecoderStatus JxlBoxContentDecoder::Process(const uint8_t* next_in,
     39                                               size_t avail_in, size_t box_pos,
     40                                               uint8_t** next_out,
     41                                               size_t* avail_out) {
     42  next_in += pos_ - box_pos;
     43  avail_in -= pos_ - box_pos;
     44 
     45  if (brob_decode_) {
     46    if (!header_done_) {
     47      if (avail_in < 4) return JXL_DEC_NEED_MORE_INPUT;
     48      if (!box_until_eof_) {
     49        if (remaining_ < 4) return JXL_DEC_ERROR;
     50        remaining_ -= 4;
     51      }
     52      next_in += 4;
     53      avail_in -= 4;
     54      pos_ += 4;
     55      header_done_ = true;
     56    }
     57 
     58    if (!brotli_dec) {
     59      brotli_dec = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
     60    }
     61 
     62    const uint8_t* next_in_before = next_in;
     63    uint8_t* next_out_before = *next_out;
     64    msan::MemoryIsInitialized(next_in, avail_in);
     65    BrotliDecoderResult res = BrotliDecoderDecompressStream(
     66        brotli_dec, &avail_in, &next_in, avail_out, next_out, nullptr);
     67    size_t consumed = next_in - next_in_before;
     68    size_t produced = *next_out - next_out_before;
     69    if (res == BROTLI_DECODER_RESULT_ERROR) {
     70      return JXL_DEC_ERROR;
     71    }
     72    msan::UnpoisonMemory(next_out_before, produced);
     73    pos_ += consumed;
     74    if (!box_until_eof_) remaining_ -= consumed;
     75    if (res == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
     76      return JXL_DEC_NEED_MORE_INPUT;
     77    }
     78    if (res == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
     79      return JXL_DEC_BOX_NEED_MORE_OUTPUT;
     80    }
     81    if (res == BROTLI_DECODER_RESULT_SUCCESS) {
     82      return JXL_DEC_BOX_COMPLETE;
     83    }
     84    // unknown Brotli result
     85    return JXL_DEC_ERROR;
     86  } else {
     87    // remaining box bytes as seen from dec->file_pos
     88    size_t can_read = avail_in;
     89    if (!box_until_eof_) can_read = std::min<size_t>(can_read, remaining_);
     90    size_t to_write = std::min<size_t>(can_read, *avail_out);
     91    memcpy(*next_out, next_in, to_write);
     92 
     93    *next_out += to_write;
     94    *avail_out -= to_write;
     95    if (!box_until_eof_) remaining_ -= to_write;
     96    pos_ += to_write;
     97 
     98    if (to_write < can_read) return JXL_DEC_BOX_NEED_MORE_OUTPUT;
     99 
    100    if (!box_until_eof_ && remaining_ > 0) return JXL_DEC_NEED_MORE_INPUT;
    101 
    102    return JXL_DEC_BOX_COMPLETE;
    103  }
    104 }
    105 
    106 }  // namespace jxl