class LUT1D(ProcessNode): "A Common LUT Format LUT 1D ProcessNode element" def __init__( self, inBitDepth=bitDepths["FLOAT16"], outBitDepth=bitDepths["FLOAT16"], id="", name="", interpolation="linear", rawHalfs="", halfDomain="", ): "%s - Initialize the standard class variables" % "LUT1D" ProcessNode.__init__(self, "LUT1D", inBitDepth, outBitDepth, id, name) if interpolation != "": self._attributes["interpolation"] = interpolation if rawHalfs != "": self._attributes["rawHalfs"] = rawHalfs if halfDomain != "": self._attributes["halfDomain"] = halfDomain self._array = None self._indexMaps = [] # __init__ def setIndexMaps(self, valuesR, valuesG=None, valuesB=None): indexMapR = IndexMap(len(valuesR[0]), valuesR) self._indexMaps.append(indexMapR) self.addElement(indexMapR) # Either one or three indexMaps if valuesG != None and valuesB != None: indexMapG = IndexMap(len(valuesG[0]), valuesG) self._indexMaps.append(indexMapG) self.addElement(indexMapG) indexMapB = IndexMap(len(valuesB[0]), valuesB) self._indexMaps.append(indexMapB) self.addElement(indexMapB) # setIndexMaps def setArray(self, dimension, values, floatEncoding="string"): dimensions = [len(values) / dimension, dimension] integers = bitDepthIsInteger(self.getAttribute("outBitDepth")) rawHalfs = not (self.getAttribute("rawHalfs") in [None, False]) self._array = Array(dimensions, values, rawHalfs=rawHalfs, integers=integers, floatEncoding=floatEncoding) self.addElement(self._array) # setArray def getLUTDimensions(self): return self._array.getDimensions() def getLUTValues(self): return self._array.getValues() def getIndexMapDimensions(self, channel): return self._indexMaps[channel].getDimensions() def getIndexMapValues(self, channel): return self._indexMaps[channel].getValues() def readChild(self, element): child = None if element.tag == "Array": rawHalfs = not (self.getAttribute("rawHalfs") in [None, False]) child = Array(rawHalfs=rawHalfs) child.read(element) integers = bitDepthIsInteger(self.getAttribute("outBitDepth")) child.setValuesAreIntegers(integers) self._array = child elif element.tag == "IndexMap": child = IndexMap() child.read(element) self._indexMaps.append(child) return child # readChild def process(self, values, stride=0, verbose=False): # Base attributes inBitDepth = self._attributes["inBitDepth"] outBitDepth = self._attributes["outBitDepth"] # Node attributes interpolation = "" if "interpolation" in self._attributes: interpolation = self._attributes["interpolation"] rawHalfs = not (self.getAttribute("rawHalfs") in [None, False]) halfDomain = not (self.getAttribute("halfDomain") in [None, False]) """ print( "interpolation : %s" % interpolation ) print( "raw halfs : %s" % rawHalfs ) print( "halfs domain : %s" % halfDomain ) """ # Get LUT dimensions dimensions = self.getLUTDimensions() # Handle processing of single values if stride == 0: stride = len(values) # Initialize the output value outValues = np.zeros(len(values), dtype=np.float32) for p in range(len(values) / stride): value = values[p * stride : (p + 1) * stride] outValue = values[p * stride : (p + 1) * stride] for i in range(min(3, stride)): # Run through single Index Map then normalize if len(self._indexMaps) > 1: outValue[i] = self._indexMaps[i].process(outValue[i]) outValue[i] /= float(dimensions[0] - 1) # Run through per-channel Index Map then normalize elif len(self._indexMaps) > 0: outValue[i] = self._indexMaps[0].process(outValue[i]) outValue[i] /= float(dimensions[0] - 1) # Normalize from bit-depth else: # Convert input bit depth outValue[i] = bitDepthToNormalized(outValue[i], inBitDepth) # Run through LUT # Use Cubic interpolation if interpolation == "cubic": outValue[i] = self._array.lookup1DCubic(outValue[i], i) # Use halfDomain lookup and interpolation elif halfDomain: outValue[i] = self._array.lookup1DHalfDomain(outValue[i], i, interpolate=True) # Linear interpolation is the default # elif interpolation == 'linear': else: outValue[i] = self._array.lookup1DLinear(outValue[i], i) # Bit Depth conversion for output is ignored for LUTs # as LUT values are assumed to target a specific bit depth # outValue[i] = normalizedToBitDepth(outValue[i], outBitDepth) # Copy the extra channels for i in range(min(3, stride), stride): outValue[i] = value[i] # Copy to the output array outValues[p * stride : (p + 1) * stride] = outValue return outValues
class LUT1D(ProcessNode): "A Common LUT Format LUT 1D ProcessNode element" def __init__(self, inBitDepth=bitDepths["FLOAT16"], outBitDepth=bitDepths["FLOAT16"], id="", name="", interpolation='linear', rawHalfs='', halfDomain=''): "%s - Initialize the standard class variables" % 'LUT1D' ProcessNode.__init__(self, 'LUT1D', inBitDepth, outBitDepth, id, name) if interpolation != '': self._attributes['interpolation'] = interpolation if rawHalfs != '': self._attributes['rawHalfs'] = rawHalfs if halfDomain != '': self._attributes['halfDomain'] = halfDomain self._array = None self._indexMaps = [] # __init__ def setIndexMaps(self, valuesR, valuesG=None, valuesB=None): indexMapR = IndexMap(len(valuesR[0]), valuesR) self._indexMaps.append(indexMapR) self.addElement(indexMapR) # Either one or three indexMaps if (valuesG != None and valuesB != None): indexMapG = IndexMap(len(valuesG[0]), valuesG) self._indexMaps.append(indexMapG) self.addElement(indexMapG) indexMapB = IndexMap(len(valuesB[0]), valuesB) self._indexMaps.append(indexMapB) self.addElement(indexMapB) # setIndexMaps def setArray(self, dimension, values, floatEncoding='string'): dimensions = [len(values) / dimension, dimension] integers = bitDepthIsInteger(self.getAttribute('outBitDepth')) rawHalfs = not (self.getAttribute('rawHalfs') in [None, False]) self._array = Array(dimensions, values, rawHalfs=rawHalfs, integers=integers, floatEncoding=floatEncoding) self.addElement(self._array) # setArray def getLUTDimensions(self): return self._array.getDimensions() def getLUTValues(self): return self._array.getValues() def getIndexMapDimensions(self, channel): return self._indexMaps[channel].getDimensions() def getIndexMapValues(self, channel): return self._indexMaps[channel].getValues() def readChild(self, element): child = None elementType = self.getElementType(element.tag) if elementType == 'Array': rawHalfs = not (self.getAttribute('rawHalfs') in [None, False]) child = Array(rawHalfs=rawHalfs) child.read(element) integers = bitDepthIsInteger(self.getAttribute('outBitDepth')) child.setValuesAreIntegers(integers) self._array = child elif elementType == 'IndexMap': child = IndexMap() child.read(element) self._indexMaps.append(child) return child # readChild def process(self, values, stride=0, verbose=False): # Base attributes inBitDepth = self._attributes['inBitDepth'] outBitDepth = self._attributes['outBitDepth'] # Node attributes interpolation = '' if 'interpolation' in self._attributes: interpolation = self._attributes['interpolation'] rawHalfs = not (self.getAttribute('rawHalfs') in [None, False]) halfDomain = not (self.getAttribute('halfDomain') in [None, False]) ''' print( "interpolation : %s" % interpolation ) print( "raw halfs : %s" % rawHalfs ) print( "halfs domain : %s" % halfDomain ) ''' # Get LUT dimensions dimensions = self.getLUTDimensions() # Handle processing of single values if stride == 0: stride = len(values) # Initialize the output value outValues = np.zeros(len(values), dtype=np.float32) for p in range(len(values) / stride): value = values[p * stride:(p + 1) * stride] outValue = values[p * stride:(p + 1) * stride] for i in range(min(3, stride)): # Run through per-channel Index Map then normalize if len(self._indexMaps) > 1: outValue[i] = self._indexMaps[i].process(outValue[i]) outValue[i] /= float(dimensions[0] - 1) # Run through single Index Map then normalize elif len(self._indexMaps) > 0: outValue[i] = self._indexMaps[0].process(outValue[i]) outValue[i] /= float(dimensions[0] - 1) # Normalize from bit-depth else: # Convert input bit depth outValue[i] = bitDepthToNormalized(outValue[i], inBitDepth) # Run through LUT # Use Cubic interpolation if interpolation == 'cubic': outValue[i] = self._array.lookup1DCubic(outValue[i], i) # Use halfDomain lookup and interpolation elif halfDomain: outValue[i] = self._array.lookup1DHalfDomain( outValue[i], i, interpolate=True) # Linear interpolation is the default #elif interpolation == 'linear': else: outValue[i] = self._array.lookup1DLinear(outValue[i], i) # Bit Depth conversion for output is ignored for LUTs # as LUT values are assumed to target a specific bit depth #outValue[i] = normalizedToBitDepth(outValue[i], outBitDepth) # Copy the extra channels for i in range(min(3, stride), stride): outValue[i] = value[i] # Copy to the output array outValues[p * stride:(p + 1) * stride] = outValue return outValues