From 9d409433e83330efb74c7d7f4c28541fdb67e93c Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Sun, 11 Jan 2026 22:29:08 +0100 Subject: [PATCH 1/2] Rename write_tag_value to write_tag_buf We have not released this yet, let's align these names before it is too late. The decoder adopted the `_buf` suffix and I find it more convincing than the more generic `_value` (that also confusingly shares it with `TiffValue`). --- src/encoder/mod.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index e67d76b..712326e 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -291,21 +291,6 @@ impl<'a, W: 'a + Write + Seek, K: TiffKind> DirectoryEncoder<'a, W, K> { }) } - /// Write a tag-value pair with prepared byte data. - /// - /// Note that the library will _not_ attempt to verify that the data type or the count of the - /// buffered value is permissible for the given tag. The data will be associated with the tag - /// exactly as-is. - /// - /// An error is returned if the byte order of the presented value does not match the byte order - /// of the underlying file (i.e. the [native byte order](`crate::tags::ByteOrder::native`)). - pub fn write_tag_value(&mut self, tag: Tag, value: &ValueBuffer) -> TiffResult<()> { - let entry = self.write_entry_buf(value)?; - self.directory.extend([(tag, entry)]); - - Ok(()) - } - /// Write a single ifd tag. pub fn write_tag(&mut self, tag: Tag, value: T) -> TiffResult<()> { // Encodes the value if necessary. In the current bytes all integers are taken as native @@ -330,6 +315,21 @@ impl<'a, W: 'a + Write + Seek, K: TiffKind> DirectoryEncoder<'a, W, K> { Ok(()) } + /// Write a tag-value pair with prepared byte data. + /// + /// Note that the library will _not_ attempt to verify that the data type or the count of the + /// buffered value is permissible for the given tag. The data will be associated with the tag + /// exactly as-is. + /// + /// An error is returned if the byte order of the presented value does not match the byte order + /// of the underlying file (i.e. the [native byte order](`crate::tags::ByteOrder::native`)). + pub fn write_tag_buf(&mut self, tag: Tag, value: &ValueBuffer) -> TiffResult<()> { + let entry = self.write_entry_buf(value)?; + self.directory.extend([(tag, entry)]); + + Ok(()) + } + /// Write some data to the tiff file, the offset of the data is returned. /// /// This could be used to write tiff strips. All of the data will be written into the file as a From 9a23090b6e7b09729c9e03b16382e97738a154f5 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Sun, 11 Jan 2026 22:30:20 +0100 Subject: [PATCH 2/2] Provide write_entry_bytes This complements the entry API of the encoder with the byte slice based method. Note we don't provide it for writing raw data, here a `std::io::Write` would be more appropriate and we should not attempt to make it `write_all`, nor compress. You'd get all the benefits of the other API through `[u8]: TiffValue` since that interface is otherwise type agnostic and `u8` specifically is endian agnostic. --- src/encoder/mod.rs | 27 +++++++++++++++++++++++++++ src/error.rs | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index 712326e..8f1cb20 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -396,6 +396,33 @@ impl<'a, W: 'a + Write + Seek, K: TiffKind> DirectoryEncoder<'a, W, K> { ) } + /// Write a directory entry by its byte data. + /// + /// The data must be pre-formatted to the byte order expected by the file. + /// + /// Returns an [`Entry`]. If the value is short enough it will *not* be written in the file but + /// stored in the entry's offset field. + pub fn write_entry_bytes(&mut self, ty: Type, data: &[u8]) -> TiffResult { + if data.len() % usize::from(ty.byte_len()) != 0 { + return Err(TiffError::UsageError(UsageError::MismatchedEntryLength { + ty, + found: data.len(), + })); + } + + let count = data.len() / usize::from(ty.byte_len()); + let count = u64::try_from(count)?; + + Self::write_entry_inner( + self.writer, + DirectoryEntry { + data_type: ty, + count: K::convert_offset(count)?, + data: data.into(), + }, + ) + } + /// Insert previously written key-value entries. /// /// It is the caller's responsibility to ensure that the data referred to by the entries is diff --git a/src/error.rs b/src/error.rs index 94dc468..9311915 100644 --- a/src/error.rs +++ b/src/error.rs @@ -5,6 +5,7 @@ use std::string; use quick_error::quick_error; use crate::decoder::ChunkType; +use crate::tags::Type; use crate::tags::{ CompressionMethod, PhotometricInterpretation, PlanarConfiguration, SampleFormat, Tag, }; @@ -211,6 +212,9 @@ quick_error! { ByteOrderMismatch { display("attempted to use data with a byte order that does not match the required one") } + MismatchedEntryLength {ty: Type, found: usize } { + display("the length of data is not a multiple of the size of the type {ty:?}, found {found}") + } } }