Skip to main content

ImageOrientation

Enum ImageOrientation 

Source
#[non_exhaustive]
pub enum ImageOrientation { TopLeft, TopRight, BottomRight, BottomLeft, LeftTop, RightTop, RightBottom, LeftBottom, Other([i32; 9]), }
Expand description

Where the first stored row and column of a still belong on screen — the eight orientations EXIF names, tags 1 through 8.

§How it reaches us

Not through AVFrame.metadata, which is where an earlier reading of libavcodec put it. Measured, against this build, by feeding mjpeg a JPEG whose EXIF IFD carries each orientation in turn: for a recognised tag (1..=8) the decoder emits an AV_FRAME_DATA_DISPLAYMATRIX frame side-data entry and puts nothing in the metadata dictionary; only an out-of-range tag (0, 9, …) is left to fall through to the dictionary, as the string " 9". So the display matrix is the road, and the metadata dictionary is where malformed tags go to be ignored.

The matrix that arrives is the one below, in units of 65536 (the 16.16 fixed point libavutil/display.h specifies), with (a, b, c, d) the entries at indices 0, 1, 3, 4:

tagvariantabcd
1TopLeft1001
2TopRight-1001
3BottomRight-100-1
4BottomLeft100-1
5LeftTop0110
6RightTop01-10
7RightBottom0-1-10
8LeftBottom0-110

§Why a vocabulary of its own

mediaframe::frame::Rotation is this crate’s home for a quarter turn and is reused by Self::rotation — but it names four values and there are eight. The other four are mirrored, and a rotation vocabulary cannot hold a reflection. The same gap shows up one level down in FFmpeg’s own API: av_display_rotation_get answers -180 for both tag 2 and tag 3, -90 for both 5 and 6, and 90 for both 7 and 8 — reading only the angle loses the mirror on half the vocabulary. This type is the eight-value reading that does not.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

TopLeft

Tag 1 — stored as displayed. The default and the overwhelming majority of files.

§

TopRight

Tag 2 — mirrored horizontally.

§

BottomRight

Tag 3 — turned half way round.

§

BottomLeft

Tag 4 — mirrored vertically.

§

LeftTop

Tag 5 — transposed (mirrored, then a quarter turn clockwise).

§

RightTop

Tag 6 — a quarter turn clockwise.

§

RightBottom

Tag 7 — transverse (mirrored, then three quarter turns clockwise).

§

LeftBottom

Tag 8 — three quarter turns clockwise.

§

Other([i32; 9])

A display matrix none of the eight names, carried verbatim as all nine of its words.

Reachable: the display matrix is a general affine transform, and a container (a MOV tkhd, a hand-built stream) may carry an arbitrary one. Rather than answer TopLeft for a transform this vocabulary cannot name — the silent-loss failure this crate refuses everywhere else — the whole matrix rides along and Self::to_exif_code admits it has no tag for it.

All nine words, not the four that carry the orientation. The escape’s job is to lose nothing: a matrix with the right linear part and a translation, or a perspective term, is not one of the eight, and carrying only [a, b, c, d] would have thrown away the very words that made it different. That is the same collapse the escape exists to prevent, one level in.

Implementations§

Source§

impl ImageOrientation

Source

pub const fn is_top_left(&self) -> bool

Returns true if this value is of type TopLeft. Returns false otherwise

Source

pub const fn is_top_right(&self) -> bool

Returns true if this value is of type TopRight. Returns false otherwise

Source

pub const fn is_bottom_right(&self) -> bool

Returns true if this value is of type BottomRight. Returns false otherwise

Source

pub const fn is_bottom_left(&self) -> bool

Returns true if this value is of type BottomLeft. Returns false otherwise

Source

pub const fn is_left_top(&self) -> bool

Returns true if this value is of type LeftTop. Returns false otherwise

Source

pub const fn is_right_top(&self) -> bool

Returns true if this value is of type RightTop. Returns false otherwise

Source

pub const fn is_right_bottom(&self) -> bool

Returns true if this value is of type RightBottom. Returns false otherwise

Source

pub const fn is_left_bottom(&self) -> bool

Returns true if this value is of type LeftBottom. Returns false otherwise

Source

pub const fn is_other(&self) -> bool

Returns true if this value is of type Other. Returns false otherwise

Source§

impl ImageOrientation

Source

pub const DISPLAY_MATRIX_BYTES: usize

The number of bytes an AV_FRAME_DATA_DISPLAYMATRIX entry carries: nine int32_t, per libavutil/display.h.

Source

pub const fn matrix(&self) -> [i32; 9]

The nine-word matrix a named orientation stands for — the exact inverse of what Self::from_display_matrix reads, and for Self::Other the words it was handed, unchanged.

libavutil/display.h lays the matrix out row-major as

| a b u |     | 0 1 2 |
| c d v |  =  | 3 4 5 |
| x y w |     | 6 7 8 |

where a b c d x y are 16.16 fixed point and u v w are 2.30. A named orientation puts the rotation-or-reflection in a b c d, no translation in x y, no perspective in u v, and unity in w.

Source

pub fn from_display_matrix(bytes: &[u8]) -> Option<Self>

Reads an orientation out of the raw bytes of an AV_FRAME_DATA_DISPLAYMATRIX side-data entry.

None when bytes is not exactly Self::DISPLAY_MATRIX_BYTES long — a malformed entry is not an orientation, and guessing one from a truncated matrix would be the invention this seat exists to avoid.

The entries are int32_t in native byte order: the side data is a C array as it sits in memory, not a wire format.

Source

pub const fn to_exif_code(&self) -> Option<u16>

The EXIF tag value, 1 through 8.

None for Self::Other: it names a transform EXIF has no tag for, and there is no number to invent for it.

Source

pub const fn from_exif_code(code: u16) -> Option<Self>

Decodes an EXIF tag value. None outside 1..=8 — never a silent collapse onto Self::TopLeft, which is what a viewer that clamps an out-of-range tag ends up showing.

Source

pub const fn is_mirrored(&self) -> bool

true when displaying the picture correctly requires a reflection as well as a turn — EXIF tags 2, 4, 5 and 7.

Read off the sign of the linear part’s determinant, which is what a reflection is, so Self::Other answers too.

Source

pub const fn rotation(&self) -> Option<Rotation>

The quarter turn, clockwise, in the EXIF specification’s mirror-then-rotate decomposition — expressed in this workspace’s existing rotation vocabulary.

None for Self::Other, whose transform need not be a multiple of 90° at all.

This is the specification’s decomposition, not a measurement: what was measured here is which matrix carries which tag (see the type’s own docs), and the tag’s meaning is EXIF’s to define. Self::is_mirrored supplies the half a Rotation cannot hold.

Source

pub const fn linear(&self) -> [i32; 4]

The linear part of the display matrix this orientation stands for, [a, b, c, d] in 16.16 fixed point — matrix indices 0, 1, 3 and 4.

A projection, not the whole value: for Self::Other it drops the five words that made the matrix unnameable. Use Self::matrix when nothing may be lost; this is for the rotation-and-reflection question, which the four words answer on their own.

Trait Implementations§

Source§

impl Clone for ImageOrientation

Source§

fn clone(&self) -> ImageOrientation

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for ImageOrientation

Source§

impl Debug for ImageOrientation

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ImageOrientation

Source§

fn default() -> ImageOrientation

Returns the “default value” for a type. Read more
Source§

impl Eq for ImageOrientation

Source§

impl Hash for ImageOrientation

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for ImageOrientation

Source§

fn eq(&self, other: &ImageOrientation) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for ImageOrientation

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more