
Adam Badura wrote:
like RGBA 8:8:8:8 or YUV 4:2:2, etc...
What "etc.."? I need to know such things... :) Or do you have any sugestions for a "general foramt specification"?
you need to separate out the concepts: numerical representation; integer, floating point, fixed point, signed/unsigned variations range of representation; 1/8/10/12/15/16 bit integer, 16/32/64 bit floats encoding/transfer characteristics; gamma corrected, log encoded, linear, relative/absolute values storage format; packed/unpacked, interleaved/planar, strided/unstrided dimensionality; 1D, 2D, 3D, 6D (and other printer ink counts), 31 and other spectral data What is the meaning of the composition/separation of the separate data channels As indicated above, the sampling of the multiple channels can be variable between channels, reconstructing regular spacing needs filters these need to work across similar dimensions as the data, probably have a functor syle interface. this then needs the spacial arangement to be navigatable in a multi-dimensional manner (N-D segmented iterators?) Type conversion is an interesting property, what does it mean to do add RGB(0.5, 0.5, 0.5) to YUV(0.5,0,0) Are they different to each other? Is YUV == Y'CbCr, does RGB (sRGB) == RGB (Adobe RGB). Pesonally I'd like strict typing so that if I assign Adobe RGB to sRGB I get an error, also the equality test should also fail, to me they are totally different, in particular Adobe RGB colour space is a 'larger type'. You may find it difficult to separate the colour aspects from what it is to be an image, especially in the video style representations. Colour manipulations should not be constrained to 0.0-1.0 no matter what the underlying representation. (see for instance www.openexr.org, ITU-R BT.709, etc) How do you handle conversion from one bit depth to another - you may need a policy/trait to cover rounding, bit depth extension e.g. valueIn12Bit = (valueIn8Bit * (pow(2, 12) -1)) / (pow(2, 8) -1) valueIn12Bit = (valueIn8Bit / (pow(2, 8) -1)) * (pow(2, 12) -1) valueIn12Bit = (valueIn8Bit << (12 - 8)) | (valueIn8Bit >> (12 - 8)) valueIn12Bit = (valueIn8Bit << (12 - 8)) But what about the intermediate values... should it really be valueIn12Bit = static_cast<typeFor12Bit>(double(valueIn8Bit * (pow(2, 12) -1)) / (pow(2, 8) -1)) or valueIn12Bit = static_cast<typeFor12Bit>((double(valueIn8Bit * (pow(2, 12) -1)) / (pow(2, 8) -1)) + 0.5) Quite common assumptions are to convert everything to float and work like that until going to an external interface. All of this is not trivial and this is before you consider ICC or similar. I suggest trying to constrain yourself to one or two uses first and see what can be generalised/simplified, otherwise it may take some time... Kevin -- | Kevin Wheatley, Cinesite (Europe) Ltd | Nobody thinks this | | Senior Technology | My employer for certain | | And Network Systems Architect | Not even myself |