This source file includes following definitions.
- clip8
- gui_osd_zebra_free
- gui_osd_zebra_init
- draw_pixel_buffered
- draw_guard_pixel
- gui_osd_draw_zebra_osd
- disp_zebra
- draw_zebra_aspect_adjust
- get_cur_buf
- draw_zebra_no_aspect_adjust
- gui_osd_draw_zebra
- gui_osd_zebra_free
- gui_osd_zebra_init
- gui_osd_draw_zebra_osd
- disp_zebra
- draw_zebra_no_aspect_adjust
- gui_osd_draw_zebra
- _module_unloader
- _module_can_unload
1 #include "camera_info.h"
2 #include "conf.h"
3 #include "keyboard.h"
4 #include "modes.h"
5 #include "viewport.h"
6 #include "properties.h"
7 #include "gui.h"
8 #include "gui_draw.h"
9 #include "gui_lang.h"
10 #include "gui_osd.h"
11 #include "gui_mbox.h"
12 #include "gui_batt.h"
13 #include "gui_space.h"
14 #include "histogram.h"
15
16 #include "zebra.h"
17 #include "gui_grid.h"
18 #include "module_def.h"
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 #define ZFIX_TOP 29
103 #define ZFIX_BOTTOM 30
104
105 static unsigned char *img_buf;
106 #ifndef THUMB_FW
107 static unsigned char *scr_buf;
108 static unsigned char *cur_buf_top, *cur_buf_bot;
109 static unsigned char *buf = NULL;
110 static int buffer_size;
111 #endif
112 static int timer = 0;
113 static color cl_under, cl_over;
114
115 unsigned char clip8(signed short x){ if (x<0) x=0; else if (x>255) x=255; return x; }
116
117 #ifndef THUMB_FW
118
119
120 static void gui_osd_zebra_free()
121 {
122 if (buf != scr_buf) free(buf);
123 buf = NULL;
124
125 free(cur_buf_top);
126 cur_buf_top = NULL;
127
128 free(cur_buf_bot);
129 cur_buf_bot = NULL;
130 }
131
132
133 static int gui_osd_zebra_init(int show)
134 {
135 cl_under = BG_COLOR(user_color(conf.zebra_color));
136 cl_over = FG_COLOR(user_color(conf.zebra_color));
137
138 if (show)
139 {
140 if (!buf)
141 {
142 timer = 0;
143
144 buffer_size = camera_screen.buffer_size - (camera_screen.buffer_height - camera_screen.height) * camera_screen.buffer_width;
145 scr_buf = vid_get_bitmap_fb();
146 if (camera_screen.zebra_nobuf == 0)
147 {
148 buf = malloc(buffer_size);
149
150 }
151 if (!buf)
152 {
153 buf = scr_buf;
154 }
155 if (camera_screen.zebra_aspect_adjust)
156 {
157 cur_buf_top = cur_buf_bot = 0;
158 }
159 else
160 {
161 cur_buf_top = malloc(camera_screen.buffer_width * ZFIX_TOP);
162 cur_buf_bot = malloc(camera_screen.buffer_width * ZFIX_BOTTOM);
163
164 if (!cur_buf_top || !cur_buf_bot)
165 gui_osd_zebra_free();
166 if (cur_buf_top) memset(cur_buf_top,0,camera_screen.buffer_width * ZFIX_TOP);
167 if (cur_buf_bot) memset(cur_buf_bot,0,camera_screen.buffer_width * ZFIX_BOTTOM);
168 }
169
170 if (camera_screen.has_variable_aspect)
171 memset(buf,0,buffer_size);
172 }
173 }
174 else {
175 if (buf)
176 gui_set_need_restore();
177
178 gui_osd_zebra_free();
179 }
180 return (buf != NULL);
181 }
182
183
184
185
186 static void draw_pixel_buffered(unsigned int offset, color cl)
187 {
188 buf[offset] = cl;
189 }
190
191
192 int draw_guard_pixel() {
193 unsigned char* buffer1 = vid_get_bitmap_fb()+camera_screen.buffer_size/2;
194 unsigned char* buffer2 = buffer1+camera_screen.buffer_size;
195 int has_disappeared=0;
196
197 if(*buffer1!=COLOR_GREEN) has_disappeared=1;
198 if(*buffer2!=COLOR_GREEN) has_disappeared=2;
199 *buffer1 = *buffer2 = COLOR_GREEN;
200 return has_disappeared;
201 }
202
203
204 static void gui_osd_draw_zebra_osd() {
205 switch (conf.zebra_draw_osd) {
206 case ZEBRA_DRAW_NONE:
207 break;
208 case ZEBRA_DRAW_OSD:
209 if (conf.show_osd) {
210 draw_set_draw_proc(draw_pixel_buffered);
211 gui_draw_osd_elements(0,1);
212 draw_set_draw_proc(NULL);
213 }
214
215 case ZEBRA_DRAW_HISTO:
216 default:
217 draw_set_draw_proc(draw_pixel_buffered);
218 libhisto->gui_osd_draw_histo(0);
219 draw_set_draw_proc(NULL);
220 break;
221 }
222 }
223
224
225 static void disp_zebra()
226 {
227
228 gui_osd_draw_zebra_osd();
229
230
231 if (buf != scr_buf)
232 memcpy(scr_buf, buf, buffer_size);
233 memcpy(scr_buf+camera_screen.buffer_size, buf, buffer_size);
234 }
235
236
237
238
239
240
241 static int draw_zebra_aspect_adjust(int mrec, unsigned int f, color *cls)
242 {
243 int v, s, x, y, over;
244 static int need_restore=0;
245 int viewport_height;
246 int viewport_width;
247 int viewport_image_offset;
248 int viewport_row_offset;
249 int viewport_xoffset;
250 int viewport_yoffset;
251 int zebra_drawn=0;
252
253 viewport_height = vid_get_viewport_height();
254 viewport_width = vid_get_viewport_width();
255 viewport_image_offset = vid_get_viewport_image_offset();
256 viewport_row_offset = vid_get_viewport_row_offset();
257 viewport_xoffset = vid_get_viewport_display_xoffset();
258 viewport_yoffset = vid_get_viewport_display_yoffset();
259
260
261 if (f) {
262 if (viewport_yoffset > 0) {
263 memset(buf, COLOR_TRANSPARENT, viewport_yoffset*camera_screen.buffer_width);
264 memset(buf+(viewport_yoffset+viewport_height)*camera_screen.buffer_width, COLOR_TRANSPARENT, viewport_yoffset*camera_screen.buffer_width);
265 }
266 int step_x, step_v, sy, sx;
267 over = 255-conf.zebra_over;
268 if (conf.zebra_multichannel) {step_x=2; step_v=6;} else {step_x=1; step_v=3;}
269 for (y=viewport_yoffset, v=viewport_image_offset; y<viewport_yoffset+viewport_height; ++y) {
270 sy = y*camera_screen.buffer_width;
271 sx = viewport_xoffset;
272 if (viewport_xoffset > 0) {
273 memset(buf+sy, COLOR_TRANSPARENT, sx*2);
274 memset(buf+sy+(sx+viewport_width)*2, COLOR_TRANSPARENT, sx*2);
275 }
276 for (x=viewport_xoffset; x<viewport_xoffset+viewport_width; x+=step_x, sx+=step_x, v+=step_v) {
277 register int yy;
278 yy = img_buf[v+1];
279 s = sy + sx*2;
280
281 if (conf.zebra_multichannel) {
282 register int uu, vv;
283 int sel;
284 uu = (signed char)img_buf[v];
285 vv = (signed char)img_buf[v+2];
286 sel=0;
287 if (!((conf.zebra_mode == ZEBRA_MODE_ZEBRA_1 || conf.zebra_mode == ZEBRA_MODE_ZEBRA_2) && (y-x-timer)&f)) {
288 if (clip8(((yy<<12) + vv*5743 + 2048)>>12)>over) sel = 4;
289 if (clip8(((yy<<12) - uu*1411 - vv*2925 + 2048)>>12)>over) sel |= 2;
290 if (clip8(((yy<<12) + uu*7258 + 2048)>>12)>over) sel |= 1;
291 }
292 buf[s] = buf[s+1] = cls[sel];
293 buf[s+2] = buf[s+3] = cls[sel];
294 }
295 else if (((conf.zebra_mode == ZEBRA_MODE_ZEBRA_1 || conf.zebra_mode == ZEBRA_MODE_ZEBRA_2) && (y-x-timer)&f))
296 buf[s] = buf[s+1] = COLOR_TRANSPARENT;
297 else
298 buf[s] = buf[s+1] = (yy>over)?cl_over:(yy<conf.zebra_under)?cl_under:COLOR_TRANSPARENT;
299
300 if (buf[s] != COLOR_TRANSPARENT && !zebra_drawn)
301 zebra_drawn = 1;
302 }
303
304 v += viewport_row_offset;
305 }
306 if (!zebra_drawn) f=0;
307 }
308
309 if (!f) {
310
311 if (need_restore) {
312 if (conf.zebra_restore_screen || conf.zebra_restore_osd) {
313 gui_set_need_restore();
314 } else {
315 if (!mrec) {
316
317 memset(buf, COLOR_TRANSPARENT, buffer_size);
318 }
319 disp_zebra();
320 }
321 need_restore=0;
322 }
323 return !(conf.zebra_restore_screen && conf.zebra_restore_osd);
324
325 } else {
326 disp_zebra();
327
328 need_restore=1;
329 return 1;
330 }
331 return 0;
332 }
333
334
335
336 static unsigned char get_cur_buf(unsigned int idx) {
337 unsigned int a;
338
339 a=camera_screen.buffer_size - camera_screen.buffer_width * ZFIX_BOTTOM;
340
341 if (idx < (unsigned)camera_screen.buffer_width * ZFIX_TOP) return(cur_buf_top[idx]);
342 if (idx >= a && idx < (unsigned)camera_screen.buffer_size) return(cur_buf_bot[idx - a]);
343 return (COLOR_TRANSPARENT);
344 }
345
346
347
348
349
350 static int draw_zebra_no_aspect_adjust(int mrec, unsigned int f, color *cls) {
351 int v, s, x, y, over;
352 static int need_restore=0;
353 int viewport_height;
354 int zebra_drawn=0;
355
356 unsigned bWide = 1;
357 unsigned aspOffset = 0;
358
359 if (camera_screen.has_variable_aspect && camera_info.props.aspect_ratio)
360 {
361 if (shooting_get_prop(camera_info.props.aspect_ratio) == 0)
362 {
363 bWide = 0;
364
365 aspOffset = camera_screen.width / 8;
366 }
367 }
368
369 viewport_height = vid_get_viewport_height();
370
371
372 if (f) {
373 int step_x, step_v;
374 over = 255-conf.zebra_over;
375 if (conf.zebra_multichannel) {step_x=2; step_v=6;} else {step_x=1; step_v=3;}
376 s = aspOffset;
377 for (y=1, v=0; y<=viewport_height; ++y) {
378 for (x=0; x<camera_screen.width; x+=step_x, s+=step_x, v+=step_v) {
379 register int yy, uu, vv;
380 int sel;
381
382 if (!bWide && (x + aspOffset >= camera_screen.width - aspOffset)) continue;
383
384 yy = img_buf[v+1];
385 if (conf.zebra_multichannel) {
386 uu = (signed char)img_buf[v];
387 vv = (signed char)img_buf[v+2];
388 sel=0;
389 if (!((conf.zebra_mode == ZEBRA_MODE_ZEBRA_1 || conf.zebra_mode == ZEBRA_MODE_ZEBRA_2) && (y-x-timer)&f)) {
390 if (clip8(((yy<<12) + vv*5743 + 2048)>>12)>over) sel = 4;
391 if (clip8(((yy<<12) - uu*1411 - vv*2925 + 2048)>>12)>over) sel |= 2;
392 if (clip8(((yy<<12) + uu*7258 + 2048)>>12)>over) sel |= 1;
393 }
394 buf[s]=buf[s+1]=cls[sel];
395 }
396 else if (((conf.zebra_mode == ZEBRA_MODE_ZEBRA_1 || conf.zebra_mode == ZEBRA_MODE_ZEBRA_2) && (y-x-timer)&f)) buf[s]=COLOR_TRANSPARENT;
397 else buf[s]=(yy>over)?cl_over:(yy<conf.zebra_under)?cl_under:COLOR_TRANSPARENT;
398 if (buf[s] != COLOR_TRANSPARENT && !zebra_drawn) zebra_drawn = 1;
399 if (mrec) {
400
401 if(get_cur_buf(s)!=COLOR_TRANSPARENT) buf[s]=get_cur_buf(s);
402 if(conf.zebra_multichannel && get_cur_buf(s+1)!=COLOR_TRANSPARENT) buf[s+1]=get_cur_buf(s+1);
403 }
404 }
405 s+=camera_screen.buffer_width-camera_screen.width;
406 if (y*camera_screen.height/viewport_height == (s+camera_screen.buffer_width)/camera_screen.buffer_width) {
407 memcpy(buf+s, buf+s-camera_screen.buffer_width, camera_screen.buffer_width);
408 s+=camera_screen.buffer_width;
409 }
410 }
411 if (!zebra_drawn) f=0;
412 }
413
414 if (!f) {
415
416 if (need_restore) {
417 if (conf.zebra_restore_screen || conf.zebra_restore_osd) {
418 gui_set_need_restore();
419 } else {
420 if (mrec) {
421
422 memcpy(buf, cur_buf_top, camera_screen.buffer_width * ZFIX_TOP);
423 memcpy(buf + buffer_size - camera_screen.buffer_width * ZFIX_BOTTOM, cur_buf_bot, camera_screen.buffer_width * ZFIX_BOTTOM);
424 for (s = camera_screen.buffer_width*ZFIX_TOP; s < buffer_size-camera_screen.buffer_width*ZFIX_BOTTOM; s++) {
425 buf[s]=COLOR_TRANSPARENT;
426 }
427 } else {
428
429 memset(buf, COLOR_TRANSPARENT, buffer_size);
430 }
431 disp_zebra();
432 }
433 need_restore=0;
434 }
435 return !(conf.zebra_restore_screen && conf.zebra_restore_osd);
436
437 } else {
438 disp_zebra();
439
440 need_restore=1;
441 return 1;
442 }
443 return 0;
444 }
445
446
447 int gui_osd_draw_zebra(int show)
448 {
449 unsigned int f;
450
451 if (!gui_osd_zebra_init(show))
452 return 0;
453
454 color cls[] = {
455 COLOR_TRANSPARENT,
456 COLOR_BLUE,
457 COLOR_GREEN,
458 COLOR_CYAN,
459 COLOR_RED,
460 COLOR_MAGENTA,
461 COLOR_YELLOW,
462 COLOR_BLACK
463 };
464
465 img_buf = vid_get_viewport_active_buffer();
466 if (!img_buf) return 0;
467
468 if (timer==0)
469 {
470 draw_guard_pixel();
471 timer = 1;
472 return 0;
473 }
474
475 if (timer==1)
476 {
477 int ready;
478 static int n=0;
479 if (!camera_info.state.mode_rec) ready=1;
480 else get_property_case(camera_info.props.shooting, &ready, 4);
481 n=draw_guard_pixel();
482 if(!ready) return 0;
483 if (cur_buf_top)
484 {
485
486 if (n==1) {
487 memcpy(cur_buf_top, scr_buf, camera_screen.buffer_width*ZFIX_TOP);
488 memcpy(cur_buf_bot, scr_buf + camera_screen.buffer_size - camera_screen.buffer_width*ZFIX_BOTTOM, camera_screen.buffer_width*ZFIX_BOTTOM);
489 }
490 else {
491 memcpy(cur_buf_top, scr_buf + camera_screen.buffer_size, camera_screen.buffer_width*ZFIX_TOP);
492 memcpy(cur_buf_bot, scr_buf + 2*camera_screen.buffer_size - camera_screen.buffer_width*ZFIX_BOTTOM, camera_screen.buffer_width*ZFIX_BOTTOM);
493 }
494 }
495 }
496 ++timer;
497
498 switch (conf.zebra_mode)
499 {
500 case ZEBRA_MODE_ZEBRA_1: f = 4; break;
501 case ZEBRA_MODE_ZEBRA_2: f = 8; break;
502 case ZEBRA_MODE_SOLID: f = 1; break;
503 case ZEBRA_MODE_BLINKED_1: f = timer&1; break;
504 case ZEBRA_MODE_BLINKED_3: f = timer&4; break;
505 case ZEBRA_MODE_BLINKED_2:
506 default: f = timer&2; break;
507 }
508
509 if (camera_screen.zebra_aspect_adjust)
510 return draw_zebra_aspect_adjust(camera_info.state.mode_rec,f,cls);
511 else
512 return draw_zebra_no_aspect_adjust(camera_info.state.mode_rec,f,cls);
513 }
514 #else
515
516
517 typedef struct
518 {
519 unsigned int yuv;
520 unsigned int op;
521 } rawcolor_s;
522
523 rawcolor_s clr[10];
524 int shown = 0;
525
526
527 static void gui_osd_zebra_free()
528 {
529 shown = 0;;
530 }
531
532
533
534 static int gui_osd_zebra_init(int show)
535 {
536 color cls[] =
537 {
538 COLOR_TRANSPARENT,
539 COLOR_BLUE,
540 COLOR_GREEN,
541 COLOR_CYAN,
542 COLOR_RED,
543 COLOR_MAGENTA,
544 COLOR_YELLOW,
545 COLOR_BLACK
546 };
547
548 cl_under = BG_COLOR(user_color(conf.zebra_color));
549 cl_over = FG_COLOR(user_color(conf.zebra_color));
550
551 if (show)
552 {
553 if (!shown)
554 {
555 timer = 0;
556 shown = 1;
557 int f;
558 for (f=0; f<8; f++)
559 {
560 clr[f].yuv = color_to_rawpx(cls[f], &(clr[f].op));
561 }
562 clr[8].yuv = color_to_rawpx(cl_over, &(clr[8].op));
563 clr[9].yuv = color_to_rawpx(cl_under, &(clr[9].op));
564 }
565 }
566 else
567 {
568 if (shown)
569 {
570 erase_zebra();
571 }
572 gui_osd_zebra_free();
573 }
574 return (shown);
575 }
576
577
578
579
580 static void gui_osd_draw_zebra_osd() {
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598 }
599
600
601 static void disp_zebra()
602 {
603
604 gui_osd_draw_zebra_osd();
605 }
606
607
608
609 static int draw_zebra_no_aspect_adjust(unsigned int f)
610 {
611 int x, y, over;
612 unsigned int v, bitmap_byte;
613 static int need_restore=0;
614 int viewport_height;
615 int viewport_width;
616 int viewport_byte_width;
617
618 int viewport_xoffset;
619 int viewport_yoffset;
620 int zebra_drawn=0;
621 static int d_cnt =0;
622 d_cnt++;
623
624 viewport_height = vid_get_viewport_height();
625 viewport_width = vid_get_viewport_width();
626 viewport_byte_width = vid_get_viewport_byte_width();
627 viewport_xoffset = vid_get_viewport_display_xoffset();
628 viewport_yoffset = vid_get_viewport_display_yoffset();
629
630
631 if (f)
632 {
633 if (viewport_yoffset > 0)
634 {
635
636 }
637 over = 255-conf.zebra_over;
638
639 for (y=0; y<viewport_height ; ++y)
640 {
641
642
643
644
645
646 for (x=0; x<viewport_width; x+=2)
647 {
648 v = y*(viewport_byte_width) + x + x ;
649 bitmap_byte = (y + viewport_yoffset) * viewport_byte_width + 2*(x + viewport_xoffset);
650
651 int sel = 0;
652 if (!((conf.zebra_mode == ZEBRA_MODE_ZEBRA_1 || conf.zebra_mode == ZEBRA_MODE_ZEBRA_2) && (y-x-timer)&f))
653 {
654 register int y1, uu, vv;
655 unsigned int ibuf = *(unsigned int*)(&img_buf[v&0xfffffffc]);
656 uu = (signed char)((ibuf&0xff)-128);
657 vv = (signed char)(((ibuf>>16)&0xff)-128);
658
659 y1 = (unsigned char)((ibuf>>8)&0xff);
660
661 if (conf.zebra_multichannel)
662 {
663 if (clip8(((y1<<12) + vv*5743 + 2048)>>12)>over) sel = 4;
664 if (clip8(((y1<<12) - uu*1411 - vv*2925 + 2048)>>12)>over) sel |= 2;
665 if (clip8(((y1<<12) + uu*7258 + 2048)>>12)>over) sel |= 1;
666 }
667 else
668 {
669
670
671 sel = (y1>over) ? 8 : (y1<conf.zebra_under) ? 9 : 0;
672 }
673 }
674
675 draw_dblpixel_raw(bitmap_byte, clr[sel].yuv, clr[sel].op);
676 if (sel)
677 zebra_drawn = 1;
678 }
679 }
680 if (!zebra_drawn) f = 0;
681 }
682
683 if (!f)
684 {
685
686 if (need_restore)
687 {
688
689 erase_zebra();
690 disp_zebra();
691 need_restore=0;
692 }
693 return !(conf.zebra_restore_screen && conf.zebra_restore_osd);
694 }
695 else
696 {
697
698 disp_zebra();
699 need_restore=1;
700 return 1;
701 }
702 return 0;
703 }
704
705
706 int gui_osd_draw_zebra(int show)
707 {
708 unsigned int f;
709
710
711
712 if ((vid_get_viewport_width() > camera_screen.width) || (vid_get_viewport_height() > camera_screen.height))
713 return 0;
714
715 if (!gui_osd_zebra_init(show))
716 return 0;
717
718 img_buf = vid_get_viewport_active_buffer();
719 if (!img_buf) return 0;
720
721
722 if (timer==0)
723 {
724 timer = 1;
725 return 0;
726 }
727
728 if (timer==1)
729 {
730 int ready;
731 if (!camera_info.state.mode_rec) ready=1;
732 else get_property_case(camera_info.props.shooting, &ready, 4);
733 if(!ready) return 0;
734
735 }
736 ++timer;
737
738 switch (conf.zebra_mode)
739 {
740 case ZEBRA_MODE_ZEBRA_1: f = 4; break;
741 case ZEBRA_MODE_ZEBRA_2: f = 8; break;
742 case ZEBRA_MODE_SOLID: f = 1; break;
743 case ZEBRA_MODE_BLINKED_1: f = timer&1; break;
744 case ZEBRA_MODE_BLINKED_3: f = timer&4; break;
745 case ZEBRA_MODE_BLINKED_2:
746 default: f = timer&2; break;
747 }
748
749 return draw_zebra_no_aspect_adjust(f);
750 }
751
752 #endif
753
754
755
756
757
758
759
760
761
762
763
764 int _module_unloader()
765 {
766 gui_osd_zebra_free();
767 return 0;
768 }
769
770 int _module_can_unload()
771 {
772 return conf.zebra_draw == 0;
773 }
774
775
776
777 libzebra_sym _libzebra =
778 {
779 {
780 0, _module_unloader, _module_can_unload, 0, 0
781 },
782
783 gui_osd_draw_zebra
784 };
785
786 ModuleInfo _module_info =
787 {
788 MODULEINFO_V1_MAGICNUM,
789 sizeof(ModuleInfo),
790 ZEBRA_VERSION,
791
792 ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,
793 ANY_PLATFORM_ALLOWED,
794
795 (int32_t)"Zebra Overlay (dll)",
796 MTYPE_EXTENSION,
797
798 &_libzebra.base,
799
800 CONF_VERSION,
801 CAM_SCREEN_VERSION,
802 ANY_VERSION,
803 CAM_INFO_VERSION,
804
805 0,
806 };
807
808