summaryrefslogtreecommitdiffstats
path: root/api/file.go
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2016-11-22 15:14:25 +0000
committerChristopher Speller <crspeller@gmail.com>2016-11-22 10:14:25 -0500
commite1fca412fc9c1f98f1682052fa8ce52166181a44 (patch)
tree19bb89069088c829cb87f9eafb806f92ef4849dd /api/file.go
parent3c65a20f4587da6315d47222b5d9852d7e5ad66f (diff)
downloadchat-e1fca412fc9c1f98f1682052fa8ce52166181a44.tar.gz
chat-e1fca412fc9c1f98f1682052fa8ce52166181a44.tar.bz2
chat-e1fca412fc9c1f98f1682052fa8ce52166181a44.zip
PLT-4442 Generate preview images sequentially in Slack importer (#4617)
* Break out image preparation to its own function. This is preparatory work to make it easier to handle the thumbnail image generation in a non-racy way in the Slack command line importer. * Build preview images sequentially in Slack import. This removes the use of goroutines from the image preview generation code run when importing Slack attachments. This slows things down, but it has important benefits: 1) Avoids a race condition with the goroutines and the command line exiting. 2) Avoids the problem of massive memory consumption when importing a Slack channel with a lot of large images attached in quick succession. Fixes PLT-4442. * Use mutliple return values instead of struct.
Diffstat (limited to 'api/file.go')
-rw-r--r--api/file.go85
1 files changed, 46 insertions, 39 deletions
diff --git a/api/file.go b/api/file.go
index dd075d3e0..8de69937a 100644
--- a/api/file.go
+++ b/api/file.go
@@ -195,50 +195,57 @@ func doUploadFile(teamId string, channelId string, userId string, rawFilename st
func handleImages(previewPathList []string, thumbnailPathList []string, fileData [][]byte) {
for i, data := range fileData {
go func(i int, data []byte) {
- // Decode image bytes into Image object
- img, imgType, err := image.Decode(bytes.NewReader(fileData[i]))
- if err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), err)
- return
- }
-
- width := img.Bounds().Dx()
- height := img.Bounds().Dy()
-
- // Fill in the background of a potentially-transparent png file as white
- if imgType == "png" {
- dst := image.NewRGBA(img.Bounds())
- draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
- draw.Draw(dst, dst.Bounds(), img, img.Bounds().Min, draw.Over)
- img = dst
- }
-
- // Flip the image to be upright
- orientation, _ := getImageOrientation(fileData[i])
-
- switch orientation {
- case UprightMirrored:
- img = imaging.FlipH(img)
- case UpsideDown:
- img = imaging.Rotate180(img)
- case UpsideDownMirrored:
- img = imaging.FlipV(img)
- case RotatedCWMirrored:
- img = imaging.Transpose(img)
- case RotatedCCW:
- img = imaging.Rotate270(img)
- case RotatedCCWMirrored:
- img = imaging.Transverse(img)
- case RotatedCW:
- img = imaging.Rotate90(img)
+ img, width, height := prepareImage(fileData[i])
+ if img != nil {
+ go generateThumbnailImage(*img, thumbnailPathList[i], width, height)
+ go generatePreviewImage(*img, previewPathList[i], width)
}
-
- go generateThumbnailImage(img, thumbnailPathList[i], width, height)
- go generatePreviewImage(img, previewPathList[i], width)
}(i, data)
}
}
+func prepareImage(fileData []byte) (*image.Image, int, int) {
+ // Decode image bytes into Image object
+ img, imgType, err := image.Decode(bytes.NewReader(fileData))
+ if err != nil {
+ l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), err)
+ return nil, 0, 0
+ }
+
+ width := img.Bounds().Dx()
+ height := img.Bounds().Dy()
+
+ // Fill in the background of a potentially-transparent png file as white
+ if imgType == "png" {
+ dst := image.NewRGBA(img.Bounds())
+ draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
+ draw.Draw(dst, dst.Bounds(), img, img.Bounds().Min, draw.Over)
+ img = dst
+ }
+
+ // Flip the image to be upright
+ orientation, _ := getImageOrientation(fileData)
+
+ switch orientation {
+ case UprightMirrored:
+ img = imaging.FlipH(img)
+ case UpsideDown:
+ img = imaging.Rotate180(img)
+ case UpsideDownMirrored:
+ img = imaging.FlipV(img)
+ case RotatedCWMirrored:
+ img = imaging.Transpose(img)
+ case RotatedCCW:
+ img = imaging.Rotate270(img)
+ case RotatedCCWMirrored:
+ img = imaging.Transverse(img)
+ case RotatedCW:
+ img = imaging.Rotate90(img)
+ }
+
+ return &img, width, height
+}
+
func getImageOrientation(imageData []byte) (int, error) {
if exifData, err := exif.Decode(bytes.NewReader(imageData)); err != nil {
return Upright, err