[mob][photos] Mix of flutter and rust decoding
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
import 'package:photos/src/rust/frb_generated.dart';
|
||||
|
||||
// These functions are ignored because they are not marked as `pub`: `process_image_ml`
|
||||
|
||||
Future<
|
||||
(
|
||||
Uint8List,
|
||||
@@ -24,6 +26,24 @@ Future<
|
||||
RustLib.instance.api
|
||||
.crateApiImageProcessingProcessImageMlFromPath(imagePath: imagePath);
|
||||
|
||||
Future<
|
||||
(
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt
|
||||
)> processImageMlFromData(
|
||||
{required List<int> rgbaData,
|
||||
required int width,
|
||||
required int height}) =>
|
||||
RustLib.instance.api.crateApiImageProcessingProcessImageMlFromData(
|
||||
rgbaData: rgbaData, width: width, height: height);
|
||||
|
||||
Future<(Uint8List, String, BigInt, BigInt)> processYoloFace(
|
||||
{required String imagePath}) =>
|
||||
RustLib.instance.api
|
||||
|
||||
@@ -72,7 +72,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||
String get codegenVersion => '2.5.1';
|
||||
|
||||
@override
|
||||
int get rustContentHash => -1741400115;
|
||||
int get rustContentHash => -804230794;
|
||||
|
||||
static const kDefaultExternalLibraryLoaderConfig =
|
||||
ExternalLibraryLoaderConfig(
|
||||
@@ -86,6 +86,23 @@ abstract class RustLibApi extends BaseApi {
|
||||
Future<(Uint8List, String, BigInt, BigInt)>
|
||||
crateApiImageProcessingProcessClip({required String imagePath});
|
||||
|
||||
Future<
|
||||
(
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt
|
||||
)>
|
||||
crateApiImageProcessingProcessImageMlFromData(
|
||||
{required List<int> rgbaData,
|
||||
required int width,
|
||||
required int height});
|
||||
|
||||
Future<
|
||||
(
|
||||
Uint8List,
|
||||
@@ -143,6 +160,49 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
argNames: ["imagePath"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<
|
||||
(
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt
|
||||
)>
|
||||
crateApiImageProcessingProcessImageMlFromData(
|
||||
{required List<int> rgbaData,
|
||||
required int width,
|
||||
required int height}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
final arg0 = cst_encode_list_prim_u_8_loose(rgbaData);
|
||||
final arg1 = cst_encode_u_32(width);
|
||||
final arg2 = cst_encode_u_32(height);
|
||||
return wire
|
||||
.wire__crate__api__image_processing__process_image_ml_from_data(
|
||||
port_, arg0, arg1, arg2);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData:
|
||||
dco_decode_record_list_prim_u_8_strict_usize_usize_list_prim_u_8_strict_usize_usize_list_prim_u_8_strict_usize_usize,
|
||||
decodeErrorData: null,
|
||||
),
|
||||
constMeta: kCrateApiImageProcessingProcessImageMlFromDataConstMeta,
|
||||
argValues: [rgbaData, width, height],
|
||||
apiImpl: this,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiImageProcessingProcessImageMlFromDataConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "process_image_ml_from_data",
|
||||
argNames: ["rgbaData", "width", "height"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<
|
||||
(
|
||||
@@ -257,6 +317,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
return raw as String;
|
||||
}
|
||||
|
||||
@protected
|
||||
List<int> dco_decode_list_prim_u_8_loose(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw as List<int>;
|
||||
}
|
||||
|
||||
@protected
|
||||
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
@@ -310,6 +376,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
);
|
||||
}
|
||||
|
||||
@protected
|
||||
int dco_decode_u_32(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw as int;
|
||||
}
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
@@ -335,6 +407,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
return utf8.decoder.convert(inner);
|
||||
}
|
||||
|
||||
@protected
|
||||
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
final len_ = sse_decode_i_32(deserializer);
|
||||
return deserializer.buffer.getUint8List(len_);
|
||||
}
|
||||
|
||||
@protected
|
||||
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
@@ -390,6 +469,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
);
|
||||
}
|
||||
|
||||
@protected
|
||||
int sse_decode_u_32(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
return deserializer.buffer.getUint32();
|
||||
}
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
@@ -419,6 +504,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
return deserializer.buffer.getUint8() != 0;
|
||||
}
|
||||
|
||||
@protected
|
||||
int cst_encode_u_32(int raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return raw;
|
||||
}
|
||||
|
||||
@protected
|
||||
int cst_encode_u_8(int raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
@@ -437,6 +528,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_list_prim_u_8_loose(
|
||||
List<int> self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_i_32(self.length, serializer);
|
||||
serializer.buffer
|
||||
.putUint8List(self is Uint8List ? self : Uint8List.fromList(self));
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_list_prim_u_8_strict(
|
||||
Uint8List self, SseSerializer serializer) {
|
||||
@@ -482,6 +582,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
sse_encode_usize(self.$9, serializer);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_u_32(int self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
serializer.buffer.putUint32(self);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_u_8(int self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
||||
@@ -24,6 +24,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
String dco_decode_String(dynamic raw);
|
||||
|
||||
@protected
|
||||
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
|
||||
|
||||
@protected
|
||||
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
|
||||
|
||||
@@ -45,6 +48,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
) dco_decode_record_list_prim_u_8_strict_usize_usize_list_prim_u_8_strict_usize_usize_list_prim_u_8_strict_usize_usize(
|
||||
dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_32(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw);
|
||||
|
||||
@@ -57,6 +63,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
String sse_decode_String(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
|
||||
|
||||
@@ -79,6 +88,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
) sse_decode_record_list_prim_u_8_strict_usize_usize_list_prim_u_8_strict_usize_usize_list_prim_u_8_strict_usize_usize(
|
||||
SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_32(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer);
|
||||
|
||||
@@ -100,6 +112,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
return cst_encode_list_prim_u_8_strict(utf8.encoder.convert(raw));
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose> cst_encode_list_prim_u_8_loose(
|
||||
List<int> raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
final ans = wire.cst_new_list_prim_u_8_loose(raw.length);
|
||||
ans.ref.ptr.asTypedList(raw.length).setAll(0, raw);
|
||||
return ans;
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_list_prim_u_8_strict(
|
||||
Uint8List raw) {
|
||||
@@ -151,6 +172,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
wireObj.field8 = cst_encode_usize(apiObj.$9);
|
||||
}
|
||||
|
||||
@protected
|
||||
int cst_encode_u_32(int raw);
|
||||
|
||||
@protected
|
||||
int cst_encode_u_8(int raw);
|
||||
|
||||
@@ -160,6 +184,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
void sse_encode_String(String self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_list_prim_u_8_strict(
|
||||
Uint8List self, SseSerializer serializer);
|
||||
@@ -184,6 +211,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
) self,
|
||||
SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_32(int self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||
|
||||
@@ -260,6 +290,35 @@ class RustLibWire implements BaseWire {
|
||||
_wire__crate__api__image_processing__process_clipPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire__crate__api__image_processing__process_image_ml_from_data(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose> rgba_data,
|
||||
int width,
|
||||
int height,
|
||||
) {
|
||||
return _wire__crate__api__image_processing__process_image_ml_from_data(
|
||||
port_,
|
||||
rgba_data,
|
||||
width,
|
||||
height,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire__crate__api__image_processing__process_image_ml_from_dataPtr =
|
||||
_lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose>,
|
||||
ffi.Uint32,
|
||||
ffi.Uint32)>>(
|
||||
'frbgen_photos_wire__crate__api__image_processing__process_image_ml_from_data');
|
||||
late final _wire__crate__api__image_processing__process_image_ml_from_data =
|
||||
_wire__crate__api__image_processing__process_image_ml_from_dataPtr
|
||||
.asFunction<
|
||||
void Function(
|
||||
int, ffi.Pointer<wire_cst_list_prim_u_8_loose>, int, int)>();
|
||||
|
||||
void wire__crate__api__image_processing__process_image_ml_from_path(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> image_path,
|
||||
@@ -332,6 +391,21 @@ class RustLibWire implements BaseWire {
|
||||
late final _wire__crate__api__simple__init_app =
|
||||
_wire__crate__api__simple__init_appPtr.asFunction<void Function(int)>();
|
||||
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose> cst_new_list_prim_u_8_loose(
|
||||
int len,
|
||||
) {
|
||||
return _cst_new_list_prim_u_8_loose(
|
||||
len,
|
||||
);
|
||||
}
|
||||
|
||||
late final _cst_new_list_prim_u_8_loosePtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose> Function(
|
||||
ffi.Int32)>>('frbgen_photos_cst_new_list_prim_u_8_loose');
|
||||
late final _cst_new_list_prim_u_8_loose = _cst_new_list_prim_u_8_loosePtr
|
||||
.asFunction<ffi.Pointer<wire_cst_list_prim_u_8_loose> Function(int)>();
|
||||
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_new_list_prim_u_8_strict(
|
||||
int len,
|
||||
) {
|
||||
@@ -374,6 +448,13 @@ final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
|
||||
external int len;
|
||||
}
|
||||
|
||||
final class wire_cst_list_prim_u_8_loose extends ffi.Struct {
|
||||
external ffi.Pointer<ffi.Uint8> ptr;
|
||||
|
||||
@ffi.Int32()
|
||||
external int len;
|
||||
}
|
||||
|
||||
final class wire_cst_record_list_prim_u_8_strict_string_usize_usize
|
||||
extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> field0;
|
||||
|
||||
@@ -32,7 +32,7 @@ final List<List<double>> gaussianKernel =
|
||||
const maxKernelSize = gaussianKernelSize;
|
||||
const maxKernelRadius = maxKernelSize ~/ 2;
|
||||
|
||||
const List<String> supportedImageFormats = [
|
||||
const List<String> supportedRustImageFormats = [
|
||||
'bmp',
|
||||
'dds',
|
||||
'farbfeld',
|
||||
@@ -48,8 +48,6 @@ const List<String> supportedImageFormats = [
|
||||
'tga',
|
||||
'tiff',
|
||||
'webp',
|
||||
'heic',
|
||||
'heif',
|
||||
];
|
||||
|
||||
Future<(Image, Uint8List)> decodeImageFromPath(String imagePath) async {
|
||||
@@ -86,35 +84,9 @@ Future<(Image, Uint8List)> decodeImageFromPath(String imagePath) async {
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> safePathFromImagepath(String imagePath) async {
|
||||
bool canRustDecodeImage(String imagePath) {
|
||||
final format = imagePath.split('.').last;
|
||||
if (supportedImageFormats.contains(format)) {
|
||||
return imagePath;
|
||||
}
|
||||
try {
|
||||
final newPath = imagePath.replaceAll(format, 'jpeg');
|
||||
final time = DateTime.now();
|
||||
final File? convertedFile = await FlutterImageCompress.compressAndGetFile(
|
||||
imagePath,
|
||||
newPath,
|
||||
format: CompressFormat.jpeg,
|
||||
);
|
||||
_logger.info(
|
||||
'Conversion successful, heic converted in ${DateTime.now().difference(time).inMilliseconds} ms',
|
||||
);
|
||||
if (convertedFile == null) {
|
||||
throw Exception('Error converting image to jpeg');
|
||||
}
|
||||
return newPath;
|
||||
} catch (e) {
|
||||
_logger.severe(
|
||||
'Error decoding image of format $format on ${Platform.isAndroid ? "Android" : "iOS"}',
|
||||
e,
|
||||
);
|
||||
throw Exception(
|
||||
'InvalidImageFormatException: Error decoding image of format $format',
|
||||
);
|
||||
}
|
||||
return supportedRustImageFormats.contains(format);
|
||||
}
|
||||
|
||||
/// Decodes [Uint8List] image data to an ui.[Image] object.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "dart:io" show File;
|
||||
import "dart:math" as math show sqrt, min, max;
|
||||
import "dart:typed_data" show Uint8List;
|
||||
|
||||
import "package:flutter/services.dart" show PlatformException;
|
||||
import "package:logging/logging.dart";
|
||||
@@ -399,10 +400,28 @@ Future<MLResult> analyzeImageStatic(Map args) async {
|
||||
final startTime = DateTime.now();
|
||||
|
||||
// Decode the image once to use for both face detection and alignment
|
||||
final safePath = await safePathFromImagepath(imagePath);
|
||||
final format = safePath.split('.').last;
|
||||
// final (image, rawRgbaBytes) = await decodeImageFromPath(imagePath);
|
||||
|
||||
final bool decodeInRust = canRustDecodeImage(imagePath);
|
||||
late (
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt,
|
||||
Uint8List,
|
||||
BigInt,
|
||||
BigInt
|
||||
) rustResults;
|
||||
if (decodeInRust) {
|
||||
rustResults = await processImageMlFromPath(imagePath: imagePath);
|
||||
} else {
|
||||
final (image, rawRgbaBytes) = await decodeImageFromPath(imagePath);
|
||||
rustResults = await processImageMlFromData(
|
||||
rgbaData: rawRgbaBytes,
|
||||
width: image.width,
|
||||
height: image.height,
|
||||
);
|
||||
}
|
||||
final (
|
||||
rawRgbaBytes,
|
||||
imageHeight,
|
||||
@@ -413,17 +432,17 @@ Future<MLResult> analyzeImageStatic(Map args) async {
|
||||
clipBytes,
|
||||
clipHeight,
|
||||
clipWidth
|
||||
) = await processImageMlFromPath(imagePath: safePath);
|
||||
) = rustResults;
|
||||
final decodedImageSize =
|
||||
Dimensions(height: imageHeight.toInt(), width: imageWidth.toInt());
|
||||
final decodeTime = DateTime.now();
|
||||
final decodeMs = decodeTime.difference(startTime).inMilliseconds;
|
||||
_logger.info(
|
||||
'ML processing in rust took ${DateTime.now().difference(decodeTime).inMilliseconds} ms for format $format',
|
||||
'ML total image processing (in rust) took ${DateTime.now().difference(decodeTime).inMilliseconds} ms',
|
||||
);
|
||||
final decodedImageSize =
|
||||
Dimensions(height: imageHeight.toInt(), width: imageWidth.toInt());
|
||||
|
||||
final result = MLResult.fromEnteFileID(enteFileID);
|
||||
result.decodedImageSize = decodedImageSize;
|
||||
|
||||
String faceMsString = "", clipMsString = "";
|
||||
final pipelines = await Future.wait([
|
||||
runFaces
|
||||
|
||||
234
mobile/rust/Cargo.lock
generated
234
mobile/rust/Cargo.lock
generated
@@ -146,29 +146,6 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.2"
|
||||
@@ -181,12 +158,6 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "bitstream-io"
|
||||
version = "2.5.3"
|
||||
@@ -249,15 +220,6 @@ dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
version = "0.15.8"
|
||||
@@ -274,17 +236,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
@@ -397,17 +348,6 @@ version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "enumn"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.2"
|
||||
@@ -424,16 +364,6 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.72.0"
|
||||
@@ -520,12 +450,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "four-cc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "431a4c31778fde52b4400de34975f219eeca55cc829a9de157cd743a5b230ecb"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
@@ -652,12 +576,6 @@ version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.4.1"
|
||||
@@ -692,15 +610,6 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.4"
|
||||
@@ -800,12 +709,6 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.2"
|
||||
@@ -829,47 +732,6 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libheif-rs"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c32c0a0c970782707070f11c8612bced800b916af4ddaf6229161dc3ceb907"
|
||||
dependencies = [
|
||||
"enumn",
|
||||
"four-cc",
|
||||
"libc",
|
||||
"libheif-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libheif-sys"
|
||||
version = "2.1.1+1.17.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f60b29be1ef3ab2aba61344f09a18c3edf552bf4f9fbec9bd68b9ea6f98e71f8"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
@@ -1083,7 +945,7 @@ version = "0.17.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
@@ -1105,16 +967,6 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.89"
|
||||
@@ -1321,7 +1173,6 @@ dependencies = [
|
||||
"bytemuck",
|
||||
"flutter_rust_bridge",
|
||||
"image",
|
||||
"libheif-rs",
|
||||
"resize",
|
||||
"rgb",
|
||||
]
|
||||
@@ -1332,34 +1183,6 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@@ -1577,12 +1400,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.2.0"
|
||||
@@ -1595,16 +1412,6 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
@@ -1694,45 +1501,6 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
|
||||
@@ -11,5 +11,4 @@ flutter_rust_bridge = "=2.5.1"
|
||||
image = "0.25.4"
|
||||
resize = "0.8.7"
|
||||
rgb = "0.8.50"
|
||||
bytemuck = "1.16.0"
|
||||
libheif-rs = "1.0.2"
|
||||
bytemuck = "1.16.0"
|
||||
@@ -1,5 +1,4 @@
|
||||
use image::ImageBuffer;
|
||||
use libheif_rs::{ColorSpace, HeifContext, LibHeif, RgbChroma};
|
||||
use resize::{px::RGB, Pixel::RGB8, Type::Lanczos3, Type::Mitchell};
|
||||
use rgb::FromSlice;
|
||||
|
||||
@@ -16,36 +15,55 @@ pub fn process_image_ml_from_path(
|
||||
usize,
|
||||
usize,
|
||||
) {
|
||||
// Check the image format by checking the file extension in the image_path string (~0ms)
|
||||
let format = image_path.split('.').last().unwrap().to_lowercase();
|
||||
// Load the image from the path (~200ms)
|
||||
let img: image::DynamicImage = image::open(image_path).expect("Failed to open image");
|
||||
|
||||
let img = if format == "heic" || format == "heif" {
|
||||
let lib_heif = LibHeif::new();
|
||||
let ctx = HeifContext::read_from_file(image_path).expect("Failed to read HEIF file");
|
||||
let handle = ctx
|
||||
.primary_image_handle()
|
||||
.expect("Failed to get primary image handle");
|
||||
let decoded = lib_heif
|
||||
.decode(&handle, ColorSpace::Rgb(RgbChroma::Rgb), None)
|
||||
.expect("Failed to decode image");
|
||||
let plane = decoded
|
||||
.planes()
|
||||
.interleaved
|
||||
.expect("Failed to get interleaved plane");
|
||||
let rgb_data = plane.data.to_vec();
|
||||
let img = image::DynamicImage::from(
|
||||
ImageBuffer::<image::Rgb<u8>, _>::from_raw(decoded.width(), decoded.height(), rgb_data)
|
||||
.expect("Failed to create image buffer"),
|
||||
);
|
||||
img
|
||||
} else {
|
||||
let img = image::open(image_path).expect("Failed to open image");
|
||||
img
|
||||
};
|
||||
// Process the image
|
||||
let results = process_image_ml(img);
|
||||
|
||||
// Load the image (~200ms)
|
||||
// let img = image::open(image_path).expect("Failed to open image");
|
||||
results
|
||||
}
|
||||
|
||||
pub fn process_image_ml_from_data(
|
||||
rgba_data: Vec<u8>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> (
|
||||
Vec<u8>,
|
||||
usize,
|
||||
usize,
|
||||
Vec<u8>,
|
||||
usize,
|
||||
usize,
|
||||
Vec<u8>,
|
||||
usize,
|
||||
usize,
|
||||
) {
|
||||
// Load the image from the data
|
||||
let img = image::DynamicImage::from(
|
||||
ImageBuffer::<image::Rgb<u8>, _>::from_raw(width, height, rgba_data)
|
||||
.expect("Failed to create image buffer"),
|
||||
);
|
||||
|
||||
// Process the image
|
||||
let results = process_image_ml(img);
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
fn process_image_ml(
|
||||
img: image::DynamicImage,
|
||||
) -> (
|
||||
Vec<u8>,
|
||||
usize,
|
||||
usize,
|
||||
Vec<u8>,
|
||||
usize,
|
||||
usize,
|
||||
Vec<u8>,
|
||||
usize,
|
||||
usize,
|
||||
) {
|
||||
// Get dimensions for resized images (0ms)
|
||||
let (width, height) = (img.width() as usize, img.height() as usize);
|
||||
let scale_face = f32::min(640.0 / width as f32, 640.0 / height as f32);
|
||||
|
||||
@@ -37,7 +37,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
||||
default_rust_auto_opaque = RustAutoOpaqueNom,
|
||||
);
|
||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.5.1";
|
||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -1741400115;
|
||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -804230794;
|
||||
|
||||
// Section: executor
|
||||
|
||||
@@ -68,6 +68,37 @@ fn wire__crate__api__image_processing__process_clip_impl(
|
||||
},
|
||||
)
|
||||
}
|
||||
fn wire__crate__api__image_processing__process_image_ml_from_data_impl(
|
||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||
rgba_data: impl CstDecode<Vec<u8>>,
|
||||
width: impl CstDecode<u32>,
|
||||
height: impl CstDecode<u32>,
|
||||
) {
|
||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
|
||||
flutter_rust_bridge::for_generated::TaskInfo {
|
||||
debug_name: "process_image_ml_from_data",
|
||||
port: Some(port_),
|
||||
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
||||
},
|
||||
move || {
|
||||
let api_rgba_data = rgba_data.cst_decode();
|
||||
let api_width = width.cst_decode();
|
||||
let api_height = height.cst_decode();
|
||||
move |context| {
|
||||
transform_result_dco::<_, _, ()>((move || {
|
||||
let output_ok = Result::<_, ()>::Ok(
|
||||
crate::api::image_processing::process_image_ml_from_data(
|
||||
api_rgba_data,
|
||||
api_width,
|
||||
api_height,
|
||||
),
|
||||
)?;
|
||||
Ok(output_ok)
|
||||
})())
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
fn wire__crate__api__image_processing__process_image_ml_from_path_impl(
|
||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||
image_path: impl CstDecode<String>,
|
||||
@@ -154,6 +185,12 @@ fn wire__crate__api__simple__init_app_impl(port_: flutter_rust_bridge::for_gener
|
||||
|
||||
// Section: dart2rust
|
||||
|
||||
impl CstDecode<u32> for u32 {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
fn cst_decode(self) -> u32 {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl CstDecode<u8> for u8 {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
fn cst_decode(self) -> u8 {
|
||||
@@ -228,6 +265,13 @@ impl SseDecode
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for u32 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
deserializer.cursor.read_u32::<NativeEndian>().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for u8 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
@@ -342,6 +386,13 @@ impl SseEncode
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for u32 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
serializer.cursor.write_u32::<NativeEndian>(self).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for u8 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
@@ -405,6 +456,15 @@ mod io {
|
||||
String::from_utf8(vec).unwrap()
|
||||
}
|
||||
}
|
||||
impl CstDecode<Vec<u8>> for *mut wire_cst_list_prim_u_8_loose {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
fn cst_decode(self) -> Vec<u8> {
|
||||
unsafe {
|
||||
let wrap = flutter_rust_bridge::for_generated::box_from_leak_ptr(self);
|
||||
flutter_rust_bridge::for_generated::vec_from_leak_ptr(wrap.ptr, wrap.len)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl CstDecode<Vec<u8>> for *mut wire_cst_list_prim_u_8_strict {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
fn cst_decode(self) -> Vec<u8> {
|
||||
@@ -475,6 +535,18 @@ field8: Default::default(), }
|
||||
wire__crate__api__image_processing__process_clip_impl(port_, image_path)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn frbgen_photos_wire__crate__api__image_processing__process_image_ml_from_data(
|
||||
port_: i64,
|
||||
rgba_data: *mut wire_cst_list_prim_u_8_loose,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) {
|
||||
wire__crate__api__image_processing__process_image_ml_from_data_impl(
|
||||
port_, rgba_data, width, height,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn frbgen_photos_wire__crate__api__image_processing__process_image_ml_from_path(
|
||||
port_: i64,
|
||||
@@ -503,6 +575,17 @@ field8: Default::default(), }
|
||||
wire__crate__api__simple__init_app_impl(port_)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn frbgen_photos_cst_new_list_prim_u_8_loose(
|
||||
len: i32,
|
||||
) -> *mut wire_cst_list_prim_u_8_loose {
|
||||
let ans = wire_cst_list_prim_u_8_loose {
|
||||
ptr: flutter_rust_bridge::for_generated::new_leak_vec_ptr(Default::default(), len),
|
||||
len,
|
||||
};
|
||||
flutter_rust_bridge::for_generated::new_leak_box_ptr(ans)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn frbgen_photos_cst_new_list_prim_u_8_strict(
|
||||
len: i32,
|
||||
@@ -514,6 +597,12 @@ field8: Default::default(), }
|
||||
flutter_rust_bridge::for_generated::new_leak_box_ptr(ans)
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct wire_cst_list_prim_u_8_loose {
|
||||
ptr: *mut u8,
|
||||
len: i32,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct wire_cst_list_prim_u_8_strict {
|
||||
|
||||
Reference in New Issue
Block a user