source: BAORadio/libindi/v1/libs/webcam/ccvt_misc.c@ 689

Last change on this file since 689 was 490, checked in by campagne, 15 years ago

import libindi (JEC)

File size: 11.9 KB
Line 
1/* CCVT: ColourConVerT: simple library for converting colourspaces
2 Copyright (C) 2002 Nemosoft Unv.
3 Email:athomas@nemsoft.co.uk
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19 For questions, remarks, patches, etc. for this program, the author can be
20 reached at nemosoft@smcc.demon.nl.
21*/
22
23/* This file contains CCVT functions that aren't available in assembly yet
24 (or are not worth programming)
25 */
26
27/*
28 * $Log$
29 * Revision 1.2 2005/04/29 16:51:20 mutlaqja
30 * Adding initial support for Video 4 Linux 2 drivers. This mean that KStars can probably control Meade Lunar Planetary Imager (LPI). V4L2 requires a fairly recent kernel (> 2.6.9) and many drivers don't fully support it yet. It will take sometime. KStars still supports V4L1 and will continue so until V4L1 is obselete. Please test KStars video drivers if you can. Any comments welcomed.
31 *
32 * CCMAIL: kstars-devel@kde.org
33 *
34 * Revision 1.1 2004/06/26 23:12:03 mutlaqja
35 * Hopefully this will fix compile issues on 64bit archs, and FreeBSD, among others. The assembly code is replaced with a more portable, albeit slower C implementation. I imported the videodev.h header after cleaning it for user space.
36 *
37 * Anyone who has problems compiling this, please report the problem to kstars-devel@kde.org
38 *
39 * I noticed one odd thing after updating my kdelibs, the LEDs don't change color when state is changed. Try that by starting any INDI device, and hit connect, if the LED turns to yellow and back to grey then it works fine, otherwise, we've got a problem.
40 *
41 * CCMAIL: kstars-devel@kde.org
42 *
43 * Revision 1.7 2003/01/02 04:10:19 nemosoft
44 * Adding ''upside down" conversion to rgb/bgr routines
45 *
46 * Revision 1.6 2002/12/03 23:29:11 nemosoft
47 * *** empty log message ***
48 *
49 * Revision 1.5 2002/12/03 23:27:41 nemosoft
50 * fixing log messages (gcc 3.2 complaining)
51 *
52 Revision 1.4 2002/12/03 22:29:07 nemosoft
53 Fixing up FTP stuff and some video
54
55 Revision 1.3 2002/11/03 22:46:25 nemosoft
56 Adding various RGB to RGB functions.
57 Adding proper copyright header too.
58 */
59
60
61#include "ccvt.h"
62#include "ccvt_types.h"
63#include <stdlib.h>
64
65static float RGBYUV02990[256], RGBYUV05870[256], RGBYUV01140[256];
66static float RGBYUV01684[256], RGBYUV03316[256];
67static float RGBYUV04187[256], RGBYUV00813[256];
68
69void InitLookupTable(void);
70
71
72/* YUYV: two Y's and one U/V */
73void ccvt_yuyv_rgb32(int width, int height, const void *src, void *dst)
74{
75 width=width; height=height; src=src; dst=dst;
76
77}
78
79
80void ccvt_yuyv_bgr32(int width, int height, const void *src, void *dst)
81{
82 const unsigned char *s;
83 PIXTYPE_bgr32 *d;
84 int l, c;
85 int r, g, b, cr, cg, cb, y1, y2;
86
87 l = height;
88 s = src;
89 d = dst;
90 while (l--) {
91 c = width >> 2;
92 while (c--) {
93 y1 = *s++;
94 cb = ((*s - 128) * 454) >> 8;
95 cg = (*s++ - 128) * 88;
96 y2 = *s++;
97 cr = ((*s - 128) * 359) >> 8;
98 cg = (cg + (*s++ - 128) * 183) >> 8;
99
100 r = y1 + cr;
101 b = y1 + cb;
102 g = y1 - cg;
103 SAT(r);
104 SAT(g);
105 SAT(b);
106 d->b = b;
107 d->g = g;
108 d->r = r;
109 d++;
110 r = y2 + cr;
111 b = y2 + cb;
112 g = y2 - cg;
113 SAT(r);
114 SAT(g);
115 SAT(b);
116 d->b = b;
117 d->g = g;
118 d->r = r;
119 d++;
120 }
121 }
122
123}
124
125void ccvt_yuyv_420p(int width, int height, const void *src, void *dsty, void *dstu, void *dstv)
126{
127 int n, l, j;
128 const unsigned char *s1, *s2;
129 unsigned char *dy, *du, *dv;
130
131 dy = (unsigned char *)dsty;
132 du = (unsigned char *)dstu;
133 dv = (unsigned char *)dstv;
134 s1 = (unsigned char *)src;
135 s2 = s1; /* keep pointer */
136 n = width * height;
137 for (; n > 0; n--) {
138 *dy = *s1;
139 dy++;
140 s1 += 2;
141 }
142
143 /* Two options here: average U/V values, or skip every second row */
144 s1 = s2; /* restore pointer */
145 s1++; /* point to U */
146 for (l = 0; l < height; l += 2) {
147 s2 = s1 + width * 2; /* odd line */
148 for (j = 0; j < width; j += 2) {
149 *du = (*s1 + *s2) / 2;
150 du++;
151 s1 += 2;
152 s2 += 2;
153 *dv = (*s1 + *s2) / 2;
154 dv++;
155 s1 += 2;
156 s2 += 2;
157 }
158 s1 = s2;
159 }
160}
161
162void bayer2rgb24(unsigned char *dst, unsigned char *src, long int WIDTH, long int HEIGHT)
163{
164 long int i;
165 unsigned char *rawpt, *scanpt;
166 long int size;
167
168 rawpt = src;
169 scanpt = dst;
170 size = WIDTH*HEIGHT;
171
172 for ( i = 0; i < size; i++ ) {
173 if ( (i/WIDTH) % 2 == 0 ) {
174 if ( (i % 2) == 0 ) {
175 /* B */
176 if ( (i > WIDTH) && ((i % WIDTH) > 0) ) {
177 *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+
178 *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4; /* R */
179 *scanpt++ = (*(rawpt-1)+*(rawpt+1)+
180 *(rawpt+WIDTH)+*(rawpt-WIDTH))/4; /* G */
181 *scanpt++ = *rawpt; /* B */
182 } else {
183 /* first line or left column */
184 *scanpt++ = *(rawpt+WIDTH+1); /* R */
185 *scanpt++ = (*(rawpt+1)+*(rawpt+WIDTH))/2; /* G */
186 *scanpt++ = *rawpt; /* B */
187 }
188 } else {
189 /* (B)G */
190 if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) ) {
191 *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2; /* R */
192 *scanpt++ = *rawpt; /* G */
193 *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* B */
194 } else {
195 /* first line or right column */
196 *scanpt++ = *(rawpt+WIDTH); /* R */
197 *scanpt++ = *rawpt; /* G */
198 *scanpt++ = *(rawpt-1); /* B */
199 }
200 }
201 } else {
202 if ( (i % 2) == 0 ) {
203 /* G(R) */
204 if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) ) {
205 *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* R */
206 *scanpt++ = *rawpt; /* G */
207 *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2; /* B */
208 } else {
209 /* bottom line or left column */
210 *scanpt++ = *(rawpt+1); /* R */
211 *scanpt++ = *rawpt; /* G */
212 *scanpt++ = *(rawpt-WIDTH); /* B */
213 }
214 } else {
215 /* R */
216 if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) ) {
217 *scanpt++ = *rawpt; /* R */
218 *scanpt++ = (*(rawpt-1)+*(rawpt+1)+
219 *(rawpt-WIDTH)+*(rawpt+WIDTH))/4; /* G */
220 *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+
221 *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4; /* B */
222 } else {
223 /* bottom line or right column */
224 *scanpt++ = *rawpt; /* R */
225 *scanpt++ = (*(rawpt-1)+*(rawpt-WIDTH))/2; /* G */
226 *scanpt++ = *(rawpt-WIDTH-1); /* B */
227 }
228 }
229 }
230 rawpt++;
231 }
232
233}
234
235/************************************************************************
236 *
237 * int RGB2YUV (int x_dim, int y_dim, void *bmp, YUV *yuv)
238 *
239 * Purpose : It takes a 24-bit RGB bitmap and convert it into
240 * YUV (4:2:0) format
241 *
242 * Input : x_dim the x dimension of the bitmap
243 * y_dim the y dimension of the bitmap
244 * bmp pointer to the buffer of the bitmap
245 * yuv pointer to the YUV structure
246 *
247 * Output : 0 OK
248 * 1 wrong dimension
249 * 2 memory allocation error
250 *
251 * Side Effect :
252 * None
253 *
254 * Date : 09/28/2000
255 *
256 * Contacts:
257 *
258 * Adam Li
259 *
260 * DivX Advance Research Center <darc@projectmayo.com>
261 *
262 ************************************************************************/
263
264int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip)
265{
266 static int init_done = 0;
267
268 long i, j, size;
269 unsigned char *r, *g, *b;
270 unsigned char *y, *u, *v;
271 unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv;
272 unsigned char *y_buffer, *u_buffer, *v_buffer;
273 unsigned char *sub_u_buf, *sub_v_buf;
274
275 if (init_done == 0)
276 {
277 InitLookupTable();
278 init_done = 1;
279 }
280
281 /* check to see if x_dim and y_dim are divisible by 2*/
282 if ((x_dim % 2) || (y_dim % 2)) return 1;
283 size = x_dim * y_dim;
284
285 /* allocate memory*/
286 y_buffer = (unsigned char *)y_out;
287 sub_u_buf = (unsigned char *)u_out;
288 sub_v_buf = (unsigned char *)v_out;
289 u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
290 v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
291 if (!(u_buffer && v_buffer))
292 {
293 if (u_buffer) free(u_buffer);
294 if (v_buffer) free(v_buffer);
295 return 2;
296 }
297
298 b = (unsigned char *)bmp;
299 y = y_buffer;
300 u = u_buffer;
301 v = v_buffer;
302
303 /* convert RGB to YUV*/
304 if (!flip) {
305 for (j = 0; j < y_dim; j ++)
306 {
307 y = y_buffer + (y_dim - j - 1) * x_dim;
308 u = u_buffer + (y_dim - j - 1) * x_dim;
309 v = v_buffer + (y_dim - j - 1) * x_dim;
310
311 for (i = 0; i < x_dim; i ++) {
312 g = b + 1;
313 r = b + 2;
314 *y = (unsigned char)( RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
315 *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2 + 128);
316 *v = (unsigned char)( (*r)/2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
317 b += 3;
318 y ++;
319 u ++;
320 v ++;
321 }
322 }
323 } else {
324 for (i = 0; i < size; i++)
325 {
326 g = b + 1;
327 r = b + 2;
328 *y = (unsigned char)( RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
329 *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2 + 128);
330 *v = (unsigned char)( (*r)/2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
331 b += 3;
332 y ++;
333 u ++;
334 v ++;
335 }
336 }
337
338 /* subsample UV*/
339 for (j = 0; j < y_dim/2; j ++)
340 {
341 psu = sub_u_buf + j * x_dim / 2;
342 psv = sub_v_buf + j * x_dim / 2;
343 pu1 = u_buffer + 2 * j * x_dim;
344 pu2 = u_buffer + (2 * j + 1) * x_dim;
345 pv1 = v_buffer + 2 * j * x_dim;
346 pv2 = v_buffer + (2 * j + 1) * x_dim;
347 for (i = 0; i < x_dim/2; i ++)
348 {
349 *psu = (*pu1 + *(pu1+1) + *pu2 + *(pu2+1)) / 4;
350 *psv = (*pv1 + *(pv1+1) + *pv2 + *(pv2+1)) / 4;
351 psu ++;
352 psv ++;
353 pu1 += 2;
354 pu2 += 2;
355 pv1 += 2;
356 pv2 += 2;
357 }
358 }
359
360 free(u_buffer);
361 free(v_buffer);
362
363 return 0;
364}
365
366
367void InitLookupTable()
368{
369 int i;
370
371 for (i = 0; i < 256; i++) RGBYUV02990[i] = (float)0.2990 * i;
372 for (i = 0; i < 256; i++) RGBYUV05870[i] = (float)0.5870 * i;
373 for (i = 0; i < 256; i++) RGBYUV01140[i] = (float)0.1140 * i;
374 for (i = 0; i < 256; i++) RGBYUV01684[i] = (float)0.1684 * i;
375 for (i = 0; i < 256; i++) RGBYUV03316[i] = (float)0.3316 * i;
376 for (i = 0; i < 256; i++) RGBYUV04187[i] = (float)0.4187 * i;
377 for (i = 0; i < 256; i++) RGBYUV00813[i] = (float)0.0813 * i;
378}
379
380
381/* RGB/BGR to RGB/BGR */
382
383#define RGBBGR_BODY24(TIN, TOUT) \
384void ccvt_ ## TIN ## _ ## TOUT (int width, int height, const void *const src, void *dst) \
385{ \
386 const PIXTYPE_ ## TIN *in = src; \
387 PIXTYPE_ ## TOUT *out = dst; \
388 int l, c, stride = 0; \
389 \
390 stride = width; \
391 out += ((height - 1) * width); \
392 stride *= 2; \
393 for (l = 0; l < height; l++) { \
394 for (c = 0; c < width; c++) { \
395 out->r = in->r; \
396 out->g = in->g; \
397 out->b = in->b; \
398 in++; \
399 out++; \
400 } \
401 out -= stride; \
402 } \
403}
404
405#define RGBBGR_BODY32(TIN, TOUT) \
406void ccvt_ ## TIN ## _ ## TOUT (int width, int height, const void *const src, void *dst) \
407{ \
408 const PIXTYPE_ ## TIN *in = src; \
409 PIXTYPE_ ## TOUT *out = dst; \
410 int l, c, stride = 0; \
411 \
412 stride = width;\
413 out += ((height - 1) * width); \
414 stride *= 2; \
415 for (l = 0; l < height; l++) { \
416 for (c = 0; c < width; c++) { \
417 out->r = in->r; \
418 out->g = in->g; \
419 out->b = in->b; \
420 out->z = 0; \
421 in++; \
422 out++; \
423 } \
424 out -= stride; \
425 } \
426}
427
428RGBBGR_BODY32(bgr24, bgr32)
429RGBBGR_BODY32(bgr24, rgb32)
430RGBBGR_BODY32(rgb24, bgr32)
431RGBBGR_BODY32(rgb24, rgb32)
432
433RGBBGR_BODY24(bgr32, bgr24)
434RGBBGR_BODY24(bgr32, rgb24)
435RGBBGR_BODY24(rgb32, bgr24)
436RGBBGR_BODY24(rgb32, rgb24)
Note: See TracBrowser for help on using the repository browser.