Line 32: | Line 32: | ||
'''L''' BYTES = Atom Value | '''L''' BYTES = Atom Value | ||
− | At which point, I was really wondering if the guys at VC weren't a bit crazy in the coconut because, usually, when you create a binary file format and deliberately choose not to use XML, that means you're after size optimization. But here, you have to know that Atoms that host values have a minimum run-length of 32 bytes. Even a simple boolean ! That means that, in order to store a boolean, you must write 2 bytes (Atom Type) + 2 bytes (Run Length = 32) + 32 bytes (the actual boolean value) = '''36 bytes total''' ! (but who am I to judge ? In order to be actually future-proof, we must not eliminate the hypothesis that tomorrow, perhaps, | + | At which point, I was really wondering if the guys at VC weren't a bit crazy in the coconut because, usually, when you create a binary file format and deliberately choose not to use XML, that means you're after size optimization. But here, you have to know that Atoms that host values have a minimum run-length of 32 bytes. Even a simple boolean ! That means that, in order to store a boolean, you must write 2 bytes (Atom Type) + 2 bytes (Run Length = 32) + 32 bytes (the actual boolean value) = '''36 bytes total''' ! (but who am I to judge ? In order to be actually future-proof, we must not eliminate the hypothesis that tomorrow, perhaps, booleans will be stored on 256 bits) (you never really know, that's the beauty with future) |
Line 65: | Line 65: | ||
COLORBOOL, 1 color + a boolean (??) | COLORBOOL, 1 color + a boolean (??) | ||
ENUMSTRING, 1 int for enum value + 1 string for enum name | ENUMSTRING, 1 int for enum value + 1 string for enum name | ||
+ | |||
+ | |||
+ | == Fields == | ||
+ | |||
+ | '''Fields''' are composed of 4 atoms (that I know of) and are like a super-atom of some sort. | ||
+ | |||
+ | A Field contains an actual parameter value, these are the parameters you can tweak in the Optical Flares plug-in and that describe the attributes of your lens flares. | ||
+ | |||
+ | There are fields in 2 types of objects : | ||
+ | * General Parameters object, which are parameters global to the lens flare | ||
+ | * Lens Objects, which describe the lens effects existing in the lens flare (a lens object is one of the 12 object types described in [[Lens_Flares]]) | ||
= Reading the File = | = Reading the File = | ||
− | So basically, instead of using a standard BinaryReader to read the file, you start by reading the header then all you're going to read are Atoms. It's a bit like if the BinaryReader transformed into an ''AtomReader'' instead. | + | So basically, instead of using a standard BinaryReader to read the file, you start by reading the header then all you're going to read are Atoms after that. It's a bit like if the BinaryReader transformed into an ''AtomReader'' instead. |
Line 76: | Line 87: | ||
The main loop of the file reader reads a single Atom that will either be : | The main loop of the file reader reads a single Atom that will either be : | ||
* The GeneralParametersBlock header (Atom Type = 0xBB8 as written above), in which case we then read the GeneralParameters | * The GeneralParametersBlock header (Atom Type = 0xBB8 as written above), in which case we then read the GeneralParameters | ||
− | * The LensObjectDescriptor header (Atom Type = 0x01 as written above), in which case we then read a LensObject | + | * The LensObjectDescriptor header (Atom Type = 0x01 as written above), in which case we then read a LensObject |
== General Parameters Block == | == General Parameters Block == | ||
Line 86: | Line 97: | ||
= LensFlare Class = | = LensFlare Class = | ||
− | Check the [Lens_Flares#The_Lens_Flare_Class] page to get my free LensFlare class in C# that is able to read OFP files. | + | Check the [[Lens_Flares#The_Lens_Flare_Class]] page to get my free LensFlare class in C# that is able to read OFP files. |
Revision as of 17:11, 9 May 2011
Contents
The Optical Flares Preset file format
It could have been a simple XML format but no ! The guys at Video Copilot knew I would be coming for them at some point, so they devised the most annoying file format on Earth !
I suppose it's one of these companies that imagine they can create some products that are "Future Proof". Moohahaha ! Sorry guys, but nothing's future proof : ask the guys in nuclear waste storage...
Moreover, their products are called Video Copilot.Net so you may think they take advantage of the smart serialization helpers that can be used with the .Net framework, like XML with XSLT for example. But that would be too easy.
The guys at VC decided to create their own future-proof-tarot-reading binary format with unique IDs and shit.
Structures
Header
The OFP file starts with a header of 4 bytes :
O F P x
The first 3 bytes are the classic signature bytes and the 4th byte x always equals 3 in my files. I assumed it's the file format version and threw an exception if it's not equal to 3.
Atoms
The remaining data in the file are what I called Atoms.
Understand that these guys didn't simply store an INT, a BOOL, a FLOAT, a STRING or anything like it : all these simple types are encapsulated by what I called an Atom class. Basically, all the elements in the remaining file are atoms.
Here is the structure of an Atom :
1 WORD = Atom Type 1 WORLD = Atom Run Length L L BYTES = Atom Value
At which point, I was really wondering if the guys at VC weren't a bit crazy in the coconut because, usually, when you create a binary file format and deliberately choose not to use XML, that means you're after size optimization. But here, you have to know that Atoms that host values have a minimum run-length of 32 bytes. Even a simple boolean ! That means that, in order to store a boolean, you must write 2 bytes (Atom Type) + 2 bytes (Run Length = 32) + 32 bytes (the actual boolean value) = 36 bytes total ! (but who am I to judge ? In order to be actually future-proof, we must not eliminate the hypothesis that tomorrow, perhaps, booleans will be stored on 256 bits) (you never really know, that's the beauty with future)
I have isolated the following Atom types encountered throughout the file :
// Field atoms FIELD_ID = 0x32, FIELD_TYPE = 0x33, FIELD_VALUE = 0x34, // Lens object atoms LENS_OBJECT_NAME = 0x02, LENS_OBJECT_HIDE = 0x03, LENS_OBJECT_SOLO = 0x04, // Block headers GENERAL_PARAMETERS = 0xBB8, LENS_OBJECT_DESCRIPTOR = 0x01, // Block end markers FIELD_END = 0x7D0, GLOBAL_PARAMS_END = 0xFA0, LENS_OBJECT_END = 0x3E8,
I created an Atom class that simply reads Atoms from a standard System.IO.BinaryReader. The run-length encoded Atom Value is stored as a variant type that can be of the following recognized types :
BOOLEAN INTEGER / ENUM FLOAT COLOR STRING VECTOR2BOOL, 2 floats + a boolean (strange, I know) COLORBOOL, 1 color + a boolean (??) ENUMSTRING, 1 int for enum value + 1 string for enum name
Fields
Fields are composed of 4 atoms (that I know of) and are like a super-atom of some sort.
A Field contains an actual parameter value, these are the parameters you can tweak in the Optical Flares plug-in and that describe the attributes of your lens flares.
There are fields in 2 types of objects :
- General Parameters object, which are parameters global to the lens flare
- Lens Objects, which describe the lens effects existing in the lens flare (a lens object is one of the 12 object types described in Lens_Flares)
Reading the File
So basically, instead of using a standard BinaryReader to read the file, you start by reading the header then all you're going to read are Atoms after that. It's a bit like if the BinaryReader transformed into an AtomReader instead.
Descriptor Atom
The main loop of the file reader reads a single Atom that will either be :
- The GeneralParametersBlock header (Atom Type = 0xBB8 as written above), in which case we then read the GeneralParameters
- The LensObjectDescriptor header (Atom Type = 0x01 as written above), in which case we then read a LensObject
General Parameters Block
LensFlare Class
Check the Lens_Flares#The_Lens_Flare_Class page to get my free LensFlare class in C# that is able to read OFP files.