// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movq 0x6bf4(%rip), %rdi      # 0x8fd8
leaq 0x3cb9(%rip), %rsi      # 0x60a4
callq 0x20e0
cmpb $0x0, 0x2070(%rbx)
je 0x2411
movq 0x6bd8(%rip), %rdi      # 0x8fd8
leaq 0x3cb1(%rip), %rsi      # 0x60b8
callq 0x20e0
jmp 0x2496
movq %r14, %rdi
callq 0x4fd4
movl %eax, %ebp
movq %r14, %rdi
callq 0x5000
cmpb $0x8, %al
jne 0x2469
movq %r14, %rdi
callq 0x4fd4
movl %eax, 0x2068(%rbx)
movq %r14, %rdi
callq 0x4fd4
movl %eax, 0x206c(%rbx)
movl 0x2068(%rbx), %ecx
testl %ecx, %ecx
setne %dl
testl %eax, %eax
setne %sil
testb %dl, %sil
jne 0x24ac
movq 0x6b78(%rip), %rdi      # 0x8fd8
leaq 0x3c8d(%rip), %rsi      # 0x60f4
jmp 0x2407
movl %eax, %r15d
movq 0x6b65(%rip), %rdi      # 0x8fd8
leaq 0x3c5e(%rip), %rsi      # 0x60d8
callq 0x20e0
movzbl %r15b, %esi
movq %rax, %rdi
callq 0x20a0
pushq $0xa
popq %rsi
movq %rax, %rdi
callq 0x2120
movb $0x0, 0x2088(%rbx)
addq $0x8, %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 0x3b4b(%rip), %xmm0     # 0x6010
psrld $0x3, %xmm0
movdqu %xmm0, 0x208c(%rbx)
movq %r14, %rdi
callq 0x5000
movb %al, 0x2070(%rbx)
cmpb $0x1, %al
je 0x2508
movzbl %al, %eax
cmpl $0x3, %eax
je 0x2508
movq 0x6ae5(%rip), %rdi      # 0x8fd8
cmpl $0x4, %eax
jne 0x262e
leaq 0x3c0d(%rip), %rsi      # 0x6110
jmp 0x2407
movl %ebp, 0x4(%rsp)
leaq 0x2050(%rbx), %r13
xorl %r15d, %r15d
movzbl 0x2070(%rbx), %eax
cmpl %eax, %r15d
jae 0x2658
movq %r14, %rdi
callq 0x5000
testb %al, %al
sete %cl
testl %r15d, %r15d
sete %dl
testb %cl, %dl
je 0x2548
movb $0x1, 0x2071(%rbx)
movb $0x1, %cl
jmp 0x254e
movb 0x2071(%rbx), %cl
addb %al, %cl
je 0x267d
movzbl %cl, %r12d
cmpb 0x2070(%rbx), %r12b
ja 0x2680
leal -0x1(%r12), %eax
imulq $0x7, %rax, %rbp
cmpb $0x1, 0x5(%r13,%rbp)
je 0x2690
addq %r13, %rbp
movb $0x1, 0x5(%rbp)
movq %r14, %rdi
callq 0x5000
movl %eax, %ecx
shrb $0x4, %cl
movb %cl, (%rbp)
andb $0xf, %al
movb %al, 0x1(%rbp)
cmpl $0x1, %r12d
jne 0x25eb
leal -0x1(%rcx), %edx
cmpb $0x1, %dl
ja 0x26ae
leal -0x1(%rax), %edx
cmpb $0x2, %dl
jae 0x26ae
cmpb $0x2, %cl
jne 0x25ca
testb $0x1, 0x2090(%rbx)
je 0x25ca
incl 0x2098(%rbx)
cmpb $0x2, %al
jne 0x25dd
testb $0x1, 0x208c(%rbx)
je 0x25dd
incl 0x2094(%rbx)
movb %cl, 0x209c(%rbx)
movb %al, 0x209d(%rbx)
jmp 0x25fc
cmpb $0x1, %cl
jne 0x26ae
cmpb $0x1, %al
jne 0x26ae
movq %r14, %rdi
callq 0x5000
movb %al, 0x2(%rbp)
incl %r15d
cmpb $0x4, %al
jb 0x2516
movq 0x69bf(%rip), %rdi      # 0x8fd8
leaq 0x3bb9(%rip), %rsi      # 0x61d9
callq 0x20e0
movzbl 0x2(%rbp), %esi
jmp 0x2483
leaq 0x3b02(%rip), %rsi      # 0x6137
callq 0x20e0
movzbl 0x2070(%rbx), %esi
movq %rax, %rdi
callq 0x20a0
leaq 0x3af0(%rip), %rsi      # 0x6140
movq %rax, %rdi
jmp 0x2407
imull $-0x3, %eax, %eax
pushq $0x8
popq %rcx
subl 0x4(%rsp), %ecx
cmpl %ecx, %eax
je 0x249d
movq 0x6967(%rip), %rdi      # 0x8fd8
leaq 0x3b89(%rip), %rsi      # 0x6201
jmp 0x2407
xorl %r12d, %r12d
movq 0x6951(%rip), %rdi      # 0x8fd8
leaq 0x3add(%rip), %rsi      # 0x616b
jmp 0x269e
movq 0x6941(%rip), %rdi      # 0x8fd8
leaq 0x3aec(%rip), %rsi      # 0x618a
callq 0x20e0
movq %rax, %rdi
movq %r12, %rsi
jmp 0x2486
movq 0x6923(%rip), %rdi      # 0x8fd8
leaq 0x3af5(%rip), %rsi      # 0x61b1
jmp 0x2407