* Additional changes for PR #477
* clang-format all files
* Make it clear in avifenc syntax that -p signals prem in the resultant AVIF
* Fix tref prem parsing to match tref auxl parsing (same syntax/box)
* parenthesize binops in assignments (style)
* Continue new convertResult pattern in avifImageYUVToRGB instead of early-out
* Replace pColorIrefType/pColorIrefToID with new avifEncoderDataFindItemByID() call, as
avifEncoderItem* mem storage may shift during new calls to avifEncoderDataCreateItem() so
deep pointers into them during this is bad, plus this happens to remove accidental
Hungarian notation, which is good
diff --git a/apps/avifenc.c b/apps/avifenc.c
index 3aa74c5..e95a564 100644
--- a/apps/avifenc.c
+++ b/apps/avifenc.c
@@ -54,7 +54,7 @@
printf(" -l,--lossless : Set all defaults to encode losslessly, and emit warnings when settings/input don't allow for it\n");
printf(" -d,--depth D : Output depth [8,10,12]. (JPEG/PNG only; For y4m or stdin, depth is retained)\n");
printf(" -y,--yuv FORMAT : Output format [default=444, 422, 420, 400]. (JPEG/PNG only; For y4m or stdin, format is retained)\n");
- printf(" -p,--premultiply : Premultiply color with alpha channel\n");
+ printf(" -p,--premultiply : Premultiply color with alpha channel and signal this in the AVIF\n");
printf(" --stdin : Read y4m frames from stdin instead of files; no input filenames allowed, must set before offering output filename\n");
printf(" --cicp,--nclx P/T/M : Set CICP values (nclx colr box) (3 raw numbers, use -r to set range flag)\n");
printf(" P = enum avifColorPrimaries\n");
diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c
index eec32d3..453f6cc 100644
--- a/apps/shared/avifjpeg.c
+++ b/apps/shared/avifjpeg.c
@@ -116,7 +116,8 @@
#if !defined(JCS_ALPHA_EXTENSIONS)
// this is only for removing alpha when processing non-premultiplied image.
-static void avifRGBAToRGB(const avifRGBImage * src, avifRGBImage * dst) {
+static void avifRGBAToRGB(const avifRGBImage * src, avifRGBImage * dst)
+{
dst->width = src->width;
dst->height = src->height;
dst->format = AVIF_RGB_FORMAT_RGB;
diff --git a/include/avif/avif.h b/include/avif/avif.h
index c13fa74..bbe0f35 100644
--- a/include/avif/avif.h
+++ b/include/avif/avif.h
@@ -471,8 +471,8 @@
avifRGBFormat format; // all channels are always full range
avifChromaUpsampling chromaUpsampling; // Defaults to AVIF_CHROMA_UPSAMPLING_AUTOMATIC: How to upsample non-4:4:4 UV (ignored for 444) when converting to RGB.
// Unused when converting to YUV. avifRGBImageSetDefaults() prefers quality over speed.
- avifBool ignoreAlpha; // Used for XRGB formats, treats formats containing alpha (such as ARGB) as if they were
- // RGB, treating the alpha bits as if they were all 1.
+ avifBool ignoreAlpha; // Used for XRGB formats, treats formats containing alpha (such as ARGB) as if they were
+ // RGB, treating the alpha bits as if they were all 1.
avifBool alphaPremultiplied; // indicates if RGB value is pre-multiplied by alpha
uint8_t * pixels;
diff --git a/src/alpha.c b/src/alpha.c
index fa1d551..e3301ae 100644
--- a/src/alpha.c
+++ b/src/alpha.c
@@ -3,8 +3,8 @@
#include "avif/internal.h"
-#include <string.h>
#include <assert.h>
+#include <string.h>
static int calcMaxChannel(uint32_t depth, avifRange range)
{
@@ -382,7 +382,8 @@
return AVIF_TRUE;
}
-avifResult avifRGBImagePremultiplyAlpha(avifRGBImage * rgb) {
+avifResult avifRGBImagePremultiplyAlpha(avifRGBImage * rgb)
+{
// no data
if (!rgb->pixels || !rgb->rowBytes) {
return AVIF_RESULT_REFORMAT_FAILED;
diff --git a/src/read.c b/src/read.c
index 941b20d..db18c9a 100644
--- a/src/read.c
+++ b/src/read.c
@@ -2033,12 +2033,13 @@
if (!memcmp(header.type, "auxl", 4)) {
uint32_t toID;
- CHECK(avifROStreamReadU32(&s, &toID)); // unsigned int(32) track_IDs[]
+ CHECK(avifROStreamReadU32(&s, &toID)); // unsigned int(32) track_IDs[];
CHECK(avifROStreamSkip(&s, header.size - sizeof(uint32_t))); // just take the first one
track->auxForID = toID;
} else if (!memcmp(header.type, "prem", 4)) {
uint32_t byID;
- CHECK(avifROStreamReadU32(&s, &byID)); // unsigned int(32) to_item_ID
+ CHECK(avifROStreamReadU32(&s, &byID)); // unsigned int(32) track_IDs[];
+ CHECK(avifROStreamSkip(&s, header.size - sizeof(uint32_t))); // just take the first one
track->premByID = byID;
} else {
CHECK(avifROStreamSkip(&s, header.size));
@@ -2613,7 +2614,7 @@
decoder->image->width = colorTrack->width;
decoder->image->height = colorTrack->height;
decoder->alphaPresent = (alphaTrack != NULL);
- decoder->image->alphaPremultiplied = decoder->alphaPresent && colorTrack->premByID == alphaTrack->id;
+ decoder->image->alphaPremultiplied = decoder->alphaPresent && (colorTrack->premByID == alphaTrack->id);
} else {
// Create from items
@@ -2770,7 +2771,7 @@
decoder->image->height = 0;
}
decoder->alphaPresent = (alphaItem != NULL);
- decoder->image->alphaPremultiplied = decoder->alphaPresent && colorItem->premByID == alphaItem->id;
+ decoder->image->alphaPremultiplied = decoder->alphaPresent && (colorItem->premByID == alphaItem->id);
}
// Sanity check tiles
diff --git a/src/reformat.c b/src/reformat.c
index 047b8c1..54a3058 100644
--- a/src/reformat.c
+++ b/src/reformat.c
@@ -1138,9 +1138,9 @@
if (avifRGBFormatHasAlpha(rgb->format) && !rgb->ignoreAlpha) {
if (image->alphaPremultiplied && !rgb->alphaPremultiplied) {
- return avifRGBImageUnpremultiplyAlpha(rgb);
+ convertResult = avifRGBImageUnpremultiplyAlpha(rgb);
} else if (!image->alphaPremultiplied && rgb->alphaPremultiplied) {
- return avifRGBImagePremultiplyAlpha(rgb);
+ convertResult = avifRGBImagePremultiplyAlpha(rgb);
}
}
diff --git a/src/write.c b/src/write.c
index e8ae8ac..b65f993 100644
--- a/src/write.c
+++ b/src/write.c
@@ -3,6 +3,7 @@
#include "avif/internal.h"
+#include <assert.h>
#include <string.h>
#include <time.h>
@@ -145,6 +146,17 @@
return item;
}
+static avifEncoderItem * avifEncoderDataFindItemByID(avifEncoderData * data, uint16_t id)
+{
+ for (uint32_t itemIndex = 0; itemIndex < data->items.count; ++itemIndex) {
+ avifEncoderItem * item = &data->items.item[itemIndex];
+ if (item->id == id) {
+ return item;
+ }
+ }
+ return NULL;
+}
+
static void avifEncoderDataDestroy(avifEncoderData * data)
{
for (uint32_t i = 0; i < data->items.count; ++i) {
@@ -461,9 +473,6 @@
// Prepare all AV1 items
- const char ** pColorIrefType = NULL;
- uint16_t * pColorIrefToID = NULL;
-
uint16_t gridColorID = 0;
if (cellCount > 1) {
avifEncoderItem * gridColorItem = avifEncoderDataCreateItem(encoder->data, "grid", "Color", 6, 0);
@@ -473,8 +482,6 @@
gridColorID = gridColorItem->id;
encoder->data->primaryItemID = gridColorID;
- pColorIrefType = &gridColorItem->irefType;
- pColorIrefToID = &gridColorItem->irefToID;
}
for (uint32_t cellIndex = 0; cellIndex < cellCount; ++cellIndex) {
@@ -490,8 +497,6 @@
item->dimgFromID = gridColorID;
} else {
encoder->data->primaryItemID = item->id;
- pColorIrefType = &item->irefType;
- pColorIrefToID = &item->irefToID;
}
}
@@ -529,8 +534,10 @@
gridAlphaID = gridAlphaItem->id;
if (encoder->data->imageMetadata->alphaPremultiplied) {
- *pColorIrefType = "prem";
- *pColorIrefToID = gridAlphaID;
+ avifEncoderItem * primaryItem = avifEncoderDataFindItemByID(encoder->data, encoder->data->primaryItemID);
+ assert(primaryItem);
+ primaryItem->irefType = "prem";
+ primaryItem->irefToID = gridAlphaID;
}
}
@@ -550,8 +557,10 @@
item->irefType = "auxl";
if (encoder->data->imageMetadata->alphaPremultiplied) {
- *pColorIrefType = "prem";
- *pColorIrefToID = item->id;
+ avifEncoderItem * primaryItem = avifEncoderDataFindItemByID(encoder->data, encoder->data->primaryItemID);
+ assert(primaryItem);
+ primaryItem->irefType = "prem";
+ primaryItem->irefToID = item->id;
}
}
}