in tensorflow_compression/cc/kernels/y4m_dataset_kernels.cc [295:394]
Status ParseHeader(string_view header, const size_t file_index,
int64_t& width, int64_t& height,
ChromaFormat& chroma_format) {
const string_view digits = "0123456789";
width = 0;
height = 0;
chroma_format = ChromaFormat::undefined;
// Last character is guaranteed to be newline because ReadHeader uses
// it to find the end of the header.
header.remove_suffix(1);
if (!absl::ConsumePrefix(&header, "YUV4MPEG2")) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' does not have a YUV4MPEG2 marker.");
}
while (!header.empty()) {
size_t pos;
if (header.size() < 2 || header[0] != ' ') {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has an invalid Y4M header. Remaining header: '", header,
"'.");
}
const char key = header[1];
header.remove_prefix(2);
switch (key) {
case 'W':
pos = header.find_first_not_of(digits);
if (!absl::SimpleAtoi(header.substr(0, pos), &width) ||
width <= 0) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has an invalid width specifier '", header.substr(0, pos),
"'.");
}
header.remove_prefix(pos == header.npos ? header.size() : pos);
break;
case 'H':
pos = header.find_first_not_of(digits);
if (!absl::SimpleAtoi(header.substr(0, pos), &height) ||
height <= 0) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has an invalid height specifier '",
header.substr(0, pos), "'.");
}
header.remove_prefix(pos == header.npos ? header.size() : pos);
break;
case 'C':
if (absl::ConsumePrefix(&header, "420jpeg")) {
chroma_format = ChromaFormat::I420;
} else if (absl::ConsumePrefix(&header, "444")) {
chroma_format = ChromaFormat::I444;
} else {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has an unsupported chroma format '",
header.substr(0, header.find(' ')), "'.");
}
break;
case 'I':
if (!absl::ConsumePrefix(&header, "p")) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' is not in progressive format.");
}
break;
default:
pos = header.find(' ');
header.remove_prefix(pos == header.npos ? header.size() : pos);
break;
}
}
if (!width) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has no width specifier.");
}
if (!height) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has no height specifier.");
}
if (chroma_format == ChromaFormat::undefined) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has no chroma format specifier.");
}
if (chroma_format == ChromaFormat::I420 && (width & 1 || height & 1)) {
return errors::InvalidArgument(
"Input file '", dataset()->filenames_[file_index],
"' has 4:2:0 chroma format, but odd width or height.");
}
return Status::OK();
}