~ubuntu-branches/ubuntu/maverick/zapping/maverick

« back to all changes in this revision

Viewing changes to libtv/pixel_format.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-03-08 23:19:08 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050308231908-oip7rfv6lcmo8c0e
Tags: 0.9.2-2ubuntu1
Rebuilt for Python transition (2.3 -> 2.4)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2001-2004 Michael H. Schimek
 
3
 *  Copyright (C) 2000-2003 I�aki Garc�a Etxebarria
 
4
 *
 
5
 *  This program is free software; you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation; either version 2 of the License, or
 
8
 *  (at your option) any later version.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 */
 
19
 
 
20
/* $Id: pixel_format.c,v 1.4 2005/01/20 01:38:33 mschimek Exp $ */
 
21
 
 
22
#ifdef HAVE_CONFIG_H
 
23
#  include "config.h"           /* Z_BYTE_ORDER */
 
24
#endif
 
25
 
 
26
#include "misc.h"
 
27
#include "pixel_format.h"
 
28
 
 
29
const char *
 
30
tv_pixfmt_name                  (tv_pixfmt              pixfmt)
 
31
{
 
32
        switch (pixfmt) {
 
33
 
 
34
#undef CASE
 
35
#define CASE(s) case TV_PIXFMT_##s : return #s ;
 
36
 
 
37
        CASE (NONE)
 
38
        CASE (YUV444)
 
39
        CASE (YVU444)
 
40
        CASE (YUV422)
 
41
        CASE (YVU422)
 
42
        CASE (YUV411)
 
43
        CASE (YVU411)
 
44
        CASE (YUV420)
 
45
        CASE (YVU420)
 
46
        CASE (YUV410)
 
47
        CASE (YVU410)
 
48
        CASE (YUVA32_LE)
 
49
        CASE (YUVA32_BE)
 
50
        CASE (YVUA32_LE)
 
51
        CASE (YVUA32_BE)
 
52
        /* AVUY32_BE synonyms */
 
53
        /* AVUY32_LE */
 
54
        /* AUVY32_BE */
 
55
        /* AUVY32_LE */
 
56
        CASE (YUV24_LE)
 
57
        CASE (YUV24_BE)
 
58
        CASE (YVU24_LE)
 
59
        CASE (YVU24_BE)
 
60
        /* VUY24_BE */
 
61
        /* VUY24_LE */
 
62
        /* UVY24_BE */
 
63
        /* UVY24_LE */
 
64
        CASE (YUYV)
 
65
        CASE (YVYU)
 
66
        CASE (UYVY)
 
67
        CASE (VYUY)
 
68
        CASE (Y8)
 
69
        CASE (RGBA32_LE)
 
70
        CASE (RGBA32_BE)
 
71
        CASE (BGRA32_LE)
 
72
        CASE (BGRA32_BE)
 
73
        /* ABGR32_BE synonyms */
 
74
        /* ABGR32_LE */
 
75
        /* ARGB32_BE */
 
76
        /* ARGB32_LE */
 
77
        CASE (RGB24_LE)
 
78
        CASE (BGR24_LE)
 
79
        /* BGR24_BE */
 
80
        /* RGB24_BE */
 
81
        CASE (RGB16_LE)
 
82
        CASE (RGB16_BE)
 
83
        CASE (BGR16_LE)
 
84
        CASE (BGR16_BE)
 
85
        CASE (RGBA16_LE)
 
86
        CASE (RGBA16_BE)
 
87
        CASE (BGRA16_LE)
 
88
        CASE (BGRA16_BE)
 
89
        CASE (ARGB16_LE)
 
90
        CASE (ARGB16_BE)
 
91
        CASE (ABGR16_LE)
 
92
        CASE (ABGR16_BE)
 
93
        CASE (RGBA12_LE)
 
94
        CASE (RGBA12_BE)
 
95
        CASE (BGRA12_LE)
 
96
        CASE (BGRA12_BE)
 
97
        CASE (ARGB12_LE)
 
98
        CASE (ARGB12_BE)
 
99
        CASE (ABGR12_LE)
 
100
        CASE (ABGR12_BE)
 
101
        CASE (RGB8)
 
102
        CASE (BGR8)
 
103
        CASE (RGBA8)
 
104
        CASE (BGRA8)
 
105
        CASE (ARGB8)
 
106
        CASE (ABGR8)
 
107
        CASE (SBGGR)
 
108
 
 
109
        case TV_PIXFMT_RESERVED0:
 
110
        case TV_PIXFMT_RESERVED1:
 
111
        case TV_PIXFMT_RESERVED2:
 
112
        case TV_PIXFMT_RESERVED3:
 
113
                break;
 
114
        }
 
115
 
 
116
        return NULL;
 
117
}
 
