Compare commits
1 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
a58bec6bae |
|
|
@ -212,8 +212,28 @@ final class ImageConverterDarwin implements ImageConverterPlatform {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final bitsPerComponent = CGImageGetBitsPerComponent(originalImage);
|
// FIX: Always use 8 bits per component for the output bitmap context.
|
||||||
final bitmapInfo = CGImageGetBitmapInfo(originalImage);
|
//
|
||||||
|
// The original code copied bitsPerComponent and bitmapInfo from the
|
||||||
|
// source CGImage. When the source is a 16-bit PNG, this produces a
|
||||||
|
// parameter combination that CGBitmapContextCreate does not support
|
||||||
|
// (e.g. RGB | 16 bits/component | kCGImageByteOrder16Little), causing
|
||||||
|
// it to return NULL. The subsequent CFRelease(NULL) in the finally
|
||||||
|
// block then triggers a fatal EXC_BREAKPOINT (brk #0x1).
|
||||||
|
//
|
||||||
|
// Since all output formats (JPEG, PNG, HEIC) produce 8-bit images,
|
||||||
|
// there is no need to create a 16-bit context. CGContextDrawImage()
|
||||||
|
// automatically downsamples 16-bit source pixels when drawing into
|
||||||
|
// an 8-bit context.
|
||||||
|
//
|
||||||
|
// kCGImageAlphaPremultipliedLast (value 1) is universally supported
|
||||||
|
// by CGBitmapContextCreate for all RGB colour spaces and correctly
|
||||||
|
// handles both opaque and transparent source images. For opaque
|
||||||
|
// output formats like JPEG, the alpha channel is discarded by the
|
||||||
|
// encoder.
|
||||||
|
const bitsPerComponent = 8;
|
||||||
|
// kCGImageAlphaPremultipliedLast = 1
|
||||||
|
const bitmapInfo = 1;
|
||||||
|
|
||||||
context = CGBitmapContextCreate(
|
context = CGBitmapContextCreate(
|
||||||
nullptr,
|
nullptr,
|
||||||
|
|
@ -251,7 +271,13 @@ final class ImageConverterDarwin implements ImageConverterPlatform {
|
||||||
}
|
}
|
||||||
return resizedImage;
|
return resizedImage;
|
||||||
} finally {
|
} finally {
|
||||||
if (context != null) CFRelease(context.cast());
|
// FIX: Check both Dart null AND FFI nullptr before releasing.
|
||||||
|
// The Dart variable `context` is non-null once assigned, but the
|
||||||
|
// native pointer may be nullptr if CGBitmapContextCreate failed.
|
||||||
|
// CFRelease(NULL) is a fatal error in CoreFoundation (brk #0x1).
|
||||||
|
if (context != null && context != nullptr) {
|
||||||
|
CFRelease(context.cast());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue