This source file includes following definitions.
- curve_free_data
- curve_load_data
- curve_init_mode
- curve_set_mode
- curve_set_file
- curveRGB_apply
- curveL_apply
- curve_apply
- _module_can_unload
1 #include "camera_info.h"
2 #include "conf.h"
3 #include "shooting.h"
4 #include "raw.h"
5 #include "gui_lang.h"
6
7 #include "curves.h"
8 #include "module_def.h"
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 unsigned short *curve_data = NULL;
33
34 #define CURVE_SIZE 1024
35 #define CURVE_BYTES (CURVE_SIZE*sizeof(unsigned short))
36
37 #define BLACK 32
38 #define LIM( a ) (((a)>1023) ? 1023: a )
39 #define RBLACK( a ) (((a)>BLACK) ? ((a)-BLACK) : 0)
40
41 #define CURVE0( a, b ) (((a) * curve0[b]) >> 12)
42 #define CURVE1( a, b ) (((a) * curve1[b]) >> 12)
43 #define CURVE2( a, b ) (((a) * curve2[b]) >> 12)
44 #define CURVE3( a, b ) (((a) * curve3[b]) >> 12)
45
46 typedef enum {
47 CURVE_NONE,
48 CURVE_CUSTOM,
49 CURVE_SYSTEM,
50 }CURVE_TYPE;
51
52 CURVE_TYPE current_curve_type = CURVE_NONE;
53
54 static void curve_free_data() {
55 free(curve_data);
56 curve_data = NULL;
57 current_curve_type = CURVE_NONE;
58 }
59
60
61 static int curve_load_data(const char *name,CURVE_TYPE curve_type) {
62 unsigned size;
63 FILE *fd;
64 if (current_curve_type != curve_type) {
65 curve_free_data();
66 }
67
68 if (curve_type == CURVE_NONE) {
69 return 1;
70 }
71
72 if(!name || !*name) {
73 curve_free_data();
74 return 0;
75 }
76
77 if( curve_type == CURVE_CUSTOM ) {
78 size = CURVE_BYTES*4;
79 }
80 else {
81 size = CURVE_BYTES*2;
82 }
83
84 if (!curve_data)
85 curve_data=malloc(size);
86
87 if(!curve_data) {
88 curve_free_data();
89 return 0;
90 }
91 fd = fopen(name, "r+b");
92 if (!fd) {
93 curve_free_data();
94 return 0;
95 }
96 fread(curve_data, 1, size, fd);
97 fclose(fd);
98 current_curve_type = curve_type;
99 return 1;
100 }
101
102 void curve_init_mode() {
103 switch(conf.curve_enable) {
104 case 1:
105 curve_load_data(conf.curve_file,CURVE_CUSTOM);
106 break;
107 case 2:
108 case 3:
109 case 4:
110 curve_load_data("A/CHDK/SYSCURVES.CVF",CURVE_SYSTEM);
111 break;
112 default:
113 conf.curve_enable = 0;
114 case 0:
115 curve_free_data();
116 }
117 }
118
119 void curve_set_mode(int value) {
120 if((value>=0) && (value<=4)) conf.curve_enable=value;
121 curve_init_mode();
122 }
123
124 void curve_set_file(const char *s) {
125 int l;
126 if(s) {
127 if(strncmp(s,"A/",2)==0) strncpy(conf.curve_file,s,99);
128 else {
129 l=strlen(CURVE_DIR);
130 strcpy(conf.curve_file,CURVE_DIR);
131 conf.curve_file[l]='/';
132 strncpy(&conf.curve_file[l+1],s,99-l-1);
133 }
134 conf.curve_file[99]=0x0;
135 curve_init_mode();
136 }
137 }
138
139
140 void curveRGB_apply() {
141 int i,j;
142 unsigned short pixVal0, pixVal1, pixVal2;
143 unsigned char *src;
144
145 unsigned short *curve0 = curve_data;
146 unsigned short *curve1 = curve0 + CURVE_SIZE;
147 unsigned short *curve2 = curve1 + CURVE_SIZE;
148 unsigned short *curve3 = curve2 + CURVE_SIZE;
149
150 if (current_curve_type != CURVE_CUSTOM)
151 return;
152
153
154 src = (unsigned char *) get_raw_image_addr();
155
156
157
158 for (i=camera_sensor.raw_rows; i;i-=2){
159
160 for (j=camera_sensor.raw_rowpix; j; j-=8, src+=10){
161 pixVal0=((0x3fc&(((unsigned short)(src[1]))<<2)) | (src[0] >> 6));
162 pixVal1=((0x3f0&(((unsigned short)(src[0]))<<4)) | (src[3] >> 4));
163 pixVal0 = curve0[pixVal0];
164 pixVal1 = curve1[pixVal1];
165 *(src+1) = (unsigned char) ((pixVal0>>2));
166 *src = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
167
168 pixVal2=((0x3c0&(((unsigned short)(src[3]))<<6)) | (src[2] >> 2));
169 pixVal0=((0x300&(((unsigned short)(src[2]))<<8)) | (src[5]));
170 pixVal2 = curve0[pixVal2];
171 pixVal0 = curve1[pixVal0];
172 *(src+3) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
173 *(src+2) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
174 *(src+5) = (unsigned char) ((pixVal0));
175
176 pixVal0=((0x3fc&(((unsigned short)(src[4]))<<2)) | (src[7] >> 6));
177 pixVal1=((0x3f0&(((unsigned short)(src[7]))<<4)) | (src[6] >> 4));
178 pixVal0 = curve0[pixVal0];
179 pixVal1 = curve1[pixVal1];
180 *(src+4) = (unsigned char) ((pixVal0>>2));
181 *(src+7) = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
182
183 pixVal2=((0x3c0&(((unsigned short)(src[6]))<<6)) | (src[9] >> 2));
184 pixVal0=((0x300&(((unsigned short)(src[9]))<<8)) | (src[8]));
185 pixVal2 = curve0[pixVal2];
186 pixVal0 = curve1[pixVal0];
187 *(src+6) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
188 *(src+9) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
189 *(src+8) = (unsigned char) ((pixVal0));
190 }
191 for (j=camera_sensor.raw_rowpix;j; j-=8, src+=10){
192 pixVal0=((0x3fc&(((unsigned short)(src[1]))<<2)) | (src[0] >> 6));
193 pixVal1=((0x3f0&(((unsigned short)(src[0]))<<4)) | (src[3] >> 4));
194 pixVal0 = curve2[pixVal0];
195 pixVal1 = curve3[pixVal1];
196 *(src+1) = (unsigned char) ((pixVal0>>2));
197 *src = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
198
199 pixVal2=((0x3c0&(((unsigned short)(src[3]))<<6)) | (src[2] >> 2));
200 pixVal0=((0x300&(((unsigned short)(src[2]))<<8)) | (src[5]));
201 pixVal2 = curve2[pixVal2];
202 pixVal0 = curve3[pixVal0];
203 *(src+3) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
204 *(src+2) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
205 *(src+5) = (unsigned char) ((pixVal0));
206
207 pixVal0=((0x3fc&(((unsigned short)(src[4]))<<2)) | (src[7] >> 6));
208 pixVal1=((0x3f0&(((unsigned short)(src[7]))<<4)) | (src[6] >> 4));
209 pixVal0 = curve2[pixVal0];
210 pixVal1 = curve3[pixVal1];
211 *(src+4) = (unsigned char) ((pixVal0>>2));
212 *(src+7) = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
213
214 pixVal2=((0x3c0&(((unsigned short)(src[6]))<<6)) | (src[9] >> 2));
215 pixVal0=((0x300&(((unsigned short)(src[9]))<<8)) | (src[8]));
216 pixVal2 = curve2[pixVal2];
217 pixVal0 = curve3[pixVal0];
218 *(src+6) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
219 *(src+9) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
220 *(src+8) = (unsigned char) ((pixVal0));
221 }
222 }
223 }
224
225
226 void curveL_apply(unsigned sys_index) {
227 int i,j;
228 unsigned short pixVal0, pixVal1, pixVal2;
229 unsigned char *src;
230
231 unsigned short *curve0;
232 unsigned short *curve1;
233 unsigned short *curve2;
234 unsigned short *curve3;
235 if (current_curve_type == CURVE_SYSTEM) {
236 if (sys_index > 1)
237 return;
238 curve0 = curve1 = curve2 = curve3 = curve_data + sys_index*CURVE_SIZE;
239 }
240 else if(current_curve_type == CURVE_CUSTOM) {
241 curve0 = curve_data;
242 curve1 = curve0 + CURVE_SIZE;
243 curve2 = curve1 + CURVE_SIZE;
244 curve3 = curve2 + CURVE_SIZE;
245 } else {
246 return;
247 }
248
249
250
251 src = (unsigned char *) get_raw_image_addr();
252
253
254 for (i=camera_sensor.raw_rows; i;i-=2){
255
256 for (j=camera_sensor.raw_rowpix; j; j-=8, src+=10){
257 pixVal0=((0x3fc&(((unsigned short)(src[1]))<<2)) | (src[0] >> 6));
258 pixVal1=((0x3f0&(((unsigned short)(src[0]))<<4)) | (src[3] >> 4));
259 if (pixVal1) {
260 pixVal1 = RBLACK( pixVal1 );
261 if (pixVal0) {
262 pixVal0 = RBLACK( pixVal0 );
263 pixVal0 = CURVE0( pixVal0, pixVal1 ) + BLACK;
264 pixVal0 = LIM( pixVal0 );
265 }
266 pixVal1 = CURVE1( pixVal1, pixVal1 ) + BLACK;
267 pixVal1 = LIM( pixVal1 );
268 }
269 *(src+1) = (unsigned char) ((pixVal0>>2));
270 *src = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
271
272 pixVal2=((0x3c0&(((unsigned short)(src[3]))<<6)) | (src[2] >> 2));
273 pixVal0=((0x300&(((unsigned short)(src[2]))<<8)) | (src[5]));
274 if (pixVal0) {
275 pixVal0 = RBLACK( pixVal0 );
276 if (pixVal2) {
277 pixVal2 = RBLACK( pixVal2 );
278 pixVal2 = CURVE0( pixVal2, pixVal0 ) + BLACK;
279 pixVal2 = LIM( pixVal2 );
280 }
281 pixVal0 = CURVE1( pixVal0, pixVal0 ) + BLACK;
282 pixVal0 = LIM( pixVal0 );
283 }
284 *(src+3) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
285 *(src+2) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
286 *(src+5) = (unsigned char) ((pixVal0));
287
288 pixVal0=((0x3fc&(((unsigned short)(src[4]))<<2)) | (src[7] >> 6));
289 pixVal1=((0x3f0&(((unsigned short)(src[7]))<<4)) | (src[6] >> 4));
290 if (pixVal1) {
291 pixVal1 = RBLACK( pixVal1 );
292 if (pixVal0) {
293 pixVal0 = RBLACK( pixVal0 );
294 pixVal0 = CURVE0( pixVal0, pixVal1 ) + BLACK;
295 pixVal0 = LIM( pixVal0 );
296 }
297 pixVal1 = CURVE1( pixVal1, pixVal1 ) + BLACK;
298 pixVal1 = LIM( pixVal1 );
299 }
300 *(src+4) = (unsigned char) ((pixVal0>>2));
301 *(src+7) = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
302
303 pixVal2=((0x3c0&(((unsigned short)(src[6]))<<6)) | (src[9] >> 2));
304 pixVal0=((0x300&(((unsigned short)(src[9]))<<8)) | (src[8]));
305 if (pixVal0) {
306 pixVal0 = RBLACK( pixVal0 );
307 if (pixVal2) {
308 pixVal2 = RBLACK( pixVal2 );
309 pixVal2 = CURVE0( pixVal2, pixVal0 ) + BLACK;
310 pixVal2 = LIM( pixVal2 );
311 }
312 pixVal0 = CURVE1( pixVal0, pixVal0 ) + BLACK;
313 pixVal0 = LIM( pixVal0 );
314 }
315 *(src+6) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
316 *(src+9) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
317 *(src+8) = (unsigned char) ((pixVal0));
318 }
319 for (j=camera_sensor.raw_rowpix; j; j-=8, src+=10){
320 pixVal0=((0x3fc&(((unsigned short)(src[1]))<<2)) | (src[0] >> 6));
321 pixVal1=((0x3f0&(((unsigned short)(src[0]))<<4)) | (src[3] >> 4));
322 if (pixVal0) {
323 pixVal0 = RBLACK( pixVal0 );
324 if (pixVal1) {
325 pixVal1 = RBLACK( pixVal1 );
326 pixVal1 = CURVE3( pixVal1, pixVal0 ) + BLACK;
327 pixVal1 = LIM( pixVal1 );
328 }
329 pixVal0 = CURVE2( pixVal0, pixVal0 ) + BLACK;
330 pixVal0 = LIM( pixVal0 );
331 }
332 *(src+1) = (unsigned char) ((pixVal0>>2));
333 *src = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
334
335 pixVal2=((0x3c0&(((unsigned short)(src[3]))<<6)) | (src[2] >> 2));
336 pixVal0=((0x300&(((unsigned short)(src[2]))<<8)) | (src[5]));
337 if (pixVal2) {
338 pixVal2 = RBLACK( pixVal2 );
339 if (pixVal0) {
340 pixVal0 = RBLACK( pixVal0 );
341 pixVal0 = CURVE3( pixVal0, pixVal2 ) + BLACK;
342 pixVal0 = LIM( pixVal0 );
343 }
344 pixVal2 = CURVE2( pixVal2, pixVal2 ) + BLACK;
345 pixVal2 = LIM( pixVal2 );
346 }
347 *(src+3) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
348 *(src+2) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
349 *(src+5) = (unsigned char) ((pixVal0));
350
351 pixVal0=((0x3fc&(((unsigned short)(src[4]))<<2)) | (src[7] >> 6));
352 pixVal1=((0x3f0&(((unsigned short)(src[7]))<<4)) | (src[6] >> 4));
353 if (pixVal0) {
354 pixVal0 = RBLACK( pixVal0 );
355 if (pixVal1) {
356 pixVal1 = RBLACK( pixVal1 );
357 pixVal1 = CURVE3( pixVal1, pixVal0 ) + BLACK;
358 pixVal1 = LIM( pixVal1 );
359 }
360 pixVal0 = CURVE2( pixVal0, pixVal0 ) + BLACK;
361 pixVal0 = LIM( pixVal0 );
362 }
363 *(src+4) = (unsigned char) ((pixVal0>>2));
364 *(src+7) = (unsigned char) ((pixVal0<<6)|(pixVal1>>4));
365
366 pixVal2=((0x3c0&(((unsigned short)(src[6]))<<6)) | (src[9] >> 2));
367 pixVal0=((0x300&(((unsigned short)(src[9]))<<8)) | (src[8]));
368 if (pixVal2) {
369 pixVal2 = RBLACK( pixVal2 );
370 if (pixVal0) {
371 pixVal0 = RBLACK( pixVal0 );
372 pixVal0 = CURVE3( pixVal0, pixVal2 ) + BLACK;
373 pixVal0 = LIM( pixVal0 );
374 }
375 pixVal2 = CURVE2( pixVal2, pixVal2 ) + BLACK;
376 pixVal2 = LIM( pixVal2 );
377 }
378 *(src+6) = (unsigned char) ((pixVal1<<4)|(pixVal2>>6));
379 *(src+9) = (unsigned char) ((pixVal2<<2)|(pixVal0>>8));
380 *(src+8) = (unsigned char) ((pixVal0));
381 }
382 }
383 }
384
385 void curve_apply() {
386 short EVbias = shooting_get_ev_correction1();
387
388 switch(conf.curve_enable) {
389 case 0:
390 break;
391 case 1:
392 if (current_curve_type == CURVE_CUSTOM){
393 if(curve_data[0] > 1023){
394 curveL_apply(0);
395 } else {
396 curveRGB_apply();
397 }
398 };
399 break;
400 case 2:
401 case 3:
402 if (current_curve_type == CURVE_SYSTEM) curveL_apply( conf.curve_enable & 1 );
403 break;
404 case 4:
405
406 if (current_curve_type == CURVE_SYSTEM) {
407 if (EVbias <-128) {
408 curveL_apply(1);
409 } else if(EVbias<-32){
410 curveL_apply(0);
411 }
412 }
413 break;
414 }
415
416 }
417
418
419
420
421
422
423
424
425 int _module_can_unload()
426 {
427 return conf.curve_enable == 0;
428 }
429
430
431
432 libcurves_sym _libcurves =
433 {
434 {
435 0, 0, _module_can_unload, 0, 0
436 },
437
438 curve_init_mode,
439 curve_apply,
440 curve_set_mode,
441 curve_set_file
442 };
443
444 ModuleInfo _module_info =
445 {
446 MODULEINFO_V1_MAGICNUM,
447 sizeof(ModuleInfo),
448 CURVES_VERSION,
449
450 ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,
451 ANY_PLATFORM_ALLOWED,
452
453 (int32_t)"Curves (dll)",
454 MTYPE_EXTENSION,
455
456 &_libcurves.base,
457
458 CONF_VERSION,
459 ANY_VERSION,
460 CAM_SENSOR_VERSION,
461 ANY_VERSION,
462
463 0,
464 };
465
466