// File: tomfunkhouser[P]gaps/pkgs/png/pngrtran.c
// Function: png_do_unshift
void /* PRIVATE */
png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
{
   png_debug(1, "in png_do_unshift");

   if (
       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
   {
      int shift[4];
      int channels = 0;
      int c;
      png_uint_16 value = 0;
      png_uint_32 row_width = row_info->width;

      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
      {
         shift[channels++] = row_info->bit_depth - sig_bits->red;
         shift[channels++] = row_info->bit_depth - sig_bits->green;
         shift[channels++] = row_info->bit_depth - sig_bits->blue;
      }
      else
      {
         shift[channels++] = row_info->bit_depth - sig_bits->gray;
      }
      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
      {
         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
      }

      for (c = 0; c < channels; c++)
      {
         if (shift[c] <= 0)
            shift[c] = 0;
         else
            value = 1;
      }

      if (!value)
         return;

      switch (row_info->bit_depth)
      {
         case 2:
         {
            png_bytep bp;
            png_uint_32 i;
            png_uint_32 istop = row_info->rowbytes;

            for (bp = row, i = 0; i < istop; i++)
            {
               *bp >>= 1;
               *bp++ &= 0x55;
            }
            break;
         }

         case 4:
         {
            png_bytep bp = row;
            png_uint_32 i;
            png_uint_32 istop = row_info->rowbytes;
            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
               (png_byte)((int)0xf >> shift[0]));

            for (i = 0; i < istop; i++)
            {
               *bp >>= shift[0];
               *bp++ &= mask;
            }
            break;
         }

         case 8:
         {
            png_bytep bp = row;
            png_uint_32 i;
            png_uint_32 istop = row_width * channels;

            for (i = 0; i < istop; i++)
            {
               *bp++ >>= shift[i%channels];
            }
            break;
         }

         case 16:
         {
            png_bytep bp = row;
            png_uint_32 i;
            png_uint_32 istop = channels * row_width;

            for (i = 0; i < istop; i++)
            {
               value = (png_uint_16)((*bp << 8) + *(bp + 1));
               value >>= shift[i%channels];
               *bp++ = (png_byte)(value >> 8);
               *bp++ = (png_byte)(value & 0xff);
            }
            break;
         }
      }
   }
}

