void LibWebpDecompressor::_ensureHeaderIsRead()

in cpp/spectrum/plugins/webp/LibWebpDecompressor.cpp [69:109]


void LibWebpDecompressor::_ensureHeaderIsRead() {
  if (_isHeaderRead) {
    return; // only read header once
  }

  // The WebP header is quite compact and using the DefaultBufferSize would be
  // wasteful here
  constexpr std::size_t HEADER_BUFFER_SIZE = 32;

  auto status = VP8_STATUS_NOT_ENOUGH_DATA;
  while (status == VP8_STATUS_NOT_ENOUGH_DATA) {
    // read next chunk
    std::vector<char> chunk(HEADER_BUFFER_SIZE);
    const auto bytesRead = _source.read(chunk.data(), HEADER_BUFFER_SIZE);
    if (bytesRead == 0) {
      break;
    }

    // append to already collected header bytes
    std::copy_n(chunk.begin(), bytesRead, std::back_inserter(_webpPayload));

    // try to extract features
    status = WebPGetFeatures(
        reinterpret_cast<std::uint8_t*>(_webpPayload.data()),
        _webpPayload.size(),
        &_webpFeatures);
  }

  SPECTRUM_ERROR_CSTR_IF_NOT(
      status == VP8_STATUS_OK,
      codecs::error::DecompressorFailure,
      "webp_get_features_failed");

  SPECTRUM_ERROR_CSTR_IF(
      _webpFeatures.height > maximumSizeDimension ||
          _webpFeatures.width > maximumSizeDimension,
      codecs::error::DecompressorFailure,
      "webp_input_size_too_large");

  _isHeaderRead = true;
}