// File: /workspace/github_cpp_makefile_star2_O2/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 $0x68, %rsp
movl %r9d, %ebp
movl %ecx, %r13d
movl %edx, %r15d
movq %rsi, %rbx
movq %rdi, %r14
movq 0xa0(%rsp), %rcx
leaq 0x10(%rsp), %rdi
leaq 0x4(%rsp), %rsi
movl %r9d, %edx
callq 0x1170d
pushq $0x1
popq %r12
testl %eax, %eax
jne 0x1098f
leaq 0x10(%rsp), %rdi
callq 0x11bca
testl %eax, %eax
jne 0x1098f
movl 0xb0(%rsp), %eax
movl %r15d, %r12d
movl %r13d, %r13d
cmpl $0x3, %eax
je 0x1090b
movq 0xa8(%rsp), %rax
xorps %xmm0, %xmm0
leaq 0x40(%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 0x4(%rsp), %xmm3
movss 0x8(%rsp), %xmm4
movss 0xc(%rsp), %xmm5
movq %r15, %rdi
callq 0x11dad
leaq 0x10(%rsp), %rdi
movq %rdi, %rsi
movq %r15, %rdx
callq 0x12024
movl 0xb0(%rsp), %eax
imulq %r12, %r13
testl %ebp, %ebp
je 0x10943
cmpl $0x3, %eax
jne 0x10943
movq 0xa0(%rsp), %rax
cmpl $0x2, (%rax)
je 0x10943
shlq $0x2, %r13
xorl %r12d, %r12d
xorl %eax, %eax
cmpq %rax, %r13
je 0x1098f
movss (%rbx,%rax,4), %xmm0
movss %xmm0, (%r14,%rax,4)
incq %rax
jmp 0x1092e
addq $0xc, %rbx
addq $0x8, %r14
leaq 0x10(%rsp), %r15
subq $0x1, %r13
jb 0x1098c
leaq -0x8(%r14), %rdi
leaq -0x4(%r14), %rsi
cvtss2sd -0xc(%rbx), %xmm0
cvtss2sd -0x8(%rbx), %xmm1
cvtss2sd -0x4(%rbx), %xmm2
movq %r14, %rdx
movq %r15, %rcx
callq 0x11b49
movss (%rbx), %xmm0
movss %xmm0, 0x4(%r14)
addq $0x10, %rbx
addq $0x10, %r14
jmp 0x10950
xorl %r12d, %r12d
movl %r12d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq