// File: /workspace/github_cpp_makefile_star2_O3/dannye[P]jed/src/encoder.cpp
// Function: encodeBlockComponent(BitWriter&, int*, int&, HuffmanTable const&, HuffmanTable const&)
bool encodeBlockComponent(
    BitWriter& bitWriter,
    int* const component,
    int& previousDC,
    const HuffmanTable& dcTable,
    const HuffmanTable& acTable
) {
    // encode DC value
    int coeff = component[0] - previousDC;
    previousDC = component[0];

    uint coeffLength = bitLength(std::abs(coeff));
    if (coeffLength > 11) {
        std::cout << "Error - DC coefficient length greater than 11\n";
        return false;
    }
    if (coeff < 0) {
        coeff += (1 << coeffLength) - 1;
    }

    uint code = 0;
    uint codeLength = 0;
    if (!getCode(dcTable, coeffLength, code, codeLength)) {
        std::cout << "Error - Invalid DC value\n";
        return false;
    }
    bitWriter.writeBits(code, codeLength);
    bitWriter.writeBits(coeff, coeffLength);

    // encode AC values
    for (uint i = 1; i < 64; ++i) {
        // find zero run length
        byte numZeroes = 0;
        while (i < 64 && component[zigZagMap[i]] == 0) {
            numZeroes += 1;
            i += 1;
        }

        if (i == 64) {
            if (!getCode(acTable, 0x00, code, codeLength)) {
                std::cout << "Error - Invalid AC value\n";
                return false;
            }
            bitWriter.writeBits(code, codeLength);
            return true;
        }

        while (numZeroes >= 16) {
            if (!getCode(acTable, 0xF0, code, codeLength)) {
                std::cout << "Error - Invalid AC value\n";
                return false;
            }
            bitWriter.writeBits(code, codeLength);
            numZeroes -= 16;
        }

        // find coeff length
        coeff = component[zigZagMap[i]];
        coeffLength = bitLength(std::abs(coeff));
        if (coeffLength > 10) {
            std::cout << "Error - AC coefficient length greater than 10\n";
            return false;
        }
        if (coeff < 0) {
            coeff += (1 << coeffLength) - 1;
        }

        // find symbol in table
        byte symbol = numZeroes << 4 | coeffLength;
        if (!getCode(acTable, symbol, code, codeLength)) {
            std::cout << "Error - Invalid AC value\n";
            return false;
        }
        bitWriter.writeBits(code, codeLength);
        bitWriter.writeBits(coeff, coeffLength);
    }

    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, %r14
movq %rcx, %rax
movq %rdi, %rbx
movq %rsi, 0x10(%rsp)
movl (%rsi), %ecx
xorl %r12d, %r12d
movl %ecx, %esi
movl $0x0, %ebp
subl (%rdx), %esi
movl %ecx, (%rdx)
je 0x31cc
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movl %ecx, %edx
shrl %edx
incl %ebp
cmpl $0x1, %ecx
movl %edx, %ecx
ja 0x31a2
cmpl $0xb, %ebp
jb 0x31ca
movq 0x3e1f(%rip), %rdi      # 0x6fd8
leaq 0x1feb(%rip), %rsi      # 0x51ab
movl $0x2e, %edx
jmp 0x34bb
incl %ebp
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %ebp, %ecx
shll %cl, %edx
notl %edx
movl %esi, %r15d
sarl $0x1f, %r15d
andl %edx, %r15d
addl %esi, %r15d
movb (%rax), %cl
movb $0x1, %dl
xorl %esi, %esi
movl %ecx, %edi
movb 0x1(%rax,%rsi), %cl
cmpb %cl, %dil
jae 0x320c
movzbl %cl, %r8d
movzbl %dil, %edi
cmpb %bpl, 0x11(%rax,%rdi)
je 0x3228
incq %rdi
cmpq %rdi, %r8
jne 0x31fd
cmpq $0xf, %rsi
leaq 0x1(%rsi), %rdi
setb %dl
incl %r12d
movq %rdi, %rsi
cmpq $0x10, %rdi
jne 0x31ea
jmp 0x342c
testb $0x1, %dl
je 0x342c
movl 0xc4(%rax,%rdi,4), %r13d
movl %r13d, %esi
movl %r12d, %ecx
shrl %cl, %esi
movq %rbx, %rdi
callq 0x3f68
addl $-0x1, %r12d
jb 0x3239
testl %ebp, %ebp
je 0x3269
decl %ebp
movl %r15d, %esi
movl %ebp, %ecx
shrl %cl, %esi
movq %rbx, %rdi
callq 0x3f68
addl $-0x1, %ebp
jb 0x3255
movl $0x1, %ecx
leaq 0x206b(%rip), %rdx      # 0x52e0
movl %ecx, %r13d
xorl %r15d, %r15d
movq 0x10(%rsp), %rcx
movzbl (%r13,%rdx), %eax
cmpl $0x0, (%rcx,%rax,4)
jne 0x32a1
incb %r15b
leaq 0x1(%r13), %rax
cmpq $0x3f, %r13
movq %rax, %r13
jb 0x3280
jmp 0x343c
cmpb $0x10, %r15b
jb 0x3320
movb (%r14), %al
movb $0x1, %cl
xorl %r12d, %r12d
xorl %edx, %edx
movl %eax, %esi
movb 0x1(%r14,%rdx), %al
cmpb %al, %sil
jae 0x32d4
movzbl %al, %edi
movzbl %sil, %esi
cmpb $-0x10, 0x11(%r14,%rsi)
je 0x32f0
incq %rsi
cmpq %rsi, %rdi
jne 0x32c4
cmpq $0xf, %rdx
leaq 0x1(%rdx), %rsi
setb %cl
incl %r12d
movq %rsi, %rdx
cmpq $0x10, %rsi
jne 0x32b1
jmp 0x34a8
testb $0x1, %cl
je 0x34a8
movl 0xc4(%r14,%rsi,4), %ebp
movl %ebp, %esi
movl %r12d, %ecx
shrl %cl, %esi
movq %rbx, %rdi
callq 0x3f68
addl $-0x1, %r12d
jb 0x3301
addb $-0x10, %r15b
cmpb $0xf, %r15b
ja 0x32a7
movl %r13d, %eax
leaq 0x1fb6(%rip), %rcx      # 0x52e0
movzbl (%rax,%rcx), %eax
movq 0x10(%rsp), %rcx
movl (%rcx,%rax,4), %eax
xorl %r12d, %r12d
movl $0x0, %ebp
testl %eax, %eax
je 0x3366
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movl %ecx, %edx
shrl %edx
incl %ebp
cmpl $0x1, %ecx
movl %edx, %ecx
ja 0x3350
cmpl $0xa, %ebp
jae 0x34d1
incl %ebp
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %ebp, %ecx
shll %cl, %edx
notl %edx
movl %eax, %ecx
sarl $0x1f, %ecx
andl %edx, %ecx
addl %eax, %ecx
movl %ecx, 0xc(%rsp)
shlb $0x4, %r15b
addb %bpl, %r15b
movb (%r14), %al
movb $0x1, %cl
xorl %edx, %edx
movl %eax, %esi
movb 0x1(%r14,%rdx), %al
cmpb %al, %sil
jae 0x33ae
movzbl %al, %edi
movzbl %sil, %esi
cmpb %r15b, 0x11(%r14,%rsi)
je 0x33ca
incq %rsi
cmpq %rsi, %rdi
jne 0x339f
cmpq $0xf, %rdx
leaq 0x1(%rdx), %rsi
setb %cl
incl %r12d
movq %rsi, %rdx
cmpq $0x10, %rsi
jne 0x338c
jmp 0x34a8
testb $0x1, %cl
je 0x34a8
movl 0xc4(%r14,%rsi,4), %r15d
movl %r15d, %esi
movl %r12d, %ecx
shrl %cl, %esi
movq %rbx, %rdi
callq 0x3f68
addl $-0x1, %r12d
jb 0x33db
testl %ebp, %ebp
movl 0xc(%rsp), %r15d
je 0x3410
decl %ebp
movl %r15d, %esi
movl %ebp, %ecx
shrl %cl, %esi
movq %rbx, %rdi
callq 0x3f68
addl $-0x1, %ebp
jb 0x33fc
leaq 0x1(%r13), %rcx
movb $0x1, %al
cmpq $0x3f, %r13
leaq 0x1ebf(%rip), %rdx      # 0x52e0
jb 0x3275
jmp 0x34c2
movq 0x3ba5(%rip), %rdi      # 0x6fd8
leaq 0x1da0(%rip), %rsi      # 0x51da
jmp 0x34b6
movb (%r14), %al
movb $0x1, %cl
xorl %r15d, %r15d
xorl %edx, %edx
movl %eax, %esi
movb 0x1(%r14,%rdx), %al
cmpb %al, %sil
jae 0x3469
movzbl %al, %edi
movzbl %sil, %esi
cmpb $0x0, 0x11(%r14,%rsi)
je 0x3482
incq %rsi
cmpq %rsi, %rdi
jne 0x3459
cmpq $0xf, %rdx
leaq 0x1(%rdx), %rsi
setb %cl
incl %r15d
movq %rsi, %rdx
cmpq $0x10, %rsi
jne 0x3446
jmp 0x34a8
testb $0x1, %cl
je 0x34a8
movl 0xc4(%r14,%rsi,4), %ebp
movl %ebp, %esi
movl %r15d, %ecx
shrl %cl, %esi
movq %rbx, %rdi
callq 0x3f68
addl $-0x1, %r15d
jb 0x348f
movb $0x1, %al
jmp 0x34c2
movq 0x3b29(%rip), %rdi      # 0x6fd8
leaq 0x1d3e(%rip), %rsi      # 0x51f4
movl $0x19, %edx
callq 0x2120
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x3b00(%rip), %rdi      # 0x6fd8
leaq 0x1d2f(%rip), %rsi      # 0x520e
jmp 0x31c0