| // 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_ |