All files / src/formats cube.ts

86.84% Statements 33/38
71.43% Branches 15/21
100% Functions 2/2
96.77% Lines 30/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57    1x 1x   1x 131080x 131080x 131080x     1x 4x 4x             4x 131124x 131124x   131124x   131088x 131088x   4x 4x   4x 4x 4x 4x   4x 4x   4x 4x     131072x 131072x             4x 4x 4x    
import { Lut, RGBTuple } from '../typings'
 
const defaultDomainMin: RGBTuple = [0, 0, 0]
const defaultDomainMax: RGBTuple = [1, 1, 1]
 
const parseTuple = (...rest: string[]) => {
  const rgbTuple = rest.map(Number)
  Iif (rgbTuple.length !== 3) throw new Error(`RGB tuple has ${rgbTuple.length}`)
  return rgbTuple as RGBTuple
}
 
export const parseCubeLut = (data: Uint8Array): Lut => {
  const lines = new TextDecoder().decode(data).split('\n')
  const lut: Partial<Lut> & { domain: Lut['domain']; data: Lut['data'] } = {
    domain: {
      min: defaultDomainMin,
      max: defaultDomainMax
    },
    data: []
  }
  for (let i = 0; i < lines.length; i++) {
    try {
      const line = lines[i]
      // Skip comments and empty lines
      if (line[0] === '#' || line === '') continue
 
      const [identifier, ...rest] = line.split(' ')
      switch (identifier) {
        case 'TITLE':
          lut.title = line.slice(7, -1)
          break
        case 'LUT_3D_SIZE' || 'LUT_1D_SIZE':
          lut.type = identifier === 'LUT_3D_SIZE' ? '3d' : '1d'
          Iif (!rest[0]) throw new Error('Lut file does not specify size')
          lut.size = Number(rest[0])
          break
        case 'DOMAIN_MIN':
          lut.domain.min = parseTuple(...rest)
          break
        case 'DOMAIN_MAX':
          lut.domain.max = parseTuple(...rest)
          break
        default:
          // We have data, parse it
          lut.data.push(parseTuple(identifier, ...rest))
          break
      }
    } catch (err) {
      throw new Error(`failed parsing cube lut at line ${i}: ${err}`)
    }
  }
 
  Iif (!lut.type) throw new Error('Lut file missing dimension')
  Iif (lut.data.length === 0) throw new Error('Lut has no data')
  return lut as Lut
}