118
 
 
119
#define PIXEL_FORMAT(pixfmt, colspc, bits_per_pixel, color_depth,       \
 
120
                     uv_hshift, uv_vshift, big_endian, planar,          \
 
121
                     vu_order, r, g, b, a)                              \
 
122
        { #pixfmt,                                                      \
 
123
          TV_PIXFMT_##pixfmt,                                           \
 
124
          colspc,                                                       \
 
125
          bits_per_pixel,                                               \
 
126
          color_depth,                                                  \
 
127
          uv_hshift,                                                    \
 
128
          uv_vshift,                                                    \
 
129
          big_endian,                                                   \
 
130
          planar,                                                       \
 
131
          vu_order,                                                     \
 
132
          .mask = { .rgb = { r, g, b, a } } }
 
133
 
 
134
#if Z_BYTE_ORDER == Z_LITTLE_ENDIAN
 
135
#  define PACKED(fmt, colspc, bits_per_pixel, color_depth, big_endian,  \
 
136
                 vu_order, x, y, z, a)                                  \
 
137
        [TV_PIXFMT_##fmt] = PIXEL_FORMAT (fmt, colspc,                  \
 
138
                bits_per_pixel, color_depth, 0, 0, big_endian,          \
 
139
                FALSE, vu_order, x, y, z, a)
 
140
 
 
141
#elif Z_BYTE_ORDER == Z_BIG_ENDIAN
 
142
#  define PACKED(fmt, colspc, bits_per_pixel, color_depth, big_endian,  \
 
143
                 vu_order, x, y, z, a)                                  \
 
144
        [TV_PIXFMT_##fmt] = PIXEL_FORMAT (fmt, colspc,                  \
 
145
                bits_per_pixel, color_depth, 0, 0, !(big_endian),       \
 
146
                FALSE, vu_order, x, y, z, a)
 
147
#else
 
148
#  error unknown endianess
 
149
#endif
 
150
 
 
151
#define PLANAR(fmt, color_depth, uv_hshift, uv_vshift, vu_order)        \
 
152
        [TV_PIXFMT_##fmt] = PIXEL_FORMAT (fmt, TV_COLSPC_YUV, 8,        \
 
153
                color_depth, uv_hshift, uv_vshift, FALSE, TRUE,         \
 
154
                vu_order, 0xFF, 0xFF, 0xFF, 0)
 
155
 
 
156
#define PACKED_YUV24(fmt, bpp, vu_order, x, y, z, a)                    \
 
157
        PACKED(fmt##_LE, TV_COLSPC_YUV,                                 \
 
158
               bpp, 24, FALSE, vu_order, x, y, z, a),                   \
 
159
        PACKED(fmt##_BE, TV_COLSPC_YUV,                                 \
 
160
               bpp, 24,  TRUE, vu_order, x, y, z, a)
 
161
 
 
162
#define YUYV(fmt, vu_order)                                             \
 
163
        [TV_PIXFMT_##fmt] = PIXEL_FORMAT (fmt, TV_COLSPC_YUV, 16,       \
 
164
                16, 0, 0, FALSE, FALSE, vu_order, 0xFF, 0xFF, 0xFF, 0)
 
165
 
 
166
#define PACKED_RGB24(fmt, bpp, x, y, z, a)                              \
 
167
        PACKED(fmt##_LE, TV_COLSPC_RGB,                                 \
 
168
               bpp, 24, FALSE, FALSE, x, y, z, a),                      \
 
169
        PACKED(fmt##_BE, TV_COLSPC_RGB,                                 \
 
170
               bpp, 24,  TRUE, FALSE, x, y, z, a)
 
171
 
 
172
#define PACKED16(fmt, x, y, z, a)                                       \
 
