@@ -10,7 +10,7 @@ use std::marker::PhantomData;
10
10
use std:: mem;
11
11
12
12
use tiff:: decoder:: { Decoder , DecodingResult } ;
13
- use tiff:: encoder:: Compression ;
13
+ use tiff:: encoder:: { Compression , DeflateLevel } ;
14
14
use tiff:: tags:: Tag ;
15
15
16
16
use crate :: color:: { ColorType , ExtendedColorType } ;
@@ -367,6 +367,60 @@ pub struct TiffEncoder<W> {
367
367
comp : Compression ,
368
368
}
369
369
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
+
370
424
fn cmyk_to_rgb ( cmyk : & [ u8 ] ) -> [ u8 ; 3 ] {
371
425
let c = f32:: from ( cmyk[ 0 ] ) ;
372
426
let m = f32:: from ( cmyk[ 1 ] ) ;
@@ -410,18 +464,24 @@ fn u8_slice_as_pod<P: bytemuck::Pod>(buf: &[u8]) -> ImageResult<std::borrow::Cow
410
464
impl < W : Write + Seek > TiffEncoder < W > {
411
465
/// Create a new encoder that writes its output to `w`
412
466
pub fn new ( w : W ) -> TiffEncoder < W > {
467
+ let comp = CompressionType :: default ( ) . into_tiff ( ) ;
468
+ TiffEncoder { w, comp }
469
+ }
470
+
471
+ /// Create a new encoder that writes its output to `w` with `CompressionType` `compression`.
472
+ ///
473
+ /// It is best to view the options as a _hint_ to the implementation on the smallest or fastest
474
+ /// option for encoding a particular image. That is, using options that map directly to a TIFF
475
+ /// image parameter will use this parameter where possible. But variants that have no direct
476
+ /// mapping may be interpreted differently in minor versions. The exact output is expressly
477
+ /// __not__ part of the SemVer stability guarantee.
478
+ pub fn new_with_compression ( w : W , comp : CompressionType ) -> Self {
413
479
TiffEncoder {
414
480
w,
415
- comp : Compression :: default ( ) ,
481
+ comp : comp . into_tiff ( ) ,
416
482
}
417
483
}
418
484
419
- /// Set the image compression setting
420
- pub fn with_compression ( mut self , comp : Compression ) -> Self {
421
- self . comp = comp;
422
- self
423
- }
424
-
425
485
/// Encodes the image `image` that has dimensions `width` and `height` and `ColorType` `c`.
426
486
///
427
487
/// 16-bit types assume the buffer is native endian.
0 commit comments