The Start Of Scan segment names which components are in this scan and which Huffman tables decode each. Today you read it, the last header before the raw entropy stream.
Read a baseline SOS header - the component count, each component's DC and AC table selectors, and the spectral parameters.
SOS (Start Of Scan, marker 0xDA) is the final header. It lists the components in this scan and, for each, a byte packing the DC table selector (Td, high nibble) and AC table selector (Ta, low nibble) - so the decoder knows which of the Huffman tables from the DHT segments to use for each component’s DC and AC coefficients. After the per-component selectors come three bytes: Ss and Se, the first and last spectral coefficient in this scan, and a byte holding the successive-approximation bits Ah and Al.
For baseline JPEG these three are fixed: Ss = 0, Se = 63 (every coefficient, DC through the last AC), and Ah = Al = 0 (no successive approximation). Progressive JPEG varies them to send coefficients in multiple passes, but that mode is out of scope here, and seeing anything but 0, 63, 0 is a sign of an image this codec does not handle. The moment this header ends, the raw entropy-coded bitstream begins - and that stream is what the rest of this chapter decodes.
// SOS (0xDA) payload:// 1 byte number of scan components Ns// per component: id byte, then (Td<<4 | Ta) selector byte// 1 byte Ss (0) 1 byte Se (63) 1 byte (Ah<<4 | Al) (0x00)// entropy-coded data begins immediately after this header.type ScanComp struct{ ID, Td, Ta byte }