This source file includes following definitions.
- round_d2i
- rawop_get_cfa
- rawop_get_cfa_offsets
- rawop_get_bits_per_pixel
- rawop_get_raw_neutral
- rawop_get_black_level
- rawop_get_white_level
- rawop_get_raw_width
- rawop_get_raw_height
- rawop_get_active_left
- rawop_get_active_top
- rawop_get_active_width
- rawop_get_active_height
- rawop_get_jpeg_left
- rawop_get_jpeg_top
- rawop_get_jpeg_width
- rawop_get_jpeg_height
- rawop_get_pixel
- rawop_set_pixel
- rawop_get_pixels_rgbg
- rawop_set_pixels_rgbg
- rawop_fill_rect
- rawop_meter
- rawop_raw_to_ev
- rawop_ev_to_raw
- rawop_create_histogram
- rawop_histo_update
- rawop_histo_range
- rawop_histo_total_pixels
- rawop_histo_bits
- rawop_histo_free
- rawop_histo_gc
- init_raw_params
- rawop_update_hook_status
- luaopen_rawop
1
2
3
4 #include "camera_info.h"
5 #include "conf.h"
6 #include "raw.h"
7 #include "math.h"
8
9 #include "lualib.h"
10 #include "lauxlib.h"
11
12 extern void set_number_field(lua_State *L, const char *name, int value);
13
14
15 static int raw_buffer_valid;
16
17
18
19 static unsigned raw_neutral;
20
21 static double log2_raw_neutral_count;
22
23
24
25 static unsigned cfa_offsets[4][2];
26 static const char *cfa_names[]={"r","g1","g2","b"};
27 #define CFA_R 0
28 #define CFA_G1 1
29 #define CFA_G2 2
30 #define CFA_B 3
31 #define RAWOP_HISTO_META "rawop.histo_meta"
32
33
34 static int round_d2i(double v) {
35 if(v<0.0) {
36 return (int)(v - 0.5);
37 }
38 return (int)(v + 0.5);
39 }
40
41
42
43
44 static int rawop_get_cfa(lua_State *L) {
45 lua_pushnumber(L,camera_sensor.cfa_pattern);
46 return 1;
47 }
48
49
50
51
52
53
54
55
56
57
58
59 static int rawop_get_cfa_offsets(lua_State *L) {
60 lua_createtable(L, 0, 4);
61 int i;
62 for(i=0;i<4;i++) {
63 lua_createtable(L, 0, 2);
64 set_number_field(L,"x",cfa_offsets[i][0]);
65 set_number_field(L,"y",cfa_offsets[i][1]);
66 lua_setfield(L, -2, cfa_names[i]);
67 }
68 return 1;
69 }
70
71
72
73
74
75 static int rawop_get_bits_per_pixel(lua_State *L) {
76 lua_pushnumber(L,camera_sensor.bits_per_pixel);
77 return 1;
78 }
79
80
81
82
83
84
85
86
87
88
89
90 static int rawop_get_raw_neutral(lua_State *L) {
91 lua_pushnumber(L,(int)raw_neutral);
92 return 1;
93 }
94
95
96
97
98
99
100
101
102
103 static int rawop_get_black_level(lua_State *L) {
104 lua_pushnumber(L,camera_sensor.black_level);
105 return 1;
106 }
107
108
109
110
111
112 static int rawop_get_white_level(lua_State *L) {
113 lua_pushnumber(L,camera_sensor.white_level);
114 return 1;
115 }
116
117
118
119
120
121 static int rawop_get_raw_width(lua_State *L) {
122 lua_pushnumber(L,camera_sensor.raw_rowpix);
123 return 1;
124 }
125
126
127
128
129
130 static int rawop_get_raw_height(lua_State *L) {
131 lua_pushnumber(L,camera_sensor.raw_rows);
132 return 1;
133 }
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 static int rawop_get_active_left(lua_State *L) {
151 lua_pushnumber(L,camera_sensor.active_area.x1);
152 return 1;
153 }
154
155
156
157
158
159 static int rawop_get_active_top(lua_State *L) {
160 lua_pushnumber(L,camera_sensor.active_area.y1);
161 return 1;
162 }
163
164
165
166
167
168 static int rawop_get_active_width(lua_State *L) {
169 lua_pushnumber(L,camera_sensor.active_area.x2 - camera_sensor.active_area.x1);
170 return 1;
171 }
172
173
174
175
176
177 static int rawop_get_active_height(lua_State *L) {
178 lua_pushnumber(L,camera_sensor.active_area.y2 - camera_sensor.active_area.y1);
179 return 1;
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 static int rawop_get_jpeg_left(lua_State *L) {
203 lua_pushnumber(L,camera_sensor.active_area.x1 + camera_sensor.jpeg.x);
204 return 1;
205 }
206
207
208
209
210
211 static int rawop_get_jpeg_top(lua_State *L) {
212 lua_pushnumber(L,camera_sensor.active_area.y1 + camera_sensor.jpeg.y);
213 return 1;
214 }
215
216
217
218
219
220 static int rawop_get_jpeg_width(lua_State *L) {
221 lua_pushnumber(L,camera_sensor.jpeg.width);
222 return 1;
223 }
224
225
226
227
228
229 static int rawop_get_jpeg_height(lua_State *L) {
230 lua_pushnumber(L,camera_sensor.jpeg.height);
231 return 1;
232 }
233
234
235
236
237
238
239
240
241
242
243
244
245 static int rawop_get_pixel(lua_State *L) {
246 if(!raw_buffer_valid) {
247 return luaL_error(L,"raw data not available");
248 }
249 unsigned x=luaL_checknumber(L,1);
250 unsigned y=luaL_checknumber(L,2);
251
252
253 if(x >= (unsigned)camera_sensor.raw_rowpix || y >= (unsigned)camera_sensor.raw_rows) {
254 return 0;
255 }
256 lua_pushnumber(L,get_raw_pixel(x,y));
257 return 1;
258 }
259
260
261
262
263
264
265
266
267 static int rawop_set_pixel(lua_State *L) {
268 if(!raw_buffer_valid) {
269 return luaL_error(L,"raw data not available");
270 }
271 unsigned int x=luaL_checknumber(L,1);
272 unsigned int y=luaL_checknumber(L,2);
273 unsigned short v=luaL_checknumber(L,3);
274
275
276 if(x >= (unsigned)camera_sensor.raw_rowpix || y >= (unsigned)camera_sensor.raw_rows) {
277 return 0;
278 }
279
280 set_raw_pixel(x,y,v);
281 return 0;
282 }
283
284
285
286
287
288
289
290
291
292 static int rawop_get_pixels_rgbg(lua_State *L) {
293 if(!raw_buffer_valid) {
294 return luaL_error(L,"raw data not available");
295 }
296 unsigned int x=luaL_checknumber(L,1);
297 unsigned int y=luaL_checknumber(L,2);
298
299 x &= 0xFFFFFFFE;
300 y &= 0xFFFFFFFE;
301
302 if(x >= (unsigned)camera_sensor.raw_rowpix || y >= (unsigned)camera_sensor.raw_rows) {
303 return 0;
304 }
305 lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_R][0],y+cfa_offsets[CFA_R][1]));
306 lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_G1][0],y+cfa_offsets[CFA_G1][1]));
307 lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_B][0],y+cfa_offsets[CFA_B][1]));
308 lua_pushnumber(L,get_raw_pixel(x+cfa_offsets[CFA_G2][0],y+cfa_offsets[CFA_G2][1]));
309 return 4;
310 }
311
312
313
314
315
316
317
318
319
320
321 static int rawop_set_pixels_rgbg(lua_State *L) {
322 if(!raw_buffer_valid) {
323 return luaL_error(L,"raw data not available");
324 }
325 unsigned int x=luaL_checknumber(L,1);
326 unsigned int y=luaL_checknumber(L,2);
327 unsigned short r=luaL_checknumber(L,3);
328 unsigned short g1=luaL_checknumber(L,4);
329 unsigned short b=luaL_checknumber(L,5);
330 unsigned short g2=luaL_optnumber(L,6,g1);
331
332 x &= 0xFFFFFFFE;
333 y &= 0xFFFFFFFE;
334
335 if(x >= (unsigned)camera_sensor.raw_rowpix - 1 || y >= (unsigned)camera_sensor.raw_rows - 1) {
336 return 0;
337 }
338 set_raw_pixel(x+cfa_offsets[CFA_R][0],y+cfa_offsets[CFA_R][1],r);
339 set_raw_pixel(x+cfa_offsets[CFA_G1][0],y+cfa_offsets[CFA_G1][1],g1);
340 set_raw_pixel(x+cfa_offsets[CFA_B][0],y+cfa_offsets[CFA_B][1],b);
341 set_raw_pixel(x+cfa_offsets[CFA_G2][0],y+cfa_offsets[CFA_G2][1],g2);
342 return 0;
343 }
344
345
346
347
348
349
350
351
352
353
354
355 static int rawop_fill_rect(lua_State *L) {
356 if(!raw_buffer_valid) {
357 return luaL_error(L,"raw data not available");
358 }
359 unsigned int xstart=luaL_checknumber(L,1);
360 unsigned int ystart=luaL_checknumber(L,2);
361 unsigned int width=luaL_checknumber(L,3);
362 unsigned int height=luaL_checknumber(L,4);
363 unsigned short val=luaL_checknumber(L,5);
364 unsigned int xstep=luaL_optnumber(L,6,1);
365 unsigned int ystep=luaL_optnumber(L,7,xstep);
366 unsigned int xmax = xstart + width;
367 unsigned int ymax = ystart + height;
368 if(xstart >= (unsigned)camera_sensor.raw_rowpix || ystart >= (unsigned)camera_sensor.raw_rows) {
369 return 0;
370 }
371 if(xmax > (unsigned)camera_sensor.raw_rowpix) {
372 xmax = (unsigned)camera_sensor.raw_rowpix;
373 }
374 if(ymax > (unsigned)camera_sensor.raw_rows) {
375 ymax = (unsigned)camera_sensor.raw_rows;
376 }
377 unsigned x,y;
378 for(y=ystart; y<ymax; y+=ystep) {
379 for(x=xstart; x<xmax; x+=xstep) {
380 set_raw_pixel(x,y,val);
381 }
382 }
383 return 0;
384 }
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404 static int rawop_meter(lua_State *L) {
405 if(!raw_buffer_valid) {
406 return luaL_error(L,"raw data not available");
407 }
408 unsigned x1=luaL_checknumber(L,1);
409 unsigned y1=luaL_checknumber(L,2);
410 unsigned x_count=luaL_checknumber(L,3);
411 unsigned y_count=luaL_checknumber(L,4);
412 unsigned x_step=luaL_checknumber(L,5);
413 unsigned y_step=luaL_checknumber(L,6);
414
415
416 if(!x_count || !y_count) {
417 return 0;
418 }
419
420 unsigned x_max = x1 + x_step * x_count;
421 unsigned y_max = y1 + y_step * y_count;
422
423 if(x_max > (unsigned)camera_sensor.raw_rowpix) {
424 return 0;
425 }
426
427 if(y_max > (unsigned)camera_sensor.raw_rows) {
428 return 0;
429 }
430
431 if(x_count*y_count > (unsigned)0xFFFFFFFF >> camera_sensor.bits_per_pixel) {
432 return 0;
433 }
434 unsigned t=0;
435 unsigned x,y;
436 for(y = y1; y < y_max; y += y_step) {
437 for(x = x1; x < x_max; x += x_step) {
438 t+=get_raw_pixel(x,y);
439 }
440 }
441 lua_pushnumber(L,t/(x_count*y_count));
442 return 1;
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 static int rawop_raw_to_ev(lua_State *L) {
462 int v=luaL_checknumber(L,1);
463 int scale=luaL_optnumber(L,2,96);
464
465 if( v <= camera_sensor.black_level) {
466 v = camera_sensor.black_level+1;
467 }
468 int r=round_d2i((double)scale*(log2(v - camera_sensor.black_level) - log2_raw_neutral_count));
469 lua_pushnumber(L,r);
470 return 1;
471 }
472
473
474
475
476
477
478
479
480
481
482
483
484 static int rawop_ev_to_raw(lua_State *L) {
485 int v=luaL_checknumber(L,1);
486 int scale=luaL_optnumber(L,2,96);
487
488 lua_pushnumber(L,round_d2i(pow(2,(double)v/(double)scale+log2_raw_neutral_count)+camera_sensor.black_level));
489 return 1;
490 }
491
492
493
494
495
496 typedef struct {
497 unsigned bits;
498 unsigned entries;
499 unsigned total_pixels;
500 unsigned *data;
501 } rawop_histo_t;
502
503
504
505
506 static int rawop_create_histogram(lua_State *L) {
507 rawop_histo_t *h = (rawop_histo_t *)lua_newuserdata(L,sizeof(rawop_histo_t));
508 if(!h) {
509 return luaL_error(L,"failed to create userdata");
510 }
511 h->total_pixels = 0;
512 h->data = NULL;
513 luaL_getmetatable(L, RAWOP_HISTO_META);
514 lua_setmetatable(L, -2);
515 return 1;
516 }
517
518
519
520
521
522
523
524
525
526
527
528 static int rawop_histo_update(lua_State *L) {
529 if(!raw_buffer_valid) {
530 return luaL_error(L,"raw data not available");
531 }
532 rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
533
534 unsigned xstart=luaL_checknumber(L,2);
535 unsigned ystart=luaL_checknumber(L,3);
536 unsigned width=luaL_checknumber(L,4);
537 unsigned height=luaL_checknumber(L,5);
538 unsigned xstep=luaL_checknumber(L,6);
539 unsigned ystep=luaL_checknumber(L,7);
540 int bits=luaL_optnumber(L,8,camera_sensor.bits_per_pixel);
541 if(bits > camera_sensor.bits_per_pixel || bits < 1) {
542 return luaL_error(L,"invalid bit depth");
543 }
544 unsigned shift = camera_sensor.bits_per_pixel - bits;
545 unsigned entries = 1 << bits;
546
547 h->total_pixels=0;
548 if(xstart >= (unsigned)camera_sensor.raw_rowpix
549 || ystart >= (unsigned)camera_sensor.raw_rows
550 || xstep == 0 || ystep == 0
551 || width == 0 || height == 0) {
552 luaL_error(L,"invalid update area");
553 return 0;
554 }
555 unsigned xmax=xstart+width;
556 unsigned ymax=ystart+height;
557 if(xmax > (unsigned)camera_sensor.raw_rowpix) {
558 xmax = (unsigned)camera_sensor.raw_rowpix;
559 }
560 if(ymax > (unsigned)camera_sensor.raw_rows) {
561 ymax = (unsigned)camera_sensor.raw_rows;
562 }
563
564 h->total_pixels=((1+(xmax - xstart - 1)/xstep))*((1+(ymax - ystart - 1)/ystep));
565
566
567 if(h->entries != entries || !h->data) {
568 free(h->data);
569 h->data = malloc(entries*sizeof(unsigned));
570 if(!h->data) {
571 h->total_pixels=0;
572 return luaL_error(L,"insufficient memory");
573 }
574 }
575 h->entries = entries;
576 h->bits = bits;
577 memset(h->data,0,h->entries*sizeof(unsigned));
578
579 unsigned x,y;
580 if(shift) {
581 for(y=ystart;y<ymax;y+=ystep) {
582 for(x=xstart;x<xmax;x+=xstep) {
583 h->data[get_raw_pixel(x,y)>>shift]++;
584 }
585 }
586 } else {
587 for(y=ystart;y<ymax;y+=ystep) {
588 for(x=xstart;x<xmax;x+=xstep) {
589 h->data[get_raw_pixel(x,y)]++;
590 }
591 }
592 }
593 return 0;
594 }
595
596
597
598
599
600 static int rawop_histo_range(lua_State *L) {
601 rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
602 if(!h->data) {
603 return luaL_error(L,"no data");
604 }
605 unsigned minval=luaL_checknumber(L,2);
606 unsigned maxval=luaL_checknumber(L,3);
607 int scale=1000;
608 if(lua_gettop(L) >= 4 && !lua_isnil(L,4)) {
609 const char *s=lua_tostring(L,4);
610 if(!s || strcmp(s,"count") != 0) {
611 scale=lua_tonumber(L,4);
612
613 if(!scale) {
614 return luaL_error(L,"invalid format");
615 }
616 } else {
617 scale=0;
618 }
619 }
620 if(maxval >= h->entries || minval > maxval) {
621 return luaL_error(L,"invalid range");
622 }
623
624 if(!h->total_pixels) {
625 return luaL_error(L,"no pixels");
626
627
628 }
629
630 unsigned count=0;
631 unsigned i;
632 for(i=minval;i<=maxval;i++) {
633 count+=h->data[i];
634 }
635
636
637 if(scale) {
638 lua_pushnumber(L,round_d2i((scale*(double)count)/(double)h->total_pixels));
639 } else {
640 lua_pushnumber(L,count);
641 }
642 return 1;
643 }
644
645
646
647
648
649 static int rawop_histo_total_pixels(lua_State *L) {
650 rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
651 if(!h->data) {
652 return luaL_error(L,"no data");
653 }
654 lua_pushnumber(L,h->total_pixels);
655 return 1;
656 }
657
658
659
660
661
662 static int rawop_histo_bits(lua_State *L) {
663 rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
664 if(!h->data) {
665 return luaL_error(L,"no data");
666 }
667 lua_pushnumber(L,h->bits);
668 return 1;
669 }
670
671
672
673
674
675 static int rawop_histo_free(lua_State *L) {
676 rawop_histo_t *h = (rawop_histo_t *)luaL_checkudata(L,1,RAWOP_HISTO_META);
677 free(h->data);
678 h->data=NULL;
679 return 0;
680 }
681
682 static int rawop_histo_gc(lua_State *L) {
683 rawop_histo_free(L);
684 return 0;
685 }
686
687 static const luaL_Reg rawop_histo_meta_methods[] = {
688 {"__gc", rawop_histo_gc},
689 {NULL, NULL}
690 };
691
692 static const luaL_Reg rawop_histo_methods[] = {
693 {"update", rawop_histo_update},
694 {"range", rawop_histo_range},
695 {"total_pixels", rawop_histo_total_pixels},
696 {"bits", rawop_histo_bits},
697 {"free", rawop_histo_free},
698 {NULL, NULL}
699 };
700
701 static const luaL_Reg rawop_funcs[] = {
702
703 {"get_cfa", rawop_get_cfa},
704 {"get_cfa_offsets", rawop_get_cfa_offsets},
705 {"get_bits_per_pixel",rawop_get_bits_per_pixel},
706 {"get_raw_neutral", rawop_get_raw_neutral},
707 {"get_black_level", rawop_get_black_level},
708 {"get_white_level", rawop_get_white_level},
709
710
711 {"get_raw_width", rawop_get_raw_width},
712 {"get_raw_height", rawop_get_raw_height},
713 {"get_active_left", rawop_get_active_left},
714 {"get_active_top", rawop_get_active_top},
715 {"get_active_width", rawop_get_active_width},
716 {"get_active_height", rawop_get_active_height},
717 {"get_jpeg_left", rawop_get_jpeg_left},
718 {"get_jpeg_top", rawop_get_jpeg_top},
719 {"get_jpeg_width", rawop_get_jpeg_width},
720 {"get_jpeg_height", rawop_get_jpeg_height},
721
722
723 {"get_pixel", rawop_get_pixel},
724 {"set_pixel", rawop_set_pixel},
725 {"get_pixels_rgbg", rawop_get_pixels_rgbg},
726 {"set_pixels_rgbg", rawop_set_pixels_rgbg},
727 {"fill_rect", rawop_fill_rect},
728 {"meter", rawop_meter},
729
730
731 {"raw_to_ev", rawop_raw_to_ev},
732 {"ev_to_raw", rawop_ev_to_raw},
733
734
735 {"create_histogram", rawop_create_histogram},
736 {NULL, NULL}
737 };
738
739
740
741 static void init_raw_params(void) {
742
743
744
745 double raw_neutral_count = (double)(camera_sensor.white_level - camera_sensor.black_level)/(6.669);
746 log2_raw_neutral_count = log2(raw_neutral_count);
747 raw_neutral = round_d2i(raw_neutral_count) + camera_sensor.black_level;
748 }
749
750
751 void rawop_update_hook_status(int active) {
752 if(active) {
753 raw_buffer_valid = is_raw_possible();
754 init_raw_params();
755 } else {
756 raw_buffer_valid = 0;
757 }
758 }
759
760 int luaopen_rawop(lua_State *L) {
761
762 raw_buffer_valid = 0;
763
764 int i;
765 int g1=1;
766 for(i=0; i<4; i++) {
767 int c = (camera_sensor.cfa_pattern >> 8*i) & 0xFF;
768 int ci=0;
769 switch(c) {
770 case 0:
771 ci=0;
772 break;
773 case 1:
774 if(g1) {
775 ci=1;
776 g1=0;
777 } else {
778 ci=2;
779 }
780 break;
781 case 2:
782 ci=3;
783 break;
784 }
785 cfa_offsets[ci][0] = i&1;
786 cfa_offsets[ci][1] = (i&2)>>1;
787 }
788
789
790
791 init_raw_params();
792
793 luaL_newmetatable(L,RAWOP_HISTO_META);
794 luaL_register(L, NULL, rawop_histo_meta_methods);
795
796 lua_newtable(L);
797 luaL_register(L, NULL, rawop_histo_methods);
798 lua_setfield(L,-2,"__index");
799 lua_pop(L,1);
800
801
802 lua_newtable(L);
803 luaL_register(L, "rawop", rawop_funcs);
804 return 1;
805 }