// File: tomfunkhouser[P]gaps/pkgs/jpeg/jdcoefct.c
// Function: decompress_onepass
METHODDEF(int)
decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION MCU_col_num;	/* index of current MCU within row */
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  int blkn, ci, xindex, yindex, yoffset, useful_width;
  JSAMPARRAY output_ptr;
  JDIMENSION start_col, output_col;
  jpeg_component_info *compptr;
  inverse_DCT_method_ptr inverse_DCT;

  /* Loop to process as much as one whole iMCU row */
  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
       yoffset++) {
    for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
	 MCU_col_num++) {
      /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
      jzero_far((void FAR *) coef->MCU_buffer[0],
		(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
	/* Suspension forced; update state counters and exit */
	coef->MCU_vert_offset = yoffset;
	coef->MCU_ctr = MCU_col_num;
	return JPEG_SUSPENDED;
      }
      /* Determine where data should go in output_buf and do the IDCT thing.
       * We skip dummy blocks at the right and bottom edges (but blkn gets
       * incremented past them!).  Note the inner loop relies on having
       * allocated the MCU_buffer[] blocks sequentially.
       */
      blkn = 0;			/* index of current DCT block within MCU */
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
	compptr = cinfo->cur_comp_info[ci];
	/* Don't bother to IDCT an uninteresting component. */
	if (! compptr->component_needed) {
	  blkn += compptr->MCU_blocks;
	  continue;
	}
	inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
	useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
						    : compptr->last_col_width;
	output_ptr = output_buf[compptr->component_index] +
	  yoffset * compptr->DCT_scaled_size;
	start_col = MCU_col_num * compptr->MCU_sample_width;
	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
	  if (cinfo->input_iMCU_row < last_iMCU_row ||
	      yoffset+yindex < compptr->last_row_height) {
	    output_col = start_col;
	    for (xindex = 0; xindex < useful_width; xindex++) {
	      (*inverse_DCT) (cinfo, compptr,
			      (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
			      output_ptr, output_col);
	      output_col += compptr->DCT_scaled_size;
	    }
	  }
	  blkn += compptr->MCU_width;
	  output_ptr += compptr->DCT_scaled_size;
	}
      }
    }
    /* Completed an MCU row, but perhaps not an iMCU row */
    coef->MCU_ctr = 0;
  }
  /* Completed the iMCU row, advance counters for next one */
  cinfo->output_iMCU_row++;
  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
    start_iMCU_row(cinfo);
    return JPEG_ROW_COMPLETED;
  }
  /* Completed the scan */
  (*cinfo->inputctl->finish_input_pass) (cinfo);
  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 0x1d8(%rax), %eax
