func decodeMetadataChunk()

in shiny/iconvg/decode.go [145:233]


func decodeMetadataChunk(p printer, m *Metadata, src buffer, opts *DecodeOptions) (src1 buffer, err error) {
	length, n := src.decodeNatural()
	if n == 0 {
		return nil, errInvalidMetadataChunkLength
	}
	if p != nil {
		p(src[:n], "Metadata chunk length: %d\n", length)
	}
	src = src[n:]
	lenSrcWant := int64(len(src)) - int64(length)

	mid, n := src.decodeNatural()
	if n == 0 {
		return nil, errInvalidMetadataIdentifier
	}
	if mid >= uint32(len(midDescriptions)) {
		return nil, errUnsupportedMetadataIdentifier
	}
	if p != nil {
		p(src[:n], "Metadata Identifier: %d (%s)\n", mid, midDescriptions[mid])
	}
	src = src[n:]

	switch mid {
	case midViewBox:
		if m.ViewBox.Min[0], src, err = decodeNumber(p, src, buffer.decodeCoordinate); err != nil {
			return nil, errInvalidViewBox
		}
		if m.ViewBox.Min[1], src, err = decodeNumber(p, src, buffer.decodeCoordinate); err != nil {
			return nil, errInvalidViewBox
		}
		if m.ViewBox.Max[0], src, err = decodeNumber(p, src, buffer.decodeCoordinate); err != nil {
			return nil, errInvalidViewBox
		}
		if m.ViewBox.Max[1], src, err = decodeNumber(p, src, buffer.decodeCoordinate); err != nil {
			return nil, errInvalidViewBox
		}
		if m.ViewBox.Min[0] > m.ViewBox.Max[0] || m.ViewBox.Min[1] > m.ViewBox.Max[1] ||
			isNaNOrInfinity(m.ViewBox.Min[0]) || isNaNOrInfinity(m.ViewBox.Min[1]) ||
			isNaNOrInfinity(m.ViewBox.Max[0]) || isNaNOrInfinity(m.ViewBox.Max[1]) {
			return nil, errInvalidViewBox
		}

	case midSuggestedPalette:
		if len(src) == 0 {
			return nil, errInvalidSuggestedPalette
		}
		length, format := 1+int(src[0]&0x3f), src[0]>>6
		decode := buffer.decodeColor4
		switch format {
		case 0:
			decode = buffer.decodeColor1
		case 1:
			decode = buffer.decodeColor2
		case 2:
			decode = buffer.decodeColor3Direct
		}
		if p != nil {
			p(src[:1], "    %d palette colors, %d bytes per color\n", length, 1+format)
		}
		src = src[1:]

		for i := 0; i < length; i++ {
			c, n := decode(src)
			if n == 0 {
				return nil, errInvalidSuggestedPalette
			}
			rgba := c.rgba()
			if c.typ != ColorTypeRGBA || !validAlphaPremulColor(rgba) {
				rgba = color.RGBA{0x00, 0x00, 0x00, 0xff}
			}
			if p != nil {
				p(src[:n], "    RGBA %02x%02x%02x%02x\n", rgba.R, rgba.G, rgba.B, rgba.A)
			}
			src = src[n:]
			if opts == nil || opts.Palette == nil {
				m.Palette[i] = rgba
			}
		}

	default:
		return nil, errUnsupportedMetadataIdentifier
	}

	if int64(len(src)) != lenSrcWant {
		return nil, errInconsistentMetadataChunkLength
	}
	return src, nil
}