Source code upload
[framework/connectivity/libgphoto2.git] / camlibs / largan / lmini / lmini_ccd.c
1 /*
2  * This file convert raw CCD bitmaps to BMP. Used for thumbnails.
3  * Code probably grafted from Largan Lmini SDK.
4  */
5
6 #include <string.h>
7
8 #include "lmini_ccd.h"
9
10
11 static void     fetchstr(int, int, int);
12 static void     dhuf(int);
13 static void     YCbCr2RGB(int *YY, int Cb, int Cr, int w, int h);
14
15 static int _nCcdFactor = 1;
16
17 static char *data;
18
19 static long     out_index;
20 static long     count;
21 static int      in_bit;
22
23 static unsigned char BUFF11[14400];
24
25 static unsigned long in_string;
26 static int      pre_y, pre_cb, pre_cr;
27
28 static int y[7446];
29
30 static const int y_max[10]= {
31         0x0,  0x0,  0x0,  0x6,
32         0xe,  0x1e, 0x3e, 0x7e,
33         0xfe, 0x1fe,
34         };
35
36 static const int y_min[10]= {
37         0x0,  0x0,  0x0,  0x2,
38         0xe,  0x1e, 0x3e, 0x7e,
39         0xfe, 0x1fe,
40         };
41
42 static const int uv_max[12]= {
43         0x0,  0x0,   0x2,   0x6,
44         0xe,  0x1e,  0x3e,  0x7e,
45         0xfe, 0x1fe, 0x3fe, 0x7fe
46         };
47
48 static const int uv_min[12]= {
49         0x0,  0x0,   0x0,   0x6,
50         0xe,  0x1e,  0x3e,  0x7e,
51         0xfe, 0x1fe, 0x3fe, 0x7fe
52         };
53
54
55 /* --------------------------------------------------------------------------- */
56 void largan_ccd2dib(char *pData, char *pDib, long dwDibRowBytes, int nCcdFactor)
57 {
58     int i, j, w, h;
59     int YY[4], Cb, Cr;
60
61     _nCcdFactor = nCcdFactor;
62
63     data = pData;
64
65 /************************************************/
66
67     Cb = 0;
68     Cr = 0;
69
70     pre_y = 0;
71     pre_cb = 0;
72     pre_cr = 0;
73
74     in_string = (*data << 8) | *(data + 1);
75
76     in_bit = 16;
77     count = 2;
78     out_index = 0;
79 /******************************************************/
80
81     for (j = 0; j < 1200; j++)
82 {
83         for (i = 0; i < 4; i++)
84             dhuf(0);
85
86         dhuf(1);
87         dhuf(2);
88         }
89
90     /* printf("Now process the DC term to R G B transfer !\n"); */
91
92     for (h = 0; h < 30; h++) /* mini size height = 30 x 2 */
93         {
94         for (w = 0; w < 40; w++)
95             {
96             for (i = 0; i < 6; i++)
97                 {
98                 int     k = i + w * 6 + h * 240;
99
100                 if (i < 4)
101                     YY[i] = y[k] * _nCcdFactor;
102                 else if (i == 4)
103                     Cb = y[k] * _nCcdFactor;
104                 else if (i == 5)
105                     Cr = y[k] * _nCcdFactor;
106                 }
107
108             YCbCr2RGB(YY, Cb, Cr, w, h);
109             }
110         }
111
112     for (i = 0, j = 0; i < 60; i++, j += 240)
113         {
114         memcpy (pDib, &BUFF11[j], 240);
115         pDib -= dwDibRowBytes;
116         }
117 }
118
119 /* --------------------------------------------------------------------------- */
120 static void YCbCr2RGB(int *YY, int Cb, int Cr, int w, int h)
121 {
122     int     i;
123     double  B,G,R;
124     double  c2 = 1.7753, c3 = -0.0015;
125     double  c5 = -0.3443, c6 = -0.7137;
126     double  c8 = -0.0009, c9 = 1.4017;
127
128     for (i = 0; i < 2; i++)
129         {
130         int     k = 3 * i + w * 6 + h * 480;
131
132         B = ((double) YY[i] + 128.0 + c2 * Cb + c3 * Cr) + 0.5;
133         if (B > 255)
134            B = 255;
135         else if (B < 0)
136            B = 0;
137         BUFF11[k] = (unsigned char) B;
138
139         G = ((double) YY[i] + 128.0 + c5 * Cb + c6 * Cr) + 0.5;
140         if (G > 255)
141            G = 255;
142         else if (G < 0)
143            G = 0;
144         BUFF11[k + 1] = (unsigned char) G;
145
146         R = ((double) YY[i] + 128.0 + c8 * Cb + c9 * Cr) + 0.5;
147         if (R > 255)
148            R = 255;
149         else if (R < 0)
150            R = 0;
151         BUFF11[k + 2] = (unsigned char) R;
152         }
153
154     for (i = 0; i < 2; i++)
155         {
156         int     k = 3 * i + w * 6 + h * 480 + 240;
157
158         B = ((double) YY[i + 2] + 128.0 + c2 * Cb + c3 * Cr) + 0.5;
159         if (B > 255)
160            B = 255;
161         else if (B < 0)
162            B = 0;
163         BUFF11[k] = (unsigned char) B;
164
165         G = ((double) YY[i + 2] + 128.0 + c5 * Cb + c6 * Cr) + 0.5;
166         if (G > 255)
167            G = 255;
168         else if (G < 0)
169            G = 0;
170         BUFF11[k + 1] = (unsigned char) G;
171
172         R = ((double) YY[i + 2] + 128.0 + c8 * Cb + c9 * Cr) + 0.5;
173         if (R > 255)
174            R = 255;
175         else if (R < 0)
176            R = 0;
177         BUFF11[k + 2] = (unsigned char) R;
178         }
179 }
180
181 /* --------------------------------------------------------------------------- */
182 static void dhuf(int flag)
183 {
184     int     code_leng, val_leng;
185     int    temp_s;
186     int    temp;
187     int     temp1;
188
189     code_leng = 2;
190     val_leng = 0;
191     temp_s = (int) in_string;
192     temp_s >>= 14;
193
194     if (flag == 0)
195         {
196         while (((int)temp_s > y_max[code_leng]) || ((int)temp_s < y_min[code_leng]))
197             {
198             code_leng++;
199             temp_s = (int) in_string;
200             temp_s >>= (16 - code_leng);
201             }
202         }
203     else
204         {
205         while (((int)temp_s > uv_max[code_leng]) || ((int)temp_s < uv_min[code_leng]))
206             {
207             code_leng++;
208             temp_s = (int) in_string;
209             temp_s >>= (16 - code_leng);
210             }
211         }
212
213     temp = (int) in_string;
214     temp >>= (16 - code_leng);
215     temp1 = (int) temp;
216
217     fetchstr(code_leng, 0, flag);
218
219     if (flag == 0)
220         {
221         if (code_leng == 3)
222             {
223             switch (temp1)
224                 {
225                 case 2 : val_leng = 1; break;
226                 case 3 : val_leng = 2; break;
227                 case 4 : val_leng = 3; break;
228                 case 5 : val_leng = 4; break;
229                 case 6 : val_leng = 5; break;
230                 default: break;
231                 }
232             }
233         else if (code_leng == 2)
234             val_leng = 0;
235         else
236             val_leng = code_leng + 2;
237         }
238     else
239         {
240         if (code_leng == 2)
241             {
242             switch (temp1)
243                 {
244                 case 0 : val_leng = 0; break;
245                 case 1 : val_leng = 1; break;
246                 case 2 : val_leng = 2; break;
247                 default: break;
248                 }
249             }
250         else
251             val_leng = code_leng;
252         }
253
254     fetchstr(val_leng, 1, flag);
255 }
256
257
258 /* --------------------------------------------------------------------------- */
259 static void fetchstr(int shift_bit, int val_flag, int flag)
260 {
261     int    temp_val;
262     int     value1, value2;
263     int     temp = 0;
264
265     temp_val = (int) in_string;
266     temp_val >>= (16 - shift_bit);
267     in_string <<= shift_bit;
268     in_bit -= shift_bit;
269
270     if ((val_flag == 1) && (shift_bit == 0))
271         {
272         if (flag == 0)
273             temp = pre_y;
274         else if (flag == 1)
275             temp = pre_cb;
276         else if (flag == 2)
277             temp = pre_cr;
278
279         y[out_index] = temp;
280         out_index++;
281         }
282
283     if ((val_flag == 1) && (shift_bit != 0))
284         {
285         value1 = (int) temp_val;
286         value2 = value1;
287         value2 &= (1 << (shift_bit - 1));
288
289         if (value2 != 0)
290             {
291             if (flag == 0)
292                 {
293                 pre_y += value1;
294                 temp = pre_y;
295                 }
296             else if (flag == 1)
297                 {
298                 pre_cb += value1;
299                 temp = pre_cb;
300                 }
301             else if (flag == 2)
302                 {
303                 pre_cr += value1;
304                 temp=pre_cr;
305                 }
306
307             y[out_index] = temp;
308             out_index++;
309             }
310         else
311             {
312             value1++;
313             value1 = -value1;
314
315             value1 &= ((1 << shift_bit) - 1);
316             value1 = -value1;
317
318             if (flag == 0)
319                 {
320                 pre_y += value1;
321                 temp = pre_y;
322                 }
323             else if (flag == 1)
324                 {
325                 pre_cb += value1;
326                 temp = pre_cb;
327                 }
328             else if (flag == 2)
329                 {
330                 pre_cr +=value1;
331                 temp = pre_cr;
332                 }
333
334             y[out_index] = temp;
335             out_index++;
336             }
337         }
338
339     while (in_bit <= 8)
340         {
341         in_string = in_string | (*(data + count) << (8 - in_bit));
342         in_bit += 8;
343         count++;
344         }
345 }
346