// File: /workspace/github_c_makefile_star2_O2/enzo1982[P]smooth/libraries/libwebp/src/dec/frame_dec.c
// Function: ReconstructRow
static void ReconstructRow(const VP8Decoder* const dec,
                           const VP8ThreadContext* ctx) {
  int j;
  int mb_x;
  const int mb_y = ctx->mb_y_;
  const int cache_id = ctx->id_;
  uint8_t* const y_dst = dec->yuv_b_ + Y_OFF;
  uint8_t* const u_dst = dec->yuv_b_ + U_OFF;
  uint8_t* const v_dst = dec->yuv_b_ + V_OFF;

  // Initialize left-most block.
  for (j = 0; j < 16; ++j) {
    y_dst[j * BPS - 1] = 129;
  }
  for (j = 0; j < 8; ++j) {
    u_dst[j * BPS - 1] = 129;
    v_dst[j * BPS - 1] = 129;
  }

  // Init top-left sample on left column too.
  if (mb_y > 0) {
    y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129;
  } else {
    // we only need to do this init once at block (0,0).
    // Afterward, it remains valid for the whole topmost row.
    memset(y_dst - BPS - 1, 127, 16 + 4 + 1);
    memset(u_dst - BPS - 1, 127, 8 + 1);
    memset(v_dst - BPS - 1, 127, 8 + 1);
  }

  // Reconstruct one row.
  for (mb_x = 0; mb_x < dec->mb_w_; ++mb_x) {
    const VP8MBData* const block = ctx->mb_data_ + mb_x;

    // Rotate in the left samples from previously decoded block. We move four
    // pixels at a time for alignment reason, and because of in-loop filter.
    if (mb_x > 0) {
      for (j = -1; j < 16; ++j) {
        Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]);
      }
      for (j = -1; j < 8; ++j) {
        Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]);
        Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]);
      }
    }
    {
      // bring top samples into the cache
      VP8TopSamples* const top_yuv = dec->yuv_t_ + mb_x;
      const int16_t* const coeffs = block->coeffs_;
      uint32_t bits = block->non_zero_y_;
      int n;

      if (mb_y > 0) {
        memcpy(y_dst - BPS, top_yuv[0].y, 16);
        memcpy(u_dst - BPS, top_yuv[0].u, 8);
        memcpy(v_dst - BPS, top_yuv[0].v, 8);
      }

      // predict and add residuals
      if (block->is_i4x4_) {   // 4x4
        uint32_t* const top_right = (uint32_t*)(y_dst - BPS + 16);

        if (mb_y > 0) {
          if (mb_x >= dec->mb_w_ - 1) {    // on rightmost border
            memset(top_right, top_yuv[0].y[15], sizeof(*top_right));
          } else {
            memcpy(top_right, top_yuv[1].y, sizeof(*top_right));
          }
        }
        // replicate the top-right pixels below
        top_right[BPS] = top_right[2 * BPS] = top_right[3 * BPS] = top_right[0];

        // predict and add residuals for all 4x4 blocks in turn.
        for (n = 0; n < 16; ++n, bits <<= 2) {
          uint8_t* const dst = y_dst + kScan[n];
          VP8PredLuma4[block->imodes_[n]](dst);
          DoTransform(bits, coeffs + n * 16, dst);
        }
      } else {    // 16x16
        const int pred_func = CheckMode(mb_x, mb_y, block->imodes_[0]);
        VP8PredLuma16[pred_func](y_dst);
        if (bits != 0) {
          for (n = 0; n < 16; ++n, bits <<= 2) {
            DoTransform(bits, coeffs + n * 16, y_dst + kScan[n]);
          }
        }
      }
      {
        // Chroma
        const uint32_t bits_uv = block->non_zero_uv_;
        const int pred_func = CheckMode(mb_x, mb_y, block->uvmode_);
        VP8PredChroma8[pred_func](u_dst);
        VP8PredChroma8[pred_func](v_dst);
        DoUVTransform(bits_uv >> 0, coeffs + 16 * 16, u_dst);
        DoUVTransform(bits_uv >> 8, coeffs + 20 * 16, v_dst);
      }

      // stash away top samples for next block
      if (mb_y < dec->mb_h_ - 1) {
        memcpy(top_yuv[0].y, y_dst + 15 * BPS, 16);
        memcpy(top_yuv[0].u, u_dst +  7 * BPS,  8);
        memcpy(top_yuv[0].v, v_dst +  7 * BPS,  8);
      }
    }
    // Transfer reconstructed samples from yuv_b_ cache to final destination.
    {
      const int y_offset = cache_id * 16 * dec->cache_y_stride_;
      const int uv_offset = cache_id * 8 * dec->cache_uv_stride_;
      uint8_t* const y_out = dec->cache_y_ + mb_x * 16 + y_offset;
      uint8_t* const u_out = dec->cache_u_ + mb_x * 8 + uv_offset;
      uint8_t* const v_out = dec->cache_v_ + mb_x * 8 + uv_offset;
      for (j = 0; j < 16; ++j) {
        memcpy(y_out + j * dec->cache_y_stride_, y_dst + j * BPS, 16);
      }
      for (j = 0; j < 8; ++j) {
        memcpy(u_out + j * dec->cache_uv_stride_, u_dst + j * BPS, 8);
        memcpy(v_out + j * dec->cache_uv_stride_, v_dst + j * BPS, 8);
      }
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, %rbp
movl 0x4(%rsi), %edi
movq %rsi, 0x78(%rsp)
movslq (%rsi), %rsi
movq 0xb20(%rbp), %r13
leaq 0x248(%r13), %rax
movq %rax, 0x68(%rsp)
xorl %eax, %eax
cmpq $0x200, %rax            # imm = 0x200
je 0xc8076
movb $-0x7f, 0x27(%r13,%rax)
addq $0x20, %rax
jmp 0xc8062
leaq 0x258(%r13), %rax
movq %rax, 0x18(%rsp)
xorl %eax, %eax
movb $-0x7f, %cl
cmpq $0x100, %rax            # imm = 0x100
je 0xc80a4
movb %cl, 0x247(%r13,%rax)
movb %cl, 0x257(%r13,%rax)
addq $0x20, %rax
jmp 0xc8086
testl %edi, %edi
jle 0xc80be
movb $-0x7f, %al
movb %al, 0x237(%r13)
movb %al, 0x227(%r13)
movb %al, 0x7(%r13)
jmp 0xc80f5
leaq 0x227(%r13), %rax
movabsq $0x7f7f7f7f7f7f7f7f, %rcx # imm = 0x7F7F7F7F7F7F7F7F
movq %rcx, 0x14(%r13)
movaps 0x50af6(%rip), %xmm0    # 0x118bd0
movups %xmm0, 0x7(%r13)
movb $0x7f, %dl
movb %dl, 0x8(%rax)
movq %rcx, (%rax)
movb %dl, 0x23f(%r13)
movq %rcx, 0x237(%r13)
leaq 0x28(%r13), %rax
movq %rax, 0x8(%rsp)
leaq 0x18(%r13), %rax
movq %rax, 0x10(%rsp)
leaq 0x8(%r13), %rax
movq %rax, 0x50(%rsp)
xorl %eax, %eax
testl %edi, %edi
sete %al
leal (,%rax,4), %ecx
movq %rcx, 0x28(%rsp)
addq $0x5, %rax
movq %rax, 0x30(%rsp)
leaq 0x208(%r13), %rax
movq %rax, 0x48(%rsp)
movq %rsi, %rax
shlq $0x4, %rax
movq %rax, 0x60(%rsp)
shlq $0x3, %rsi
movq %rsi, 0x70(%rsp)
movl $0x301, %esi            # imm = 0x301
xorl %r14d, %r14d
xorl %r12d, %r12d
movl %edi, 0x24(%rsp)
movq %rbp, 0x58(%rsp)
movslq 0x198(%rbp), %rax
cmpq %rax, %r12
jge 0xc8503
movq 0x78(%rsp), %rax
movq 0x18(%rax), %rbx
testq %r12, %r12
je 0xc81ca
pushq $0x14
popq %rax
cmpq $0x234, %rax            # imm = 0x234
je 0xc819a
movl (%r13,%rax), %ecx
movl %ecx, -0x10(%r13,%rax)
addq $0x20, %rax
jmp 0xc8182
xorl %eax, %eax
cmpq $0x120, %rax            # imm = 0x120
je 0xc81ca
movl 0x22c(%r13,%rax), %ecx
movl 0x23c(%r13,%rax), %edx
movl %ecx, 0x224(%r13,%rax)
movl %edx, 0x234(%r13,%rax)
addq $0x20, %rax
jmp 0xc819c
imulq $0x320, %r12, %rax      # imm = 0x320
addq %rbx, %rax
movq %r12, %rcx
shlq $0x5, %rcx
addq 0xb08(%rbp), %rcx
movl 0x314(%rax), %r15d
testl %edi, %edi
movq %rax, 0x38(%rsp)
movq %rsi, 0x90(%rsp)
movq %r14, 0x88(%rsp)
movq %r12, 0x40(%rsp)
movq %rcx, 0x80(%rsp)
jle 0xc8260
movups (%rcx), %xmm0
movq 0x50(%rsp), %rax
movups %xmm0, (%rax)
movq 0x10(%rcx), %rax
movq %rax, 0x228(%r13)
movq 0x18(%rcx), %rax
movq %rax, 0x238(%r13)
movq 0x38(%rsp), %rax
cmpb $0x0, 0x300(%rax)
je 0xc8275
movslq 0x198(%rbp), %rax
decq %rax
cmpq %rax, %r12
jge 0xc82e4
movl 0x20(%rcx), %eax
movq 0x10(%rsp), %rcx
movl %eax, (%rcx)
jmp 0xc8303
cmpb $0x0, 0x300(%rax)
je 0xc8275
movq 0x10(%rsp), %rax
movl (%rax), %eax
jmp 0xc8303
testq %r12, %r12
movzbl 0x301(%rax), %eax
movq 0x28(%rsp), %r12
cmoveq 0x30(%rsp), %r12
testl %eax, %eax
movl %r12d, %ecx
cmovnel %eax, %ecx
movq 0x8(%rsp), %rdi
leaq 0xa9192(%rip), %rax     # 0x171430
callq *(%rax,%rcx,8)
testl %r15d, %r15d
je 0xc837e
addq %r14, %rbx
xorl %r14d, %r14d
cmpq $0x20, %r14
je 0xc837e
leaq 0x50bbf(%rip), %rax     # 0x118e80
movzwl (%r14,%rax), %edx
addq 0x8(%rsp), %rdx
movl %r15d, %edi
movq %rbx, %rsi
callq 0xc9286
shll $0x2, %r15d
addq $0x20, %rbx
addq $0x2, %r14
jmp 0xc82b0
movzbl 0xf(%rcx), %eax
imull $0x1010101, %eax, %ecx  # imm = 0x1010101
movq 0x10(%rsp), %rdx
movl %ecx, (%rdx)
movl %eax, %ecx
shll $0x8, %ecx
orl %eax, %ecx
movl %ecx, %eax
shll $0x10, %eax
orl %ecx, %eax
movl %eax, 0x198(%r13)
movl %eax, 0x118(%r13)
movl %eax, 0x98(%r13)
leaq (%rbx,%r14), %r12
addq %rsi, %rbx
xorl %r14d, %r14d
cmpq $0x20, %r14
je 0xc8368
leaq 0x50b51(%rip), %rax     # 0x118e80
movzwl (%r14,%rax), %ebp
addq 0x8(%rsp), %rbp
movzbl (%rbx), %eax
movq %rbp, %rdi
leaq 0xa912a(%rip), %rcx     # 0x171470
callq *(%rcx,%rax,8)
movl %r15d, %edi
movq %r12, %rsi
movq %rbp, %rdx
callq 0xc9286
shll $0x2, %r15d
addq $0x20, %r12
addq $0x2, %r14
incq %rbx
jmp 0xc8322
cmpq $0x0, 0x40(%rsp)
movq 0x28(%rsp), %r12
cmoveq 0x30(%rsp), %r12
movq 0x58(%rsp), %rbp
movq 0x38(%rsp), %r14
movl 0x318(%r14), %ebx
movzbl 0x311(%r14), %eax
testl %eax, %eax
cmovnel %eax, %r12d
movq 0x68(%rsp), %r15
movq %r15, %rdi
leaq 0xa9119(%rip), %rax     # 0x1714c0
callq *(%rax,%r12,8)
movq 0x18(%rsp), %rdi
leaq 0xa9109(%rip), %rax     # 0x1714c0
callq *(%rax,%r12,8)
leaq 0x200(%r14), %rsi
movl %ebx, %edi
movq %r15, %rdx
callq 0xc92c9
shrl $0x8, %ebx
addq $0x280, %r14            # imm = 0x280
movl %ebx, %edi
movq %r14, %rsi
movq 0x18(%rsp), %rdx
callq 0xc92c9
movl 0x19c(%rbp), %eax
decl %eax
movl 0x24(%rsp), %ecx
movl %ecx, %ebx
cmpl %eax, %ecx
jge 0xc8420
movq 0x48(%rsp), %rax
movups (%rax), %xmm0
movq 0x80(%rsp), %rcx
movups %xmm0, (%rcx)
movq 0x328(%r13), %rax
movq %rax, 0x10(%rcx)
movq 0x338(%r13), %rax
movq %rax, 0x18(%rcx)
movslq 0xb40(%rbp), %rax
imulq 0x60(%rsp), %rax
movslq 0xb44(%rbp), %rdx
movq 0x40(%rsp), %r12
movq %r12, %rsi
shlq $0x4, %rsi
addq 0xb28(%rbp), %rsi
imulq 0x70(%rsp), %rdx
addq %rax, %rsi
movq 0xb30(%rbp), %rax
leaq (,%r12,8), %rdi
movq 0xb38(%rbp), %rcx
addq %rdi, %rcx
movq 0x8(%rsp), %r8
xorl %r9d, %r9d
movq 0x88(%rsp), %r14
cmpq $0x10, %r9
je 0xc849f
movslq 0xb40(%rbp), %r10
movslq %r9d, %r11
imulq %r10, %r11
movups (%r8), %xmm0
movups %xmm0, (%rsi,%r11)
incq %r9
addq $0x20, %r8
jmp 0xc8479
addq %rdi, %rax
addq %rdx, %rax
addq %rdx, %rcx
movq 0x18(%rsp), %rdx
xorl %esi, %esi
cmpq $0x8, %rsi
je 0xc84e6
movslq 0xb44(%rbp), %rdi
movslq %esi, %r8
imulq %r8, %rdi
movq -0x10(%rdx), %r9
movq %r9, (%rax,%rdi)
movslq 0xb44(%rbp), %rdi
imulq %r8, %rdi
movq (%rdx), %r8
movq %r8, (%rcx,%rdi)
incq %rsi
addq $0x20, %rdx
jmp 0xc84af
incq %r12
movl $0x320, %eax            # imm = 0x320
addq %rax, %r14
movq 0x90(%rsp), %rsi
addq %rax, %rsi
movl %ebx, %edi
jmp 0xc8161
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq