// File: tomfunkhouser[P]gaps/pkgs/jpeg/jquant1.c
// Function: quantize_ord_dither
METHODDEF(void)
quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
		     JSAMPARRAY output_buf, int num_rows)
/* General case, with ordered dithering */
{
  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
  register JSAMPROW input_ptr;
  register JSAMPROW output_ptr;
  JSAMPROW colorindex_ci;
  int * dither;			/* points to active row of dither matrix */
  int row_index, col_index;	/* current indexes into dither matrix */
  int nc = cinfo->out_color_components;
  int ci;
  int row;
  JDIMENSION col;
  JDIMENSION width = cinfo->output_width;

  for (row = 0; row < num_rows; row++) {
    /* Initialize output values to 0 so can process components separately */
    jzero_far((void FAR *) output_buf[row],
	      (size_t) (width * SIZEOF(JSAMPLE)));
    row_index = cquantize->row_index;
    for (ci = 0; ci < nc; ci++) {
      input_ptr = input_buf[row] + ci;
      output_ptr = output_buf[row];
      colorindex_ci = cquantize->colorindex[ci];
      dither = cquantize->odither[ci][row_index];
      col_index = 0;

      for (col = width; col > 0; col--) {
	/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
	 * select output value, accumulate into output code for this pixel.
	 * Range-limiting need not be done explicitly, as we have extended
	 * the colorindex table to produce the right answers for out-of-range
	 * inputs.  The maximum dither is +- MAXJSAMPLE; this sets the
	 * required amount of padding.
	 */
	*output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
	input_ptr += nc;
	output_ptr++;
	col_index = (col_index + 1) & ODITHER_MASK;
      }
    }
    /* Advance row index for next row */
    row_index = (row_index + 1) & ODITHER_MASK;
    cquantize->row_index = row_index;
  }
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movl %ecx, 0x4c(%rsp)
movq 0x60(%rsp), %rax
movq 0x270(%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x60(%rsp), %rax
movl 0x90(%rax), %eax
movl %eax, 0x14(%rsp)
movq 0x60(%rsp), %rax
movl 0x88(%rax), %eax
movl %eax, 0x4(%rsp)
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jge 0xf515d
movq 0x50(%rsp), %rax
movslq 0xc(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
movl 0x4(%rsp), %eax
movl %eax, %esi
shlq $0x0, %rsi
callq 0xf9470
movq 0x40(%rsp), %rax
movl 0x4c(%rax), %eax
movl %eax, 0x1c(%rsp)
movl $0x0, 0x10(%rsp)
movl 0x10(%rsp), %eax
cmpl 0x14(%rsp), %eax
jge 0xf5133
movq 0x58(%rsp), %rax
movslq 0xc(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x10(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x38(%rsp)
movq 0x50(%rsp), %rax
movslq 0xc(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x30(%rsp)
movq 0x40(%rsp), %rax
movq 0x30(%rax), %rax
movslq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
movslq 0x10(%rsp), %rcx
movq 0x50(%rax,%rcx,8), %rax
movslq 0x1c(%rsp), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
movl $0x0, 0x18(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jbe 0xf5121
movq 0x28(%rsp), %rax
movq 0x38(%rsp), %rcx
movzbl (%rcx), %ecx
movq 0x20(%rsp), %rdx
movslq 0x18(%rsp), %rsi
addl (%rdx,%rsi,4), %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
movq 0x30(%rsp), %rax
movzbl (%rax), %ecx
addl %edx, %ecx
movb %cl, (%rax)
movl 0x14(%rsp), %ecx
movq 0x38(%rsp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x38(%rsp)
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
movl 0x18(%rsp), %eax
addl $0x1, %eax
andl $0xf, %eax
movl %eax, 0x18(%rsp)
movl 0x8(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x8(%rsp)
jmp 0xf50b0
jmp 0xf5123
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0xf502d
movl 0x1c(%rsp), %eax
addl $0x1, %eax
andl $0xf, %eax
movl %eax, 0x1c(%rsp)
movl 0x1c(%rsp), %ecx
movq 0x40(%rsp), %rax
movl %ecx, 0x4c(%rax)
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0xf4fee
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)