diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist
index 9625e10..7c56964 100644
--- a/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 11.0
+ 12.0
diff --git a/example/ios/Podfile b/example/ios/Podfile
index fdcc671..d97f17e 100644
--- a/example/ios/Podfile
+++ b/example/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-# platform :ios, '11.0'
+# platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index d161b21..973bd64 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -15,8 +15,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
blurhash_ffi: 4831b96320d4273876c9a2fd3f7d50b8a3a53509
- Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
+ Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
-PODFILE CHECKSUM: 70d9d25280d0dd177a5f637cdb0f0b0b12c6a189
+PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796
-COCOAPODS: 1.12.1
+COCOAPODS: 1.15.2
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index df8adb5..2843ebb 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -219,7 +219,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1430;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
@@ -457,7 +457,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -584,7 +584,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -633,7 +633,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index 87131a0..8e3ca5d 100644
--- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
();
final listener = ImageStreamListener((imageInfo, _) async {
- final ByteData? bytes =
- await imageInfo.image.toByteData(format: ui.ImageByteFormat.rawRgba);
+ final ByteData? bytes = await imageInfo.image
+ .toByteData(format: ui.ImageByteFormat.rawRgba);
if (bytes == null) {
completer.completeError(BlurhashFFIException(
'Could not decode Image from Image provider',
@@ -186,15 +186,10 @@ class BlurhashFFI {
return;
}
final Uint8List list = bytes.buffer.asUint8List();
- final rgbBytes = Uint8List(list.length ~/ 4 * 3);
- for (var i = 0, j = 0; i < list.length; i += 4, j += 3) {
- rgbBytes[j] = list[i];
- rgbBytes[j + 1] = list[i + 1];
- rgbBytes[j + 2] = list[i + 2];
- }
+
if (!completer.isCompleted) {
completer.complete(BlurHashImageInfo(imageInfo.image.height,
- imageInfo.image.width, imageInfo.image.width * 3, rgbBytes));
+ imageInfo.image.width, imageInfo.image.width * 4, list));
}
}, onError: (dynamic exception, StackTrace? stackTrace) {
completer.completeError(exception, stackTrace);
@@ -356,7 +351,6 @@ class BlurhashFFI {
data.pixelsPointer,
data.rowStride,
);
- data.free();
final String resultString = result.cast().toDartString();
final _EncodeResponse response =
_EncodeResponse(data.id, resultString);
@@ -365,7 +359,6 @@ class BlurhashFFI {
} else if (data is _DecodeRequest) {
final Pointer result = _bindings.decode(data.blurHashPointer,
data.width, data.height, data.punch, data.channels);
- data.free();
final Uint8List resultImage = result.asTypedList(
data.width * data.height * data.channels,
// preffer way but works only from dart 3.1.0, and requre to change generated bindings
@@ -402,7 +395,7 @@ class BlurhashFFI {
final stackTrace = StackTrace.current;
throw BlurhashFFIException(
'ERORR: ${Isolate.current.debugName}', stackTrace, e);
- }
+ }
}
final ReceivePort helperReceivePort = ReceivePort()..listen(onSend);
@@ -423,7 +416,11 @@ class BlurhashFFIException extends Error {
[this.level = Level.SEVERE]);
}
-class _DecodeToArrayRequest {
+mixin Freeable {
+ void free();
+}
+
+class _DecodeToArrayRequest with Freeable{
final int id;
final String blurHash;
final int width;
@@ -444,6 +441,7 @@ class _DecodeToArrayRequest {
return _bhptr!.cast();
}
+ @override
void free() {
if (_bhptr != null) {
malloc.free(_bhptr!);
@@ -452,7 +450,7 @@ class _DecodeToArrayRequest {
}
}
-class _DecodeRequest {
+class _DecodeRequest with Freeable{
final int id;
final String blurHash;
final int width;
@@ -471,7 +469,7 @@ class _DecodeRequest {
}
return _bhptr!.cast();
}
-
+ @override
void free() {
if (_bhptr != null) {
malloc.free(_bhptr!);
@@ -480,7 +478,7 @@ class _DecodeRequest {
}
}
-class _EncodeRequest {
+class _EncodeRequest with Freeable{
final int id;
final Uint8List pixels;
final int width;
@@ -501,6 +499,7 @@ class _EncodeRequest {
return pixelsPtr!;
}
+ @override
void free() {
if (pixelsPtr != null) {
calloc.free(pixelsPtr!);
diff --git a/lib/blurhash_ffi_bindings_generated.dart b/lib/blurhash_ffi_bindings_generated.dart
index 81194fb..07c3231 100644
--- a/lib/blurhash_ffi_bindings_generated.dart
+++ b/lib/blurhash_ffi_bindings_generated.dart
@@ -34,7 +34,7 @@ class BlurhashFfiBindings {
/// `yComponents` - The number of components in the Y direction. Must be between 1 and 9. 3 to 5 is usually a good range for this.
/// `width` - The width in pixels of the supplied image.
/// `height` - The height in pixels of the supplied image.
- /// `rgb` - A pointer to the pixel data. This is supplied in RGB order, with 3 bytes per pixels.
+ /// `rgb` - A pointer to the pixel data. This is supplied in RGBA format, with 4 bytes per pixels.
/// `bytesPerRow` - The number of bytes per row of the RGB pixel data.
ffi.Pointer blurHashForPixels(
int xComponents,
@@ -166,22 +166,4 @@ class BlurhashFfiBindings {
'freePixelArray');
late final _freePixelArray =
_freePixelArrayPtr.asFunction)>();
-
- /// freeBlurhash : Frees the blurhash string
- /// Parameters :
- /// blurhash : Blurhash string pointer which will be freed.
- /// Returns : void (None)
- void freeString(
- ffi.Pointer blurhash,
- ) {
- return _freeString(
- blurhash,
- );
- }
-
- late final _freeStringPtr =
- _lookup)>>(
- 'freeString');
- late final _freeString =
- _freeStringPtr.asFunction)>();
}
diff --git a/src/blurhash_ffi.c b/src/blurhash_ffi.c
index 8cbf1a4..4ccce6a 100644
--- a/src/blurhash_ffi.c
+++ b/src/blurhash_ffi.c
@@ -48,6 +48,8 @@ const char *blurHashForPixels(int xComponents, int yComponents, int width, int h
}
}
+ free(rgb);
+
float *dc = &factors[0];
float *ac = dc + 3;
int acCount = xComponents * yComponents - 1;
@@ -88,12 +90,14 @@ static float *multiplyBasisFunction(int xComponent, int yComponent, int width, i
float r = 0, g = 0, b = 0;
float normalisation = (xComponent == 0 && yComponent == 0) ? 1 : 2;
+ int channels = (int)bytesPerRow / width;
+
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
float basis = cosf(M_PI * xComponent * x / width) * cosf(M_PI * yComponent * y / height);
- r += basis * sRGBToLinear(rgb[3 * x + 0 + y * bytesPerRow]);
- g += basis * sRGBToLinear(rgb[3 * x + 1 + y * bytesPerRow]);
- b += basis * sRGBToLinear(rgb[3 * x + 2 + y * bytesPerRow]);
+ r += basis * sRGBToLinear(rgb[channels * x + 0 + y * bytesPerRow]);
+ g += basis * sRGBToLinear(rgb[channels * x + 1 + y * bytesPerRow]);
+ b += basis * sRGBToLinear(rgb[channels * x + 2 + y * bytesPerRow]);
}
}
diff --git a/src/blurhash_ffi.h b/src/blurhash_ffi.h
index 64a38e8..26957a8 100644
--- a/src/blurhash_ffi.h
+++ b/src/blurhash_ffi.h
@@ -28,7 +28,7 @@
`yComponents` - The number of components in the Y direction. Must be between 1 and 9. 3 to 5 is usually a good range for this.
`width` - The width in pixels of the supplied image.
`height` - The height in pixels of the supplied image.
- `rgb` - A pointer to the pixel data. This is supplied in RGB order, with 3 bytes per pixels.
+ `rgb` - A pointer to the pixel data. This is supplied in RGBA format, with 4 bytes per pixels.
`bytesPerRow` - The number of bytes per row of the RGB pixel data.
*/