From 1b5a58c4dcaba392bf39431807da467cf323dd13 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Sat, 22 Jul 2023 23:06:00 +0800 Subject: [PATCH 1/4] Quick hack to support 10 bit HDR AVIF using PQ transfer function... https://en.wikipedia.org/wiki/Perceptual_quantizer --- SDWebImageAVIFCoder/Classes/ColorSpace.m | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/SDWebImageAVIFCoder/Classes/ColorSpace.m b/SDWebImageAVIFCoder/Classes/ColorSpace.m index fb3ead8..fb0873b 100644 --- a/SDWebImageAVIFCoder/Classes/ColorSpace.m +++ b/SDWebImageAVIFCoder/Classes/ColorSpace.m @@ -395,6 +395,29 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul *shouldRelease = FALSE; return; } + if(colorPrimaries == AVIF_COLOR_PRIMARIES_BT2020 && + transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_SMPTE2084) { + static CGColorSpaceRef bt2020pq = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + CFStringRef colorSpaceName = NULL; + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)) { + colorSpaceName = kCGColorSpaceITUR_2100_PQ; + } else if (@available(macOS 10.15.4, iOS 13.4, tvOS 13.4, watchOS 6.2, *)) { + colorSpaceName = kCGColorSpaceITUR_2020_PQ; + } else if (@available(macOS 10.14.6, iOS 12.6, tvOS 12.0, watchOS 5.0, *)) { + colorSpaceName = kCGColorSpaceITUR_2020_PQ_EOTF; + } + if (colorSpaceName) { + bt2020pq = CGColorSpaceCreateWithName(colorSpaceName); + } else { + bt2020pq = defaultColorSpace; + } + }); + *ref = bt2020pq; + *shouldRelease = FALSE; + return; + } if(colorPrimaries == AVIF_COLOR_PRIMARIES_BT2020 && transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_LINEAR) { static CGColorSpaceRef bt2020linear = NULL; From acf892335e0cbdf109c4e0cd139e4b329fd0b447 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Sat, 22 Jul 2023 23:25:15 +0800 Subject: [PATCH 2/4] Hack the bt2020 hlg and p3 pq as well --- SDWebImageAVIFCoder/Classes/ColorSpace.m | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/SDWebImageAVIFCoder/Classes/ColorSpace.m b/SDWebImageAVIFCoder/Classes/ColorSpace.m index fb0873b..103938b 100644 --- a/SDWebImageAVIFCoder/Classes/ColorSpace.m +++ b/SDWebImageAVIFCoder/Classes/ColorSpace.m @@ -418,6 +418,28 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul *shouldRelease = FALSE; return; } + if(colorPrimaries == AVIF_COLOR_PRIMARIES_BT2020 && + transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_HLG) { + static CGColorSpaceRef bt2020hlg = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + CFStringRef colorSpaceName = NULL; + if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)) { + colorSpaceName = kCGColorSpaceITUR_2100_HLG; + } else if (@available(macOS 10.15.6, iOS 12.6, tvOS 12.0, watchOS 5.0, *)) { + colorSpaceName = kCGColorSpaceITUR_2020_HLG; + } + if (colorSpaceName) { + bt2020hlg = CGColorSpaceCreateWithName(colorSpaceName); + } else { + bt2020hlg = defaultColorSpace; + } + }); + + *ref = bt2020hlg; + *shouldRelease = FALSE; + return; + } if(colorPrimaries == AVIF_COLOR_PRIMARIES_BT2020 && transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_LINEAR) { static CGColorSpaceRef bt2020linear = NULL; @@ -448,6 +470,27 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul *shouldRelease = FALSE; return; } + if(colorPrimaries == AVIF_COLOR_PRIMARIES_SMPTE432 /* Display P3 */ && + transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_SMPTE2084) { + static CGColorSpaceRef p3pq = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + CFStringRef colorSpaceName = NULL; + if (@available(macOS 10.15.4, iOS 13.4, tvOS 13.4, watchOS 6.2, *)) { + colorSpaceName = kCGColorSpaceDisplayP3_PQ; + } else if (@available(macOS 10.14.6, iOS 12.6, tvOS 12.0, watchOS 5.0, *)) { + colorSpaceName = kCGColorSpaceDisplayP3_PQ_EOTF; + } + if (colorSpaceName) { + p3pq = CGColorSpaceCreateWithName(colorSpaceName); + } else { + p3pq = defaultColorSpace; + } + }); + *ref = p3pq; + *shouldRelease = FALSE; + return; + } if(colorPrimaries == AVIF_COLOR_PRIMARIES_SMPTE432 /* Display P3 */ && transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_HLG) { static CGColorSpaceRef p3hlg = NULL; From 30135e8f4ff4a50482a0c5c0f3590252457f3a57 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Sun, 23 Jul 2023 00:21:30 +0800 Subject: [PATCH 3/4] Update the watchOS available support --- Cartfile | 2 +- Cartfile.resolved | 7 ++- SDWebImageAVIFCoder/Classes/ColorSpace.m | 72 +++++++++++------------- 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/Cartfile b/Cartfile index 11c87eb..bd1a409 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ github "SDWebImage/SDWebImage" ~> 5.10 -github "SDWebImage/libavif-Xcode" >= 0.11.0 \ No newline at end of file +github "SDWebImage/libavif-Xcode" >= 0.11.2-rc1 \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index 174319a..ca7e367 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,3 +1,4 @@ -github "SDWebImage/SDWebImage" "5.10.2" -github "SDWebImage/libaom-Xcode" "1.0.2" -github "SDWebImage/libavif-Xcode" "0.8.1" +github "SDWebImage/SDWebImage" "5.17.0" +github "SDWebImage/libaom-Xcode" "3.0.0" +github "SDWebImage/libavif-Xcode" "0.11.2-rc1" +github "SDWebImage/libvmaf-Xcode" "2.3.1" diff --git a/SDWebImageAVIFCoder/Classes/ColorSpace.m b/SDWebImageAVIFCoder/Classes/ColorSpace.m index 103938b..e90f0f2 100644 --- a/SDWebImageAVIFCoder/Classes/ColorSpace.m +++ b/SDWebImageAVIFCoder/Classes/ColorSpace.m @@ -164,45 +164,37 @@ static void CalcTransferFunction(uint16_t const transferCharacteristics, vImageT } } CGColorSpaceRef SDAVIFCreateColorSpaceMono(avifColorPrimaries const colorPrimaries, avifTransferCharacteristics const transferCharacteristics) { - if (@available(macOS 10.10, iOS 8.0, tvOS 8.0, *)) { - vImage_Error err; - vImageWhitePoint white; - vImageTransferFunction transfer; - CalcWhitePoint(colorPrimaries, &white); - CalcTransferFunction(transferCharacteristics, &transfer); - CGColorSpaceRef colorSpace = vImageCreateMonochromeColorSpaceWithWhitePointAndTransferFunction(&white, &transfer, kCGRenderingIntentDefault, kvImagePrintDiagnosticsToConsole, &err); - if(err != kvImageNoError) { - NSLog(@"[BUG] Failed to create monochrome color space: %ld", err); - if(colorSpace != NULL) { - CGColorSpaceRelease(colorSpace); - } - return NULL; + vImage_Error err; + vImageWhitePoint white; + vImageTransferFunction transfer; + CalcWhitePoint(colorPrimaries, &white); + CalcTransferFunction(transferCharacteristics, &transfer); + CGColorSpaceRef colorSpace = vImageCreateMonochromeColorSpaceWithWhitePointAndTransferFunction(&white, &transfer, kCGRenderingIntentDefault, kvImagePrintDiagnosticsToConsole, &err); + if(err != kvImageNoError) { + NSLog(@"[BUG] Failed to create monochrome color space: %ld", err); + if(colorSpace != NULL) { + CGColorSpaceRelease(colorSpace); } - return colorSpace; - }else{ return NULL; } + return colorSpace; } CGColorSpaceRef SDAVIFCreateColorSpaceRGB(avifColorPrimaries const colorPrimaries, avifTransferCharacteristics const transferCharacteristics) { - if (@available(macOS 10.10, iOS 8.0, tvOS 8.0, *)) { - vImage_Error err; - vImageRGBPrimaries primaries; - vImageTransferFunction transfer; - CalcRGBPrimaries(colorPrimaries, &primaries); - CalcTransferFunction(transferCharacteristics, &transfer); - CGColorSpaceRef colorSpace = vImageCreateRGBColorSpaceWithPrimariesAndTransferFunction(&primaries, &transfer, kCGRenderingIntentDefault, kvImagePrintDiagnosticsToConsole, &err); - if(err != kvImageNoError) { - NSLog(@"[BUG] Failed to create monochrome color space: %ld", err); - if(colorSpace != NULL) { - CGColorSpaceRelease(colorSpace); - } - return NULL; + vImage_Error err; + vImageRGBPrimaries primaries; + vImageTransferFunction transfer; + CalcRGBPrimaries(colorPrimaries, &primaries); + CalcTransferFunction(transferCharacteristics, &transfer); + CGColorSpaceRef colorSpace = vImageCreateRGBColorSpaceWithPrimariesAndTransferFunction(&primaries, &transfer, kCGRenderingIntentDefault, kvImagePrintDiagnosticsToConsole, &err); + if(err != kvImageNoError) { + NSLog(@"[BUG] Failed to create monochrome color space: %ld", err); + if(colorSpace != NULL) { + CGColorSpaceRelease(colorSpace); } - return colorSpace; - }else{ return NULL; } + return colorSpace; } void SDAVIFCalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* shouldRelease) { @@ -214,7 +206,7 @@ void SDAVIFCalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* shou }); } if(avif->icc.data && avif->icc.size) { - if(@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) { + if(@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { CFDataRef iccData = CFDataCreate(kCFAllocatorDefault, avif->icc.data, avif->icc.size); *ref = CGColorSpaceCreateWithICCData(iccData); CFRelease(iccData); @@ -312,7 +304,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul }); } if(avif->icc.data && avif->icc.size) { - if(@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) { + if(@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { CFDataRef iccData = CFDataCreate(kCFAllocatorDefault, avif->icc.data, avif->icc.size); *ref = CGColorSpaceCreateWithICCData(iccData); CFRelease(iccData); @@ -339,7 +331,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef bt709 = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { + if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) { bt709 = CGColorSpaceCreateWithName(kCGColorSpaceITUR_709); } else { bt709 = defaultColorSpace; @@ -354,7 +346,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef sRGB = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.5, iOS 9.0, tvOS 9.0, *)) { + if (@available(macOS 10.5, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) { sRGB = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); } else { sRGB = defaultColorSpace; @@ -369,7 +361,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef sRGBlinear = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) { + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { sRGBlinear = CGColorSpaceCreateWithName(kCGColorSpaceLinearSRGB); } else { sRGBlinear = defaultColorSpace; @@ -385,7 +377,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef bt2020 = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { + if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) { bt2020 = CGColorSpaceCreateWithName(kCGColorSpaceITUR_2020); } else { bt2020 = defaultColorSpace; @@ -445,7 +437,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef bt2020linear = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.14.3, iOS 12.3, tvOS 12.3, *)) { + if (@available(macOS 10.14.3, iOS 12.3, tvOS 12.3, watchOS 5.0, *)) { bt2020linear = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearITUR_2020); } else { bt2020linear = defaultColorSpace; @@ -460,7 +452,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef p3 = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.11.2, iOS 9.3, tvOS 9.3, *)) { + if (@available(macOS 10.11.2, iOS 9.3, tvOS 9.3, watchOS 2.2, *)) { p3 = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3); } else { p3 = defaultColorSpace; @@ -496,7 +488,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef p3hlg = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.14.6, iOS 13.0, tvOS 13.0, *)) { + if (@available(macOS 10.14.6, iOS 13.0, tvOS 13.0, watchOS 5.0, *)) { p3hlg = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3_HLG); } else { p3hlg = defaultColorSpace; @@ -512,7 +504,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul static CGColorSpaceRef p3linear = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (@available(macOS 10.14.3, iOS 12.3, tvOS 12.3, *)) { + if (@available(macOS 10.14.3, iOS 12.3, tvOS 12.3, watchOS 5.0, *)) { p3linear = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearDisplayP3); } else { p3linear = defaultColorSpace; From e7033342bfc26991affeaa299b83a2b2e579cc6d Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Sun, 23 Jul 2023 00:30:21 +0800 Subject: [PATCH 4/4] Remove the unused code to setup matrix --- SDWebImageAVIFCoder/Classes/Conversion.m | 135 +---------------------- 1 file changed, 3 insertions(+), 132 deletions(-) diff --git a/SDWebImageAVIFCoder/Classes/Conversion.m b/SDWebImageAVIFCoder/Classes/Conversion.m index b15e33a..7b470c3 100644 --- a/SDWebImageAVIFCoder/Classes/Conversion.m +++ b/SDWebImageAVIFCoder/Classes/Conversion.m @@ -55,36 +55,7 @@ static CGImageRef CreateImageFromBuffer(avifImage * avif, vImage_Buffer* result) return imageRef; } -static avifBool avifPrepareReformatState(const avifImage * image, const avifRGBImage * rgb, avifReformatState * state) -{ - if ((image->depth != 8) && (image->depth != 10) && (image->depth != 12)) { - return AVIF_FALSE; - } - if ((rgb->depth != 8) && (rgb->depth != 10) && (rgb->depth != 12) && (rgb->depth != 16)) { - return AVIF_FALSE; - } - - // These matrix coefficients values are currently unsupported. Revise this list as more support is added. - // - // YCgCo performs limited-full range adjustment on R,G,B but the current implementation performs range adjustment - // on Y,U,V. So YCgCo with limited range is unsupported. - if ((image->matrixCoefficients == 3 /* CICP reserved */) || - ((image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO) && (image->yuvRange == AVIF_RANGE_LIMITED)) || - (image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_BT2020_CL) || - (image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_SMPTE2085) || - (image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL) || - (image->matrixCoefficients >= AVIF_MATRIX_COEFFICIENTS_ICTCP)) { // Note the >= catching "future" CICP values here too - return AVIF_FALSE; - } - - if ((image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) && (image->yuvFormat != AVIF_PIXEL_FORMAT_YUV444)) { - return AVIF_FALSE; - } - - if (image->yuvFormat == AVIF_PIXEL_FORMAT_NONE) { - return AVIF_FALSE; - } - +static void PrepareReformatState(const avifImage * image, avifReformatState * state) { avifGetPixelFormatInfo(image->yuvFormat, &state->formatInfo); avifCalcYUVCoefficients(image, &state->kr, &state->kg, &state->kb); state->mode = AVIF_REFORMAT_MODE_YUV_COEFFICIENTS; @@ -100,113 +71,13 @@ static avifBool avifPrepareReformatState(const avifImage * image, const avifRGBI state->kg = 0.0f; state->kb = 0.0f; } - - state->yuvChannelBytes = (image->depth > 8) ? 2 : 1; - state->rgbChannelBytes = (rgb->depth > 8) ? 2 : 1; - state->rgbChannelCount = avifRGBFormatChannelCount(rgb->format); - state->rgbPixelBytes = state->rgbChannelBytes * state->rgbChannelCount; - - switch (rgb->format) { - case AVIF_RGB_FORMAT_RGB: - state->rgbOffsetBytesR = state->rgbChannelBytes * 0; - state->rgbOffsetBytesG = state->rgbChannelBytes * 1; - state->rgbOffsetBytesB = state->rgbChannelBytes * 2; - state->rgbOffsetBytesA = 0; - break; - case AVIF_RGB_FORMAT_RGBA: - state->rgbOffsetBytesR = state->rgbChannelBytes * 0; - state->rgbOffsetBytesG = state->rgbChannelBytes * 1; - state->rgbOffsetBytesB = state->rgbChannelBytes * 2; - state->rgbOffsetBytesA = state->rgbChannelBytes * 3; - break; - case AVIF_RGB_FORMAT_ARGB: - state->rgbOffsetBytesA = state->rgbChannelBytes * 0; - state->rgbOffsetBytesR = state->rgbChannelBytes * 1; - state->rgbOffsetBytesG = state->rgbChannelBytes * 2; - state->rgbOffsetBytesB = state->rgbChannelBytes * 3; - break; - case AVIF_RGB_FORMAT_BGR: - state->rgbOffsetBytesB = state->rgbChannelBytes * 0; - state->rgbOffsetBytesG = state->rgbChannelBytes * 1; - state->rgbOffsetBytesR = state->rgbChannelBytes * 2; - state->rgbOffsetBytesA = 0; - break; - case AVIF_RGB_FORMAT_BGRA: - state->rgbOffsetBytesB = state->rgbChannelBytes * 0; - state->rgbOffsetBytesG = state->rgbChannelBytes * 1; - state->rgbOffsetBytesR = state->rgbChannelBytes * 2; - state->rgbOffsetBytesA = state->rgbChannelBytes * 3; - break; - case AVIF_RGB_FORMAT_ABGR: - state->rgbOffsetBytesA = state->rgbChannelBytes * 0; - state->rgbOffsetBytesB = state->rgbChannelBytes * 1; - state->rgbOffsetBytesG = state->rgbChannelBytes * 2; - state->rgbOffsetBytesR = state->rgbChannelBytes * 3; - break; - - default: - return AVIF_FALSE; - } - - state->yuvDepth = image->depth; - state->yuvRange = image->yuvRange; - state->yuvMaxChannel = (1 << image->depth) - 1; - state->rgbMaxChannel = (1 << rgb->depth) - 1; - state->rgbMaxChannelF = (float)state->rgbMaxChannel; - state->biasY = (state->yuvRange == AVIF_RANGE_LIMITED) ? (float)(16 << (state->yuvDepth - 8)) : 0.0f; - state->biasUV = (float)(1 << (state->yuvDepth - 1)); - state->rangeY = (float)((state->yuvRange == AVIF_RANGE_LIMITED) ? (219 << (state->yuvDepth - 8)) : state->yuvMaxChannel); - state->rangeUV = (float)((state->yuvRange == AVIF_RANGE_LIMITED) ? (224 << (state->yuvDepth - 8)) : state->yuvMaxChannel); - - uint32_t cpCount = 1 << image->depth; - if (state->mode == AVIF_REFORMAT_MODE_IDENTITY) { - for (uint32_t cp = 0; cp < cpCount; ++cp) { - state->unormFloatTableY[cp] = ((float)cp - state->biasY) / state->rangeY; - state->unormFloatTableUV[cp] = ((float)cp - state->biasY) / state->rangeY; - } - } else { - for (uint32_t cp = 0; cp < cpCount; ++cp) { - // Review this when implementing YCgCo limited range support. - state->unormFloatTableY[cp] = ((float)cp - state->biasY) / state->rangeY; - state->unormFloatTableUV[cp] = ((float)cp - state->biasUV) / state->rangeUV; - } - } - - state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_NO_OP; - if (image->alphaPlane) { - if (!avifRGBFormatHasAlpha(rgb->format) || rgb->ignoreAlpha) { - // if we are converting some image with alpha into a format without alpha, we should do 'premultiply alpha' before - // discarding alpha plane. This has the same effect of rendering this image on a black background, which makes sense. - if (!image->alphaPremultiplied) { - state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY; - } - } else { - if (!image->alphaPremultiplied && rgb->alphaPremultiplied) { - state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY; - } else if (image->alphaPremultiplied && !rgb->alphaPremultiplied) { - state->toRGBAlphaMode = AVIF_ALPHA_MULTIPLY_MODE_UNMULTIPLY; - } - } - } - - return AVIF_TRUE; } - -static void SetupConversionInfo(avifImage * avif, +static void SetupConversionInfo(const avifImage * avif, avifReformatState* state, vImage_YpCbCrToARGBMatrix* matrix, vImage_YpCbCrPixelRange* pixelRange) { - avifRGBImage emptyRGBImage = { - .width = avif->width, - .height = avif->height, - .depth = avif->depth, - .format = AVIF_RGB_FORMAT_ARGB, - - .pixels = NULL, - .rowBytes = 0, - }; - avifPrepareReformatState(avif, &emptyRGBImage, state); + PrepareReformatState(avif, state); // Setup Matrix matrix->Yp = 1.0f;