// File: /workspace/github_cpp_makefile_star2_O1/tomfunkhouser[P]gaps/pkgs/jpeg/jcsample.c
// Function: h2v2_smooth_downsample
METHODDEF(void)
h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
			JSAMPARRAY input_data, JSAMPARRAY output_data)
{
  int inrow, outrow;
  JDIMENSION colctr;
  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
  register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
  INT32 membersum, neighsum, memberscale, neighscale;

  /* Expand input data enough to let all the output samples be generated
   * by the standard loop.  Special-casing padded output would be more
   * efficient.
   */
  expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
		    cinfo->image_width, output_cols * 2);

  /* We don't bother to form the individual "smoothed" input pixel values;
   * we can directly compute the output which is the average of the four
   * smoothed values.  Each of the four member pixels contributes a fraction
   * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
   * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
   * output.  The four corner-adjacent neighbor pixels contribute a fraction
   * SF to just one smoothed pixel, or SF/4 to the final output; while the
   * eight edge-adjacent neighbors contribute SF to each of two smoothed
   * pixels, or SF/2 overall.  In order to use integer arithmetic, these
   * factors are scaled by 2^16 = 65536.
   * Also recall that SF = smoothing_factor / 1024.
   */

  memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
  neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */

  inrow = 0;
  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
    outptr = output_data[outrow];
    inptr0 = input_data[inrow];
    inptr1 = input_data[inrow+1];
    above_ptr = input_data[inrow-1];
    below_ptr = input_data[inrow+2];

    /* Special case for first column: pretend column -1 is same as column 0 */
    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
	       GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
	       GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
    neighsum += neighsum;
    neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
		GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
    membersum = membersum * memberscale + neighsum * neighscale;
    *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
    inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;

    for (colctr = output_cols - 2; colctr > 0; colctr--) {
      /* sum of pixels directly mapped to this output element */
      membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
		  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
      /* sum of edge-neighbor pixels */
      neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
		 GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
		 GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
		 GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
      /* The edge-neighbors count twice as much as corner-neighbors */
      neighsum += neighsum;
      /* Add in the corner-neighbors */
      neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
		  GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
      /* form final output scaled up by 2^16 */
      membersum = membersum * memberscale + neighsum * neighscale;
      /* round, descale and output it */
      *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
      inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
    }

    /* Special case for last column */
    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
	       GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
	       GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
    neighsum += neighsum;
    neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
		GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
    membersum = membersum * memberscale + neighsum * neighscale;
    *outptr = (JSAMPLE) ((membersum + 32768) >> 16);

    inrow += 2;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, 0x20(%rsp)
