1 /* ***** BEGIN LICENSE BLOCK *****
7 * Copyright (c) 2008 BBC Research
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * ***** END LICENSE BLOCK ***** */
34 //#include "array_psi.h"
37 /* encapsulates the structure of a frame, frames consist of three
38 * components, luma, chroma (cr, cb). Dimensions of the frame may
39 * be aquired from each component directly. alternatively some
40 * useful class functions will determine the chroma dimensions
41 * given a chroma format convention.
45 enum Chroma
{CrRGB
, Cr444
, Cr422
, Cr411
, Cr420
, YOnly
};
47 /* determine the width of a chroma component, given a chroma format
48 * type and the luma width */
49 static int widthOfChroma(Chroma c
, int luma_width
)
52 case CrRGB
: /* falls through */
55 case Cr422
: /* falls through */
67 /* determine the height of a chroma component, given a chroma format
68 * type and the luma height */
69 static int heightOfChroma(Chroma c
, int luma_height
)
72 case CrRGB
: /* falls through */
88 /* determine the chroma type for a frame given the luma and chroma
90 static Chroma
chromaFromRatio(const Array2d
<int>& compY
,
91 const Array2d
<int>& compCr
,
92 const Array2d
<int>& compCb
)
94 /* If the two components are not of equal size, it is not a valid
96 assert(compCr
.height() == compCb
.height());
97 assert(compCr
.width() == compCb
.width());
99 /* attempt to find the chroma type */
100 if (compCr
.height() == 0 && compCr
.width() == 0)
103 /* Look for H subsampling */
104 if (compY
.width() == compCr
.width() * 4) {
107 if (compY
.width() == compCr
.width() * 2) {
108 if (compY
.height() == compCr
.height())
110 if (compY
.height() == compCr
.height() * 2)
115 throw /* some exception saying invalid ratio */;
119 /* this should check for sensible image dimensions too? */
120 RawFrame(int width
, int height
, enum Chroma chroma
) :
121 chroma(chroma
), luma(width
, height
),
122 cr(widthOfChroma(chroma
, width
), heightOfChroma(chroma
, height
)),
123 cb(widthOfChroma(chroma
, width
), heightOfChroma(chroma
, height
)),
124 g(luma
), r(cr
), b(cb
)
129 /* this should check for sensible image dimensions too? */
130 // RawFrame(const Size2d &size, enum Chroma chroma)
132 // , luma(size.width, size.height)
133 // , cr(widthOfChroma(chroma, size.width), heightOfChroma(chroma, size.height))
134 // , cb(widthOfChroma(chroma, size.width), heightOfChroma(chroma, size.height))
140 /* convert a single component to a YOnly frame */
141 RawFrame(const Array2d
<int>& component
) :
142 chroma(YOnly
), luma(component
.width(), component
.height()), cr(0, 0) /* initialize chroma to a zero sized array */
143 , cb(0, 0) /* initialize chroma to a zero sized array */
144 , g(luma
), r(cr
), b(cb
)
150 /* convert three seperate components to the apropriate frame type */
151 /* there is some irritating fun here - To determine the chroma type,
152 * one needs to check the correct ratios of components. However,
153 * if there is a fault in the ratios, then an exception must be
154 * thrown. Blame C++. */
155 RawFrame(const Array2d
<int>& compY
, const Array2d
<int>& compCr
,
156 const Array2d
<int>& compCb
) :
157 chroma(chromaFromRatio(compY
, compCr
, compCb
)) //new arrays with size of input arrays
158 , luma(compY
.width(), compY
.height()), cr(compCr
.width(),
160 cb(compCb
.width(), compCb
.height()), g(luma
) //intialise references
163 //copy input data to new arrays
171 /* food for thought: these should probably become references,
172 * if allocations are needed, then allocate, otherwise use the