Add facility to read frames in RGB & RGBA format
[imageviewer.git] / rawFrame.h
blobdd7450fa93f94aa0d0763670b562707c9362aec0
1 /* ***** BEGIN LICENSE BLOCK *****
3 * $Id$
5 * The MIT License
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
25 * THE SOFTWARE.
27 * ***** END LICENSE BLOCK ***** */
29 #ifndef __RAWFRAME_H
30 #define __RAWFRAME_H
32 #include <assert.h>
34 //#include "array_psi.h"
35 #include "array_df.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.
43 struct RawFrame {
44 public:
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)
51 switch (c) {
52 case CrRGB: /* falls through */
53 case Cr444:
54 return luma_width;
55 case Cr422: /* falls through */
56 case Cr420:
57 return luma_width/2;
58 case Cr411:
59 return luma_width/4;
60 case YOnly:
61 return 0;
63 throw;
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)
71 switch (c) {
72 case CrRGB: /* falls through */
73 case Cr444:
74 return luma_height;
75 case Cr422:
76 return luma_height;
77 case Cr411:
78 return luma_height;
79 case Cr420:
80 return luma_height/2;
81 case YOnly:
82 return 0;
84 throw;
88 /* determine the chroma type for a frame given the luma and chroma
89 * components */
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
95 * frame */
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)
101 return YOnly;
103 /* Look for H subsampling */
104 if (compY.width() == compCr.width() * 4) {
105 return Cr411;
107 if (compY.width() == compCr.width() * 2) {
108 if (compY.height() == compCr.height())
109 return Cr422;
110 if (compY.height() == compCr.height() * 2)
111 return Cr420;
114 return Cr444;
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)
131 // : 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))
135 // , g(luma)
136 // , r(cr)
137 // , b(cb)
138 // {};
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)
146 luma = component;
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(),
159 compCr.height()),
160 cb(compCb.width(), compCb.height()), g(luma) //intialise references
161 , r(cr), b(cb)
163 //copy input data to new arrays
164 luma = compY;
165 cr = compCr;
166 cb = compCb;
170 const Chroma chroma;
171 /* food for thought: these should probably become references,
172 * if allocations are needed, then allocate, otherwise use the
173 * reference. */
174 Array2d<int> luma;
175 Array2d<int> cr;
176 Array2d<int> cb;
178 Array2d<int>& g;
179 Array2d<int>& r;
180 Array2d<int>& b;
183 #endif