// File: tomfunkhouser[P]gaps/pkgs/jpeg/jcdctmgr.c
// Function: start_pass_fdctmgr
METHODDEF(void)
start_pass_fdctmgr (j_compress_ptr cinfo)
{
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
  int ci, qtblno, i;
  jpeg_component_info *compptr;
  JQUANT_TBL * qtbl;
  DCTELEM * dtbl;

  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       ci++, compptr++) {
    qtblno = compptr->quant_tbl_no;
    /* Make sure specified quantization table is present */
    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
	cinfo->quant_tbl_ptrs[qtblno] == NULL)
      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
    qtbl = cinfo->quant_tbl_ptrs[qtblno];
    /* Compute divisors for this quant table */
    /* We may do this more than once for same table, but it's not a big deal */
    switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
    case JDCT_ISLOW:
      /* For LL&M IDCT method, divisors are equal to raw quantization
       * coefficients multiplied by 8 (to counteract scaling).
       */
      if (fdct->divisors[qtblno] == NULL) {
	fdct->divisors[qtblno] = (DCTELEM *)
	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				      DCTSIZE2 * SIZEOF(DCTELEM));
      }
      dtbl = fdct->divisors[qtblno];
      for (i = 0; i < DCTSIZE2; i++) {
	dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
      }
      break;
#endif
#ifdef DCT_IFAST_SUPPORTED
    case JDCT_IFAST:
      {
	/* For AA&N IDCT method, divisors are equal to quantization
	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
	 *   scalefactor[0] = 1
	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
	 * We apply a further scale factor of 8.
	 */
#define CONST_BITS 14
	static const INT16 aanscales[DCTSIZE2] = {
	  /* precomputed values scaled up by 14 bits */
	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
	};
	SHIFT_TEMPS

	if (fdct->divisors[qtblno] == NULL) {
	  fdct->divisors[qtblno] = (DCTELEM *)
	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
					DCTSIZE2 * SIZEOF(DCTELEM));
	}
	dtbl = fdct->divisors[qtblno];
	for (i = 0; i < DCTSIZE2; i++) {
	  dtbl[i] = (DCTELEM)
	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
				  (INT32) aanscales[i]),
		    CONST_BITS-3);
	}
      }
      break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
    case JDCT_FLOAT:
      {
	/* For float AA&N IDCT method, divisors are equal to quantization
	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
	 *   scalefactor[0] = 1
	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
	 * We apply a further scale factor of 8.
	 * What's actually stored is 1/divisor so that the inner loop can
	 * use a multiplication rather than a division.
	 */
	FAST_FLOAT * fdtbl;
	int row, col;
	static const double aanscalefactor[DCTSIZE] = {
	  1.0, 1.387039845, 1.306562965, 1.175875602,
	  1.0, 0.785694958, 0.541196100, 0.275899379
	};

	if (fdct->float_divisors[qtblno] == NULL) {
	  fdct->float_divisors[qtblno] = (FAST_FLOAT *)
	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
					DCTSIZE2 * SIZEOF(FAST_FLOAT));
	}
	fdtbl = fdct->float_divisors[qtblno];
	i = 0;
	for (row = 0; row < DCTSIZE; row++) {
	  for (col = 0; col < DCTSIZE; col++) {
	    fdtbl[i] = (FAST_FLOAT)
	      (1.0 / (((double) qtbl->quantval[i] *
		       aanscalefactor[row] * aanscalefactor[col] * 8.0)));
	    i++;
	  }
	}
      }
      break;
