Re: Inital Houdini lut support
Jeremy Selan <jeremy...@...>
Looks good to me!
I have a few comments, but these dont need to be addressed yet.
* In terms of coding style, you put the return value on a new line, where as I tend to not. I'm actually fine either way, but I'd really like to keep the codebase uniform in this regard. I'm going to be putting together coding guidelines together in the next few days, and once we pick what's preferred I'll do a single cleanup pass to bring the whole codebase up to spec. (I'll also attack line lengths, and #include order at the same time).
* Your commit, c7a1bfadeb..., (where you change the walk order to match GLs ordering) was not strictly necessary. Lut3DOp.h defines two 3dlut index helpers:
int GetGLLut3DArrayOffset(...) int GetAutodeskLut3DArrayOffset(...)
You could have used the second function, rather than the first, to save yourself this trouble. (It is poorly named though, any better idea on names?)
* We will be able to resolve ambiguously named formats (such as the super ambiguous .lut) with a minor addition to FileTransform.cpp. (This code is already in FileTransform:GetFile in code comment form).
The idea is inspired by image reading in Nuke. OCIO will use the file extension to guess the format, and attempt to load it. (in the case of multiple formats with the same extension, just pick one). If this fails, then try to load all other formats with the same extension until one succeeds. If this fails too, then go ahead and try all known formats in case it's a misnamed file. The cool part of this is that users don't have to worry about file format naming (assuming the lut readers all are good about throwing exceptions early on malformed luts), and performance doesnt suffer either as the format results are cached so the rollover detection only happens once per session.
I'll implement this behavior before the next .lut format is added.
-- Jeremy
|
|
Re: Inital Houdini lut support
Jeremy Selan <jeremy...@...>
Also - for future reference - you don't need to include the patch file. It will be sufficient to just include the SHA1 hash for the top- most commit that corresponds to the topic.
For example, in this case 9c2a6d47bb18ee6ca565e2ae1691486f8ae57c0b (You can find this for old commits using gitk, in your repo).
Thanks!
-- Jeremy
|
|
Re: Review: pkg-config support and some OCIO_VERSION changes
Jeremy Selan <jeremy...@...>
Looks good to me!
I really like the VERSION consolidation and the cmake "configure_file" mojo. Now that I know about that approach, I'll use it for the OCIO_NAMESPACE #define as well...
-- Jeremy
|
|
Re: Inital Houdini lut support
Malcolm Humphreys <malcolmh...@...>
* In terms of coding style, you put the return value on a new line, where as I tend to not. I'm actually fine either way, but I'd really like to keep the codebase uniform in this regard. I'm going to be putting together coding guidelines together in the next few days, and once we pick what's preferred I'll do a single cleanup pass to bring the whole codebase up to spec. (I'll also attack line lengths, and #include order at the same time). I'm happy to match what ever style you put forward, I mainly like doing this as it makes it really clear what a function / method is returning. We don't have function overloading but in code bases where you do I find this helps. My only other note would be about indenting all namespaces, I see you want to limit to 80 char columns (+1) this with the namespace indenting is going to make for some very compact coding. ie. --snip-- OCIO_NAMESPACE_ENTER { namespace { void foo(); } } OCIO_NAMESPACE_EXIT --snip-- --snip-- OCIO_NAMESPACE_ENTER { namespace { void foo(); } // anonymous namespace } OCIO_NAMESPACE_EXIT --snip-- * Your commit, c7a1bfadeb..., (where you change the walk order to match GLs ordering) was not strictly necessary. Lut3DOp.h defines two 3dlut index helpers:
int GetGLLut3DArrayOffset(...) int GetAutodeskLut3DArrayOffset(...)
You could have used the second function, rather than the first, to save yourself this trouble. (It is poorly named though, any better idea on names?) int GetRGBLut3DArrayOffset(...)? * We will be able to resolve ambiguously named formats (such as the super ambiguous .lut) with a minor addition to FileTransform.cpp. (This code is already in FileTransform:GetFile in code comment form).
The idea is inspired by image reading in Nuke. OCIO will use the file extension to guess the format, and attempt to load it. (in the case of multiple formats with the same extension, just pick one). If this fails, then try to load all other formats with the same extension until one succeeds. If this fails too, then go ahead and try all known formats in case it's a misnamed file. The cool part of this is that users don't have to worry about file format naming (assuming the lut readers all are good about throwing exceptions early on malformed luts), and performance doesnt suffer either as the format results are cached so the rollover detection only happens once per session.
I'll implement this behavior before the next .lut format is added. Sounds good, like in nuke could your see us forcing a loader in the profile format? .malcolm
|
|
Jeremy Selan <jeremy...@...>
I'm completely in favor of making the OCIO configuration files easier to read and edit. I have a few specific concerns about YAML, but it's definitely worth exploring. Care to take a stab at it? In defense of XML ... * It's the 'no format decision' decision. Support is ubiquitous, and no one ever wonders, "what the hell is this?" YAML is not nearly as widely known. Never having looked at YAML before, when I first looked at your configuration file I was wondering which formatting parts were important. But this could be made more obvious with a few tweaks to the outputter format. * We've already got the XML code working. * The ASC CDL defines an xml spec which I would like to support (for interoperability with other CDL apps), so we're not going to be be able to ditch tinyxml. * This may not be wise in the long term, but I really like how OCIO has minimal external build dependencies. (Some day when the windows port needs to be attacked, this should keep life simple I hope!) Does OSX have YAML as part of its base installation? Do normal linux distros? (I assume Windows doesnt) Is there a minimal yaml implementation we could pull internal, similar in spirit to tinyxml? If so (assuming it can be namespaced properly, and the licence terms are suitable) I'd love to keep it internal. I'm not sure that yaml's strong python support is relevant to this discussion. OCIO serialization is handled on the C++ side, and the python bindings provide typed interfaces to the transforms. (I.e., a CDLTransform is a native python class as opposed to a python dict with particular key value pairs). And, I would prefer that folks manipulating OCIO profiles in python use the native OCIO API rather than mucking with the serialized representations. Or is there another use case I'm missing? Also, in terms of overall development priorities I wouldn't personally put this at the top of my list. (I was much more excited about your adding Houdini lut support, for example). But I can see that making the format less daunting could be a selling point adoption. -- Jeremy On Tue, Oct 5, 2010 at 6:43 PM, Malcolm Humphreys <malcolmh...@...> wrote: Are people super into the idea of using xml?
We used xml for nearly everything at RSP, over time it became clear that it's a pretty poor choice for a lot of things.
One of the developers introduced the use of YAML (http://www.yaml.org/ http://en.wikipedia.org/wiki/YAML) and it took off with everyone, it happened again when I recommended it's introduction at DrD (where pretty much everything was XML). RV has started to use it for it's package descriptions as well.
As I don't think any other apps will actually be writing ocio profiles other than the ocio api, and people will be hand writing these profiles. I don't see a benefit to using xml for a profile description, if we using as an interchange format then maybe.
btw. I really don't like file format discussions but I think this would really help ocio profile readability. If people are into the idea I'm happy to do the leg work to get it to work.
I have attached a small demo python script for you to check out, it mostly shows off how to define your own custom yaml serialisation. You need PyYaml (http://pyyaml.org/) to run the demo.
Why I like it: - super simple to parse and serialise objects - human readable / editable - easy to define your own custom types - using yaml in python is so simple
It would be quite easy to have binary data (eg file luts) interweaved inside a yaml file. http://en.wikipedia.org/wiki/YAML#Other_specified_data_types --snip-- picture: !!binary | R0lGODlhDAAMAIQAAP//9/X 17unp5WZmZgAAAOfn515eXv Pz7Y6OjuDg4J+fn5OTk6enp 56enmleECcgggoBADs=mZmE --snip--
http://www.yaml.org/spec/1.2/spec.html#id2759572 - Relation to JSON http://www.yaml.org/spec/1.2/spec.html#id2759732 - Relation to XML
YAML --snip-- ocs_profile_version: 1 resource_path: luts luma_b: '0.0722' luma_g: '0.7152' luma_r: '0.2126' role_compositing_log: lgh role_scene_linear: lnh strictparsing: true displays: Film1D: !Display {colorspace: vd8, device: sRGB} Log: !Display {colorspace: lg10, device: sRGB} colorspaces: dt8: !ColorSpace bitdepth: 8ui description: null family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: null, src: diffusemult.spimtx} - !ColorSpaceTransform {dst: lnh, src: vd8} lg10: !ColorSpace bitdepth: 10ui description: lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries. family: lg gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: lnh: !ColorSpace bitdepth: 16f description: The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 inthis space corresponds to a properly exposed 18% grey card. family: ln gpuallocation: lg2 gpumax: 6 gpumin: -15 isdata: false to_reference: null vd8: !ColorSpace bitdepth: 8ui description: vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: linear, src: vd10.spi1d} --snip--
XML --snip-- <ocioconfig version="1" resourcepath="luts" strictparsing="true" luma_r="0.2126" luma_g="0.7152" luma_b="0.0722" role_scene_linear="lnh" role_compositing_log="lgh"> <display device="sRGB" name="Film1D" colorspace="vd8"/> <display device="sRGB" name="Log" colorspace="lg10"/> <colorspace name="lnh" family="ln" bitdepth="16f" isdata="false" gpuallocation="lg2" gpumin="-15" gpumax="6"> <description>The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 in this space corresponds to a properly exposed 18% grey card. </description> </colorspace> <colorspace name="lg10" family="lg" bitdepth="10ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries.</description> <to_reference> <group> <file src="lg10.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lg16" family="lg" bitdepth="16ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg16 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 16bit uiint version is used for DI deliveries in the rare case where this is requested. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lgh" family="lg" bitdepth="16f" isdata="false" gpuallocation="uniform" gpumin="-0.2" gpumax="1.615"> <description>Converts from scanned film to the show linear reference space. This is a custom curve based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This floating point version of the conversion that includes a large range of over-shoot and under-shoot values. This allows for colortiming offsetsto be applied and reversed out losslessly. For internal use only. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="vd8" family="vd" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. </description> <to_reference> <group> <file src="vd10.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="dt8" family="dt" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description> </description> <to_reference> <group> <file src="diffusemult.spimtx"/> <colorspacetransform src="vd8" dst="lnh"/> </group> </to_reference> </colorspace> </ocioconfig> --snip--
.malcolm
|
|
toggle quoted messageShow quoted text
On Oct 7, 2:26 pm, Jeremy Selan <jeremy...@...> wrote: I'm completely in favor of making the OCIO configuration files easier to read and edit.
I have a few specific concerns about YAML, but it's definitely worth exploring. Care to take a stab at it?
In defense of XML ...
* It's the 'no format decision' decision. Support is ubiquitous, and no one ever wonders, "what the hell is this?" YAML is not nearly as widely known. Never having looked at YAML before, when I first looked at your configuration file I was wondering which formatting parts were important. But this could be made more obvious with a few tweaks to the outputter format.
* We've already got the XML code working.
* The ASC CDL defines an xml spec which I would like to support (for interoperability with other CDL apps), so we're not going to be be able to ditch tinyxml.
* This may not be wise in the long term, but I really like how OCIO has minimal external build dependencies. (Some day when the windows port needs to be attacked, this should keep life simple I hope!) Does OSX have YAML as part of its base installation? Do normal linux distros? (I assume Windows doesnt) Is there a minimal yaml implementation we could pull internal, similar in spirit to tinyxml? If so (assuming it can be namespaced properly, and the licence terms are suitable) I'd love to keep it internal.
I'm not sure that yaml's strong python support is relevant to this discussion. OCIO serialization is handled on the C++ side, and the python bindings provide typed interfaces to the transforms. (I.e., a CDLTransform is a native python class as opposed to a python dict with particular key value pairs). And, I would prefer that folks manipulating OCIO profiles in python use the native OCIO API rather than mucking with the serialized representations. Or is there another use case I'm missing?
Also, in terms of overall development priorities I wouldn't personally put this at the top of my list. (I was much more excited about your adding Houdini lut support, for example). But I can see that making the format less daunting could be a selling point adoption.
-- Jeremy
On Tue, Oct 5, 2010 at 6:43 PM, Malcolm Humphreys
<malcolmh...@...> wrote:
Are people super into the idea of using xml? We used xml for nearly everything at RSP, over time it became clear that it's a pretty poor choice for a lot of things. One of the developers introduced the use of YAML (http://www.yaml.org/ http://en.wikipedia.org/wiki/YAML) and it took off with everyone, it happened again when I recommended it's introduction at DrD (where pretty much everything was XML). RV has started to use it for it's package descriptions as well. As I don't think any other apps will actually be writing ocio profiles other than the ocio api, and people will be hand writing these profiles. I don't see a benefit to using xml for a profile description, if we using as an interchange format then maybe. btw. I really don't like file format discussions but I think this would really help ocio profile readability. If people are into the idea I'm happy to do the leg work to get it to work. I have attached a small demo python script for you to check out, it mostly shows off how to define your own custom yaml serialisation. You need PyYaml (http://pyyaml.org/) to run the demo. Why I like it: - super simple to parse and serialise objects - human readable / editable - easy to define your own custom types - using yaml in python is so simple It would be quite easy to have binary data (eg file luts) interweaved inside a yaml file. http://en.wikipedia.org/wiki/YAML#Other_specified_data_types --snip-- picture: !!binary | R0lGODlhDAAMAIQAAP//9/X 17unp5WZmZgAAAOfn515eXv Pz7Y6OjuDg4J+fn5OTk6enp 56enmleECcgggoBADs=mZmE --snip-- http://www.yaml.org/spec/1.2/spec.html#id2759572- Relation to JSON http://www.yaml.org/spec/1.2/spec.html#id2759732- Relation to XML YAML --snip-- ocs_profile_version: 1 resource_path: luts luma_b: '0.0722' luma_g: '0.7152' luma_r: '0.2126' role_compositing_log: lgh role_scene_linear: lnh strictparsing: true displays: Film1D: !Display {colorspace: vd8, device: sRGB} Log: !Display {colorspace: lg10, device: sRGB} colorspaces: dt8: !ColorSpace bitdepth: 8ui description: null family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: null, src: diffusemult.spimtx} - !ColorSpaceTransform {dst: lnh, src: vd8} lg10: !ColorSpace bitdepth: 10ui description: lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries. family: lg gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: lnh: !ColorSpace bitdepth: 16f description: The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 inthis space corresponds to a properly exposed 18% grey card. family: ln gpuallocation: lg2 gpumax: 6 gpumin: -15 isdata: false to_reference: null vd8: !ColorSpace bitdepth: 8ui description: vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: linear, src: vd10.spi1d} --snip-- XML --snip-- <ocioconfig version="1" resourcepath="luts" strictparsing="true" luma_r="0.2126" luma_g="0.7152" luma_b="0.0722" role_scene_linear="lnh" role_compositing_log="lgh"> <display device="sRGB" name="Film1D" colorspace="vd8"/> <display device="sRGB" name="Log" colorspace="lg10"/> <colorspace name="lnh" family="ln" bitdepth="16f" isdata="false" gpuallocation="lg2" gpumin="-15" gpumax="6"> <description>The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 in this space corresponds to a properly exposed 18% grey card. </description> </colorspace> <colorspace name="lg10" family="lg" bitdepth="10ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries.</description> <to_reference> <group> <file src="lg10.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lg16" family="lg" bitdepth="16ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg16 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 16bit uiint version is used for DI deliveries in the rare case where this is requested. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lgh" family="lg" bitdepth="16f" isdata="false" gpuallocation="uniform" gpumin="-0.2" gpumax="1.615"> <description>Converts from scanned film to the show linear reference space. This is a custom curve based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This floating point version of the conversion that includes a large range of over-shoot and under-shoot values. This allows for colortiming offsetsto be applied and reversed out losslessly. For internal use only. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="vd8" family="vd" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. </description> <to_reference> <group> <file src="vd10.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="dt8" family="dt" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description> </description> <to_reference> ...
read more »
|
|
Malcolm Humphreys <malcolmh...@...>
Sorry I will be responding to this soon, bit busy for the next 3 days.
.malcolm
toggle quoted messageShow quoted text
On 09/10/2010, at 9:35 AM, bsloan wrote: http://code.google.com/p/yaml-cpp/
...is the compiled yaml io library. I believe yaml support is built into the python distro.
-blake
On Oct 7, 2:26 pm, Jeremy Selan <jeremy...@...> wrote:
I'm completely in favor of making the OCIO configuration files easier to read and edit.
I have a few specific concerns about YAML, but it's definitely worth exploring. Care to take a stab at it?
In defense of XML ...
* It's the 'no format decision' decision. Support is ubiquitous, and no one ever wonders, "what the hell is this?" YAML is not nearly as widely known. Never having looked at YAML before, when I first looked at your configuration file I was wondering which formatting parts were important. But this could be made more obvious with a few tweaks to the outputter format.
* We've already got the XML code working.
* The ASC CDL defines an xml spec which I would like to support (for interoperability with other CDL apps), so we're not going to be be able to ditch tinyxml.
* This may not be wise in the long term, but I really like how OCIO has minimal external build dependencies. (Some day when the windows port needs to be attacked, this should keep life simple I hope!) Does OSX have YAML as part of its base installation? Do normal linux distros? (I assume Windows doesnt) Is there a minimal yaml implementation we could pull internal, similar in spirit to tinyxml? If so (assuming it can be namespaced properly, and the licence terms are suitable) I'd love to keep it internal.
I'm not sure that yaml's strong python support is relevant to this discussion. OCIO serialization is handled on the C++ side, and the python bindings provide typed interfaces to the transforms. (I.e., a CDLTransform is a native python class as opposed to a python dict with particular key value pairs). And, I would prefer that folks manipulating OCIO profiles in python use the native OCIO API rather than mucking with the serialized representations. Or is there another use case I'm missing?
Also, in terms of overall development priorities I wouldn't personally put this at the top of my list. (I was much more excited about your adding Houdini lut support, for example). But I can see that making the format less daunting could be a selling point adoption.
-- Jeremy
On Tue, Oct 5, 2010 at 6:43 PM, Malcolm Humphreys
<malcolmh...@...> wrote:
Are people super into the idea of using xml? We used xml for nearly everything at RSP, over time it became clear that it's a pretty poor choice for a lot of things. One of the developers introduced the use of YAML (http://www.yaml.org/ http://en.wikipedia.org/wiki/YAML) and it took off with everyone, it happened again when I recommended it's introduction at DrD (where pretty much everything was XML). RV has started to use it for it's package descriptions as well. As I don't think any other apps will actually be writing ocio profiles other than the ocio api, and people will be hand writing these profiles. I don't see a benefit to using xml for a profile description, if we using as an interchange format then maybe. btw. I really don't like file format discussions but I think this would really help ocio profile readability. If people are into the idea I'm happy to do the leg work to get it to work. I have attached a small demo python script for you to check out, it mostly shows off how to define your own custom yaml serialisation. You need PyYaml (http://pyyaml.org/) to run the demo. Why I like it: - super simple to parse and serialise objects - human readable / editable - easy to define your own custom types - using yaml in python is so simple It would be quite easy to have binary data (eg file luts) interweaved inside a yaml file. http://en.wikipedia.org/wiki/YAML#Other_specified_data_types --snip-- picture: !!binary | R0lGODlhDAAMAIQAAP//9/X 17unp5WZmZgAAAOfn515eXv Pz7Y6OjuDg4J+fn5OTk6enp 56enmleECcgggoBADs=mZmE --snip-- http://www.yaml.org/spec/1.2/spec.html#id2759572- Relation to JSON http://www.yaml.org/spec/1.2/spec.html#id2759732- Relation to XML YAML --snip-- ocs_profile_version: 1 resource_path: luts luma_b: '0.0722' luma_g: '0.7152' luma_r: '0.2126' role_compositing_log: lgh role_scene_linear: lnh strictparsing: true displays: Film1D: !Display {colorspace: vd8, device: sRGB} Log: !Display {colorspace: lg10, device: sRGB} colorspaces: dt8: !ColorSpace bitdepth: 8ui description: null family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: null, src: diffusemult.spimtx} - !ColorSpaceTransform {dst: lnh, src: vd8} lg10: !ColorSpace bitdepth: 10ui description: lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries. family: lg gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: lnh: !ColorSpace bitdepth: 16f description: The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 inthis space corresponds to a properly exposed 18% grey card. family: ln gpuallocation: lg2 gpumax: 6 gpumin: -15 isdata: false to_reference: null vd8: !ColorSpace bitdepth: 8ui description: vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: linear, src: vd10.spi1d} --snip-- XML --snip-- <ocioconfig version="1" resourcepath="luts" strictparsing="true" luma_r="0.2126" luma_g="0.7152" luma_b="0.0722" role_scene_linear="lnh" role_compositing_log="lgh"> <display device="sRGB" name="Film1D" colorspace="vd8"/> <display device="sRGB" name="Log" colorspace="lg10"/> <colorspace name="lnh" family="ln" bitdepth="16f" isdata="false" gpuallocation="lg2" gpumin="-15" gpumax="6"> <description>The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 in this space corresponds to a properly exposed 18% grey card. </description> </colorspace> <colorspace name="lg10" family="lg" bitdepth="10ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries.</description> <to_reference> <group> <file src="lg10.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lg16" family="lg" bitdepth="16ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg16 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 16bit uiint version is used for DI deliveries in the rare case where this is requested. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lgh" family="lg" bitdepth="16f" isdata="false" gpuallocation="uniform" gpumin="-0.2" gpumax="1.615"> <description>Converts from scanned film to the show linear reference space. This is a custom curve based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This floating point version of the conversion that includes a large range of over-shoot and under-shoot values. This allows for colortiming offsetsto be applied and reversed out losslessly. For internal use only. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="vd8" family="vd" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. </description> <to_reference> <group> <file src="vd10.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="dt8" family="dt" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description> </description> <to_reference> ...
read more »
|
|
Review: ExponentTransform can serialize itself
Jeremy Selan <jeremy...@...>
The ExponentTransform (a publicly exposed class for doing power / gamma operations) previously could not serialize itself to xml. This commit adds the feature. Repo: http://github.com/jeremyselan/OpenColorIOCommits: 4581f2e0725466c43cc6237d93d356a4a28bfa3e -- Jeremy
|
|
Malcolm Humphreys <malcolmh...@...>
I'm completely in favor of making the OCIO configuration files easier to read and edit.
I have a few specific concerns about YAML, but it's definitely worth exploring. Care to take a stab at it? Ok lets jump in :) In defense of XML ...
* It's the 'no format decision' decision. Support is ubiquitous, and no one ever wonders, "what the hell is this?" YAML is not nearly as widely known. Never having looked at YAML before, when I first looked at your configuration file I was wondering which formatting parts were important. But this could be made more obvious with a few tweaks to the outputter format. There are a few good articles on the subject of choosing XML 'just because', these two I like. http://www.ibm.com/developerworks/library/x-sbxml.htmlhttp://www.ibm.com/developerworks/xml/library/x-matters23.htmlI think XML is a great fit for a lot of things and I would still choose it for these but it's used a little too much 'just because'. * We've already got the XML code working. True, but it feels a bit ridged and requires a lot of code to do relatively simple serialisation. I find this is inherently part of using xml, and is nothing different from anywhere else I have used it or seen it used. Looking at it, the current serialisation boils down to dumping Config::Impl to disk http://github.com/imageworks/OpenColorIO/blob/master/src/core/Config.cpp (line: 136) Config::Impl consists of: - a few std::string's - RGB float array - prefixed list of roles - unordered vector of display devices. - unordered vector of colorspaces Config::writeXML (line: 761) and Config::Impl::loadXmlElement (line: 836) do most of the heavy lifting in terms of overall XML structure. (Looking at this now there is a bit too much knowledge about <display>'s which we might want to refactor into a clearer core concept.) ParseUtils.cpp does most of the string -> ocio data type glue while XmlIO.cpp takes care of all the logic and structure for every Transform() type. See below I have attached a yaml-cpp demo for doing the same thing. * The ASC CDL defines an xml spec which I would like to support (for interoperability with other CDL apps), so we're not going to be be able to ditch tinyxml. I don't think this should change. But If we were going to have a way to support OCIO Transform() plugins (at compile time or run time). I think it would be important for each Transform() to know how to seialize themselves. This means tinyxml would become only a build dependency for the CDL Transform() plugin and not the entire core. * This may not be wise in the long term, but I really like how OCIO has minimal external build dependencies. (Some day when the windows port needs to be attacked, this should keep life simple I hope!) Does OSX have YAML as part of its base installation? Do normal linux distros? (I assume Windows doesnt) Is there a minimal yaml implementation we could pull internal, similar in spirit to tinyxml? If so (assuming it can be namespaced properly, and the licence terms are suitable) I'd love to keep it internal. Agreed, this should all be internal to OCIO. Both http://code.google.com/p/yaml-cpp and http://pyyaml.org/wiki/LibYAML are MIT Licensed ( http://en.wikipedia.org/wiki/MIT_License). It's pretty open licence you just need to include a named reference and MIT licence with OCIO. I have never used the LibYAML but I do like the stream / state based style yaml-cpp has chosen. http://code.google.com/p/yaml-cpp/wiki/HowToEmitYAMLyaml-cpp is namespaced with YAML:: and I consider it to be pretty small lib. --snip stlemitter.h-- namespace YAML { template <typename T> inline Emitter& operator << (Emitter& emitter, const std::vector <T>& v) { typedef typename std::vector <T> vec; emitter << BeginSeq; for(typename vec::const_iterator it=v.begin();it!=v.end();++it) emitter << *it; emitter << EndSeq; return emitter; } ... --snip stlemitter.h-- I'm not sure that yaml's strong python support is relevant to this discussion. OCIO serialization is handled on the C++ side, and the python bindings provide typed interfaces to the transforms. (I.e., a CDLTransform is a native python class as opposed to a python dict with particular key value pairs). And, I would prefer that folks manipulating OCIO profiles in python use the native OCIO API rather than mucking with the serialized representations. Or is there another use case I'm missing? Sure its just an easy way to prototype the yaml, like you said this should all be internal to OCIO. I don't think you will be able to stop people from mucking with the XML directly in python either. Attached is a quick yaml-cpp demo which setups a similar structure to configs/testing/config.ocio then serializes it to YAML, parses that YAML into a new config and checks some of the data. Also, in terms of overall development priorities I wouldn't personally put this at the top of my list. (I was much more excited about your adding Houdini lut support, for example). But I can see that making the format less daunting could be a selling point adoption. I see the profiles as the key concept that makes OCIO interesting. All the other parts are important on the implementation side of things, but the day to day interaction will be all about the profiles. As long as the profiles are clear and easily extendable I think we will be in a good place. .malcolm -- Jeremy
On Tue, Oct 5, 2010 at 6:43 PM, Malcolm Humphreys <malcolmh...@...> wrote:
Are people super into the idea of using xml?
We used xml for nearly everything at RSP, over time it became clear that it's a pretty poor choice for a lot of things.
One of the developers introduced the use of YAML (http://www.yaml.org/ http://en.wikipedia.org/wiki/YAML) and it took off with everyone, it happened again when I recommended it's introduction at DrD (where pretty much everything was XML). RV has started to use it for it's package descriptions as well.
As I don't think any other apps will actually be writing ocio profiles other than the ocio api, and people will be hand writing these profiles. I don't see a benefit to using xml for a profile description, if we using as an interchange format then maybe.
btw. I really don't like file format discussions but I think this would really help ocio profile readability. If people are into the idea I'm happy to do the leg work to get it to work.
I have attached a small demo python script for you to check out, it mostly shows off how to define your own custom yaml serialisation. You need PyYaml (http://pyyaml.org/) to run the demo.
Why I like it: - super simple to parse and serialise objects - human readable / editable - easy to define your own custom types - using yaml in python is so simple
It would be quite easy to have binary data (eg file luts) interweaved inside a yaml file. http://en.wikipedia.org/wiki/YAML#Other_specified_data_types --snip-- picture: !!binary | R0lGODlhDAAMAIQAAP//9/X 17unp5WZmZgAAAOfn515eXv Pz7Y6OjuDg4J+fn5OTk6enp 56enmleECcgggoBADs=mZmE --snip--
http://www.yaml.org/spec/1.2/spec.html#id2759572 - Relation to JSON http://www.yaml.org/spec/1.2/spec.html#id2759732 - Relation to XML
YAML --snip-- ocs_profile_version: 1 resource_path: luts luma_b: '0.0722' luma_g: '0.7152' luma_r: '0.2126' role_compositing_log: lgh role_scene_linear: lnh strictparsing: true displays: Film1D: !Display {colorspace: vd8, device: sRGB} Log: !Display {colorspace: lg10, device: sRGB} colorspaces: dt8: !ColorSpace bitdepth: 8ui description: null family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: null, src: diffusemult.spimtx} - !ColorSpaceTransform {dst: lnh, src: vd8} lg10: !ColorSpace bitdepth: 10ui description: lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries. family: lg gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: lnh: !ColorSpace bitdepth: 16f description: The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 inthis space corresponds to a properly exposed 18% grey card. family: ln gpuallocation: lg2 gpumax: 6 gpumin: -15 isdata: false to_reference: null vd8: !ColorSpace bitdepth: 8ui description: vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. family: vd8 gpuallocation: uniform gpumax: 1 gpumin: 0 isdata: false to_reference: - !File {interpolation: linear, src: vd10.spi1d} --snip--
XML --snip-- <ocioconfig version="1" resourcepath="luts" strictparsing="true" luma_r="0.2126" luma_g="0.7152" luma_b="0.0722" role_scene_linear="lnh" role_compositing_log="lgh"> <display device="sRGB" name="Film1D" colorspace="vd8"/> <display device="sRGB" name="Log" colorspace="lg10"/> <colorspace name="lnh" family="ln" bitdepth="16f" isdata="false" gpuallocation="lg2" gpumin="-15" gpumax="6"> <description>The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 in this space corresponds to a properly exposed 18% grey card. </description> </colorspace> <colorspace name="lg10" family="lg" bitdepth="10ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg10 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 10bit uiint version is used for DI deliveries.</description> <to_reference> <group> <file src="lg10.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lg16" family="lg" bitdepth="16ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>lg16 converts from scanned film to the show linear reference space. This is a custom conversion based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This 16bit uiint version is used for DI deliveries in the rare case where this is requested. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="nearest" /> </group> </to_reference> </colorspace> <colorspace name="lgh" family="lg" bitdepth="16f" isdata="false" gpuallocation="uniform" gpumin="-0.2" gpumax="1.615"> <description>Converts from scanned film to the show linear reference space. This is a custom curve based on several Kodak acquisition stocks. All three color channels have the same response and there is no cross talk. This transform has a shoulder and toe compensation. This floating point version of the conversion that includes a large range of over-shoot and under-shoot values. This allows for colortiming offsetsto be applied and reversed out losslessly. For internal use only. </description> <to_reference> <group> <file src="lgf.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="vd8" family="vd" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description>vd8 is an 8 bit sRGB like,2.2 gamma, conversion to and from the reference colorspace. This is a 1-d representation does not include any subtractive color mixing or crosstalk compensation. This is commonly used to interchange files between internal and external vendors. This is used as the interchange space for final images on direct to video or television products. </description> <to_reference> <group> <file src="vd10.spi1d" interpolation="linear" /> </group> </to_reference> </colorspace> <colorspace name="dt8" family="dt" bitdepth="8ui" isdata="false" gpuallocation="uniform" gpumin="0" gpumax="1"> <description> </description> <to_reference> <group> <file src="diffusemult.spimtx"/> <colorspacetransform src="vd8" dst="lnh"/> </group> </to_reference> </colorspace> </ocioconfig> --snip--
.malcolm
|
|
Re: Review: ExponentTransform can serialize itself
Malcolm Humphreys <malcolmh...@...>
LGTM - even without any tests : )
.malcolm
toggle quoted messageShow quoted text
On 14/10/2010, at 3:53 AM, Jeremy Selan wrote: The ExponentTransform (a publicly exposed class for doing power / gamma operations) previously could not serialize itself to xml. This commit adds the feature.
Repo: http://github.com/jeremyselan/OpenColorIO
Commits: 4581f2e0725466c43cc6237d93d356a4a28bfa3e
-- Jeremy
|
|
Review: use CPack to create the source tarball
Malcolm Humphreys <malcolmh...@...>
|
|
Re: Review: use CPack to create the source tarball
Jeremy Selan <jeremy...@...>
|
|
Re: Review: use CPack to create the source tarball
Jeremy Selan <jeremy...@...>
One gotcha: when you use `make package_source` it appears to grab all files in the subdirectory, including the build dirs and other files which may not be part of the repository. I'm looking at setting up cpack to only include specified subdirs.
-- Jeremy
toggle quoted messageShow quoted text
|
|
Re: Review: use CPack to create the source tarball
Malcolm Humphreys <malcolmh...@...>
There is a cpack ignore dirs command, I would recommended doing out of source builds also.
"Jeremy Selan" <jeremy...@...> wrote:
toggle quoted messageShow quoted text
One gotcha: when you use `make package_source` it appears to grab all files in the subdirectory, including the build dirs and other files which may not be part of the repository. I'm looking at setting up cpack to only include specified subdirs.
-- Jeremy
On Fri, Oct 15, 2010 at 3:20 PM, Jeremy Selan <jeremy...@...> wrote:
looks good to me. -- Jeremy
On Thu, Oct 14, 2010 at 4:22 AM, Malcolm Humphreys <malcolmh...@...> wrote:
* added cpack support to replace the tgz_create script. Run 'make package_source' to create 'olio.VERSION.tar.gz' * removed tgz_create script
http://github.com/malcolmhumphreys/OpenColorIO/commit/a02d021cb8bc9d297e4db4d133e16fc189f75405
.malcolm
-- Sent from my phone.
|
|
Re: Review: use CPack to create the source tarball
Hi Jeremy, On Fri, Oct 15, 2010 at 5:35 PM, Jeremy Selan <jeremy...@...> wrote: One gotcha: when you use `make package_source` it appears to grab all files in the subdirectory, including the build dirs and other files which may not be part of the repository. I'm looking at setting up cpack to only include specified subdirs. You can use the CPACK_SOURCE_IGNORE_FILES to hold a semi-colon separated list of regexs to ignore files/directories. Cheers, Alan.
|
|
Jeremy Selan <jeremy...@...>
Ok, I'm convinced. Let's give YAML a shot.
In terms of broad technical strokes, I think either YAML or XML would be sufficient. But given your enthusiasm for YAML, and it's superior human readability, there's no argument against it. (Other than the work / support involved).
A few additional comments as we get going:
* This will break the API, so before I roll the commit(s) into the master branch we'll tag off a stable 0.6 branch. Feel free to do anything you want in your local git branch, of course.
* As we introduce OCIO "dynamic" Transform plugins, my hope is to not burden them with the task of serialization. But let's not worry about this for now.
* I agree that Yaml-cpp seems like our best option of the ones you've mentioned. Let's go with it. Is is feasible to wrap it into the OCIO namespace? see src/core/tinyxml/tinyxml.h as an example It's got a lot of source files, but I really would prefer if possible to keep all OCIO symbols inside a versioned namespace.
* For the OCIO:Config implementation, the list of display devices and color spaces actually do preserve order. While the ordering is not relevant to color processing, it is useful in a UI context.
* Keeping the serialization code internally as statics - not on the Transforms themselves - is useful so we dont need to expose the serialization to the public API. Or do you have a better implementation in mind?
As soon as you have even a stub implementation -- it doesnt need to build -- I'd love to see it!
Thanks for all your work on this issue,
Jeremy
|
|
Hi All,
Just wanted to throw a quick thought in on C++ LUTs.
I've recently been dealing with Arri's Alexa. One of the more unusual aspects of it's Log-C transform is that it changes based on the camera's ASA.
I thought you might want to allow for LUTs which specify arguments, as this would be required for Log-C, and may be needed or useful further down the line.
Anyway - that was all :) When the API is ready I'd be happy to supply S-Log, Log-C, sRGB, and Rec709 transforms both to and from linear.
Cheers,
Alan.
|
|
Review: YAML serialization
Malcolm Humphreys <malcolmh...@...>
- Initial checkin of YAML serialization - Added ext/yaml-cpp-0.2.5.tar.gz with a patch to build it static - Added yaml-cpp to the LICENCE file - CDLTransform should be the only thing depending on tinyxml - PyOCIO_Config_getXML now returns YAML not XML, this should be fixed soon. Possibly this python method should be removed and we use the config.__str__() instead, this would make it slightly more pythonic http://github.com/malcolmhumphreys/OpenColorIO/commit/ef6cddf742b961e89061ddd9a68f968eb0d4e5fd.malcolm
|
|
Malcolm Humphreys <malcolmh...@...>
Ok, I'm convinced. Let's give YAML a shot. Ok, so there is a initial go at this in the other mail. In terms of broad technical strokes, I think either YAML or XML would be sufficient. But given your enthusiasm for YAML, and it's superior human readability, there's no argument against it. (Other than the work / support involved).
A few additional comments as we get going: * I agree that Yaml-cpp seems like our best option of the ones you've mentioned. Let's go with it. Is is feasible to wrap it into the OCIO namespace? see src/core/tinyxml/tinyxml.h as an example It's got a lot of source files, but I really would prefer if possible to keep all OCIO symbols inside a versioned namespace. I have added a local copy of yaml-cpp and a patch to make it build static. Once we get a little further down the road, we can work with the yaml-cpp project to get a customisable namespace for our purpose. * For the OCIO:Config implementation, the list of display devices and color spaces actually do preserve order. While the ordering is not relevant to color processing, it is useful in a UI context. So the yaml is slightly different to the demo's I sent through before displays and colorspace are now YAML sequences so order is preserved. (there is a !!omap tag for doing ordered maps but a sequence matches nicely to the current OCIO structure http://www.yaml.org/spec/1.2/spec.html#id2761292) eg. displays: - !<Display> ... colorspaces: - !<ColorSpace> ... Roles are a map but could be a sequence also depending on preference. roles: default: !<Role> {colorspace: raw} Both roles and displays get emitted in the Flow style (all on one line) but could be emitted in the Block style if thats more legible. Note. -- this -- displays: - !<Display> {device: sRGB, name: Raw, colorspace: raw} -- and this -- displays: - !<Display> device: sRGB name: Raw colorspace: raw -- Will parse the same, but it's nice to choose a style that makes sense for emission. Another thing which might be nice is having the following 'detail:' and 'gpu:' fields to make the profile not so vertically challenged. --snip-- ocs_profile_version: 1 resource_path: strictparsing: false luma: [ 0.2126, 0.7152, 0.0722 ] roles: default: !<Role> {colorspace: raw} displays: - !<Display> {device: sRGB, name: Raw, colorspace: raw} colorspaces: - !<ColorSpace> name: raw detail: { family: raw, bitdepth: 32f, isdata: true } gpu: { gpuallocation: uniform, gpumin: 0, gpumax: 1 } description: | A raw color space. Conversions to and from this space are no-ops. --snip-- * Keeping the serialization code internally as statics - not on the Transforms themselves - is useful so we dont need to expose the serialization to the public API. Or do you have a better implementation in mind? I have some ideas but I thought it would be better to just do a swap out replacement first, then tackle plug-able Transform() serialization later. Thanks for all your work on this issue, No problem. .malcolm
|
|
Joseph Slomka <jsl...@...>
Alan,
It seems that this can be taken care of by having multiple colorspaces. For Arri log or Red log it is simple enough to treat each ISO rating as a separate colorspace. If you didn't want to work that way you can always create a dynamic colorspace object.
-Joseph
________________________________________ From: ocio...@... [ocio...@...] On Behalf Of Alan Jones [sky...@...] Sent: Sunday, October 17, 2010 8:31 AM To: ocio...@... Subject: [ocio-dev] C++ LUTs
Hi All,
Just wanted to throw a quick thought in on C++ LUTs.
I've recently been dealing with Arri's Alexa. One of the more unusual aspects of it's Log-C transform is that it changes based on the camera's ASA.
I thought you might want to allow for LUTs which specify arguments, as this would be required for Log-C, and may be needed or useful further down the line.
Anyway - that was all :) When the API is ready I'd be happy to supply S-Log, Log-C, sRGB, and Rec709 transforms both to and from linear.
Cheers,
Alan.
|
|