Hi,
Here is another version for those with cameras like mine (A720is) that have plenty of ram available.
This version allocates two viewport memory buffers. After creating a stereo pair if you go into alt mode you can use the up/down keys to change the stereo alignment vertically. Use the left/right to change the alignment horizontally in Anaglyph mode. But in pairs mode the left/right keys will move both pairs to another place inside the image. This is fun. It allows you to scroll left and right in stereo.
//Stereo pair display test code
// Put this after the line #include "motion_detector.h" in main.c
#include "gui_draw.h"
#define PAIRS_MODE 1
#define GRAY_MODE 2
#define COLOR_MODE 3
static char * imgbuf1 = 0;
static int clip(int v) {
if (v<0) v=0;
if (v>255) v=255;
return v;
}
static int clips(int v) {
if (v<-127) v=-127;
if (v>127) v=127;
return v;
}
static void writeDiag(char* string){
static char buffer[30];
strcpy(buffer, string);
draw_string(10, 10, buffer, conf.osd_color);
}
/* in this version the stereo mode is hardwired. In my own version I have it in the conf structure as conf.stereo_mode */
#define STEREO_MODE PAIRS_MODE
void stereo_pair() {
int x, y, y1, dx1, dy1;
int ry, yd, ru, rv, vd, lu, lv;
static unsigned char *img;
static char str[15];
static int viewport_height;
static int viewport_width;// screenwidth * 3
static int dx = 0, dy = 0;
static int stereoStage = 0;
static int viewport_sizeb;
char *imgp, *imgbufp, *imgbuf1p;
if(!STEREO_MODE) return;
img=((mode_get()&MODE_MASK) == MODE_PLAY)?vid_get_viewport_fb_d():((kbd_is_key_pressed(KEY_SHOOT_HALF))?vid_get_viewport_fb():vid_get_viewport_live_fb());
if (img==NULL) img = vid_get_viewport_fb();
viewport_width = screen_width * 3;
viewport_height = vid_get_viewport_height();
viewport_sizeb = viewport_height * viewport_width;
if((mode_get()&MODE_MASK) == MODE_PLAY) {
if (kbd_is_key_pressed(KEY_SHOOT_HALF)) {
if(imgbuf == 0) imgbuf = malloc(viewport_sizeb);
if(imgbuf1 == 0) imgbuf1 = malloc(viewport_sizeb);
if(!imgbuf || !imgbuf1) {
writeDiag("No memory");
return;
}
if(stereoStage <= 0) {
if((img[0] == 255) && (img[1] == 254) && (img[2] == 253)) return;
if(imgbuf) {
memcpy(imgbuf,img, viewport_sizeb);
img[0] = 255;// indicate that this has been saved
img[1] = 254;
img[2] = 253;
stereoStage = 1;
writeDiag("Left image saved");
}
return;
}
if(stereoStage == 1) {
if(imgbuf) {
if((img[0] == 255) && (img[1] == 254) && (img[2] == 253)) return;
memcpy(imgbuf1,img, viewport_sizeb);
stereoStage = 2;
return;
}
return;
}
if(stereoStage == 2) {
dx = 0;
dy = 0;
if(STEREO_MODE == PAIRS_MODE) {
for(y=0;y<viewport_height;y++) {
memcpy(img + y * viewport_width,
imgbuf + y * viewport_width + viewport_width/4, viewport_width/2);
memcpy(img + y * viewport_width + viewport_width/2,
imgbuf1 + y * viewport_width + viewport_width/4, viewport_width/2);
}
}
else if(STEREO_MODE == GRAY_MODE){
for(x = 0; x < viewport_sizeb; x+=6){// grayscale anaglyph (R= leftY, G=rightY, B=rightY)
ry = imgbuf1[x + 1];
yd = ry - imgbuf[x + 1];
img[x] = (signed char)clips((692 * yd)/4096);// new u
img[x + 1] = (1225 * imgbuf[x + 1] + 2871 * ry) / 4096;//new y0
img[x + 2] = (signed char)clips(-yd/2);// new v
img[x + 3] = (1225 * imgbuf[x + 3] + 2871 * imgbuf1[x + 3]) / 4096;//new y1
img[x + 4] = (1225 * imgbuf[x + 4] + 2871 * imgbuf1[x + 4]) / 4096;//new y2
img[x + 5] = (1225 * imgbuf[x + 5] + 2871 * imgbuf1[x + 5]) / 4096;//new y3
}
}
else{
for(x = 0; x < viewport_sizeb; x+=6){// color anaglyph (R= leftR, G=rightG, B=rightB)
ry = imgbuf1[x + 1];
yd = ry - imgbuf[x + 1];
ru = (signed char) imgbuf1[x];
rv = (signed char) imgbuf1[x + 2];
lu = (signed char) imgbuf[x];
lv = (signed char) imgbuf[x + 2];
vd = rv - lv;
img[x] = (signed char)clips(ru + (971 * vd + 692 * yd) / 4096);// new u
img[x + 2] = (signed char)clips(-yd/2 + (2871 * lv + 1225 * rv) / 4096);// new v
img[x + 1] = clip((1225 * imgbuf[x + 1] + 2871 * ry - 1712 * vd) / 4096);//new y0
img[x + 3] = clip((1225 * imgbuf[x + 3] + 2871 * imgbuf1[x + 3] - 1712 * vd) / 4096);//new y1
img[x + 4] = clip((1225 * imgbuf[x + 4] + 2871 * imgbuf1[x + 4] - 1712 * vd) / 4096);//new y2
img[x + 5] = clip((1225 * imgbuf[x + 5] + 2871 * imgbuf1[x + 5] - 1712 * vd) / 4096);//new y3
}
}
img[0] = 255;// indicate that this is stereo
img[1] = 254;
img[2] = 253;
for(y=0;y<screen_height;y++) for(x = 0; x < screen_width;x++) draw_pixel(x,y,0);// clear the screen
stereoStage = -1;
return;
}
}
else {
if((img[0] != 255) || (img[1] != 254) || (img[2] != 253)) return;
if((stereoStage >= 0) || (gui_get_mode() != GUI_MODE_ALT)) return;
dx1 = dx;
dy1 = dy;
if (kbd_is_key_pressed(KEY_RIGHT)) {
dx = dx - 6;
}
if (kbd_is_key_pressed(KEY_LEFT)) {
dx = dx + 6;
}
if (kbd_is_key_pressed(KEY_DOWN)) {
dy = dy - 1;
}
if (kbd_is_key_pressed(KEY_UP)) {
dy = dy + 1;
}
if((dy1 == dy) && (dx1 == dx)) return;
if(STEREO_MODE == PAIRS_MODE) {
for(y=0;y<viewport_height;y++) {
memcpy(img + y * viewport_width,
imgbuf + y * viewport_width + viewport_width/4 + dx, viewport_width/2);
y1 = y + dy;
if((y1 < 0) || (y1 >= viewport_height)) continue;
memcpy(img + y * viewport_width + viewport_width/2,
imgbuf1 + y1 * viewport_width + viewport_width/4 + dx, viewport_width/2);
}
}
else if(STEREO_MODE == GRAY_MODE){
for(y=0;y<viewport_height;y++) {
y1 = y + dy;
if((y1 < 0) || (y1 >= viewport_height)) continue;
if((dx < 0) && (y1 == 0)) continue;
if((dx > 0) && (y1 == viewport_height-1)) continue;
imgp = img + y * viewport_width;
imgbufp = imgbuf + y * viewport_width;
imgbuf1p = imgbuf1 + y1 * viewport_width;
for(x = 0; x < viewport_width; x+=6){// grayscale anaglyph (R= leftY, G=rightY, B=rightY)
ry = imgbuf1p[dx + x + 1];
yd = ry - imgbufp[x + 1];
imgp[x] = (signed char)clips((692 * yd)/4096);// new u
imgp[x + 1] = (1225 * imgbufp[x + 1] + 2871 * ry) / 4096;//new y0
imgp[x + 2] = (signed char)clips(-yd/2);// new v
imgp[x + 3] = (1225 * imgbufp[x + 3] + 2871 * imgbuf1p[dx + x + 3]) / 4096;//new y1
imgp[x + 4] = (1225 * imgbufp[x + 4] + 2871 * imgbuf1p[dx + x + 4]) / 4096;//new y2
imgp[x + 5] = (1225 * imgbufp[x + 5] + 2871 * imgbuf1p[dx + x + 5]) / 4096;//new y3
}
}
}
else{
for(y=0;y<viewport_height;y++) {
y1 = y + dy;
if((y1 < 0) || (y1 >= viewport_height)) continue;
if((dx < 0) && (y1 == 0)) continue;
if((dx > 0) && (y1 == viewport_height-1)) continue;
imgp = img + y * viewport_width;
imgbufp = imgbuf + y * viewport_width;//left
imgbuf1p = imgbuf1 + y1 * viewport_width;// right, shifting is done here
for(x = 0; x < viewport_width; x+=6){// color anaglyph (R= leftR, G=rightG, B=rightB)
ru = (signed char) imgbuf1p[dx + x];
ry = imgbuf1p[dx + x + 1];
rv = (signed char) imgbuf1p[dx + x + 2];
lu = (signed char) imgbufp[x];
yd = ry - imgbufp[x + 1];
lv = (signed char) imgbufp[x + 2];
vd = rv - lv;
imgp[x] = (signed char)clips(ru + (971 * vd + 692 * yd) / 4096);// new u
imgp[x + 1] = clip((1225 * imgbuf1p[dx + x + 1] + 2871 * ry - 1712 * vd) / 4096);//new y0
imgp[x + 2] = (signed char)clips(-yd/2 + (2871 * lv + 1225 * rv) / 4096);// new v
imgp[x + 3] = clip((1225 * imgbufp[x + 3] + 2871 * imgbuf1p[dx + x + 3] - 1712 * vd) / 4096);//new y1
imgp[x + 4] = clip((1225 * imgbufp[x + 4] + 2871 * imgbuf1p[dx + x + 4] - 1712 * vd) / 4096);//new y2
imgp[x + 5] = clip((1225 * imgbufp[x + 5] + 2871 * imgbuf1p[dx + x + 5] - 1712 * vd) / 4096);//new y3
}
}
}
img[0] = 255;// indicate that this is stereo
img[1] = 254;
img[2] = 253;
for(y=0;y<screen_height;y++) for(x = 0; x < screen_width;x++) draw_pixel(x,y,0);// clear the screen
sprintf(str, "dx:%2d dy:%2d", dx/6,dy);
str[11]=0;
draw_string(0, 0, str, conf.osd_color);
}
}
return;
}
//end of stereo pair test code. Put the line stereo_pair(); after the histogram_process(); line below in main.c