// File: cloudinary[P]fuif/transform/squeeze.h
// Function: fwd_hsqueeze(Image&, int, int)
void fwd_hsqueeze(Image &input, int c, int rc) {
    const Channel &chin = input.channel[c];

    v_printf(4,"Doing horizontal squeeze of channel %i to new channel %i\n",c,rc);

    Channel chout((chin.w+1)/2, chin.h, chin.minval, chin.maxval, chin.q, chin.hshift+1,chin.vshift,chin.hcshift+1,chin.vcshift);
    Channel chout_residual(chin.w-chout.w,chout.h,chout.minval-chout.maxval,chout.maxval-chout.minval,1, chin.hshift+1,chin.vshift,chin.hcshift,chin.vcshift);
    chout.component = chin.component;
    chout_residual.component = chin.component;

    for (int y=0; y<chout.h; y++) {
      for (int x=0; x<chout_residual.w; x++) {
        pixel_type A = chin.value(y,x*2);
        pixel_type B = chin.value(y,x*2+1);
        pixel_type avg = (A+B+(A>B))>>1;
        chout.value(y,x) = avg;
        pixel_type diff = A-B;
        pixel_type next_avg = avg;
        if (x+1<chout_residual.w) next_avg = (chin.value(y,x*2+2) + chin.value(y,x*2+3) + (chin.value(y,x*2+2) > chin.value(y,x*2+3))) >> 1;  // which will be chout.value(y,x+1)
        else if (chin.w & 1) next_avg = (chin.value(y,x*2+2));

        pixel_type left = (x>0 ? chin.value(y,x*2-1) : avg);
        pixel_type tendency=smooth_tendency(left,avg,next_avg);

        chout_residual.value(y,x) = diff-tendency;

      }
      if (chin.w & 1) {
        int x = chout.w-1;
        chout.value(y,x) = chin.value(y,x*2);
      }
    }
    input.channel[c] = chout;
//    chout_residual.actual_minmax(&chout_residual.minval, &chout_residual.maxval);
    input.channel.insert(input.channel.begin()+rc, chout_residual);
}

// Assembly:
pushq %rbx
subq $0x170, %rsp            # imm = 0x170
movq %rdi, 0x168(%rsp)
movl %esi, 0x164(%rsp)
movl %edx, 0x160(%rsp)
movq 0x168(%rsp), %rdi
movslq 0x164(%rsp), %rsi
callq 0x4ba0
movq %rax, 0x158(%rsp)
movl 0x164(%rsp), %edx
movl 0x160(%rsp), %ecx
leaq 0x3ad34(%rip), %rsi     # 0x46b74
xorl %eax, %eax
movl $0x4, %edi
callq 0x3a770
movq 0x158(%rsp), %rax
movq %rax, 0x88(%rsp)
movl 0x18(%rax), %esi
movl 0x1c(%rax), %edx
movl %esi, %edi
incl %edi
movl %esi, %ecx
shrl $0x1f, %edi
movl %edi, %esi
leal 0x1(%rcx,%rsi), %esi
sarl %esi
movswl 0x20(%rax), %ecx
movswl 0x22(%rax), %r8d
movl 0x28(%rax), %r9d
movl 0x2c(%rax), %edi
incl %edi
movl 0x30(%rax), %r10d
movl 0x34(%rax), %r11d
incl %r11d
movl 0x38(%rax), %ebx
movq %rsp, %rax
movl %ebx, 0x18(%rax)
movl %r11d, 0x10(%rax)
movl %r10d, 0x8(%rax)
movl %edi, (%rax)
leaq 0x118(%rsp), %rdi
callq 0x12200
movq 0x158(%rsp), %rdi
movl 0x130(%rsp), %eax
movl 0x134(%rsp), %edx
movl 0x18(%rdi), %esi
movl 0x2c(%rdi), %r8d
subl %eax, %esi
movswl 0x138(%rsp), %r9d
movswl 0x13a(%rsp), %eax
movl %r9d, %ecx
subl %eax, %ecx
subl %r9d, %eax
incl %r8d
movl 0x30(%rdi), %r9d
movl 0x34(%rdi), %r10d
movl 0x38(%rdi), %r11d
movq %rsp, %rdi
movl %r11d, 0x18(%rdi)
movl %r10d, 0x10(%rdi)
movl %r9d, 0x8(%rdi)
movl %r8d, (%rdi)
movswl %cx, %ecx
movswl %ax, %r8d
leaq 0xd8(%rsp), %rdi
movl $0x1, %r9d
callq 0x12200
jmp 0xbf25
movq 0x158(%rsp), %rax
movl 0x3c(%rax), %eax
movl %eax, 0x154(%rsp)
movq 0x158(%rsp), %rax
movl 0x3c(%rax), %eax
movl %eax, 0x114(%rsp)
movl $0x0, 0xc8(%rsp)
movl 0xc8(%rsp), %eax
cmpl 0x134(%rsp), %eax
jge 0xc38c
movl $0x0, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
cmpl 0xf0(%rsp), %eax
jge 0xc2fe
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %edx
addl %edx, %edx
callq 0x12ba0
movw %ax, 0x86(%rsp)
jmp 0xbfae
movw 0x86(%rsp), %ax
movw %ax, 0xc2(%rsp)
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %ecx
movl %ecx, %eax
leal 0x1(%rax,%rax), %edx
callq 0x12ba0
movw %ax, 0x84(%rsp)
jmp 0xbfe9
movw 0x84(%rsp), %ax
movw %ax, 0xc0(%rsp)
movswl 0xc2(%rsp), %ecx
movswl 0xc0(%rsp), %edx
movl %ecx, %eax
addl %edx, %eax
subl %edx, %ecx
setg %cl
movzbl %cl, %ecx
addl %ecx, %eax
shrl %eax
movw %ax, 0xbe(%rsp)
movw 0xbe(%rsp), %ax
movw %ax, 0x76(%rsp)
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %edx
leaq 0x118(%rsp), %rdi
callq 0x12110
movq %rax, 0x78(%rsp)
jmp 0xc050
movq 0x78(%rsp), %rax
movw 0x76(%rsp), %cx
movw %cx, (%rax)
movswl 0xc2(%rsp), %eax
movswl 0xc0(%rsp), %ecx
subl %ecx, %eax
movw %ax, 0xbc(%rsp)
movw 0xbe(%rsp), %ax
movw %ax, 0xba(%rsp)
movl 0xc4(%rsp), %eax
addl $0x1, %eax
cmpl 0xf0(%rsp), %eax
jge 0xc1cf
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %ecx
movl %ecx, %eax
leal 0x2(%rax,%rax), %edx
callq 0x12ba0
movw %ax, 0x74(%rsp)
jmp 0xc0c6
movw 0x74(%rsp), %ax
cwtl
movl %eax, 0x6c(%rsp)
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %ecx
movl %ecx, %eax
leal 0x3(%rax,%rax), %edx
callq 0x12ba0
movw %ax, 0x72(%rsp)
jmp 0xc0f8
movl 0x6c(%rsp), %eax
movw 0x72(%rsp), %cx
movswl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x64(%rsp)
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %ecx
movl %ecx, %eax
leal 0x2(%rax,%rax), %edx
callq 0x12ba0
movw %ax, 0x6a(%rsp)
jmp 0xc132
movw 0x6a(%rsp), %ax
cwtl
movl %eax, 0x5c(%rsp)
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %ecx
movl %ecx, %eax
leal 0x3(%rax,%rax), %edx
callq 0x12ba0
movw %ax, 0x62(%rsp)
jmp 0xc164
movl 0x64(%rsp), %eax
movl 0x5c(%rsp), %ecx
movw 0x62(%rsp), %dx
movswl %dx, %edx
cmpl %edx, %ecx
setg %cl
andb $0x1, %cl
movzbl %cl, %ecx
addl %ecx, %eax
sarl %eax
movw %ax, 0xba(%rsp)
jmp 0xc219
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
jmp 0xc450
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x12380
jmp 0xc450
movq 0x158(%rsp), %rax
movl 0x18(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xc217
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %ecx
movl %ecx, %eax
leal 0x2(%rax,%rax), %edx
callq 0x12ba0
movw %ax, 0x5a(%rsp)
jmp 0xc20a
movw 0x5a(%rsp), %ax
movw %ax, 0xba(%rsp)
jmp 0xc219
cmpl $0x0, 0xc4(%rsp)
jle 0xc257
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %ecx
movl %ecx, %eax
leal -0x1(%rax,%rax), %edx
callq 0x12ba0
movw %ax, 0x58(%rsp)
jmp 0xc24b
movw 0x58(%rsp), %ax
movw %ax, 0x56(%rsp)
jmp 0xc264
movw 0xbe(%rsp), %ax
movw %ax, 0x56(%rsp)
movw 0x56(%rsp), %ax
movw %ax, 0xb8(%rsp)
movswl 0xb8(%rsp), %edi
movswl 0xbe(%rsp), %esi
movswl 0xba(%rsp), %edx
callq 0x131f0
movw %ax, 0x54(%rsp)
jmp 0xc295
movw 0x54(%rsp), %ax
movw %ax, 0xb6(%rsp)
movzwl 0xbc(%rsp), %eax
movzwl 0xb6(%rsp), %ecx
subl %ecx, %eax
movw %ax, 0x46(%rsp)
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %edx
leaq 0xd8(%rsp), %rdi
callq 0x12110
movq %rax, 0x48(%rsp)
jmp 0xc2db
movq 0x48(%rsp), %rax
movw 0x46(%rsp), %cx
movw %cx, (%rax)
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0xbf73
movq 0x158(%rsp), %rax
movl 0x18(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xc374
movl 0x130(%rsp), %eax
decl %eax
movl %eax, 0xb0(%rsp)
movq 0x158(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xb0(%rsp), %edx
addl %edx, %edx
callq 0x12ba0
movw %ax, 0x44(%rsp)
jmp 0xc345
movl 0xc8(%rsp), %esi
movl 0xb0(%rsp), %edx
leaq 0x118(%rsp), %rdi
callq 0x12110
movq %rax, 0x38(%rsp)
jmp 0xc367
movq 0x38(%rsp), %rax
movw 0x44(%rsp), %cx
movw %cx, (%rax)
jmp 0xc376
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0xbf54
movq 0x168(%rsp), %rdi
movslq 0x164(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
leaq 0x118(%rsp), %rsi
callq 0x12390
jmp 0xc3b3
movq 0x168(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x127d0
movq %rax, 0x98(%rsp)
movslq 0x160(%rsp), %rsi
leaq 0x98(%rsp), %rdi
callq 0x12800
movq %rax, 0xa0(%rsp)
leaq 0xa8(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x12840
movq 0x28(%rsp), %rdi
movq 0xa8(%rsp), %rsi
leaq 0xd8(%rsp), %rdx
callq 0x12c20
movq %rax, 0x30(%rsp)
jmp 0xc420
movq 0x30(%rsp), %rax
movq %rax, 0x90(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x12380
leaq 0x118(%rsp), %rdi
callq 0x12380
addq $0x170, %rsp            # imm = 0x170
popq %rbx
retq
leaq 0x118(%rsp), %rdi
callq 0x12380
movq 0xd0(%rsp), %rdi
callq 0x36a0
nopw (%rax,%rax)