movq %rdx, %r14
movq %rsi, 0x8(%rsp)
movl 0x1c(%rsi), %ebp
movl 0x30(%rdi), %r12d
movq %rdi, (%rsp)
movl 0x13c(%rdi), %ebx
movl %ebp, %r13d
shll $0x4, %r13d
movl %r13d, %eax
subl %r12d, %eax
testl %eax, %eax
setle %al
cmpl $-0x1, %ebx
setl %cl
orb %al, %cl
jne 0x775e5
addl $0x2, %ebx
movl %r12d, %eax
notl %eax
addl %eax, %r13d
incq %r13
xorl %r15d, %r15d
movq -0x8(%r14,%r15,8), %rdi
movzbl -0x1(%rdi,%r12), %esi
addq %r12, %rdi
movq %r13, %rdx
callq 0xe260
incq %r15
cmpq %r15, %rbx
jne 0x775c7
movq 0x8(%rsp), %rax
cmpl $0x0, 0xc(%rax)
jle 0x77823
shll $0x3, %ebp
movq (%rsp), %rax
movl 0x110(%rax), %eax
shll $0x4, %eax
leal (%rax,%rax,4), %edx
movl $0x4000, %ecx           # imm = 0x4000
subl %edx, %ecx
addl $-0x8, %ebp
addq $0x6, %rbp
xorl %edx, %edx
movq $0x0, 0x10(%rsp)
movq %r14, 0x18(%rsp)
movq %rdx, (%rsp)
movq 0x10(%rsp), %rdx
movq -0x8(%r14,%rdx,8), %rdi
movq (%r14,%rdx,8), %r10
movq 0x8(%r14,%rdx,8), %r9
movq 0x10(%r14,%rdx,8), %r8
movzbl (%r10), %r11d
movzbl 0x1(%r10), %ebx
movzbl (%r9), %r15d
addl %r11d, %r15d
movzbl 0x1(%r9), %r11d
addl %ebx, %r11d
addl %r15d, %r11d
movzbl (%rdi), %ebx
movzbl 0x1(%rdi), %r12d
movzbl (%r8), %r13d
movzbl 0x1(%r8), %r14d
addl %ebx, %r12d
addl %r15d, %r12d
movzbl 0x2(%r10), %r15d
addl %r13d, %r14d
addl %r15d, %r14d
movzbl 0x2(%r9), %r15d
addl %r12d, %r14d
addl %r15d, %r14d
movzbl 0x2(%rdi), %r15d
movzbl 0x2(%r8), %r12d
addl %r15d, %r12d
addl %ebx, %r13d
addl %r12d, %r13d
leal (%r13,%r14,2), %ebx
imull %ecx, %r11d
imull %eax, %ebx
addl %r11d, %ebx
addl $0x8000, %ebx           # imm = 0x8000
movq 0x20(%rsp), %rsi
movq (%rsp), %r11
movq (%rsi,%r11,8), %r11
addq $0x2, %rdx
movq %rdx, 0x10(%rsp)
shrl $0x10, %ebx
movb %bl, (%r11)
xorl %r12d, %r12d
movzbl 0x2(%r10,%r12,2), %ebx
movzbl 0x3(%r10,%r12,2), %r14d
addl %ebx, %r14d
movzbl 0x2(%r9,%r12,2), %r15d
movzbl 0x3(%r9,%r12,2), %ebx
addl %r15d, %ebx
addl %r14d, %ebx
movzbl 0x2(%rdi,%r12,2), %r14d
movzbl 0x3(%rdi,%r12,2), %r15d
addl %r14d, %r15d
movzbl 0x2(%r8,%r12,2), %r14d
movzbl 0x3(%r8,%r12,2), %r13d
addl %r14d, %r13d
addl %r15d, %r13d
movzbl 0x1(%r10,%r12,2), %r14d
movzbl 0x4(%r10,%r12,2), %r15d
addl %r14d, %r15d
movzbl 0x1(%r9,%r12,2), %r14d
addl %r15d, %r14d
addl %r13d, %r14d
movzbl 0x4(%r9,%r12,2), %r15d
addl %r14d, %r15d
movzbl 0x1(%rdi,%r12,2), %r14d
movzbl 0x4(%rdi,%r12,2), %r13d
addl %r14d, %r13d
movzbl 0x1(%r8,%r12,2), %r14d
addl %r13d, %r14d
movzbl 0x4(%r8,%r12,2), %r13d
leal (%r14,%r15,2), %r14d
addl %r13d, %r14d
imull %ecx, %ebx
imull %eax, %r14d
addl %r14d, %ebx
addl $0x8000, %ebx           # imm = 0x8000
shrl $0x10, %ebx
movb %bl, 0x1(%r11,%r12)
incq %r12
cmpl %r12d, %ebp
jne 0x776d0
movzbl 0x2(%r10,%r12,2), %r14d
movzbl 0x3(%r10,%r12,2), %r15d
movzbl 0x2(%r9,%r12,2), %ebx
addl %r14d, %ebx
movzbl 0x3(%r9,%r12,2), %r14d
addl %r15d, %r14d
addl %r14d, %ebx
movzbl 0x2(%rdi,%r12,2), %r15d
movzbl 0x3(%rdi,%r12,2), %r13d
movzbl 0x2(%r8,%r12,2), %esi
addl %r13d, %r15d
addl %r14d, %r15d
movzbl 0x3(%r8,%r12,2), %r14d
movzbl 0x1(%r10,%r12,2), %r10d
addl %r14d, %esi
addl %r10d, %esi
addl %r15d, %esi
movzbl 0x1(%r9,%r12,2), %r9d
addl %r9d, %esi
movzbl 0x1(%rdi,%r12,2), %edi
movzbl 0x1(%r8,%r12,2), %r8d
addl %edi, %r8d
addl %r13d, %r14d
addl %r8d, %r14d
leal (%r14,%rsi,2), %esi
imull %ecx, %ebx
imull %eax, %esi
addl %ebx, %esi
addl $0x8000, %esi           # imm = 0x8000
shrl $0x10, %esi
movb %sil, 0x1(%r11,%r12)
movq (%rsp), %rdx
incq %rdx
movq 0x8(%rsp), %rsi
movslq 0xc(%rsi), %rsi
cmpq %rsi, %rdx
movq 0x18(%rsp), %r14
jl 0x77625
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq