The container format is CDF, which can be parsed using libucdf. The result is
named binary streams. The structure of these binary streams is discussed in
this document.

bmil: 32 bit signed int in 1/10000 mil

[tlb]: type+length encoded bin records
	1 byte of record type
	4 bytes of record length
	$length bytes of data

[ilb]: ID+length encoded bin records
	2 bytes of record ID
	4 bytes of record length
	$length bytes of data

[l4b]: length encoded bin records
	4 byte of record length
	$length bytes of data

Board6/Data:
	[l4b]
		Same text format as in the protel/ASCII file's RECORD=Board records

Polygons6/Data:
	[l4b]
		Same text format as in the protel/ASCII file's RECORD=Polygon records

Tracks6/Data:
	[tlb] record type:  0x04; typical record length: 45
		@0,  len=1: layer
		@2,  len=1: keepout?
		@3,  len=2: net (ID?)
		@5,  len=2: polygon?
		@7,  len=2: component (ID?)
		@13, len=4: x1 coord in bmil
		@17, len=4: y1 coord in bmil
		@21, len=4: x2 coord in bmil
		@25, len=4: y2 coord in bmil
		@29, len=4: width coord in bmil
		@36, len=1: unionindex
		@44, len=1: user routed

Arcs6/Data:
	[tlb] record type:  0x01; typical record length: 56
		@0,  len=1: layer
		@3,  len=2: net (ID?)
		@7,  len=2: component (ID?)
		@13, len=4: x coord in bmil
		@17, len=4: y coord in bmil
		@21, len=4: radius in bmil
		@25, len=8: start angle (double?)
		@33, len=8: end angle (double?)
		@41, len=4: width bmil
		@48, len=1: unionindex
		@55, len=1: user routed

Texts6/Data:
	[tlb] record type:  0x05; typical length: 230
		@0,  len=1: layer class
		@7,  len=2: component (ID?), only if layer class is 2 or 5
		@13, len=4: x coord in bmil
		@17, len=4: y coord in bmil
		@21, len=4: height
		@27, len=8: rotation (double)
		@35, len=1: is mirrored
		@36, len=4: stroke width bmil
		@40, len=1: is comment
		@41, len=1: is designator
		@46, len=64: font name
		@115, len=1: text ID?
		@226, len=2: text-specific layer ID
		@228, len=1: text-specific layer type: 0=copper, 3=non-copper
	[l4b] text string
		pascal string (first byte is net length)

	Figuring the layer is somewhat complicated:
		- for copper layers (@228=0), check offs (@226):
			- 1 is top copper
			- -1 is bottom copper
			- anything from 2 is intern copper, offset is offs-1 from top copper
		- for non-copper layers (@228=3), check offs (@226):
			6 = top silk
			7 = bottom silk
			8 = top paste
			9 = bottom paste
			10 = top mask
			11 = bottom mask

Fills6/Data: TODO
	[tlb] record type:  0x06; typical record length: 46
		@0,  len=1: layer
		@3,  len=2: net (ID?)
		@7,  len=2: component (ID?)
		@13, len=4: x1 coord in bmil
		@17, len=4: y1 coord in bmil
		@21, len=4: x2 coord in bmil
		@25, len=4: y2 coord in bmil
		@29, len=8: rotation (double?)
		@38, len=8: dir2 ??? (double?)
		@45, len=1: user routed ?


Vias6/Data:
	[tlb] record type:  0x03; typical record length: 209
		@0,  len=1: bbvia top end layer
		@1,  len=1: bbvia bottom end layer
		@3,  len=2: net (ID?)
		@13, len=4: x coord in bmil
		@17, len=4: y coord in bmil
		@21, len=4: copper dia
		@25, len=4: hole dia
		@40, len=1: CAGV, CCSV, CENV ?
		@70, len=1: unionindex

Rules6/Data:
	[ilb]
		Same text format as in the protel/ASCII file's RECORD=Rule records

Classes6/Data:
	[l4b]
		Same text format as in the protel/ASCII file's RECORD=Class records

Nets6/Data:
	[l4b]
		Same text format as in the protel/ASCII file's RECORD=Net records

Pads6/Data:
	1 byte record type

	[l4b]
		name of the pad (pascal string)

	[l4b]
		block 1: unknown

	[l4b]
		block 2: unknown

	[l4b]
		block 3, length 120
		@0, len=1: layer (+23 in the perl script)
		@1, len=1: altlayer?
		@3, len=2: net ID
		@7, len=2: component ID
		@13, len=4: X, bmil
		@17, len=4: Y, bmil
		@21, len=4: sx, bmil
		@25, len=4: sy, bmil
		@29, len=4: mid-sx, bmil
		@33, len=4: mid-sy, bmil
		@37, len=4: bottom-sx, bmil
		@41, len=4: bottom-sy, bmil
		@45, len=4: hole size
		@49, len=1: top type
		@50, len=1: mid type
		@51, len=1: bottom type
		@52, len=8: pad rotation, double?
		@60, len=1: plated
		@62, len=1: padmode 0=simple, 1=top-middle-bottom, 2=full-stack
		@68, len=4: CCW bmil: thermal geo (Conductor Width?)
		@72, len=1: CEN: thermal geo (number?)
		@74, len=4: CAG bmil: thermal geo (gap?)
		@78, len=4: CPR bmil: Plane thermal something
		@82, len=4: CPC bmil: Plane Clearance
		@86, len=4: CPE: paste expansion manual
		@90, len=4: CSE: mask expansion manual?
		@94, len=1: CPL?
		@101, len=1: CPEV: paste expansion mode
		@102, len=1: CSEV: mask expansion mode
		@106, len=8: hole rotation, double?
		(@121, len=1: hole type?)

		TODO: CSS would be the thermal style

	[l4b]*
		Read more blocks until a zero length block is read


	Record type:
		1=arc
		2=pstk
		4=track (line)
		6=fill


	types:
		1=circle or round
		2=rect
		3=oval or octagon
		4=(thermal)
		6=(point)
		7=(point)
		9=roundrect

Components6/Data
	[l4b]
		Same text format as in the protel/ASCII file's RECORD=Component records

ComponentsBodies6/Data (3d model?)
	skip 23 bytes of header
	[l4b]
		Same text format as in the protel/ASCII file's RECORD=CompontentBody records
	at the end nskip=16 (??? perl line 405):
		read 4 bytes skiplen
		skip $nskip*$skiplen
		skip 4 more bytes for whatever
		go back and repeat (including skipping 23 bytes)


Models/Data: 3d, don't care
UniqueIDPrimitiveInformation/Data: 3d, don't care ?
