// File: /workspace/github_c_makefile_star2_O2/ijleesw[P]data-compression/src/golomb/encode.c
// Function: zlib_encode
int 
zlib_encode (void *input, unsigned long input_len, 
    void **output, unsigned long *output_len, int level)
{
  int ret, flush;
  unsigned have;
  z_stream strm;
  //unsigned char in[CHUNK];
  unsigned char *in;
  //unsigned char out[CHUNK];
  unsigned char *out_head, *out;
  unsigned long bytes_left, bytes_written;
  unsigned long output_bytes_left;
  int buf_realloc_penalty = BUF_REALLOC_PENALTY;

  bytes_left = input_len;
  bytes_written = 0;
  in = (unsigned char*) input;

  /* allocate exactly enough space to out as in */
  /* XXX this is probably too much space, since we're encoding
   * what are the performance hits of large malloc, i wonder... */
  if ( !(out_head = (unsigned char*) malloc (input_len)) ) {
    printf ("malloc failed\n");
    goto encode_error_save;
  }
  out = out_head;
  output_bytes_left = input_len;

  /* allocate deflate state */
  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;
  strm.opaque = Z_NULL;
  ret = deflateInit(&strm, level);
  if (ret != Z_OK) {
    //return ret;
    return 1;
  }

  /* compress until end of file */
  do {
    //strm.avail_in = fread(in, 1, CHUNK, source);
    if (bytes_left > CHUNK) {
      strm.avail_in = CHUNK;
      strm.next_in = in;
      in += CHUNK;
      //bytes_left -= CHUNK;
      flush = Z_NO_FLUSH;
    } else if (bytes_left == 0) {
      printf ("hmm, shouldnt have come here?\n");
      break;
    } else {
      strm.avail_in = bytes_left;
      strm.next_in = in;
      in += bytes_left;
      //bytes_left = 0;
      flush = Z_FINISH;
    }

    //printf ("going ahead with %d bytes\n", strm.avail_in);

    //if (ferror(source)) {
      //(void)deflateEnd(&strm);
      //return Z_ERRNO;
    //}

    //flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
    //strm.next_in = in;

    /* run deflate() on input until output buffer not full, finish
       compression if all of source has been read in */
    do {

      /* to take care of the case when output is not big enough */
      if (bytes_left && output_bytes_left <= bytes_left) {
        unsigned extra = buf_realloc_penalty*CHUNK;
        unsigned offset = out - out_head;
        if (!(out_head = realloc (out_head, input_len + extra)) ) {
          printf ("allocing more bytes didnt work");
          goto encode_error_save;
        }
        out = out_head + offset;
        output_bytes_left += extra;
        buf_realloc_penalty *= BUF_REALLOC_PENALTY;
      }

      strm.avail_out = CHUNK;
      strm.next_out = out;
      ret = deflate(&strm, flush);    /* no bad return value */
      assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
      have = CHUNK - strm.avail_out;
      out += have;

      bytes_written += have;

      //if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
        //(void)deflateEnd(&strm);
        //return Z_ERRNO;
      //}
    } while (strm.avail_out == 0);
    assert(strm.avail_in == 0);     /* all input will be used */

    bytes_left = (bytes_left > CHUNK) ? (bytes_left - CHUNK) : 0;
    /* done when last data in file processed */
  } while (flush != Z_FINISH);
  assert(ret == Z_STREAM_END);        /* stream will be complete */

  /* clean up and return */
  (void)deflateEnd(&strm);

  /* general sanity checks and cleanup */
  if (bytes_written > input_len)
    printf ("encoding sucks: input was %lu but output is %lu\n",
        input_len, bytes_written);

  if ( !(out_head = realloc (out_head, bytes_written)) )  {
    perror ("realloc failed: ");
    goto encode_error_save;
  }
  *output = out_head;
  *output_len = bytes_written;
  return 0;

encode_error_save:
  if (out_head) free (out_head);
  *output_len = 0;
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movl %r8d, %ebx
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %rbp
movq %rdi, %r12
movq %rsi, %rdi
callq 0x2170
testq %rax, %rax
je 0x2b2d
movq %rax, %r13
xorps %xmm0, %xmm0
leaq 0x38(%rsp), %rdi
movups %xmm0, 0x40(%rdi)
andq $0x0, 0x50(%rdi)
leaq 0x1754(%rip), %rdx      # 0x426b
pushq $0x70
popq %rcx
movl %ebx, %esi
callq 0x2120
testl %eax, %eax
je 0x2b44
pushq $0x1
popq %rax
jmp 0x2c65
leaq 0x194f(%rip), %rdi      # 0x4483
callq 0x2040
pushq $0x1
popq %rax
xorl %r15d, %r15d
jmp 0x2c62
movq %r12, 0x18(%rsp)
movq %r15, 0x30(%rsp)
movq %r14, 0x10(%rsp)
xorl %r15d, %r15d
pushq $0x3
popq %rbx
movq %r13, %r12
movq %rbp, %rdi
movq %rbp, 0x20(%rsp)
movq %rbp, 0x28(%rsp)
xorl %ebp, %ebp
movl $0x2000, %eax           # imm = 0x2000
movl $0x2000, %ecx           # imm = 0x2000
movl $0x0, 0xc(%rsp)
cmpq $0x2000, %rdi           # imm = 0x2000
ja 0x2b9b
testq %rdi, %rdi
je 0x2c77
movl %edi, %ecx
movq %rdi, %rax
pushq $0x4
popq %rsi
movl %esi, 0xc(%rsp)
movl %ecx, 0x40(%rsp)
movq 0x18(%rsp), %rcx
movq %rcx, 0x38(%rsp)
addq %rax, %rcx
movq %rcx, 0x18(%rsp)
movq %rdi, %r14
cmpq %rdi, 0x28(%rsp)
ja 0x2be7
movl %ebx, %ebp
shll $0xd, %ebp
movq 0x20(%rsp), %rax
leaq (%rax,%rbp), %rsi
movq %r12, %rdi
callq 0x21a0
testq %rax, %rax
je 0x2c49
subl %r12d, %r13d
addq %rax, %r13
addq %rbp, 0x28(%rsp)
leal (%rbx,%rbx,2), %ebx
movq %rax, %r12
movl $0x2000, 0x58(%rsp)     # imm = 0x2000
movq %r13, 0x50(%rsp)
leaq 0x38(%rsp), %rdi
movl 0xc(%rsp), %esi
callq 0x20b0
cmpl $-0x2, %eax
je 0x2ce3
movl %eax, %ebp
movl 0x58(%rsp), %eax
movl $0x2000, %ecx           # imm = 0x2000
subl %eax, %ecx
addq %rcx, %r13
addq %rcx, %r15
testl %eax, %eax
movq %r14, %rdi
je 0x2bb1
cmpl $0x0, 0x40(%rsp)
jne 0x2d02
leaq -0x2000(%rdi), %rax
cmpq $0x2000, %rdi           # imm = 0x2000
movq %rax, %rdi
ja 0x2b6b
jmp 0x2c83
leaq 0x1622(%rip), %rdi      # 0x4272
xorl %r15d, %r15d
xorl %eax, %eax
callq 0x2080
pushq $0x1
popq %rax
movq 0x10(%rsp), %r14
movq %r15, (%r14)
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1813(%rip), %rdi      # 0x4491
callq 0x2040
cmpl $0x1, %ebp
jne 0x2d21
leaq 0x38(%rsp), %rdi
callq 0x2190
movq 0x20(%rsp), %rsi
cmpq %rsi, %r15
movq 0x10(%rsp), %r14
jbe 0x2cb6
leaq 0x16d9(%rip), %rdi      # 0x4385
movq %r15, %rdx
xorl %eax, %eax
callq 0x2080
movq %r12, %rdi
movq %r15, %rsi
callq 0x21a0
testq %rax, %rax
je 0x2cd2
movq 0x30(%rsp), %rcx
movq %rax, (%rcx)
xorl %eax, %eax
jmp 0x2c62
leaq 0x164f(%rip), %rdi      # 0x4328
callq 0x21d0
jmp 0x2b39
leaq 0x15a7(%rip), %rdi      # 0x4291
leaq 0x15b6(%rip), %rsi      # 0x42a7
leaq 0x15c3(%rip), %rcx      # 0x42bb
movl $0x3f9, %edx            # imm = 0x3F9
callq 0x2090
leaq 0x15f8(%rip), %rdi      # 0x4301
leaq 0x1597(%rip), %rsi      # 0x42a7
leaq 0x15a4(%rip), %rcx      # 0x42bb
movl $0x404, %edx            # imm = 0x404
callq 0x2090
leaq 0x15ec(%rip), %rdi      # 0x4314
leaq 0x1578(%rip), %rsi      # 0x42a7
leaq 0x1585(%rip), %rcx      # 0x42bb
movl $0x409, %edx            # imm = 0x409
callq 0x2090