add pause/resume for main sequence & capturing in pause mode

This commit is contained in:
eddyem 2020-03-30 18:55:52 +03:00
parent 85da8be186
commit a1cbbd613f
3 changed files with 105 additions and 63 deletions

View File

@ -35,6 +35,9 @@ static void processKeybrd(unsigned char key, int mod, _U_ int x, _U_ int y){
key += 'a'-1;
DBG("CTRL+%c", key);
switch(key){
case 'r': // roll colorfun
win->winevt |= WINEVT_ROLLCOLORFUN;
break;
case 's': // save image
win->winevt |= WINEVT_SAVEIMAGE;
break;
@ -50,20 +53,27 @@ static void processKeybrd(unsigned char key, int mod, _U_ int x, _U_ int y){
win->zoom = 1;
win->x = 0; win->y = 0;
break;
case 27:
case 27: // esc - kill
killwindow();
break;
case 'l':
case 'c': // capture in pause mode
if(win->winevt & WINEVT_PAUSE)
win->winevt |= WINEVT_GETIMAGE;
break;
case 'l': // flip left-right
win->flip ^= WIN_FLIP_LR;
break;
case 'u':
case 'p': // pause capturing
win->winevt ^= WINEVT_PAUSE;
break;
case 'u': // flip up-down
win->flip ^= WIN_FLIP_UD;
break;
case 'Z':
case 'Z': // zoom+
win->zoom *= 1.1f;
calc_win_props(NULL, NULL);
break;
case 'z':
case 'z': // zoom-
win->zoom /= 1.1f;
calc_win_props(NULL, NULL);
break;
@ -155,9 +165,12 @@ typedef struct{
#define SHIFT_K(key) (key | (GLUT_ACTIVE_SHIFT<<8))
#define ALT_K(key) (key | (GLUT_ACTIVE_ALT<<8))
static const menuentry entries[] = {
{"Flip image LR", 'l'},
{"Flip image UD", 'u'},
{"Capture in pause mode (c)", 'c'},
{"Flip image LR (l)", 'l'},
{"Flip image UD (u)", 'u'},
{"Make a pause/continue (p)", 'p'},
{"Restore zoom (0)", '0'},
{"Roll colorfun (ctrl+r)", CTRL_K('r')},
{"Save image (ctrl+s)", CTRL_K('s')},
{"Close this window (ESC)", 27},
{"Quit (ctrl+q)", CTRL_K('q')},

View File

@ -43,51 +43,33 @@ void signals(int sig){
static int GrabImage(fc2Context context, fc2Image *convertedImage){
fc2Error error;
fc2Image rawImage;
// start capture
FC2FNE(fc2StartCapture, context);
error = fc2CreateImage(&rawImage);
if (error != FC2_ERROR_OK)
{
if(error != FC2_ERROR_OK){
printf("Error in fc2CreateImage: %s\n", fc2ErrorToDescription(error));
return -1;
}
// Retrieve the image
error = fc2RetrieveBuffer(context, &rawImage);
if (error != FC2_ERROR_OK)
{
if (error != FC2_ERROR_OK){
printf("Error in retrieveBuffer: %s\n", fc2ErrorToDescription(error));
return -1;
}
// Convert image to gray
windowData *win = getWin();
if(win) pthread_mutex_lock(&win->mutex);
error = fc2ConvertImageTo(FC2_PIXEL_FORMAT_MONO8, &rawImage, convertedImage);
if (error != FC2_ERROR_OK)
{
if(win) pthread_mutex_unlock(&win->mutex);
if(error != FC2_ERROR_OK){
printf("Error in fc2ConvertImageTo: %s\n", fc2ErrorToDescription(error));
return -1;
}
fc2StopCapture(context);
fc2DestroyImage(&rawImage);
return 0;
}
// main thread to deal with image
void* image_thread(_U_ void *data){
FNAME();
//struct timeval tv;
windowData *win = getWin();
// int w = win->image->w, h = win->image->h, x,y, id = win->ID;
// GLubyte i;
while(1){
pthread_mutex_lock(&win->mutex);
if(win->killthread){
pthread_mutex_unlock(&win->mutex);
DBG("got killthread");
pthread_exit(NULL);
}
// Do something here
//win->image->changed = 1;
pthread_mutex_unlock(&win->mutex);
usleep(10000);
}
}
/**
* Convert gray (unsigned short) into RGB components (GLubyte)
* @argument L - gray level
@ -127,26 +109,39 @@ static void gray2rgb(double gray, GLubyte *rgb){
typedef enum{
COLORFN_LINEAR, // linear
COLORFN_LOG, // ln
COLORFN_SQRT // sqrt
COLORFN_SQRT, // sqrt
COLORFN_MAX // end of list
} colorfn_type;
static colorfn_type ft = COLORFN_LINEAR;
static double linfun(double arg){ return arg; } // bung for PREVIEW_LINEAR
static double logfun(double arg){ return log(1.+arg); } // for PREVIEW_LOG
static double (*colorfun)(double) = linfun; // default function to convert color
void change_colorfun(colorfn_type f){
static void change_colorfun(colorfn_type f){
DBG("New colorfn: %d", f);
switch (f){
case COLORFN_LINEAR:
colorfun = linfun;
break;
case COLORFN_LOG:
colorfun = logfun;
ft = COLORFN_LOG;
break;
default: // sqrt
case COLORFN_SQRT:
colorfun = sqrt;
ft = COLORFN_SQRT;
break;
default: // linear
colorfun = linfun;
ft = COLORFN_LINEAR;
}
}
static void roll_colorfun(){
colorfn_type t = ++ft;
if(t == COLORFN_MAX) t = COLORFN_LINEAR;
change_colorfun(t);
}
static void change_displayed_image(windowData *win, fc2Image *convertedImage){
if(!win || !win->image) return;
rawimage *im = win->image;
@ -210,6 +205,36 @@ static void saveImages(fc2Image *convertedImage, char *prefix){
// and save FITS here
}
// manage some menu/shortcut events
static void winevt_manage(windowData *win, fc2Image *convertedImage){
if(win->winevt & WINEVT_SAVEIMAGE){ // save image
DBG("Try to make screenshot");
saveImages(convertedImage, "ScreenShot");
win->winevt &= ~WINEVT_SAVEIMAGE;
}
if(win->winevt & WINEVT_ROLLCOLORFUN){
roll_colorfun();
win->winevt &= ~WINEVT_ROLLCOLORFUN;
change_displayed_image(win, convertedImage);
}
}
// main thread to deal with image
void* image_thread(_U_ void *data){
FNAME();
fc2Image *img = (fc2Image*) data;
while(1){
windowData *win = getWin();
if(!win) pthread_exit(NULL);
if(win->killthread){
DBG("got killthread");
pthread_exit(NULL);
}
if(win->winevt) winevt_manage(win, img);
usleep(10000);
}
}
int main(int argc, char **argv){
int ret = 0;
initial_setup();
@ -285,12 +310,9 @@ int main(int argc, char **argv){
VMESG("Set gain value to %gdB", G.gain);
}
FC2FNE(fc2StartCapture, context);
if(G.showimage){
imageview_init();
}
// main cycle
fc2Image convertedImage;
FC2FNE(fc2CreateImage, &convertedImage);
@ -308,41 +330,43 @@ int main(int argc, char **argv){
}
if(G.showimage){
if(!mainwin && start){
DBG("Create window @ start");
mainwin = createGLwin("Sample window", convertedImage.cols, convertedImage.rows, NULL);
start = FALSE;
if(!mainwin){
WARNX("Can't open OpenGL window, image preview will be inaccessible");
}else
pthread_create(&mainwin->thread, NULL, &image_thread, NULL); //(void*)mainwin);
pthread_create(&mainwin->thread, NULL, &image_thread, (void*)&convertedImage); //(void*)mainwin);
}
if((mainwin = getWin())){
if(mainwin->winevt & WINEVT_SAVEIMAGE){ // save image
DBG("Try to make screenshot");
saveImages(&convertedImage, "ScreenShot");
mainwin->winevt &= ~WINEVT_SAVEIMAGE;
}
DBG("change image");
if(mainwin->killthread) goto destr;
change_displayed_image(mainwin, &convertedImage);
while((mainwin = getWin())){ // test paused state & grabbing custom frames
if((mainwin->winevt & WINEVT_PAUSE) == 0) break;
if(mainwin->winevt & WINEVT_GETIMAGE){
mainwin->winevt &= ~WINEVT_GETIMAGE;
if(!GrabImage(context, &convertedImage))
change_displayed_image(mainwin, &convertedImage);
}
usleep(10000);
}
}else break;
}
if(--G.nimages <= 0) break;
}
FC2FNE(fc2DestroyImage, &convertedImage);
err = fc2StopCapture(context);
if(err != FC2_ERROR_OK){
fc2DestroyContext(context);
printf("Error in fc2StopCapture: %s\n", fc2ErrorToDescription(err));
signals(12);
}
destr:
fc2DestroyContext(context);
if((mainwin = getWin())) mainwin->winevt |= WINEVT_PAUSE;
destr:
if(G.showimage){
while(getWin());
while((mainwin = getWin())){
if(mainwin->killthread) break;
}
DBG("Close window");
clear_GL_context();
}
FC2FNE(fc2DestroyImage, &convertedImage);
fc2StopCapture(context);
fc2DestroyContext(context);
signals(ret);
return ret;
}

View File

@ -35,10 +35,15 @@ typedef struct{
int changed; // == 1 if data was changed outside (to redraw)
} rawimage;
// events from menu
// events from menu:
// temporaly stop capture of regular sequence
#define WINEVT_PAUSE (1<<0)
#define WINEVT_RESUME (1<<1)
// capture one image in pause mode
#define WINEVT_GETIMAGE (1<<1)
// save current image
#define WINEVT_SAVEIMAGE (1<<2)
// change color palette function
#define WINEVT_ROLLCOLORFUN (1<<3)
// flip image
#define WIN_FLIP_LR (1<<0)