// File: tomfunkhouser[P]gaps/pkgs/jpeg/jdmainct.c
// Function: process_data_context_main
METHODDEF(void)
process_data_context_main (j_decompress_ptr cinfo,
			   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
			   JDIMENSION out_rows_avail)
{
  my_main_ptr mainp = (my_main_ptr) cinfo->main;

  /* Read input data if we haven't filled the main buffer yet */
  if (! mainp->buffer_full) {
    if (! (*cinfo->coef->decompress_data) (cinfo,
					   mainp->xbuffer[mainp->whichptr]))
      return;			/* suspension forced, can do nothing more */
    mainp->buffer_full = TRUE;	/* OK, we have an iMCU row to work with */
    mainp->iMCU_row_ctr++;	/* count rows received */
  }

  /* Postprocessor typically will not swallow all the input data it is handed
   * in one call (due to filling the output buffer first).  Must be prepared
   * to exit and restart.  This switch lets us keep track of how far we got.
   * Note that each case falls through to the next on successful completion.
   */
  switch (mainp->context_state) {
  case CTX_POSTPONED_ROW:
    /* Call postprocessor using previously set pointers for postponed row */
    (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
			&mainp->rowgroup_ctr, mainp->rowgroups_avail,
			output_buf, out_row_ctr, out_rows_avail);
    if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
      return;			/* Need to suspend */
    mainp->context_state = CTX_PREPARE_FOR_IMCU;
    if (*out_row_ctr >= out_rows_avail)
      return;			/* Postprocessor exactly filled output buf */
    /*FALLTHROUGH*/
  case CTX_PREPARE_FOR_IMCU:
    /* Prepare to process first M-1 row groups of this iMCU row */
    mainp->rowgroup_ctr = 0;
    mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
    /* Check for bottom of image: if so, tweak pointers to "duplicate"
     * the last sample row, and adjust rowgroups_avail to ignore padding rows.
     */
    if (mainp->iMCU_row_ctr == cinfo->total_iMCU_rows)
      set_bottom_pointers(cinfo);
    mainp->context_state = CTX_PROCESS_IMCU;
    /*FALLTHROUGH*/
  case CTX_PROCESS_IMCU:
    /* Call postprocessor using previously set pointers */
    (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
			&mainp->rowgroup_ctr, mainp->rowgroups_avail,
			output_buf, out_row_ctr, out_rows_avail);
    if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
      return;			/* Need to suspend */
    /* After the first iMCU, change wraparound pointers to normal state */
    if (mainp->iMCU_row_ctr == 1)
      set_wraparound_pointers(cinfo);
    /* Prepare to load new iMCU row using other xbuffer list */
    mainp->whichptr ^= 1;	/* 0=>1 or 1=>0 */
    mainp->buffer_full = FALSE;
    /* Still need to process last row group of this iMCU row, */
    /* which is saved at index M+1 of the other xbuffer */
    mainp->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
    mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
    mainp->context_state = CTX_POSTPONED_ROW;
  }
}

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movq %rdx, 0x20(%rsp)
movl %ecx, 0x1c(%rsp)
movq 0x30(%rsp), %rax
movq 0x228(%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
cmpl $0x0, 0x60(%rax)
jne 0xec8d7
movq 0x30(%rsp), %rax
movq 0x230(%rax), %rax
movq 0x18(%rax), %rax
movq 0x30(%rsp), %rdi
movq 0x10(%rsp), %rcx
movq 0x10(%rsp), %rdx
movslq 0x78(%rdx), %rdx
movq 0x68(%rcx,%rdx,8), %rsi
callq *%rax
cmpl $0x0, %eax
jne 0xec8b7
jmp 0xecabe
movq 0x10(%rsp), %rax
movl $0x1, 0x60(%rax)
movq 0x10(%rsp), %rax
movl 0x84(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x84(%rax)
movq 0x10(%rsp), %rax
movl 0x7c(%rax), %eax
movl %eax, 0xc(%rsp)
testl %eax, %eax
je 0xec996
jmp 0xec8ed
movl 0xc(%rsp), %eax
subl $0x1, %eax
je 0xec9e9
jmp 0xec8fc
movl 0xc(%rsp), %eax
subl $0x2, %eax
jne 0xecabe
jmp 0xec90b
movq 0x30(%rsp), %rax
movq 0x238(%rax), %rax
movq 0x8(%rax), %rax
movq 0x30(%rsp), %rdi
movq 0x10(%rsp), %rcx
movq 0x10(%rsp), %rdx
movslq 0x78(%rdx), %rdx
movq 0x68(%rcx,%rdx,8), %rsi
movq 0x10(%rsp), %rdx
addq $0x64, %rdx
movq 0x10(%rsp), %rcx
movl 0x80(%rcx), %ecx
movq 0x28(%rsp), %r8
movq 0x20(%rsp), %r9
movl 0x1c(%rsp), %r10d
movl %r10d, (%rsp)
callq *%rax
movq 0x10(%rsp), %rax
movl 0x64(%rax), %eax
movq 0x10(%rsp), %rcx
cmpl 0x80(%rcx), %eax
jae 0xec976
jmp 0xecabe
movq 0x10(%rsp), %rax
movl $0x0, 0x7c(%rax)
movq 0x20(%rsp), %rax
movl (%rax), %eax
cmpl 0x1c(%rsp), %eax
jb 0xec994
jmp 0xecabe
jmp 0xec996
movq 0x10(%rsp), %rax
movl $0x0, 0x64(%rax)
movq 0x30(%rsp), %rax
movl 0x1a0(%rax), %ecx
subl $0x1, %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x80(%rax)
movq 0x10(%rsp), %rax
movl 0x84(%rax), %eax
movq 0x30(%rsp), %rcx
cmpl 0x1a4(%rcx), %eax
jne 0xec9dd
movq 0x30(%rsp), %rdi
callq 0xece10
movq 0x10(%rsp), %rax
movl $0x1, 0x7c(%rax)
movq 0x30(%rsp), %rax
movq 0x238(%rax), %rax
movq 0x8(%rax), %rax
movq 0x30(%rsp), %rdi
movq 0x10(%rsp), %rcx
movq 0x10(%rsp), %rdx
movslq 0x78(%rdx), %rdx
movq 0x68(%rcx,%rdx,8), %rsi
movq 0x10(%rsp), %rdx
addq $0x64, %rdx
movq 0x10(%rsp), %rcx
movl 0x80(%rcx), %ecx
movq 0x28(%rsp), %r8
movq 0x20(%rsp), %r9
movl 0x1c(%rsp), %r10d
movl %r10d, (%rsp)
callq *%rax
movq 0x10(%rsp), %rax
movl 0x64(%rax), %eax
movq 0x10(%rsp), %rcx
cmpl 0x80(%rcx), %eax
jae 0xeca51
jmp 0xecabe
movq 0x10(%rsp), %rax
cmpl $0x1, 0x84(%rax)
jne 0xeca69
movq 0x30(%rsp), %rdi
callq 0xecf50
movq 0x10(%rsp), %rax
movl 0x78(%rax), %ecx
xorl $0x1, %ecx
movl %ecx, 0x78(%rax)
movq 0x10(%rsp), %rax
movl $0x0, 0x60(%rax)
movq 0x30(%rsp), %rax
movl 0x1a0(%rax), %ecx
addl $0x1, %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x64(%rax)
movq 0x30(%rsp), %rax
movl 0x1a0(%rax), %ecx
addl $0x2, %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x80(%rax)
movq 0x10(%rsp), %rax
movl $0x2, 0x7c(%rax)
addq $0x38, %rsp
retq
nopw %cs:(%rax,%rax)