| // Copyright 2026 Google LLC | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // | |
| #ifndef THIRD_PARTY_CREDENTIO_FORMATS_ID3_ID3_H_ | |
| #define THIRD_PARTY_CREDENTIO_FORMATS_ID3_ID3_H_ | |
| #include <cstdint> | |
| #include <string> | |
| #include "absl/status/statusor.h" | |
| #include "absl/strings/cord.h" | |
| #include "riegeli/bytes/reader.h" | |
| namespace credentio { | |
| // Represents the header of an ID3 tag. | |
| struct Id3Header { | |
| // Whether or not unsynchronisation is used. | |
| bool use_unsynchronisation; | |
| // Whether or not the extended header is present. | |
| bool has_extended_header; | |
| // Whether or not the experimental indicator is set. | |
| bool is_experimental; | |
| // The size of the ID3 tag, excluding the size of the header but including the | |
| // size of the extended header if present. | |
| uint32_t tag_size; | |
| // The size of the extended header, excluding the size field itself. Only | |
| // relevant if `has_extended_header` is true. | |
| uint32_t extended_header_size; | |
| // Extended flags in the extended header. Only relevant if | |
| // `has_extended_header` is true. | |
| std::string extended_flags; | |
| // The size of the padding added to the end of the ID3 tag. Only relevant if | |
| // `has_extended_header` is true. | |
| uint32_t padding_size; | |
| // The total frame CRC in the extended header. Only relevant if | |
| // `has_extended_header` is true. | |
| std::string total_frame_crc; | |
| // The major version of the tag (e.g., 3 for ID3v2.3, 4 for ID3v2.4). | |
| uint8_t major_version = 3; | |
| // Parses the ID3 header from the given input. | |
| static absl::StatusOr<Id3Header> Parse(riegeli::Reader& input); | |
| // Returns the ID3 header encoded as an `absl::Cord`. | |
| absl::Cord ToCord() const; | |
| }; | |
| // Represents a raw ID3 frame read from an MP3 file. | |
| struct Id3Frame { | |
| // The offset of the ID3 frame from the beginning of the MP3 file. | |
| uint64_t offset; | |
| // The size of the ID3 frame, including the 10-byte header. | |
| uint64_t length; | |
| // The 4-character ID of the frame (e.g., "GEOB"). | |
| std::string id; | |
| // Returns the offset of the data section within the frame, relative to | |
| // the beginning of the MP3 file. The data section starts immediately after | |
| // the 10-byte ID3 frame header. | |
| uint64_t data_offset() const { return offset + 10; } | |
| // Returns the length of the data section within the frame. | |
| uint64_t data_length() const { return length - 10; } | |
| bool operator==(const Id3Frame& other) const { | |
| return offset == other.offset && length == other.length && id == other.id; | |
| } | |
| }; | |
| struct GeobFrame { | |
| std::string mime_type; | |
| std::string encapsulated_object; | |
| // Parses a GEOB frame from the given input. | |
| static absl::StatusOr<GeobFrame> Parse(riegeli::Reader& input, | |
| uint64_t data_offset, | |
| uint64_t data_length); | |
| }; | |
| } // namespace credentio | |
| #endif // THIRD_PARTY_CREDENTIO_FORMATS_ID3_ID3_H_ |