File: yuv2rgb.c

package info (click to toggle)
zapping 0.10~cvs6-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 9,856 kB
  • ctags: 11,841
  • sloc: ansic: 111,154; asm: 11,770; sh: 9,812; xml: 2,742; makefile: 1,283; perl: 488
file content (173 lines) | stat: -rw-r--r-- 4,294 bytes parent folder | download | duplicates (6)
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
/*
 * yuv2rgb.c, Software YUV <-> RGB coverter
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdlib.h>
#include <stdio.h>

#include <glib.h>
#include "common/math.h"
#include "csconvert.h"
#include "yuv2rgb.h"
#include "gen_conv.h"
#include "zmisc.h"
#include "libtv/cpu.h"
#include "globals.h"

#define MODE_RGB  0x1
#define MODE_BGR  0x2

/* Won't run on x86-64. */
#if defined (HAVE_X86) && defined (CAN_COMPILE_SSE)

typedef void
packed2planar_fn		(uint8_t *py,
				 uint8_t *pu,
				 uint8_t *pv,
				 const uint8_t *image,
				 int h_size,
				 int v_size,
				 unsigned int y_stride,
				 unsigned int uv_stride,
				 unsigned int rgb_stride);
typedef void
packed2packed_fn		(uint8_t *dst,
				 const uint8_t *src,
				 int h_size,
				 int v_size,
				 unsigned int dest_stride,
				 unsigned int src_stride);

static void *
rgb_to_yuv420_function		(tv_pixfmt		pixfmt)
{
  if (cpu_features & CPU_FEATURE_MMX)
    switch (pixfmt)
      {
      case TV_PIXFMT_RGBA16_LE:	return mmx_rgb5551_yuv420;
      case TV_PIXFMT_BGRA16_LE:	return mmx_bgr5551_yuv420;
      case TV_PIXFMT_RGB16_LE:	return mmx_rgb565_yuv420;
      case TV_PIXFMT_BGR16_LE:	return mmx_bgr565_yuv420;
      case TV_PIXFMT_RGB24_LE:	return mmx_rgb24_yuv420;
      case TV_PIXFMT_BGR24_LE:	return mmx_bgr24_yuv420;
      case TV_PIXFMT_RGBA32_LE:	return mmx_rgb32_yuv420;
      case TV_PIXFMT_BGRA32_LE:	return mmx_bgr32_yuv420;
      default:			break;
      }

  return NULL;
}

static void *
rgb_to_yuyv_function		(tv_pixfmt		pixfmt)
{
  if (cpu_features & CPU_FEATURE_MMX)
    switch (pixfmt)
      {
      case TV_PIXFMT_RGBA16_LE:	return mmx_rgb5551_yuyv;
      case TV_PIXFMT_BGRA16_LE:	return mmx_bgr5551_yuyv;
      case TV_PIXFMT_RGB16_LE:	return mmx_rgb565_yuyv;
      case TV_PIXFMT_BGR16_LE:	return mmx_bgr565_yuyv;
      case TV_PIXFMT_RGB24_LE:	return mmx_rgb24_yuyv;
      case TV_PIXFMT_BGR24_LE:	return mmx_bgr24_yuyv;
      case TV_PIXFMT_RGBA32_LE:	return mmx_rgb32_yuyv;
      case TV_PIXFMT_BGRA32_LE:	return mmx_bgr32_yuyv;
      default:			break;
      }

  return NULL;
}

static void
packed2planar_proxy		(void *			dst_image,
				 const tv_image_format *dst_format,
				 const void *		src_image,
				 const tv_image_format *src_format,
				 const void *		user_data)
{
  packed2planar_fn *f = user_data;

  f ((uint8_t *) dst_image + dst_format->offset[0],
     (uint8_t *) dst_image + dst_format->offset[1],
     (uint8_t *) dst_image + dst_format->offset[2],
     (const uint8_t *) src_image + src_format->offset[0],
     MIN (dst_format->width, src_format->width),
     MIN (dst_format->height, src_format->height),
     dst_format->bytes_per_line[0],
     dst_format->bytes_per_line[1],
     src_format->bytes_per_line[0]);
}

static void
packed2packed_proxy		(void *			dst_image,
				 const tv_image_format *dst_format,
				 const void *		src_image,
				 const tv_image_format *src_format,
				 const void *		user_data)
{
  packed2packed_fn *f = user_data;

  f ((uint8_t *) dst_image + dst_format->offset[0],
     (const uint8_t *) src_image + src_format->offset[0],
     MIN (dst_format->width, src_format->width),
     MIN (dst_format->height, src_format->height),
     dst_format->bytes_per_line[0],
     src_format->bytes_per_line[0]);
}

static void
mmx_register_converters		(void)
{
  static tv_pixfmt pixfmts [] = {
    TV_PIXFMT_RGBA16_LE,
    TV_PIXFMT_BGRA16_LE,
    TV_PIXFMT_RGB16_LE,
    TV_PIXFMT_BGR16_LE,
    TV_PIXFMT_RGB24_LE,
    TV_PIXFMT_BGR24_LE,
    TV_PIXFMT_RGBA32_LE,
    TV_PIXFMT_BGRA32_LE,
  };
  unsigned int i;
  void *p;

  for (i = 0; i < N_ELEMENTS (pixfmts); ++i)
    {
      if ((p = rgb_to_yuv420_function (pixfmts[i])))
	{
	  register_converter ("-yuv420",
			      pixfmts[i], TV_PIXFMT_YUV420,
			      packed2planar_proxy, p);
	  register_converter ("-yvu420",
			      pixfmts[i], TV_PIXFMT_YVU420,
			      packed2planar_proxy, p);
	}

      if ((p = rgb_to_yuyv_function (pixfmts[i])))
	register_converter ("-yuyv",
			    pixfmts[i], TV_PIXFMT_YUYV,
			    packed2packed_proxy, p);
    }
}

#else /* !(HAVE_X86 && CAN_COMPILE_SSE) */

static void
mmx_register_converters (void)
{
}

#endif /* !(HAVE_X86 && CAN_COMPILE_SSE) */

void startup_yuv2rgb (void) 
{
  mmx_register_converters ();
}

void shutdown_yuv2rgb (void)
{
}