Skip to content

Instantly share code, notes, and snippets.

@andrewbunday
Created August 19, 2011 15:40
Show Gist options
  • Save andrewbunday/1157106 to your computer and use it in GitHub Desktop.
Save andrewbunday/1157106 to your computer and use it in GitHub Desktop.
A Simple extractor to parse a valid xml based CDL and convert it into a simplified ColorCorrectionCollection xml file.
#!/usr/bin/env python
#
# Author: Andrew Bunday
# Date: 19/08/11
#
# A Simple extractor to parse a valid xml based CDL and convert it into
# a simplified ColorCorrectionCollection xml file.
import xml.etree.ElementTree
from xml.etree.ElementTree import XMLParser, ElementTree, Element
import sys, re
from StringIO import StringIO as sio
def indent(elem, level=0):
"""Pretty prints the otherwise plain xml string output"""
i = "\n" + level*" "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
indent(elem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
try:
if len(sys.argv) < 2: raise ValueError('No cdl file provided')
p = open( sys.argv[-1], 'rU' )
xml_raw = p.read()
p.close()
except Exception as e :
print "Error: %s" % e
sys.exit(1)
#Stripping out any unwarranted quotation from the xml stream.
xml_clean = re.sub( '"', '' , re.sub('""', "'", xml_raw ) )
try:
tree = xml.etree.ElementTree.parse( sio(xml_clean) )
except Exception as e:
print e
# Create the root for our new xml tree
collectionElem = Element("ColorCorrectionCollection")
collectionElem.set('xmlns', "urn:ASC:CDL:v1.2")
# Iterate through each of the color decisions within the cdl.
# For each one we find we grab out the media reference string
# and filter it for information about the shot since the id's are
# often autogenerated sequential garbage.
#
# For each decision we find we extract the SOP and saturation data
# and build a new clean node which we add to our previously created root.
decisionNodes = tree.findall("{urn:ASC:CDL:v1.01}ColorDecision")
for decisionNode in decisionNodes:
mediaRef = decisionNode.getiterator('{urn:ASC:CDL:v1.01}MediaRef')[0].get('ref')
slateRef = re.findall( '.*/(.*)/\w+-\w+\.dpx', mediaRef )[0]
colorCorrectionElem = Element("ColorCorrection")
colorCorrectionElem.set( 'id', slateRef )
colorCorrections = decisionNode.getiterator('{urn:ASC:CDL:v1.01}ColorCorrection')
for colorCorrection in decisionNode.getiterator('{urn:ASC:CDL:v1.01}ColorCorrection') :
slopeElem = Element('Slope')
slopeElem.text = colorCorrection.find('{urn:ASC:CDL:v1.01}SOPNode/{urn:ASC:CDL:v1.01}Slope').text
offsetElem = Element('Offset')
offsetElem.text = colorCorrection.find('{urn:ASC:CDL:v1.01}SOPNode/{urn:ASC:CDL:v1.01}Offset').text
powerElem = Element('Power')
powerElem.text = colorCorrection.find('{urn:ASC:CDL:v1.01}SOPNode/{urn:ASC:CDL:v1.01}Power').text
SOPElem = Element("SOPNode")
SOPElem.append(slopeElem)
SOPElem.append(offsetElem)
SOPElem.append(powerElem)
colorCorrectionElem.append(SOPElem)
try:
saturationElem = Element('Saturation')
saturationElem.text = colorCorrection.find('{urn:ASC:CDL:v1.01}SatNode/{urn:ASC:CDL:v1.01}Saturation').text
SATElem = Element('SatNode')
SATElem.append(saturationElem)
colorCorrectionElem.append(SATElem)
except Exception as e:
#the is no saturation on this node... stupid optional extras
pass
collectionElem.append( colorCorrectionElem )
indent(collectionElem)
collectionTree = ElementTree( collectionElem )
# A user may put 'monkey.ccc' or 'monkey' as the filename. We ensure we always have a single
# .ccc file extension.
filename = raw_input( "Save .ccc file as:" ).strip(".ccc")
collectionTree.write( "%s.ccc" % filename )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment