hlsdemux: Enable support for external subtitles
[platform/upstream/gstreamer.git] / ext / closedcaption / io-sim.c
1 /*
2  *  libzvbi -- VBI device simulation
3  *
4  *  Copyright (C) 2004, 2007 Michael H. Schimek
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public
17  *  License along with this library; if not, write to the 
18  *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
19  *  Boston, MA  02110-1301  USA.
20  */
21
22 /* $Id: io-sim.c,v 1.18 2009-12-14 23:43:40 mschimek Exp $ */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #ifdef _MSC_VER
29 #define _USE_MATH_DEFINES       /* Needed for M_PI and M_LN2 */
30 #endif
31 #include <math.h>               /* sin(), log() */
32 #include <errno.h>
33 #include <ctype.h>              /* isspace() */
34 #include <limits.h>             /* INT_MAX */
35
36 #include "misc.h"
37 #include "sliced.h"
38 #include "sampling_par.h"
39 #include "raw_decoder.h"
40 #include "hamm.h"
41
42 #  define sp_sample_format sampling_format
43 #  define SAMPLES_PER_LINE(sp)                                          \
44         ((sp)->bytes_per_line / VBI_PIXFMT_BPP ((sp)->sampling_format))
45 #  define SYSTEM_525(sp)                                                \
46         (525 == (sp)->scanning)
47
48 #include "io-sim.h"
49
50 /**
51  * @addtogroup Rawenc Raw VBI encoder
52  * @ingroup Raw
53  * @brief Converting sliced VBI data to raw VBI images.
54  *
55  * These are functions converting sliced VBI data to raw VBI images as
56  * transmitted in the vertical blanking interval of analog video standards.
57  * They are mainly intended for tests of the libzvbi bit slicer and
58  * raw VBI decoder.
59  */
60
61 #  define VBI_PIXFMT_RGB24_LE VBI_PIXFMT_RGB24
62 #  define VBI_PIXFMT_BGR24_LE VBI_PIXFMT_BGR24
63 #  define VBI_PIXFMT_RGBA24_LE VBI_PIXFMT_RGBA32_LE
64 #  define VBI_PIXFMT_BGRA24_LE VBI_PIXFMT_BGRA32_LE
65 #  define VBI_PIXFMT_RGBA24_BE VBI_PIXFMT_RGBA32_BE
66 #  define VBI_PIXFMT_BGRA24_BE VBI_PIXFMT_BGRA32_BE
67 #  define vbi_pixfmt_bytes_per_pixel VBI_PIXFMT_BPP
68
69 #define PI 3.1415926535897932384626433832795029
70
71 #define PULSE(zero_level)                                               \
72 do {                                                                    \
73         if (0 == seq) {                                                 \
74                 raw[i] = SATURATE (zero_level, 0, 255);                 \
75         } else if (3 == seq) {                                          \
76                 raw[i] = SATURATE (zero_level + (int) signal_amp,       \
77                                    0, 255);                             \
78         } else if ((seq ^ bit) & 1) { /* down */                        \
79                 double r = sin (q * tr - (PI / 2.0));                   \
80                 r = r * r * signal_amp;                                 \
81                 raw[i] = SATURATE (zero_level + (int) r, 0, 255);       \
82         } else { /* up */                                               \
83                 double r = sin (q * tr);                                \
84                 r = r * r * signal_amp;                                 \
85                 raw[i] = SATURATE (zero_level + (int) r, 0, 255);       \
86         }                                                               \
87 } while (0)
88
89 #define PULSE_SEQ(zero_level)                                           \
90 do {                                                                    \
91         double tr;                                                      \
92         unsigned int bit;                                               \
93         unsigned int byte;                                              \
94         unsigned int seq;                                               \
95                                                                         \
96         tr = t - t1;                                                    \
97         bit = tr * bit_rate;                                            \
98         byte = bit >> 3;                                                \
99         bit &= 7;                                                       \
100         seq = (buf[byte] >> 7) + buf[byte + 1] * 2;                     \
101         seq = (seq >> bit) & 3;                                         \
102         PULSE (zero_level);                                             \
103 } while (0)
104
105 _vbi_inline void
106 vbi_sincos (double x, double *sinx, double *cosx)
107 {
108   *sinx = sin (x);
109   *cosx = cos (x);
110 }
111
112 #define vbi_log2(x) (log (x) / M_LN2)
113
114 static void
115 signal_teletext (uint8_t * raw,
116     const vbi_sampling_par * sp,
117     int black_level,
118     double signal_amp,
119     double bit_rate,
120     unsigned int frc, unsigned int payload, const vbi_sliced * sliced)
121 {
122   double bit_period = 1.0 / bit_rate;
123   /* Teletext System B: Sixth CRI pulse at 12 us
124      (+.5 b/c we start with a 0 bit). */
125   double t1 = 12e-6 - 13 * bit_period;
126   double t2 = t1 + (payload * 8 + 24 + 1) * bit_period;
127   double q = (PI / 2.0) * bit_rate;
128   double sample_period = 1.0 / sp->sampling_rate;
129   unsigned int samples_per_line;
130   uint8_t buf[64];
131   unsigned int i;
132   double t;
133
134   buf[0] = 0x00;
135   buf[1] = 0x55;                /* clock run-in */
136   buf[2] = 0x55;
137   buf[3] = frc;
138
139   memcpy (buf + 4, sliced->data, payload);
140
141   buf[payload + 4] = 0x00;
142
143   t = sp->offset / (double) sp->sampling_rate;
144
145   samples_per_line = SAMPLES_PER_LINE (sp);
146
147   for (i = 0; i < samples_per_line; ++i) {
148     if (t >= t1 && t < t2)
149       PULSE_SEQ (black_level);
150
151     t += sample_period;
152   }
153 }
154
155 static void
156 signal_vps (uint8_t * raw,
157     const vbi_sampling_par * sp,
158     int black_level, int white_level, const vbi_sliced * sliced)
159 {
160   static const uint8_t biphase[] = {
161     0xAA, 0x6A, 0x9A, 0x5A,
162     0xA6, 0x66, 0x96, 0x56,
163     0xA9, 0x69, 0x99, 0x59,
164     0xA5, 0x65, 0x95, 0x55
165   };
166   double bit_rate = 15625 * 160 * 2;
167   double t1 = 12.5e-6 - .5 / bit_rate;
168   double t4 = t1 + ((4 + 13 * 2) * 8) / bit_rate;
169   double q = (PI / 2.0) * bit_rate;
170   double sample_period = 1.0 / sp->sampling_rate;
171   unsigned int samples_per_line;
172   double signal_amp = (0.5 / 0.7) * (white_level - black_level);
173   uint8_t buf[32];
174   unsigned int i;
175   double t;
176
177   CLEAR (buf);
178
179   buf[1] = 0x55;                /* 0101 0101 */
180   buf[2] = 0x55;                /* 0101 0101 */
181   buf[3] = 0x51;                /* 0101 0001 */
182   buf[4] = 0x99;                /* 1001 1001 */
183
184   for (i = 0; i < 13; ++i) {
185     unsigned int b = sliced->data[i];
186
187     buf[5 + i * 2] = biphase[b >> 4];
188     buf[6 + i * 2] = biphase[b & 15];
189   }
190
191   buf[6 + 12 * 2] &= 0x7F;
192
193   t = sp->offset / (double) sp->sampling_rate;
194
195   samples_per_line = SAMPLES_PER_LINE (sp);
196
197   for (i = 0; i < samples_per_line; ++i) {
198     if (t >= t1 && t < t4)
199       PULSE_SEQ (black_level);
200
201     t += sample_period;
202   }
203 }
204
205 static void
206 wss_biphase (uint8_t buf[32], const vbi_sliced * sliced)
207 {
208   unsigned int bit;
209   unsigned int data;
210   unsigned int i;
211
212   /* 29 bit run-in and 24 bit start code, lsb first. */
213
214   buf[0] = 0x00;
215   buf[1] = 0x1F;                /* 0001 1111 */
216   buf[2] = 0xC7;                /* 1100 0111 */
217   buf[3] = 0x71;                /* 0111 0001 */
218   buf[4] = 0x1C;                /* 000 | 1 1100 */
219   buf[5] = 0x8F;                /* 1000 1111 */
220   buf[6] = 0x07;                /* 0000 0111 */
221   buf[7] = 0x1F;                /*    1 1111 */
222
223   bit = 8 + 29 + 24;
224   data = sliced->data[0] + sliced->data[1] * 256;
225
226   for (i = 0; i < 14; ++i) {
227     static const unsigned int biphase[] = { 0x38, 0x07 };
228     unsigned int byte;
229     unsigned int shift;
230     unsigned int seq;
231
232     byte = bit >> 3;
233     shift = bit & 7;
234     bit += 6;
235
236     seq = biphase[data & 1] << shift;
237     data >>= 1;
238
239     assert (byte < 31);
240
241     buf[byte] |= seq;
242     buf[byte + 1] = seq >> 8;
243   }
244 }
245
246 static void
247 signal_wss_625 (uint8_t * raw,
248     const vbi_sampling_par * sp,
249     int black_level, int white_level, const vbi_sliced * sliced)
250 {
251   double bit_rate = 15625 * 320;
252   double t1 = 11.0e-6 - .5 / bit_rate;
253   double t4 = t1 + (29 + 24 + 14 * 6 + 1) / bit_rate;
254   double q = (PI / 2.0) * bit_rate;
255   double sample_period = 1.0 / sp->sampling_rate;
256   double signal_amp = (0.5 / 0.7) * (white_level - black_level);
257   unsigned int samples_per_line;
258   uint8_t buf[32];
259   unsigned int i;
260   double t;
261
262   CLEAR (buf);
263
264   wss_biphase (buf, sliced);
265
266   t = sp->offset / (double) sp->sampling_rate;
267
268   samples_per_line = SAMPLES_PER_LINE (sp);
269
270   for (i = 0; i < samples_per_line; ++i) {
271     if (t >= t1 && t < t4)
272       PULSE_SEQ (black_level);
273
274     t += sample_period;
275   }
276 }
277
278 static void
279 signal_closed_caption (uint8_t * raw,
280     const vbi_sampling_par * sp,
281     int blank_level,
282     int white_level,
283     unsigned int flags, double bit_rate, const vbi_sliced * sliced)
284 {
285   double D = 1.0 / bit_rate;
286   double t0 = 10.5e-6;          /* CRI start half amplitude (EIA 608-B) */
287   double t1 = t0 - .25 * D;     /* CRI start, blanking level */
288   double t2 = t1 + 7 * D;       /* CRI 7 cycles */
289   /* First start bit, left edge half amplitude, minus rise time. */
290   double t3 = t0 + 6.5 * D - 120e-9;
291   double q1 = PI * bit_rate * 2;
292   /* Max. rise/fall time 240 ns (EIA 608-B). */
293   double q2 = PI / 120e-9;
294   double signal_mean;
295   double signal_high;
296   double sample_period = 1.0 / sp->sampling_rate;
297   unsigned int samples_per_line;
298   double t;
299   unsigned int data;
300   unsigned int i;
301
302   /* Twice 7 data + odd parity, start bit 0 -> 1 */
303
304   data = (sliced->data[1] << 12) + (sliced->data[0] << 4) + 8;
305
306   t = sp->offset / (double) sp->sampling_rate;
307
308   samples_per_line = SAMPLES_PER_LINE (sp);
309
310   if (flags & _VBI_RAW_SHIFT_CC_CRI) {
311     /* Wrong signal shape found by Rich Kadel,
312        zapping-misc@lists.sourceforge.net 2006-07-16. */
313     t0 += D / 2;
314     t1 += D / 2;
315     t2 += D / 2;
316   }
317
318   if (flags & _VBI_RAW_LOW_AMP_CC) {
319     /* Low amplitude signal found by Rich Kadel,
320        zapping-misc@lists.sourceforge.net 2007-08-15. */
321     white_level = white_level * 6 / 10;
322   }
323
324   signal_mean = (white_level - blank_level) * .25;      /* 25 IRE */
325   signal_high = blank_level + (white_level - blank_level) * .5;
326
327   for (i = 0; i < samples_per_line; ++i) {
328     if (t >= t1 && t < t2) {
329       raw[i] = SATURATE (blank_level + (1.0 - cos (q1 * (t - t1)))
330           * signal_mean, 0, 255);
331     } else {
332       unsigned int bit;
333       unsigned int seq;
334       double d;
335
336       d = t - t3;
337       bit = d * bit_rate;
338       seq = (data >> bit) & 3;
339
340       d -= bit * D;
341       if ((1 == seq || 2 == seq)
342           && fabs (d) < .120e-6) {
343         int level;
344
345         if (1 == seq)
346           level = blank_level + (1.0 + cos (q2 * d))
347               * signal_mean;
348         else
349           level = blank_level + (1.0 - cos (q2 * d))
350               * signal_mean;
351         raw[i] = SATURATE (level, 0, 255);
352       } else if (data & (2 << bit)) {
353         raw[i] = SATURATE (signal_high, 0, 255);
354       } else {
355         raw[i] = SATURATE (blank_level, 0, 255);
356       }
357     }
358
359     t += sample_period;
360   }
361 }
362
363 static void
364 clear_image (uint8_t * p,
365     unsigned int value,
366     unsigned int width, unsigned int height, unsigned int bytes_per_line)
367 {
368   if (width == bytes_per_line) {
369     memset (p, value, height * bytes_per_line);
370   } else {
371     while (height-- > 0) {
372       memset (p, value, width);
373       p += bytes_per_line;
374     }
375   }
376 }
377
378 /**
379  * @param raw Noise will be added to this raw VBI image.
380  * @param sp Describes the raw VBI data in the buffer. @a sp->sampling_format
381  *   must be @c VBI_PIXFMT_Y8 (@c VBI_PIXFMT_YUV420 in libzvbi 0.2.x).
382  *   Note for compatibility in libzvbi 0.2.x vbi_sampling_par is a
383  *   synonym of vbi_raw_decoder, but the (private) decoder fields in
384  *   this structure are ignored.
385  * @param min_freq Minimum frequency of the noise in Hz.
386  * @param max_freq Maximum frequency of the noise in Hz. @a min_freq and
387  *   @a max_freq define the cut off frequency at the half power points
388  *   (gain -3 dB).
389  * @param amplitude Maximum amplitude of the noise, should lie in range
390  *   0 to 256.
391  * @param seed Seed for the pseudo random number generator built into
392  *   this function. Given the same @a seed value the function will add
393  *   the same noise, which can be useful for tests.
394  *
395  * This function adds white noise to a raw VBI image.
396  *
397  * To produce realistic noise @a min_freq = 0, @a max_freq = 5e6 and
398  * @a amplitude = 20 to 50 seems appropriate.
399  *
400  * @returns
401  * FALSE if the @a sp sampling parameters are invalid.
402  *
403  * @since 0.2.26
404  */
405 vbi_bool
406 vbi_raw_add_noise (uint8_t * raw,
407     const vbi_sampling_par * sp,
408     unsigned int min_freq,
409     unsigned int max_freq, unsigned int amplitude, unsigned int seed)
410 {
411   double f0, w0, sn, cs, bw, alpha, a0;
412   float a1, a2, b0, b1, z0, z1, z2;
413   unsigned int n_lines;
414   unsigned long samples_per_line;
415   unsigned long padding;
416   uint32_t seed32;
417
418   assert (NULL != raw);
419   assert (NULL != sp);
420
421   if (unlikely (!_vbi_sampling_par_valid_log (sp, /* log */ NULL)))
422     return FALSE;
423
424   switch (sp->sp_sample_format) {
425     case VBI_PIXFMT_YUV420:
426       break;
427
428     default:
429       return FALSE;
430   }
431
432   if (unlikely (sp->sampling_rate <= 0))
433     return FALSE;
434
435   /* Biquad bandpass filter.
436      http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */
437
438   f0 = ((double) min_freq + max_freq) * 0.5;
439
440   if (f0 <= 0.0)
441     return TRUE;
442
443   w0 = 2 * M_PI * f0 / sp->sampling_rate;
444   vbi_sincos (w0, &sn, &cs);
445   bw = fabs (vbi_log2 (MAX (min_freq, max_freq) / f0));
446   alpha = sn * sinh (log (2) / 2 * bw * w0 / sn);
447   a0 = 1 + alpha;
448   a1 = 2 * cs / a0;
449   a2 = (alpha - 1) / a0;
450   b0 = sn / (2 * a0);
451   b1 = 0;
452
453   if (amplitude > 256)
454     amplitude = 256;
455
456   n_lines = sp->count[0] + sp->count[1];
457
458   if (unlikely (0 == amplitude || 0 == n_lines || 0 == sp->bytes_per_line))
459     return TRUE;
460
461   samples_per_line = sp->bytes_per_line;
462   padding = 0;
463
464   seed32 = seed;
465
466   z1 = 0;
467   z2 = 0;
468
469   do {
470     uint8_t *raw_end = raw + samples_per_line;
471
472     do {
473       int noise;
474
475       /* We use our own simple PRNG to produce
476          predictable results for tests. */
477       seed32 = seed32 * 1103515245u + 12345;
478       noise = ((seed32 / 65536) % (amplitude * 2 + 1))
479           - amplitude;
480
481       z0 = noise + a1 * z1 + a2 * z2;
482       noise = (int) (b0 * (z0 - z2) + b1 * z1);
483       z2 = z1;
484       z1 = z0;
485
486       *raw++ = SATURATE (*raw + noise, 0, 255);
487     } while (raw < raw_end);
488
489     raw += padding;
490   } while (--n_lines > 0);
491
492   return TRUE;
493 }
494
495 static vbi_bool
496 signal_u8 (uint8_t * raw,
497     const vbi_sampling_par * sp,
498     int blank_level,
499     int black_level,
500     int white_level,
501     unsigned int flags,
502     const vbi_sliced * sliced, unsigned int n_sliced_lines, const char *caller)
503 {
504   unsigned int n_scan_lines;
505   unsigned int samples_per_line;
506
507   n_scan_lines = sp->count[0] + sp->count[1];
508   samples_per_line = SAMPLES_PER_LINE (sp);
509
510   clear_image (raw,
511       SATURATE (blank_level, 0, 255),
512       samples_per_line, n_scan_lines, sp->bytes_per_line);
513
514   for (; n_sliced_lines-- > 0; ++sliced) {
515     unsigned int row;
516     uint8_t *raw1;
517
518     if (0 == sliced->line) {
519       goto bounds;
520     } else if (0 != sp->start[1]
521         && sliced->line >= (unsigned int) sp->start[1]) {
522       row = sliced->line - sp->start[1];
523       if (row >= (unsigned int) sp->count[1])
524         goto bounds;
525
526       if (sp->interlaced) {
527         row = row * 2 + !(flags & _VBI_RAW_SWAP_FIELDS);
528       } else if (0 == (flags & _VBI_RAW_SWAP_FIELDS)) {
529         row += sp->count[0];
530       }
531     } else if (0 != sp->start[0]
532         && sliced->line >= (unsigned int) sp->start[0]) {
533       row = sliced->line - sp->start[0];
534       if (row >= (unsigned int) sp->count[0])
535         goto bounds;
536
537       if (sp->interlaced) {
538         row *= 2 + ! !(flags & _VBI_RAW_SWAP_FIELDS);
539       } else if (flags & _VBI_RAW_SWAP_FIELDS) {
540         row += sp->count[0];
541       }
542     } else {
543     bounds:
544       warning (caller, "Sliced line %u out of bounds.", sliced->line);
545       return FALSE;
546     }
547
548     raw1 = raw + row * sp->bytes_per_line;
549
550     switch (sliced->id) {
551       case VBI_SLICED_TELETEXT_A:      /* ok? */
552         signal_teletext (raw1, sp, black_level,
553             /* amplitude */ .7 * (white_level
554                 - black_level),
555             /* bit_rate */ 25 * 625 * 397,
556             /* FRC */ 0xE7,
557             /* payload */ 37,
558             sliced);
559         break;
560
561       case VBI_SLICED_TELETEXT_B_L10_625:
562       case VBI_SLICED_TELETEXT_B_L25_625:
563       case VBI_SLICED_TELETEXT_B:
564         signal_teletext (raw1, sp, black_level,
565             .66 * (white_level - black_level),
566             25 * 625 * 444, 0x27, 42, sliced);
567         break;
568
569       case VBI_SLICED_TELETEXT_C_625:
570         signal_teletext (raw1, sp, black_level,
571             .7 * (white_level - black_level), 25 * 625 * 367, 0xE7, 33, sliced);
572         break;
573
574       case VBI_SLICED_TELETEXT_D_625:
575         signal_teletext (raw1, sp, black_level,
576             .7 * (white_level - black_level), 5642787, 0xA7, 34, sliced);
577         break;
578
579       case VBI_SLICED_CAPTION_625_F1:
580       case VBI_SLICED_CAPTION_625_F2:
581       case VBI_SLICED_CAPTION_625:
582         signal_closed_caption (raw1, sp,
583             blank_level, white_level, flags, 25 * 625 * 32, sliced);
584         break;
585
586       case VBI_SLICED_VPS:
587       case VBI_SLICED_VPS_F2:
588         signal_vps (raw1, sp, black_level, white_level, sliced);
589         break;
590
591       case VBI_SLICED_WSS_625:
592         signal_wss_625 (raw1, sp, black_level, white_level, sliced);
593         break;
594
595       case VBI_SLICED_TELETEXT_B_525:
596         signal_teletext (raw1, sp, black_level,
597             /* amplitude */ .7 * (white_level
598                 - black_level),
599             /* bit_rate */ 5727272,
600             /* FRC */ 0x27,
601             /* payload */ 34,
602             sliced);
603         break;
604
605       case VBI_SLICED_TELETEXT_C_525:
606         signal_teletext (raw1, sp, black_level,
607             .7 * (white_level - black_level), 5727272, 0xE7, 33, sliced);
608         break;
609
610       case VBI_SLICED_TELETEXT_D_525:
611         signal_teletext (raw1, sp, black_level,
612             .7 * (white_level - black_level), 5727272, 0xA7, 34, sliced);
613         break;
614
615       case VBI_SLICED_CAPTION_525_F1:
616       case VBI_SLICED_CAPTION_525_F2:
617       case VBI_SLICED_CAPTION_525:
618         signal_closed_caption (raw1, sp,
619             blank_level, white_level, flags, 30000 * 525 * 32 / 1001, sliced);
620         break;
621
622       default:
623         warning (caller,
624             "Service 0x%08x (%s) not supported.",
625             sliced->id, vbi_sliced_name (sliced->id));
626         return FALSE;
627     }
628   }
629
630   return TRUE;
631 }
632
633 vbi_bool
634 _vbi_raw_vbi_image (uint8_t * raw,
635     unsigned long raw_size,
636     const vbi_sampling_par * sp,
637     int blank_level,
638     int white_level,
639     unsigned int flags, const vbi_sliced * sliced, unsigned int n_sliced_lines)
640 {
641   unsigned int n_scan_lines;
642   unsigned int black_level;
643
644   if (unlikely (!_vbi_sampling_par_valid_log (sp, NULL)))
645     return FALSE;
646
647   n_scan_lines = sp->count[0] + sp->count[1];
648   if (unlikely (n_scan_lines * sp->bytes_per_line > raw_size)) {
649     warning (__FUNCTION__,
650         "(%u + %u lines) * %lu bytes_per_line "
651         "> %lu raw_size.",
652         sp->count[0], sp->count[1],
653         (unsigned long) sp->bytes_per_line, raw_size);
654     return FALSE;
655   }
656
657   if (unlikely (0 != white_level && blank_level > white_level)) {
658     warning (__FUNCTION__,
659         "Invalid blanking %d or peak white level %d.",
660         blank_level, white_level);
661   }
662
663   if (SYSTEM_525 (sp)) {
664     /* Observed value. */
665     const unsigned int peak = 200;      /* 255 */
666
667     if (0 == white_level) {
668       blank_level = (int) (40.0 * peak / 140);
669       black_level = (int) (47.5 * peak / 140);
670       white_level = peak;
671     } else {
672       black_level = (int) (blank_level + 7.5 * (white_level - blank_level));
673     }
674   } else {
675     const unsigned int peak = 200;      /* 255 */
676
677     if (0 == white_level) {
678       blank_level = (int) (43.0 * peak / 140);
679       white_level = peak;
680     }
681
682     black_level = blank_level;
683   }
684
685   return signal_u8 (raw, sp,
686       blank_level, black_level, white_level,
687       flags, sliced, n_sliced_lines, __FUNCTION__);
688 }
689
690 #define RGBA_TO_RGB16(value)                                            \
691         (+(((value) & 0xF8) >> (3 - 0))                                 \
692          +(((value) & 0xFC00) >> (10 - 5))                              \
693          +(((value) & 0xF80000) >> (19 - 11)))
694
695 #define RGBA_TO_RGBA15(value)                                           \
696         (+(((value) & 0xF8) >> (3 - 0))                                 \
697          +(((value) & 0xF800) >> (11 - 5))                              \
698          +(((value) & 0xF80000) >> (19 - 10))                           \
699          +(((value) & 0x80000000) >> (31 - 15)))
700
701 #define RGBA_TO_ARGB15(value)                                           \
702         (+(((value) & 0xF8) >> (3 - 1))                                 \
703          +(((value) & 0xF800) >> (11 - 6))                              \
704          +(((value) & 0xF80000) >> (19 - 11))                           \
705          +(((value) & 0x80000000) >> (31 - 0)))
706
707 #define RGBA_TO_RGBA12(value)                                           \
708         (+(((value) & 0xF0) >> (4 - 0))                                 \
709          +(((value) & 0xF000) >> (12 - 4))                              \
710          +(((value) & 0xF00000) >> (20 - 8))                            \
711          +(((value) & 0xF0000000) >> (28 - 12)))
712
713 #define RGBA_TO_ARGB12(value)                                           \
714         (+(((value) & 0xF0) << -(4 - 12))                               \
715          +(((value) & 0xF000) >> (12 - 8))                              \
716          +(((value) & 0xF00000) >> (20 - 4))                            \
717          +(((value) & 0xF0000000) >> (28 - 0)))
718
719 #define RGBA_TO_RGB8(value)                                             \
720         (+(((value) & 0xE0) >> (5 - 0))                                 \
721          +(((value) & 0xE000) >> (13 - 3))                              \
722          +(((value) & 0xC00000) >> (22 - 6)))
723
724 #define RGBA_TO_BGR8(value)                                             \
725         (+(((value) & 0xE0) >> (5 - 5))                                 \
726          +(((value) & 0xE000) >> (13 - 2))                              \
727          +(((value) & 0xC00000) >> (22 - 0)))
728
729 #define RGBA_TO_RGBA7(value)                                            \
730         (+(((value) & 0xC0) >> (6 - 0))                                 \
731          +(((value) & 0xE000) >> (13 - 2))                              \
732          +(((value) & 0xC00000) >> (22 - 5))                            \
733          +(((value) & 0x80000000) >> (31 - 7)))
734
735 #define RGBA_TO_ARGB7(value)                                            \
736         (+(((value) & 0xC0) >> (6 - 6))                                 \
737          +(((value) & 0xE000) >> (13 - 3))                              \
738          +(((value) & 0xC00000) >> (22 - 1))                            \
739          +(((value) & 0x80000000) >> (31 - 0)))
740
741 #define MST1(d, val, mask) (d) = ((d) & ~(mask)) | ((val) & (mask))
742 #define MST2(d, val, mask) (d) = ((d) & (mask)) | (val)
743
744 #define SCAN_LINE_TO_N(conv, n)                                         \
745 do {                                                                    \
746         for (i = 0; i < samples_per_line; ++i) {                        \
747                 uint8_t *dd = d + i * (n);                              \
748                 unsigned int value = s[i] * 0x01010101;                 \
749                 unsigned int mask = ~pixel_mask;                        \
750                                                                         \
751                 value = conv (value) & pixel_mask;                      \
752                 MST2 (dd[0], value >> 0, mask >> 0);                    \
753                 if (n >= 2)                                             \
754                         MST2 (dd[1], value >> 8, mask >> 8);            \
755                 if (n >= 3)                                             \
756                         MST2 (dd[2], value >> 16, mask >> 16);          \
757                 if (n >= 4)                                             \
758                         MST2 (dd[3], value >> 24, mask >> 24);          \
759         }                                                               \
760 } while (0)
761
762 #define SCAN_LINE_TO_RGB2(conv, endian)                                 \
763 do {                                                                    \
764         for (i = 0; i < samples_per_line; ++i) {                        \
765                 uint8_t *dd = d + i * 2;                                \
766                 unsigned int value = s[i] * 0x01010101;                 \
767                 unsigned int mask;                                      \
768                                                                         \
769                 value = conv (value) & pixel_mask;                      \
770                 mask = ~pixel_mask;                                     \
771                 MST2 (dd[0 + endian], value >> 0, mask >> 0);           \
772                 MST2 (dd[1 - endian], value >> 8, mask >> 8);           \
773         }                                                               \
774 } while (0)
775
776 vbi_bool
777 _vbi_raw_video_image (uint8_t * raw,
778     unsigned long raw_size,
779     const vbi_sampling_par * sp,
780     int blank_level,
781     int black_level,
782     int white_level,
783     unsigned int pixel_mask,
784     unsigned int flags, const vbi_sliced * sliced, unsigned int n_sliced_lines)
785 {
786   unsigned int n_scan_lines;
787   unsigned int samples_per_line;
788   vbi_sampling_par sp8;
789   unsigned int size;
790   uint8_t *buf;
791   uint8_t *s;
792   uint8_t *d;
793
794   if (unlikely (!_vbi_sampling_par_valid_log (sp, NULL)))
795     return FALSE;
796
797   n_scan_lines = sp->count[0] + sp->count[1];
798   if (unlikely (n_scan_lines * sp->bytes_per_line > raw_size)) {
799     warning (__FUNCTION__,
800         "%u + %u lines * %lu bytes_per_line > %lu raw_size.",
801         sp->count[0], sp->count[1],
802         (unsigned long) sp->bytes_per_line, raw_size);
803     return FALSE;
804   }
805
806   if (unlikely (0 != white_level
807           && (blank_level > black_level || black_level > white_level))) {
808     warning (__FUNCTION__,
809         "Invalid blanking %d, black %d or peak "
810         "white level %d.", blank_level, black_level, white_level);
811   }
812
813   switch (sp->sp_sample_format) {
814     case VBI_PIXFMT_YVYU:
815     case VBI_PIXFMT_VYUY:      /* 0xAAUUVVYY */
816       pixel_mask = (+((pixel_mask & 0xFF00) << 8)
817           + ((pixel_mask & 0xFF0000) >> 8)
818           + ((pixel_mask & 0xFF0000FF)));
819       break;
820
821     case VBI_PIXFMT_RGBA24_BE: /* 0xRRGGBBAA */
822       pixel_mask = SWAB32 (pixel_mask);
823       break;
824
825     case VBI_PIXFMT_BGR24_LE:  /* 0x00RRGGBB */
826     case VBI_PIXFMT_BGRA15_LE:
827     case VBI_PIXFMT_BGRA15_BE:
828     case VBI_PIXFMT_ABGR15_LE:
829     case VBI_PIXFMT_ABGR15_BE:
830       pixel_mask = (+((pixel_mask & 0xFF) << 16)
831           + ((pixel_mask & 0xFF0000) >> 16)
832           + ((pixel_mask & 0xFF00FF00)));
833       break;
834
835     case VBI_PIXFMT_BGRA24_BE: /* 0xBBGGRRAA */
836       pixel_mask = (+((pixel_mask & 0xFFFFFF) << 8)
837           + ((pixel_mask & 0xFF000000) >> 24));
838       break;
839
840     default:
841       break;
842   }
843
844   switch (sp->sp_sample_format) {
845     case VBI_PIXFMT_RGB16_LE:
846     case VBI_PIXFMT_RGB16_BE:
847     case VBI_PIXFMT_BGR16_LE:
848     case VBI_PIXFMT_BGR16_BE:
849       pixel_mask = RGBA_TO_RGB16 (pixel_mask);
850       break;
851
852     case VBI_PIXFMT_RGBA15_LE:
853     case VBI_PIXFMT_RGBA15_BE:
854     case VBI_PIXFMT_BGRA15_LE:
855     case VBI_PIXFMT_BGRA15_BE:
856       pixel_mask = RGBA_TO_RGBA15 (pixel_mask);
857       break;
858
859     case VBI_PIXFMT_ARGB15_LE:
860     case VBI_PIXFMT_ARGB15_BE:
861     case VBI_PIXFMT_ABGR15_LE:
862     case VBI_PIXFMT_ABGR15_BE:
863       pixel_mask = RGBA_TO_ARGB15 (pixel_mask);
864       break;
865
866     default:
867       break;
868   }
869
870   if (0 == pixel_mask) {
871     /* Done! :-) */
872     return TRUE;
873   }
874
875   /* ITU-R BT.601 sampling assumed. */
876
877   if (SYSTEM_525 (sp)) {
878     if (0 == white_level) {
879       /* Cutting off the bottom of the signal
880          confuses the vbi_bit_slicer (can't adjust
881          the threshold fast enough), probably other
882          decoders as well. */
883       blank_level = 5;          /* 16 - 40 * 220 / 100; */
884       black_level = 16;
885       white_level = 16 + 219;
886     }
887   } else {
888     if (0 == white_level) {
889       /* Observed values: 30-30-280 (WSS PAL) -? */
890       blank_level = 5;          /* 16 - 43 * 220 / 100; */
891       black_level = 16;
892       white_level = 16 + 219;
893     }
894   }
895
896   sp8 = *sp;
897
898   samples_per_line = SAMPLES_PER_LINE (sp);
899
900   sp8.sampling_format = VBI_PIXFMT_YUV420;
901
902   sp8.bytes_per_line = samples_per_line * 1 /* bpp */ ;
903
904   size = n_scan_lines * samples_per_line;
905   buf = vbi_malloc (size);
906   if (NULL == buf) {
907     error (NULL, "Out of memory.");
908     errno = ENOMEM;
909     return FALSE;
910   }
911
912   if (!signal_u8 (buf, &sp8,
913           blank_level, black_level, white_level,
914           flags, sliced, n_sliced_lines, __FUNCTION__)) {
915     vbi_free (buf);
916     return FALSE;
917   }
918
919   s = buf;
920   d = raw;
921
922   while (n_scan_lines-- > 0) {
923     unsigned int i;
924
925     switch (sp->sp_sample_format) {
926       case VBI_PIXFMT_PAL8:
927       case VBI_PIXFMT_YUV420:
928         for (i = 0; i < samples_per_line; ++i)
929           MST1 (d[i], s[i], pixel_mask);
930         break;
931
932       case VBI_PIXFMT_RGBA24_LE:
933       case VBI_PIXFMT_RGBA24_BE:
934       case VBI_PIXFMT_BGRA24_LE:
935       case VBI_PIXFMT_BGRA24_BE:
936         SCAN_LINE_TO_N (+, 4);
937         break;
938
939       case VBI_PIXFMT_RGB24_LE:
940       case VBI_PIXFMT_BGR24_LE:
941         SCAN_LINE_TO_N (+, 3);
942         break;
943
944       case VBI_PIXFMT_YUYV:
945       case VBI_PIXFMT_YVYU:
946         for (i = 0; i < samples_per_line; i += 2) {
947           uint8_t *dd = d + i * 2;
948           unsigned int uv = (s[i] + s[i + 1] + 1) >> 1;
949
950           MST1 (dd[0], s[i], pixel_mask);
951           MST1 (dd[1], uv, pixel_mask >> 8);
952           MST1 (dd[2], s[i + 1], pixel_mask);
953           MST1 (dd[3], uv, pixel_mask >> 16);
954         }
955         break;
956
957       case VBI_PIXFMT_UYVY:
958       case VBI_PIXFMT_VYUY:
959         for (i = 0; i < samples_per_line; i += 2) {
960           uint8_t *dd = d + i * 2;
961           unsigned int uv = (s[i] + s[i + 1] + 1) >> 1;
962
963           MST1 (dd[0], uv, pixel_mask >> 8);
964           MST1 (dd[1], s[i], pixel_mask);
965           MST1 (dd[2], uv, pixel_mask >> 16);
966           MST1 (dd[3], s[i + 1], pixel_mask);
967         }
968         break;
969
970       case VBI_PIXFMT_RGB16_LE:
971       case VBI_PIXFMT_BGR16_LE:
972         SCAN_LINE_TO_RGB2 (RGBA_TO_RGB16, 0);
973         break;
974
975       case VBI_PIXFMT_RGB16_BE:
976       case VBI_PIXFMT_BGR16_BE:
977         SCAN_LINE_TO_RGB2 (RGBA_TO_RGB16, 1);
978         break;
979
980       case VBI_PIXFMT_RGBA15_LE:
981       case VBI_PIXFMT_BGRA15_LE:
982         SCAN_LINE_TO_RGB2 (RGBA_TO_RGBA15, 0);
983         break;
984
985       case VBI_PIXFMT_RGBA15_BE:
986       case VBI_PIXFMT_BGRA15_BE:
987         SCAN_LINE_TO_RGB2 (RGBA_TO_RGBA15, 1);
988         break;
989
990       case VBI_PIXFMT_ARGB15_LE:
991       case VBI_PIXFMT_ABGR15_LE:
992         SCAN_LINE_TO_RGB2 (RGBA_TO_ARGB15, 0);
993         break;
994
995       case VBI_PIXFMT_ARGB15_BE:
996       case VBI_PIXFMT_ABGR15_BE:
997         SCAN_LINE_TO_RGB2 (RGBA_TO_ARGB15, 1);
998         break;
999
1000     }
1001
1002     s += sp8.bytes_per_line;
1003     d += sp->bytes_per_line;
1004   }
1005
1006   vbi_free (buf);
1007
1008   return TRUE;
1009 }
1010
1011 /**
1012  * @example examples/rawout.c
1013  * Raw VBI output example.
1014  */
1015
1016 /**
1017  * @param raw A raw VBI image will be stored here.
1018  * @param raw_size Size of the @a raw buffer in bytes. The buffer
1019  *   must be large enough for @a sp->count[0] + count[1] lines
1020  *   of @a sp->bytes_per_line each, with @a sp->samples_per_line
1021  *   (in libzvbi 0.2.x @a sp->bytes_per_line) bytes actually written.
1022  * @param sp Describes the raw VBI data to generate. @a sp->sampling_format
1023  *   must be @c VBI_PIXFMT_Y8 (@c VBI_PIXFMT_YUV420 with libzvbi 0.2.x).
1024  *   @a sp->synchronous is ignored. Note for compatibility in libzvbi
1025  *   0.2.x vbi_sampling_par is a synonym of vbi_raw_decoder, but the
1026  *   (private) decoder fields in this structure are ignored.
1027  * @param blank_level The level of the horizontal blanking in the raw
1028  *   VBI image. Must be <= @a white_level.
1029  * @param white_level The peak white level in the raw VBI image. Set to
1030  *   zero to get the default blanking and white level.
1031  * @param swap_fields If @c TRUE the second field will be stored first
1032  *   in the @c raw buffer. Note you can also get an interlaced image
1033  *   by setting @a sp->interlaced to @c TRUE. @a sp->synchronous is
1034  *   ignored.
1035  * @param sliced Pointer to an array of vbi_sliced containing the
1036  *   VBI data to be encoded.
1037  * @param n_sliced_lines Number of elements in the @a sliced array.
1038  *
1039  * This function basically reverses the operation of the vbi_raw_decoder,
1040  * taking sliced VBI data and generating a raw VBI image similar to those
1041  * you would get from raw VBI sampling hardware. The following data services
1042  * are currently supported: All Teletext services, VPS, WSS 625, Closed
1043  * Caption 525 and 625.
1044  *
1045  * The function encodes sliced data as is, e.g. without adding or
1046  * checking parity bits, without checking if the line number is correct
1047  * for the respective data service, or if the signal will fit completely
1048  * in the given space (@a sp->offset and @a sp->samples_per_line at
1049  * @a sp->sampling_rate).
1050  *
1051  * Apart of the payload the generated video signal is invariable and
1052  * attempts to be faithful to related standards. You can only change the
1053  * characteristics of the assumed capture device. Sync pulses and color
1054  * bursts and not generated if the sampling parameters extend to this area.
1055  *
1056  * @note
1057  * This function is mainly intended for testing purposes. It is optimized
1058  * for accuracy, not for speed.
1059  *
1060  * @returns
1061  * @c FALSE if the @a raw_size is too small, if the @a sp sampling
1062  * parameters are invalid, if the signal levels are invalid,
1063  * if the @a sliced array contains unsupported services or line numbers
1064  * outside the @a sp sampling parameters.
1065  *
1066  * @since 0.2.22
1067  */
1068 vbi_bool
1069 vbi_raw_vbi_image (uint8_t * raw,
1070     unsigned long raw_size,
1071     const vbi_sampling_par * sp,
1072     int blank_level,
1073     int white_level,
1074     vbi_bool swap_fields,
1075     const vbi_sliced * sliced, unsigned int n_sliced_lines)
1076 {
1077   return _vbi_raw_vbi_image (raw, raw_size, sp,
1078       blank_level, white_level,
1079       swap_fields ? _VBI_RAW_SWAP_FIELDS : 0, sliced, n_sliced_lines);
1080 }
1081
1082 /**
1083  * @param raw A raw VBI image will be stored here.
1084  * @param raw_size Size of the @a raw buffer in bytes. The buffer
1085  *   must be large enough for @a sp->count[0] + count[1] lines
1086  *   of @a sp->bytes_per_line each, with @a sp->samples_per_line
1087  *   times bytes per pixel (in libzvbi 0.2.x @a sp->bytes_per_line)
1088  *   actually written.
1089  * @param sp Describes the raw VBI data to generate. Note for
1090  *  compatibility in libzvbi 0.2.x vbi_sampling_par is a synonym of
1091  *  vbi_raw_decoder, but the (private) decoder fields in this
1092  *  structure are ignored.
1093  * @param blank_level The level of the horizontal blanking in the raw
1094  *   VBI image. Must be <= @a black_level.
1095  * @param black_level The black level in the raw VBI image. Must be
1096  *   <= @a white_level.
1097  * @param white_level The peak white level in the raw VBI image. Set to
1098  *   zero to get the default blanking, black and white level.
1099  * @param pixel_mask This mask selects which color or alpha channel
1100  *   shall contain VBI data. Depending on @a sp->sampling_format it is
1101  *   interpreted as 0xAABBGGRR or 0xAAVVUUYY. A value of 0x000000FF
1102  *   for example writes data in "red bits", not changing other
1103  *   bits in the @a raw buffer. When the @a sp->sampling_format is a
1104  *   planar YUV the function writes the Y plane only.
1105  * @param swap_fields If @c TRUE the second field will be stored first
1106  *   in the @c raw buffer. Note you can also get an interlaced image
1107  *   by setting @a sp->interlaced to @c TRUE. @a sp->synchronous is
1108  *   ignored.
1109  * @param sliced Pointer to an array of vbi_sliced containing the
1110  *   VBI data to be encoded.
1111  * @param n_sliced_lines Number of elements in the @a sliced array.
1112  *
1113  * Generates a raw VBI image similar to those you get from video
1114  * capture hardware. Otherwise identical to vbi_raw_vbi_image().
1115  *
1116  * @returns
1117  * @c FALSE if the @a raw_size is too small, if the @a sp sampling
1118  * parameters are invalid, if the signal levels are invalid,
1119  * if the @a sliced array contains unsupported services or line numbers
1120  * outside the @a sp sampling parameters.
1121  *
1122  * @since 0.2.22
1123  */
1124 vbi_bool
1125 vbi_raw_video_image (uint8_t * raw,
1126     unsigned long raw_size,
1127     const vbi_sampling_par * sp,
1128     int blank_level,
1129     int black_level,
1130     int white_level,
1131     unsigned int pixel_mask,
1132     vbi_bool swap_fields,
1133     const vbi_sliced * sliced, unsigned int n_sliced_lines)
1134 {
1135   return _vbi_raw_video_image (raw, raw_size, sp,
1136       blank_level, black_level,
1137       white_level, pixel_mask,
1138       swap_fields ? _VBI_RAW_SWAP_FIELDS : 0, sliced, n_sliced_lines);
1139 }
1140
1141 /*
1142 Local variables:
1143 c-set-style: K&R
1144 c-basic-offset: 8
1145 End:
1146 */