// File: /workspace/github_c_makefile_star2_O2/ijleesw[P]data-compression/src/golomb/encode.c
// Function: get_run_length_encoding
int
get_run_length_encoding (unsigned char *in, 
    unsigned long size,
    unsigned int **out,
    unsigned long *outsize)
{
  unsigned int *rle;
  int i, j;
  int rle_index = 0;
  int need_to_splice = 0;
  unsigned char allones = 255;

  rle = rle_buf;


  for (i = 0; i < size; ++i) {
    //if (i>=2904188) { printf ("got char %d, i = %d, r_l_s[in[i]] = %d\n", in[i], i, rle_lookup_sizes[in[i]]); fflush(stdout); }
    for (j = 0; j < rle_lookup_sizes[in[i]]; ++j) {
      //if (i>=2904188) { printf ("> j = %d\n", j); fflush(stdout); }
      if (!j && need_to_splice) {
        //printf ("splicing..");
        if (rle_lookup[in[i]][0] > 1) {
          /* this means that the first bit is a run of one or more
           * zeros.  so we can successfully splice with the previous set
           * */
          //assert (rle_index > 7);
          //printf ("increased %d with %d\n", 
              //rle[rle_index - 2], rle_lookup[in[i]][0]);
          rle[rle_index - 2] += rle_lookup[in[i]][0];
          rle_index--;
        } else { 
          /* darn, the first entry is a 1 (ie, the first bit is a 1), so
           * we cant splice, so move increase the value of the last
           * non-zero int in the rle, and move index back one so as to
           * overwrite the last 0 */
          rle[rle_index - 2]++;
          --rle_index; 
        }
        need_to_splice = 0;
      } else {
        //if (i>=2904188) printf ("> rie_index = %d\n", rle_index);
        rle[rle_index++] = rle_lookup[in[i]][j];
        //if (i>=2904188) printf ("> reached here too\n");
        //printf ("writing %d\n", rle_lookup[in[i]][j]);
      }
    }

    if (rle[rle_index - 1] == 0)
      need_to_splice = 1;
  }

  //printf ("got char %d\n", allones);
  for (j = 0; j < rle_lookup_sizes[allones]; ++j) {
    if (!j && need_to_splice) {
      //printf ("splicing..");
      if (rle_lookup[allones][0] > 1) {
        /* this means that the first bit is a run of one or more
         * zeros.  so we can successfully splice with the previous set
         * */
        //assert (rle_index > 7);
        //printf ("increased %d with %d\n", 
            //rle[rle_index - 2], rle_lookup[allones][0]);
        rle[rle_index - 2] += rle_lookup[allones][0];
        rle_index--;
      } else { 
        /* darn, the first entry is a 1 (ie, the first bit is a 1), so
         * we cant splice, so move index back one so as to overwrite
         * the last 0 */
        rle[rle_index - 2]++;
        --rle_index; 
      }
      need_to_splice = 0;
    } else {
      rle[rle_index++] = rle_lookup[allones][j];
      //printf ("writing %d\n", rle_lookup[allones][j]);
    }
  }

  if ( !(*out = malloc (sizeof (unsigned int) * (rle_index))) ) {
    perror ("cant malloc: ");
    return 1;
  }

  if ( !(memcpy (*out, rle, sizeof (unsigned int) * (rle_index))) ) {
    perror ("cant memcpy: ");
    free (*out);
    return 1;
  }

  *outsize = rle_index;
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movq %rdx, %r14
xorl %r9d, %r9d
leaq 0x3d05(%rip), %r10      # 0x6190
leaq 0x417e(%rip), %rax      # 0x6610
leaq 0x4a87(%rip), %rcx      # 0x6f20
pushq $0x1
popq %rbp
xorl %r8d, %r8d
xorl %edx, %edx
cmpq %rsi, %r9
je 0x250a
xorl %r11d, %r11d
movzbl (%rdi,%r9), %r12d
movslq (%r10,%r12,4), %r13
movslq %r8d, %r15
cmpq %r13, %r11
jge 0x24fc
testq %r11, %r11
jne 0x24e3
testl %edx, %edx
je 0x24e3
leaq (%r12,%r12,8), %rdx
movzbl (%rax,%rdx), %edx
cmpb $0x1, %dl
adcl $0x0, %edx
movzbl %dl, %edx
addl %edx, -0x8(%rcx,%r15,4)
decl %r15d
xorl %edx, %edx
movl %r15d, %r8d
jmp 0x24f7
leaq (%r12,%r12,8), %r8
addq %r11, %r8
movzbl (%rax,%r8), %r12d
leal 0x1(%r15), %r8d
movl %r12d, (%rcx,%r15,4)
incq %r11
jmp 0x24a9
cmpl $0x0, -0x4(%rcx,%r15,4)
cmovel %ebp, %edx
incq %r9
jmp 0x24a1
movl 0x407c(%rip), %esi      # 0x658c
movzbl 0x49ef(%rip), %r9d      # 0x6f07
xorl %edi, %edi
testl %esi, %esi
cmovlel %edi, %esi
cmpb $0x1, %r9b
adcl $0x0, %r9d
movzbl %r9b, %r9d
movslq %r8d, %r12
cmpq %rdi, %rsi
je 0x2562
testq %rdi, %rdi
jne 0x254b
testl %edx, %edx
je 0x254b
addl %r9d, -0x8(%rcx,%r12,4)
decl %r12d
xorl %edx, %edx
movl %r12d, %r8d
jmp 0x255d
movzbl 0x8f7(%rdi,%rax), %r10d
leal 0x1(%r12), %r8d
movl %r10d, (%rcx,%r12,4)
incq %rdi
jmp 0x252b
leaq (,%r12,4), %r15
movq %r15, %rdi
callq 0x2170
movq %rax, (%r14)
testq %rax, %rax
je 0x25a2
leaq 0x499f(%rip), %rsi      # 0x6f20
movq %rax, %rdi
movq %r15, %rdx
callq 0x2140
movq %r12, (%rbx)
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1c57(%rip), %rdi      # 0x4200
callq 0x21d0
jmp 0x2591