// Assembly:
pushq %rax
movq %rdi, (%rsp)
movq %rsi, -0x8(%rsp)
movq %rdx, -0x10(%rsp)
movq (%rsp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x3, %eax
je 0x1106ef
movl $0x0, -0x24(%rsp)
movw $0x0, -0x2a(%rsp)
movq (%rsp), %rax
movl (%rax), %eax
movl %eax, -0x30(%rsp)
movq (%rsp), %rax
movzbl 0x10(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x11040c
movq (%rsp), %rax
movzbl 0x11(%rax), %ecx
movq -0x10(%rsp), %rax
movzbl (%rax), %eax
subl %eax, %ecx
movl -0x24(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rsp)
cltq
movl %ecx, -0x20(%rsp,%rax,4)
movq (%rsp), %rax
movzbl 0x11(%rax), %ecx
movq -0x10(%rsp), %rax
movzbl 0x1(%rax), %eax
subl %eax, %ecx
movl -0x24(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rsp)
cltq
movl %ecx, -0x20(%rsp,%rax,4)
movq (%rsp), %rax
movzbl 0x11(%rax), %ecx
movq -0x10(%rsp), %rax
movzbl 0x2(%rax), %eax
subl %eax, %ecx
movl -0x24(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rsp)
cltq
movl %ecx, -0x20(%rsp,%rax,4)
jmp 0x110432
movq (%rsp), %rax
movzbl 0x11(%rax), %ecx
movq -0x10(%rsp), %rax
movzbl 0x3(%rax), %eax
subl %eax, %ecx
movl -0x24(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rsp)
cltq
movl %ecx, -0x20(%rsp,%rax,4)
movq (%rsp), %rax
movzbl 0x10(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x110468
movq (%rsp), %rax
movzbl 0x11(%rax), %ecx
movq -0x10(%rsp), %rax
movzbl 0x4(%rax), %eax
subl %eax, %ecx
movl -0x24(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rsp)
cltq
movl %ecx, -0x20(%rsp,%rax,4)
movl $0x0, -0x28(%rsp)
movl -0x28(%rsp), %eax
cmpl -0x24(%rsp), %eax
jge 0x1104ab
movslq -0x28(%rsp), %rax
cmpl $0x0, -0x20(%rsp,%rax,4)
jg 0x110495
movslq -0x28(%rsp), %rax
movl $0x0, -0x20(%rsp,%rax,4)
jmp 0x11049c
movw $0x1, -0x2a(%rsp)
jmp 0x11049e
movl -0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rsp)
jmp 0x110470
cmpw $0x0, -0x2a(%rsp)
jne 0x1104b8
jmp 0x1106ef
movq (%rsp), %rax
movzbl 0x11(%rax), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0x80(%rsp)
subl $0xe, %eax
ja 0x1106ed
movq -0x80(%rsp), %rax
leaq 0x291e9(%rip), %rcx     # 0x1396c8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%rsp), %rax
movq 0x8(%rax), %rax
movl %eax, -0x40(%rsp)
movq -0x8(%rsp), %rax
movq %rax, -0x38(%rsp)
movl $0x0, -0x3c(%rsp)
movl -0x3c(%rsp), %eax
cmpl -0x40(%rsp), %eax
jae 0x110542
movq -0x38(%rsp), %rax
movzbl (%rax), %ecx
sarl %ecx
movb %cl, (%rax)
movq -0x38(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x38(%rsp)
movzbl (%rax), %ecx
andl $0x55, %ecx
movb %cl, (%rax)
movl -0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rsp)
jmp 0x110506
jmp 0x1106ed
movq -0x8(%rsp), %rax
movq %rax, -0x48(%rsp)
movq (%rsp), %rax
movq 0x8(%rax), %rax
movl %eax, -0x50(%rsp)
movl -0x20(%rsp), %ecx
movl $0xf0, %eax
sarl %cl, %eax
andl $0xf0, %eax
movl -0x20(%rsp), %ecx
movl $0xf, %edx
sarl %cl, %edx
movl %edx, %ecx
movzbl %cl, %ecx
orl %ecx, %eax
movb %al, -0x51(%rsp)
movl $0x0, -0x4c(%rsp)
movl -0x4c(%rsp), %eax
cmpl -0x50(%rsp), %eax
jae 0x1105d1
movl -0x20(%rsp), %ecx
movq -0x48(%rsp), %rax
movzbl (%rax), %edx
sarl %cl, %edx
movl %edx, %ecx
movb %cl, (%rax)
movzbl -0x51(%rsp), %edx
movq -0x48(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x48(%rsp)
movzbl (%rax), %ecx
andl %edx, %ecx
movb %cl, (%rax)
movl -0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rsp)
jmp 0x11058b
jmp 0x1106ed
movq -0x8(%rsp), %rax
movq %rax, -0x60(%rsp)
movl -0x30(%rsp), %eax
imull -0x24(%rsp), %eax
movl %eax, -0x68(%rsp)
movl $0x0, -0x64(%rsp)
movl -0x64(%rsp), %eax
cmpl -0x68(%rsp), %eax
jae 0x110636
movl -0x64(%rsp), %eax
xorl %edx, %edx
divl -0x24(%rsp)
movl %edx, %eax
movl -0x20(%rsp,%rax,4), %ecx
movq -0x60(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x60(%rsp)
movzbl (%rax), %edx
sarl %cl, %edx
movl %edx, %ecx
movb %cl, (%rax)
movl -0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rsp)
jmp 0x1105f5
jmp 0x1106ed
movq -0x8(%rsp), %rax
movq %rax, -0x70(%rsp)
movl -0x24(%rsp), %eax
imull -0x30(%rsp), %eax
movl %eax, -0x78(%rsp)
movl $0x0, -0x74(%rsp)
movl -0x74(%rsp), %eax
cmpl -0x78(%rsp), %eax
jae 0x1106eb
movq -0x70(%rsp), %rax
movzbl (%rax), %eax
shll $0x8, %eax
movq -0x70(%rsp), %rcx
movzbl 0x1(%rcx), %ecx
addl %ecx, %eax
movw %ax, -0x2a(%rsp)
movl -0x74(%rsp), %eax
xorl %edx, %edx
divl -0x24(%rsp)
movl %edx, %eax
movl -0x20(%rsp,%rax,4), %ecx
movzwl -0x2a(%rsp), %eax
sarl %cl, %eax
movw %ax, -0x2a(%rsp)
movzwl -0x2a(%rsp), %eax
sarl $0x8, %eax
movb %al, %cl
movq -0x70(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x70(%rsp)
movb %cl, (%rax)
movzwl -0x2a(%rsp), %eax
andl $0xff, %eax
movb %al, %cl
movq -0x70(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x70(%rsp)
movb %cl, (%rax)
movl -0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rsp)
jmp 0x11065a
jmp 0x1106ed
jmp 0x1106ef
popq %rax
retq
nopw %cs:(%rax,%rax)