// File: /workspace/github_cpp_makefile_star2_O2/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, 0x10(%rsp)
movq %rdi, %r12
movq %rsi, 0x18(%rsp)
movl 0x1c(%rsi), %ebx
movq %rdx, 0x8(%rsp)
leaq -0x8(%rdx), %rdi
movl 0x30(%r12), %edx
movl 0x13c(%r12), %esi
addl $0x2, %esi
movl %ebx, %ecx
shll $0x4, %ecx
callq 0x6c3d0
movl 0x110(%r12), %eax
imull $-0x50, %eax, %ecx
addl $0x4000, %ecx           # imm = 0x4000
shll $0x4, %eax
leal -0x8(,%rbx,8), %edx
orq $0x6, %rdx
xorl %edi, %edi
xorl %r9d, %r9d
movq 0x18(%rsp), %rsi
movslq 0xc(%rsi), %r8
cmpq %r8, %r9
jge 0x6c1e0
movq 0x8(%rsp), %rsi
movq -0x8(%rsi,%rdi,8), %r8
movq (%rsi,%rdi,8), %r10
movq 0x8(%rsi,%rdi,8), %r11
movq %r9, (%rsp)
movq 0x10(%rsi,%rdi,8), %r9
movzbl (%r10), %ebx
movzbl 0x1(%r10), %ebp
movzbl (%r11), %r14d
addl %ebx, %r14d
movzbl 0x1(%r11), %ebx
addl %ebp, %ebx
addl %r14d, %ebx
movzbl (%r8), %ebp
movzbl 0x1(%r8), %r15d
movzbl (%r9), %r12d
movzbl 0x1(%r9), %r13d
addl %ebp, %r15d
addl %r14d, %r15d
movzbl 0x2(%r10), %r14d
addl %r12d, %r13d
addl %r14d, %r13d
movzbl 0x2(%r11), %r14d
addl %r15d, %r13d
addl %r14d, %r13d
movzbl 0x2(%r8), %r14d
movzbl 0x2(%r9), %r15d
addl %r14d, %r15d
addl %ebp, %r12d
addl %r15d, %r12d
leal (%r12,%r13,2), %ebp
movl %ecx, %r14d
imull %ebx, %r14d
movl %eax, %ebx
imull %ebp, %ebx
addl %r14d, %ebx
addl $0x8000, %ebx           # imm = 0x8000
movq 0x10(%rsp), %rsi
movq (%rsp), %r14
movq (%rsi,%r14,8), %r12
addq $0x2, %rdi
shrl $0x10, %ebx
movb %bl, (%r12)
xorl %r13d, %r13d
movzbl 0x2(%r10,%r13,2), %r14d
movzbl 0x3(%r10,%r13,2), %r15d
movzbl 0x2(%r9,%r13,2), %ebp
cmpl %r13d, %edx
je 0x6c151
addl %r14d, %r15d
movzbl 0x2(%r11,%r13,2), %r14d
movzbl 0x3(%r11,%r13,2), %ebx
addl %r14d, %ebx
addl %r15d, %ebx
movzbl 0x2(%r8,%r13,2), %r14d
movzbl 0x3(%r8,%r13,2), %r15d
addl %r14d, %r15d
movzbl 0x3(%r9,%r13,2), %r14d
addl %ebp, %r14d
addl %r15d, %r14d
movzbl 0x1(%r10,%r13,2), %ebp
movzbl 0x4(%r10,%r13,2), %r15d
addl %ebp, %r15d
movzbl 0x1(%r11,%r13,2), %ebp
addl %r15d, %ebp
addl %r14d, %ebp
movzbl 0x4(%r11,%r13,2), %r14d
addl %ebp, %r14d
movzbl 0x1(%r8,%r13,2), %ebp
movzbl 0x4(%r8,%r13,2), %r15d
addl %ebp, %r15d
movzbl 0x1(%r9,%r13,2), %ebp
addl %r15d, %ebp
movzbl 0x4(%r9,%r13,2), %r15d
leal (%rbp,%r14,2), %ebp
addl %r15d, %ebp
movl %ecx, %r14d
imull %ebx, %r14d
movl %eax, %ebx
imull %ebp, %ebx
addl %r14d, %ebx
addl $0x8000, %ebx           # imm = 0x8000
shrl $0x10, %ebx
movb %bl, 0x1(%r12,%r13)
incq %r13
jmp 0x6c097
movzbl 0x2(%r11,%r13,2), %ebx
movq %rdi, 0x20(%rsp)
movzbl 0x3(%r11,%r13,2), %edi
addl %r15d, %edi
addl %r14d, %ebx
addl %edi, %ebx
movzbl 0x2(%r8,%r13,2), %r14d
movzbl 0x3(%r8,%r13,2), %r15d
movzbl 0x3(%r9,%r13,2), %esi
movzbl 0x1(%r10,%r13,2), %r10d
movzbl 0x1(%r11,%r13,2), %r11d
addl %r15d, %r14d
addl %edi, %r14d
addl %esi, %ebp
addl %r10d, %ebp
addl %r14d, %ebp
addl %r11d, %ebp
movzbl 0x1(%r8,%r13,2), %edi
movzbl 0x1(%r9,%r13,2), %r8d
addl %edi, %r8d
addl %r15d, %esi
addl %r8d, %esi
leal (%rsi,%rbp,2), %esi
movl %ecx, %edi
imull %ebx, %edi
movl %eax, %r8d
imull %esi, %r8d
leal (%rdi,%r8), %esi
addl $0x8000, %esi           # imm = 0x8000
movq 0x20(%rsp), %rdi
shrl $0x10, %esi
movb %sil, 0x1(%r12,%r13)
movq (%rsp), %r9
incq %r9
jmp 0x6bfda
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq