// File: /workspace/github_cpp_makefile_star2_O3/lvandeve[P]lodepng/lodepng_util.cpp
// Function: lodepng::convertFromXYZ_chrm(float*, float const*, unsigned int, unsigned int, LodePNGInfo const*, unsigned int, lodepng::LodePNGICC const*, float const*, unsigned int)
static unsigned convertFromXYZ_chrm(float* out, const float* in, unsigned w, unsigned h,
                                    const LodePNGInfo* info, unsigned use_icc, const LodePNGICC* icc,
                                    const float whitepoint[3], unsigned rendering_intent) {
  size_t i, n;

  float m[9]; /* XYZ to linear RGB matrix */
  float white[3]; /* The whitepoint (absolute) of the target RGB space */

  if(lodepng_mulofl((size_t)w, (size_t)h, &n)) return 92;

  if(getChrm(m, white, use_icc, icc, info)) return 1;
  if(invMatrix(m)) return 1; /* error, not invertible */

  /* for relative rendering intent (any except absolute "3"), must whitepoint adapt to the original whitepoint.
  this also ensures grayscale stays grayscale (with absolute, grayscale could become e.g. blue or sepia) */
  if(rendering_intent != 3) {
    float a[9] = {1,0,0, 0,1,0, 0,0,1};
    /* "white" = absolute whitepoint of the new target RGB space, read from the target color profile.
    "whitepoint" is original absolute whitepoint (input as parameter of this function) of an
    RGB space the XYZ data once had before it was converted to XYZ, in other words the whitepoint that
    we want to adapt our current data to to make sure values that had equal R==G==B in the old space have
    the same property now (white stays white and gray stays gray).
    Note: "absolute" whitepoint above means, can be used as-is, not needing further adaptation itself like icc.white does.*/
    if(getAdaptationMatrix(a, 1, whitepoint[0], whitepoint[1], whitepoint[2], white[0], white[1], white[2])) {
      return 1;
    }
    /* multiply the from xyz matrix with the adaptation matrix: in total,
    the resulting matrix first adapts in XYZ space, then converts to RGB*/
    mulMatrixMatrix(m, m, a);
  }

  /* Apply the above computed XYZ-to-linear-RGB matrix to the pixels.
  This transformation also includes the whitepoint adaptation. The transform
  can be skipped only if it's the unit matrix (only if grayscale profile and no
  whitepoint adaptation, such as with rendering intent 3)*/
  if(!use_icc || icc->inputspace == 2 || rendering_intent != 3) {
    for(i = 0; i < n; i++) {
      size_t j = i * 4;
      mulMatrix(&out[j + 0], &out[j + 1], &out[j + 2], m, in[j + 0], in[j + 1], in[j + 2]);
      out[j + 3] = in[j + 3];
    }
  } else {
    for(i = 0; i < n * 4; i++) {
      out[i] = in[i];
    }
  }

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r9d, %ebp
movl %ecx, %r13d
movl %edx, %r12d
movq %rsi, %rbx
movq %rdi, %r14
movq 0x90(%rsp), %rcx
movq %rsp, %rdi
leaq 0x24(%rsp), %rsi
movl %r9d, %edx
callq 0x14051
movl $0x1, %r15d
testl %eax, %eax
jne 0x1324f
movq %rsp, %rdi
callq 0x14708
testl %eax, %eax
jne 0x1324f
movl 0xa0(%rsp), %ecx
movl %r12d, %eax
movl %r13d, %r12d
cmpl $0x3, %ecx
je 0x1310a
movq %rax, %r13
movq 0x98(%rsp), %rax
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %r15
movaps %xmm0, (%r15)
movaps %xmm0, 0x10(%r15)
movl $0x3f800000, %ecx       # imm = 0x3F800000
movl %ecx, (%r15)
movl %ecx, 0x10(%r15)
movl %ecx, 0x20(%r15)
movss (%rax), %xmm0
movss 0x4(%rax), %xmm1
movss 0x8(%rax), %xmm2
movss 0x24(%rsp), %xmm3
movss 0x28(%rsp), %xmm4
movss 0x2c(%rsp), %xmm5
movq %r15, %rdi
callq 0x148e9
movq %rsp, %rdi
movq %rdi, %rsi
movq %r15, %rdx
callq 0x14bd7
movq %r13, %rax
movl 0xa0(%rsp), %ecx
imulq %rax, %r12
testl %ebp, %ebp
movq 0x90(%rsp), %rax
je 0x1314e
cmpl $0x3, %ecx
jne 0x1314e
cmpl $0x2, (%rax)
je 0x1314e
shlq $0x2, %r12
xorl %r15d, %r15d
testq %r12, %r12
je 0x1324f
xorl %eax, %eax
movss (%rbx,%rax,4), %xmm0
movss %xmm0, (%r14,%rax,4)
incq %rax
cmpq %rax, %r12
jne 0x13136
jmp 0x1324f
xorl %r15d, %r15d
testq %r12, %r12
je 0x1324f
movaps (%rsp), %xmm0
movups 0x4(%rsp), %xmm1
movups 0x8(%rsp), %xmm2
movss 0xc(%rsp), %xmm3
movlhps %xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0]
shufps $0xe2, %xmm0, %xmm3     # xmm3 = xmm3[2,0],xmm0[2,3]
cvtps2pd %xmm3, %xmm0
movss 0x10(%rsp), %xmm3
movlhps %xmm1, %xmm3            # xmm3 = xmm3[0],xmm1[0]
shufps $0xe2, %xmm1, %xmm3     # xmm3 = xmm3[2,0],xmm1[2,3]
cvtps2pd %xmm3, %xmm1
movss 0x14(%rsp), %xmm3
movlhps %xmm2, %xmm3            # xmm3 = xmm3[0],xmm2[0]
shufps $0xe2, %xmm2, %xmm3     # xmm3 = xmm3[2,0],xmm2[2,3]
cvtps2pd %xmm3, %xmm2
xorps %xmm3, %xmm3
cvtss2sd 0x18(%rsp), %xmm3
xorps %xmm4, %xmm4
cvtss2sd 0x1c(%rsp), %xmm4
movl $0xc, %eax
xorps %xmm5, %xmm5
cvtss2sd 0x20(%rsp), %xmm5
xorps %xmm6, %xmm6
cvtss2sd -0xc(%rbx,%rax), %xmm6
xorps %xmm7, %xmm7
cvtss2sd -0x8(%rbx,%rax), %xmm7
xorps %xmm8, %xmm8
cvtss2sd -0x4(%rbx,%rax), %xmm8
movaps %xmm7, %xmm9
movlhps %xmm7, %xmm9            # xmm9 = xmm9[0],xmm7[0]
mulpd %xmm1, %xmm9
movaps %xmm6, %xmm10
movlhps %xmm6, %xmm10           # xmm10 = xmm10[0],xmm6[0]
mulpd %xmm0, %xmm10
addpd %xmm9, %xmm10
movaps %xmm8, %xmm9
movlhps %xmm8, %xmm9            # xmm9 = xmm9[0],xmm8[0]
mulpd %xmm2, %xmm9
addpd %xmm10, %xmm9
cvtpd2ps %xmm9, %xmm9
movlpd %xmm9, -0xc(%r14,%rax)
mulsd %xmm4, %xmm7
mulsd %xmm3, %xmm6
addsd %xmm7, %xmm6
mulsd %xmm5, %xmm8
addsd %xmm6, %xmm8
xorps %xmm6, %xmm6
cvtsd2ss %xmm8, %xmm6
movss %xmm6, -0x4(%r14,%rax)
movss (%rbx,%rax), %xmm6
movss %xmm6, (%r14,%rax)
addq $0x10, %rax
decq %r12
jne 0x131b8
movl %r15d, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq