source: svn/trunk/newcon3bcm2_21bu/magnum/commonutils/pxl/bpxl.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 14.0 KB
RevLine 
[2]1/***************************************************************************
2 *     Copyright (c) 2003-2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bpxl.c $
11 * $brcm_Revision: Hydra_Software_Devel/19 $
12 * $brcm_Date: 1/17/11 7:25p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/commonutils/pxl/bpxl.c $
19 *
20 * Hydra_Software_Devel/19   1/17/11 7:25p nissen
21 * SW7405-3671: Added luma formats.
22 *
23 * Hydra_Software_Devel/18   8/17/10 2:21p nissen
24 * SW35230-1029: Fixed error when calling BPXL_GetBytesPerNPixels with a
25 * invalid PXL format.
26 *
27 * Hydra_Software_Devel/17   12/17/09 2:15p nissen
28 * SW7405-3590: Fixed converting YCbCr 422 formats to/from other YCbCr
29 * formats.
30 *
31 * Hydra_Software_Devel/16   12/14/09 11:10a nissen
32 * SW7405-3590: Fixed converting RGB to 10-bit YCbCr.
33 *
34 * Hydra_Software_Devel/15   4/4/08 10:07a nissen
35 * PR 40122: Added more support for 10-bit 422 40-bit packed formats.
36 *
37 * Hydra_Software_Devel/14   3/28/08 10:18a nissen
38 * PR 40122: Added 10-bit 422 40-bit packed formats.
39 *
40 * Hydra_Software_Devel/13   9/17/07 4:39p syang
41 * PR 34592: eY8_Cb8_Cr8_A8 and eA8_Cr8_Cb8_Y8 was accidently removed by
42 * merging from 7401
43 *
44 * Hydra_Software_Devel/12   9/14/07 10:57a syang
45 * PR 33575: merge from 7401
46 *
47 * Hydra_Software_Devel/Refsw_Dedicated_vdc_7401/1   9/7/07 5:12p jessem
48 * PR 34592: Added BPXL_P_Format_Info  table and BPXL_ConvertFmtToStr to
49 * help convert pixel format to a string literal.
50 *
51 * Hydra_Software_Devel/8   8/25/06 10:39a nissen
52 * PR 20763: Added support for 10-bit versions of YCbCr 444 and 422.
53 *
54 * Hydra_Software_Devel/7   2/24/05 1:46p nissen
55 * PR 14207: Added bstd.h include.
56 *
57 * Hydra_Software_Devel/6   10/9/03 1:32p nissen
58 * Removed use of float constants.
59 *
60 * Hydra_Software_Devel/5   9/19/03 3:42p nissen
61 * Changed use of float type to int when doing color space conversion (PR
62 * 8043).
63 *
64 * Hydra_Software_Devel/4   8/26/03 4:18p nissen
65 * Renamed YCrCb to YCbCr.
66 *
67 * Hydra_Software_Devel/3   8/6/03 2:21p nissen
68 * Fixed bug in YCrCb to RGB color conversion. Fixed bug when getting
69 * bytes per n pixels for sub-byte formats.
70 *
71 * Hydra_Software_Devel/2   6/9/03 3:05p nissen
72 * Added pixel and component conversion functions.
73 *
74 * Hydra_Software_Devel/1   5/28/03 3:39p nissen
75 * Pixel Format module.
76 *
77 ***************************************************************************/
78
79#include "bstd.h"
80#include "bstd_defs.h"
81#include "berr.h"
82#include "bdbg.h"
83#include "bpxl.h"
84
85
86typedef struct
87{
88        BPXL_Format ePxlFmt;
89        const char *pcFmtName;
90} BPXL_P_Format_Info;
91
92
93/****************************************************************************/
94/* Making an entry for pixel format                                         */
95/****************************************************************************/
96#define BPXL_P_MAKE_PXL(PxlFmt)                                             \
97{                                                                           \
98        (PxlFmt),                                                               \
99        (#PxlFmt)                                                               \
100}
101
102static const BPXL_P_Format_Info s_aPxlFmtInfo[] =
103{
104        /* YCbCr 444 */
105        BPXL_P_MAKE_PXL(BPXL_eA8_Y8_Cb8_Cr8),
106        BPXL_P_MAKE_PXL(BPXL_eCr8_Cb8_Y8_A8),
107        BPXL_P_MAKE_PXL(BPXL_eY8_Cb8_Cr8_A8),
108        BPXL_P_MAKE_PXL(BPXL_eA8_Cr8_Cb8_Y8),
109
110        /* YCbCr 422 */
111        BPXL_P_MAKE_PXL(BPXL_eCr8_Y18_Cb8_Y08),
112        BPXL_P_MAKE_PXL(BPXL_eY18_Cr8_Y08_Cb8),
113        BPXL_P_MAKE_PXL(BPXL_eY08_Cb8_Y18_Cr8),
114        BPXL_P_MAKE_PXL(BPXL_eCb8_Y08_Cr8_Y18),
115        BPXL_P_MAKE_PXL(BPXL_eCb8_Y18_Cr8_Y08),
116        BPXL_P_MAKE_PXL(BPXL_eY18_Cb8_Y08_Cr8),
117        BPXL_P_MAKE_PXL(BPXL_eY08_Cr8_Y18_Cb8),
118        BPXL_P_MAKE_PXL(BPXL_eCr8_Y08_Cb8_Y18),
119
120        /* YCbCr 420 */
121        BPXL_P_MAKE_PXL(BPXL_eY8),
122        BPXL_P_MAKE_PXL(BPXL_eCb8_Cr8),
123        BPXL_P_MAKE_PXL(BPXL_eCr8_Cb8),
124
125        /* YCbCr 444 10-bit */
126        BPXL_P_MAKE_PXL(BPXL_eX2_Cr10_Y10_Cb10),
127
128        /* YCbCr 422 10-bit */
129        BPXL_P_MAKE_PXL(BPXL_eX2_Y010_Cb10_Y110_X2_Cr10_Y010_Cb10_X2_Y110_Cr10_Y010_X2_Cb10_Y110_Cr10),
130
131        /* YCbCr 422 10-bit (packed 40-bit pixel)*/
132        BPXL_P_MAKE_PXL(BPXL_eCr10_Y110_Cb10_Y010),
133        BPXL_P_MAKE_PXL(BPXL_eY110_Cr10_Y010_Cb10),
134        BPXL_P_MAKE_PXL(BPXL_eY010_Cb10_Y110_Cr10),
135        BPXL_P_MAKE_PXL(BPXL_eCb10_Y010_Cr10_Y110),
136        BPXL_P_MAKE_PXL(BPXL_eCb10_Y110_Cr10_Y010),
137        BPXL_P_MAKE_PXL(BPXL_eY110_Cb10_Y010_Cr10),
138        BPXL_P_MAKE_PXL(BPXL_eY010_Cr10_Y110_Cb10),
139        BPXL_P_MAKE_PXL(BPXL_eCr10_Y010_Cb10_Y110),
140
141        /* RGB */
142        BPXL_P_MAKE_PXL(BPXL_eA8_R8_G8_B8),
143        BPXL_P_MAKE_PXL(BPXL_eA8_B8_G8_R8),
144        BPXL_P_MAKE_PXL(BPXL_eR8_G8_B8_A8),
145        BPXL_P_MAKE_PXL(BPXL_eB8_G8_R8_A8),
146
147        BPXL_P_MAKE_PXL(BPXL_eX8_R8_G8_B8),
148        BPXL_P_MAKE_PXL(BPXL_eX8_B8_G8_R8),
149        BPXL_P_MAKE_PXL(BPXL_eR8_G8_B8_X8),
150        BPXL_P_MAKE_PXL(BPXL_eB8_G8_R8_X8),
151
152        BPXL_P_MAKE_PXL(BPXL_eR8_G8_B8),
153        BPXL_P_MAKE_PXL(BPXL_eB8_G8_R8),
154
155        BPXL_P_MAKE_PXL(BPXL_eR5_G6_B5),
156        BPXL_P_MAKE_PXL(BPXL_eB5_G6_R5),
157
158        BPXL_P_MAKE_PXL(BPXL_eA1_R5_G5_B5),
159        BPXL_P_MAKE_PXL(BPXL_eA1_B5_G5_R5),
160        BPXL_P_MAKE_PXL(BPXL_eR5_G5_B5_A1),
161        BPXL_P_MAKE_PXL(BPXL_eB5_G5_R5_A1),
162
163        BPXL_P_MAKE_PXL(BPXL_eX1_R5_G5_B5),
164        BPXL_P_MAKE_PXL(BPXL_eX1_B5_G5_R5),
165        BPXL_P_MAKE_PXL(BPXL_eR5_G5_B5_X1),
166        BPXL_P_MAKE_PXL(BPXL_eB5_G5_R5_X1),
167
168        BPXL_P_MAKE_PXL(BPXL_eW1_R5_G5_B5),
169        BPXL_P_MAKE_PXL(BPXL_eW1_B5_G5_R5),
170        BPXL_P_MAKE_PXL(BPXL_eR5_G5_B5_W1),
171        BPXL_P_MAKE_PXL(BPXL_eB5_G5_R5_W1),
172
173        BPXL_P_MAKE_PXL(BPXL_eA4_R4_G4_B4),
174        BPXL_P_MAKE_PXL(BPXL_eA4_B4_G4_R4),
175        BPXL_P_MAKE_PXL(BPXL_eR4_G4_B4_A4),
176        BPXL_P_MAKE_PXL(BPXL_eB4_G4_R4_A4),
177
178        BPXL_P_MAKE_PXL(BPXL_eX4_R4_G4_B4),
179        BPXL_P_MAKE_PXL(BPXL_eX4_B4_G4_R4),
180        BPXL_P_MAKE_PXL(BPXL_eR4_G4_B4_X4),
181        BPXL_P_MAKE_PXL(BPXL_eB4_G4_R4_X4),
182
183        /* Palette */
184        BPXL_P_MAKE_PXL(BPXL_eP1),
185        BPXL_P_MAKE_PXL(BPXL_eP2),
186        BPXL_P_MAKE_PXL(BPXL_eP4),
187        BPXL_P_MAKE_PXL(BPXL_eP8),
188        BPXL_P_MAKE_PXL(BPXL_eA8_P8),
189        BPXL_P_MAKE_PXL(BPXL_eY8_P8),
190
191        /* Alpha */
192        BPXL_P_MAKE_PXL(BPXL_eA1),
193        BPXL_P_MAKE_PXL(BPXL_eA2),
194        BPXL_P_MAKE_PXL(BPXL_eA4),
195        BPXL_P_MAKE_PXL(BPXL_eA8),
196        BPXL_P_MAKE_PXL(BPXL_eW1),
197
198        /* 3D (Special) */
199        BPXL_P_MAKE_PXL(BPXL_eL8),
200        BPXL_P_MAKE_PXL(BPXL_eL8_A8),
201        BPXL_P_MAKE_PXL(BPXL_eZ16),
202
203        BPXL_P_MAKE_PXL(BPXL_eL4_A4),
204        BPXL_P_MAKE_PXL(BPXL_eL15_L05_A6),
205
206        BPXL_P_MAKE_PXL(BPXL_INVALID)
207};
208
209/***************************************************************************/
210BERR_Code BPXL_ConvertComponent(
211        BPXL_Format eDstFormat,
212        BPXL_Format eSrcFormat,
213        unsigned int uiSrcPixel,
214        unsigned int uiCompNum,
215        unsigned int *puiDstComp )
216{
217        unsigned int uiDstComp = 0;
218        unsigned int uiSrcSize;
219        unsigned int uiDstSize;
220
221        /* Check parameter */
222        if( puiDstComp == NULL )
223        {
224                return BERR_TRACE(BERR_INVALID_PARAMETER);
225        }
226
227        /* Convert pixel components */
228        uiSrcSize = BPXL_COMPONENT_SIZE(eSrcFormat, uiCompNum);
229        uiDstSize = BPXL_COMPONENT_SIZE(eDstFormat, uiCompNum);
230
231        /* Check if both src and dst have specified component */
232        if( uiSrcSize && uiDstSize )
233        {
234                unsigned int uiSrcPos = BPXL_COMPONENT_POS(eSrcFormat, uiCompNum);
235                unsigned int uiSrcMask = BPXL_COMPONENT_MASK(eSrcFormat, uiCompNum);
236                unsigned int uiDstMask = BPXL_COMPONENT_MASK(eDstFormat, uiCompNum);
237
238                if( uiSrcSize >= uiDstSize )
239                {
240                        /* Convert component down in size */
241                        uiDstComp = (uiSrcPixel >> (uiSrcPos + uiSrcSize - uiDstSize)) & uiDstMask;
242                }
243                else
244                {
245                        /* Convert component up using high to low order replication */
246                        signed int siBitCount = uiDstSize;
247
248                        while( siBitCount > 0 )
249                        {
250                                siBitCount -= (signed int) uiSrcSize;
251                                uiDstComp |= (siBitCount > 0) ?
252                                        ((uiSrcPixel >> uiSrcPos) & uiSrcMask) << siBitCount :
253                                        ((uiSrcPixel >> uiSrcPos) & uiSrcMask) >> siBitCount;
254                        }
255                }
256        }
257
258        *puiDstComp = uiDstComp;
259
260        return BERR_SUCCESS;
261}
262
263/***************************************************************************/
264BERR_Code BPXL_ConvertPixel(
265        BPXL_Format eDstFormat,
266        BPXL_Format eSrcFormat,
267        unsigned int uiSrcPixel,
268        unsigned int *puiDstPixel )
269{
270        unsigned int uiDstPixel = 0;
271        unsigned int uiDstComp;
272        unsigned int ii;
273
274        /* Check parameter */
275        if( puiDstPixel == NULL )
276        {
277                return BERR_TRACE(BERR_INVALID_PARAMETER);
278        }
279
280        /* Convert pixel components */
281        if( BPXL_IS_YCbCr422_FORMAT(eSrcFormat) && (!BPXL_IS_YCbCr422_FORMAT(eDstFormat)) )
282        {
283                for( ii = 0; ii < 3; ++ ii )
284                {
285                        BPXL_ConvertComponent( eDstFormat, eSrcFormat, uiSrcPixel, ii, &uiDstComp );
286                        uiDstPixel |= uiDstComp << BPXL_COMPONENT_POS(eDstFormat, ii);
287                }
288        }
289        else if( (!BPXL_IS_YCbCr422_FORMAT(eSrcFormat)) && BPXL_IS_YCbCr422_FORMAT(eDstFormat) )
290        {
291                BPXL_ConvertComponent( eDstFormat, eSrcFormat, uiSrcPixel, 0, &uiDstComp );
292                uiDstPixel |= uiDstComp << BPXL_COMPONENT_POS(eDstFormat, 0);
293                BPXL_ConvertComponent( eDstFormat, eSrcFormat, uiSrcPixel, 1, &uiDstComp );
294                uiDstPixel |= uiDstComp << BPXL_COMPONENT_POS(eDstFormat, 1);
295                BPXL_ConvertComponent( eDstFormat, eSrcFormat, uiSrcPixel, 2, &uiDstComp );
296                uiDstPixel |= uiDstComp << BPXL_COMPONENT_POS(eDstFormat, 2);
297                uiDstPixel |= uiDstComp << BPXL_COMPONENT_POS(eDstFormat, 3);
298        }
299        else
300        {
301                for( ii = 0; ii < 4; ++ ii )
302                {
303                        BPXL_ConvertComponent( eDstFormat, eSrcFormat, uiSrcPixel, ii, &uiDstComp );
304                        uiDstPixel |= uiDstComp << BPXL_COMPONENT_POS(eDstFormat, ii);
305                }
306        }
307
308        *puiDstPixel = uiDstPixel;
309
310        return BERR_SUCCESS;
311}
312
313/***************************************************************************/
314BERR_Code BPXL_ConvertPixel_RGBtoYCbCr(
315        BPXL_Format eDstFormat,
316        BPXL_Format eSrcFormat,
317        unsigned int uiSrcPixel,
318        unsigned int *puiDstPixel )
319{
320        unsigned int ulA, ulR, ulG, ulB;
321        unsigned int ulY, ulCr, ulCb;
322
323        /* Check parameter */
324        if( puiDstPixel == NULL )
325        {
326                return BERR_TRACE(BERR_INVALID_PARAMETER);
327        }
328
329        /* Get ARGB components */
330        BPXL_ConvertComponent( BPXL_eA8_R8_G8_B8, eSrcFormat, uiSrcPixel, 0, &ulB );
331        BPXL_ConvertComponent( BPXL_eA8_R8_G8_B8, eSrcFormat, uiSrcPixel, 1, &ulG );
332        BPXL_ConvertComponent( BPXL_eA8_R8_G8_B8, eSrcFormat, uiSrcPixel, 2, &ulR );
333        BPXL_ConvertComponent( BPXL_eA8_R8_G8_B8, eSrcFormat, uiSrcPixel, 3, &ulA );
334
335        /* Convert RGB components to YCbCr */
336        /* Y  = R *  0.257 + G *  0.504 + B *  0.098 + 16  */
337        /* Cb = R * -0.148 + G * -0.291 + B *  0.439 + 128 */
338        /* Cr = R *  0.439 + G * -0.368 + B * -0.071 + 128 */
339        ulY  = ulR *  0x41CA + ulG *  0x8106 + ulB *  0x1916 + 0x100000;
340        ulCb = ulR * -0x25E3 + ulG * -0x4A7F + ulB *  0x7062 + 0x800000;
341        ulCr = ulR *  0x7062 + ulG * -0x5E35 + ulB * -0x122D + 0x800000;
342
343        /* Make destination pixel */
344        if( eDstFormat == BPXL_eX2_Cr10_Y10_Cb10 )
345        {
346                ulY  = ulY >> 14;
347                ulCb = ulCb >> 14;
348                ulCr = ulCr >> 14;
349                *puiDstPixel = BPXL_MAKE_PIXEL_10BIT(eDstFormat, ulY, ulCb, ulCr);
350        }
351        else
352        {
353                ulY  = ulY >> 16;
354                ulCb = ulCb >> 16;
355                ulCr = ulCr >> 16;
356                *puiDstPixel = BPXL_MAKE_PIXEL(eDstFormat, BPXL_HAS_ALPHA(eDstFormat) ? ulA : ulY, ulY, ulCb, ulCr);
357        }
358
359        return BERR_SUCCESS;
360}
361
362/***************************************************************************/
363BERR_Code BPXL_ConvertPixel_YCbCrtoRGB(
364        BPXL_Format eDstFormat,
365        BPXL_Format eSrcFormat,
366        unsigned int uiSrcPixel,
367        unsigned int uiSrcAlign,
368        unsigned int uiSrcAlpha,
369        unsigned int *puiDstPixel )
370{
371        signed int lA, lR, lG, lB;
372        signed int lY, lY0, lY1, lCr, lCb;
373
374        /* Check parameter */
375        if( puiDstPixel == NULL )
376        {
377                return BERR_TRACE(BERR_INVALID_PARAMETER);
378        }
379
380        /* Get YCbCr components */
381        lCr = BPXL_GET_COMPONENT(eSrcFormat, uiSrcPixel, 0) - 128;
382        lCb = BPXL_GET_COMPONENT(eSrcFormat, uiSrcPixel, 1) - 128;
383        lY1 = BPXL_GET_COMPONENT(eSrcFormat, uiSrcPixel, 2) - 16;
384        lY0 = BPXL_GET_COMPONENT(eSrcFormat, uiSrcPixel, 3) - 16;
385        lY  = (BPXL_HAS_ALPHA(eSrcFormat) || (uiSrcAlign & 1)) ? lY1 : lY0;
386
387        /* Convert to ARGB components */
388        /* R = (Y - 16) * 1.164 + (Cr - 128) * 1.596 */
389        /* G = (Y - 16) * 1.164 - (Cr - 128) * 0.813 - (Cb - 128) * 0.391 */
390        /* B = (Y - 16) * 1.164 + (Cb - 128) * 2.018 */
391        lA = (signed int) (BPXL_HAS_ALPHA(eSrcFormat) ? BPXL_GET_COMPONENT(eSrcFormat, uiSrcPixel, 3) : uiSrcAlpha);
392        lR = (signed int) ((lY * 0x129FB + lCr * 0x19893) >> 16);
393        lG = (signed int) ((lY * 0x129FB - lCr * 0x0D020 - lCb * 0x06418) >> 16);
394        lB = (signed int) ((lY * 0x129FB + lCb * 0x2049B) >> 16);
395
396        /* Clamp RGB components */
397        lR = (lR > 0xFF) ? 0xFF : ((lR < 0) ? 0 : lR);
398        lG = (lG > 0xFF) ? 0xFF : ((lG < 0) ? 0 : lG);
399        lB = (lB > 0xFF) ? 0xFF : ((lB < 0) ? 0 : lB);
400
401        /* Make destination pixel */
402        *puiDstPixel = BPXL_MAKE_PIXEL(eDstFormat, lA, lR, lG, lB);
403
404        return BERR_SUCCESS;
405}
406
407/***************************************************************************/
408BERR_Code BPXL_GetBytesPerNPixels(
409        BPXL_Format eFormat,
410        unsigned int uiNPixels,
411        unsigned int *puiBytes )
412{
413        unsigned int uiBytes = 0;
414
415        /* Check parameter */
416        if( puiBytes == NULL )
417        {
418                return BERR_TRACE(BERR_INVALID_PARAMETER);
419        }
420
421        /* check if format is YCbCr 422 10-bit */
422        if( BPXL_IS_YCbCr422_10BIT_FORMAT(eFormat) )
423        {
424                /* align size to 6 pixels (per 4 dwords) */
425                uiBytes = ((uiNPixels + 5) / 6) * 16;
426        }
427        /* check if format is YCbCr 422 10-bit packed format (eg. BPXL_eCr10_Y110_Cb10_Y010)*/
428        else if( BPXL_IS_YCbCr422_10BIT_PACKED_FORMAT(eFormat) )
429        {
430                /* align size to 8 pixels (per 5 dwords) */
431                uiBytes = ((uiNPixels + 7) / 8) * 20;
432        }
433        else if( eFormat != BPXL_INVALID )
434        {
435                unsigned int uiBitsPerPixel = BPXL_BITS_PER_PIXEL(eFormat);
436
437                /* calculate bytes for sub-byte formats */
438                if( uiBitsPerPixel < 8 )
439                {
440                        uiNPixels += 8 / uiBitsPerPixel - 1;
441                        uiBytes = uiNPixels / (8 / uiBitsPerPixel);
442                }
443                /* calculate bytes for formats that are a byte or larger */
444                else
445                {
446                        /* align size of YCbCr 422 and YCbCr 420 chroma formats to 2 pixels */
447                        if( BPXL_IS_YCbCr422_FORMAT(eFormat) || BPXL_IS_YCbCr420_CHROMA_FORMAT(eFormat) )
448                                uiNPixels = (uiNPixels + 1) & (~1);
449
450                        uiBytes = (uiNPixels * uiBitsPerPixel) / 8;
451                }
452        }
453
454        *puiBytes = uiBytes;
455        return BERR_SUCCESS;
456}
457
458/***************************************************************************/
459const char* BPXL_ConvertFmtToStr(
460                BPXL_Format eFormat )
461{
462        uint32_t i = 0;
463
464        while (s_aPxlFmtInfo[i].ePxlFmt != BPXL_INVALID)
465        {
466                if (s_aPxlFmtInfo[i].ePxlFmt == eFormat)
467                {
468                        return s_aPxlFmtInfo[i].pcFmtName;
469                }
470                i++;
471        }
472
473        return "BPXL_INVALID";
474}
475/* End of File */
Note: See TracBrowser for help on using the repository browser.