173
        PACKED(fmt##_LE, TV_COLSPC_RGB,                                 \
 
174
               16, 16, FALSE, FALSE, x, y, z, a),                       \
 
175
        PACKED(fmt##_BE, TV_COLSPC_RGB,                                 \
 
176
               16, 16,  TRUE, FALSE, x, y, z, a)
 
177
 
 
178
#define PACKED8(fmt, x, y, z, a)                                        \
 
179
        [TV_PIXFMT_##fmt] = PIXEL_FORMAT (fmt, TV_COLSPC_RGB, 8, 8,     \
 
180
                0, 0, FALSE, FALSE, FALSE, x, y, z, a)
 
181
 
 
182
static const tv_pixel_format
 
183
pixel_formats [] = {
 
184
        PLANAR (YUV444, 24, 0, 0, FALSE), 
 
185
        PLANAR (YVU444, 24, 0, 0, TRUE), 
 
186
        PLANAR (YUV422, 16, 1, 0, FALSE), 
 
187
        PLANAR (YVU422, 16, 1, 0, TRUE), 
 
188
        PLANAR (YUV411, 12, 2, 0, FALSE), 
 
189
        PLANAR (YVU411, 12, 2, 0, TRUE), 
 
190
        PLANAR (YUV420, 12, 1, 1, FALSE), 
 
191
        PLANAR (YVU420, 12, 1, 1, TRUE), 
 
192
        PLANAR (YUV410,  9, 2, 2, FALSE), 
 
193
        PLANAR (YVU410,  9, 2, 2, TRUE), 
 
194
 
 
195
        PACKED_YUV24 (YUVA32, 32, FALSE, 0xFF, 0xFF00, 0xFF0000, 0xFF000000),
 
196
        PACKED_YUV24 (YVUA32, 32,  TRUE, 0xFF, 0xFF0000, 0xFF00, 0xFF000000),
 
197
 
 
198
        PACKED_YUV24 (YUV24, 24, FALSE, 0xFF, 0xFF00, 0xFF0000, 0),
 
199
        PACKED_YUV24 (YVU24, 24, FALSE, 0xFF, 0xFF0000, 0xFF00, 0),
 
200
 
 
201
        YUYV (YUYV, FALSE),
 
202
        YUYV (YVYU,  TRUE),
 
203
        YUYV (UYVY, FALSE),
 
204
        YUYV (VYUY,  TRUE),
 
205
 
 
206
        [TV_PIXFMT_Y8] = PIXEL_FORMAT (Y8, TV_COLSPC_YUV, 8, 8,
 
207
                                       0, 0, FALSE, FALSE, FALSE,
 
208
                                       0xFF, 0, 0, 0),
 
209
 
 
210
        PACKED_RGB24 (RGBA32, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000),
 
211
        PACKED_RGB24 (BGRA32, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000),
 
212
 
 
213
        PACKED (RGB24_LE, TV_COLSPC_RGB,
 
214
                24, 24, FALSE, FALSE, 0xFF, 0xFF00, 0xFF0000, 0),
 
215
        PACKED (BGR24_LE, TV_COLSPC_RGB,
 
216
                24, 24, FALSE, FALSE, 0xFF0000, 0xFF00, 0xFF, 0),
 
217
 
 
218
        PACKED16 (RGB16, 0x001F, 0x07E0, 0xF800, 0),
 
219
        PACKED16 (BGR16, 0xF800, 0x07E0, 0x001F, 0),
 
220
 
 
221
        PACKED16 (RGBA16, 0x001F, 0x03E0, 0x7C00, 0x8000),
 
222
        PACKED16 (BGRA16, 0x7C00, 0x03E0, 0x001F, 0x8000),
 
223
        PACKED16 (ARGB16, 0x003E, 0x07C0, 0xF800, 0x0001),
 
224
        PACKED16 (ABGR16, 0xF800, 0x07C0, 0x003E, 0x0001),
 
225
 
 
226
        PACKED16 (RGBA12, 0x000F, 0x00F0, 0x0F00, 0xF000),
 
227
        PACKED16 (BGRA12, 0x0F00, 0x00F0, 0x000F, 0xF000),
 
228
        PACKED16 (ARGB12, 0x00F0, 0x0F00, 0xF000, 0x000F),
 
229
        PACKED16 (ABGR12, 0xF000, 0x0F00, 0x00F0, 0x000F),
 
230
 
 
231
        PACKED8 (RGB8, 0x07, 0x38, 0xC0, 0),
 
232
        PACKED8 (BGR8, 0xE0, 0x1C, 0x03, 0),
 
233
 
 
234
        PACKED8 (RGBA8, 0x03, 0x1C, 0x60, 0x80),
 
235
        PACKED8 (BGRA8, 0x60, 0x1C, 0x03, 0x80),
 
236
        PACKED8 (ARGB8, 0x06, 0x38, 0xC0, 0x01),
 
237
        PACKED8 (ABGR8, 0xC0, 0x38, 0x06, 0x01),
 
238
 
 
239
        [TV_PIXFMT_SBGGR] = PIXEL_FORMAT (SBGGR, TV_COLSPC_RGB, 8, 24,
 
240
                                          0, 0, FALSE, FALSE, FALSE,
 
241
                                          0xFF, 0xFF, 0xFF, 0),
 
242
};
 
