blob: bf1bc3ec0f8bcb73a4c7ce8385cfde5ada8d284a [file]
// Copyright 2026 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//go:build ignore
// +build ignore
package main
// print-riff-chunks.go prints a RIFF's chunks' position and type.
//
// ANI, AVI, WAV and WEBP files are all RIFF files.
//
// Usage: go run print-riff-chunks.go foo.webp
import (
"flag"
"fmt"
"os"
)
func main() {
if err := main1(); err != nil {
os.Stderr.WriteString(err.Error() + "\n")
os.Exit(1)
}
}
func main1() error {
flag.Parse()
args := flag.Args()
if len(args) != 1 {
return fmt.Errorf("usage: progname filename.riff")
}
src, err := os.ReadFile(args[0])
if err != nil {
return err
}
pos := 0
if len(src) < 12 {
return posError(pos, len(src))
} else if len(src) > 0x7FFF_FFFF {
return fmt.Errorf("RIFF file is too large")
}
chunkLen := int64(u32le(src[pos+4 : pos+8]))
if int64(len(src)-8) < chunkLen {
return posError(0, len(src))
}
fmt.Printf("pos = 0x%08X = %10d (+8) len = 0x%08X = %10d RIFF/%s\n",
0, 0, chunkLen, chunkLen, clean(src[8:12]))
pos = 12
for pos < len(src) {
if pos > (len(src) - 8) {
return posError(pos, len(src))
}
n := int64(u32le(src[pos+4 : pos+8]))
fmt.Printf("pos = 0x%08X = %10d (+8) len = 0x%08X = %10d %s\n",
pos, pos, n, n, clean(src[pos:pos+4]))
pos += 8
if (n & 1) != 0 {
n++
}
if int64(len(src)-pos) < n {
return posError(pos, len(src))
}
pos += int(n)
}
fmt.Printf("pos = 0x%08X = %10d ~~~~\n",
pos, pos)
return nil
}
func posError(pos int, lenSrc int) error {
return fmt.Errorf("bad RIFF, pos = 0x%08X = %10d, len(src) = 0x%08X = %10d",
pos, pos, lenSrc, lenSrc)
}
func clean(b []byte) string {
a := [4]byte{}
for i, c := range b[:4] {
if (c < '!') || ('~' < c) {
c = '.'
}
a[i] = c
}
return string(a[:4])
}
func u32le(b []byte) uint32 {
return (uint32(b[0]) << 0) |
(uint32(b[1]) << 8) |
(uint32(b[2]) << 16) |
(uint32(b[3]) << 24)
}