codec_in_out.h (3457B)
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 #ifndef LIB_JXL_CODEC_IN_OUT_H_ 7 #define LIB_JXL_CODEC_IN_OUT_H_ 8 9 // Holds inputs/outputs for decoding/encoding images. 10 11 #include <jxl/memory_manager.h> 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <utility> 16 #include <vector> 17 18 #include "lib/jxl/base/status.h" 19 #include "lib/jxl/color_encoding_internal.h" 20 #include "lib/jxl/headers.h" 21 #include "lib/jxl/image.h" 22 #include "lib/jxl/image_bundle.h" 23 #include "lib/jxl/luminance.h" 24 25 namespace jxl { 26 27 // Optional text/EXIF metadata. 28 struct Blobs { 29 std::vector<uint8_t> exif; 30 std::vector<uint8_t> iptc; 31 std::vector<uint8_t> jhgm; 32 std::vector<uint8_t> jumbf; 33 std::vector<uint8_t> xmp; 34 }; 35 36 // Holds a preview, a main image or one or more frames, plus the inputs/outputs 37 // to/from decoding/encoding. 38 class CodecInOut { 39 public: 40 explicit CodecInOut(JxlMemoryManager* memory_manager) 41 : memory_manager(memory_manager), 42 preview_frame(memory_manager, &metadata.m) { 43 frames.reserve(1); 44 frames.emplace_back(memory_manager, &metadata.m); 45 } 46 47 // Move-only. 48 CodecInOut(CodecInOut&&) = default; 49 CodecInOut& operator=(CodecInOut&&) = default; 50 51 size_t LastStillFrame() const { 52 JXL_DASSERT(!frames.empty()); 53 size_t last = 0; 54 for (size_t i = 0; i < frames.size(); i++) { 55 last = i; 56 if (frames[i].duration > 0) break; 57 } 58 return last; 59 } 60 61 ImageBundle& Main() { return frames[LastStillFrame()]; } 62 const ImageBundle& Main() const { return frames[LastStillFrame()]; } 63 64 // If c_current.IsGray(), all planes must be identical. 65 Status SetFromImage(Image3F&& color, const ColorEncoding& c_current) { 66 JXL_RETURN_IF_ERROR(Main().SetFromImage(std::move(color), c_current)); 67 SetIntensityTarget(&this->metadata.m); 68 JXL_RETURN_IF_ERROR(SetSize(Main().xsize(), Main().ysize())); 69 return true; 70 } 71 72 Status SetSize(size_t xsize, size_t ysize) { 73 JXL_RETURN_IF_ERROR(metadata.size.Set(xsize, ysize)); 74 return true; 75 } 76 77 Status CheckMetadata() const { 78 JXL_ENSURE(metadata.m.bit_depth.bits_per_sample != 0); 79 JXL_ENSURE(!metadata.m.color_encoding.ICC().empty()); 80 81 if (preview_frame.xsize() != 0) { 82 JXL_RETURN_IF_ERROR(preview_frame.VerifyMetadata()); 83 } 84 JXL_ENSURE(preview_frame.metadata() == &metadata.m); 85 86 for (const ImageBundle& ib : frames) { 87 JXL_RETURN_IF_ERROR(ib.VerifyMetadata()); 88 JXL_ENSURE(ib.metadata() == &metadata.m); 89 } 90 return true; 91 } 92 93 size_t xsize() const { return metadata.size.xsize(); } 94 size_t ysize() const { return metadata.size.ysize(); } 95 Status ShrinkTo(size_t xsize, size_t ysize) { 96 // preview is unaffected. 97 for (ImageBundle& ib : frames) { 98 JXL_RETURN_IF_ERROR(ib.ShrinkTo(xsize, ysize)); 99 } 100 JXL_RETURN_IF_ERROR(SetSize(xsize, ysize)); 101 return true; 102 } 103 104 // -- DECODER OUTPUT, ENCODER INPUT: 105 106 // Metadata stored into / retrieved from bitstreams. 107 108 JxlMemoryManager* memory_manager; 109 110 Blobs blobs; 111 112 CodecMetadata metadata; // applies to preview and all frames 113 114 // If metadata.have_preview: 115 ImageBundle preview_frame; 116 117 std::vector<ImageBundle> frames; // size=1 if !metadata.have_animation 118 119 // If the image should be written to a JPEG, use this quality for encoding. 120 size_t jpeg_quality; 121 }; 122 123 } // namespace jxl 124 125 #endif // LIB_JXL_CODEC_IN_OUT_H_