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 ***** */
30 #include "rawIOv210.h"
32 typedef unsigned int uint_t
;
33 typedef unsigned char uint8_t;
35 //read the first 10 bit sample from the least significant bits of the 4 bytes pointed to by 'data'
36 inline uint_t
readv210sample_pos2of3(uint8_t* data
)
38 const uint_t lsb
= (data
[2] & 0xf0) >> 4;
39 const uint_t msb
= (data
[3] & 0x3f) << 4;
43 //read the second 10 bit sample from the middle bits of the 4 bytes pointed to by 'data'
44 inline uint_t
readv210sample_pos1of3(uint8_t* data
)
46 const uint_t lsb
= (data
[1] & 0xfc) >> 2;
47 const uint_t msb
= (data
[2] & 0x0f) << 6;
51 //read the third 10 bit sample from the more significant bits of the 4 bytes pointed to by 'data'
52 inline uint_t
readv210sample_pos0of3(uint8_t* data
)
54 const uint_t lsb
= (data
[0] & 0xff);
55 const uint_t msb
= (data
[1] & 0x03) << 8;
59 void unpackv210line(uint8_t *data
, const int y
, RawFrame
&dst
)
65 const int num_firstpass_samples_luma
= (dst
.luma
.width()/3)*3; //actual (not padded) number of sets of 3 luma samples in line
67 for (x
= 0; x
< num_firstpass_samples_luma
; ptr
+= 8) {
68 dst
.luma
[y
][x
++] = readv210sample_pos1of3(ptr
+ 0);
69 dst
.luma
[y
][x
++] = readv210sample_pos0of3(ptr
+ 4);
70 dst
.luma
[y
][x
++] = readv210sample_pos2of3(ptr
+ 4);
73 if (x
<dst
.luma
.width()) {
74 dst
.luma
[y
][x
] = readv210sample_pos1of3(ptr
+ 0);
78 if (x
<dst
.luma
.width()) {
79 dst
.luma
[y
][x
] = readv210sample_pos0of3(ptr
+ 4);
83 const int num_firstpass_samples_chroma
= (dst
.luma
.width()/2/3)*3;
85 for (x
= 0; x
< num_firstpass_samples_chroma
; ptr
+= 16) {
86 dst
.cb
[y
][x
] = readv210sample_pos0of3(ptr
+ 0);
87 dst
.cr
[y
][x
] = readv210sample_pos2of3(ptr
+ 0);
90 dst
.cb
[y
][x
] = readv210sample_pos1of3(ptr
+ 4);
91 dst
.cr
[y
][x
] = readv210sample_pos0of3(ptr
+ 8);
94 dst
.cb
[y
][x
] = readv210sample_pos2of3(ptr
+ 8);
95 dst
.cr
[y
][x
] = readv210sample_pos1of3(ptr
+ 12);
99 if (x
<dst
.luma
.width()/2) {
100 dst
.cb
[y
][x
] = readv210sample_pos0of3(ptr
+ 0);
101 dst
.cr
[y
][x
] = readv210sample_pos2of3(ptr
+ 0);
105 if (x
<dst
.luma
.width()/2) {
106 dst
.cb
[y
][x
] = readv210sample_pos1of3(ptr
+ 4);
107 dst
.cr
[y
][x
] = readv210sample_pos0of3(ptr
+ 8);
112 RawFrame
& RawReaderv210::read(RawFrame
&f
)
114 //there must be an even number of luma samples because v210 is 4:2:2
115 assert((f
.luma
.width() & 1) == 0);
116 assert(f
.chroma
== RawFrame::Cr422
);
118 /* pad with to a multiple of 48 luma samples */
119 /* nb, 48 luma samples becomes 128 bytes */
120 const uint_t padded_w
= ((f
.luma
.width() + 47)/48) * 48; //number of luma samples, padded
121 const uint_t padded_line_length
= (2*padded_w
*4) / 3; //number of bytes on each line in the file, includin padding data
123 uint8_t *data
= new uint8_t[padded_line_length
];
126 for (int y
=0; y
<f
.luma
.height(); y
++) {
128 linesRead
= fread(data
, padded_line_length
, 1, infile
);
131 unpackv210line(data
, y
, f
);
135 // throw /* some eof/shortread exception */ ;
140 RawFrame
& RawReaderv210::read()
142 throw /* unknown framesize */;
145 void RawWriterv210::write(const RawFrame
& f
) const
151 void RawWriterv210::write(const RawFrame
& f
, const int depth
) const
153 const int Yoffset
= 0; //Y has no offset
154 const int shift
= 10 - depth
; //no shift for 10 bits, 2 bits shift for 8 bit source
155 const int UVoffset
= 0;
157 int v210LineLength
= (2 * f
.luma
.width() * 4) / 3; //there are three components in 4 bytes
158 char *outLine
= (char *)calloc(v210LineLength
, sizeof(char));
159 assert(f
.chroma
== RawFrame::Cr422
);
161 for (int y
= 0; y
< f
.luma
.height(); y
++) {
163 /* pack to v210 format */
164 /* do the luminance first */
166 for (int x
=0; x
<v210LineLength
; x
+=16) {
167 int pix
=f
.luma
[y
][i
++];
171 outLine
[x
+1] = (pix
<< 2) & 0xFC;
172 outLine
[x
+2] = (pix
>> 6) & 0x0F;
178 outLine
[x
+4] = pix
& 0xFF;
179 outLine
[x
+5] = (pix
>> 8) & 0x03;
185 outLine
[x
+6] = (pix
<< 4) & 0xF0;
186 outLine
[x
+7] = (pix
>> 4) & 0x3F;
192 outLine
[x
+9] = (pix
<< 2) & 0xFC;
193 outLine
[x
+10] = (pix
>> 6) & 0x0F;
199 outLine
[x
+12] = pix
& 0xFF;
200 outLine
[x
+13] = (pix
>> 8) & 0x03;
206 outLine
[x
+14] = (pix
<< 4) & 0xF0;
207 outLine
[x
+15] = (pix
>> 4) & 0x3F;
212 for (int x
=0; x
<v210LineLength
; x
+=16) {
218 outLine
[x
] = pix
& 0xFF;
219 outLine
[x
+1] |= (pix
>> 8) & 0x03;
226 outLine
[x
+2] |= (pix
<< 4) & 0xF0;
227 outLine
[x
+3] = (pix
>> 4) & 0x3F;
234 outLine
[x
+5] |= (pix
<< 2) & 0xFC;
235 outLine
[x
+6] |= (pix
>> 6) & 0x0F;
242 outLine
[x
+8] = pix
& 0xFF;
243 outLine
[x
+9] |= (pix
>> 8) & 0x03;
250 outLine
[x
+10] |= (pix
<< 4) & 0xF0;
251 outLine
[x
+11] = (pix
>> 4) & 0x3F;
258 outLine
[x
+13] |= (pix
<< 2) & 0xFC;
259 outLine
[x
+14] |= (pix
>> 6) & 0x0F;
263 fwrite(outLine
, v210LineLength
, 1, outfile
);