subl $0x1, %eax
movl %eax, 0x50(%rsp)
movq 0x68(%rsp), %rax
movl 0x1a4(%rax), %eax
subl $0x1, %eax
movl %eax, 0x4c(%rsp)
movq 0x58(%rsp), %rax
movl 0x2c(%rax), %eax
movl %eax, 0x38(%rsp)
movl 0x38(%rsp), %eax
movq 0x58(%rsp), %rcx
cmpl 0x30(%rcx), %eax
jge 0xedc9b
movq 0x58(%rsp), %rax
movl 0x28(%rax), %eax
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
cmpl 0x50(%rsp), %eax
ja 0xedc7f
movq 0x58(%rsp), %rax
movq 0x38(%rax), %rdi
movq 0x68(%rsp), %rax
movslq 0x1e0(%rax), %rsi
shlq $0x7, %rsi
callq 0xf9470
movq 0x68(%rsp), %rax
movq 0x250(%rax), %rax
movq 0x8(%rax), %rax
movq 0x68(%rsp), %rdi
movq 0x58(%rsp), %rsi
addq $0x38, %rsi
callq *%rax
cmpl $0x0, %eax
jne 0xeda93
movl 0x38(%rsp), %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x2c(%rax)
movl 0x54(%rsp), %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x28(%rax)
movl $0x0, 0x74(%rsp)
jmp 0xedd03
movl $0x0, 0x48(%rsp)
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
movq 0x68(%rsp), %rcx
cmpl 0x1b0(%rcx), %eax
jge 0xedc6d
movq 0x68(%rsp), %rax
movslq 0x44(%rsp), %rcx
movq 0x1b8(%rax,%rcx,8), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpl $0x0, 0x30(%rax)
jne 0xedaef
movq 0x18(%rsp), %rax
movl 0x3c(%rax), %eax
addl 0x48(%rsp), %eax
movl %eax, 0x48(%rsp)
jmp 0xedc5d
movq 0x68(%rsp), %rax
movq 0x258(%rax), %rax
movq 0x18(%rsp), %rcx
movslq 0x4(%rcx), %rcx
movq 0x8(%rax,%rcx,8), %rax
movq %rax, 0x10(%rsp)
movl 0x54(%rsp), %eax
cmpl 0x50(%rsp), %eax
jae 0xedb26
movq 0x18(%rsp), %rax
movl 0x34(%rax), %eax
movl %eax, 0xc(%rsp)
jmp 0xedb32
movq 0x18(%rsp), %rax
movl 0x44(%rax), %eax
movl %eax, 0xc(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x60(%rsp), %rax
movq 0x18(%rsp), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movl 0x38(%rsp), %ecx
movq 0x18(%rsp), %rdx
imull 0x24(%rdx), %ecx
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0x28(%rsp)
movl 0x54(%rsp), %eax
movq 0x18(%rsp), %rcx
imull 0x40(%rcx), %eax
movl %eax, 0x24(%rsp)
movl $0x0, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
movq 0x18(%rsp), %rcx
cmpl 0x38(%rcx), %eax
jge 0xedc5b
movq 0x68(%rsp), %rax
movl 0xb0(%rax), %eax
cmpl 0x4c(%rsp), %eax
jb 0xedbb6
movl 0x38(%rsp), %eax
addl 0x3c(%rsp), %eax
movq 0x18(%rsp), %rcx
cmpl 0x48(%rcx), %eax
jge 0xedc1f
movl 0x24(%rsp), %eax
movl %eax, 0x20(%rsp)
movl $0x0, 0x40(%rsp)
movl 0x40(%rsp), %eax
cmpl 0x34(%rsp), %eax
jge 0xedc1d
movq 0x10(%rsp), %rax
movq 0x68(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq 0x58(%rsp), %rcx
movl 0x48(%rsp), %edx
addl 0x40(%rsp), %edx
movslq %edx, %rdx
movq 0x38(%rcx,%rdx,8), %rdx
movq 0x28(%rsp), %rcx
movl 0x20(%rsp), %r8d
callq *%rax
movq 0x18(%rsp), %rax
movl 0x24(%rax), %eax
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x40(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
jmp 0xedbc6
jmp 0xedc1f
movq 0x18(%rsp), %rax
movl 0x34(%rax), %eax
addl 0x48(%rsp), %eax
movl %eax, 0x48(%rsp)
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 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0xedb81
jmp 0xedc5d
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0xedaa3
jmp 0xedc6f
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0xeda1d
movq 0x58(%rsp), %rax
movl $0x0, 0x28(%rax)
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0xed9ff
movq 0x68(%rsp), %rax
movl 0xb8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xb8(%rax)
movq 0x68(%rsp), %rcx
movl 0xb0(%rcx), %eax
addl $0x1, %eax
movl %eax, 0xb0(%rcx)
movq 0x68(%rsp), %rcx
cmpl 0x1a4(%rcx), %eax
jae 0xedce4
movq 0x68(%rsp), %rdi
callq 0xedd10
movl $0x3, 0x74(%rsp)
jmp 0xedd03
movq 0x68(%rsp), %rax
movq 0x240(%rax), %rax
movq 0x18(%rax), %rax
movq 0x68(%rsp), %rdi
callq *%rax
movl $0x4, 0x74(%rsp)
movl 0x74(%rsp), %eax
addq $0x78, %rsp
retq
nopl (%rax)