Files
mixbox_flutter/lib/mixbox_loader.dart
Robert Felker d199344d5d init
2026-02-10 17:07:13 +01:00

115 lines
3.7 KiB
Dart

import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/services.dart' show rootBundle;
import 'package:archive/archive.dart';
import 'package:mixbox/mixbox.dart'; // pub.dev/packages/archive
/// Helper pour initialiser Mixbox avec la LUT depuis les assets
class MixboxLoader {
/// Charge et initialise la LUT depuis un fichier asset
///
/// Le fichier mixbox_lut.dat doit être placé dans assets/
/// et déclaré dans pubspec.yaml:
///
/// flutter:
/// assets:
/// - assets/mixbox_lut.dat
///
/// Usage:
/// await MixboxLoader.initializeFromAsset('assets/mixbox_lut.dat');
static Future<void> initializeFromAsset(String assetPath) async {
final data = await rootBundle.load(assetPath);
final bytes = data.buffer.asUint8List();
// Décompression (le fichier original utilise Deflate)
final decompressed = _decompressLutData(bytes);
// Note: La méthode initialize() doit être adaptée dans mixbox.dart
// pour accepter les données décompressées
Mixbox.initialize(decompressed);
}
/// Décompresse les données de la LUT
static Uint8List _decompressLutData(Uint8List compressedData) {
// Skip les 192 premiers bytes (header)
final deflatedBytes = compressedData.sublist(192);
// Décompression avec raw deflate
final inflated = Inflate(deflatedBytes).getBytes();
// Post-traitement: reconstruction différentielle
for (int i = 0; i < inflated.length; i++) {
final previous = ((i & 63) != 0) ? inflated[i - 1] : 127;
inflated[i] = (previous + (inflated[i] - 127)) & 0xFF;
}
// Création du buffer final avec padding pour l'interpolation
// Taille: (64^3 * 3) + 4353 = 790785
final lut = Uint8List(64 * 64 * 64 * 3 + 4353);
lut.setAll(0, inflated);
return lut;
}
/// Génère une LUT de test (approximation simple, non-production!)
/// Utilisez ceci uniquement pour les tests sans le fichier .dat
static Uint8List generateTestLut() {
final size = 64 * 64 * 64 * 3 + 4353;
final lut = Uint8List(size);
// Approximation linéaire simple (pas physiquement correct!)
for (int r = 0; r < 64; r++) {
for (int g = 0; g < 64; g++) {
for (int b = 0; b < 64; b++) {
final idx = r + g * 64 + b * 64 * 64;
// Valeurs approximatives (à ne PAS utiliser en production)
lut[idx + 192] = (r * 4).clamp(0, 255);
lut[idx + 262336] = (g * 4).clamp(0, 255);
lut[idx + 524480] = (b * 4).clamp(0, 255);
}
}
}
return lut;
}
}
/// Extension pour faciliter l'utilisation avec Flutter Color
extension MixboxColorExtension on Color {
/// Convertit Flutter Color en format Mixbox (0xAARRGGBB)
int toMixboxInt() {
return (alpha << 24) | (red << 16) | (green << 8) | blue;
}
/// Convertit Flutter Color en format Mixbox float [r, g, b, a]
List<double> toMixboxFloat() {
return [red / 255.0, green / 255.0, blue / 255.0, alpha / 255.0];
}
/// Mélange cette couleur avec une autre via Mixbox
Color mixWith(Color other, double t) {
final mixed = Mixbox.lerp(toMixboxInt(), other.toMixboxInt(), t);
return Color(mixed);
}
/// Crée une Color depuis un int Mixbox
static Color fromMixboxInt(int mixboxColor) {
return Color(mixboxColor);
}
/// Crée une Color depuis un float Mixbox [r, g, b] ou [r, g, b, a]
static Color fromMixboxFloat(List<double> rgb) {
final r = (rgb[0] * 255).round().clamp(0, 255);
final g = (rgb[1] * 255).round().clamp(0, 255);
final b = (rgb[2] * 255).round().clamp(0, 255);
final a = rgb.length > 3 ? (rgb[3] * 255).round().clamp(0, 255) : 255;
return Color.fromARGB(a, r, g, b);
}
}
// Ajoutez cette dépendance dans pubspec.yaml:
// dependencies:
// archive: ^3.4.0