#706 use safer byte data format

This commit is contained in:
Thibault Deckers 2023-08-17 00:52:55 +02:00
parent 1d13c09379
commit 951cc4d295

View file

@ -16,13 +16,12 @@ mixin HistogramMixin {
Completer? _completer; Completer? _completer;
static const int bins = 256; static const int bins = 256;
static const int normMax = bins - 1;
Future<HistogramLevels> getHistogramLevels(ImageInfo info, bool forceUpdate) async { Future<HistogramLevels> getHistogramLevels(ImageInfo info, bool forceUpdate) async {
if (_levels.isEmpty || forceUpdate) { if (_levels.isEmpty || forceUpdate) {
if (_completer == null) { if (_completer == null) {
_completer = Completer(); _completer = Completer();
final data = (await info.image.toByteData(format: ImageByteFormat.rawExtendedRgba128))!; final data = (await info.image.toByteData(format: ImageByteFormat.rawStraightRgba))!;
_levels = switch (settings.overlayHistogramStyle) { _levels = switch (settings.overlayHistogramStyle) {
OverlayHistogramStyle.rgb => await compute<ByteData, HistogramLevels>(_computeRgbLevels, data), OverlayHistogramStyle.rgb => await compute<ByteData, HistogramLevels>(_computeRgbLevels, data),
OverlayHistogramStyle.luminance => await compute<ByteData, HistogramLevels>(_computeLuminanceLevels, data), OverlayHistogramStyle.luminance => await compute<ByteData, HistogramLevels>(_computeLuminanceLevels, data),
@ -42,17 +41,17 @@ mixin HistogramMixin {
final greenLevels = List.filled(bins, 0); final greenLevels = List.filled(bins, 0);
final blueLevels = List.filled(bins, 0); final blueLevels = List.filled(bins, 0);
final floats = Float32List.view(data.buffer); final view = Uint8List.view(data.buffer);
final pixelCount = floats.length / 4; final pixelCount = view.length / 4;
for (var i = 0; i < pixelCount; i += 4) { for (var i = 0; i < pixelCount; i += 4) {
final a = floats[i + 3]; final a = view[i + 3];
if (a > 0) { if (a > 0) {
final r = floats[i + 0]; final r = view[i + 0];
final g = floats[i + 1]; final g = view[i + 1];
final b = floats[i + 2]; final b = view[i + 2];
redLevels[(r * normMax).round()]++; redLevels[r]++;
greenLevels[(g * normMax).round()]++; greenLevels[g]++;
blueLevels[(b * normMax).round()]++; blueLevels[b]++;
} }
} }
@ -73,17 +72,17 @@ mixin HistogramMixin {
static HistogramLevels _computeLuminanceLevels(ByteData data) { static HistogramLevels _computeLuminanceLevels(ByteData data) {
final lumLevels = List.filled(bins, 0); final lumLevels = List.filled(bins, 0);
const normMax = bins - 1;
final floats = Float32List.view(data.buffer); final view = Uint8List.view(data.buffer);
final pixelCount = floats.length / 4; final pixelCount = view.length / 4;
for (var i = 0; i < pixelCount; i += 4) { for (var i = 0; i < pixelCount; i += 4) {
final a = floats[i + 3]; final a = view[i + 3];
if (a > 0) { if (a > 0) {
final r = floats[i + 0]; final r = view[i + 0];
final g = floats[i + 1]; final g = view[i + 1];
final b = floats[i + 2]; final b = view[i + 2];
final c = Color.fromARGB((a * 255).round(), (r * 255).round(), (g * 255).round(), (b * 255).round()); lumLevels[(Color.fromARGB(a, r, g, b).computeLuminance() * normMax).round()]++;
lumLevels[(c.computeLuminance() * normMax).round()]++;
} }
} }