Skip to content

Commit

Permalink
downgrade iOS to v11, added full support for tvOS and WatchOS
Browse files Browse the repository at this point in the history
  • Loading branch information
awxkee committed Jan 10, 2023
1 parent 072cc26 commit 70ab19b
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 19 deletions.
16 changes: 8 additions & 8 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,35 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/awxkee/libaom.swift.git",
"state" : {
"revision" : "968e44ab7d53a78439caabe4fe0e19e1b5207a1e",
"version" : "1.0.1"
"revision" : "5edd755916eaf0951b8d92ca2c5b3941ead9a9a0",
"version" : "1.0.2"
}
},
{
"identity" : "libdav1d.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/awxkee/libdav1d.swift.git",
"state" : {
"revision" : "44e67528b0ad5e8f8840af727949925826c6162a",
"version" : "1.0.2"
"revision" : "8b5c794bae0190792e6969e2e9bdde9529deb8e9",
"version" : "1.0.4"
}
},
{
"identity" : "libyuv.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/awxkee/libyuv.swift.git",
"state" : {
"revision" : "27a7157a956b5d95f07d8b2b29d61c5fcd8c4f4d",
"version" : "1.0.0"
"revision" : "6ccc8fc35d5f6e5b419c0792f0b1de8e5a448e45",
"version" : "1.0.1"
}
},
{
"identity" : "nuke",
"kind" : "remoteSourceControl",
"location" : "https://github.com/kean/Nuke.git",
"state" : {
"revision" : "93c8dc78fbc0aa3538a0db460eb389d4180af242",
"version" : "11.3.1"
"revision" : "2e9337168d08acccf72c039bf9324be24a1cf7d7",
"version" : "11.5.3"
}
}
],
Expand Down
6 changes: 3 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription

