123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // Copyright 2011 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Original code was cropped and fixed by @DarthSim for imgproxy needs
- package imagemeta
- import (
- "io"
- "github.com/imgproxy/imgproxy/v3/imagetype"
- "golang.org/x/image/riff"
- "golang.org/x/image/vp8"
- "golang.org/x/image/vp8l"
- )
- var (
- webpFccALPH = riff.FourCC{'A', 'L', 'P', 'H'}
- webpFccVP8 = riff.FourCC{'V', 'P', '8', ' '}
- webpFccVP8L = riff.FourCC{'V', 'P', '8', 'L'}
- webpFccVP8X = riff.FourCC{'V', 'P', '8', 'X'}
- webpFccWEBP = riff.FourCC{'W', 'E', 'B', 'P'}
- )
- func DecodeWebpMeta(r io.Reader) (Meta, error) {
- formType, riffReader, err := riff.NewReader(r)
- if err != nil {
- return nil, err
- }
- if formType != webpFccWEBP {
- return nil, newFormatError("WEBP", "invalid form type")
- }
- var buf [10]byte
- for {
- chunkID, chunkLen, chunkData, err := riffReader.Next()
- if err == io.EOF {
- err = newFormatError("WEBP", "no VP8, VP8L or VP8X chunk found")
- }
- if err != nil {
- return nil, err
- }
- switch chunkID {
- case webpFccALPH:
- // Ignore
- case webpFccVP8:
- if int32(chunkLen) < 0 {
- return nil, newFormatError("WEBP", "invalid chunk length")
- }
- d := vp8.NewDecoder()
- d.Init(chunkData, int(chunkLen))
- fh, err := d.DecodeFrameHeader()
- return &meta{
- format: imagetype.WEBP,
- width: fh.Width,
- height: fh.Height,
- }, err
- case webpFccVP8L:
- conf, err := vp8l.DecodeConfig(chunkData)
- if err != nil {
- return nil, err
- }
- return &meta{
- format: imagetype.WEBP,
- width: conf.Width,
- height: conf.Height,
- }, nil
- case webpFccVP8X:
- if chunkLen != 10 {
- return nil, newFormatError("WEBP", "invalid chunk length")
- }
- if _, err := io.ReadFull(chunkData, buf[:10]); err != nil {
- return nil, err
- }
- widthMinusOne := uint32(buf[4]) | uint32(buf[5])<<8 | uint32(buf[6])<<16
- heightMinusOne := uint32(buf[7]) | uint32(buf[8])<<8 | uint32(buf[9])<<16
- return &meta{
- format: imagetype.WEBP,
- width: int(widthMinusOne) + 1,
- height: int(heightMinusOne) + 1,
- }, nil
- default:
- return nil, newFormatError("WEBP", "unknown chunk")
- }
- }
- }
- func init() {
- RegisterFormat("RIFF????WEBPVP8", DecodeWebpMeta)
- }
|