blob: 1b96a0764e41e17d0437b0693dd55f0af9626477 [file]
// 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_