Skip to content

Commit

Permalink
Rename 'coni' box to 'mini' in EXPERIMENTAL_AVIR (AOMediaCodec#1959)
Browse files Browse the repository at this point in the history
to follow the specification change proposal updates.
  • Loading branch information
y-guyon authored Jan 19, 2024
1 parent 9f6e550 commit 3fab232
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 74 deletions.
12 changes: 6 additions & 6 deletions include/avif/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,13 @@ typedef enum avifItemCategory

#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
// AVIF color_type field meaning in CondensedImageBox
typedef enum avifConiColorType
typedef enum avifMiniColorType
{
AVIF_CONI_COLOR_TYPE_SRGB = 0,
AVIF_CONI_COLOR_TYPE_NCLX_5BIT = 1,
AVIF_CONI_COLOR_TYPE_NCLX_8BIT = 2,
AVIF_CONI_COLOR_TYPE_ICC = 3
} avifConiColorType;
AVIF_MINI_COLOR_TYPE_SRGB = 0,
AVIF_MINI_COLOR_TYPE_NCLX_5BIT = 1,
AVIF_MINI_COLOR_TYPE_NCLX_8BIT = 2,
AVIF_MINI_COLOR_TYPE_ICC = 3
} avifMiniColorType;
#endif // AVIF_ENABLE_EXPERIMENTAL_AVIR

// ---------------------------------------------------------------------------
Expand Down
92 changes: 46 additions & 46 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ typedef struct avifDecoderItem
avifBool ipmaSeen; // if true, this item already received a property association
avifBool progressive; // if true, this item has progressive layers (a1lx), but does not select a specific layer (the layer_id value in lsel is set to 0xFFFF)
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
avifPixelFormat coniPixelFormat; // Set from the CondensedImageBox, if present (AVIF_PIXEL_FORMAT_NONE otherwise)
avifChromaSamplePosition coniChromaSamplePosition; // Set from the CondensedImageBox, if present (AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN otherwise)
avifPixelFormat miniPixelFormat; // Set from the CondensedImageBox, if present (AVIF_PIXEL_FORMAT_NONE otherwise)
avifChromaSamplePosition miniChromaSamplePosition; // Set from the CondensedImageBox, if present (AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN otherwise)
#endif
} avifDecoderItem;
AVIF_ARRAY_DECLARE(avifDecoderItemArray, avifDecoderItem *, item);
Expand Down Expand Up @@ -741,7 +741,7 @@ typedef struct avifMeta
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
// If true, the fields above were extracted from a CondensedImageBox. It imposes some
// constraints on its optional extendedMeta field, such as forbidden item IDs, properties etc.
avifBool fromConi;
avifBool fromMini;
#endif
} avifMeta;

