diff options
Diffstat (limited to 'internal/media/media.go')
-rw-r--r-- | internal/media/media.go | 110 |
1 files changed, 70 insertions, 40 deletions
diff --git a/internal/media/media.go b/internal/media/media.go index aa11787b2..022de063e 100644 --- a/internal/media/media.go +++ b/internal/media/media.go @@ -33,15 +33,15 @@ type Media struct { below fields represent the processing state of the media thumbnail */ - thumbing processState - thumb *ImageMeta + thumbstate processState + thumb *ImageMeta /* below fields represent the processing state of the full-sized media */ - processing processState - processed *ImageMeta + fullSizeState processState + fullSize *ImageMeta /* below pointers to database and storage are maintained so that @@ -58,20 +58,20 @@ func (m *Media) Thumb(ctx context.Context) (*ImageMeta, error) { m.mu.Lock() defer m.mu.Unlock() - switch m.thumbing { + switch m.thumbstate { case received: // we haven't processed a thumbnail for this media yet so do it now thumb, err := deriveThumbnail(m.rawData, m.attachment.File.ContentType) if err != nil { m.err = fmt.Errorf("error deriving thumbnail: %s", err) - m.thumbing = errored + m.thumbstate = errored return nil, m.err } // put the thumbnail in storage if err := m.storage.Put(m.attachment.Thumbnail.Path, thumb.image); err != nil { m.err = fmt.Errorf("error storing thumbnail: %s", err) - m.thumbing = errored + m.thumbstate = errored return nil, m.err } @@ -89,12 +89,12 @@ func (m *Media) Thumb(ctx context.Context) (*ImageMeta, error) { if err := m.database.Put(ctx, m.attachment); err != nil { if err != db.ErrAlreadyExists { m.err = fmt.Errorf("error putting attachment: %s", err) - m.thumbing = errored + m.thumbstate = errored return nil, m.err } if err := m.database.UpdateByPrimaryKey(ctx, m.attachment); err != nil { m.err = fmt.Errorf("error updating attachment: %s", err) - m.thumbing = errored + m.thumbstate = errored return nil, m.err } } @@ -103,7 +103,7 @@ func (m *Media) Thumb(ctx context.Context) (*ImageMeta, error) { m.thumb = thumb // we're done processing the thumbnail! - m.thumbing = complete + m.thumbstate = complete fallthrough case complete: return m.thumb, nil @@ -111,46 +111,76 @@ func (m *Media) Thumb(ctx context.Context) (*ImageMeta, error) { return nil, m.err } - return nil, fmt.Errorf("thumbnail processing status %d unknown", m.thumbing) + return nil, fmt.Errorf("thumbnail processing status %d unknown", m.thumbstate) } -func (m *Media) Full(ctx context.Context) (*ImageMeta, error) { - var clean []byte - var err error - var original *ImageMeta - - ct := m.attachment.File.ContentType -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - switch ct { - case mimeImageJpeg, mimeImagePng: - // first 'clean' image by purging exif data from it - var exifErr error - if clean, exifErr = purgeExif(m.rawData); exifErr != nil { - return nil, fmt.Errorf("error cleaning exif data: %s", exifErr) +func (m *Media) FullSize(ctx context.Context) (*ImageMeta, error) { + m.mu.Lock() + defer m.mu.Unlock() + + switch m.fullSizeState { + case received: + var clean []byte + var err error + var decoded *ImageMeta + + ct := m.attachment.File.ContentType + switch ct { + case mimeImageJpeg, mimeImagePng: + // first 'clean' image by purging exif data from it + var exifErr error + if clean, exifErr = purgeExif(m.rawData); exifErr != nil { + err = exifErr + break + } + decoded, err = decodeImage(clean, ct) + case mimeImageGif: + // gifs are already clean - no exif data to remove + clean = m.rawData + decoded, err = decodeGif(clean) + default: + err = fmt.Errorf("content type %s not a processible image type", ct) } - original, err = decodeImage(clean, ct) - case mimeImageGif: - // gifs are already clean - no exif data to remove - clean = m.rawData - original, err = decodeGif(clean) - default: - err = fmt.Errorf("content type %s not a processible image type", ct) - } - if err != nil { - return nil, err + if err != nil { + m.err = err + m.fullSizeState = errored + return nil, err + } + + // set the fullsize of this media + m.fullSize = decoded + + // we're done processing the full-size image + m.fullSizeState = complete + fallthrough + case complete: + return m.fullSize, nil + case errored: + return nil, m.err } - return original, nil + return nil, fmt.Errorf("full size processing status %d unknown", m.fullSizeState) } +// PreLoad begins the process of deriving the thumbnail and encoding the full-size image. +// It does this in a non-blocking way, so you can call it and then come back later and check +// if it's finished. func (m *Media) PreLoad(ctx context.Context) { go m.Thumb(ctx) - m.mu.Lock() - defer m.mu.Unlock() + go m.FullSize(ctx) } -func (m *Media) Load() { - m.mu.Lock() - defer m.mu.Unlock() +// Load is the blocking equivalent of pre-load. It makes sure the thumbnail and full-size image +// have been processed, then it returns the full-size image. +func (m *Media) Load(ctx context.Context) (*gtsmodel.MediaAttachment, error) { + if _, err := m.Thumb(ctx); err != nil { + return nil, err + } + + if _, err := m.FullSize(ctx); err != nil { + return nil, err + } + + return m.attachment, nil } |