• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /*******************************************************************************************
19  Class :: CCYUV420SEMItoYUV420.cpp
20 ------------------------------------
21 The YUV420SEMI is semi interleaved and output format is YUV420 planar
22 
23 ********************************************************************************************/
24 #include "colorconv_config.h"
25 #include "ccyuv420semitoyuv420.h"
26 
27 
New()28 OSCL_EXPORT_REF ColorConvertBase* CCYUV420SEMItoYUV420 :: New()
29 {
30     CCYUV420SEMItoYUV420* self = OSCL_NEW(CCYUV420SEMItoYUV420, ());
31     return OSCL_STATIC_CAST(ColorConvertBase*, self);
32 }
33 
34 
CCYUV420SEMItoYUV420()35 CCYUV420SEMItoYUV420 :: CCYUV420SEMItoYUV420()
36 {
37 }
38 
39 
~CCYUV420SEMItoYUV420()40 OSCL_EXPORT_REF CCYUV420SEMItoYUV420 :: ~CCYUV420SEMItoYUV420()
41 {
42 }
43 
44 
Init(int32 SrcWidth,int32 SrcHeight,int32 SrcPitch,int32 DstWidth,int32 DstHeight,int32 DstPitch,int32 nRotation)45 int32 CCYUV420SEMItoYUV420:: Init(int32 SrcWidth, int32 SrcHeight, int32 SrcPitch, int32 DstWidth, int32 DstHeight, int32 DstPitch, int32 nRotation)
46 {
47     /* no scaled outputs */
48     if (!(nRotation&0x1))
49     {
50         if ((SrcWidth != DstWidth) || (SrcHeight != DstHeight))
51         {
52             return 0;
53         }
54     }
55     else // with rotation
56     {
57         if ((SrcWidth != DstHeight) || (SrcHeight != DstWidth))
58         {
59             return 0;
60         }
61     }
62 
63     if (SrcPitch != SrcWidth) // not support source cropping
64     {
65         return 0;
66     }
67     else
68     {
69         _mSrc_width = SrcWidth;
70         _mSrc_height = SrcHeight;
71         _mSrc_pitch = SrcPitch;
72         _mDst_width = DstWidth;
73         _mDst_height = DstHeight;
74         _mDst_pitch = DstPitch;
75         _mDst_mheight = DstHeight;
76         _mRotation = nRotation;
77 
78         _mInitialized = true;
79 
80         return 1;
81     }
82 
83 }
84 
85 
GetOutputBufferSize(void)86 int32 CCYUV420SEMItoYUV420:: GetOutputBufferSize(void)
87 {
88     OSCL_ASSERT(_mInitialized == true);
89 
90     return((_mDst_pitch * _mDst_mheight*3) >> 1);
91 }
92 
93 
SetMode(int32 nMode)94 int32 CCYUV420SEMItoYUV420::SetMode(int32 nMode)
95 {
96     OSCL_UNUSED_ARG(nMode);
97     OSCL_ASSERT(_mInitialized == true);
98 
99     return 1;
100 }
101 
SetYuvFullRange(bool range)102 int32 CCYUV420SEMItoYUV420::SetYuvFullRange(bool range)
103 {
104     OSCL_UNUSED_ARG(range);
105     OSCL_ASSERT(_mInitialized == true);
106 
107     return 1;  // has no meaning in this class. Always return 1
108 }
109 
Convert(uint8 * inyuvBuf,uint8 * outyuvBuf)110 int32 CCYUV420SEMItoYUV420::Convert(uint8 *inyuvBuf, uint8 *outyuvBuf)
111 {
112     uint8 *yuvBuf[3] = {NULL, NULL, NULL };
113     int outYsize = (_mDst_pitch * _mDst_mheight);
114     OSCL_ASSERT(inyuvBuf);
115     OSCL_ASSERT(outyuvBuf);
116 
117     yuvBuf[0] = outyuvBuf;
118     yuvBuf[1] = (outyuvBuf + outYsize);
119     yuvBuf[2] = (outyuvBuf + outYsize + (outYsize >> 2));
120 
121     return (Convert(inyuvBuf, yuvBuf));
122 }
123 
124 
Convert(uint8 * inyuv,uint8 ** outyuv)125 int32 CCYUV420SEMItoYUV420::Convert(uint8 *inyuv, uint8 **outyuv)
126 {
127 
128     int32 i, j;
129     uint16 *outcb, *outcr;
130     uint32 *outy;
131     uint32 *inyuv_4;
132     uint32 temp, tempU, tempV;
133     int outYsize, offset;
134 
135     int lpitch = _mDst_pitch;
136     int lheight = _mSrc_height;
137 
138     OSCL_ASSERT(inyuv);
139     OSCL_ASSERT(outyuv);
140     OSCL_ASSERT(_mInitialized == true);
141 
142     outYsize = (lpitch * _mDst_mheight);
143 
144     inyuv_4 = (uint32 *)inyuv;
145 
146     switch (_mRotation)
147     {
148         case 0://Rotation0
149 
150             outy = (uint32*) outyuv[0];
151             outcb = (uint16*) outyuv[1];
152             outcr = (uint16*) outyuv[2];
153 
154             offset = lpitch - _mSrc_width;
155 
156             /* Y copying */
157             for (i = lheight; i > 0; i--)
158             {
159                 for (j = _mSrc_width >> 2; j > 0; j--)
160                 {
161                     temp = *inyuv_4++;
162                     *outy++ = temp;
163                 }
164                 /* in case the dest pitch is larger than width */
165                 outy += (offset >> 2);
166             }
167 
168             /* U & V copying */
169             for (i = lheight >> 1; i > 0; i--)
170             {
171                 for (j = _mSrc_width >> 2; j > 0; j--)
172                 {
173                     temp = *inyuv_4++; /* V1U1V0U0 */
174                     tempU = temp & 0xFF; // U0
175                     tempU = tempU | ((temp >> 8) & 0xFF00); //U1U0
176 
177                     tempV = (temp >> 8) & 0xFF; // V0
178                     tempV = tempV | ((temp >> 16) & 0xFF00); //V1V0
179 
180                     *outcb++ = tempU;
181                     *outcr++ = tempV;
182                 }
183                 /* in case the dest pitch is larger than width */
184                 outcb += (offset >> 2);
185                 outcr += (offset >> 2);
186             }
187 
188             break;
189 
190         case 1: // Rotation90 CW
191             /* To traverse in raster scan for output and vertical scan on the input.
192             ** You can write output 4 bytes at a time.
193             ** However, it takes more number of variables and more code size.
194             */
195             uint32 temp1;
196             outy = (uint32*) outyuv[0];
197             outcb = (uint16*) outyuv[1];
198             outcr = (uint16*) outyuv[2];
199 
200             outy  = outy + (lpitch >> 2) - 1;
201             outcb = outcb + (lpitch >> 2) - 1;
202             outcr = outcr + (lpitch >> 2) - 1;
203 
204             /* Y copying */
205             for (i = _mSrc_width; i > 0; i--)
206             {
207                 for (j = lheight >> 2; j > 0; j--)
208                 {
209                     temp = (*inyuv);
210                     inyuv += _mSrc_width;
211                     temp = (temp << 8) | (*inyuv);
212                     inyuv += _mSrc_width;
213                     temp = (temp << 8) | (*inyuv);
214                     inyuv += _mSrc_width;
215                     temp = (temp << 8) | (*inyuv);
216                     inyuv += _mSrc_width;
217                     *outy = temp;
218                     outy--;
219                 }
220                 inyuv = inyuv - (lheight * _mSrc_width) + 1;
221                 outy = outy + (lheight >> 2) + (lpitch >> 2);
222                 /* in case the dest pitch is larger than width */
223             }
224 
225             inyuv = inyuv + (lheight * _mSrc_width) - _mSrc_width;
226 
227             /* U & V copying */
228             for (i = _mSrc_width >> 1; i > 0; i--)
229             {
230                 for (j = lheight >> 2; j > 0; j--)
231                 {
232                     temp = *inyuv++; //U0
233                     temp1 = *inyuv--; //V0
234                     inyuv += _mSrc_width;
235                     temp = (temp << 8) | (*inyuv); //U1U0
236                     inyuv++;
237                     temp1 = (temp1 << 8) | (*inyuv); //V1V0
238                     inyuv--;
239                     inyuv += _mSrc_width;
240 
241                     *outcb = temp;
242                     *outcr = temp1;
243                     outcb--;
244                     outcr--;
245                 }
246                 /* in case the dest pitch is larger than width */
247                 inyuv = inyuv - ((lheight >> 1) * _mSrc_width) + 2;
248                 outcb = outcb + (lheight >> 2) + (lpitch >> 2);
249                 outcr = outcr + (lheight >> 2) + (lpitch >> 2);
250             }
251             break;
252 
253         case 2://Rotation180
254 
255             outy  = (uint32*)((uint8*)outyuv[0] + outYsize - 4);
256             outcb = (uint16*)((uint8*)outyuv[1] + (outYsize >> 2) - 4);
257             outcr = (uint16*)((uint8*)outyuv[2] + (outYsize >> 2) - 4);
258 
259             offset = lpitch - _mSrc_width;
260 
261             /* Y copying */
262             for (i = lheight; i > 0; i--)
263             {
264                 for (j = _mSrc_width >> 2; j > 0; j--)
265                 {
266                     temp = *inyuv_4++;
267                     *outy-- = SWAP_4(temp);
268                 }
269                 /* in case the dest pitch is larger than width */
270                 outy -= (offset >> 2);
271             }
272 
273             /* U & V copying */
274             for (i = lheight >> 1; i > 0; i--)
275             {
276                 for (j = _mSrc_width >> 2; j > 0; j--)
277                 {
278                     temp = *inyuv_4++; /* V1U1V0U0 */
279                     tempU = temp & 0xFF; // U0
280                     tempU = (tempU << 8) | ((temp >> 16) & 0xFF); //U0U1
281 
282                     tempV = (temp >> 8) & 0xFF; // V0
283                     tempV = (tempV << 8) | (temp >> 24); //V0V1
284 
285                     *outcb-- = tempU;
286                     *outcr-- = tempV;
287                 }
288                 /* in case the dest pitch is larger than width */
289                 outcb -= (offset >> 2);
290                 outcr -= (offset >> 2);
291             }
292 
293             break;
294 
295         case 3: // Rotation270  CW
296             /* To traverse in raster scan for output and vertical scan on the input.
297             ** You can write output 4 bytes at a time.
298             ** However, it takes more number of variables and more code size.
299             */
300             outy = (uint32*) outyuv[0];
301             outcb = (uint16*) outyuv[1];
302             outcr = (uint16*) outyuv[2];
303 
304             outy  = outy + ((lpitch >> 2) * (_mSrc_width - 1));
305             outcb = outcb + ((lpitch >> 2) * ((_mSrc_width >> 1) - 1));
306             outcr = outcr + ((lpitch >> 2) * ((_mSrc_width >> 1) - 1));
307 
308             /* Y copying */
309             for (i = _mSrc_width; i > 0; i--)
310             {
311                 for (j = lheight >> 2; j > 0; j--)
312                 {
313                     temp = (*inyuv);
314                     inyuv += _mSrc_width;
315                     temp |= ((*inyuv) << 8);
316                     inyuv += _mSrc_width;
317                     temp |= ((*inyuv) << 16);
318                     inyuv += _mSrc_width;
319                     temp |= ((*inyuv) << 24);
320                     inyuv += _mSrc_width;
321                     *outy = temp;
322                     outy++;
323                 }
324                 inyuv = inyuv - (lheight * _mSrc_width) + 1;
325                 outy = outy - ((lheight >> 2) + (lpitch >> 2));
326                 /* in case the dest pitch is larger than width */
327             }
328 
329             inyuv = inyuv + (lheight * _mSrc_width) - _mSrc_width;
330 
331             /* U & V copying */
332             for (i = _mSrc_width >> 1; i > 0; i--)
333             {
334                 for (j = lheight >> 2; j > 0; j--)
335                 {
336                     temp = *inyuv++; //U0
337                     temp1 = *inyuv--; //V0
338                     inyuv += _mSrc_width;
339                     temp |= ((*inyuv) << 8); //U0U1
340                     inyuv++;
341                     temp1 |= ((*inyuv) << 8); //V0V1
342                     inyuv--;
343                     inyuv += _mSrc_width;
344 
345                     *outcb = temp;
346                     *outcr = temp1;
347                     outcb++;
348                     outcr++;
349                 }
350                 /* in case the dest pitch is larger than width */
351                 inyuv = inyuv - ((lheight >> 1) * _mSrc_width) + 2;
352                 outcb = outcb - ((lheight >> 2) + (lpitch >> 2));
353                 outcr = outcr - ((lheight >> 2) + (lpitch >> 2));
354             }
355             break;
356 
357         default:
358             break;
359 
360     }//switch
361 
362     return 1;
363 }
364 
365 
366 
367 
368 
369