Skip to content

Commit

Permalink
fix provider releasing
Browse files Browse the repository at this point in the history
  • Loading branch information
awxkee committed Jan 5, 2023
1 parent 1fa7de6 commit 40c2ce1
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 57 deletions.
12 changes: 0 additions & 12 deletions Sources/avif/AVIFDepth.swift

This file was deleted.

5 changes: 2 additions & 3 deletions Sources/avif/AVIFEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@ import AppKit
#endif

public class AVIFEncoder {
public static func encode(image: PlatformImage, quality: Double = 1.0, speed: Int = -1,
depth: AVIFDepth = AVIFDepth.eightBits) throws -> Data {
public static func encode(image: PlatformImage, quality: Double = 1.0, speed: Int = -1) throws -> Data {
var newImage = image
if newImage.size.width.truncatingRemainder(dividingBy: 2) != 0
|| newImage.size.height.truncatingRemainder(dividingBy: 2) != 0 {
let newSize = CGSize(width: CGFloat((Int(newImage.size.width) / 2) * 2),
height: CGFloat((Int(newImage.size.height) / 2) * 2))
newImage = imageScaled(toScale: image, to: newSize)
}
return try AVIFEncoding().encode(newImage, speed: speed, depth: depth.rawValue, quality: quality)
return try AVIFEncoding().encode(newImage, speed: speed, quality: quality)
}

private static func imageScaled(toScale image: PlatformImage, to size: CGSize, scale: CGFloat? = nil) -> PlatformImage {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ - (void* _Nullable)addImage:(Image * _Nonnull)platformImage duration:(NSUInteger
avifImage * image = avifImageCreate(width, height, 8, AVIF_PIXEL_FORMAT_YUV420);
avifRGBImageSetDefaults(&rgb, image);
avifRGBImageAllocatePixels(&rgb);
rgb.alphaPremultiplied = true;
memcpy(rgb.pixels, rgba, rgb.rowBytes * image->height);

free(rgba);
Expand Down
4 changes: 2 additions & 2 deletions Sources/avifc/AVIFDataDecoder.mm
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ - (nullable Image *)incrementallyDecodeData:(NSData *)data {
image = [UIImage imageWithCGImage:imageRef scale:1 orientation: UIImageOrientationUp];
#endif

CFRelease(provider);
CGDataProviderRelease(provider);
CGImageRelease(imageRef);
CGColorSpaceRelease(colorSpace);
return image;
Expand Down Expand Up @@ -263,7 +263,7 @@ - (nullable Image *)decode:(nonnull NSInputStream *)inputStream sampleSize:(CGSi
#endif

CGColorSpaceRelease(colorSpace);
CFRelease(provider);
CGDataProviderRelease(provider);
CGImageRelease(imageRef);
return image;
}
Expand Down
22 changes: 14 additions & 8 deletions Sources/avifc/AVIFEncoding.m → Sources/avifc/AVIFEncoding.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
#import <Accelerate/Accelerate.h>
#include "AVIFEncoding.h"
#include "PlatformImage.h"
#include <vector>

static void releaseSharedEncoder(avifEncoder* encoder) {
avifEncoderDestroy(encoder);
}

@implementation AVIFEncoding {
}

- (nullable NSData *)encodeImage:(nonnull Image *)platformImage
speed:(NSInteger)speed
depth:(NSUInteger)depth
quality:(double)quality error:(NSError * _Nullable *_Nullable)error {
unsigned char * rgba = [platformImage rgbaPixels];
#if TARGET_OS_OSX
Expand All @@ -31,9 +35,10 @@ - (nullable NSData *)encodeImage:(nonnull Image *)platformImage
int height = [platformImage size].height * [platformImage scale];
#endif
avifRGBImage rgb;
avifImage * image = avifImageCreate(width, height, (uint32_t)depth, AVIF_PIXEL_FORMAT_YUV420);
avifImage * image = avifImageCreate(width, height, (uint32_t)8, AVIF_PIXEL_FORMAT_YUV420);
avifRGBImageSetDefaults(&rgb, image);
avifRGBImageAllocatePixels(&rgb);
rgb.alphaPremultiplied = true;
memcpy(rgb.pixels, rgba, rgb.rowBytes * image->height);

free(rgba);
Expand All @@ -45,7 +50,7 @@ - (nullable NSData *)encodeImage:(nonnull Image *)platformImage
return nil;
}

avifEncoder * encoder = avifEncoderCreate();
std::shared_ptr<avifEncoder> encoder(avifEncoderCreate(), releaseSharedEncoder);
encoder->maxThreads = 4;
if (quality != 1.0) {
int rescaledQuality = AVIF_QUANTIZER_WORST_QUALITY - (int)(quality * AVIF_QUANTIZER_WORST_QUALITY);
Expand All @@ -55,21 +60,22 @@ - (nullable NSData *)encodeImage:(nonnull Image *)platformImage
if (speed != -1) {
encoder->speed = (int)MAX(MIN(speed, AVIF_SPEED_FASTEST), AVIF_SPEED_SLOWEST);
}
avifResult addImageResult = avifEncoderAddImage(encoder, image, 1, AVIF_ADD_IMAGE_FLAG_SINGLE);
auto encoderPtr = encoder.get();
avifResult addImageResult = avifEncoderAddImage(encoderPtr, image, 1, AVIF_ADD_IMAGE_FLAG_SINGLE);
if (addImageResult != AVIF_RESULT_OK) {
avifRGBImageFreePixels(&rgb);
avifImageDestroy(image);
avifEncoderDestroy(encoder);
encoder.reset();
*error = [[NSError alloc] initWithDomain:@"AVIFEncoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat: @"add image failed with result: %s", avifResultToString(addImageResult)] }];
return nil;
}

avifRWData avifOutput = AVIF_DATA_EMPTY;
avifResult finishResult = avifEncoderFinish(encoder, &avifOutput);
avifResult finishResult = avifEncoderFinish(encoderPtr, &avifOutput);
if (finishResult != AVIF_RESULT_OK) {
avifRGBImageFreePixels(&rgb);
avifImageDestroy(image);
avifEncoderDestroy(encoder);
encoder.reset();
*error = [[NSError alloc] initWithDomain:@"AVIFEncoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat: @"encoding failed with result: %s", avifResultToString(addImageResult)] }];
return nil;
}
Expand All @@ -79,7 +85,7 @@ - (nullable NSData *)encodeImage:(nonnull Image *)platformImage
avifRWDataFree(&avifOutput);
avifRGBImageFreePixels(&rgb);
avifImageDestroy(image);
avifEncoderDestroy(encoder);
encoder.reset();

return result;
}
Expand Down
38 changes: 7 additions & 31 deletions Sources/avifc/PlatformImage.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ -(nonnull uint8_t *) rgbaPixels {
CGImageRef imageRef = [self makeCGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
int targetBytesPerRow = ((4 * (int)width) + 31) & (~31);
uint8_t *targetMemory = malloc((int)(targetBytesPerRow * height));
int stride = (int)4 * (int)width * sizeof(uint8_t);
uint8_t *targetMemory = malloc((int)(stride * height));

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;

CGContextRef targetContext = CGBitmapContextCreate(targetMemory, width, height, 8, targetBytesPerRow, colorSpace, bitmapInfo);
CGContextRef targetContext = CGBitmapContextCreate(targetMemory, width, height, 8, stride, colorSpace, bitmapInfo);

[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithCGContext:targetContext flipped:FALSE]];
Expand All @@ -40,36 +40,17 @@ -(nonnull uint8_t *) rgbaPixels {

[NSGraphicsContext restoreGraphicsState];

int bufferBytesPerRow = ((3 * (int)width) + 31) & (~31);
uint8_t *buffer = malloc(bufferBytesPerRow * height);

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
uint32_t *color = ((uint32_t *)&targetMemory[y * targetBytesPerRow + x * 4]);

uint32_t r = ((*color >> 16) & 0xff);
uint32_t g = ((*color >> 8) & 0xff);
uint32_t b = (*color & 0xff);

buffer[y * bufferBytesPerRow + x * 3 + 0] = r;
buffer[y * bufferBytesPerRow + x * 3 + 1] = g;
buffer[y * bufferBytesPerRow + x * 3 + 2] = b;
}
}

CGContextRelease(targetContext);

free(targetMemory);

return buffer;
return targetMemory;
}
#else
- (unsigned char *)rgbaPixels {
CGImageRef imageRef = [self CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
unsigned char *rawData = (unsigned char*) malloc(height * width * 4 * sizeof(uint8_t));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
Expand All @@ -80,12 +61,7 @@ - (unsigned char *)rgbaPixels {

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);

unsigned char* newBytes = [AVIFRGBAMultiplier unpremultiplyBytes:rawData width:width height:height depth:8];
if (newBytes) {
free(rawData);
rawData = newBytes;
}

return rawData;
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion Sources/avifc/include/AVIFEncoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@

@interface AVIFEncoding : NSObject

- (nullable NSData *)encodeImage:(nonnull Image *)platformImage speed:(NSInteger)speed depth:(NSUInteger)depth quality:(double)quality error:(NSError * _Nullable *_Nullable)error;
- (nullable NSData *)encodeImage:(nonnull Image *)platformImage speed:(NSInteger)speed quality:(double)quality error:(NSError * _Nullable *_Nullable)error;

@end

0 comments on commit 40c2ce1

Please sign in to comment.