// File: dannye[P]jed/src/decoder.cpp
// Function: readHuffmanTable(BitReader&, JPGImage*)
void readHuffmanTable(BitReader& bitReader, JPGImage* const image) {
    std::cout << "Reading DHT Marker\n";
    int length = bitReader.readWord();
    length -= 2;

    while (length > 0) {
        byte tableInfo = bitReader.readByte();
        byte tableID = tableInfo & 0x0F;
        bool acTable = tableInfo >> 4;

        if (tableID > 3) {
            std::cout << "Error - Invalid Huffman table ID: " << (uint)tableID << '\n';
            image->valid = false;
            return;
        }

        HuffmanTable& hTable = (acTable) ?
            (image->huffmanACTables[tableID]) :
            (image->huffmanDCTables[tableID]);
        hTable.set = true;

        hTable.offsets[0] = 0;
        uint allSymbols = 0;
        for (uint i = 1; i <= 16; ++i) {
            allSymbols += bitReader.readByte();
            hTable.offsets[i] = allSymbols;
        }
        if (allSymbols > 176) {
            std::cout << "Error - Too many symbols in Huffman table: " << allSymbols << '\n';
            image->valid = false;
            return;
        }

        for (uint i = 0; i < allSymbols; ++i) {
            hTable.symbols[i] = bitReader.readByte();
        }

        generateCodes(hTable);

        length -= 17 + allSymbols;
    }

    if (length != 0) {
        std::cout << "Error - DHT invalid\n";
        image->valid = false;
        return;
    }
}

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movq 0x9143(%rip), %rdi      # 0xbfd8
leaq 0x635f(%rip), %rsi      # 0x91fb
callq 0x2110
movq 0x30(%rsp), %rdi
callq 0x7a40
movl %eax, 0x24(%rsp)
movl 0x24(%rsp), %eax
subl $0x2, %eax
movl %eax, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
jle 0x3084
movq 0x30(%rsp), %rdi
callq 0x7a80
movb %al, 0x23(%rsp)
movzbl 0x23(%rsp), %eax
andl $0xf, %eax
movb %al, 0x22(%rsp)
movzbl 0x23(%rsp), %eax
sarl $0x4, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x21(%rsp)
movzbl 0x22(%rsp), %eax
cmpl $0x3, %eax
jle 0x2f3b
movq 0x90d4(%rip), %rdi      # 0xbfd8
leaq 0x6304(%rip), %rsi      # 0x920f
callq 0x2110
movq %rax, %rdi
movzbl 0x22(%rsp), %esi
callq 0x21b0
movq %rax, %rdi
movl $0xa, %esi
callq 0x2160
movq 0x28(%rsp), %rax
movb $0x0, 0x2088(%rax)
jmp 0x30aa
testb $0x1, 0x21(%rsp)
je 0x2f62
movq 0x28(%rsp), %rax
addq $0x1230, %rax           # imm = 0x1230
movzbl 0x22(%rsp), %ecx
imulq $0x388, %rcx, %rcx      # imm = 0x388
addq %rcx, %rax
movq %rax, (%rsp)
jmp 0x2f80
movq 0x28(%rsp), %rax
addq $0x410, %rax            # imm = 0x410
movzbl 0x22(%rsp), %ecx
imulq $0x388, %rcx, %rcx      # imm = 0x388
addq %rcx, %rax
movq %rax, (%rsp)
movq (%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
movb $0x1, 0x384(%rax)
movq 0x18(%rsp), %rax
movb $0x0, (%rax)
movl $0x0, 0x14(%rsp)
movl $0x1, 0x10(%rsp)
cmpl $0x10, 0x10(%rsp)
ja 0x2fe8
movq 0x30(%rsp), %rdi
callq 0x7a80
movzbl %al, %eax
addl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x14(%rsp), %eax
movb %al, %dl
movq 0x18(%rsp), %rax
movl 0x10(%rsp), %ecx
movb %dl, (%rax,%rcx)
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x2fad
cmpl $0xb0, 0x14(%rsp)
jbe 0x302c
movq 0x8fdf(%rip), %rdi      # 0xbfd8
leaq 0x6232(%rip), %rsi      # 0x9232
callq 0x2110
movq %rax, %rdi
movl 0x14(%rsp), %esi
callq 0x21b0
movq %rax, %rdi
movl $0xa, %esi
callq 0x2160
movq 0x28(%rsp), %rax
movb $0x0, 0x2088(%rax)
jmp 0x30aa
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
cmpl 0x14(%rsp), %eax
jae 0x3064
movq 0x30(%rsp), %rdi
callq 0x7a80
movb %al, %dl
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movb %dl, 0x11(%rax,%rcx)
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x3034
movq 0x18(%rsp), %rdi
callq 0x2df0
movl 0x14(%rsp), %ecx
addl $0x11, %ecx
movl 0x24(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x24(%rsp)
jmp 0x2eba
cmpl $0x0, 0x24(%rsp)
je 0x30aa
movq 0x8f46(%rip), %rdi      # 0xbfd8
leaq 0x61c5(%rip), %rsi      # 0x925e
callq 0x2110
movq 0x28(%rsp), %rax
movb $0x0, 0x2088(%rax)
addq $0x38, %rsp
retq
nop