(ctx context.Context, fileRef blob.Ref)
| 257 | } |
| 258 | |
| 259 | func (ih *ImageHandler) scaleImage(ctx context.Context, fileRef blob.Ref) (*formatAndImage, error) { |
| 260 | fr, err := ih.newFileReader(ctx, fileRef) |
| 261 | if err != nil { |
| 262 | return nil, err |
| 263 | } |
| 264 | defer fr.Close() |
| 265 | |
| 266 | sr := readerutil.NewStatsReader(imageBytesFetchedVar, fr) |
| 267 | sr, conf, err := imageConfigFromReader(sr) |
| 268 | if err == images.ErrHEIC { |
| 269 | jpegBytes, err := images.HEIFToJPEG(sr, &images.Dimensions{MaxWidth: ih.MaxWidth, MaxHeight: ih.MaxHeight}) |
| 270 | if err != nil { |
| 271 | log.Printf("cannot convert with heiftojpeg: %v", err) |
| 272 | return nil, errors.New("error converting HEIC image to jpeg") |
| 273 | } |
| 274 | return &formatAndImage{format: "jpeg", image: jpegBytes}, nil |
| 275 | } |
| 276 | if err != nil { |
| 277 | return nil, err |
| 278 | } |
| 279 | |
| 280 | // TODO(wathiede): build a size table keyed by conf.ColorModel for |
| 281 | // common color models for a more exact size estimate. |
| 282 | |
| 283 | // This value is an estimate of the memory required to decode an image. |
| 284 | // PNGs range from 1-64 bits per pixel (not all of which are supported by |
| 285 | // the Go standard parser). JPEGs encoded in YCbCr 4:4:4 are 3 byte/pixel. |
| 286 | // For all other JPEGs this is an overestimate. For GIFs it is 3x larger |
| 287 | // than needed. How accurate this estimate is depends on the mix of |
| 288 | // images being resized concurrently. |
| 289 | ramSize := int64(conf.Width) * int64(conf.Height) * 3 |
| 290 | |
| 291 | if err = ih.ResizeSem.Acquire(ramSize); err != nil { |
| 292 | return nil, err |
| 293 | } |
| 294 | defer ih.ResizeSem.Release(ramSize) |
| 295 | |
| 296 | i, imConfig, err := images.Decode(sr, &images.DecodeOpts{ |
| 297 | MaxWidth: ih.MaxWidth, |
| 298 | MaxHeight: ih.MaxHeight, |
| 299 | }) |
| 300 | if err != nil { |
| 301 | return nil, err |
| 302 | } |
| 303 | b := i.Bounds() |
| 304 | format := imConfig.Format |
| 305 | |
| 306 | isSquare := b.Dx() == b.Dy() |
| 307 | if ih.Square && !isSquare { |
| 308 | i = squareImage(i) |
| 309 | b = i.Bounds() |
| 310 | _ = b |
| 311 | } |
| 312 | |
| 313 | // Encode as a new image |
| 314 | var buf bytes.Buffer |
| 315 | switch format { |
| 316 | case "png": |
no test coverage detected