@@ -53,7 +53,16 @@ static void SetupConversionInfo(avifImage * avif,
5353 avifReformatState* state,
5454 vImage_YpCbCrToARGBMatrix* matrix,
5555 vImage_YpCbCrPixelRange* pixelRange) {
56- avifPrepareReformatState (avif, state);
56+ avifRGBImage emptyRGBImage = {
57+ .width = avif->width ,
58+ .height = avif->height ,
59+ .depth = avif->depth ,
60+ .format = AVIF_RGB_FORMAT_ARGB,
61+
62+ .pixels = NULL ,
63+ .rowBytes = 0 ,
64+ };
65+ avifPrepareReformatState (avif, &emptyRGBImage, state);
5766
5867 // Setup Matrix
5968 matrix->Yp = 1 .0f ;
@@ -144,6 +153,7 @@ static CGImageRef CreateImage8(avifImage * avif) {
144153 uint8_t * argbBufferData = NULL ;
145154 uint8_t * dummyCbData = NULL ;
146155 uint8_t * dummyCrData = NULL ;
156+ uint8_t * scaledAlphaBufferData = NULL ;
147157
148158 vImage_Error err = kvImageNoError;
149159
@@ -413,12 +423,52 @@ static CGImageRef CreateImage8(avifImage * avif) {
413423 }
414424
415425 if (hasAlpha) { // alpha
416- vImage_Buffer alphaBuffer = {
417- .data = avif->alphaPlane ,
418- .width = avif->width ,
419- .height = avif->height ,
420- .rowBytes = avif->alphaRowBytes ,
421- };
426+ vImage_Buffer alphaBuffer = {0 };
427+ if (avif->alphaRange == AVIF_RANGE_LIMITED) {
428+ float * floatAlphaBufferData = NULL ;
429+ floatAlphaBufferData = calloc (avif->width * avif->height , sizeof (float ));
430+ scaledAlphaBufferData = calloc (avif->width * avif->height , sizeof (uint8_t ));
431+ if (floatAlphaBufferData == NULL || scaledAlphaBufferData == NULL ) {
432+ err = kvImageMemoryAllocationError;
433+ goto end_prepare_alpha;
434+ }
435+ vImage_Buffer origAlphaBuffer = {
436+ .data = avif->alphaPlane ,
437+ .width = avif->width ,
438+ .height = avif->height ,
439+ .rowBytes = avif->alphaRowBytes ,
440+ };
441+ vImage_Buffer floatAlphaBuffer = {
442+ .data = floatAlphaBufferData,
443+ .width = avif->width ,
444+ .height = avif->height ,
445+ .rowBytes = avif->width * sizeof (float ),
446+ };
447+ alphaBuffer.width = avif->width ;
448+ alphaBuffer.height = avif->height ;
449+ alphaBuffer.data = scaledAlphaBufferData;
450+ alphaBuffer.rowBytes = avif->width * sizeof (uint8_t );
451+ err = vImageConvert_Planar8toPlanarF (&origAlphaBuffer, &floatAlphaBuffer, 255 .0f , 0 .0f , kvImageNoFlags);
452+ if (err != kvImageNoError) {
453+ NSLog (@" Failed to convert alpha planes from uint8 to float: %ld " , err);
454+ goto end_prepare_alpha;
455+ }
456+ err = vImageConvert_PlanarFtoPlanar8 (&floatAlphaBuffer, &alphaBuffer, 235 .0f , 16 .0f , kvImageNoFlags);
457+ if (err != kvImageNoError) {
458+ NSLog (@" Failed to convert alpha planes from float to uint8: %ld " , err);
459+ goto end_prepare_alpha;
460+ }
461+ end_prepare_alpha:
462+ free (floatAlphaBufferData);
463+ if (err != kvImageNoError) {
464+ goto end_alpha;
465+ }
466+ } else {
467+ alphaBuffer.width = avif->width ;
468+ alphaBuffer.height = avif->height ;
469+ alphaBuffer.data = avif->alphaPlane ;
470+ alphaBuffer.rowBytes = avif->alphaRowBytes ;
471+ }
422472 if (monochrome) { // alpha_mono
423473 uint8_t * tmpBufferData = NULL ;
424474 uint8_t * monoBufferData = NULL ;
@@ -515,6 +565,7 @@ static CGImageRef CreateImage8(avifImage * avif) {
515565 free (argbBufferData);
516566 free (dummyCbData);
517567 free (dummyCrData);
568+ free (scaledAlphaBufferData);
518569 return result;
519570}
520571
@@ -665,18 +716,32 @@ static CGImageRef CreateImage16U(avifImage * avif) {
665716 .height = avif->height ,
666717 .rowBytes = avif->width * sizeof (uint16_t ),
667718 };
719+ float offset = 0 .0f ;
720+ float rangeMax = 0 .0f ;
721+ if (avif->depth == 10 ) {
722+ if (avif->alphaRange == AVIF_RANGE_LIMITED) {
723+ offset = 64 .0f ;
724+ rangeMax = 940 .0f ;
725+ } else {
726+ offset = 0 .0f ;
727+ rangeMax = 1023 .0f ;
728+ }
729+ } else if (avif->depth == 12 ) {
730+ if (avif->alphaRange == AVIF_RANGE_LIMITED) {
731+ offset = 256 .0f ;
732+ rangeMax = 3760 .0f ;
733+ } else {
734+ offset = 0 .0f ;
735+ rangeMax = 4095 .0f ;
736+ }
737+ }
738+ float const scale = (float )(rangeMax - offset) / 65535 .0f ;
668739 err = vImageConvert_16UToF (&origAlpha, &floatAlphaBuffer, 0 .0f , 1 .0f , kvImageNoFlags);
669740 if (err != kvImageNoError) {
670741 NSLog (@" Failed to convert alpha planes from uint16 to float: %ld " , err);
671742 goto end_prepare_alpha;
672743 }
673- float scale = 1 .0f ;
674- if (avif->depth == 10 ) {
675- scale = (float )((1 << 10 ) - 1 ) / 65535 .0f ;
676- } else if (avif->depth == 12 ) {
677- scale = (float )((1 << 12 ) - 1 ) / 65535 .0f ;
678- }
679- err = vImageConvert_FTo16U (&floatAlphaBuffer, &scaledAlphaBuffer, 0 .0f , scale, kvImageNoFlags);
744+ err = vImageConvert_FTo16U (&floatAlphaBuffer, &scaledAlphaBuffer, offset, scale, kvImageNoFlags);
680745 if (err != kvImageNoError) {
681746 NSLog (@" Failed to convert alpha planes from uint16 to float: %ld " , err);
682747 goto end_prepare_alpha;
0 commit comments