imageConfigFromReader calls image.DecodeConfig on r. It returns an io.Reader that is the concatenation of the bytes read and the remaining r, the image configuration, and the error from image.DecodeConfig. If the image is HEIC, and its config was decoded properly (but partially, because we don't do
(r io.Reader)
| 220 | // If the image is HEIC, and its config was decoded properly (but partially, |
| 221 | // because we don't do ColorModel yet), it returns images.ErrHEIC. |
| 222 | func imageConfigFromReader(r io.Reader) (io.Reader, image.Config, error) { |
| 223 | header := new(bytes.Buffer) |
| 224 | tr := io.TeeReader(r, header) |
| 225 | // We just need width & height for memory considerations, so we use the |
| 226 | // standard library's DecodeConfig, skipping the EXIF parsing and |
| 227 | // orientation correction for images.DecodeConfig. |
| 228 | // image.DecodeConfig is able to deal with HEIC because we registered it |
| 229 | // in internal/images. |
| 230 | conf, format, err := image.DecodeConfig(tr) |
| 231 | if err == nil && format == "heic" { |
| 232 | err = images.ErrHEIC |
| 233 | } |
| 234 | return io.MultiReader(header, r), conf, err |
| 235 | } |
| 236 | |
| 237 | func (ih *ImageHandler) newFileReader(ctx context.Context, fileRef blob.Ref) (io.ReadCloser, error) { |
| 238 | fi, ok := fileInfoPacked(ctx, ih.Search, ih.Fetcher, nil, fileRef) |