summaryrefslogtreecommitdiff
path: root/avstream/avscamera/sys/YUVSynthesizer.cpp
blob: 27b4c7e98b2627334bf1cbf402b0dcb0a0582033 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**************************************************************************

    A/V Stream Camera Sample

    Copyright (c) 2014, Microsoft Corporation.

    File:

        YUVSynthesizer.cpp

    Abstract:

        This file contains the implementation of CYUVSynthesizer.

        A Base image synthesizer for all YUV formats.  It provides a YUV color
        palette and sets up cached gradient bars.

    History:

        created 4/14/2014

**************************************************************************/

#include "Common.h"

/**************************************************************************

    PAGED CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA

const UCHAR4 *
CYUVSynthesizer::
GetPalette()
/*++

Routine Description:

    Get a pointer to an array of palette colors.  Used mostly to handle
    different color primaries.  Location of the primary must agree with
    Commit().

Arguments:

    none

Return Value:

    A pointer to an array of color primaries used for rendering.

--*/
{
    PAGED_CODE();

    static
    UCHAR4 Colors [MAX_COLOR] =
    {
        {128, 16, 128},     // BLACK
        {128, 235, 128},    // WHITE
        {16, 211, 146},     // YELLOW
        {166, 170, 16},     // CYAN
        {54, 145, 34},      // GREEN
        {202, 106, 222},    // MAGENTA
        {90, 81, 240},      // RED
        {240, 41, 109},     // BLUE
        {128, 125, 128},    // GREY
        {128, 235, 128}     // TEXT_COLOR
    };

    return Colors;
};

//  Macros used to do fixed-point arithmetic in initialization.
#define   TO_Q24_8bit_to_32bit_signed(_x_)     (        (  ( LONG) (_x_) ) << 24 )
#define FROM_Q24_32bit_to_8bit_signed(_x_)     (( CHAR) (( ( LONG) (_x_) ) >> 24 ))
#define   TO_Q24_8bit_to_32bit_unsigned(_x_)   (        (  (ULONG) (_x_) ) << 24 )
#define FROM_Q24_32bit_to_8bit_unsigned(_x_)   ((UCHAR) (( (ULONG) (_x_) ) >> 24 ))

BOOLEAN
CYUVSynthesizer::
Initialize()
/*++

Routine Description:

    Class initialization.

    Used to pre-initialize a bitmap that contains a gradient bar that starts
    with one of our rendering colors and fades to black.  Each row will contain
    the gradient for a single starting color.  To paint a gradient bar, simply
    replicate the row as many times as necessary.  
    
    This front-loads all gradient calculations to initialization and caches the 
    result, allowing us to render a gradient bar in the time it takes to copy
    the pixels even on a relatively slow machine.

Arguments:

    none

Return Value:

    TRUE - success.

--*/
{
    PAGED_CODE();

    //  First, do the base class initialization.
    BOOLEAN Status = CSynthesizer::Initialize();

    if( Status )
    {
        //  Now initialize the Gradient bmp...
        CKsRgbQuad  *Bmp = m_GradientBmp;
        //  {54, 145, 34},      // GREEN to {128, 16, 128},     // BLACK
        for( ULONG color=BLACK; color<MAX_COLOR; color++ )
        {
            //  Must treat chroma as signed & luma as unsigned here.
            ULONG   HALF     = TO_Q24_8bit_to_32bit_unsigned(1)>>1;   // round, don't truncate.
            LONG    U        = TO_Q24_8bit_to_32bit_signed  (m_Colors[color][0])+HALF;
            ULONG   Y        = TO_Q24_8bit_to_32bit_unsigned(m_Colors[color][1])+HALF;
            LONG    V        = TO_Q24_8bit_to_32bit_signed  (m_Colors[color][2])+HALF;
            LONG    UDelta   = U-TO_Q24_8bit_to_32bit_signed  (m_Colors[BLACK][0]);
            ULONG   YDelta   = Y-TO_Q24_8bit_to_32bit_unsigned(m_Colors[BLACK][1]);
            LONG    VDelta   = V-TO_Q24_8bit_to_32bit_signed  (m_Colors[BLACK][2]);

            UDelta /= (LONG) m_Width;
            YDelta /= (LONG) m_Width;
            VDelta /= (LONG) m_Width;

            for(ULONG i = 0; i < m_Width; i++)
            {
                *Bmp++ = CKsRgbQuad(
                             FROM_Q24_32bit_to_8bit_signed  (V),
                             FROM_Q24_32bit_to_8bit_unsigned(Y),
                             FROM_Q24_32bit_to_8bit_signed  (U)
                         );
                U -= UDelta;
                Y -= YDelta;
                V -= VDelta;
            }
        }
    }
    return Status;
}