@@ -60,7 +60,20 @@ impl DecodingResult {
6060 buffer : & BufferLayoutPreference ,
6161 limits : & Limits ,
6262 ) -> Result < ( ) , TiffError > {
63- let extent = DecodingExtent :: U8 ( buffer. complete_len ) ;
63+ let sample_type = buffer. sample_type . ok_or ( TiffError :: UnsupportedError (
64+ TiffUnsupportedError :: UnknownInterpretation ,
65+ ) ) ?;
66+
67+ let extent = sample_type. extent_for_bytes ( buffer. complete_len ) ;
68+ self . resize_to_extent ( extent, limits)
69+ }
70+
71+ fn resize_to_extent (
72+ & mut self ,
73+ extent : DecodingExtent ,
74+ limits : & Limits ,
75+ ) -> Result < ( ) , TiffError > {
76+ // FIXME: we *can* reuse the allocation sometimes.
6477 * self = extent. to_result_buffer ( limits) ?;
6578 Ok ( ( ) )
6679 }
@@ -1144,22 +1157,6 @@ impl<R: Read + Seek> Decoder<R> {
11441157 Ok ( u32:: try_from ( self . image ( ) . chunk_offsets . len ( ) ) ?)
11451158 }
11461159
1147- pub fn read_chunk_to_buffer (
1148- & mut self ,
1149- mut buffer : DecodingBuffer ,
1150- chunk_index : u32 ,
1151- output_width : usize ,
1152- ) -> TiffResult < ( ) > {
1153- let ( width, height) = self . image ( ) . chunk_data_dimensions ( chunk_index) ?;
1154-
1155- let mut layout = self . image ( ) . readout_for_size ( width, height) ?;
1156- layout. set_row_stride ( output_width) ?;
1157-
1158- self . read_chunk_to_bytes ( buffer. as_bytes_mut ( ) , chunk_index, & layout) ?;
1159-
1160- Ok ( ( ) )
1161- }
1162-
11631160 fn read_chunk_to_bytes (
11641161 & mut self ,
11651162 buffer : & mut [ u8 ] ,
@@ -1276,6 +1273,32 @@ impl<R: Read + Seek> Decoder<R> {
12761273 Ok ( ( ) )
12771274 }
12781275
1276+ /// Read the specified chunk (at index `chunk_index`) into a provide buffer.
1277+ ///
1278+ /// It will re-allocate the buffer into the correct type and size, within the decoder's
1279+ /// configured limits, and then pass it to the underlying method. This is essentially a
1280+ /// type-safe wrapper around the raw [`Self::read_chunk_to_bytes`] method.
1281+ ///
1282+ /// Note that for planar images each chunk contains only one sample of the underlying data.
1283+ pub fn read_chunk_to_buffer (
1284+ & mut self ,
1285+ buffer : & mut DecodingResult ,
1286+ chunk_index : u32 ,
1287+ output_width : usize ,
1288+ ) -> TiffResult < ( ) > {
1289+ let ( width, height) = self . image ( ) . chunk_data_dimensions ( chunk_index) ?;
1290+
1291+ let mut layout = self . image ( ) . readout_for_size ( width, height) ?;
1292+ layout. set_row_stride ( output_width) ?;
1293+
1294+ let extent = layout. result_extent_for_planes ( 0 ..1 ) ?;
1295+ buffer. resize_to_extent ( extent, & self . value_reader . limits ) ?;
1296+
1297+ self . read_chunk_to_bytes ( buffer. as_buffer ( 0 ) . as_bytes_mut ( ) , chunk_index, & layout) ?;
1298+
1299+ Ok ( ( ) )
1300+ }
1301+
12791302 /// Read chunks corresponding to several planes of a region of pixels.
12801303 ///
12811304 /// For non planar images this is equivalent to [`Self::read_chunk_bytes`] as there is only one
@@ -1388,29 +1411,47 @@ impl<R: Read + Seek> Decoder<R> {
13881411
13891412 /// Decodes the entire image into a provided buffer.
13901413 ///
1391- /// Returns a [`TiffError::UsageError`] if the chunk is smaller than the size indicated with a
1392- /// call to [`Self::image_buffer_layout`]. Note that the alignment may be arbitrary, but an
1393- /// alignment smaller than the preferred alignment may perform worse .
1414+ /// It will re-allocate the buffer into the correct type and size, within the decoder's
1415+ /// configured limits, and then pass it to the underlying method. This is essentially a
1416+ /// type-safe wrapper around the raw [`Self::read_image_bytes`] method .
13941417 ///
13951418 /// # Examples
13961419 ///
13971420 /// ```
13981421 /// use tiff::decoder::{Decoder, DecodingResult, Limits};
13991422 ///
14001423 /// let mut result = DecodingResult::I8(vec![]);
1401- /// let limits = Limits::unlimited();
14021424 ///
14031425 /// let mut reader = /* */
14041426 /// # Decoder::new(std::io::Cursor::new(include_bytes!(concat!(
14051427 /// # env!("CARGO_MANIFEST_DIR"), "/tests/images/tiled-gray-i1.tif"
14061428 /// # )))).unwrap();
14071429 ///
1408- /// let layout = reader.image_buffer_layout()?;
1409- /// result.resize_to(&layout, &limits)?;
1410- /// reader.read_image_bytes(result.as_buffer(0).as_bytes_mut())?;
1430+ /// reader.read_image_to_buffer(&mut result)?;
14111431 ///
14121432 /// # Ok::<_, tiff::TiffError>(())
14131433 /// ```
1434+ pub fn read_image_to_buffer (
1435+ & mut self ,
1436+ result : & mut DecodingResult ,
1437+ ) -> TiffResult < BufferLayoutPreference > {
1438+ let readout = self . image ( ) . readout_for_image ( ) ?;
1439+
1440+ let planes = readout. to_plane_layout ( ) ?;
1441+ let layout = BufferLayoutPreference :: from_planes ( & planes) ;
1442+
1443+ let extent = readout. result_extent_for_planes ( 0 ..1 ) ?;
1444+ result. resize_to_extent ( extent, & self . value_reader . limits ) ?;
1445+ self . read_image_bytes ( result. as_buffer ( 0 ) . as_bytes_mut ( ) ) ?;
1446+
1447+ Ok ( layout)
1448+ }
1449+
1450+ /// Decodes the entire image into a provided buffer.
1451+ ///
1452+ /// Returns a [`TiffError::UsageError`] if the chunk is smaller than the size indicated with a
1453+ /// call to [`Self::image_buffer_layout`]. Note that the alignment may be arbitrary, but an
1454+ /// alignment smaller than the preferred alignment may perform worse.
14141455 ///
14151456 /// # Error
14161457 ///
0 commit comments