// File: lvandeve[P]lodepng/lodepng_util.cpp
// Function: lodepng::iccBackwardTRC(lodepng::LodePNGICCCurve const*, float)
static float iccBackwardTRC(const LodePNGICCCurve* curve, float x) {
  if(curve->type == 0) {
    return x;
  }
  if(curve->type == 1) {
    size_t a, b, m;
    float v;
    if(x <= 0) return x;
    if(x >= 1) return x;
    /* binary search in the table */
    /* TODO: use faster way of inverting the lookup table */
    a = 0;
    b = curve->lut_size;
    for(;;) {
      if(a == b) return curve->lut[a];
      if(a + 1 == b) {
        /* LERP */
        float v0 = curve->lut[a];
        float v1 = curve->lut[b];
        float fraction;
        if(v0 == v1) return v0;
        fraction = (x - v0) / (v1 - v0);
        return v0 * (1 - fraction) + v1 * fraction;
      }
      m = (a + b) / 2u;
      v = curve->lut[m];
      if(v > x) {
        b = m;
      } else {
        a = m;
      }
    }
  }
  if(curve->type == 2) {
    /* Gamma compression */
    return (x > 0) ? lodepng_powf(x, 1.0f / curve->gamma) : x;
  }
  /* TODO: all the ones below are untested  */
  if(curve->type == 3) {
    if(x < 0) return x;
    return x > 0 ? ((lodepng_powf(x, 1.0f / curve->gamma) - curve->b) / curve->a) : (-curve->b / curve->a);
  }
  if(curve->type == 4) {
    if(x < 0) return x;
    return x > curve->c ?
        ((lodepng_powf(x - curve->c, 1.0f / curve->gamma) - curve->b) / curve->a) :
        (-curve->b / curve->a);
  }
  if(curve->type == 5) {
    return x > (curve->c * curve->d) ?
        ((lodepng_powf(x, 1.0f / curve->gamma) - curve->b) / curve->a) :
        (x / curve->c);
  }
  if(curve->type == 6) {
    return x > (curve->c * curve->d + curve->f) ?
        ((lodepng_powf(x - curve->c, 1.0f / curve->gamma) - curve->b) / curve->a) :
        ((x - curve->f) / curve->c);
  }
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movss %xmm0, -0x14(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x22c09
movss -0x14(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq -0x10(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x22d74
xorps %xmm0, %xmm0
ucomiss -0x14(%rbp), %xmm0
jb 0x22c2e
movss -0x14(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movss -0x14(%rbp), %xmm0
movss 0x8fdb9(%rip), %xmm1    # 0xb29f4
ucomiss %xmm1, %xmm0
jb 0x22c4f
movss -0x14(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x28(%rbp), %rax
jne 0x22c88
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x20(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq -0x20(%rbp), %rax
addq $0x1, %rax
cmpq -0x28(%rbp), %rax
jne 0x22d2d
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x20(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x28(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0x3c(%rbp)
movss -0x38(%rbp), %xmm0
ucomiss -0x3c(%rbp), %xmm0
jne 0x22ce2
jp 0x22ce2
movss -0x38(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movss -0x14(%rbp), %xmm0
subss -0x38(%rbp), %xmm0
movss -0x3c(%rbp), %xmm1
subss -0x38(%rbp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x40(%rbp)
movss -0x38(%rbp), %xmm0
movss 0x8fce8(%rip), %xmm2    # 0xb29f4
subss -0x40(%rbp), %xmm2
movss -0x3c(%rbp), %xmm1
mulss -0x40(%rbp), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq -0x20(%rbp), %rax
addq -0x28(%rbp), %rax
shrq %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x30(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0x34(%rbp)
movss -0x34(%rbp), %xmm0
ucomiss -0x14(%rbp), %xmm0
jbe 0x22d67
movq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x22d6f
movq -0x30(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x22c63
movq -0x10(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x22dc5
movss -0x14(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jbe 0x22dac
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
movss 0x8fc59(%rip), %xmm1    # 0xb29f4
divss 0x18(%rax), %xmm1
callq 0x21170
movss %xmm0, -0x44(%rbp)
jmp 0x22db6
movss -0x14(%rbp), %xmm0
movss %xmm0, -0x44(%rbp)
movss -0x44(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq -0x10(%rbp), %rax
cmpl $0x3, (%rax)
jne 0x22e5e
xorps %xmm0, %xmm0
ucomiss -0x14(%rbp), %xmm0
jbe 0x22dea
movss -0x14(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movss -0x14(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jbe 0x22e2b
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
movss 0x8fbec(%rip), %xmm1    # 0xb29f4
divss 0x18(%rax), %xmm1
callq 0x21170
movq -0x10(%rbp), %rax
subss 0x20(%rax), %xmm0
movq -0x10(%rbp), %rax
divss 0x1c(%rax), %xmm0
movss %xmm0, -0x48(%rbp)
jmp 0x22e4f
movq -0x10(%rbp), %rax
movss 0x20(%rax), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movq -0x10(%rbp), %rax
divss 0x1c(%rax), %xmm0
movss %xmm0, -0x48(%rbp)
movss -0x48(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq -0x10(%rbp), %rax
cmpl $0x4, (%rax)
jne 0x22f02
xorps %xmm0, %xmm0
ucomiss -0x14(%rbp), %xmm0
jbe 0x22e83
movss -0x14(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
ucomiss 0x24(%rax), %xmm0
jbe 0x22ecf
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
subss 0x24(%rax), %xmm0
movq -0x10(%rbp), %rax
movss 0x8fb48(%rip), %xmm1    # 0xb29f4
divss 0x18(%rax), %xmm1
callq 0x21170
movq -0x10(%rbp), %rax
subss 0x20(%rax), %xmm0
movq -0x10(%rbp), %rax
divss 0x1c(%rax), %xmm0
movss %xmm0, -0x4c(%rbp)
jmp 0x22ef3
movq -0x10(%rbp), %rax
movss 0x20(%rax), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movq -0x10(%rbp), %rax
divss 0x1c(%rax), %xmm0
movss %xmm0, -0x4c(%rbp)
movss -0x4c(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq -0x10(%rbp), %rax
cmpl $0x5, (%rax)
jne 0x22f7d
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
movss 0x24(%rax), %xmm1
movq -0x10(%rbp), %rax
mulss 0x28(%rax), %xmm1
ucomiss %xmm1, %xmm0
jbe 0x22f5b
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
movss 0x8fabc(%rip), %xmm1    # 0xb29f4
divss 0x18(%rax), %xmm1
callq 0x21170
movq -0x10(%rbp), %rax
subss 0x20(%rax), %xmm0
movq -0x10(%rbp), %rax
divss 0x1c(%rax), %xmm0
movss %xmm0, -0x50(%rbp)
jmp 0x22f6e
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
divss 0x24(%rax), %xmm0
movss %xmm0, -0x50(%rbp)
movss -0x50(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
movq -0x10(%rbp), %rax
cmpl $0x6, (%rax)
jne 0x2301c
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
movss 0x24(%rax), %xmm1
movq -0x10(%rbp), %rax
movss 0x28(%rax), %xmm3
movq -0x10(%rbp), %rax
movss 0x30(%rax), %xmm2
mulss %xmm3, %xmm1
addss %xmm2, %xmm1
ucomiss %xmm1, %xmm0
jbe 0x22ff4
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
subss 0x24(%rax), %xmm0
movq -0x10(%rbp), %rax
movss 0x8fa23(%rip), %xmm1    # 0xb29f4
divss 0x18(%rax), %xmm1
callq 0x21170
movq -0x10(%rbp), %rax
subss 0x20(%rax), %xmm0
movq -0x10(%rbp), %rax
divss 0x1c(%rax), %xmm0
movss %xmm0, -0x54(%rbp)
jmp 0x23010
movss -0x14(%rbp), %xmm0
movq -0x10(%rbp), %rax
subss 0x30(%rax), %xmm0
movq -0x10(%rbp), %rax
divss 0x24(%rax), %xmm0
movss %xmm0, -0x54(%rbp)
movss -0x54(%rbp), %xmm0
movss %xmm0, -0x4(%rbp)
jmp 0x23024
xorps %xmm0, %xmm0
movss %xmm0, -0x4(%rbp)
movss -0x4(%rbp), %xmm0
addq $0x60, %rsp
popq %rbp
retq
nop