@@ -10,8 +10,8 @@ use anyhow::{Context as _, Result, ensure, format_err};
1010use base64:: Engine as _;
1111use futures:: StreamExt ;
1212use image:: ImageReader ;
13- use image:: codecs:: jpeg:: JpegEncoder ;
1413use image:: { DynamicImage , GenericImage , GenericImageView , ImageFormat , Pixel , Rgba } ;
14+ use image:: { codecs:: jpeg:: JpegEncoder , metadata:: Orientation } ;
1515use num_traits:: FromPrimitive ;
1616use tokio:: { fs, task} ;
1717use tokio_stream:: wrappers:: ReadDirStream ;
@@ -362,7 +362,10 @@ impl<'a> BlobObject<'a> {
362362 return Ok ( name) ;
363363 }
364364 let mut img = imgreader. decode ( ) . context ( "image decode failure" ) ?;
365- let orientation = exif. as_ref ( ) . map ( |exif| exif_orientation ( exif, context) ) ;
365+ let orientation = exif
366+ . as_ref ( )
367+ . map ( |exif| exif_orientation ( exif, context) )
368+ . unwrap_or ( Orientation :: NoTransforms ) ;
366369 let mut encoded = Vec :: new ( ) ;
367370
368371 if * vt == Viewtype :: Sticker {
@@ -381,13 +384,7 @@ impl<'a> BlobObject<'a> {
381384 return Ok ( name) ;
382385 }
383386 }
384-
385- img = match orientation {
386- Some ( 90 ) => img. rotate90 ( ) ,
387- Some ( 180 ) => img. rotate180 ( ) ,
388- Some ( 270 ) => img. rotate270 ( ) ,
389- _ => img,
390- } ;
387+ img. apply_orientation ( orientation) ;
391388
392389 // max_wh is the maximum image width and height, i.e. the resolution-limit.
393390 // target_wh target-resolution for resizing the image.
@@ -551,18 +548,17 @@ fn image_metadata(file: &std::fs::File) -> Result<(u64, Option<exif::Exif>)> {
551548 Ok ( ( len, exif) )
552549}
553550
554- fn exif_orientation ( exif : & exif:: Exif , context : & Context ) -> i32 {
555- if let Some ( orientation) = exif. get_field ( exif:: Tag :: Orientation , exif:: In :: PRIMARY ) {
556- // possible orientation values are described at http://sylvana.net/jpegcrop/exif_orientation.html
557- // we only use rotation, in practise, flipping is not used.
558- match orientation. value . get_uint ( 0 ) {
559- Some ( 3 ) => return 180 ,
560- Some ( 6 ) => return 90 ,
561- Some ( 8 ) => return 270 ,
562- other => warn ! ( context, "Exif orientation value ignored: {other:?}." ) ,
563- }
551+ fn exif_orientation ( exif : & exif:: Exif , context : & Context ) -> Orientation {
552+ if let Some ( orientation) = exif. get_field ( exif:: Tag :: Orientation , exif:: In :: PRIMARY )
553+ && let Some ( val) = orientation. value . get_uint ( 0 )
554+ && let Ok ( val) = TryInto :: < u8 > :: try_into ( val)
555+ {
556+ return Orientation :: from_exif ( val) . unwrap_or ( {
557+ warn ! ( context, "Exif orientation value ignored: {val:?}." ) ;
558+ Orientation :: NoTransforms
559+ } ) ;
564560 }
565- 0
561+ Orientation :: NoTransforms
566562}
567563
568564/// All files in the blobdir.
0 commit comments