Files
gortsplib/pkg/codecs/jpeg/start_of_frame1.go

84 lines
2.1 KiB
Go

package jpeg
import (
"fmt"
)
// StartOfFrame1 is a SOF1 marker.
type StartOfFrame1 struct {
Type uint8
Width int
Height int
QuantizationTableCount uint8 // write only
}
// Unmarshal decodes the marker.
func (m *StartOfFrame1) Unmarshal(buf []byte) error {
if len(buf) != 15 {
return fmt.Errorf("unsupported SOF size of %d", len(buf))
}
precision := buf[0]
if precision != 8 {
return fmt.Errorf("precision %d is not supported", precision)
}
m.Height = int(buf[1])<<8 | int(buf[2])
m.Width = int(buf[3])<<8 | int(buf[4])
components := buf[5]
if components != 3 {
return fmt.Errorf("number of components = %d is not supported", components)
}
samp0 := buf[7]
switch samp0 {
case 0x21:
m.Type = 0
case 0x22:
m.Type = 1
default:
return fmt.Errorf("samp0 %x is not supported", samp0)
}
samp1 := buf[10]
if samp1 != 0x11 {
return fmt.Errorf("samp1 %x is not supported", samp1)
}
samp2 := buf[13]
if samp2 != 0x11 {
return fmt.Errorf("samp2 %x is not supported", samp2)
}
return nil
}
// Marshal encodes the marker.
func (m StartOfFrame1) Marshal(buf []byte) []byte {
buf = append(buf, []byte{0xFF, MarkerStartOfFrame1}...)
buf = append(buf, []byte{0, 17}...) // length
buf = append(buf, []byte{8}...) // precision
buf = append(buf, []byte{byte(m.Height >> 8), byte(m.Height)}...) // height
buf = append(buf, []byte{byte(m.Width >> 8), byte(m.Width)}...) // width
buf = append(buf, []byte{3}...) // components
if (m.Type & 0x3f) == 0 { // component 0
buf = append(buf, []byte{0x00, 0x21, 0}...)
} else {
buf = append(buf, []byte{0x00, 0x22, 0}...)
}
var secondQuantizationTable byte
if m.QuantizationTableCount == 2 {
secondQuantizationTable = 1
} else {
secondQuantizationTable = 0
}
buf = append(buf, []byte{1, 0x11, secondQuantizationTable}...) // component 1
buf = append(buf, []byte{2, 0x11, secondQuantizationTable}...) // component 2
return buf
}