Skip to content

Commit 38600bf

Browse files
committed
Support libavif v0.6.0(decoder)
1 parent ab2fde9 commit 38600bf

4 files changed

Lines changed: 82 additions & 17 deletions

File tree

Cartfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
github "SDWebImage/SDWebImage" ~> 5.0
2-
github "SDWebImage/libavif-Xcode" ~> 0.5
2+
github "SDWebImage/libavif-Xcode" ~> 0.6

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ let package = Package(
1818
// Dependencies declare other packages that this package depends on.
1919
// .package(url: /* package url */, from: "1.0.0"),
2020
.package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.1.0"),
21-
.package(url: "https://github.com/SDWebImage/libavif-Xcode.git", from: "0.5.0")
21+
.package(url: "https://github.com/SDWebImage/libavif-Xcode.git", from: "0.6.0")
2222
],
2323
targets: [
2424
// Targets are the basic building blocks of a package. A target can define a module or a test suite.

SDWebImageAVIFCoder.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ Which is built based on the open-sourced libavif codec.
3636
s.source_files = 'SDWebImageAVIFCoder/Classes/**/*', 'SDWebImageAVIFCoder/Module/SDWebImageAVIFCoder.h'
3737

3838
s.dependency 'SDWebImage', '~> 5.0'
39-
s.dependency 'libavif', '~> 0.5'
39+
s.dependency 'libavif', '~> 0.6'
4040
end

SDWebImageAVIFCoder/Classes/SDImageAVIFCoder.m

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)