// File: tomfunkhouser[P]gaps/pkgs/png/pngwutil.c
// Function: png_do_write_interlace
void /* PRIVATE */
png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
{
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */

   /* Start of interlace block */
   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};

   /* Offset to next interlace block */
   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};

   png_debug(1, "in png_do_write_interlace");

   /* We don't have to do anything on the last pass (6) */
   if (pass < 6)
   {
      /* Each pixel depth is handled separately */
      switch (row_info->pixel_depth)
      {
         case 1:
         {
            png_bytep sp;
            png_bytep dp;
            int shift;
            int d;
            int value;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            dp = row;
            d = 0;
            shift = 7;
            for (i = png_pass_start[pass]; i < row_width;
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 3);
               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 7;
                  *dp++ = (png_byte)d;
                  d = 0;
               }
               else
                  shift--;

            }
            if (shift != 7)
               *dp = (png_byte)d;
            break;
         }
         case 2:
         {
            png_bytep sp;
            png_bytep dp;
            int shift;
            int d;
            int value;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            dp = row;
            shift = 6;
            d = 0;
            for (i = png_pass_start[pass]; i < row_width;
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 2);
               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 6;
                  *dp++ = (png_byte)d;
                  d = 0;
               }
               else
                  shift -= 2;
            }
            if (shift != 6)
                   *dp = (png_byte)d;
            break;
         }
         case 4:
         {
            png_bytep sp;
            png_bytep dp;
            int shift;
            int d;
            int value;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            dp = row;
            shift = 4;
            d = 0;
            for (i = png_pass_start[pass]; i < row_width;
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 1);
               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 4;
                  *dp++ = (png_byte)d;
                  d = 0;
               }
               else
                  shift -= 4;
            }
            if (shift != 4)
               *dp = (png_byte)d;
            break;
         }
         default:
         {
            png_bytep sp;
            png_bytep dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
            png_size_t pixel_bytes;

            /* Start at the beginning */
            dp = row;
            /* Find out how many bytes each pixel takes up */
            pixel_bytes = (row_info->pixel_depth >> 3);
            /* Loop through the row, only looking at the pixels that
               matter */
            for (i = png_pass_start[pass]; i < row_width;
               i += png_pass_inc[pass])
            {
               /* Find out where the original pixel is */
               sp = row + (png_size_t)i * pixel_bytes;
               /* Move the pixel */
               if (dp != sp)
                  png_memcpy(dp, sp, pixel_bytes);
               /* Next pixel */
               dp += pixel_bytes;
            }
            break;
         }
      }
      /* Set new row width */
      row_info->width = (row_info->width +
         png_pass_inc[pass] - 1 -
         png_pass_start[pass]) /
         png_pass_inc[pass];
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
            row_info->width);
   }
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movq %rdi, 0x100(%rsp)
movq %rsi, 0xf8(%rsp)
movl %edx, 0xf4(%rsp)
movq 0x11afb(%rip), %rax     # 0x1404c0
movq %rax, 0xd0(%rsp)
movq 0x11af4(%rip), %rax     # 0x1404c8
movq %rax, 0xd8(%rsp)
movq 0x11aed(%rip), %rax     # 0x1404d0
movq %rax, 0xe0(%rsp)
movl 0x11ae7(%rip), %eax     # 0x1404d8
movl %eax, 0xe8(%rsp)
movq 0x11ae1(%rip), %rax     # 0x1404e0
movq %rax, 0xb0(%rsp)
movq 0x11ada(%rip), %rax     # 0x1404e8
movq %rax, 0xb8(%rsp)
movq 0x11ad3(%rip), %rax     # 0x1404f0
movq %rax, 0xc0(%rsp)
movl 0x11acd(%rip), %eax     # 0x1404f8
movl %eax, 0xc8(%rsp)
cmpl $0x6, 0xf4(%rsp)
jge 0x12ef5f
movq 0x100(%rsp), %rax
movzbl 0x13(%rax), %eax
movl %eax, 0x14(%rsp)
subl $0x1, %eax
je 0x12ea78
jmp 0x12ea57
movl 0x14(%rsp), %eax
subl $0x2, %eax
je 0x12ebd9
jmp 0x12ea66
movl 0x14(%rsp), %eax
subl $0x4, %eax
je 0x12eceb
jmp 0x12edf7
movq 0x100(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x8c(%rsp)
movq 0xf8(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl $0x0, 0x98(%rsp)
movl $0x7, 0x9c(%rsp)
movslq 0xf4(%rsp), %rax
movl 0xd0(%rsp,%rax,4), %eax
movl %eax, 0x90(%rsp)
movl 0x90(%rsp), %eax
cmpl 0x8c(%rsp), %eax
jae 0x12ebb7
movq 0xf8(%rsp), %rax
movl 0x90(%rsp), %ecx
shrl $0x3, %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
movzbl (%rax), %eax
movl 0x90(%rsp), %edx
andl $0x7, %edx
movl $0x7, %ecx
subl %edx, %ecx
sarl %cl, %eax
andl $0x1, %eax
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %eax
movl 0x9c(%rsp), %ecx
shll %cl, %eax
orl 0x98(%rsp), %eax
movl %eax, 0x98(%rsp)
cmpl $0x0, 0x9c(%rsp)
jne 0x12eb82
movl $0x7, 0x9c(%rsp)
movl 0x98(%rsp), %eax
movb %al, %cl
movq 0xa0(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0xa0(%rsp)
movb %cl, (%rax)
movl $0x0, 0x98(%rsp)
jmp 0x12eb93
movl 0x9c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0x12eb95
movslq 0xf4(%rsp), %rax
movl 0xb0(%rsp,%rax,4), %eax
addl 0x90(%rsp), %eax
movl %eax, 0x90(%rsp)
jmp 0x12eac5
cmpl $0x7, 0x9c(%rsp)
je 0x12ebd4
movl 0x98(%rsp), %eax
movb %al, %cl
movq 0xa0(%rsp), %rax
movb %cl, (%rax)
jmp 0x12eea9
movq 0x100(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x64(%rsp)
movq 0xf8(%rsp), %rax
movq %rax, 0x78(%rsp)
movl $0x6, 0x74(%rsp)
movl $0x0, 0x70(%rsp)
movslq 0xf4(%rsp), %rax
movl 0xd0(%rsp,%rax,4), %eax
movl %eax, 0x68(%rsp)
movl 0x68(%rsp), %eax
cmpl 0x64(%rsp), %eax
jae 0x12ecd2
movq 0xf8(%rsp), %rax
movl 0x68(%rsp), %ecx
shrl $0x2, %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rax
movzbl (%rax), %eax
movl 0x68(%rsp), %edx
andl $0x3, %edx
movl $0x3, %ecx
subl %edx, %ecx
shll %ecx
sarl %cl, %eax
andl $0x3, %eax
movl %eax, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
movl 0x74(%rsp), %ecx
shll %cl, %eax
orl 0x70(%rsp), %eax
movl %eax, 0x70(%rsp)
cmpl $0x0, 0x74(%rsp)
jne 0x12eca9
movl $0x6, 0x74(%rsp)
movl 0x70(%rsp), %eax
movb %al, %cl
movq 0x78(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x78(%rsp)
movb %cl, (%rax)
movl $0x0, 0x70(%rsp)
jmp 0x12ecb4
movl 0x74(%rsp), %eax
subl $0x2, %eax
movl %eax, 0x74(%rsp)
jmp 0x12ecb6
movslq 0xf4(%rsp), %rax
movl 0xb0(%rsp,%rax,4), %eax
addl 0x68(%rsp), %eax
movl %eax, 0x68(%rsp)
jmp 0x12ec17
cmpl $0x6, 0x74(%rsp)
je 0x12ece6
movl 0x70(%rsp), %eax
movb %al, %cl
movq 0x78(%rsp), %rax
movb %cl, (%rax)
jmp 0x12eea9
movq 0x100(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x3c(%rsp)
movq 0xf8(%rsp), %rax
movq %rax, 0x50(%rsp)
movl $0x4, 0x4c(%rsp)
movl $0x0, 0x48(%rsp)
movslq 0xf4(%rsp), %rax
movl 0xd0(%rsp,%rax,4), %eax
movl %eax, 0x40(%rsp)
movl 0x40(%rsp), %eax
cmpl 0x3c(%rsp), %eax
jae 0x12edde
movq 0xf8(%rsp), %rax
movl 0x40(%rsp), %ecx
shrl %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
movzbl (%rax), %eax
movl 0x40(%rsp), %edx
andl $0x1, %edx
movl $0x1, %ecx
subl %edx, %ecx
shll $0x2, %ecx
sarl %cl, %eax
andl $0xf, %eax
movl %eax, 0x44(%rsp)
movl 0x44(%rsp), %eax
movl 0x4c(%rsp), %ecx
shll %cl, %eax
orl 0x48(%rsp), %eax
movl %eax, 0x48(%rsp)
cmpl $0x0, 0x4c(%rsp)
jne 0x12edb5
movl $0x4, 0x4c(%rsp)
movl 0x48(%rsp), %eax
movb %al, %cl
movq 0x50(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x50(%rsp)
movb %cl, (%rax)
movl $0x0, 0x48(%rsp)
jmp 0x12edc0
movl 0x4c(%rsp), %eax
subl $0x4, %eax
movl %eax, 0x4c(%rsp)
jmp 0x12edc2
movslq 0xf4(%rsp), %rax
movl 0xb0(%rsp,%rax,4), %eax
addl 0x40(%rsp), %eax
movl %eax, 0x40(%rsp)
jmp 0x12ed29
cmpl $0x4, 0x4c(%rsp)
je 0x12edf2
movl 0x48(%rsp), %eax
movb %al, %cl
movq 0x50(%rsp), %rax
movb %cl, (%rax)
jmp 0x12eea9
movq 0x100(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x20(%rsp)
movq 0xf8(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x100(%rsp), %rax
movzbl 0x13(%rax), %eax
sarl $0x3, %eax
cltq
movq %rax, 0x18(%rsp)
movslq 0xf4(%rsp), %rax
movl 0xd0(%rsp,%rax,4), %eax
movl %eax, 0x24(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x20(%rsp), %eax
jae 0x12eea7
movq 0xf8(%rsp), %rax
movl 0x24(%rsp), %ecx
imulq 0x18(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x30(%rsp)
movq 0x28(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x12ee7f
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0xf3d0
movq 0x18(%rsp), %rax
addq 0x28(%rsp), %rax
movq %rax, 0x28(%rsp)
movslq 0xf4(%rsp), %rax
movl 0xb0(%rsp,%rax,4), %eax
addl 0x24(%rsp), %eax
movl %eax, 0x24(%rsp)
jmp 0x12ee3b
jmp 0x12eea9
movq 0x100(%rsp), %rax
movl (%rax), %eax
movslq 0xf4(%rsp), %rcx
addl 0xb0(%rsp,%rcx,4), %eax
subl $0x1, %eax
movslq 0xf4(%rsp), %rcx
subl 0xd0(%rsp,%rcx,4), %eax
movslq 0xf4(%rsp), %rcx
xorl %edx, %edx
divl 0xb0(%rsp,%rcx,4)
movl %eax, %ecx
movq 0x100(%rsp), %rax
movl %ecx, (%rax)
movq 0x100(%rsp), %rax
movzbl 0x13(%rax), %eax
cmpl $0x8, %eax
jl 0x12ef27
movq 0x100(%rsp), %rax
movl (%rax), %eax
movq 0x100(%rsp), %rcx
movzbl 0x13(%rcx), %ecx
shrq $0x3, %rcx
imulq %rcx, %rax
movq %rax, 0x8(%rsp)
jmp 0x12ef4e
movq 0x100(%rsp), %rax
movl (%rax), %eax
movq 0x100(%rsp), %rcx
movzbl 0x13(%rcx), %ecx
imulq %rcx, %rax
addq $0x7, %rax
shrq $0x3, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rcx
movq 0x100(%rsp), %rax
movq %rcx, 0x8(%rax)
addq $0x108, %rsp            # imm = 0x108
retq
nopw (%rax,%rax)