summaryrefslogtreecommitdiff
path: root/internal/media/util.go
diff options
context:
space:
mode:
authorLibravatar Tobi Smethurst <31960611+tsmethurst@users.noreply.github.com>2021-04-19 19:42:19 +0200
committerLibravatar GitHub <noreply@github.com>2021-04-19 19:42:19 +0200
commit32c5fd987a06e11b14a4247d13187657c14adedd (patch)
treef5b787ca0f020bea5fd020925e52d3592a77a6ad /internal/media/util.go
parentApi/v1/accounts (#8) (diff)
downloadgotosocial-32c5fd987a06e11b14a4247d13187657c14adedd.tar.xz
Api/v1/statuses (#11)
This PR adds: Statuses New status creation. View existing status Delete a status Fave a status Unfave a status See who's faved a status Media Upload media attachment and store/retrieve it Upload custom emoji and store/retrieve it Fileserver Serve files from storage Testing Test models, testrig -- run a GTS test instance and play around with it.
Diffstat (limited to 'internal/media/util.go')
-rw-r--r--internal/media/util.go125
1 files changed, 110 insertions, 15 deletions
diff --git a/internal/media/util.go b/internal/media/util.go
index 9ffb79a46..64d1ee770 100644
--- a/internal/media/util.go
+++ b/internal/media/util.go
@@ -70,6 +70,36 @@ func supportedImageType(mimeType string) bool {
return false
}
+// supportedVideoType checks mime type of a video against a slice of accepted types,
+// and returns True if the mime type is accepted.
+func supportedVideoType(mimeType string) bool {
+ acceptedVideoTypes := []string{
+ "video/mp4",
+ "video/mpeg",
+ "video/webm",
+ }
+ for _, accepted := range acceptedVideoTypes {
+ if mimeType == accepted {
+ return true
+ }
+ }
+ return false
+}
+
+// supportedEmojiType checks that the content type is image/png -- the only type supported for emoji.
+func supportedEmojiType(mimeType string) bool {
+ acceptedEmojiTypes := []string{
+ "image/gif",
+ "image/png",
+ }
+ for _, accepted := range acceptedEmojiTypes {
+ if mimeType == accepted {
+ return true
+ }
+ }
+ return false
+}
+
// purgeExif is a little wrapper for the action of removing exif data from an image.
// Only pass pngs or jpegs to this function.
func purgeExif(b []byte) ([]byte, error) {
@@ -87,11 +117,50 @@ func purgeExif(b []byte) ([]byte, error) {
return clean, nil
}
-func deriveImage(b []byte, extension string) (*imageAndMeta, error) {
+func deriveGif(b []byte, extension string) (*imageAndMeta, error) {
+ var g *gif.GIF
+ var err error
+ switch extension {
+ case "image/gif":
+ g, err = gif.DecodeAll(bytes.NewReader(b))
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, fmt.Errorf("extension %s not recognised", extension)
+ }
+
+ // use the first frame to get the static characteristics
+ width := g.Config.Width
+ height := g.Config.Height
+ size := width * height
+ aspect := float64(width) / float64(height)
+
+ bh, err := blurhash.Encode(4, 3, g.Image[0])
+ if err != nil || bh == "" {
+ return nil, err
+ }
+
+ out := &bytes.Buffer{}
+ if err := gif.EncodeAll(out, g); err != nil {
+ return nil, err
+ }
+
+ return &imageAndMeta{
+ image: out.Bytes(),
+ width: width,
+ height: height,
+ size: size,
+ aspect: aspect,
+ blurhash: bh,
+ }, nil
+}
+
+func deriveImage(b []byte, contentType string) (*imageAndMeta, error) {
var i image.Image
var err error
- switch extension {
+ switch contentType {
case "image/jpeg":
i, err = jpeg.Decode(bytes.NewReader(b))
if err != nil {
@@ -102,28 +171,25 @@ func deriveImage(b []byte, extension string) (*imageAndMeta, error) {
if err != nil {
return nil, err
}
- case "image/gif":
- i, err = gif.Decode(bytes.NewReader(b))
- if err != nil {
- return nil, err
- }
default:
- return nil, fmt.Errorf("extension %s not recognised", extension)
+ return nil, fmt.Errorf("content type %s not recognised", contentType)
}
width := i.Bounds().Size().X
height := i.Bounds().Size().Y
size := width * height
aspect := float64(width) / float64(height)
+
bh, err := blurhash.Encode(4, 3, i)
if err != nil {
- return nil, fmt.Errorf("error generating blurhash: %s", err)
+ return nil, err
}
out := &bytes.Buffer{}
if err := jpeg.Encode(out, i, nil); err != nil {
return nil, err
}
+
return &imageAndMeta{
image: out.Bytes(),
width: width,
@@ -134,16 +200,16 @@ func deriveImage(b []byte, extension string) (*imageAndMeta, error) {
}, nil
}
-// deriveThumbnailFromImage returns a byte slice and metadata for a 256-pixel-width thumbnail
+// deriveThumbnail returns a byte slice and metadata for a thumbnail of width x and height y,
// of a given jpeg, png, or gif, or an error if something goes wrong.
//
// Note that the aspect ratio of the image will be retained,
-// so it will not necessarily be a square.
-func deriveThumbnail(b []byte, extension string) (*imageAndMeta, error) {
+// so it will not necessarily be a square, even if x and y are set as the same value.
+func deriveThumbnail(b []byte, contentType string, x uint, y uint) (*imageAndMeta, error) {
var i image.Image
var err error
- switch extension {
+ switch contentType {
case "image/jpeg":
i, err = jpeg.Decode(bytes.NewReader(b))
if err != nil {
@@ -160,10 +226,10 @@ func deriveThumbnail(b []byte, extension string) (*imageAndMeta, error) {
return nil, err
}
default:
- return nil, fmt.Errorf("extension %s not recognised", extension)
+ return nil, fmt.Errorf("content type %s not recognised", contentType)
}
- thumb := resize.Thumbnail(256, 256, i, resize.NearestNeighbor)
+ thumb := resize.Thumbnail(x, y, i, resize.NearestNeighbor)
width := thumb.Bounds().Size().X
height := thumb.Bounds().Size().Y
size := width * height
@@ -182,6 +248,35 @@ func deriveThumbnail(b []byte, extension string) (*imageAndMeta, error) {
}, nil
}
+// deriveStaticEmojji takes a given gif or png of an emoji, decodes it, and re-encodes it as a static png.
+func deriveStaticEmoji(b []byte, contentType string) (*imageAndMeta, error) {
+ var i image.Image
+ var err error
+
+ switch contentType {
+ case "image/png":
+ i, err = png.Decode(bytes.NewReader(b))
+ if err != nil {
+ return nil, err
+ }
+ case "image/gif":
+ i, err = gif.Decode(bytes.NewReader(b))
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, fmt.Errorf("content type %s not allowed for emoji", contentType)
+ }
+
+ out := &bytes.Buffer{}
+ if err := png.Encode(out, i); err != nil {
+ return nil, err
+ }
+ return &imageAndMeta{
+ image: out.Bytes(),
+ }, nil
+}
+
type imageAndMeta struct {
image []byte
width int