~noskcaj/ubuntu/saucy/sflphone/merge-1.2.3-2

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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
//------------------------------------------------------------------------------
// File: AMVideo.cpp
//
// Desc: DirectShow base classes - implements helper functions for
//       bitmap formats.
//
// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------

#include <pjmedia-videodev/config.h>

#if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0

#include <streams.h>
#include <limits.h>

// These are bit field masks for true colour devices

const DWORD bits555[] = {0x007C00,0x0003E0,0x00001F};
const DWORD bits565[] = {0x00F800,0x0007E0,0x00001F};
const DWORD bits888[] = {0xFF0000,0x00FF00,0x0000FF};

// This maps bitmap subtypes into a bits per pixel value and also a
// name. unicode and ansi versions are stored because we have to
// return a pointer to a static string.
const struct {
    const GUID *pSubtype;
    WORD BitCount;
    CHAR *pName;
    WCHAR *wszName;
} BitCountMap[] =  { &MEDIASUBTYPE_RGB1,        1,   "RGB Monochrome",     L"RGB Monochrome",
                     &MEDIASUBTYPE_RGB4,        4,   "RGB VGA",            L"RGB VGA",
                     &MEDIASUBTYPE_RGB8,        8,   "RGB 8",              L"RGB 8",
                     &MEDIASUBTYPE_RGB565,      16,  "RGB 565 (16 bit)",   L"RGB 565 (16 bit)",
                     &MEDIASUBTYPE_RGB555,      16,  "RGB 555 (16 bit)",   L"RGB 555 (16 bit)",
                     &MEDIASUBTYPE_RGB24,       24,  "RGB 24",             L"RGB 24",
                     &MEDIASUBTYPE_RGB32,       32,  "RGB 32",             L"RGB 32",
                     &MEDIASUBTYPE_ARGB32,    32,  "ARGB 32",             L"ARGB 32",
                     &MEDIASUBTYPE_Overlay,     0,   "Overlay",            L"Overlay",
                     &GUID_NULL,                0,   "UNKNOWN",            L"UNKNOWN"
};

// Return the size of the bitmap as defined by this header

STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader)
{
    return DIBSIZE(*pHeader);
}


// This is called if the header has a 16 bit colour depth and needs to work
// out the detailed type from the bit fields (either RGB 565 or RGB 555)

STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader)
{
    BITMAPINFO *pbmInfo = (BITMAPINFO *) pbmiHeader;
    ASSERT(pbmiHeader->biBitCount == 16);

    // If its BI_RGB then it's RGB 555 by default

    if (pbmiHeader->biCompression == BI_RGB) {
        return MEDIASUBTYPE_RGB555;
    }

    // Compare the bit fields with RGB 555

    DWORD *pMask = (DWORD *) pbmInfo->bmiColors;
    if (pMask[0] == bits555[0]) {
        if (pMask[1] == bits555[1]) {
            if (pMask[2] == bits555[2]) {
                return MEDIASUBTYPE_RGB555;
            }
        }
    }

    // Compare the bit fields with RGB 565

    pMask = (DWORD *) pbmInfo->bmiColors;
    if (pMask[0] == bits565[0]) {
        if (pMask[1] == bits565[1]) {
            if (pMask[2] == bits565[2]) {
                return MEDIASUBTYPE_RGB565;
            }
        }
    }
    return GUID_NULL;
}


// Given a BITMAPINFOHEADER structure this returns the GUID sub type that is
// used to describe it in format negotiations. For example a video codec fills
// in the format block with a VIDEOINFO structure, it also fills in the major
// type with MEDIATYPE_VIDEO and the subtype with a GUID that matches the bit
// count, for example if it is an eight bit image then MEDIASUBTYPE_RGB8

STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader)
{
    ASSERT(pbmiHeader);

    // If it's not RGB then create a GUID from the compression type

    if (pbmiHeader->biCompression != BI_RGB) {
        if (pbmiHeader->biCompression != BI_BITFIELDS) {
            FOURCCMap FourCCMap(pbmiHeader->biCompression);
            return (const GUID) FourCCMap;
        }
    }

    // Map the RGB DIB bit depth to a image GUID

    switch(pbmiHeader->biBitCount) {
        case 1    :   return MEDIASUBTYPE_RGB1;
        case 4    :   return MEDIASUBTYPE_RGB4;
        case 8    :   return MEDIASUBTYPE_RGB8;
        case 16   :   return GetTrueColorType(pbmiHeader);
        case 24   :   return MEDIASUBTYPE_RGB24;
        case 32   :   return MEDIASUBTYPE_RGB32;
    }
    return GUID_NULL;
}


// Given a video bitmap subtype we return the number of bits per pixel it uses
// We return a WORD bit count as thats what the BITMAPINFOHEADER uses. If the
// GUID subtype is not found in the table we return an invalid USHRT_MAX

