// File: dannye[P]jed/src/decoder.cpp
// Function: readScans(BitReader&, JPGImage*)
void readScans(BitReader& bitReader, JPGImage* const image) {
    // decode first scan
    readStartOfScan(bitReader, image);
    if (!image->valid) {
        return;
    }
    printScanInfo(image);
    decodeHuffmanData(bitReader, image);

    byte last = bitReader.readByte();
    byte current = bitReader.readByte();

    // decode additional scans, if any
    while (image->valid) {
        if (!bitReader.hasBits()) {
            std::cout << "Error - File ended prematurely\n";
            image->valid = false;
            return;
        }
        if (last != 0xFF) {
            std::cout << "Error - Expected a marker\n";
            image->valid = false;
            return;
        }

        // end of image
        if (current == EOI) {
            break;
        }
        // huffman tables (progressive only)
        else if (current == DHT && image->frameType == SOF2) {
            readHuffmanTable(bitReader, image);
        }
        // additional scans (progressive only)
        else if (current == SOS && image->frameType == SOF2) {
            readStartOfScan(bitReader, image);
            if (!image->valid) {
                return;
            }
            printScanInfo(image);
            decodeHuffmanData(bitReader, image);
        }
        // new restart interval (progressive only)
        else if (current == DRI && image->frameType == SOF2) {
            readRestartInterval(bitReader, image);
        }
        // restart marker, perhaps from the very end of previous scan
        else if (current >= RST0 && current <= RST7) {
            // RSTN has no size
        }
        // ignore multiple 0xFF's in a row
        else if (current == 0xFF) {
            current = bitReader.readByte();
            continue;
        }
        else {
            std::cout << "Error - Invalid marker: 0x" << std::hex << (uint)current << std::dec << '\n';
            image->valid = false;
            return;
        }
        last = bitReader.readByte();
        current = bitReader.readByte();
    }
}

// Assembly:
subq $0x18, %rsp
movq %rdi, 0x10(%rsp)
movq %rsi, 0x8(%rsp)
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x30b0
movq 0x8(%rsp), %rax
testb $0x1, 0x2088(%rax)
jne 0x47a0
jmp 0x49da
movq 0x8(%rsp), %rdi
callq 0x3d30
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x49e0
movq 0x10(%rsp), %rdi
callq 0x7a80
movb %al, 0x7(%rsp)
movq 0x10(%rsp), %rdi
callq 0x7a80
movb %al, 0x6(%rsp)
movq 0x8(%rsp), %rax
testb $0x1, 0x2088(%rax)
je 0x49da
movq 0x10(%rsp), %rdi
callq 0x7ae0
testb $0x1, %al
jne 0x4819
movq 0x77dc(%rip), %rdi      # 0xbfd8
leaq 0x4fb2(%rip), %rsi      # 0x97b5
callq 0x2110
movq 0x8(%rsp), %rax
movb $0x0, 0x2088(%rax)
jmp 0x49da
movzbl 0x7(%rsp), %eax
cmpl $0xff, %eax
je 0x4849
movq 0x77ac(%rip), %rdi      # 0xbfd8
leaq 0x4fa2(%rip), %rsi      # 0x97d5
callq 0x2110
movq 0x8(%rsp), %rax
movb $0x0, 0x2088(%rax)
jmp 0x49da
movzbl 0x6(%rsp), %eax
cmpl $0xd9, %eax
jne 0x485a
jmp 0x49da
movzbl 0x6(%rsp), %eax
cmpl $0xc4, %eax
jne 0x488d
movq 0x8(%rsp), %rax
movzbl 0x2065(%rax), %eax
cmpl $0xc2, %eax
jne 0x488d
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x2e80
jmp 0x49b7
movzbl 0x6(%rsp), %eax
cmpl $0xda, %eax
jne 0x48ec
movq 0x8(%rsp), %rax
movzbl 0x2065(%rax), %eax
cmpl $0xc2, %eax
jne 0x48ec
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x30b0
movq 0x8(%rsp), %rax
testb $0x1, 0x2088(%rax)
jne 0x48ce
jmp 0x49da
movq 0x8(%rsp), %rdi
callq 0x3d30
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x49e0
jmp 0x49b5
movzbl 0x6(%rsp), %eax
cmpl $0xdd, %eax
jne 0x491f
movq 0x8(%rsp), %rax
movzbl 0x2065(%rax), %eax
cmpl $0xc2, %eax
jne 0x491f
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x3830
jmp 0x49b3
movzbl 0x6(%rsp), %eax
cmpl $0xd0, %eax
jl 0x4939
movzbl 0x6(%rsp), %eax
cmpl $0xd7, %eax
jg 0x4939
jmp 0x49b1
movzbl 0x6(%rsp), %eax
cmpl $0xff, %eax
jne 0x4958
movq 0x10(%rsp), %rdi
callq 0x7a80
movb %al, 0x6(%rsp)
jmp 0x47d5
movq 0x7679(%rip), %rdi      # 0xbfd8
leaq 0x4f60(%rip), %rsi      # 0x98c6
callq 0x2110
movq %rax, %rdi
leaq 0x312b(%rip), %rsi      # 0x7aa0
callq 0x2050
movq %rax, %rdi
movzbl 0x6(%rsp), %esi
callq 0x21b0
movq %rax, %rdi
leaq 0x312f(%rip), %rsi      # 0x7ac0
callq 0x2050
movq %rax, %rdi
movl $0xa, %esi
callq 0x2160
movq 0x8(%rsp), %rax
movb $0x0, 0x2088(%rax)
jmp 0x49da
jmp 0x49b3
jmp 0x49b5
jmp 0x49b7
jmp 0x49b9
movq 0x10(%rsp), %rdi
callq 0x7a80
movb %al, 0x7(%rsp)
movq 0x10(%rsp), %rdi
callq 0x7a80
movb %al, 0x6(%rsp)
jmp 0x47d5
addq $0x18, %rsp
retq
nop