riff.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package riff implements the Resource Interchange File Format, used by media
  5. // formats such as AVI, WAVE and WEBP.
  6. //
  7. // A RIFF stream contains a sequence of chunks. Each chunk consists of an 8-byte
  8. // header (containing a 4-byte chunk type and a 4-byte chunk length), the chunk
  9. // data (presented as an io.Reader), and some padding bytes.
  10. //
  11. // A detailed description of the format is at
  12. // http://www.tactilemedia.com/info/MCI_Control_Info.html
  13. package riff // import "golang.org/x/image/riff"
  14. import (
  15. "errors"
  16. "io"
  17. "io/ioutil"
  18. "math"
  19. )
  20. var (
  21. errMissingPaddingByte = errors.New("riff: missing padding byte")
  22. errMissingRIFFChunkHeader = errors.New("riff: missing RIFF chunk header")
  23. errListSubchunkTooLong = errors.New("riff: list subchunk too long")
  24. errShortChunkData = errors.New("riff: short chunk data")
  25. errShortChunkHeader = errors.New("riff: short chunk header")
  26. errStaleReader = errors.New("riff: stale reader")
  27. )
  28. // u32 decodes the first four bytes of b as a little-endian integer.
  29. func u32(b []byte) uint32 {
  30. return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
  31. }
  32. const chunkHeaderSize = 8
  33. // FourCC is a four character code.
  34. type FourCC [4]byte
  35. // LIST is the "LIST" FourCC.
  36. var LIST = FourCC{'L', 'I', 'S', 'T'}
  37. // NewReader returns the RIFF stream's form type, such as "AVI " or "WAVE", and
  38. // its chunks as a *Reader.
  39. func NewReader(r io.Reader) (formType FourCC, data *Reader, err error) {
  40. var buf [chunkHeaderSize]byte
  41. if _, err := io.ReadFull(r, buf[:]); err != nil {
  42. if err == io.EOF || err == io.ErrUnexpectedEOF {
  43. err = errMissingRIFFChunkHeader
  44. }
  45. return FourCC{}, nil, err
  46. }
  47. if buf[0] != 'R' || buf[1] != 'I' || buf[2] != 'F' || buf[3] != 'F' {
  48. return FourCC{}, nil, errMissingRIFFChunkHeader
  49. }
  50. return NewListReader(u32(buf[4:]), r)
  51. }
  52. // NewListReader returns a LIST chunk's list type, such as "movi" or "wavl",
  53. // and its chunks as a *Reader.
  54. func NewListReader(chunkLen uint32, chunkData io.Reader) (listType FourCC, data *Reader, err error) {
  55. if chunkLen < 4 {
  56. return FourCC{}, nil, errShortChunkData
  57. }
  58. z := &Reader{r: chunkData}
  59. if _, err := io.ReadFull(chunkData, z.buf[:4]); err != nil {
  60. if err == io.EOF || err == io.ErrUnexpectedEOF {
  61. err = errShortChunkData
  62. }
  63. return FourCC{}, nil, err
  64. }
  65. z.totalLen = chunkLen - 4
  66. return FourCC{z.buf[0], z.buf[1], z.buf[2], z.buf[3]}, z, nil
  67. }
  68. // Reader reads chunks from an underlying io.Reader.
  69. type Reader struct {
  70. r io.Reader
  71. err error
  72. totalLen uint32
  73. chunkLen uint32
  74. chunkReader *chunkReader
  75. buf [chunkHeaderSize]byte
  76. padded bool
  77. }
  78. // Next returns the next chunk's ID, length and data. It returns io.EOF if there
  79. // are no more chunks. The io.Reader returned becomes stale after the next Next
  80. // call, and should no longer be used.
  81. //
  82. // It is valid to call Next even if all of the previous chunk's data has not
  83. // been read.
  84. func (z *Reader) Next() (chunkID FourCC, chunkLen uint32, chunkData io.Reader, err error) {
  85. if z.err != nil {
  86. return FourCC{}, 0, nil, z.err
  87. }
  88. // Drain the rest of the previous chunk.
  89. if z.chunkLen != 0 {
  90. want := z.chunkLen
  91. var got int64
  92. got, z.err = io.Copy(ioutil.Discard, z.chunkReader)
  93. if z.err == nil && uint32(got) != want {
  94. z.err = errShortChunkData
  95. }
  96. if z.err != nil {
  97. return FourCC{}, 0, nil, z.err
  98. }
  99. }
  100. z.chunkReader = nil
  101. if z.padded {
  102. if z.totalLen == 0 {
  103. z.err = errListSubchunkTooLong
  104. return FourCC{}, 0, nil, z.err
  105. }
  106. z.totalLen--
  107. _, z.err = io.ReadFull(z.r, z.buf[:1])
  108. if z.err != nil {
  109. if z.err == io.EOF {
  110. z.err = errMissingPaddingByte
  111. }
  112. return FourCC{}, 0, nil, z.err
  113. }
  114. }
  115. // We are done if we have no more data.
  116. if z.totalLen == 0 {
  117. z.err = io.EOF
  118. return FourCC{}, 0, nil, z.err
  119. }
  120. // Read the next chunk header.
  121. if z.totalLen < chunkHeaderSize {
  122. z.err = errShortChunkHeader
  123. return FourCC{}, 0, nil, z.err
  124. }
  125. z.totalLen -= chunkHeaderSize
  126. if _, z.err = io.ReadFull(z.r, z.buf[:chunkHeaderSize]); z.err != nil {
  127. if z.err == io.EOF || z.err == io.ErrUnexpectedEOF {
  128. z.err = errShortChunkHeader
  129. }
  130. return FourCC{}, 0, nil, z.err
  131. }
  132. chunkID = FourCC{z.buf[0], z.buf[1], z.buf[2], z.buf[3]}
  133. z.chunkLen = u32(z.buf[4:])
  134. if z.chunkLen > z.totalLen {
  135. z.err = errListSubchunkTooLong
  136. return FourCC{}, 0, nil, z.err
  137. }
  138. z.padded = z.chunkLen&1 == 1
  139. z.chunkReader = &chunkReader{z}
  140. return chunkID, z.chunkLen, z.chunkReader, nil
  141. }
  142. type chunkReader struct {
  143. z *Reader
  144. }
  145. func (c *chunkReader) Read(p []byte) (int, error) {
  146. if c != c.z.chunkReader {
  147. return 0, errStaleReader
  148. }
  149. z := c.z
  150. if z.err != nil {
  151. if z.err == io.EOF {
  152. return 0, errStaleReader
  153. }
  154. return 0, z.err
  155. }
  156. n := int(z.chunkLen)
  157. if n == 0 {
  158. return 0, io.EOF
  159. }
  160. if n < 0 {
  161. // Converting uint32 to int overflowed.
  162. n = math.MaxInt32
  163. }
  164. if n > len(p) {
  165. n = len(p)
  166. }
  167. n, err := z.r.Read(p[:n])
  168. z.totalLen -= uint32(n)
  169. z.chunkLen -= uint32(n)
  170. if err != io.EOF {
  171. z.err = err
  172. }
  173. return n, err
  174. }