// File: /workspace/github_c_makefile_star2_O3/dolphinking[P]slimox/src/slimox-main.c
// Function: main
int main(int argc, char** argv) {
    enum {
        OPERATION_INVALID,
        OPERATION_COMP,
        OPERATION_DECOMP,
        OPERATION_PACK,
        OPERATION_UNPACK,
    } operation = OPERATION_INVALID;

    char option;
    uint32_t block_size = 16777216; /* 16MB by default */
    ppm_model_t* ppm = ppm_model_new();
    buf_t* ib = buf_new();
    buf_t* ob = buf_new();
    struct timeval time_start;
    struct timeval time_end;
    double cost_time;

    /* timer start */
    gettimeofday(&time_start, NULL);

#if defined(_WIN32) || defined(_WIN64)
    /* we need to set stdin/stdout to binary mode under windows */
    setmode(fileno(stdin), O_BINARY);
    setmode(fileno(stdout), O_BINARY);
#endif

    /* process args */
    while(argc > 1 && sscanf(argv[1], "-%c", &option) > 0) {
        if(option == 'q') { /* quiet mode */
            fclose(stderr);
            memmove(&argv[1], &argv[2], (--argc) * sizeof(*argv));
            continue;
        }
        if(option == 'b') { /* set blocksize */
            if(sscanf(argv[1] + 2, "%d", &block_size) > 0) {
                block_size *= 1048576;
            } else {
                fprintf(stderr, "error: Invalid blocksize\n");
                exit(-1);
            }
            memmove(&argv[1], &argv[2], (--argc) * sizeof(*argv));
            continue;
        }
        fprintf(stderr, "error: Invalid argument\n");
        exit(-1);
    }
    buf_resize(ib, block_size);

    /* start! */
    fprintf(stderr, msg_start);
    if(argc == 4 && strcmp(argv[1], "e") == 0) { /* pack directory */
        operation = OPERATION_PACK;
        if(pack(argv[2], argv[3], ppm, block_size) == -1) {
            abort();
        }

        /* timer end */
        gettimeofday(&time_end, NULL);
        cost_time = (time_end.tv_sec - time_start.tv_sec) + (time_end.tv_usec - time_start.tv_usec) / 1000000.0;
        fprintf(stderr, "encode done in %.2lfsec\n", cost_time);
    }
    if(argc == 4 && strcmp(argv[1], "d") == 0) { /* unpack directory */
        operation = OPERATION_PACK;
        if(unpack(argv[2], argv[3], ppm, block_size) == -1) {
            abort();
        }

        /* timer end */
        gettimeofday(&time_end, NULL);
        cost_time = (time_end.tv_sec - time_start.tv_sec) + (time_end.tv_usec - time_start.tv_usec) / 1000000.0;
        fprintf(stderr, "encode done in %.2lfsec\n", cost_time);
    }

    if(operation == OPERATION_INVALID) { /* bad operation */
        fprintf(stderr, msg_help);
    }
    ppm_model_del(ppm);
    buf_del(ib);
    buf_del(ob);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, 0x8(%rsp)
movl %edi, %r15d
movl $0x1000000, 0x4(%rsp)   # imm = 0x1000000
movl $0x320838, %edi         # imm = 0x320838
callq 0x1180
movq %rax, %r13
movl $0x0, 0x8(%rax)
movq $0x0, (%rax)
leaq 0x10(%rax), %rbx
movl $0x1, %edi
movl $0x10, %esi
callq 0x1120
movq %rax, %r14
xorl %r12d, %r12d
movl $0x2a0806, %edx         # imm = 0x2A0806
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10e0
movq %r14, 0x2a0820(%r13)
movl $0x1, %edi
movl $0x10, %esi
callq 0x1120
movq %rax, 0x2a0818(%r13)
movb $0x0, 0x2a0828(%r13)
movq %r13, %rax
addq $0x2a082a, %rax         # imm = 0x2A082A
leaq 0x1ac6(%rip), %rcx      # 0xb2b0
movd 0x4(%rcx,%r12,8), %xmm0
movd (%rcx,%r12,8), %xmm1
punpcklwd %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
pshufd $0x0, %xmm1, %xmm0      # xmm0 = xmm1[0,0,0,0]
xorl %edx, %edx
movdqu %xmm0, (%rax,%rdx,4)
addq $0x4, %rdx
cmpq $0x400, %rdx            # imm = 0x400
jne 0x9802
incq %r12
addq $0x1000, %rax           # imm = 0x1000
cmpq $0x80, %r12
jne 0x97ea
movabsq $0x100010000, %rax      # imm = 0x100010000
movq %rax, 0x32082a(%r13)
xorl %ebx, %ebx
leaq 0x18(%rsp), %rdi
xorl %esi, %esi
callq 0x10d0
cmpl $0x2, %r15d
jl 0x9907
movq %r13, 0x10(%rsp)
movq 0x8(%rsp), %rax
leaq 0x8(%rax), %r12
leaq 0x10(%rax), %r13
leal -0x1(%r15), %ebp
shlq $0x3, %rbp
leaq 0x3(%rsp), %rbx
movq (%r12), %rdi
leaq 0x19d9(%rip), %rsi      # 0xb252
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1190
testl %eax, %eax
jle 0x98f8
movzbl 0x3(%rsp), %eax
cmpl $0x62, %eax
je 0x98ab
cmpl $0x71, %eax
jne 0x9aac
movq 0x4757(%rip), %rax      # 0xdff8
movq (%rax), %rdi
callq 0x1090
jmp 0x98d3
movq (%r12), %rdi
addq $0x2, %rdi
leaq 0x199c(%rip), %rsi      # 0xb256
leaq 0x4(%rsp), %rdx
xorl %eax, %eax
callq 0x1190
testl %eax, %eax
jle 0x9aa7
shll $0x14, 0x4(%rsp)
leal -0x1(%r15), %r14d
movq %r12, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x11e0
addq $-0x8, %rbp
cmpl $0x2, %r15d
movl %r14d, %r15d
jg 0x986e
jmp 0x98fb
movl %r15d, %r14d
cmpl $0x4, %r14d
sete %bl
movq 0x10(%rsp), %r13
movl 0x4(%rsp), %eax
testl %eax, %eax
jne 0x9914
xorl %r15d, %r15d
jmp 0x9935
movl %eax, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
mulsd 0x16e2(%rip), %xmm0     # 0xb008
cvttsd2si %xmm0, %rax
movl %eax, %edi
callq 0x1180
movq %rax, %r15
movq 0x46bc(%rip), %r14      # 0xdff8
movq (%r14), %rdi
movq 0x47ea(%rip), %rsi      # 0xe130
xorl %eax, %eax
callq 0x1140
testb %bl, %bl
movq 0x8(%rsp), %r12
je 0x9a6e
movq 0x8(%r12), %rax
movb (%rax), %bpl
cmpb $0x65, %bpl
je 0x99f0
movl %ebp, %ecx
cmpb $0x64, %cl
jne 0x997d
cmpb $0x0, 0x1(%rax)
je 0x9a78
cmpb $0x65, %bpl
jne 0x9a6e
movq 0x2a0820(%r13), %rbx
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x99a3
movq (%rdi), %rax
movq %rax, (%rbx)
callq 0x1030
jmp 0x998e
movq %rbx, %rdi
callq 0x1030
movq 0x2a0818(%r13), %rbx
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x99c7
movq (%rdi), %rax
movq %rax, (%rbx)
callq 0x1030
jmp 0x99b2
movq %rbx, %rdi
callq 0x1030
movq %r13, %rdi
callq 0x1030
movq %r15, %rdi
callq 0x1030
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x0, 0x1(%rax)
jne 0x9a6e
movq 0x10(%r12), %rdi
movq 0x18(%r12), %rsi
movl 0x4(%rsp), %ecx
movq %r13, %rdx
callq 0x9ab8
cmpl $-0x1, %eax
je 0x9ab1
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10d0
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq 0x18(%rsp), %rax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
subq 0x20(%rsp), %rcx
xorps %xmm0, %xmm0
cvtsi2sd %rcx, %xmm0
divsd 0x168b(%rip), %xmm0     # 0xb0d8
addsd %xmm1, %xmm0
movq (%r14), %rdi
leaq 0x1831(%rip), %rsi      # 0xb28c
movb $0x1, %al
callq 0x1140
movq 0x8(%r12), %rax
movb (%rax), %cl
jmp 0x996e
callq 0x1275
jmp 0x9987
movq 0x10(%r12), %rdi
movq 0x18(%r12), %rsi
movl 0x4(%rsp), %ecx
movq %r13, %rdx
callq 0xa8c7
cmpl $-0x1, %eax
je 0x9ab1
leaq 0x28(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x1293
jmp 0x9987
callq 0x1250
callq 0x12e8
callq 0x1040
nop