A linear DNG in and out: the writer, and a three-sample RawImage
dr-export gains write_linear_dng — LinearRaw, DNG 1.4, u16 samples at the sensor's scale, the body's matrices with their illuminants, the as-shot neutral, the EXIF block an export writes — streamed strip by strip through a closure so the composite is never held (FR-MRG-11). The tiff crate's directory is a map, so PhotometricInterpretation is written over what new_image set, which is the trick the S15.1 spike thought it had to hand-roll around. The test reads the file back through rawler. dr-decode's RawImage carries samples_per_pixel (a linear DNG is 3), the body's profile with its calibrations mapped back to EXIF illuminant codes, and the cleaned make and model. The GPU uploads a three-sample image as it is, normalised by black and white like a photosite, through a full f16 conversion — subnormals kept, because a 14-bit LSB sits at f16's smallest normal and rounding it to zero would crush exactly the shadows the file was written to keep.
This commit is contained in:
@@ -213,7 +213,7 @@ impl tiff::encoder::TiffValue for Undefined<'_> {
|
||||
/// specification says, `dr-decode` reads them back with `from_utf8_lossy`, and
|
||||
/// a mangled accent is a far better outcome than a refusal. So the bytes go
|
||||
/// through verbatim with the terminating NUL the type requires.
|
||||
struct Ascii<'a>(&'a str);
|
||||
pub(crate) struct Ascii<'a>(pub(crate) &'a str);
|
||||
|
||||
impl tiff::encoder::TiffValue for Ascii<'_> {
|
||||
const BYTE_LEN: u8 = 1;
|
||||
@@ -241,7 +241,7 @@ impl tiff::encoder::TiffValue for Ascii<'_> {
|
||||
/// a value that forced little-endian would be read back byte-swapped on a
|
||||
/// big-endian machine. `exif.rs` builds its own header and so chooses its own
|
||||
/// order; here the container has already chosen.
|
||||
struct Rationals<'a>(&'a [(u32, u32)]);
|
||||
pub(crate) struct Rationals<'a>(pub(crate) &'a [(u32, u32)]);
|
||||
|
||||
impl tiff::encoder::TiffValue for Rationals<'_> {
|
||||
const BYTE_LEN: u8 = 8;
|
||||
@@ -317,7 +317,7 @@ where
|
||||
/// and then no pointer is written either, so the file has no trace of the
|
||||
/// directory rather than a pointer to an empty one.
|
||||
#[derive(Default)]
|
||||
struct SubDirectories {
|
||||
pub(crate) struct SubDirectories {
|
||||
exif: Option<u32>,
|
||||
gps: Option<u32>,
|
||||
}
|
||||
@@ -335,7 +335,7 @@ struct SubDirectories {
|
||||
/// A TIFF gets no separate EXIF *block* — no APP1, no `eXIf` chunk. Its own
|
||||
/// directory is the EXIF structure, and adding a second copy inside it would
|
||||
/// give a reader two answers to every question.
|
||||
fn sub_directories<W>(
|
||||
pub(crate) fn sub_directories<W>(
|
||||
encoder: &mut tiff::encoder::TiffEncoder<W>,
|
||||
source: Option<&SourceMetadata>,
|
||||
width: u32,
|
||||
@@ -465,7 +465,7 @@ where
|
||||
///
|
||||
/// No `Orientation`, for the reason `exif.rs` gives at length: the pixels
|
||||
/// arriving here are already upright.
|
||||
fn tag_metadata<W, K>(
|
||||
pub(crate) fn tag_metadata<W, K>(
|
||||
dir: &mut tiff::encoder::DirectoryEncoder<'_, W, K>,
|
||||
source: Option<&SourceMetadata>,
|
||||
sub: &SubDirectories,
|
||||
|
||||
Reference in New Issue
Block a user