// File: /workspace/github_cpp_makefile_star2_O1/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 0x142b2
movl $0x1, %r15d
testl %eax, %eax
jne 0x134af
movq %rsp, %rdi
callq 0x14943
testl %eax, %eax
jne 0x134af
movl 0xa0(%rsp), %ecx
movl %r12d, %eax
movl %r13d, %r12d
cmpl $0x3, %ecx
je 0x1334d
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 0x14b0b
movq %rsp, %rdi
movq %rdi, %rsi
movq %r15, %rdx
callq 0x14dfa
movq %r13, %rax
movl 0xa0(%rsp), %ecx
imulq %rax, %r12
testl %ebp, %ebp
movq 0x90(%rsp), %rax
je 0x13391
cmpl $0x3, %ecx
jne 0x13391
cmpl $0x2, (%rax)
je 0x13391
shlq $0x2, %r12
xorl %r15d, %r15d
testq %r12, %r12
je 0x134af
xorl %eax, %eax
movss (%rbx,%rax,4), %xmm0
movss %xmm0, (%r14,%rax,4)
incq %rax
cmpq %rax, %r12
jne 0x13379
jmp 0x134af
xorl %r15d, %r15d
testq %r12, %r12
je 0x134af
xorps %xmm0, %xmm0
cvtss2sd (%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x4(%rsp), %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0x8(%rsp), %xmm2
xorps %xmm3, %xmm3
cvtss2sd 0xc(%rsp), %xmm3
xorps %xmm4, %xmm4
cvtss2sd 0x10(%rsp), %xmm4
xorps %xmm5, %xmm5
cvtss2sd 0x14(%rsp), %xmm5
cvtss2sd 0x18(%rsp), %xmm6
cvtss2sd 0x1c(%rsp), %xmm7
movl $0xc, %eax
cvtss2sd 0x20(%rsp), %xmm8
xorps %xmm9, %xmm9
cvtss2sd -0xc(%rbx,%rax), %xmm9
xorps %xmm11, %xmm11
cvtss2sd -0x8(%rbx,%rax), %xmm11
xorps %xmm10, %xmm10
cvtss2sd -0x4(%rbx,%rax), %xmm10
movaps %xmm11, %xmm12
mulsd %xmm1, %xmm12
movaps %xmm9, %xmm13
mulsd %xmm0, %xmm13
addsd %xmm12, %xmm13
movaps %xmm10, %xmm12
mulsd %xmm2, %xmm12
addsd %xmm13, %xmm12
cvtsd2ss %xmm12, %xmm12
movss %xmm12, -0xc(%r14,%rax)
movaps %xmm11, %xmm12
mulsd %xmm4, %xmm12
movaps %xmm9, %xmm13
mulsd %xmm3, %xmm13
addsd %xmm12, %xmm13
movaps %xmm10, %xmm12
mulsd %xmm5, %xmm12
addsd %xmm13, %xmm12
cvtsd2ss %xmm12, %xmm12
movss %xmm12, -0x8(%r14,%rax)
mulsd %xmm7, %xmm11
mulsd %xmm6, %xmm9
addsd %xmm11, %xmm9
mulsd %xmm8, %xmm10
addsd %xmm9, %xmm10
xorps %xmm9, %xmm9
cvtsd2ss %xmm10, %xmm9
movss %xmm9, -0x4(%r14,%rax)
movss (%rbx,%rax), %xmm9
movss %xmm9, (%r14,%rax)
addq $0x10, %rax
decq %r12
jne 0x133ea
movl %r15d, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq