github.com/bluenviron/mediacommon@v1.9.3/pkg/codecs/jpeg/start_of_frame1.go (about) 1 package jpeg 2 3 import ( 4 "fmt" 5 ) 6 7 // StartOfFrame1 is a SOF1 marker. 8 type StartOfFrame1 struct { 9 Type uint8 10 Width int 11 Height int 12 QuantizationTableCount uint8 // write only 13 } 14 15 // Unmarshal decodes the marker. 16 func (m *StartOfFrame1) Unmarshal(buf []byte) error { 17 if len(buf) != 15 { 18 return fmt.Errorf("unsupported SOF size of %d", len(buf)) 19 } 20 21 precision := buf[0] 22 if precision != 8 { 23 return fmt.Errorf("precision %d is not supported", precision) 24 } 25 26 m.Height = int(buf[1])<<8 | int(buf[2]) 27 m.Width = int(buf[3])<<8 | int(buf[4]) 28 29 components := buf[5] 30 if components != 3 { 31 return fmt.Errorf("number of components = %d is not supported", components) 32 } 33 34 samp0 := buf[7] 35 switch samp0 { 36 case 0x21: 37 m.Type = 0 38 39 case 0x22: 40 m.Type = 1 41 42 default: 43 return fmt.Errorf("samp0 %x is not supported", samp0) 44 } 45 46 samp1 := buf[10] 47 if samp1 != 0x11 { 48 return fmt.Errorf("samp1 %x is not supported", samp1) 49 } 50 51 samp2 := buf[13] 52 if samp2 != 0x11 { 53 return fmt.Errorf("samp2 %x is not supported", samp2) 54 } 55 56 return nil 57 } 58 59 // Marshal encodes the marker. 60 func (m StartOfFrame1) Marshal(buf []byte) []byte { 61 buf = append(buf, []byte{0xFF, MarkerStartOfFrame1}...) 62 buf = append(buf, []byte{0, 17}...) // length 63 buf = append(buf, []byte{8}...) // precision 64 buf = append(buf, []byte{byte(m.Height >> 8), byte(m.Height)}...) // height 65 buf = append(buf, []byte{byte(m.Width >> 8), byte(m.Width)}...) // width 66 buf = append(buf, []byte{3}...) // components 67 if (m.Type & 0x3f) == 0 { // component 0 68 buf = append(buf, []byte{0x00, 0x21, 0}...) 69 } else { 70 buf = append(buf, []byte{0x00, 0x22, 0}...) 71 } 72 73 var secondQuantizationTable byte 74 if m.QuantizationTableCount == 2 { 75 secondQuantizationTable = 1 76 } else { 77 secondQuantizationTable = 0 78 } 79 80 buf = append(buf, []byte{1, 0x11, secondQuantizationTable}...) // component 1 81 buf = append(buf, []byte{2, 0x11, secondQuantizationTable}...) // component 2 82 return buf 83 }