diff options
author | 2024-07-31 20:43:39 +0200 | |
---|---|---|
committer | 2024-07-31 18:43:39 +0000 | |
commit | 697261da53cdb0b4230cb800d71bf333b367bff4 (patch) | |
tree | c02e2a2ae736c8ecbc306d3965420393f30f2a94 | |
parent | [feature] Implement Mastodon-compatible roles (#3136) (diff) | |
download | gotosocial-697261da53cdb0b4230cb800d71bf333b367bff4.tar.xz |
[chore] Take account of rotation data when calculating full size image dimensions (#3159)
* [chore] Take account of rotation data when calculating full size image dimensions
* boobies
-rw-r--r-- | internal/media/ffmpeg.go | 85 | ||||
-rw-r--r-- | internal/media/processingmedia.go | 1 | ||||
-rw-r--r-- | internal/media/util.go | 29 |
3 files changed, 65 insertions, 50 deletions
diff --git a/internal/media/ffmpeg.go b/internal/media/ffmpeg.go index 0de5797ab..e26ec78d7 100644 --- a/internal/media/ffmpeg.go +++ b/internal/media/ffmpeg.go @@ -437,6 +437,42 @@ func (res *ffprobeResult) Process() (*result, error) { } } + // Check extra packet / frame information + // for provided orientation (not always set). + for _, pf := range res.PacketsAndFrames { + for _, d := range pf.SideDataList { + + // Ensure frame side + // data IS rotation data. + if d.Rotation == 0 { + continue + } + + // Ensure rotation not + // already been specified. + if r.rotation != 0 { + return nil, errors.New("multiple sets of rotation data") + } + + // Drop any decimal + // rotation value. + rot := int(d.Rotation) + + // Round rotation to multiple of 90. + // More granularity is not needed. + if q := rot % 90; q > 45 { + rot += (90 - q) + } else { + rot -= q + } + + // Drop any value above 360 + // or below -360, these are + // just repeat full turns. + r.rotation = (rot % 360) + } + } + // Preallocate streams to max possible lengths. r.audio = make([]audioStream, 0, len(res.Streams)) r.video = make([]videoStream, 0, len(res.Streams)) @@ -450,12 +486,19 @@ func (res *ffprobeResult) Process() (*result, error) { stream: stream{codec: s.CodecName}, }) case "video": - var framerate float32 + // Determine proper display dimensions, + // taking account of rotation data. + width, height := displayDimensions( + s.Width, + s.Height, + r.rotation, + ) // Parse stream framerate, bearing in // mind that some static container formats // (e.g. jpeg) still return a framerate, so // we also check for a non-1 timebase (dts). + var framerate float32 if str := s.RFrameRate; str != "" && s.DurationTS > 1 { var num, den uint32 @@ -478,49 +521,13 @@ func (res *ffprobeResult) Process() (*result, error) { // Append video stream data to result. r.video = append(r.video, videoStream{ stream: stream{codec: s.CodecName}, - width: s.Width, - height: s.Height, + width: width, + height: height, framerate: framerate, }) } } - // Check extra packet / frame information - // for provided orientation (not always set). - for _, pf := range res.PacketsAndFrames { - for _, d := range pf.SideDataList { - - // Ensure frame side - // data IS rotation data. - if d.Rotation == 0 { - continue - } - - // Ensure rotation not - // already been specified. - if r.rotation != 0 { - return nil, errors.New("multiple sets of rotation data") - } - - // Drop any decimal - // rotation value. - rot := int(d.Rotation) - - // Round rotation to multiple of 90. - // More granularity is not needed. - if q := rot % 90; q > 45 { - rot += (90 - q) - } else { - rot -= q - } - - // Drop any value above 360 - // or below -360, these are - // just repeat full turns. - r.rotation = (rot % 360) - } - } - return &r, nil } diff --git a/internal/media/processingmedia.go b/internal/media/processingmedia.go index 3da036ac7..5d1d47b97 100644 --- a/internal/media/processingmedia.go +++ b/internal/media/processingmedia.go @@ -223,7 +223,6 @@ func (p *ProcessingMedia) store(ctx context.Context) error { width, height, aspect, - result.rotation, ) p.media.FileMeta.Small.Width = thumbWidth p.media.FileMeta.Small.Height = thumbHeight diff --git a/internal/media/util.go b/internal/media/util.go index dd445844d..7e84b4cdc 100644 --- a/internal/media/util.go +++ b/internal/media/util.go @@ -35,15 +35,13 @@ import ( "github.com/disintegration/imaging" ) -// thumbSize returns the dimensions to use for an input -// image of given width / height, for its outgoing thumbnail. -// This attempts to maintains the original image aspect ratio. -func thumbSize(width, height int, aspect float32, rotation int) (int, int) { - const ( - maxThumbWidth = 512 - maxThumbHeight = 512 - ) - +// displayDimensions takes account of the +// given rotation data to return width and +// height values as the image will be displayed. +func displayDimensions( + width, height int, + rotation int, +) (int, int) { // If image is rotated by // any odd multiples of 90, // flip width / height to @@ -51,9 +49,20 @@ func thumbSize(width, height int, aspect float32, rotation int) (int, int) { switch rotation { case -90, 90, -270, 270: width, height = height, width - aspect = 1 / aspect } + return width, height +} + +// thumbSize returns the dimensions to use for an input +// image of given width / height, for its outgoing thumbnail. +// This attempts to maintains the original image aspect ratio. +func thumbSize(width, height int, aspect float32) (int, int) { + const ( + maxThumbWidth = 512 + maxThumbHeight = 512 + ) + switch { // Simplest case, within bounds! case width < maxThumbWidth && |