243
 
 
244
unsigned int
 
245
tv_pixfmt_bytes_per_pixel       (tv_pixfmt              pixfmt)
 
246
{
 
247
        unsigned int index = (unsigned int) pixfmt;
 
248
 
 
249
        if (index > N_ELEMENTS (pixel_formats))
 
250
                return 0;
 
251
 
 
252
        return pixel_formats[index].bits_per_pixel >> 3;
 
253
}
 
254
 
 
255
const tv_pixel_format *
 
256
tv_pixel_format_from_pixfmt     (tv_pixfmt              pixfmt)
 
257
{
 
258
        unsigned int index = (unsigned int) pixfmt;
 
259
        const tv_pixel_format *pf;
 
260
 
 
261
        if (index > N_ELEMENTS (pixel_formats))
 
262
                return NULL;
 
263
 
 
264
        pf = &pixel_formats[index];
 
265
 
 
266
        if (0 == pf->bits_per_pixel)
 
267
                return NULL;
 
268
 
 
269
        return pf;
 
270
}
 
271
 
 
272
/* Number of set bits. */
 
273
static unsigned int
 
274
popcnt                          (unsigned int           x)
 
275
{
 
276
        x -= ((x >> 1) & 0x55555555);
 
277
        x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
 
278
        x = (x + (x >> 4)) & 0x0F0F0F0F;
 
279
 
 
280
        return (x * 0x01010101) >> 24;
 
281
}
 
282
 
 
283
/* Note this works only for RGB formats. */
 
284
tv_pixfmt
 
285
tv_pixel_format_to_pixfmt       (const tv_pixel_format *format)
 