Expand Down Expand Up @@ -1192,14 +1192,14 @@ static avifResult avifDecoderItemValidateProperties(const avifDecoderItem * item
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (item->coniPixelFormat != AVIF_PIXEL_FORMAT_NONE) {
// This is a 'coni' box.
if (item->miniPixelFormat != AVIF_PIXEL_FORMAT_NONE) {
// This is a 'mini' box.

if (item->coniPixelFormat != avifCodecConfigurationBoxGetFormat(&configProp->u.av1C)) {
if (item->miniPixelFormat != avifCodecConfigurationBoxGetFormat(&configProp->u.av1C)) {
avifDiagnosticsPrintf(diag,
"Item ID %u format [%s] specified by coni box does not match %s property format [%s]",
"Item ID %u format [%s] specified by mini box does not match %s property format [%s]",
item->id,
avifPixelFormatToString(item->coniPixelFormat),
avifPixelFormatToString(item->miniPixelFormat),
configPropName,
avifPixelFormatToString(avifCodecConfigurationBoxGetFormat(&configProp->u.av1C)));
return AVIF_RESULT_BMFF_PARSE_FAILED;
Expand All @@ -1210,12 +1210,12 @@ static avifResult avifDecoderItemValidateProperties(const avifDecoderItem * item
// CSP_UNKNOWN - the source video transfer function must be signaled outside the AV1 bitstream
// See https://aomediacodec.github.io/av1-spec/#color-config-semantics

// So item->coniChromaSamplePosition can differ and will override the AV1 value.
} else if ((uint8_t)item->coniChromaSamplePosition != configProp->u.av1C.chromaSamplePosition) {
// So item->miniChromaSamplePosition can differ and will override the AV1 value.
} else if ((uint8_t)item->miniChromaSamplePosition != configProp->u.av1C.chromaSamplePosition) {
avifDiagnosticsPrintf(diag,
"Item ID %u chroma sample position [%u] specified by coni box does not match %s property chroma sample position [%u]",
"Item ID %u chroma sample position [%u] specified by mini box does not match %s property chroma sample position [%u]",
item->id,
(uint32_t)item->coniChromaSamplePosition,
(uint32_t)item->miniChromaSamplePosition,
configPropName,
configProp->u.av1C.chromaSamplePosition);
return AVIF_RESULT_BMFF_PARSE_FAILED;
Expand Down Expand Up @@ -1650,7 +1650,7 @@ static avifResult avifDecoderFindMetadata(avifDecoder * decoder, avifMeta * meta
BEGIN_STREAM(exifBoxStream, exifContents.data, exifContents.size, &decoder->diag, "Exif header");
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
// The CondensedImageBox does not signal the exifTiffHeaderOffset.
if (!meta->fromConi)
if (!meta->fromMini)
#endif
{
uint32_t exifTiffHeaderOffset;
Expand Down Expand Up @@ -1759,7 +1759,7 @@ static avifResult avifParseItemLocationBox(avifMeta * meta, const uint8_t * raw,
}
AVIF_CHECKRES(avifCheckItemID("iloc", itemID, diag));
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (meta->fromConi && itemID < 5) {
if (meta->fromMini && itemID < 5) {
// This is the extendedMeta field of an enclosing CondensedImageBox.
// Item IDs 1 to 4 are reserved and already defined, including their locations.
avifDiagnosticsPrintf(diag, "%s: Box[iloc] has a forbidden item ID [%u]", s.diagContext, itemID);
Expand Down Expand Up @@ -1791,7 +1791,7 @@ static avifResult avifParseItemLocationBox(avifMeta * meta, const uint8_t * raw,
}
if (constructionMethod == 1) {
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (meta->fromConi) {
if (meta->fromMini) {
// This is the extendedMeta field of an enclosing CondensedImageBox.
// It may not contain an ItemDataBox.
avifDiagnosticsPrintf(diag, "%s: Box[iloc] has a forbidden construction method [%u]", s.diagContext, constructionMethod);
Expand Down Expand Up @@ -2341,7 +2341,7 @@ static avifResult avifParseItemPropertyContainerBox(avifPropertyArray * properti
static avifResult avifParseItemPropertyAssociation(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag, uint32_t * outVersionAndFlags)
{
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (meta->fromConi) {
if (meta->fromMini) {
// The CondensedImageBox will always create 8 item properties, so to refer to the
// first property in the ItemPropertyContainerBox of its extendedMeta field, use index 9.
assert(meta->properties.count >= 8);
Expand Down Expand Up @@ -2649,7 +2649,7 @@ static avifResult avifParseItemInfoEntry(avifMeta * meta, const uint8_t * raw, s
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (meta->fromConi && itemID < 5) {
if (meta->fromMini && itemID < 5) {
// This is the extendedMeta field of an enclosing CondensedImageBox.
// itemID 1 is reserved for the primary color item, 2 for the alpha auxiliary item,
// 3 for the Exif metadata item and 4 for the XMP metadata item.
Expand Down Expand Up @@ -3363,19 +3363,19 @@ static avifResult avifParseExtendedMeta(avifMeta * meta, uint64_t rawOffset, con

if (!memcmp(header.type, "hdlr", 4) || !memcmp(header.type, "dinf", 4) || !memcmp(header.type, "idat", 4) ||
!memcmp(header.type, "pitm", 4)) {
avifDiagnosticsPrintf(diag, "Box[coni] shall have no Box[%.4s] in its extendedMeta field", (const char *)header.type);
avifDiagnosticsPrintf(diag, "Box[mini] shall have no Box[%.4s] in its extendedMeta field", (const char *)header.type);
return AVIF_RESULT_BMFF_PARSE_FAILED;
} else if (!memcmp(header.type, "iinf", 4)) {
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 5, "coni", "iinf", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 5, "mini", "iinf", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKRES(avifParseItemInfoBox(meta, avifROStreamCurrent(&s), header.size, diag));
} else if (!memcmp(header.type, "iloc", 4)) {
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 1, "coni", "iloc", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 1, "mini", "iloc", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKRES(avifParseItemLocationBox(meta, avifROStreamCurrent(&s), header.size, diag));
} else if (!memcmp(header.type, "iprp", 4)) {
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 4, "coni", "iprp", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 4, "mini", "iprp", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKRES(avifParseItemPropertiesBox(meta, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, diag));
} else if (!memcmp(header.type, "iref", 4)) {
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 6, "coni", "iref", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 6, "mini", "iref", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKRES(avifParseItemReferenceBox(meta, avifROStreamCurrent(&s), header.size, diag));
}

Expand Down Expand Up @@ -3403,9 +3403,9 @@ static avifProperty * avifDecoderItemAddProperty(avifDecoderItem * item, const a
static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
// Experimental box.
BEGIN_STREAM(s, raw, rawLen, diag, "Box[coni]");
BEGIN_STREAM(s, raw, rawLen, diag, "Box[mini]");

meta->fromConi = AVIF_TRUE;
meta->fromMini = AVIF_TRUE;

// Read the bit fields.
// TODO(yguyon): Implement or return an appropriate error in cases where AVIF_RESULT_NOT_IMPLEMENTED is returned.
Expand Down Expand Up @@ -3451,7 +3451,7 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
uint32_t transferCharacteristics;
uint32_t matrixCoefficients;
uint32_t iccDataSize;
if (colorType == AVIF_CONI_COLOR_TYPE_ICC) {
if (colorType == AVIF_MINI_COLOR_TYPE_ICC) {
colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
if (isMonochrome) {
Expand All @@ -3462,14 +3462,14 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &iccDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint icc_data_size_minus_one;
AVIF_CHECKERR(iccDataSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++iccDataSize;
} else if (colorType == AVIF_CONI_COLOR_TYPE_SRGB) {
} else if (colorType == AVIF_MINI_COLOR_TYPE_SRGB) {
// sRGB
colorPrimaries = AVIF_COLOR_PRIMARIES_SRGB;
transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB;
matrixCoefficients = isMonochrome ? AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED : AVIF_MATRIX_COEFFICIENTS_BT601;
iccDataSize = 0;
} else {
const uint32_t numBitsPerComponent = (colorType == AVIF_CONI_COLOR_TYPE_NCLX_5BIT) ? 5 : 8;
const uint32_t numBitsPerComponent = (colorType == AVIF_MINI_COLOR_TYPE_NCLX_5BIT) ? 5 : 8;
AVIF_CHECKERR(avifROStreamReadBits(&s, &colorPrimaries, numBitsPerComponent),
AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(5/8) color_primaries;
AVIF_CHECKERR(avifROStreamReadBits(&s, &transferCharacteristics, numBitsPerComponent),
Expand Down Expand Up @@ -3539,14 +3539,14 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset

avifCodecConfigurationBox alphaCodecConfig = { 0 };
if (hasAlpha) {
AVIF_CHECKERR(avifParseCodecConfiguration(&s, &alphaCodecConfig, "coni", diag),
AVIF_CHECKERR(avifParseCodecConfiguration(&s, &alphaCodecConfig, "mini", diag),
AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) alpha_item_codec_config[];
}
avifCodecConfigurationBox colorCodecConfig;
AVIF_CHECKERR(avifParseCodecConfiguration(&s, &colorCodecConfig, "coni", diag),
AVIF_CHECKERR(avifParseCodecConfiguration(&s, &colorCodecConfig, "mini", diag),
AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) main_item_codec_config[];

// Make sure all extended_meta, metadata and coded chunks fit into the 'coni' box whose size is rawLen.
// Make sure all extended_meta, metadata and coded chunks fit into the 'mini' box whose size is rawLen.
// There should be no missing nor unused byte.
AVIF_CHECKERR(avifROStreamRemainingBytes(&s) ==
(uint64_t)extendedMetaSize + iccDataSize + alphaItemDataSize + colorItemDataSize + exifSize + xmpSize,
Expand All @@ -3569,17 +3569,17 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
memcpy(colorItem->type, "av01", 4);
colorItem->width = width;
colorItem->height = height;
colorItem->coniPixelFormat = yuvFormat;
colorItem->coniChromaSamplePosition = yuvChromaSamplePosition;
colorItem->miniPixelFormat = yuvFormat;
colorItem->miniChromaSamplePosition = yuvChromaSamplePosition;

avifDecoderItem * alphaItem = NULL;
if (hasAlpha) {
AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, /*itemID=*/2, &alphaItem));
memcpy(alphaItem->type, "av01", 4);
alphaItem->width = width;
alphaItem->height = height;
alphaItem->coniPixelFormat = AVIF_PIXEL_FORMAT_YUV400;
alphaItem->coniChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
alphaItem->miniPixelFormat = AVIF_PIXEL_FORMAT_YUV400;
alphaItem->miniChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
}

// Property with fixed index 1.
Expand Down Expand Up @@ -3755,8 +3755,8 @@ static avifResult avifParse(avifDecoder * decoder)
avifBool needsMeta = AVIF_FALSE;
avifBool needsMoov = AVIF_FALSE;
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
avifBool coniSeen = AVIF_FALSE;
avifBool needsConi = AVIF_FALSE;
avifBool miniSeen = AVIF_FALSE;
avifBool needsMini = AVIF_FALSE;
#endif

for (;;) {
Expand Down Expand Up @@ -3789,7 +3789,7 @@ static avifResult avifParse(avifDecoder * decoder)
// TODO: reorg this code to only do these memcmps once each
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (!memcmp(header.type, "ftyp", 4) || !memcmp(header.type, "meta", 4) || !memcmp(header.type, "moov", 4) ||
!memcmp(header.type, "coni", 4)) {
!memcmp(header.type, "mini", 4)) {
#else
if (!memcmp(header.type, "ftyp", 4) || !memcmp(header.type, "meta", 4) || !memcmp(header.type, "moov", 4)) {
#endif
Expand Down Expand Up @@ -3819,8 +3819,8 @@ static avifResult avifParse(avifDecoder * decoder)
needsMeta = avifFileTypeHasBrand(&ftyp, "avif");
needsMoov = avifFileTypeHasBrand(&ftyp, "avis");
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
needsConi = avifFileTypeHasBrand(&ftyp, "avir");
if (needsConi && (needsMeta || needsMoov)) {
needsMini = avifFileTypeHasBrand(&ftyp, "avir");
if (needsMini && (needsMeta || needsMoov)) {
return AVIF_RESULT_INVALID_FTYP;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_AVIR
Expand All @@ -3835,26 +3835,26 @@ static avifResult avifParse(avifDecoder * decoder)
moovSeen = AVIF_TRUE;
decoder->imageSequenceTrackPresent = AVIF_TRUE;
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
} else if (!memcmp(header.type, "coni", 4)) {
} else if (!memcmp(header.type, "mini", 4)) {
AVIF_CHECKERR(!metaSeen && !moovSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
AVIF_CHECKRES(avifParseCondensedImageBox(data->meta, boxOffset, boxContents.data, boxContents.size, data->diag));
coniSeen = AVIF_TRUE;
miniSeen = AVIF_TRUE;
#endif // AVIF_ENABLE_EXPERIMENTAL_AVIR
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (ftypSeen && !needsConi && coniSeen) {
// The 'coni' box should be ignored if there is no 'avir' brand, but libavif allows reading them in any order.
if (ftypSeen && !needsMini && miniSeen) {
// The 'mini' box should be ignored if there is no 'avir' brand, but libavif allows reading them in any order.
return AVIF_RESULT_NOT_IMPLEMENTED; // TODO(yguyon): Implement
}
#endif // AVIF_ENABLE_EXPERIMENTAL_AVIR

// See if there is enough information to consider Parse() a success and early-out:
// * If the brand 'avif' is present, require a meta box
// * If the brand 'avis' is present, require a moov box
// * If AVIF_ENABLE_EXPERIMENTAL_AVIR is defined and the brand 'avir' is present, require a coni box
// * If AVIF_ENABLE_EXPERIMENTAL_AVIR is defined and the brand 'avir' is present, require a mini box
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (ftypSeen && (!needsMeta || metaSeen) && (!needsMoov || moovSeen) && (!needsConi || coniSeen)) {
if (ftypSeen && (!needsMeta || metaSeen) && (!needsMoov || moovSeen) && (!needsMini || miniSeen)) {
#else
if (ftypSeen && (!needsMeta || metaSeen) && (!needsMoov || moovSeen)) {
#endif
Expand All @@ -3868,7 +3868,7 @@ static avifResult avifParse(avifDecoder * decoder)
return AVIF_RESULT_TRUNCATED_DATA;
}
#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
if (needsConi && !coniSeen) {
if (needsMini && !miniSeen) {
return AVIF_RESULT_TRUNCATED_DATA;
}
#endif
Expand Down
Loading

0 comments on commit 3fab232

Please sign in to comment.