STDAPI_(WORD) GetBitCount(const GUID *pSubtype)
{
    ASSERT(pSubtype);
    const GUID *pMediaSubtype;
    INT iPosition = 0;

    // Scan the mapping list seeing if the source GUID matches any known
    // bitmap subtypes, the list is terminated by a GUID_NULL entry

    while (TRUE) {
        pMediaSubtype = BitCountMap[iPosition].pSubtype;
        if (IsEqualGUID(*pMediaSubtype,GUID_NULL)) {
            return USHRT_MAX;
        }
        if (IsEqualGUID(*pMediaSubtype,*pSubtype)) {
            return BitCountMap[iPosition].BitCount;
        }
        iPosition++;
    }
}


// Given a bitmap subtype we return a description name that can be used for
// debug purposes. In a retail build this function still returns the names
// If the subtype isn't found in the lookup table we return string UNKNOWN

int LocateSubtype(const GUID *pSubtype)
{
    ASSERT(pSubtype);
    const GUID *pMediaSubtype;
    INT iPosition = 0;

    // Scan the mapping list seeing if the source GUID matches any known
    // bitmap subtypes, the list is terminated by a GUID_NULL entry

    while (TRUE) {
        pMediaSubtype = BitCountMap[iPosition].pSubtype;
        if (IsEqualGUID(*pMediaSubtype,*pSubtype) ||
            IsEqualGUID(*pMediaSubtype,GUID_NULL)
            )
        {
            break;
        }

        iPosition++;
    }

    return iPosition;
}



STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype)
{
    return BitCountMap[LocateSubtype(pSubtype)].wszName;
}

STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype)
{
    return BitCountMap[LocateSubtype(pSubtype)].pName;
}

#ifndef GetSubtypeName
#error wxutil.h should have defined GetSubtypeName
#endif
#undef GetSubtypeName

// this is here for people that linked to it directly; most people
// would use the header file that picks the A or W version.
STDAPI_(CHAR *) GetSubtypeName(const GUID *pSubtype)
{
    return GetSubtypeNameA(pSubtype);
}


// The mechanism for describing a bitmap format is with the BITMAPINFOHEADER
// This is really messy to deal with because it invariably has fields that
// follow it holding bit fields, palettes and the rest. This function gives
// the number of bytes required to hold a VIDEOINFO that represents it. This
// count includes the prefix information (like the rcSource rectangle) the
// BITMAPINFOHEADER field, and any other colour information on the end.
//
// WARNING If you want to copy a BITMAPINFOHEADER into a VIDEOINFO always make
// sure that you use the HEADER macro because the BITMAPINFOHEADER field isn't
// right at the start of the VIDEOINFO (there are a number of other fields),
//
//     CopyMemory(HEADER(pVideoInfo),pbmi,sizeof(BITMAPINFOHEADER));
//

STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader)
{
    // Everyone has this to start with this
    LONG Size = SIZE_PREHEADER + pHeader->biSize;

    ASSERT(pHeader->biSize >= sizeof(BITMAPINFOHEADER));

    // Does this format use a palette, if the number of colours actually used
    // is zero then it is set to the maximum that are allowed for that colour
    // depth (an example is 256 for eight bits). Truecolour formats may also
    // pass a palette with them in which case the used count is non zero

    // This would scare me.
    ASSERT(pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed == 0);

    if (pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed) {
        LONG Entries = (DWORD) 1 << pHeader->biBitCount;
        if (pHeader->biClrUsed) {
            Entries = pHeader->biClrUsed;
        }
        Size += Entries * sizeof(RGBQUAD);
    }

    // Truecolour formats may have a BI_BITFIELDS specifier for compression
    // type which means that room for three DWORDs should be allocated that
    // specify where in each pixel the RGB colour components may be found

    if (pHeader->biCompression == BI_BITFIELDS) {
        Size += SIZE_MASKS;
    }

    // A BITMAPINFO for a palettised image may also contain a palette map that
    // provides the information to map from a source palette to a destination
    // palette during a BitBlt for example, because this information is only
    // ever processed during drawing you don't normally store the palette map
    // nor have any way of knowing if it is present in the data structure

    return Size;
}


// Returns TRUE if the VIDEOINFO contains a palette

STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo)
{
    if (PALETTISED(pVideoInfo) == FALSE) {
        if (pVideoInfo->bmiHeader.biClrUsed == 0) {
            return FALSE;
        }
    }
    return TRUE;
}


// Return a pointer to the first entry in a palette

STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo)
{
    if (pVideoInfo->bmiHeader.biCompression == BI_BITFIELDS) {
        return TRUECOLOR(pVideoInfo)->bmiColors;
    }
    return COLORS(pVideoInfo);
}

#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */