def process(self, values, stride=0, verbose=False): # Cast all values to float32 for processing result = np.array(values, np.float32) if verbose: print( "Processing %d values. Stride size: %d" % (len(values), stride) ) # Pass the value through each ProcessNode in the ProcessList for i in range(len(self._processes)): processNode = self._processes[i] #print( "processing : %s" % result ) # Process the current value using the ProcessNode if (processNode.getAttribute('bypass') == None or not(getFeatureCompatibility() & featureSets["Autodesk"]) ): result = processNode.process(result, stride, verbose=verbose) if verbose: print( "%s (%s) - result value : %s, result type : %s" % (processNode.getAttribute('name'), processNode.getNodeType(), " ".join(map(lambda x: "%3.6f" % x, result)), type(result) ) ) if (processNode.getAttribute('bypass') != None and not(getFeatureCompatibility() & featureSets["Autodesk"])): print( "%s (%s) - bypass ignored based on feature compatibility setting." % (processNode.getAttribute('name'), processNode.getNodeType()) ) # Bypass this ProcessNode else: if verbose: print( "%s (%s) - bypassing" % (processNode.getAttribute('name'), processNode.getNodeType())) # Handle bit-depth mismatches if i > 0 and i < (len(self._processes)-1): RangeClass = ProcessList.serializableClasses['Range'] inBitDepth = self._processes[i-1].getOutBitDepth() outBitDepth = self._processes[i+1].getInBitDepth() if inBitDepth != outBitDepth: if verbose: print( "%s (%s) - Adding a Range node to adapt bit depth %s to bit depth %s" % ( processNode.getAttribute('name'), processNode.getNodeType(), inBitDepth, outBitDepth)) RangeAdapter = RangeClass(inBitDepth, outBitDepth, "adapter", "adapter", style='noClamp') result = RangeAdapter.process(result, verbose=verbose) if verbose: print( "%s (%s) - result value : %s, result type : %s" % (RangeAdapter.getAttribute('name'), RangeAdapter.getNodeType(), " ".join(map(lambda x: "%3.6f" % x, result)), type(result) ) ) return result
def read(self, element, strict=False): root = element # Store attributes for key, value in root.attrib.iteritems(): self.setAttribute(key, value) # Read child elements for child in root: # Find the Python class associated with this XML element tag elementType = child.tag.replace('-', '') elementType = child.tag.replace('_', '') elementClass = self.getClass(elementType) #print( elementType, elementClass ) if elementClass != None: # Instantiate the class and read XML data element = elementClass() # Add ProcessNodes to the ProcessList data structures processNodeClass = self.getClass("ProcessNode") if issubclass(elementClass, processNodeClass): element.read(child, strict=strict) # Check that a given ProcessNode class is compatible with # the current feature set if ((elementType in ["ExposureContrast", "Gamma", "Log", "Reference"] and not (getFeatureCompatibility() & featureSets["Autodesk"])) or (elementType in ["Group"] and not (getFeatureCompatibility() & featureSets["Duiker Research"]))): msg = "Unsupported feature : ProcessNode type %s" % elementType if strict: raise Errors.UnsupportedExtensionError(msg) else: print("ProcessList::read - %s" % msg) self.addProcess(element) # Add elements to the ProcessList data structures else: element.read(child) self.addElement(element) else: msg = "Ignoring element : %s" % child.tag if strict: raise Errors.UnknownProcessNodeError(msg) else: print("ProcessList::read - %s" % msg)
def read(self, element, strict=False): root = element # Store attributes for key, value in root.attrib.iteritems(): self.setAttribute(key, value) # Read child elements for child in root: # Find the Python class associated with this XML element tag elementType = child.tag.replace('-', '') elementType = child.tag.replace('_', '') elementClass = self.getClass(elementType) #print( elementType, elementClass ) if elementClass != None: # Instantiate the class and read XML data element = elementClass() # Add ProcessNodes to the ProcessList data structures processNodeClass = self.getClass("ProcessNode") if issubclass(elementClass, processNodeClass): element.read(child, strict=strict) # Check that a given ProcessNode class is compatible with # the current feature set if ( (elementType in ["ExposureContrast", "Gamma", "Log", "Reference"] and not (getFeatureCompatibility() & featureSets["Autodesk"])) or (elementType in ["Group"] and not (getFeatureCompatibility() & featureSets["Duiker Research"])) ): msg = "Unsupported feature : ProcessNode type %s" % elementType if strict: raise Errors.UnsupportedExtensionError(msg) else: print( "ProcessList::read - %s" % msg ) self.addProcess( element ) # Add elements to the ProcessList data structures else: element.read(child) self.addElement( element ) else: msg = "Ignoring element : %s" % child.tag if strict: raise Errors.UnknownProcessNodeError(msg) else: print( "ProcessList::read - %s" % msg )
def writeFile(self, clfPath, writeSelfContained=False, writeGzip=False): document = self.write(writeSelfContained=writeSelfContained) # Writing Gzipped XML data if writeGzip: if getFeatureCompatibility() & featureSets["Duiker Research"]: prettyString = self.xmlPrettify(document, clfPath) f = gzip.open(clfPath, 'wb') f.write(prettyString) f.close() else: msg = "Unsupported feature : write gzipped file" #print( "ProcessList::writeFile - %s" % msg ) raise Errors.UnsupportedExtensionError(msg) # Writing XML text else: # Non pretty-saving to disk #document.write(scriptPath) # Pretty saving to to disk prettyString = self.xmlPrettify(document, clfPath) fp = open(clfPath, 'wb') fp.write(prettyString) fp.close() return True
def readFile(self, clfPath, strict=False): # Support for reading gzipped xml data if getFeatureCompatibility() & featureSets["Duiker Research"]: # Try to read as gzipped XML file try: f = gzip.open(clfPath, 'rb') tree = etree.parse(f) root = tree.getroot() self.read(root, strict) f.close() # Read as normal XML otherwise except: tree = etree.parse(clfPath) root = tree.getroot() self.read(root, strict) # Read as XML otherwise else: tree = etree.parse(clfPath) root = tree.getroot() self.read(root, strict)
def process(self, values, stride=0, verbose=False): # Handle processing of single values if stride == 0: stride = len(values) # Pass through if there aren't at least three channels if stride < 3: return values # Base attributes inBitDepth = self._attributes['inBitDepth'] outBitDepth = self._attributes['outBitDepth'] # Node attributes style = '' if 'style' in self._attributes: style = self._attributes['style'] if (not (getFeatureCompatibility() & featureSets["Autodesk"]) and style in ['v1.2_Fwd', 'noClampFwd', 'v1.2_Rev', 'noClampRev']): msg = "Unsupported feature : Autodesk CDL style keyword %s" % style raise Errors.UnsupportedExtensionError(msg) # Node parameters slope = [1.0, 1.0, 1.0] offset = [0.0, 0.0, 0.0] power = [1.0, 1.0, 1.0] saturation = 1.0 if 'slope' in self._values: slope = self._values['slope'] if 'offset' in self._values: offset = self._values['offset'] if 'power' in self._values: power = self._values['power'] if 'saturation' in self._values: saturation = self._values['saturation'] ''' print( "slope : %s" % slope ) print( "offset : %s" % offset ) print( "power : %s" % power ) print( "saturation : %s" % saturation ) ''' # Initialize the output value outValues = np.zeros(len(values), dtype=np.float32) # Support CLF spec and Autodesk CTF style keywords for p in range(len(values) / stride): value = values[p * stride:(p + 1) * stride] outValue = values[p * stride:(p + 1) * stride] if style == 'Fwd' or style == 'v1.2_Fwd': for i in range(3): outValue[i] = bitDepthToNormalized(value[i], inBitDepth) outValue[i] = pow( clamp(outValue[i] * slope[i] + offset[i]), power[i]) luma = 0.2126 * outValue[0] + 0.7152 * outValue[ 1] + 0.0722 * outValue[2] for i in range(3): outValue[i] = clamp(luma + saturation * (outValue[i] - luma)) outValue[i] = normalizedToBitDepth(outValue[i], outBitDepth) elif style == 'FwdNoClamp' or style == 'noClampFwd': for i in range(3): outValue[i] = bitDepthToNormalized(value[i], inBitDepth) tmp = outValue[i] * slope[i] + offset[i] if tmp < 0: outValue[i] = tmp else: outValue[i] = pow(tmp, power[i]) luma = 0.2126 * outValue[0] + 0.7152 * outValue[ 1] + 0.0722 * outValue[2] for i in range(3): outValue[i] = luma + saturation * (outValue[i] - luma) outValue[i] = normalizedToBitDepth(outValue[i], outBitDepth) elif style == 'Rev' or style == 'v1.2_Rev': for i in range(3): outValue[i] = bitDepthToNormalized(value[i], inBitDepth) outValue[i] = clamp(outValue[i]) luma = 0.2126 * outValue[0] + 0.7152 * outValue[ 1] + 0.0722 * outValue[2] for i in range(3): outSat = luma + (1.0 / saturation) * (outValue[i] - luma) outValue[i] = (pow(clamp(outSat), 1.0 / power[i]) - offset[i]) / slope[i] outValue[i] = clamp(outValue[i]) outValue[i] = normalizedToBitDepth(outValue[i], outBitDepth) elif style == 'RevNoClamp' or style == 'noClampRev': for i in range(3): outValue[i] = bitDepthToNormalized(value[i], inBitDepth) luma = 0.2126 * outValue[0] + 0.7152 * outValue[ 1] + 0.0722 * outValue[2] for i in range(3): outSat = luma + (1.0 / saturation) * (outValue[i] - luma) if outSat < 0: outValue[i] = (clamp(outSat) - offset[i]) / slope[i] else: outValue[i] = (pow(clamp(outSat), 1.0 / power[i]) - offset[i]) / slope[i] 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
def process(self, values, stride=0, verbose=False): # Cast all values to float32 for processing result = np.array(values, np.float32) if verbose: print("Processing %d values. Stride size: %d" % (len(values), stride)) # Pass the value through each ProcessNode in the ProcessList for i in range(len(self._processes)): processNode = self._processes[i] #print( "processing : %s" % result ) # Process the current value using the ProcessNode if (processNode.getAttribute('bypass') == None or not (getFeatureCompatibility() & featureSets["Autodesk"])): result = processNode.process(result, stride, verbose=verbose) if verbose: print("%s (%s) - result value : %s, result type : %s" % (processNode.getAttribute('name'), processNode.getNodeType(), " ".join( map(lambda x: "%3.6f" % x, result)), type(result))) if (processNode.getAttribute('bypass') != None and not (getFeatureCompatibility() & featureSets["Autodesk"])): print( "%s (%s) - bypass ignored based on feature compatibility setting." % (processNode.getAttribute('name'), processNode.getNodeType())) # Bypass this ProcessNode else: if verbose: print("%s (%s) - bypassing" % (processNode.getAttribute('name'), processNode.getNodeType())) # Handle bit-depth mismatches if i > 0 and i < (len(self._processes) - 1): RangeClass = ProcessList.serializableClasses['Range'] inBitDepth = self._processes[i - 1].getOutBitDepth() outBitDepth = self._processes[i + 1].getInBitDepth() if inBitDepth != outBitDepth: if verbose: print( "%s (%s) - Adding a Range node to adapt bit depth %s to bit depth %s" % (processNode.getAttribute('name'), processNode.getNodeType(), inBitDepth, outBitDepth)) RangeAdapter = RangeClass(inBitDepth, outBitDepth, "adapter", "adapter", style='noClamp') result = RangeAdapter.process(result, verbose=verbose) if verbose: print( "%s (%s) - result value : %s, result type : %s" % (RangeAdapter.getAttribute('name'), RangeAdapter.getNodeType(), " ".join( map(lambda x: "%3.6f" % x, result)), type(result))) return result