// File: /workspace/github_c_makefile_star2_O0/ijleesw[P]data-compression/src/golomb/main.c
// Function: main
int main (int argc, char** argv)
{
    unsigned int *out;
    unsigned long outsize;
    unsigned char *decoded;
    unsigned char *ge, *gd;
    unsigned long ge_size, gd_size;
    unsigned int golomb_param;
    unsigned long decoded_size;
    //unsigned char input[] = { 1, 5, 4, 5 };
    //unsigned char str[] = {0, 0, 0, 0, 8, 2, 20, 128, 30};
    //unsigned char input[INPUTSZ];
    int i;
    int inputsz = INPUTSZ;

    srand (time(NULL));


    unsigned char* buf;

    if (argc < 4) {
        printf("Usage: %s <input path> <compression path> <decompression path>\n", argv[0]);
        return -1;
    }
    if (!(buf = (unsigned char*)readFile(argv[1]))) {
        perror("File open error.\n");
        return -1;
    }
    inputsz = strlen((char*)buf);

    //for (int i = 0; i < inputsz; i++) {
        //printf("%d ",(unsigned char)buf[i]);
    //}
    //printf("length: %d\n",inputsz);
    unsigned char *input = buf;




    //printf ("testing golomb encoding\n");
    if (golomb_encode (input, inputsz, (void*)&ge, &ge_size, &golomb_param) ) {
        printf ("golomb encoding failed\n");
    } else {

        //printf ("g-e param: %d, g-e chars: ", golomb_param);

        for (i = 0; i < ge_size; ++i) {
            //printf ("%s %s ",  hex2bin[ge[i] >> 4], hex2bin[ge[i] & 0x0f]);
            //printf(" ... => %d\n", ge[i]);
        }
        //printf ("ge_size = %lu\n", ge_size);

        //printf ("writing compressed data to file ...\n");
        FILE *compressed = fopen(argv[2], "w");
        for (int i = 0; i < ge_size; i++) {
            fputc(ge[i], compressed);
            //printf ("finished %dth\n", i+1); fflush(stdout);
        }
        //printf ("writing finished.\n");
        
        fclose(compressed);


        if (golomb_decode (ge, ge_size, golomb_param, (void*)&gd, &gd_size)) {
            printf ("golomb decoding failed\n");
        } else {
            
            if (gd_size != inputsz) {
                //printf ("gd_size != inputsz/ gd_size = %d\n", gd_size);
                goto print_on_error;
            }

            for (i = 0; i < inputsz; ++i) {  // -------------(*)
                if (gd[i] != input[i]) {
                    //printf ("entry %d mismatches\n", i);
                    goto print_on_error;
                }
                /*else {
                    printf("gd[i] = %d, input[i] = %d\n", gd[i], input[i]);
                }*/
            }

            //printf ("writing decompressed data to file ...\n");
            FILE *decompressed = fopen(argv[3], "w"); 
            for (int i = 0; i < gd_size; i++) fputc(gd[i], decompressed);
            //printf ("writing finished.\n");

            fclose(decompressed);
        }
    }

/*
    printf("============Golomb Coding============\n");
    printf("original file: %s\n", argv[1]);
    printf("original size: %d\n\n", inputsz);

    printf("compressed file: %s\n", argv[2]);
    printf("compressed size: %d\n", ge_size);
    printf("compression ratio: %.5f\n\n", (double)inputsz/ge_size);

    printf("decompressed file: %s\n", argv[3]);
    printf("is same as original: true\n");  // already checked at (*)
*/

    return 0;

print_on_error:
    //printf ("Entered print_on_error.\n");
/*
    printf ("input unsigned chars: ");
    for (i = 0; i < inputsz; ++i)
        printf ("%d ", input[i]);
    printf ("\n");

    printf ("gd chars: ");
    for (i = 0; i < gd_size; ++i) 
        printf ("%d ", gd[i]);
    printf ("\n");*/
    return 0;
}

// Assembly:
subq $0x98, %rsp
movl $0x0, 0x94(%rsp)
movl %edi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movl $0x4, 0x38(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0x2170
movl %eax, %edi
callq 0x2100
cmpl $0x4, 0x90(%rsp)
jge 0x235c
movq 0x88(%rsp), %rax
movq (%rax), %rsi
leaq 0x1d0f(%rip), %rdi      # 0x4054
movb $0x0, %al
callq 0x2080
movl $0xffffffff, 0x94(%rsp) # imm = 0xFFFFFFFF
jmp 0x256b
movq 0x88(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x3dd0
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
jne 0x2394
leaq 0x1d15(%rip), %rdi      # 0x4094
callq 0x21e0
movl $0xffffffff, 0x94(%rsp) # imm = 0xFFFFFFFF
jmp 0x256b
movq 0x30(%rsp), %rdi
callq 0x2070
movl %eax, 0x38(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rdi
movslq 0x38(%rsp), %rsi
leaq 0x68(%rsp), %rdx
leaq 0x58(%rsp), %rcx
leaq 0x4c(%rsp), %r8
callq 0x2ac0
cmpl $0x0, %eax
je 0x23e2
leaq 0x1cd0(%rip), %rdi      # 0x40a6
movb $0x0, %al
callq 0x2080
jmp 0x2553
movl $0x0, 0x3c(%rsp)
movslq 0x3c(%rsp), %rax
cmpq 0x58(%rsp), %rax
jae 0x2405
jmp 0x23f8
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x23ea
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rdi
leaq 0x1ca6(%rip), %rsi      # 0x40be
callq 0x21d0
movq %rax, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
movslq 0x1c(%rsp), %rax
cmpq 0x58(%rsp), %rax
jae 0x245b
movq 0x68(%rsp), %rax
movslq 0x1c(%rsp), %rcx
movzbl (%rax,%rcx), %edi
movq 0x20(%rsp), %rsi
callq 0x20e0
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x242a
movq 0x20(%rsp), %rdi
callq 0x2060
movq 0x68(%rsp), %rdi
movq 0x58(%rsp), %rsi
movl 0x4c(%rsp), %edx
leaq 0x60(%rsp), %rcx
leaq 0x50(%rsp), %r8
callq 0x30e0
cmpl $0x0, %eax
je 0x249a
leaq 0x1c32(%rip), %rdi      # 0x40c0
movb $0x0, %al
callq 0x2080
jmp 0x2551
movq 0x50(%rsp), %rax
movslq 0x38(%rsp), %rcx
cmpq %rcx, %rax
je 0x24ae
jmp 0x2560
movl $0x0, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
cmpl 0x38(%rsp), %eax
jge 0x24f1
movq 0x60(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movq 0x28(%rsp), %rcx
movslq 0x3c(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
je 0x24e2
jmp 0x2560
jmp 0x24e4
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x24b6
movq 0x88(%rsp), %rax
movq 0x18(%rax), %rdi
leaq 0x1bba(%rip), %rsi      # 0x40be
callq 0x21d0
movq %rax, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
movslq 0xc(%rsp), %rax
cmpq 0x50(%rsp), %rax
jae 0x2547
movq 0x60(%rsp), %rax
movslq 0xc(%rsp), %rcx
movzbl (%rax,%rcx), %edi
movq 0x10(%rsp), %rsi
callq 0x20e0
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x2516
movq 0x10(%rsp), %rdi
callq 0x2060
jmp 0x2553
movl $0x0, 0x94(%rsp)
jmp 0x256b
movl $0x0, 0x94(%rsp)
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
nopw (%rax,%rax)