@@ -10,7 +10,7 @@ use std::marker::PhantomData;
1010use std:: mem;
1111
1212use tiff:: decoder:: { Decoder , DecodingResult } ;
13- use tiff:: encoder:: Compression ;
13+ use tiff:: encoder:: { Compression , DeflateLevel } ;
1414use tiff:: tags:: Tag ;
1515
1616use crate :: color:: { ColorType , ExtendedColorType } ;
@@ -367,6 +367,60 @@ pub struct TiffEncoder<W> {
367367 comp : Compression ,
368368}
369369
370+ /// Compression types supported by the TIFF format
371+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
372+ pub enum CompressionType {
373+ /// No compression
374+ Uncompressed ,
375+ /// LZW compression
376+ Lzw ,
377+ /// Deflate compression
378+ Deflate ( TiffDeflateLevel ) ,
379+ /// Bit packing compression
380+ Packbits ,
381+ }
382+
383+ impl Default for CompressionType {
384+ fn default ( ) -> Self {
385+ CompressionType :: Deflate ( Default :: default ( ) )
386+ }
387+ }
388+
389+ /// The level of compression used by the Deflate algorithm.
390+ /// It allows trading compression ratio for compression speed.
391+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Default ) ]
392+ #[ non_exhaustive]
393+ pub enum TiffDeflateLevel {
394+ /// The fastest possible compression mode.
395+ Fast = 1 ,
396+ /// The conserative choice between speed and ratio.
397+ #[ default]
398+ Balanced = 6 ,
399+ /// The best compression available with Deflate.
400+ Best = 9 ,
401+ }
402+
403+ impl TiffDeflateLevel {
404+ fn into_tiff ( self : TiffDeflateLevel ) -> DeflateLevel {
405+ match self {
406+ TiffDeflateLevel :: Fast => DeflateLevel :: Fast ,
407+ TiffDeflateLevel :: Balanced => DeflateLevel :: Balanced ,
408+ TiffDeflateLevel :: Best => DeflateLevel :: Best ,
409+ }
410+ }
411+ }
412+
413+ impl CompressionType {
414+ fn into_tiff ( self : CompressionType ) -> Compression {
415+ match self {
416+ CompressionType :: Uncompressed => Compression :: Uncompressed ,
417+ CompressionType :: Lzw => Compression :: Lzw ,
418+ CompressionType :: Deflate ( lvl) => Compression :: Deflate ( lvl. into_tiff ( ) ) ,
419+ CompressionType :: Packbits => Compression :: Packbits ,
420+ }
421+ }
422+ }
423+
370424fn cmyk_to_rgb ( cmyk : & [ u8 ] ) -> [ u8 ; 3 ] {
371425 let c = f32:: from ( cmyk[ 0 ] ) ;
372426 let m = f32:: from ( cmyk[ 1 ] ) ;
@@ -450,18 +504,24 @@ fn u8_slice_as_u16(buf: &[u8]) -> ImageResult<DtypeContainer<u16>> {
450504impl < W : Write + Seek > TiffEncoder < W > {
451505 /// Create a new encoder that writes its output to `w`
452506 pub fn new ( w : W ) -> TiffEncoder < W > {
507+ let comp = CompressionType :: default ( ) . into_tiff ( ) ;
508+ TiffEncoder { w, comp }
509+ }
510+
511+ /// Create a new encoder that writes its output to `w` with `CompressionType` `compression`.
512+ ///
513+ /// It is best to view the options as a _hint_ to the implementation on the smallest or fastest
514+ /// option for encoding a particular image. That is, using options that map directly to a TIFF
515+ /// image parameter will use this parameter where possible. But variants that have no direct
516+ /// mapping may be interpreted differently in minor versions. The exact output is expressly
517+ /// __not__ part of the SemVer stability guarantee.
518+ pub fn new_with_compression ( w : W , comp : CompressionType ) -> Self {
453519 TiffEncoder {
454520 w,
455- comp : Compression :: default ( ) ,
521+ comp : comp . into_tiff ( ) ,
456522 }
457523 }
458524
459- /// Set the image compression setting
460- pub fn with_compression ( mut self , comp : Compression ) -> Self {
461- self . comp = comp;
462- self
463- }
464-
465525 /// Encodes the image `image` that has dimensions `width` and `height` and `ColorType` `c`.
466526 ///
467527 /// 16-bit types assume the buffer is native endian.
0 commit comments