// File: tomfunkhouser[P]gaps/pkgs/jpeg/jdcoefct.c
// Function: decompress_data
METHODDEF(int)
decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  JDIMENSION block_num;
  int ci, block_row, block_rows;
  JBLOCKARRAY buffer;
  JBLOCKROW buffer_ptr;
  JSAMPARRAY output_ptr;
  JDIMENSION output_col;
  jpeg_component_info *compptr;
  inverse_DCT_method_ptr inverse_DCT;

  /* Force some input to be done if we are getting ahead of the input. */
  while (cinfo->input_scan_number < cinfo->output_scan_number ||
	 (cinfo->input_scan_number == cinfo->output_scan_number &&
	  cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
      return JPEG_SUSPENDED;
  }

  /* OK, output from the virtual arrays. */
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       ci++, compptr++) {
    /* Don't bother to IDCT an uninteresting component. */
    if (! compptr->component_needed)
      continue;
    /* Align the virtual buffer for this component. */
    buffer = (*cinfo->mem->access_virt_barray)
      ((j_common_ptr) cinfo, coef->whole_image[ci],
       cinfo->output_iMCU_row * compptr->v_samp_factor,
       (JDIMENSION) compptr->v_samp_factor, FALSE);
    /* Count non-dummy DCT block rows in this iMCU row. */
    if (cinfo->output_iMCU_row < last_iMCU_row)
      block_rows = compptr->v_samp_factor;
    else {
      /* NB: can't use last_row_height here; it is input-side-dependent! */
      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    }
    inverse_DCT = cinfo->idct->inverse_DCT[ci];
    output_ptr = output_buf[ci];
    /* Loop over all DCT blocks to be processed. */
    for (block_row = 0; block_row < block_rows; block_row++) {
      buffer_ptr = buffer[block_row];
      output_col = 0;
      for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
			output_ptr, output_col);
	buffer_ptr++;
	output_col += compptr->DCT_scaled_size;
      }
      output_ptr += compptr->DCT_scaled_size;
    }
  }

  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
    return JPEG_ROW_COMPLETED;
  return JPEG_SCAN_COMPLETED;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq 0x68(%rsp), %rax
movq 0x230(%rax), %rax
movq %rax, 0x58(%rsp)
movq 0x68(%rsp), %rax
movl 0x1a4(%rax), %eax
subl $0x1, %eax
movl %eax, 0x54(%rsp)
movq 0x68(%rsp), %rax
movl 0xac(%rax), %ecx
movq 0x68(%rsp), %rdx
movb $0x1, %al
cmpl 0xb4(%rdx), %ecx
movb %al, 0xf(%rsp)
jl 0xed742
movq 0x68(%rsp), %rax
movl 0xac(%rax), %ecx
movq 0x68(%rsp), %rdx
xorl %eax, %eax
cmpl 0xb4(%rdx), %ecx
movb %al, 0xe(%rsp)
jne 0xed73a
movq 0x68(%rsp), %rax
movl 0xb0(%rax), %eax
movq 0x68(%rsp), %rcx
cmpl 0xb8(%rcx), %eax
setbe %al
movb %al, 0xe(%rsp)
movb 0xe(%rsp), %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0xed74c
jmp 0xed779
movq 0x68(%rsp), %rax
movq 0x240(%rax), %rax
movq (%rax), %rax
movq 0x68(%rsp), %rdi
callq *%rax
cmpl $0x0, %eax
jne 0xed774
movl $0x0, 0x74(%rsp)
jmp 0xed989
jmp 0xed6e1
movl $0x0, 0x4c(%rsp)
movq 0x68(%rsp), %rax
movq 0x130(%rax), %rax
movq %rax, 0x18(%rsp)
movl 0x4c(%rsp), %eax
movq 0x68(%rsp), %rcx
cmpl 0x38(%rcx), %eax
jge 0xed956
movq 0x18(%rsp), %rax
cmpl $0x0, 0x30(%rax)
jne 0xed7b4
jmp 0xed938
movq 0x68(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x40(%rax), %rax
movq 0x68(%rsp), %rdi
movq 0x58(%rsp), %rcx
movslq 0x4c(%rsp), %rdx
movq 0x88(%rcx,%rdx,8), %rsi
movq 0x68(%rsp), %rcx
movl 0xb8(%rcx), %edx
movq 0x18(%rsp), %rcx
imull 0xc(%rcx), %edx
movq 0x18(%rsp), %rcx
movl 0xc(%rcx), %ecx
xorl %r8d, %r8d
callq *%rax
movq %rax, 0x38(%rsp)
movq 0x68(%rsp), %rax
movl 0xb8(%rax), %eax
cmpl 0x54(%rsp), %eax
jae 0xed81d
movq 0x18(%rsp), %rax
movl 0xc(%rax), %eax
movl %eax, 0x44(%rsp)
jmp 0xed848
movq 0x18(%rsp), %rax
movl 0x20(%rax), %eax
movq 0x18(%rsp), %rcx
xorl %edx, %edx
divl 0xc(%rcx)
movl %edx, 0x44(%rsp)
cmpl $0x0, 0x44(%rsp)
jne 0xed846
movq 0x18(%rsp), %rax
movl 0xc(%rax), %eax
movl %eax, 0x44(%rsp)
jmp 0xed848
movq 0x68(%rsp), %rax
movq 0x258(%rax), %rax
movslq 0x4c(%rsp), %rcx
movq 0x8(%rax,%rcx,8), %rax
movq %rax, 0x10(%rsp)
movq 0x60(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x28(%rsp)
movl $0x0, 0x48(%rsp)
movl 0x48(%rsp), %eax
cmpl 0x44(%rsp), %eax
jge 0xed936
movq 0x38(%rsp), %rax
movslq 0x48(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x30(%rsp)
movl $0x0, 0x24(%rsp)
movl $0x0, 0x50(%rsp)
movl 0x50(%rsp), %eax
movq 0x18(%rsp), %rcx
cmpl 0x1c(%rcx), %eax
jae 0xed90a
movq 0x10(%rsp), %rax
movq 0x68(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq 0x28(%rsp), %rcx
movl 0x24(%rsp), %r8d
callq *%rax
movq 0x30(%rsp), %rax
addq $0x80, %rax
movq %rax, 0x30(%rsp)
movq 0x18(%rsp), %rax
movl 0x24(%rax), %eax
addl 0x24(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x50(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x50(%rsp)
jmp 0xed8af
movq 0x18(%rsp), %rax
movl 0x24(%rax), %ecx
movq 0x28(%rsp), %rax
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0x28(%rsp)
movl 0x48(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x48(%rsp)
jmp 0xed87e
jmp 0xed938
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
movq 0x18(%rsp), %rax
addq $0x60, %rax
movq %rax, 0x18(%rsp)
jmp 0xed792
movq 0x68(%rsp), %rcx
movl 0xb8(%rcx), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rcx)
movq 0x68(%rsp), %rcx
cmpl 0x1a4(%rcx), %eax
jae 0xed981
movl $0x3, 0x74(%rsp)
jmp 0xed989
movl $0x4, 0x74(%rsp)
movl 0x74(%rsp), %eax
addq $0x78, %rsp
retq
nopw %cs:(%rax,%rax)