// File: /workspace/github_c_makefile_star2_O2/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 $0x48, %rsp
movq %rsi, 0x8(%rsp)
movl %edi, %r13d
movl $0x1000000, 0x4(%rsp)   # imm = 0x1000000
movl $0x320838, %edi         # imm = 0x320838
callq 0x1180
movq %rax, %r12
andl $0x0, 0x8(%rax)
andq $0x0, (%rax)
leaq 0x10(%rax), %rbx
callq 0x6fe5
movq %rax, %r14
xorl %r15d, %r15d
movl $0x2a0806, %edx         # imm = 0x2A0806
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10e0
movq %r14, 0x2a0820(%r12)
callq 0x6fe5
movq %rax, 0x2a0818(%r12)
movb $0x0, 0x2a0828(%r12)
movq %r12, %rax
addq $0x2a082a, %rax         # imm = 0x2A082A
leaq 0x1559(%rip), %rcx      # 0x81f0
cmpq $0x80, %r15
je 0x6ccb
movq (%rcx,%r15,8), %xmm0
pshuflw $0xe8, %xmm0, %xmm0     # xmm0 = xmm0[0,2,2,3,4,5,6,7]
xorl %edx, %edx
cmpq $0x400, %rdx            # imm = 0x400
je 0x6cc0
movd %xmm0, (%rax,%rdx,4)
incq %rdx
jmp 0x6cad
incq %r15
addq $0x1000, %rax           # imm = 0x1000
jmp 0x6c97
movabsq $0x100010000, %rax      # imm = 0x100010000
movq %r12, 0x30(%rsp)
movq %rax, 0x32082a(%r12)
callq 0x6ff0
movq %rax, 0x28(%rsp)
callq 0x6ff0
movq %rax, 0x20(%rsp)
leaq 0x10(%rsp), %rdi
xorl %esi, %esi
callq 0x10d0
movq 0x8(%rsp), %rax
leaq 0x8(%rax), %rbp
leaq 0x10(%rax), %r15
leal -0x1(%r13), %r12d
shlq $0x3, %r12
leaq 0x147c(%rip), %r14      # 0x819a
leaq 0x3(%rsp), %rbx
cmpl $0x2, %r13d
jl 0x6da1
movq (%rbp), %rdi
movq %r14, %rsi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1190
testl %eax, %eax
jle 0x6da1
movzbl 0x3(%rsp), %eax
cmpl $0x62, %eax
je 0x6d62
cmpl $0x71, %eax
jne 0x6f92
movq 0x42a0(%rip), %rax      # 0xaff8
movq (%rax), %rdi
callq 0x1090
jmp 0x6d8a
movq (%rbp), %rdi
addq $0x2, %rdi
leaq 0x142d(%rip), %rsi      # 0x819e
leaq 0x4(%rsp), %rdx
xorl %eax, %eax
callq 0x1190
testl %eax, %eax
jle 0x6fa7
shll $0x14, 0x4(%rsp)
decl %r13d
movq %rbp, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x11e0
addq $-0x8, %r12
jmp 0x6d23
movl 0x4(%rsp), %ebx
movq 0x28(%rsp), %r12
movl 0xc(%r12), %eax
cmpl %ebx, %eax
setae %cl
shrl %eax
cmpl %ebx, %eax
setbe %al
testb %al, %cl
jne 0x6de7
movl %ebx, %eax
cvtsi2sd %rax, %xmm0
mulsd 0x123a(%rip), %xmm0     # 0x8008
cvttsd2si %xmm0, %rax
movl %eax, 0xc(%r12)
movq (%r12), %rdi
movl %eax, %esi
callq 0x11b0
movq %rax, (%r12)
movl %ebx, 0x8(%r12)
movq 0x4205(%rip), %rax      # 0xaff8
movq (%rax), %rdi
movq 0x4333(%rip), %rsi      # 0xb130
xorl %eax, %eax
callq 0x1140
cmpl $0x4, %r13d
movq 0x30(%rsp), %r15
jne 0x6f00
movq (%rbp), %rax
movb (%rax), %r14b
cmpb $0x65, %r14b
je 0x6e7f
movl %r14d, %ecx
cmpb $0x64, %cl
jne 0x6e32
cmpb $0x0, 0x1(%rax)
je 0x6f1d
cmpb $0x65, %r14b
jne 0x6f00
movq 0x2a0820(%r15), %rdi
callq 0x6ffb
movq 0x2a0818(%r15), %rdi
callq 0x6ffb
movq %r15, %rdi
callq 0x1030
movq %r12, %rdi
callq 0x6fd0
movq 0x20(%rsp), %rdi
callq 0x6fd0
xorl %eax, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x0, 0x1(%rax)
jne 0x6f00
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0x18(%rax), %rsi
movl 0x4(%rsp), %ecx
movq %r15, %rdx
callq 0x7020
cmpl $-0x1, %eax
je 0x6fcb
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10d0
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq 0x10(%rsp), %rax
cvtsi2sd %rax, %xmm1
subq 0x18(%rsp), %rcx
cvtsi2sd %rcx, %xmm0
divsd 0x1147(%rip), %xmm0     # 0x8020
addsd %xmm1, %xmm0
movq 0x4114(%rip), %rax      # 0xaff8
movq (%rax), %rdi
leaq 0x12e6(%rip), %rsi      # 0x81d4
movb $0x1, %al
callq 0x1140
movq (%rbp), %rax
movb (%rax), %cl
jmp 0x6e23
movq 0x40f1(%rip), %rax      # 0xaff8
movq (%rax), %rdi
movq 0x4227(%rip), %rsi      # 0xb138
xorl %eax, %eax
callq 0x1140
jmp 0x6e3c
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0x18(%rax), %rsi
movl 0x4(%rsp), %ecx
movq %r15, %rdx
callq 0x798f
cmpl $-0x1, %eax
je 0x6fcb
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10d0
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq 0x10(%rsp), %rax
cvtsi2sd %rax, %xmm1
subq 0x18(%rsp), %rcx
cvtsi2sd %rcx, %xmm0
divsd 0x10af(%rip), %xmm0     # 0x8020
addsd %xmm1, %xmm0
movq 0x407c(%rip), %rax      # 0xaff8
movq (%rax), %rdi
leaq 0x124e(%rip), %rsi      # 0x81d4
movb $0x1, %al
callq 0x1140
jmp 0x6e3c
movq 0x405f(%rip), %rax      # 0xaff8
movq (%rax), %rcx
leaq 0x1218(%rip), %rdi      # 0x81bb
pushq $0x18
jmp 0x6fba
movq 0x404a(%rip), %rax      # 0xaff8
movq (%rax), %rcx
leaq 0x11e9(%rip), %rdi      # 0x81a1
pushq $0x19
popq %rsi
pushq $0x1
popq %rdx
callq 0x1210
pushq $-0x1
popq %rdi
callq 0x1200
callq 0x1040