#endif
    default:
      ERREXIT(cinfo, JERR_NOT_COMPILED);
      break;
    }
  }
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq 0x50(%rsp), %rax
movq 0x1e8(%rax), %rax
movq %rax, 0x48(%rsp)
movl $0x0, 0x44(%rsp)
movq 0x50(%rsp), %rax
movq 0x58(%rax), %rax
movq %rax, 0x30(%rsp)
movl 0x44(%rsp), %eax
movq 0x50(%rsp), %rcx
cmpl 0x4c(%rcx), %eax
jge 0xe0af9
movq 0x30(%rsp), %rax
movl 0x10(%rax), %eax
movl %eax, 0x40(%rsp)
cmpl $0x0, 0x40(%rsp)
jl 0xe07ee
cmpl $0x4, 0x40(%rsp)
jge 0xe07ee
movq 0x50(%rsp), %rax
movslq 0x40(%rsp), %rcx
cmpq $0x0, 0x60(%rax,%rcx,8)
jne 0xe081e
movq 0x50(%rsp), %rax
movq (%rax), %rax
movl $0x34, 0x28(%rax)
movl 0x40(%rsp), %ecx
movq 0x50(%rsp), %rax
movq (%rax), %rax
movl %ecx, 0x2c(%rax)
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdi
callq *%rax
movq 0x50(%rsp), %rax
movslq 0x40(%rsp), %rcx
movq 0x60(%rax,%rcx,8), %rax
movq %rax, 0x28(%rsp)
movq 0x50(%rsp), %rax
movl 0x114(%rax), %eax
movl %eax, 0xc(%rsp)
testl %eax, %eax
je 0xe0868
jmp 0xe0847
movl 0xc(%rsp), %eax
subl $0x1, %eax
je 0xe08fc
jmp 0xe0856
movl 0xc(%rsp), %eax
subl $0x2, %eax
je 0xe09ae
jmp 0xe0ab8
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
cmpq $0x0, 0x18(%rax,%rcx,8)
jne 0xe08a9
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdi
movl $0x1, %esi
movl $0x100, %edx            # imm = 0x100
callq *%rax
movq %rax, %rdx
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
movq %rdx, 0x18(%rax,%rcx,8)
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, 0x20(%rsp)
movl $0x0, 0x3c(%rsp)
cmpl $0x40, 0x3c(%rsp)
jge 0xe08f7
movq 0x28(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movzwl (%rax,%rcx,2), %edx
shll $0x3, %edx
movq 0x20(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0xe08c5
jmp 0xe0ad9
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
cmpq $0x0, 0x18(%rax,%rcx,8)
jne 0xe093d
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdi
movl $0x1, %esi
movl $0x100, %edx            # imm = 0x100
callq *%rax
movq %rax, %rdx
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
movq %rdx, 0x18(%rax,%rcx,8)
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, 0x20(%rsp)
movl $0x0, 0x3c(%rsp)
cmpl $0x40, 0x3c(%rsp)
jge 0xe09a9
movq 0x28(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movzwl (%rax,%rcx,2), %eax
movslq 0x3c(%rsp), %rdx
leaq 0x563e6(%rip), %rcx     # 0x136d60
movswq (%rcx,%rdx,2), %rcx
imulq %rcx, %rax
addq $0x400, %rax            # imm = 0x400
sarq $0xb, %rax
movl %eax, %edx
movq 0x20(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0xe0959
jmp 0xe0ad9
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
cmpq $0x0, 0x40(%rax,%rcx,8)
jne 0xe09ef
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdi
movl $0x1, %esi
movl $0x100, %edx            # imm = 0x100
callq *%rax
movq %rax, %rdx
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
movq %rdx, 0x40(%rax,%rcx,8)
movq 0x48(%rsp), %rax
movslq 0x40(%rsp), %rcx
movq 0x40(%rax,%rcx,8), %rax
movq %rax, 0x18(%rsp)
movl $0x0, 0x3c(%rsp)
movl $0x0, 0x14(%rsp)
cmpl $0x8, 0x14(%rsp)
jge 0xe0ab6
movl $0x0, 0x10(%rsp)
cmpl $0x8, 0x10(%rsp)
jge 0xe0aa4
movq 0x28(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movzwl (%rax,%rcx,2), %eax
cvtsi2sd %eax, %xmm1
movslq 0x14(%rsp), %rcx
leaq 0x56395(%rip), %rax     # 0x136de0
mulsd (%rax,%rcx,8), %xmm1
movslq 0x10(%rsp), %rcx
leaq 0x56384(%rip), %rax     # 0x136de0
mulsd (%rax,%rcx,8), %xmm1
movsd 0x5278f(%rip), %xmm0    # 0x1331f8
mulsd %xmm0, %xmm1
movsd 0x52593(%rip), %xmm0    # 0x133008
divsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x18(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0xe0a26
jmp 0xe0aa6
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0xe0a13
jmp 0xe0ad9
movq 0x50(%rsp), %rax
movq (%rax), %rax
movl $0x30, 0x28(%rax)
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdi
callq *%rax
jmp 0xe0adb
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
movq 0x30(%rsp), %rax
addq $0x60, %rax
movq %rax, 0x30(%rsp)
jmp 0xe07b0
addq $0x58, %rsp
retq
nop