From d77f85b7dfae7a4c5acbb67e76a2fc59d567e1de Mon Sep 17 00:00:00 2001 From: Samuel Hawksby-Robinson Date: Thu, 1 Oct 2020 17:47:34 +0100 Subject: [PATCH] Added file decoding reused protocol file type detection --- go.mod | 2 + go.sum | 2 + images/files.go | 96 ++++++++++++++++++++++++++++------------- images/meta.go | 4 +- protocol/images/type.go | 35 +++------------ 5 files changed, 78 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index 3f24e2b72..ca9d4bc36 100644 --- a/go.mod +++ b/go.mod @@ -73,6 +73,8 @@ require ( go.uber.org/zap v1.13.0 golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect + golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 // indirect + golang.org/x/text v0.3.3 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/tools v0.0.0-20200211045251-2de505fc5306 // indirect google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect diff --git a/go.sum b/go.sum index 513da8c68..173750744 100644 --- a/go.sum +++ b/go.sum @@ -861,6 +861,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/images/files.go b/images/files.go index 31cdb1808..d5842266d 100644 --- a/images/files.go +++ b/images/files.go @@ -1,10 +1,16 @@ package images import ( + "errors" "image" + "image/gif" "image/jpeg" + "image/png" "io" + "net/http" "os" + + "golang.org/x/image/webp" ) func Get(fileName string) (image.Image, error) { @@ -14,19 +20,28 @@ func Get(fileName string) (image.Image, error) { } defer file.Close() - switch getFileType(file) { - case JPEG: - err = decodeJpeg(file) - break - case PNG: - err = decodePng(file) - break - case WEBP: - err = decodeWebp(file) - break + fb := make([]byte, 12) + file.Read(fb) + ft := GetFileType(fb) + if ft == UNKNOWN { + return nil, errors.New("unsupported file type") } - img, err := jpeg.Decode(file) + var img image.Image + switch ft { + case JPEG: + img, err = jpeg.Decode(file) + break + case PNG: + img, err = png.Decode(file) + break + case GIF: + img, err = gif.Decode(file) + break + case WEBP: + img, err = webp.Decode(file) + break + } if err != nil { return nil, err } @@ -34,6 +49,45 @@ func Get(fileName string) (image.Image, error) { return img, nil } +func GetFileType(buf []byte) FileType { + switch { + case isJpeg(buf): + return JPEG + case isPng(buf): + return PNG + case isGif(buf): + return GIF + case isWebp(buf): + return WEBP + default: + return UNKNOWN + } +} + +func isJpeg(buf []byte) bool { + return len(buf) > 2 && + buf[0] == 0xFF && + buf[1] == 0xD8 && + buf[2] == 0xFF +} + +func isPng(buf []byte) bool { + return len(buf) > 3 && + buf[0] == 0x89 && buf[1] == 0x50 && + buf[2] == 0x4E && buf[3] == 0x47 +} + +func isGif(buf []byte) bool { + return len(buf) > 2 && + buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46 +} + +func isWebp(buf []byte) bool { + return len(buf) > 11 && + buf[8] == 0x57 && buf[9] == 0x45 && + buf[10] == 0x42 && buf[11] == 0x50 +} + func Render(img image.Image, imgDetail *Details) error { out, err := os.Create(imgDetail.FileName) if err != nil { @@ -52,26 +106,6 @@ func Render(img image.Image, imgDetail *Details) error { return nil } -func getFileType(file *os.File) FileType { - // TODO - return JPEG -} - -func decodeJpeg(file *os.File) error { - // TODO - return nil -} - -func decodePng(file *os.File) error { - // TODO - return nil -} - -func decodeWebp(file *os.File) error { - // TODO - return nil -} - func renderJpeg(w io.Writer, m image.Image, imgDetail *Details) error { o := new(jpeg.Options) o.Quality = imgDetail.Quality diff --git a/images/meta.go b/images/meta.go index 19168414a..5ec20159b 100644 --- a/images/meta.go +++ b/images/meta.go @@ -6,8 +6,10 @@ import ( ) const ( + UNKNOWN FileType = 1 + iota + // Raster image types - JPEG FileType = 1 + iota + JPEG PNG GIF WEBP diff --git a/protocol/images/type.go b/protocol/images/type.go index 91c7a174b..b64ccb95d 100644 --- a/protocol/images/type.go +++ b/protocol/images/type.go @@ -1,42 +1,19 @@ package images import ( + "github.com/status-im/status-go/images" "github.com/status-im/status-go/protocol/protobuf" ) -func jpeg(buf []byte) bool { - return len(buf) > 2 && - buf[0] == 0xFF && - buf[1] == 0xD8 && - buf[2] == 0xFF -} - -func png(buf []byte) bool { - return len(buf) > 3 && - buf[0] == 0x89 && buf[1] == 0x50 && - buf[2] == 0x4E && buf[3] == 0x47 -} - -func gif(buf []byte) bool { - return len(buf) > 2 && - buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46 -} - -func webp(buf []byte) bool { - return len(buf) > 11 && - buf[8] == 0x57 && buf[9] == 0x45 && - buf[10] == 0x42 && buf[11] == 0x50 -} - func ImageType(buf []byte) protobuf.ImageMessage_ImageType { - switch { - case jpeg(buf): + switch images.GetFileType(buf){ + case images.JPEG: return protobuf.ImageMessage_JPEG - case png(buf): + case images.PNG: return protobuf.ImageMessage_PNG - case gif(buf): + case images.GIF: return protobuf.ImageMessage_GIF - case webp(buf): + case images.WEBP: return protobuf.ImageMessage_WEBP default: return protobuf.ImageMessage_UNKNOWN_IMAGE_TYPE