let package = Package(
name: "avif",
platforms: [.iOS(.v14), .macOS(.v12), .macCatalyst(.v14)],
platforms: [.iOS(.v11), .macOS(.v12), .macCatalyst(.v14), .watchOS(.v6), .tvOS(.v13)],
products: [
.library(
name: "avif",
Expand All @@ -16,8 +16,8 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/awxkee/libaom.swift.git", "1.0.0"..<"1.1.0"),
.package(url: "https://github.com/awxkee/libdav1d.swift.git", exact: "1.0.2"),
.package(url: "https://github.com/awxkee/libyuv.swift.git", exact: "1.0.0"),
.package(url: "https://github.com/awxkee/libdav1d.swift.git", "1.0.0"..<"1.1.0"),
.package(url: "https://github.com/awxkee/libyuv.swift.git", "1.0.0"..<"1.1.0"),
.package(url: "https://github.com/kean/Nuke.git", "11.0.0"..<"12.0.0")
],
targets: [
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

## What's This?

A package to display AVIF on iOS and MacOS or encode AVIF images. Also provider AVIF support for Nuke. Have support for older versions of iOS that doesn't have support for AVIF images
This package is provides full (compatibility support) for AVIF images for all apple platforms. Supports encode AVIF and decode AVIF images in convinient and fast way

A package to display AVIF on iOS, MacOS, Catalyst, WatchOS, tvOS or encode AVIF images. Also provider AVIF support for Nuke. Have support for older versions of iOS, WatchOS, MacOSX, tvOS, Catalyst and all the simulators that doesn't have support for AVIF images

Package based on `dav1d` to have the best speed of decompressing on devices that do not have support for AV1 hardware codec.
As AVIF encoder have `aom` as just this one looks reasonable to encode AVIF images on mobile devices
</br>
Main aim of the project is to use `AVIF` image in `iOS` etc with usable speed and convenience
Main aim of the project is to use `AVIF` image on all Apple platforms etc with usable speed and convenience

Supports animated AVIF's with realtime FPS like 24+
Also supports encoding animated AVIF's

Precompiled for iOS 14+, Mac OS 12+, Mac Catalyst 14+
Precompiled for iOS 11+, Mac OS 12+, Mac Catalyst 14+, WatchOS 6+, tvOS 13+

## Installation

Expand Down Expand Up @@ -45,6 +47,7 @@ let encodedData = animatedEncoder.encode()
```

## Nuke Plugin

If you wish to use `AVIF` with <a href="https://github.com/kean/Nuke" target="_blank">`Nuke`</a> you may add `avifnuke` library to project and activate the plugin on app init

```swift
Expand All @@ -59,6 +62,11 @@ Nuke.loadImage(with: url, into: imageView)

Currently, avif nuke plugin do not support animated avifs so you have to do it yourself

## Disclaimer

#AVIF
Alliance for Open Media has developed the AVIF image format, a format that makes images have a smaller file size than with JPEG, PNG, GIF, or HEIF, without sacrificing image quality. AVIF offers lossy and lossless compression and has already 70% support by web browsers. It is regarded as a significant advancement in media compression. It is the goal of AOMedia to create open, royalty-free software standards for multimedia distribution. Specifically, AVIF will be free for everyone to use. There is a long list of big companies behind AOMedia, including Netflix, Google, Facebook, Apple, and Microsoft. In terms of image file formats for the web, JPG and PNG are considered the most popular. Several years ago, Google developed a format called WebP that delivers images 30% smaller than JPGs, while maintaining image quality. With AVIF, images are 50% smaller than JPG while maintaining the same quality.

## TODO
- [ ] Tests
- [ ] Some examples
6 changes: 6 additions & 0 deletions Sources/avif/AVIFDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ public final class AVIFDecoder {
return image
}

public static func decode(from data: Data, sampleSize: CGSize = .zero) throws -> PlatformImage {
let iStream = InputStream(data: data)
let image = try AVIFDataDecoder().decode(iStream, sampleSize: sampleSize, maxContentSize: 0)
return image
}

public static func readSize(data: Data) throws -> CGSize {
guard let decoder = avifDecoderCreate() else {
throw AVIFUnderlyingError(underlyingError: "Can't initialize decoder")
Expand Down
5 changes: 4 additions & 1 deletion Sources/avif/AVIFEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ public class AVIFEncoder {
let destSize = NSMakeSize(CGFloat(size.width), CGFloat(size.height))
let newImage = NSImage(size: destSize)
newImage.lockFocus()
image.draw(in: NSMakeRect(0, 0, destSize.width, destSize.height), from: NSMakeRect(0, 0, image.size.width, image.size.height), operation: NSCompositingOperation.copy, fraction: CGFloat(1))
image.draw(in: NSMakeRect(0, 0, destSize.width, destSize.height),
from: NSMakeRect(0, 0, image.size.width, image.size.height),
operation: NSCompositingOperation.copy,
fraction: CGFloat(1))
newImage.unlockFocus()
newImage.size = destSize
return NSImage(data: newImage.tiffRepresentation!)!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ @implementation AVIFAnimatedDecoder {
-(nullable id)initWithData:(nonnull NSData*)data {
_idec = avifDecoderCreate();

avifDecoderSetIOMemory(_idec, data.bytes, data.length);
avifDecoderSetIOMemory(_idec, reinterpret_cast<const uint8_t*>(data.bytes), data.length);
CGFloat scale = 1;

_idec->strictFlags = AVIF_STRICT_DISABLED;
Expand Down Expand Up @@ -74,7 +74,7 @@ -(nullable CGImageRef)get:(int)frame {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
int flags = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;

CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, premultiplied, rgbImage.width*rgbImage.height*rgbImage.depth/2, AV1CGDataProviderReleaseDataCallback);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, premultiplied, rgbImage.width*rgbImage.height*4, AV1CGDataProviderReleaseDataCallback);
if (!provider) {
free(premultiplied);
return NULL;
Expand Down
1 change: 1 addition & 0 deletions Sources/avifc/AVIFAnimatedEncoder.mm
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.depth = 8;
rgb.alphaPremultiplied = true;
memcpy(rgb.pixels, rgba, rgb.rowBytes * image->height);

Expand Down
3 changes: 2 additions & 1 deletion Sources/avifc/AVIFRGBAMultiplier.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ +(nullable unsigned char*)unpremultiplyBytes:(nonnull unsigned char*)data width:
}

+(nullable NSData*)unpremultiply:(nonnull NSData*)data width:(NSInteger)width height:(NSInteger)height depth:(NSInteger)depth {
int stride = (int)width * (depth > 8 ? sizeof(uint16_t) : sizeof(uint8_t));
void* unpremultipliedBytes = [AVIFRGBAMultiplier unpremultiplyBytes:(unsigned char*)data.bytes width:width height:height depth:depth];
if (!unpremultipliedBytes) {
return nil;
}
NSData* returningData = [[NSData alloc] initWithBytesNoCopy:unpremultipliedBytes length:width*height*depth/2 deallocator:^(void * _Nonnull bytes, NSUInteger length) {
NSData* returningData = [[NSData alloc] initWithBytesNoCopy:unpremultipliedBytes length:height*stride deallocator:^(void * _Nonnull bytes, NSUInteger length) {
free(bytes);
}];
return returningData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ -(nonnull uint8_t *) rgbaPixels {
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
int stride = (int)4 * (int)width * sizeof(uint8_t);
uint8_t *targetMemory = malloc((int)(stride * height));
uint8_t *targetMemory = reinterpret_cast<uint8_t*>(malloc((int)(stride * height)));

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
Expand Down

0 comments on commit 70ab19b

Please sign in to comment.