Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add avifIsAlpha() to internal.h #2057

Merged
merged 3 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/avif/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ void avifImageCopyNoAlloc(avifImage * dstImage, const avifImage * srcImage);
// Ignores the gainMap field (which exists only if AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP is defined).
void avifImageCopySamples(avifImage * dstImage, const avifImage * srcImage, avifPlanesFlags planes);

// ---------------------------------------------------------------------------
// Alpha

typedef struct avifAlphaParams
{
uint32_t width;
Expand Down Expand Up @@ -321,6 +324,8 @@ typedef enum avifItemCategory
AVIF_ITEM_CATEGORY_COUNT
} avifItemCategory;

avifBool avifIsAlpha(avifItemCategory itemCategory);

// ---------------------------------------------------------------------------

#if defined(AVIF_ENABLE_EXPERIMENTAL_AVIR)
Expand Down
10 changes: 10 additions & 0 deletions src/avif.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,16 @@ avifBool avifCleanApertureBoxConvertCropRect(avifCleanApertureBox * clap,

// ---------------------------------------------------------------------------

avifBool avifIsAlpha(avifItemCategory itemCategory)
{
if (itemCategory == AVIF_ITEM_ALPHA) {
return AVIF_TRUE;
}
return AVIF_FALSE;
}

// ---------------------------------------------------------------------------

avifBool avifAreGridDimensionsValid(avifPixelFormat yuvFormat, uint32_t imageW, uint32_t imageH, uint32_t tileW, uint32_t tileH, avifDiagnostics * diag)
{
// ISO/IEC 23000-22:2019, Section 7.3.11.4.2:
Expand Down
21 changes: 10 additions & 11 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ static avifResult avifDecoderDataAllocateGridImagePlanes(avifDecoderData * data,
return AVIF_RESULT_INVALID_IMAGE_GRID;
}

avifBool alpha = (tile->input->itemCategory == AVIF_ITEM_ALPHA);
const avifBool alpha = avifIsAlpha(tile->input->itemCategory);
if (alpha) {
// An alpha tile does not contain any YUV pixels.
AVIF_ASSERT_OR_RETURN(tile->image->yuvFormat == AVIF_PIXEL_FORMAT_NONE);
Expand Down Expand Up @@ -1618,8 +1618,7 @@ static avifResult avifDecoderDataCopyTileToImage(avifDecoderData * data,
#endif
AVIF_ASSERT_OR_RETURN(avifImageSetViewRect(&dstView, dst, &dstViewRect) == AVIF_RESULT_OK &&
avifImageSetViewRect(&srcView, tile->image, &srcViewRect) == AVIF_RESULT_OK);
avifImageCopySamples(&dstView, &srcView, (tile->input->itemCategory == AVIF_ITEM_ALPHA) ? AVIF_PLANES_A : AVIF_PLANES_YUV);

avifImageCopySamples(&dstView, &srcView, avifIsAlpha(tile->input->itemCategory) ? AVIF_PLANES_A : AVIF_PLANES_YUV);
return AVIF_RESULT_OK;
}

Expand Down Expand Up @@ -4968,7 +4967,7 @@ avifResult avifDecoderReset(avifDecoder * decoder)
continue;
}
#endif
if (c == AVIF_ITEM_ALPHA && !mainItems[c]->width && !mainItems[c]->height) {
if (avifIsAlpha(c) && !mainItems[c]->width && !mainItems[c]->height) {
// NON-STANDARD: Alpha subimage does not have an ispe property; adopt width/height from color item
AVIF_ASSERT_OR_RETURN(!(decoder->strictFlags & AVIF_STRICT_ALPHA_ISPE_REQUIRED));
mainItems[c]->width = mainItems[AVIF_ITEM_COLOR]->width;
Expand All @@ -4978,7 +4977,7 @@ avifResult avifDecoderReset(avifDecoder * decoder)
AVIF_CHECKRES(avifDecoderGenerateImageTiles(decoder, &data->tileInfos[c], mainItems[c], c));

avifStrictFlags strictFlags = decoder->strictFlags;
if (c == AVIF_ITEM_ALPHA && !isAlphaItemInInput) {
if (avifIsAlpha(c) && !isAlphaItemInInput) {
// In this case, the made up grid item will not have an associated pixi property. So validate everything else
// but the pixi property.
strictFlags &= ~AVIF_STRICT_PIXI_REQUIRED;
Expand All @@ -4989,7 +4988,7 @@ avifResult avifDecoderReset(avifDecoder * decoder)

if (mainItems[AVIF_ITEM_COLOR]->progressive) {
decoder->progressiveState = AVIF_PROGRESSIVE_STATE_AVAILABLE;
// data->color.firstTileIndex is not yet defined but will be set to 0 a few lines below.
// data->tileInfos[AVIF_ITEM_COLOR].firstTileIndex is not yet defined but will be set to 0 a few lines below.
const avifTile * colorTile = &data->tiles.tile[0];
if (colorTile->input->samples.count > 1) {
decoder->progressiveState = AVIF_PROGRESSIVE_STATE_ACTIVE;
Expand Down Expand Up @@ -5184,7 +5183,7 @@ static avifResult avifGetErrorForItemCategory(avifItemCategory itemCategory)
return AVIF_RESULT_DECODE_GAIN_MAP_FAILED;
}
#endif
return (itemCategory == AVIF_ITEM_ALPHA) ? AVIF_RESULT_DECODE_ALPHA_FAILED : AVIF_RESULT_DECODE_COLOR_FAILED;
return avifIsAlpha(itemCategory) ? AVIF_RESULT_DECODE_ALPHA_FAILED : AVIF_RESULT_DECODE_COLOR_FAILED;
}

static avifResult avifDecoderDecodeTiles(avifDecoder * decoder, uint32_t nextImageIndex, avifTileInfo * info)
Expand All @@ -5201,7 +5200,7 @@ static avifResult avifDecoderDecodeTiles(avifDecoder * decoder, uint32_t nextIma
}

avifBool isLimitedRangeAlpha = AVIF_FALSE;
if (!tile->codec->getNextImage(tile->codec, decoder, sample, tile->input->itemCategory == AVIF_ITEM_ALPHA, &isLimitedRangeAlpha, tile->image)) {
if (!tile->codec->getNextImage(tile->codec, decoder, sample, avifIsAlpha(tile->input->itemCategory), &isLimitedRangeAlpha, tile->image)) {
avifDiagnosticsPrintf(&decoder->diag, "tile->codec->getNextImage() failed");
return avifGetErrorForItemCategory(tile->input->itemCategory);
}
Expand Down Expand Up @@ -5229,7 +5228,7 @@ static avifResult avifDecoderDecodeTiles(avifDecoder * decoder, uint32_t nextIma
// of the specification. However, it was allowed in version 1.0.0 of the
// specification. To allow such files, simply convert the alpha plane to
// full range.
if ((tile->input->itemCategory == AVIF_ITEM_ALPHA) && isLimitedRangeAlpha) {
if (avifIsAlpha(tile->input->itemCategory) && isLimitedRangeAlpha) {
avifResult result = avifImageLimitedToFullAlpha(tile->image);
if (result != AVIF_RESULT_OK) {
avifDiagnosticsPrintf(&decoder->diag, "avifImageLimitedToFullAlpha failed");
Expand Down Expand Up @@ -5281,7 +5280,7 @@ static avifResult avifDecoderDecodeTiles(avifDecoder * decoder, uint32_t nextIma
default:
if ((decoder->image->width != src->width) || (decoder->image->height != src->height) ||
(decoder->image->depth != src->depth)) {
if (tile->input->itemCategory == AVIF_ITEM_ALPHA) {
if (avifIsAlpha(tile->input->itemCategory)) {
avifDiagnosticsPrintf(&decoder->diag,
"The color image item does not match the alpha image item in width, height, or bit depth");
return AVIF_RESULT_DECODE_ALPHA_FAILED;
Expand All @@ -5295,7 +5294,7 @@ static avifResult avifDecoderDecodeTiles(avifDecoder * decoder, uint32_t nextIma
break;
}

if (tile->input->itemCategory == AVIF_ITEM_ALPHA) {
if (avifIsAlpha(tile->input->itemCategory)) {
avifImageStealPlanes(decoder->image, src, AVIF_PLANES_A);
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
} else if (tile->input->itemCategory == AVIF_ITEM_GAIN_MAP) {
Expand Down
37 changes: 23 additions & 14 deletions src/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,7 @@ static avifResult avifEncoderAddImageItems(avifEncoder * encoder,
uint16_t * topLevelItemID)
{
const uint32_t cellCount = gridCols * gridRows;
const char * infeName = (itemCategory == AVIF_ITEM_ALPHA) ? infeNameAlpha
const char * infeName = avifIsAlpha(itemCategory) ? infeNameAlpha
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
: (itemCategory == AVIF_ITEM_GAIN_MAP) ? infeNameGainMap
#endif
Expand Down Expand Up @@ -1192,7 +1192,12 @@ static avifBool avifEncoderDataShouldForceKeyframeForAlpha(const avifEncoderData

static avifResult avifGetErrorForItemCategory(avifItemCategory itemCategory)
{
return (itemCategory == AVIF_ITEM_ALPHA) ? AVIF_RESULT_ENCODE_ALPHA_FAILED : AVIF_RESULT_ENCODE_COLOR_FAILED;
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
if (itemCategory == AVIF_ITEM_GAIN_MAP) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a bug fix then?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, a tiny one

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please mention this bug fix in the commit message.

return AVIF_RESULT_ENCODE_GAIN_MAP_FAILED;
}
#endif
return avifIsAlpha(itemCategory) ? AVIF_RESULT_ENCODE_ALPHA_FAILED : AVIF_RESULT_ENCODE_COLOR_FAILED;
}

static avifResult avifValidateImageBasicProperties(const avifImage * avifImage)
Expand Down Expand Up @@ -1662,7 +1667,9 @@ static avifResult avifEncoderAddImageInternal(avifEncoder * encoder,
}
cellImage = paddedCellImage;
}
const int quantizer = (item->itemCategory == AVIF_ITEM_ALPHA) ? encoder->data->quantizerAlpha

const avifBool isAlpha = avifIsAlpha(item->itemCategory);
const int quantizer = isAlpha ? encoder->data->quantizerAlpha
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
: (item->itemCategory == AVIF_ITEM_GAIN_MAP) ? encoder->data->quantizerGainMap
#endif
Expand All @@ -1673,7 +1680,7 @@ static avifResult avifEncoderAddImageInternal(avifEncoder * encoder,
avifResult encodeResult = item->codec->encodeImage(item->codec,
encoder,
cellImage,
item->itemCategory == AVIF_ITEM_ALPHA,
isAlpha,
encoder->data->tileRowsLog2,
encoder->data->tileColsLog2,
quantizer,
Expand Down Expand Up @@ -1780,10 +1787,12 @@ static avifResult avifEncoderWriteMediaDataBox(avifEncoder * encoder,
// only process metadata (XMP/Exif) payloads when metadataPass is true
continue;
}
avifBool isAlphaOrGainMap = item->itemCategory == AVIF_ITEM_ALPHA;
const avifBool isAlpha = avifIsAlpha(item->itemCategory);
const avifBool isAlphaOrGainMap = isAlpha
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
isAlphaOrGainMap = isAlphaOrGainMap || item->itemCategory == AVIF_ITEM_GAIN_MAP;
|| item->itemCategory == AVIF_ITEM_GAIN_MAP
#endif
;
if (alphaAndGainMapPass != isAlphaOrGainMap) {
// only process alpha payloads when alphaPass is true
continue;
Expand All @@ -1794,8 +1803,7 @@ static avifResult avifEncoderWriteMediaDataBox(avifEncoder * encoder,
// We always interleave all AV1 items for layered images.
AVIF_ASSERT_OR_RETURN(item->encodeOutput->samples.count == item->mdatFixups.count);

avifEncoderItemReference * ref = (item->itemCategory == AVIF_ITEM_ALPHA) ? avifArrayPush(layeredAlphaItems)
: avifArrayPush(layeredColorItems);
avifEncoderItemReference * ref = avifArrayPush(isAlpha ? layeredAlphaItems : layeredColorItems);
AVIF_CHECKERR(ref != NULL, AVIF_RESULT_OUT_OF_MEMORY);
*ref = item;
continue;
Expand All @@ -1820,7 +1828,7 @@ static avifResult avifEncoderWriteMediaDataBox(avifEncoder * encoder,
avifEncodeSample * sample = &item->encodeOutput->samples.sample[sampleIndex];
AVIF_CHECKRES(avifRWStreamWrite(s, sample->data.data, sample->data.size));

if (item->itemCategory == AVIF_ITEM_ALPHA) {
if (isAlpha) {
encoder->ioStats.alphaOBUSize += sample->data.size;
} else if (item->itemCategory == AVIF_ITEM_COLOR) {
encoder->ioStats.colorOBUSize += sample->data.size;
Expand Down Expand Up @@ -2254,7 +2262,7 @@ static avifResult avifRWStreamWriteProperties(avifItemPropertyDedup * const dedu
imageHeight = item->gridHeight;
}

// Properties all image items need
// Properties all image items need (coded and derived)
// ispe = image spatial extent (width, height)
avifItemPropertyDedupStart(dedup);
avifBoxMarker ispe;
Expand All @@ -2272,15 +2280,16 @@ static avifResult avifRWStreamWriteProperties(avifItemPropertyDedup * const dedu
hasPixi = AVIF_FALSE;
}
#endif
const avifBool isAlpha = avifIsAlpha(item->itemCategory);
const uint8_t depth = (uint8_t)itemMetadata->depth;
if (hasPixi) {
avifItemPropertyDedupStart(dedup);
uint8_t channelCount =
(item->itemCategory == AVIF_ITEM_ALPHA || (itemMetadata->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) ? 1 : 3;
uint8_t channelCount = (isAlpha || (itemMetadata->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) ? 1 : 3;
avifBoxMarker pixi;
AVIF_CHECKRES(avifRWStreamWriteFullBox(&dedup->s, "pixi", AVIF_BOX_SIZE_TBD, 0, 0, &pixi));
AVIF_CHECKRES(avifRWStreamWriteU8(&dedup->s, channelCount)); // unsigned int (8) num_channels;
for (uint8_t chan = 0; chan < channelCount; ++chan) {
AVIF_CHECKRES(avifRWStreamWriteU8(&dedup->s, (uint8_t)itemMetadata->depth)); // unsigned int (8) bits_per_channel;
AVIF_CHECKRES(avifRWStreamWriteU8(&dedup->s, depth)); // unsigned int (8) bits_per_channel;
}
avifRWStreamFinishBox(&dedup->s, pixi);
AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->ipma, AVIF_FALSE));
Expand All @@ -2293,7 +2302,7 @@ static avifResult avifRWStreamWriteProperties(avifItemPropertyDedup * const dedu
AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->ipma, AVIF_TRUE));
}

if (item->itemCategory == AVIF_ITEM_ALPHA) {
if (isAlpha) {
// Alpha specific properties

avifItemPropertyDedupStart(dedup);
Expand Down
Loading