// File: tomfunkhouser[P]gaps/pkgs/jpeg/jcparam.c
// Function: jpeg_simple_progression
GLOBAL(void)
jpeg_simple_progression (j_compress_ptr cinfo)
{
  int ncomps = cinfo->num_components;
  int nscans;
  jpeg_scan_info * scanptr;

  /* Safety check to ensure start_compress not called yet. */
  if (cinfo->global_state != CSTATE_START)
    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);

  /* Figure space needed for script.  Calculation must match code below! */
  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
    /* Custom script for YCbCr color images. */
    nscans = 10;
  } else {
    /* All-purpose script for other color spaces. */
    if (ncomps > MAX_COMPS_IN_SCAN)
      nscans = 6 * ncomps;	/* 2 DC + 4 AC scans per component */
    else
      nscans = 2 + 4 * ncomps;	/* 2 DC scans; 4 AC scans per component */
  }

  /* Allocate space for script.
   * We need to put it in the permanent pool in case the application performs
   * multiple compressions without changing the settings.  To avoid a memory
   * leak if jpeg_simple_progression is called repeatedly for the same JPEG
   * object, we try to re-use previously allocated space, and we allocate
   * enough space to handle YCbCr even if initially asked for grayscale.
   */
  if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
    cinfo->script_space_size = MAX(nscans, 10);
    cinfo->script_space = (jpeg_scan_info *)
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
			cinfo->script_space_size * SIZEOF(jpeg_scan_info));
  }
  scanptr = cinfo->script_space;
  cinfo->scan_info = scanptr;
  cinfo->num_scans = nscans;

  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
    /* Custom script for YCbCr color images. */
    /* Initial DC scan */
    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
    /* Initial AC scan: get some luma data out in a hurry */
    scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
    /* Chroma data is too small to be worth expending many scans on */
    scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
    scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
    /* Complete spectral selection for luma AC */
    scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
    /* Refine next bit of luma AC */
    scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
    /* Finish DC successive approximation */
    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
    /* Finish AC successive approximation */
    scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
    scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
    /* Luma bottom bit comes last since it's usually largest scan */
    scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
  } else {
    /* All-purpose script for other color spaces. */
    /* Successive approximation first pass */
    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
    scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
    scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
    /* Successive approximation second pass */
    scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
    /* Successive approximation final pass */
    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
    scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
  }
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movq 0x20(%rsp), %rax
movl 0x4c(%rax), %eax
movl %eax, 0x1c(%rsp)
movq 0x20(%rsp), %rax
cmpl $0x64, 0x24(%rax)
je 0xd69f4
movq 0x20(%rsp), %rax
movq (%rax), %rax
movl $0x14, 0x28(%rax)
movq 0x20(%rsp), %rax
movl 0x24(%rax), %ecx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movl %ecx, 0x2c(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x20(%rsp), %rdi
callq *%rax
cmpl $0x3, 0x1c(%rsp)
jne 0xd6a10
movq 0x20(%rsp), %rax
cmpl $0x3, 0x50(%rax)
jne 0xd6a10
movl $0xa, 0x18(%rsp)
jmp 0xd6a32
cmpl $0x4, 0x1c(%rsp)
jle 0xd6a22
imull $0x6, 0x1c(%rsp), %eax
movl %eax, 0x18(%rsp)
jmp 0xd6a30
movl 0x1c(%rsp), %eax
shll $0x2, %eax
addl $0x2, %eax
movl %eax, 0x18(%rsp)
jmp 0xd6a32
movq 0x20(%rsp), %rax
cmpq $0x0, 0x1f8(%rax)
je 0xd6a52
movq 0x20(%rsp), %rax
movl 0x200(%rax), %eax
cmpl 0x18(%rsp), %eax
jge 0xd6ab1
cmpl $0xa, 0x18(%rsp)
jle 0xd6a63
movl 0x18(%rsp), %eax
movl %eax, 0xc(%rsp)
jmp 0xd6a6e
movl $0xa, %eax
movl %eax, 0xc(%rsp)
jmp 0xd6a6e
movl 0xc(%rsp), %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0x200(%rax)
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x20(%rsp), %rdi
movq 0x20(%rsp), %rcx
movslq 0x200(%rcx), %rcx
imulq $0x24, %rcx, %rdx
xorl %esi, %esi
callq *%rax
movq %rax, %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x1f8(%rax)
movq 0x20(%rsp), %rax
movq 0x1f8(%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0xf8(%rax)
movl 0x18(%rsp), %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0xf0(%rax)
cmpl $0x3, 0x1c(%rsp)
jne 0xd6c57
movq 0x20(%rsp), %rax
cmpl $0x3, 0x50(%rax)
jne 0xd6c57
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
xorl %edx, %edx
movl $0x1, %ecx
callq 0xd6d30
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
xorl %r8d, %r8d
movl $0x1, %edx
movl $0x5, %ecx
movl $0x2, %r9d
movl %r8d, %esi
callq 0xd6df0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl $0x2, %esi
movl $0x1, %r9d
movl $0x3f, %ecx
xorl %r8d, %r8d
movl %r9d, %edx
callq 0xd6df0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl $0x1, %r9d
movl $0x3f, %ecx
xorl %r8d, %r8d
movl %r9d, %esi
movl %r9d, %edx
callq 0xd6df0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
xorl %r8d, %r8d
movl $0x6, %edx
movl $0x3f, %ecx
movl $0x2, %r9d
movl %r8d, %esi
callq 0xd6df0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
xorl %esi, %esi
movl $0x1, %r9d
movl $0x3f, %ecx
movl $0x2, %r8d
movl %r9d, %edx
callq 0xd6df0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0xd6d30
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl $0x2, %esi
movl $0x1, %r8d
movl $0x3f, %ecx
xorl %r9d, %r9d
movl %r8d, %edx
callq 0xd6df0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl $0x1, %r8d
movl $0x3f, %ecx
xorl %r9d, %r9d
movl %r8d, %esi
movl %r8d, %edx
callq 0xd6df0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
xorl %r9d, %r9d
movl $0x1, %r8d
movl $0x3f, %ecx
movl %r9d, %esi
movl %r8d, %edx
callq 0xd6df0
movq %rax, 0x10(%rsp)
jmp 0xd6d22
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
xorl %edx, %edx
movl $0x1, %ecx
callq 0xd6d30
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
movl $0x1, %edx
movl $0x5, %ecx
xorl %r8d, %r8d
movl $0x2, %r9d
callq 0xd6e70
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
movl $0x6, %edx
movl $0x3f, %ecx
xorl %r8d, %r8d
movl $0x2, %r9d
callq 0xd6e70
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
movl $0x1, %r9d
movl $0x3f, %ecx
movl $0x2, %r8d
movl %r9d, %edx
callq 0xd6e70
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0xd6d30
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %esi
movl $0x1, %r8d
movl $0x3f, %ecx
xorl %r9d, %r9d
movl %r8d, %edx
callq 0xd6e70
movq %rax, 0x10(%rsp)
addq $0x28, %rsp
retq
nopw (%rax,%rax)