// File: /workspace/github_cpp_makefile_star2_O3/dannye[P]jed/src/decoder.cpp
// Function: readStartOfFrame(BitReader&, JPGImage*)
void readStartOfFrame(BitReader& bitReader, JPGImage* const image) {
    std::cout << "Reading SOF Marker\n";
    if (image->numComponents != 0) {
        std::cout << "Error - Multiple SOFs detected\n";
        image->valid = false;
        return;
    }

    uint length = bitReader.readWord();

    byte precision = bitReader.readByte();
    if (precision != 8) {
        std::cout << "Error - Invalid precision: " << (uint)precision << '\n';
        image->valid = false;
        return;
    }

    image->height = bitReader.readWord();
    image->width = bitReader.readWord();
    if (image->height == 0 || image->width == 0) {
        std::cout << "Error - Invalid dimensions\n";
        image->valid = false;
        return;
    }
    image->blockHeight = (image->height + 7) / 8;
    image->blockWidth = (image->width + 7) / 8;
    image->blockHeightReal = image->blockHeight;
    image->blockWidthReal = image->blockWidth;

    image->numComponents = bitReader.readByte();
    if (image->numComponents == 4) {
        std::cout << "Error - CMYK color mode not supported\n";
        image->valid = false;
        return;
    }
    if (image->numComponents != 1 && image->numComponents != 3) {
        std::cout << "Error - " << (uint)image->numComponents << " color components given (1 or 3 required)\n";
        image->valid = false;
        return;
    }
    for (uint i = 0; i < image->numComponents; ++i) {
        byte componentID = bitReader.readByte();
        // component IDs are usually 1, 2, 3 but rarely can be seen as 0, 1, 2
        // always force them into 1, 2, 3 for consistency
        if (componentID == 0 && i == 0) {
            image->zeroBased = true;
        }
        if (image->zeroBased) {
            componentID += 1;
        }
        if (componentID == 0 || componentID > image->numComponents) {
            std::cout << "Error - Invalid component ID: " << (uint)componentID << '\n';
            image->valid = false;
            return;
        }
        ColorComponent& component = image->colorComponents[componentID - 1];
        if (component.usedInFrame) {
            std::cout << "Error - Duplicate color component ID: " << (uint)componentID << '\n';
            image->valid = false;
            return;
        }
        component.usedInFrame = true;

        byte samplingFactor = bitReader.readByte();
        component.horizontalSamplingFactor = samplingFactor >> 4;
        component.verticalSamplingFactor = samplingFactor & 0x0F;
        if (componentID == 1) {
            if ((component.horizontalSamplingFactor != 1 && component.horizontalSamplingFactor != 2) ||
                (component.verticalSamplingFactor != 1 && component.verticalSamplingFactor != 2)) {
                std::cout << "Error - Sampling factors not supported\n";
                image->valid = false;
                return;
            }
            if (component.horizontalSamplingFactor == 2 && image->blockWidth % 2 == 1) {
                image->blockWidthReal += 1;
            }
            if (component.verticalSamplingFactor == 2 && image->blockHeight % 2 == 1) {
                image->blockHeightReal += 1;
            }
            image->horizontalSamplingFactor = component.horizontalSamplingFactor;
            image->verticalSamplingFactor = component.verticalSamplingFactor;
        }
        else {
            if (component.horizontalSamplingFactor != 1 || component.verticalSamplingFactor != 1) {
                std::cout << "Error - Sampling factors not supported\n";
                image->valid = false;
                return;
            }
        }

        component.quantizationTableID = bitReader.readByte();
        if (component.quantizationTableID > 3) {
            std::cout << "Error - Invalid quantization table ID: " << (uint)component.quantizationTableID << '\n';
            image->valid = false;
            return;
        }
    }

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

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movq 0x7bf1(%rip), %rdi      # 0x9fd8
leaq 0x4d56(%rip), %rsi      # 0x7144
movl $0x13, %edx
callq 0x2130
cmpb $0x0, 0x2070(%rbx)
je 0x2419
movq 0x7bd0(%rip), %rdi      # 0x9fd8
leaq 0x4d49(%rip), %rsi      # 0x7158
movl $0x1f, %edx
jmp 0x24f7
xorl %ebp, %ebp
movb %bpl, 0x1(%r14)
leaq 0x8(%r14), %r15
movq %r15, %rdi
callq 0x2140
movl %eax, 0xc(%rsp)
movq %r15, %rdi
callq 0x2140
movl %eax, 0x8(%rsp)
movb %bpl, 0x1(%r14)
movq %r15, %rdi
callq 0x2140
movzbl %al, %ebp
cmpl $0x8, %ebp
jne 0x24c2
xorl %ebp, %ebp
movb %bpl, 0x1(%r14)
movq %r15, %rdi
callq 0x2140
movl %eax, %r13d
shll $0x8, %r13d
movq %r15, %rdi
callq 0x2140
addl %r13d, %eax
movl %eax, 0x2068(%rbx)
movb %bpl, 0x1(%r14)
movq %r15, %rdi
callq 0x2140
movl %eax, %r13d
shll $0x8, %r13d
movq %r15, %rdi
callq 0x2140
movl 0x2068(%rbx), %ecx
testl %ecx, %ecx
setne %dl
addl %r13d, %eax
movl %eax, 0x206c(%rbx)
setne %sil
testb %dl, %sil
jne 0x2512
movq 0x7b24(%rip), %rdi      # 0x9fd8
leaq 0x4cd9(%rip), %rsi      # 0x7194
movl $0x1b, %edx
jmp 0x24f7
movq 0x7b0f(%rip), %r14      # 0x9fd8
leaq 0x4ca8(%rip), %rsi      # 0x7178
movl $0x1b, %edx
movq %r14, %rdi
callq 0x2130
movl %ebp, %esi
movq %r14, %rdi
callq 0x20a0
leaq 0x4(%rsp), %rsi
movb $0xa, (%rsi)
movl $0x1, %edx
movq %rax, %rdi
callq 0x2130
movb $0x0, 0x2088(%rbx)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movd %eax, %xmm0
movd %ecx, %xmm1
punpckldq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
pshufd $0x44, %xmm1, %xmm0     # xmm0 = xmm1[0,1,0,1]
paddd 0x4ae5(%rip), %xmm0     # 0x7010
psrld $0x3, %xmm0
movdqu %xmm0, 0x208c(%rbx)
movb $0x0, 0x1(%r14)
movq %r15, %rdi
callq 0x2140
movb %al, 0x2070(%rbx)
cmpb $0x1, %al
je 0x2575
movzbl %al, %eax
cmpl $0x3, %eax
je 0x2575
cmpl $0x4, %eax
jne 0x26d2
movq 0x7a71(%rip), %rdi      # 0x9fd8
leaq 0x4c42(%rip), %rsi      # 0x71b0
movl $0x26, %edx
jmp 0x24f7
leaq 0x2050(%rbx), %rax
movq %rax, 0x10(%rsp)
xorl %ebp, %ebp
movb $0x0, 0x1(%r14)
movq %r15, %rdi
callq 0x2140
testb %al, %al
sete %cl
testl %ebp, %ebp
sete %dl
testb %cl, %dl
je 0x25a9
movb $0x1, 0x2071(%rbx)
movb $0x1, %cl
jmp 0x25af
movb 0x2071(%rbx), %cl
addb %al, %cl
je 0x270d
movzbl %cl, %r13d
cmpb 0x2070(%rbx), %r13b
ja 0x2710
leal -0x1(%r13), %eax
leaq (,%rax,8), %r12
subq %rax, %r12
movq 0x10(%rsp), %rax
cmpb $0x1, 0x5(%rax,%r12)
je 0x2740
addq %rax, %r12
movb $0x1, 0x5(%r12)
movb $0x0, 0x1(%r14)
movq %r15, %rdi
callq 0x2140
movl %eax, %ecx
shrb $0x4, %cl
movb %cl, (%r12)
andb $0xf, %al
movb %al, 0x1(%r12)
cmpl $0x1, %r13d
jne 0x2661
leal -0x1(%rcx), %edx
cmpb $0x1, %dl
ja 0x2770
leal -0x1(%rax), %edx
cmpb $0x2, %dl
jae 0x2770
cmpb $0x2, %cl
jne 0x2640
testb $0x1, 0x2090(%rbx)
je 0x2640
incl 0x2098(%rbx)
cmpb $0x2, %al
jne 0x2653
testb $0x1, 0x208c(%rbx)
je 0x2653
incl 0x2094(%rbx)
movb %cl, 0x209c(%rbx)
movb %al, 0x209d(%rbx)
jmp 0x2672
cmpb $0x1, %cl
jne 0x2770
cmpb $0x1, %al
jne 0x2770
movb $0x0, 0x1(%r14)
movq %r15, %rdi
callq 0x2140
movb %al, 0x2(%r12)
cmpb $0x4, %al
jae 0x2788
incl %ebp
movzbl 0x2070(%rbx), %eax
cmpl %eax, %ebp
jb 0x2583
leal (%rax,%rax,2), %eax
movl 0xc(%rsp), %edx
shll $0x8, %edx
addl 0x8(%rsp), %edx
movl $0x8, %ecx
subl %edx, %ecx
addl %eax, %ecx
je 0x2503
movq 0x7917(%rip), %rdi      # 0x9fd8
leaq 0x4bd9(%rip), %rsi      # 0x72a1
movl $0x14, %edx
jmp 0x24f7
movq 0x78ff(%rip), %r14      # 0x9fd8
leaq 0x4af7(%rip), %rsi      # 0x71d7
movl $0x8, %edx
movq %r14, %rdi
callq 0x2130
movzbl 0x2070(%rbx), %esi
movq %r14, %rdi
callq 0x20a0
leaq 0x4add(%rip), %rsi      # 0x71e0
movl $0x2a, %edx
jmp 0x24f4
xorl %r13d, %r13d
movq 0x78c1(%rip), %r14      # 0x9fd8
leaq 0x4aed(%rip), %rsi      # 0x720b
movl $0x1e, %edx
movq %r14, %rdi
callq 0x2130
movq %r14, %rdi
movq %r13, %rsi
callq 0x20a0
leaq 0x5(%rsp), %rsi
jmp 0x24ec
movq 0x7891(%rip), %r14      # 0x9fd8
leaq 0x4adc(%rip), %rsi      # 0x722a
movl $0x26, %edx
movq %r14, %rdi
callq 0x2130
movq %r14, %rdi
movq %r13, %rsi
callq 0x20a0
leaq 0x6(%rsp), %rsi
jmp 0x24ec
movq 0x7861(%rip), %rdi      # 0x9fd8
leaq 0x4ad3(%rip), %rsi      # 0x7251
movl $0x27, %edx
jmp 0x24f7
movq 0x7849(%rip), %r14      # 0x9fd8
leaq 0x4ae3(%rip), %rsi      # 0x7279
movl $0x27, %edx
movq %r14, %rdi
callq 0x2130
movzbl 0x2(%r12), %esi
movq %r14, %rdi
callq 0x20a0
leaq 0x7(%rsp), %rsi
jmp 0x24ec