// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
// JPEG XL to JPEG bytes decoder logic. The JxlToJpegDecoder class keeps track // of the decoder state needed to parse the JPEG reconstruction box and provide // the reconstructed JPEG to the output buffer.
class JxlToJpegDecoder { public: // Returns whether an output buffer is set. bool IsOutputSet() const { return next_out_ != nullptr; }
// Returns whether the decoder is parsing a boxa JPEG box was parsed. bool IsParsingBox() const { return inside_box_; }
// Sets the output buffer used when producing JPEG output.
JxlDecoderStatus SetOutputBuffer(uint8_t* data, size_t size) { if (next_out_) return JXL_DEC_ERROR;
next_out_ = data;
avail_size_ = size; return JXL_DEC_SUCCESS;
}
// Releases the buffer set with SetOutputBuffer().
size_t ReleaseOutputBuffer() {
size_t result = avail_size_;
next_out_ = nullptr;
avail_size_ = 0; return result;
}
void StartBox(bool box_until_eof, size_t contents_size) { // A new box implies that we clear the buffer.
buffer_.clear();
inside_box_ = true; if (box_until_eof) {
box_until_eof_ = true;
} else {
box_size_ = contents_size;
}
}
// Consumes data from next_in/avail_in to reconstruct JPEG data. // Uses box_size_, inside_box_ and box_until_eof_ to calculate how much to // consume. Potentially stores unparsed data in buffer_. // Potentially populates jpeg_data_. Potentially updates inside_box_. // Returns JXL_DEC_JPEG_RECONSTRUCTION when finished, JXL_DEC_NEED_MORE_INPUT // if more input is needed, JXL_DEC_ERROR on parsing error.
JxlDecoderStatus Process(const uint8_t** next_in, size_t* avail_in);
// Returns non-owned copy of the JPEGData, only after Process finished and // the JPEGData was not yet moved to an image bundle with // SetImageBundleJpegData.
jpeg::JPEGData* GetJpegData() { return jpeg_data_.get(); }
// Returns how many exif or xmp app markers are present in the JPEG data. A // return value higher than 1 would require multiple exif boxes or multiple // xmp boxes in the container format, and this is not supported by the API and // considered an error. May only be called after Process returned success. static size_t NumExifMarkers(const jpeg::JPEGData& jpeg_data); static size_t NumXmpMarkers(const jpeg::JPEGData& jpeg_data);
// Returns box content size for metadata, using the known data from the app // markers. static JxlDecoderStatus ExifBoxContentSize(const jpeg::JPEGData& jpeg_data,
size_t* size); static JxlDecoderStatus XmlBoxContentSize(const jpeg::JPEGData& jpeg_data,
size_t* size);
// Returns JXL_DEC_ERROR if there is no exif/XMP marker or the data size // does not match, or this function is called before Process returned // success, JXL_DEC_SUCCESS otherwise. As input, provide the full box contents // but not the box header. In case of exif, this includes the 4-byte TIFF // header, even though it won't be copied into the JPEG. static JxlDecoderStatus SetExif(const uint8_t* data, size_t size,
jpeg::JPEGData* jpeg_data); static JxlDecoderStatus SetXmp(const uint8_t* data, size_t size,
jpeg::JPEGData* jpeg_data);
// Sets the JpegData of the ImageBundle passed if there is anything to set. // Releases the JpegData from this decoder if set.
Status SetImageBundleJpegData(ImageBundle* ib) { if (IsOutputSet() && jpeg_data_ != nullptr) { if (!jpeg::SetJPEGDataFromICC(ib->metadata()->color_encoding.ICC(),
jpeg_data_.get())) { returnfalse;
}
ib->jpeg_data = std::move(jpeg_data_);
} returntrue;
}
private: // Content of the most recently parsed JPEG reconstruction box if any.
std::vector<uint8_t> buffer_;
// Decoded content of the most recently parsed JPEG reconstruction box is // stored here.
std::unique_ptr<jpeg::JPEGData> jpeg_data_;
// True if the decoder is currently reading bytes inside a JPEG reconstruction // box. bool inside_box_ = false;
// True if the JPEG reconstruction box had undefined size (all remaining // bytes). bool box_until_eof_ = false; // Size of most recently parsed JPEG reconstruction box contents.
size_t box_size_ = 0;
// Next bytes to write JPEG reconstruction to.
uint8_t* next_out_ = nullptr; // Available bytes to write JPEG reconstruction to.
size_t avail_size_ = 0;
};
#else
// Fake class that disables support for decoding JPEG XL to JPEG. class JxlToJpegDecoder { public: bool IsOutputSet() const { returnfalse; } bool IsParsingBox() const { returnfalse; }
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.