286
{
 
287
        unsigned int color_depth;
 
288
        unsigned int mask;
 
289
        unsigned int mask_a;
 
290
        unsigned int r_msb;
 
291
        unsigned int a_lsb;
 
292
 
 
293
        assert (NULL != format);
 
294
 
 
295
        if (format->bits_per_pixel < 7
 
296
            || 0 == format->mask.rgb.r
 
297
            || 0 == format->mask.rgb.g
 
298
            || 0 == format->mask.rgb.b)
 
299
                return TV_PIXFMT_UNKNOWN;
 
300
 
 
301
        mask = format->mask.rgb.r | format->mask.rgb.g | format->mask.rgb.b;
 
302
 
 
303
        if (format->mask.rgb.g > format->mask.rgb.r) {
 
304
                if (format->mask.rgb.g > format->mask.rgb.b)
 
305
                        return TV_PIXFMT_UNKNOWN; /* GRB, GBR */
 
306
        } else {
 
307
                if (format->mask.rgb.b > format->mask.rgb.g)
 
308
                        return TV_PIXFMT_UNKNOWN; /* RBG, BRG */
 
309
        }
 
310
 
 
311
        color_depth = format->color_depth;
 
312
        if (0 == color_depth)
 
313
                color_depth = popcnt (mask);
 
314
 
 
315
        mask_a = format->mask.rgb.a;
 
316
        if (0 == mask_a)
 
317
                mask_a = mask
 
318
                        ^ (0xFFFFFFFFUL >> (32 - format->bits_per_pixel));
 
319
 
 
320
        if (mask > mask_a) {
 
321
                if (mask_a > format->mask.rgb.r
 
322
                    || format->mask.rgb.a > format->mask.rgb.b)
 
323
                        return TV_PIXFMT_UNKNOWN; /* XGAX, XAGX */
 
324
        }
 
325
 
 
326
        a_lsb = (mask >= mask_a);
 
327
        r_msb = (format->mask.rgb.r >= format->mask.rgb.b);
 
328
 
 
329
        switch (color_depth) {
 
330
        case 24:
 
331
                if (32 == format->bits_per_pixel) {
 
332
                        static tv_pixfmt mapping [] = {
 
333
                                TV_PIXFMT_RGBA32_LE, TV_PIXFMT_RGBA32_BE,
 
334
                                TV_PIXFMT_BGRA32_LE, TV_PIXFMT_BGRA32_BE,
 
335
                                TV_PIXFMT_ARGB32_LE, TV_PIXFMT_ARGB32_BE,
 
336
                                TV_PIXFMT_ABGR32_LE, TV_PIXFMT_ABGR32_BE,
 
337
                        };
 
338
 
 
339
                        return mapping [a_lsb * 4 + r_msb * 2
 
340
                                        + format->big_endian];
 
341
                } else {
 
342
                        static tv_pixfmt mapping [] = {
 
343
                                TV_PIXFMT_RGB24_LE, TV_PIXFMT_BGR24_LE
 
344
                        };
 
345
 
 
346
                        return mapping [r_msb];
 
347
                }
 
348
 
 
349
        case 16:
 
350
        {
 
351
                static tv_pixfmt mapping [] = {
 
352
                        TV_PIXFMT_RGB16_LE, TV_PIXFMT_RGB16_BE,
 
353
                        TV_PIXFMT_BGR16_LE, TV_PIXFMT_BGR16_BE,
 
354
                };
 
355
 
 
356
                return mapping [r_msb * 2 + format->big_endian];
 
357
        }
 
358
 
 
359
        case 15:
 
360
        {
 
361
                static tv_pixfmt mapping [] = {
 
362
                        TV_PIXFMT_RGBA16_LE, TV_PIXFMT_RGBA16_BE,
 
363
                        TV_PIXFMT_BGRA16_LE, TV_PIXFMT_BGRA16_BE,
 
364
                        TV_PIXFMT_ARGB16_LE, TV_PIXFMT_ARGB16_BE,
 
365
                        TV_PIXFMT_ABGR16_LE, TV_PIXFMT_ABGR16_BE,
 
366
                };
 
367
 
 
368
                return mapping [a_lsb * 4 + r_msb * 2 + format->big_endian];
 
369
        }
 
370
 
 
371
        case 12:
 
372
        {
 
373
                static tv_pixfmt mapping [] = {
 
374
                        TV_PIXFMT_RGBA12_LE, TV_PIXFMT_RGBA12_BE,
 
375
                        TV_PIXFMT_BGRA12_LE, TV_PIXFMT_BGRA12_BE,
 
376
                        TV_PIXFMT_ARGB12_LE, TV_PIXFMT_ARGB12_BE,
 
377
                        TV_PIXFMT_ABGR12_LE, TV_PIXFMT_ABGR12_BE,
 
378
                };
 
379
 
 
380
                return mapping [a_lsb * 4 + r_msb * 2 + format->big_endian];
 
381
        }
 
382
 
 
383
        case 8:
 
384
        {
 
385
                static tv_pixfmt mapping [] = {
 
386
                        TV_PIXFMT_RGB8, TV_PIXFMT_BGR8
 
387
                };
 
388
 
 
389
                return mapping [r_msb];
 
390
        }
 
391
 
 
392
        case 7:
 
393
        {
 
394
                static tv_pixfmt mapping [] = {
 
395
                        TV_PIXFMT_RGBA8, TV_PIXFMT_BGRA8,
 
396
                        TV_PIXFMT_ARGB8, TV_PIXFMT_ABGR8,
 
397
                };
 
398
 
 
399
                return mapping [a_lsb * 2 + r_msb];
 
400
                break;
 
401
        }
 
402
        
 
403
        default:
 
404
                break;
 
405
        }
 
406
 
 
407
        return TV_PIXFMT_UNKNOWN;
 
408
}