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

Last change on this file since 614 was 490, checked in by campagne, 14 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.