1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
// 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.
// Tools for reading from / writing to ISOBMFF format for JPEG XL.
#ifndef TOOLS_BOX_BOX_H_
#define TOOLS_BOX_BOX_H_
#include <string>
#include <vector>
#include "lib/jxl/base/padded_bytes.h"
#include "lib/jxl/base/status.h"
#include "lib/jxl/codec_in_out.h"
#include "lib/jxl/dec_file.h"
#include "lib/jxl/enc_file.h"
namespace jpegxl {
namespace tools {
// A top-level box in the box format.
struct Box {
// The type of the box.
// If "uuid", use extended_type instead
char type[4];
// The extended_type is only used when type == "uuid".
// Extended types are not used in JXL. However, the box format itself
// supports this so they are handled correctly.
char extended_type[16];
// Size of the data, excluding box header. The box ends, and next box
// begins, at data + size. May not be used if data_size_given is false.
uint64_t data_size;
// If the size is not given, the datasize extends to the end of the file.
// If this field is false, the size field may not be used.
bool data_size_given;
};
// Parses the header of a BMFF box. Returns the result in a Box struct.
// Updates next_in and available_in to point at the data in the box, directly
// after the header.
// Sets the data_size if known, or must be handled by the caller and runs until
// the end of the container file if not known.
// NOTE: available_in should be at least 8 up to 32 bytes to parse the
// header without error.
jxl::Status ParseBoxHeader(const uint8_t** next_in, size_t* available_in,
Box* box);
// TODO(lode): streaming C API
jxl::Status AppendBoxHeader(const Box& box, jxl::PaddedBytes* out);
// NOTE: after DecodeJpegXlContainerOneShot, the exif etc. pointers point to
// regions within the input data passed to that function.
struct JpegXlContainer {
// Exif metadata, or null if not present in the container.
// The exif data has the format of 'Exif block' as defined in
// ISO/IEC23008-12:2017 Clause A.2.1
// Here we assume the tiff header offset is 0 and store only the
// actual Exif data (starting with the tiff header MM or II)
// TODO(lode): support the theoretical case of multiple exif boxes
const uint8_t* exif = nullptr; // Not owned
size_t exif_size = 0;
// Brotli-compressed exif metadata, if present. The data points to the brotli
// compressed stream, it is not decompressed here.
const uint8_t* exfc = nullptr; // Not owned
size_t exfc_size = 0;
// XML boxes for XMP. There may be multiple XML boxes.
// Each entry points to XML location and provides size.
// The memory is not owned.
// TODO(lode): for C API, cannot use std::vector.
std::vector<std::pair<const uint8_t*, size_t>> xml;
// Brotli-compressed xml boxes. The bytes are given in brotli-compressed form
// and are not decompressed here.
std::vector<std::pair<const uint8_t*, size_t>> xmlc;
// JUMBF superbox data, or null if not present in the container.
// The parsing of the nested boxes inside is not handled here.
const uint8_t* jumb = nullptr; // Not owned
size_t jumb_size = 0;
// TODO(lode): add frame index data
// JPEG reconstruction data, or null if not present in the container.
const uint8_t* jpeg_reconstruction = nullptr;
size_t jpeg_reconstruction_size = 0;
// The main JPEG XL codestream, of which there must be 1 in the container.
// TODO(lode): support split codestream: there may be multiple jxlp boxes.
const uint8_t* codestream = nullptr; // Not owned
size_t codestream_size = 0;
};
// Returns whether `data` starts with a container header; definitely returns
// false if `size` is less than 12 bytes.
bool IsContainerHeader(const uint8_t* data, size_t size);
// NOTE: the input data must remain valid as long as `container` is used,
// because its exif etc. pointers point to that data.
jxl::Status DecodeJpegXlContainerOneShot(const uint8_t* data, size_t size,
JpegXlContainer* container);
// TODO(lode): streaming C API
jxl::Status EncodeJpegXlContainerOneShot(const JpegXlContainer& container,
jxl::PaddedBytes* out);
// TODO(veluca): this doesn't really belong here.
jxl::Status DecodeJpegXlToJpeg(jxl::DecompressParams params,
const JpegXlContainer& container,
jxl::CodecInOut* io,
jxl::ThreadPool* pool = nullptr);
} // namespace tools
} // namespace jpegxl
#endif // TOOLS_BOX_BOX_H_
|