parent
d58482f88d
commit
b0bfd6d028
@ -1,2 +1,3 @@
|
|||||||
/libavif-0.5.7.tar.gz
|
/libavif-0.5.7.tar.gz
|
||||||
/libavif-0.7.1.tar.gz
|
/libavif-0.7.1.tar.gz
|
||||||
|
/libavif-0.7.2.tar.gz
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
From 84232e2d786967e1ce9aec668f0d31568e83f72c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
Date: Wed, 29 Apr 2020 17:34:57 +0200
|
||||||
|
Subject: [PATCH] apps: Use correct enum for colourPrimaries
|
||||||
|
|
||||||
|
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
---
|
||||||
|
apps/avifenc.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/apps/avifenc.c b/apps/avifenc.c
|
||||||
|
index 11595b7..e812670 100644
|
||||||
|
--- a/apps/avifenc.c
|
||||||
|
+++ b/apps/avifenc.c
|
||||||
|
@@ -352,7 +352,7 @@ int main(int argc, char * argv[])
|
||||||
|
if (lossless && (inputFormat != AVIF_APP_FILE_FORMAT_Y4M)) {
|
||||||
|
if (!nclxSet) { // don't stomp on the user's cmdline nclx values
|
||||||
|
// Assume SRGB unless they tell us otherwise via --nclx
|
||||||
|
- nclx.colourPrimaries = AVIF_NCLX_TRANSFER_CHARACTERISTICS_BT709;
|
||||||
|
+ nclx.colourPrimaries = AVIF_NCLX_COLOUR_PRIMARIES_BT709;
|
||||||
|
nclx.transferCharacteristics = AVIF_NCLX_TRANSFER_CHARACTERISTICS_SRGB;
|
||||||
|
nclx.matrixCoefficients = AVIF_NCLX_MATRIX_COEFFICIENTS_IDENTITY; // this is key for lossless
|
||||||
|
nclx.range = AVIF_RANGE_FULL;
|
@ -0,0 +1,279 @@
|
|||||||
|
From e4e5d752ece581d6ef9fbb8bab0ab2edfde13fc5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joe Drago <jdrago@netflix.com>
|
||||||
|
Date: Mon, 27 Apr 2020 14:27:31 -0700
|
||||||
|
Subject: [PATCH] Added avifenc Lossless (--lossless, -l) mode, which sets new
|
||||||
|
defaults and warns when anything would cause the AVIF to not be lossless
|
||||||
|
|
||||||
|
---
|
||||||
|
CHANGELOG.md | 2 +
|
||||||
|
apps/avifenc.c | 119 ++++++++++++++++++++++++++++++++++++++---
|
||||||
|
apps/shared/avifjpeg.c | 2 +-
|
||||||
|
apps/shared/avifjpeg.h | 2 +-
|
||||||
|
apps/shared/avifpng.c | 8 ++-
|
||||||
|
apps/shared/avifpng.h | 4 +-
|
||||||
|
6 files changed, 123 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/CHANGELOG.md b/CHANGELOG.md
|
||||||
|
index 19c8d08..8d05a5f 100644
|
||||||
|
--- a/CHANGELOG.md
|
||||||
|
+++ b/CHANGELOG.md
|
||||||
|
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
+### Added
|
||||||
|
+- avifenc: Lossless (--lossless, -l) mode, which sets new defaults and warns when anything would cause the AVIF to not be lossless
|
||||||
|
|
||||||
|
## [0.7.2] - 2020-04-24
|
||||||
|
### Added
|
||||||
|
diff --git a/apps/avifenc.c b/apps/avifenc.c
|
||||||
|
index 357596c..2d5a591 100644
|
||||||
|
--- a/apps/avifenc.c
|
||||||
|
+++ b/apps/avifenc.c
|
||||||
|
@@ -25,6 +25,7 @@ static void syntax(void)
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -h,--help : Show syntax help\n");
|
||||||
|
printf(" -j,--jobs J : Number of jobs (worker threads, default: 1)\n");
|
||||||
|
+ 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, depth is retained)\n");
|
||||||
|
printf(" -y,--yuv FORMAT : Output format [default=444, 422, 420]. (JPEG/PNG only; For y4m, format is retained)\n");
|
||||||
|
printf(" -n,--nclx P/T/M : Set nclx colr box values (3 raw numbers, use -r to set range flag)\n");
|
||||||
|
@@ -156,6 +157,7 @@ int main(int argc, char * argv[])
|
||||||
|
avifRange requestedRange = AVIF_RANGE_FULL;
|
||||||
|
avifBool requestedRangeSet = AVIF_FALSE;
|
||||||
|
avifBool nclxSet = AVIF_FALSE;
|
||||||
|
+ avifBool lossless = AVIF_FALSE;
|
||||||
|
avifEncoder * encoder = NULL;
|
||||||
|
|
||||||
|
avifNclxColorProfile nclx;
|
||||||
|
@@ -300,6 +302,19 @@ int main(int argc, char * argv[])
|
||||||
|
fprintf(stderr, "ERROR: Invalid imir axis: %s\n", arg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+ } else if (!strcmp(arg, "-l") || !strcmp(arg, "--lossless")) {
|
||||||
|
+ lossless = AVIF_TRUE;
|
||||||
|
+
|
||||||
|
+ // Set defaults, and warn later on if anything looks incorrect
|
||||||
|
+ requestedFormat = AVIF_PIXEL_FORMAT_YUV444; // don't subsample GBR
|
||||||
|
+ minQuantizer = AVIF_QUANTIZER_LOSSLESS; // lossless
|
||||||
|
+ maxQuantizer = AVIF_QUANTIZER_LOSSLESS; // lossless
|
||||||
|
+ minQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS; // lossless
|
||||||
|
+ maxQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS; // lossless
|
||||||
|
+ codecChoice = AVIF_CODEC_CHOICE_AOM; // rav1e doesn't support lossless transform yet:
|
||||||
|
+ // https://github.com/xiph/rav1e/issues/151
|
||||||
|
+ requestedRange = AVIF_RANGE_FULL; // avoid limited range
|
||||||
|
+ requestedRangeSet = AVIF_TRUE;
|
||||||
|
} else {
|
||||||
|
// Positional argument
|
||||||
|
if (!inputFilename) {
|
||||||
|
@@ -325,6 +340,26 @@ int main(int argc, char * argv[])
|
||||||
|
avifImage * avif = avifImageCreateEmpty();
|
||||||
|
avifRWData raw = AVIF_DATA_EMPTY;
|
||||||
|
|
||||||
|
+ uint32_t sourceDepth = 0;
|
||||||
|
+ avifBool sourceWasRGB = AVIF_TRUE;
|
||||||
|
+ avifAppFileFormat inputFormat = avifGuessFileFormat(inputFilename);
|
||||||
|
+ if (inputFormat == AVIF_APP_FILE_FORMAT_UNKNOWN) {
|
||||||
|
+ fprintf(stderr, "Cannot determine input file extension: %s\n", inputFilename);
|
||||||
|
+ returnCode = 1;
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (lossless && (inputFormat != AVIF_APP_FILE_FORMAT_Y4M)) {
|
||||||
|
+ if (!nclxSet) { // don't stomp on the user's cmdline nclx values
|
||||||
|
+ // Assume SRGB unless they tell us otherwise via --nclx
|
||||||
|
+ nclx.colourPrimaries = AVIF_NCLX_TRANSFER_CHARACTERISTICS_BT709;
|
||||||
|
+ nclx.transferCharacteristics = AVIF_NCLX_TRANSFER_CHARACTERISTICS_SRGB;
|
||||||
|
+ nclx.matrixCoefficients = AVIF_NCLX_MATRIX_COEFFICIENTS_IDENTITY; // this is key for lossless
|
||||||
|
+ nclx.range = AVIF_RANGE_FULL;
|
||||||
|
+ nclxSet = AVIF_TRUE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Set range and nclx in advance so any upcoming RGB -> YUV use the proper coefficients
|
||||||
|
if (requestedRangeSet) {
|
||||||
|
avif->yuvRange = requestedRange;
|
||||||
|
@@ -334,12 +369,6 @@ int main(int argc, char * argv[])
|
||||||
|
avifImageSetProfileNCLX(avif, &nclx);
|
||||||
|
}
|
||||||
|
|
||||||
|
- avifAppFileFormat inputFormat = avifGuessFileFormat(inputFilename);
|
||||||
|
- if (inputFormat == AVIF_APP_FILE_FORMAT_UNKNOWN) {
|
||||||
|
- fprintf(stderr, "Cannot determine input file extension: %s\n", inputFilename);
|
||||||
|
- returnCode = 1;
|
||||||
|
- goto cleanup;
|
||||||
|
- }
|
||||||
|
if (inputFormat == AVIF_APP_FILE_FORMAT_Y4M) {
|
||||||
|
if (requestedRangeSet) {
|
||||||
|
fprintf(stderr, "WARNING: Ignoring range (-r) value when encoding from y4m content.\n");
|
||||||
|
@@ -353,13 +382,16 @@ int main(int argc, char * argv[])
|
||||||
|
nclx.range = avif->yuvRange;
|
||||||
|
avifImageSetProfileNCLX(avif, &nclx);
|
||||||
|
}
|
||||||
|
+ sourceDepth = avif->depth;
|
||||||
|
+ sourceWasRGB = AVIF_FALSE;
|
||||||
|
} else if (inputFormat == AVIF_APP_FILE_FORMAT_JPEG) {
|
||||||
|
if (!avifJPEGRead(avif, inputFilename, requestedFormat, requestedDepth)) {
|
||||||
|
returnCode = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
+ sourceDepth = 8;
|
||||||
|
} else if (inputFormat == AVIF_APP_FILE_FORMAT_PNG) {
|
||||||
|
- if (!avifPNGRead(avif, inputFilename, requestedFormat, requestedDepth)) {
|
||||||
|
+ if (!avifPNGRead(avif, inputFilename, requestedFormat, requestedDepth, &sourceDepth)) {
|
||||||
|
returnCode = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
@@ -395,7 +427,78 @@ int main(int argc, char * argv[])
|
||||||
|
avif->imir.axis = imirAxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
- printf("AVIF to be written:\n");
|
||||||
|
+ avifBool usingAOM = AVIF_FALSE;
|
||||||
|
+ const char * codecName = avifCodecName(codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE);
|
||||||
|
+ if (codecName && !strcmp(codecName, "aom")) {
|
||||||
|
+ usingAOM = AVIF_TRUE;
|
||||||
|
+ }
|
||||||
|
+ avifBool hasAlpha = (avif->alphaPlane && avif->alphaRowBytes);
|
||||||
|
+ avifBool losslessColorQP = (minQuantizer == AVIF_QUANTIZER_LOSSLESS) && (maxQuantizer == AVIF_QUANTIZER_LOSSLESS);
|
||||||
|
+ avifBool losslessAlphaQP = (minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS) && (maxQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS);
|
||||||
|
+ avifBool depthMatches = (sourceDepth == avif->depth);
|
||||||
|
+ avifBool using444 = (avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV444);
|
||||||
|
+ avifBool usingFullRange = (avif->yuvRange == AVIF_RANGE_FULL);
|
||||||
|
+ avifBool usingIdentityMatrix = (nclxSet && (nclx.matrixCoefficients == AVIF_NCLX_MATRIX_COEFFICIENTS_IDENTITY));
|
||||||
|
+
|
||||||
|
+ // Guess if the enduser is asking for lossless and enable it so that warnings can be emitted
|
||||||
|
+ if (losslessColorQP && (!hasAlpha || losslessAlphaQP)) {
|
||||||
|
+ // The enduser is probably expecting lossless. Turn it on and emit warnings
|
||||||
|
+ printf("Min/max QPs set to %d, assuming --lossless to enable warnings on potential lossless issues.\n", AVIF_QUANTIZER_LOSSLESS);
|
||||||
|
+ lossless = AVIF_TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Check for any reasons lossless will fail, and complain loudly
|
||||||
|
+ if (lossless) {
|
||||||
|
+ if (!usingAOM) {
|
||||||
|
+ fprintf(stderr, "WARNING: [--lossless] Only aom (-c) supports lossless transforms. Output might not be lossless.\n");
|
||||||
|
+ lossless = AVIF_FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!losslessColorQP) {
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "WARNING: [--lossless] Color quantizer range (--min, --max) not set to %d. Color output might not be lossless.\n",
|
||||||
|
+ AVIF_QUANTIZER_LOSSLESS);
|
||||||
|
+ lossless = AVIF_FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (hasAlpha && !losslessAlphaQP) {
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "WARNING: [--lossless] Alpha present and alpha quantizer range (--minalpha, --maxalpha) not set to %d. Alpha output might not be lossless.\n",
|
||||||
|
+ AVIF_QUANTIZER_LOSSLESS);
|
||||||
|
+ lossless = AVIF_FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!depthMatches) {
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "WARNING: [--lossless] Input depth (%d) does not match output depth (%d). Output might not be lossless.\n",
|
||||||
|
+ sourceDepth,
|
||||||
|
+ avif->depth);
|
||||||
|
+ lossless = AVIF_FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (sourceWasRGB) {
|
||||||
|
+ if (!using444) {
|
||||||
|
+ fprintf(stderr, "WARNING: [--lossless] Input data was RGB and YUV subsampling (-y) isn't YUV444. Output might not be lossless.\n");
|
||||||
|
+ lossless = AVIF_FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!usingFullRange) {
|
||||||
|
+ fprintf(stderr, "WARNING: [--lossless] Input data was RGB and output range (-r) isn't full. Output might not be lossless.\n");
|
||||||
|
+ lossless = AVIF_FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!usingIdentityMatrix) {
|
||||||
|
+ fprintf(stderr, "WARNING: [--lossless] Input data was RGB and nclx matrixCoefficients isn't set to identity (--nclx x/x/0); Output might not be lossless.\n");
|
||||||
|
+ lossless = AVIF_FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ const char * lossyHint = " (Lossy)";
|
||||||
|
+ if (lossless) {
|
||||||
|
+ lossyHint = " (Lossless)";
|
||||||
|
+ }
|
||||||
|
+ printf("AVIF to be written:%s\n", lossyHint);
|
||||||
|
avifImageDump(avif);
|
||||||
|
|
||||||
|
printf("Encoding with AV1 codec '%s' speed [%d], color QP [%d (%s) <-> %d (%s)], alpha QP [%d (%s) <-> %d (%s)], %d worker thread(s), please wait...\n",
|
||||||
|
diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c
|
||||||
|
index dcefb41..39bd0cd 100644
|
||||||
|
--- a/apps/shared/avifjpeg.c
|
||||||
|
+++ b/apps/shared/avifjpeg.c
|
||||||
|
@@ -30,7 +30,7 @@ static void my_error_exit(j_common_ptr cinfo)
|
||||||
|
longjmp(myerr->setjmp_buffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
-avifBool avifJPEGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, int requestedDepth)
|
||||||
|
+avifBool avifJPEGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth)
|
||||||
|
{
|
||||||
|
avifBool ret = AVIF_FALSE;
|
||||||
|
FILE * f = NULL;
|
||||||
|
diff --git a/apps/shared/avifjpeg.h b/apps/shared/avifjpeg.h
|
||||||
|
index 13c54dd..3824aea 100644
|
||||||
|
--- a/apps/shared/avifjpeg.h
|
||||||
|
+++ b/apps/shared/avifjpeg.h
|
||||||
|
@@ -6,7 +6,7 @@
|
||||||
|
|
||||||
|
#include "avif/avif.h"
|
||||||
|
|
||||||
|
-avifBool avifJPEGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, int requestedDepth);
|
||||||
|
+avifBool avifJPEGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth);
|
||||||
|
avifBool avifJPEGWrite(avifImage * avif, const char * outputFilename, int jpegQuality);
|
||||||
|
|
||||||
|
#endif // ifndef LIBAVIF_APPS_SHARED_AVIFJPEG_H
|
||||||
|
diff --git a/apps/shared/avifpng.c b/apps/shared/avifpng.c
|
||||||
|
index 843d6b0..3573a46 100644
|
||||||
|
--- a/apps/shared/avifpng.c
|
||||||
|
+++ b/apps/shared/avifpng.c
|
||||||
|
@@ -14,7 +14,7 @@
|
||||||
|
#pragma GCC diagnostic ignored "-Wclobbered"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, int requestedDepth)
|
||||||
|
+avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth, uint32_t * outPNGDepth)
|
||||||
|
{
|
||||||
|
avifBool readResult = AVIF_FALSE;
|
||||||
|
png_structp png = NULL;
|
||||||
|
@@ -104,6 +104,10 @@ avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelForm
|
||||||
|
imgBitDepth = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (outPNGDepth) {
|
||||||
|
+ *outPNGDepth = imgBitDepth;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
png_read_update_info(png, info);
|
||||||
|
|
||||||
|
avif->width = rawWidth;
|
||||||
|
@@ -143,7 +147,7 @@ avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelForm
|
||||||
|
return readResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
-avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, int requestedDepth)
|
||||||
|
+avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, uint32_t requestedDepth)
|
||||||
|
{
|
||||||
|
avifBool writeResult = AVIF_FALSE;
|
||||||
|
png_structp png = NULL;
|
||||||
|
diff --git a/apps/shared/avifpng.h b/apps/shared/avifpng.h
|
||||||
|
index a10220e..12b68ad 100644
|
||||||
|
--- a/apps/shared/avifpng.h
|
||||||
|
+++ b/apps/shared/avifpng.h
|
||||||
|
@@ -7,7 +7,7 @@
|
||||||
|
#include "avif/avif.h"
|
||||||
|
|
||||||
|
// if (requestedDepth == 0), do best-fit
|
||||||
|
-avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, int requestedDepth);
|
||||||
|
-avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, int requestedDepth);
|
||||||
|
+avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth, uint32_t * outPNGDepth);
|
||||||
|
+avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, uint32_t requestedDepth);
|
||||||
|
|
||||||
|
#endif // ifndef LIBAVIF_APPS_SHARED_AVIFPNG_H
|
@ -0,0 +1,150 @@
|
|||||||
|
From ebb29b37711c749681278f8b778f0e6c031c4ca2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wan-Teh Chang <wtc@google.com>
|
||||||
|
Date: Mon, 27 Apr 2020 18:43:51 -0700
|
||||||
|
Subject: [PATCH] Do not ignore GCC's -Wclobbered warning
|
||||||
|
|
||||||
|
The C Standard requires certain local variables in the function calling
|
||||||
|
setjmp be declared as volatile. I went through the code and declare
|
||||||
|
variables as volatile according to the C Standard, except for the 'rgb'
|
||||||
|
struct variable. Document my rationale.
|
||||||
|
---
|
||||||
|
apps/shared/avifjpeg.c | 44 ++++++++++++++++++++++++++----------------
|
||||||
|
apps/shared/avifpng.c | 25 ++++++++++++++++--------
|
||||||
|
2 files changed, 44 insertions(+), 25 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c
|
||||||
|
index 39bd0cd..5e68211 100644
|
||||||
|
--- a/apps/shared/avifjpeg.c
|
||||||
|
+++ b/apps/shared/avifjpeg.c
|
||||||
|
@@ -12,11 +12,6 @@
|
||||||
|
|
||||||
|
#include "iccjpeg.h"
|
||||||
|
|
||||||
|
-// This warning triggers false postives way too often in here.
|
||||||
|
-#if defined(__GNUC__) && !defined(__clang__)
|
||||||
|
-#pragma GCC diagnostic ignored "-Wclobbered"
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
struct my_error_mgr
|
||||||
|
{
|
||||||
|
struct jpeg_error_mgr pub;
|
||||||
|
@@ -30,31 +25,44 @@ static void my_error_exit(j_common_ptr cinfo)
|
||||||
|
longjmp(myerr->setjmp_buffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Note on setjmp() and volatile variables:
|
||||||
|
+//
|
||||||
|
+// K & R, The C Programming Language 2nd Ed, p. 254 says:
|
||||||
|
+// ... Accessible objects have the values they had when longjmp was called,
|
||||||
|
+// except that non-volatile automatic variables in the function calling setjmp
|
||||||
|
+// become undefined if they were changed after the setjmp call.
|
||||||
|
+//
|
||||||
|
+// Therefore, 'iccData' is declared as volatile. 'rgb' should be declared as
|
||||||
|
+// volatile, but doing so would be inconvenient (try it) and since it is a
|
||||||
|
+// struct, the compiler is unlikely to put it in a register. 'ret' does not need
|
||||||
|
+// to be declared as volatile because it is not modified between setjmp and
|
||||||
|
+// longjmp. But GCC's -Wclobbered warning may have trouble figuring that out, so
|
||||||
|
+// we preemptively declare it as volatile.
|
||||||
|
+
|
||||||
|
avifBool avifJPEGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth)
|
||||||
|
{
|
||||||
|
- avifBool ret = AVIF_FALSE;
|
||||||
|
- FILE * f = NULL;
|
||||||
|
- uint8_t * iccData = NULL;
|
||||||
|
+ volatile avifBool ret = AVIF_FALSE;
|
||||||
|
+ uint8_t * volatile iccData = NULL;
|
||||||
|
|
||||||
|
avifRGBImage rgb;
|
||||||
|
memset(&rgb, 0, sizeof(avifRGBImage));
|
||||||
|
|
||||||
|
+ FILE * f = fopen(inputFilename, "rb");
|
||||||
|
+ if (!f) {
|
||||||
|
+ fprintf(stderr, "Can't open JPEG file for read: %s\n", inputFilename);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
struct my_error_mgr jerr;
|
||||||
|
struct jpeg_decompress_struct cinfo;
|
||||||
|
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||||
|
jerr.pub.error_exit = my_error_exit;
|
||||||
|
if (setjmp(jerr.setjmp_buffer)) {
|
||||||
|
- return AVIF_FALSE;
|
||||||
|
+ goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
|
||||||
|
- f = fopen(inputFilename, "rb");
|
||||||
|
- if (!f) {
|
||||||
|
- fprintf(stderr, "Can't open JPEG file for read: %s\n", inputFilename);
|
||||||
|
- goto cleanup;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
setup_read_icc_profile(&cinfo);
|
||||||
|
jpeg_stdio_src(&cinfo, f);
|
||||||
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
@@ -63,10 +71,12 @@ avifBool avifJPEGRead(avifImage * avif, const char * inputFilename, avifPixelFor
|
||||||
|
int row_stride = cinfo.output_width * cinfo.output_components;
|
||||||
|
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
|
||||||
|
|
||||||
|
+ uint8_t * iccDataTmp;
|
||||||
|
unsigned int iccDataLen;
|
||||||
|
- if (read_icc_profile(&cinfo, &iccData, &iccDataLen)) {
|
||||||
|
+ if (read_icc_profile(&cinfo, &iccDataTmp, &iccDataLen)) {
|
||||||
|
+ iccData = iccDataTmp;
|
||||||
|
if (avif->profileFormat == AVIF_PROFILE_FORMAT_NONE) {
|
||||||
|
- avifImageSetProfileICC(avif, iccData, (size_t)iccDataLen);
|
||||||
|
+ avifImageSetProfileICC(avif, iccDataTmp, (size_t)iccDataLen);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "WARNING: JPEG contains ICC profile which is being overridden with --nclx\n");
|
||||||
|
}
|
||||||
|
diff --git a/apps/shared/avifpng.c b/apps/shared/avifpng.c
|
||||||
|
index 3573a46..934b5aa 100644
|
||||||
|
--- a/apps/shared/avifpng.c
|
||||||
|
+++ b/apps/shared/avifpng.c
|
||||||
|
@@ -9,17 +9,26 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
-// This warning triggers false postives way too often in here.
|
||||||
|
-#if defined(__GNUC__) && !defined(__clang__)
|
||||||
|
-#pragma GCC diagnostic ignored "-Wclobbered"
|
||||||
|
-#endif
|
||||||
|
+// Note on setjmp() and volatile variables:
|
||||||
|
+//
|
||||||
|
+// K & R, The C Programming Language 2nd Ed, p. 254 says:
|
||||||
|
+// ... Accessible objects have the values they had when longjmp was called,
|
||||||
|
+// except that non-volatile automatic variables in the function calling setjmp
|
||||||
|
+// become undefined if they were changed after the setjmp call.
|
||||||
|
+//
|
||||||
|
+// Therefore, 'rowPointers' is declared as volatile. 'rgb' should be declared as
|
||||||
|
+// volatile, but doing so would be inconvenient (try it) and since it is a
|
||||||
|
+// struct, the compiler is unlikely to put it in a register. 'readResult' and
|
||||||
|
+// 'writeResult' do not need to be declared as volatile because they are not
|
||||||
|
+// modified between setjmp and longjmp. But GCC's -Wclobbered warning may have
|
||||||
|
+// trouble figuring that out, so we preemptively declare them as volatile.
|
||||||
|
|
||||||
|
avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth, uint32_t * outPNGDepth)
|
||||||
|
{
|
||||||
|
- avifBool readResult = AVIF_FALSE;
|
||||||
|
+ volatile avifBool readResult = AVIF_FALSE;
|
||||||
|
png_structp png = NULL;
|
||||||
|
png_infop info = NULL;
|
||||||
|
- png_bytep * rowPointers = NULL;
|
||||||
|
+ png_bytep * volatile rowPointers = NULL;
|
||||||
|
|
||||||
|
avifRGBImage rgb;
|
||||||
|
memset(&rgb, 0, sizeof(avifRGBImage));
|
||||||
|
@@ -149,10 +158,10 @@ avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelForm
|
||||||
|
|
||||||
|
avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, uint32_t requestedDepth)
|
||||||
|
{
|
||||||
|
- avifBool writeResult = AVIF_FALSE;
|
||||||
|
+ volatile avifBool writeResult = AVIF_FALSE;
|
||||||
|
png_structp png = NULL;
|
||||||
|
png_infop info = NULL;
|
||||||
|
- png_bytep * rowPointers = NULL;
|
||||||
|
+ png_bytep * volatile rowPointers = NULL;
|
||||||
|
|
||||||
|
avifRGBImage rgb;
|
||||||
|
memset(&rgb, 0, sizeof(avifRGBImage));
|
@ -1 +1 @@
|
|||||||
SHA512 (libavif-0.7.1.tar.gz) = d6b2850797d37de3986bd1c1a366c8b35d1b1565db07ad7034cf4de88f17d2798d042b6fa61596b068161a645a9209070ac454dd5d9928cb6c08e5a58fe585ac
|
SHA512 (libavif-0.7.2.tar.gz) = 543aae3dde2ed19a8d2d22425260d09f577fbddbd5bc293cc9ec97e427f3854e7a957b4975130b1129a0c73847398ce88ab22de48bec500b83bc56fde671e6b7
|
||||||
|
Loading…
Reference in new issue