// File: tomfunkhouser[P]gaps/pkgs/jpeg/jccoefct.c
// Function: compress_output
METHODDEF(jboolean)
compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION MCU_col_num;	/* index of current MCU within row */
  int blkn, ci, xindex, yindex, yoffset;
  JDIMENSION start_col;
  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
  JBLOCKROW buffer_ptr;
  jpeg_component_info *compptr;

  /* Align the virtual buffers for the components used in this scan.
   * NB: during first pass, this is safe only because the buffers will
   * already be aligned properly, so jmemmgr.c won't need to do any I/O.
   */
  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    compptr = cinfo->cur_comp_info[ci];
    buffer[ci] = (*cinfo->mem->access_virt_barray)
      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
       coef->iMCU_row_num * compptr->v_samp_factor,
       (JDIMENSION) compptr->v_samp_factor, FALSE);
  }

  /* Loop to process 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 < cinfo->MCUs_per_row;
	 MCU_col_num++) {
      /* Construct list of pointers to DCT blocks belonging to this MCU */
      blkn = 0;			/* index of current DCT block within MCU */
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
	compptr = cinfo->cur_comp_info[ci];
	start_col = MCU_col_num * compptr->MCU_width;
	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
	    coef->MCU_buffer[blkn++] = buffer_ptr++;
	  }
	}
      }
      /* Try to write the MCU. */
      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
	/* Suspension forced; update state counters and exit */
	coef->MCU_vert_offset = yoffset;
	coef->mcu_ctr = MCU_col_num;
	return FALSE;
      }
    }
    /* Completed an MCU row, but perhaps not an iMCU row */
    coef->mcu_ctr = 0;
  }
  /* Completed the iMCU row, advance counters for next one */
  coef->iMCU_row_num++;
  start_iMCU_row(cinfo);
  return TRUE;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq 0x68(%rsp), %rax
movq 0x1c8(%rax), %rax
movq %rax, 0x58(%rsp)
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movq 0x68(%rsp), %rcx
cmpl 0x144(%rcx), %eax
jge 0xdb2eb
movq 0x68(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movq 0x148(%rax,%rcx,8), %rax
movq %rax, (%rsp)
movq 0x68(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x40(%rax), %rax
movq 0x68(%rsp), %rdi
movq 0x58(%rsp), %rcx
movq (%rsp), %rdx
movslq 0x4(%rdx), %rdx
movq 0x70(%rcx,%rdx,8), %rsi
movq 0x58(%rsp), %rcx
movl 0x10(%rcx), %edx
movq (%rsp), %rcx
imull 0xc(%rcx), %edx
movq (%rsp), %rcx
movl 0xc(%rcx), %ecx
xorl %r8d, %r8d
callq *%rax
movq %rax, %rcx
movslq 0x4c(%rsp), %rax
movq %rcx, 0x10(%rsp,%rax,8)
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0xdb267
movq 0x58(%rsp), %rax
movl 0x18(%rax), %eax
movl %eax, 0x40(%rsp)
movl 0x40(%rsp), %eax
movq 0x58(%rsp), %rcx
cmpl 0x1c(%rcx), %eax
jge 0xdb49f
movq 0x58(%rsp), %rax
movl 0x14(%rax), %eax
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
movq 0x68(%rsp), %rcx
cmpl 0x168(%rcx), %eax
jae 0xdb483
movl $0x0, 0x50(%rsp)
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movq 0x68(%rsp), %rcx
cmpl 0x144(%rcx), %eax
jge 0xdb42a
movq 0x68(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movq 0x148(%rax,%rcx,8), %rax
movq %rax, (%rsp)
movl 0x54(%rsp), %eax
movq (%rsp), %rcx
imull 0x34(%rcx), %eax
movl %eax, 0x3c(%rsp)
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
movq (%rsp), %rcx
cmpl 0x38(%rcx), %eax
jge 0xdb418
movslq 0x4c(%rsp), %rax
movq 0x10(%rsp,%rax,8), %rax
movl 0x44(%rsp), %ecx
addl 0x40(%rsp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movl 0x3c(%rsp), %ecx
shlq $0x7, %rcx
addq %rcx, %rax
movq %rax, 0x8(%rsp)
movl $0x0, 0x48(%rsp)
movl 0x48(%rsp), %eax
movq (%rsp), %rcx
cmpl 0x34(%rcx), %eax
jge 0xdb406
movq 0x8(%rsp), %rdx
movq %rdx, %rax
addq $0x80, %rax
movq %rax, 0x8(%rsp)
movq 0x58(%rsp), %rax
movl 0x50(%rsp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x50(%rsp)
movslq %ecx, %rcx
movq %rdx, 0x20(%rax,%rcx,8)
movl 0x48(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x48(%rsp)
jmp 0xdb3bf
jmp 0xdb408
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0xdb37d
jmp 0xdb41a
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0xdb33a
movq 0x68(%rsp), %rax
movq 0x1f0(%rax), %rax
movq 0x8(%rax), %rax
movq 0x68(%rsp), %rdi
movq 0x58(%rsp), %rsi
addq $0x20, %rsi
callq *%rax
cmpl $0x0, %eax
jne 0xdb471
movl 0x40(%rsp), %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x18(%rax)
movl 0x54(%rsp), %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x14(%rax)
movl $0x0, 0x74(%rsp)
jmp 0xdb4bf
jmp 0xdb473
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0xdb315
movq 0x58(%rsp), %rax
movl $0x0, 0x14(%rax)
movl 0x40(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
jmp 0xdb2f7
movq 0x58(%rsp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq 0x68(%rsp), %rdi
callq 0xdaa80
movl $0x1, 0x74(%rsp)
movl 0x74(%rsp), %eax
addq $0x78, %rsp
retq
nopl (%rax,%rax)