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

View File

@ -43,51 +43,33 @@ void signals(int sig){
static int GrabImage(fc2Context context, fc2Image *convertedImage){ static int GrabImage(fc2Context context, fc2Image *convertedImage){
fc2Error error; fc2Error error;
fc2Image rawImage; fc2Image rawImage;
// start capture
FC2FNE(fc2StartCapture, context);
error = fc2CreateImage(&rawImage); error = fc2CreateImage(&rawImage);
if (error != FC2_ERROR_OK) if(error != FC2_ERROR_OK){
{
printf("Error in fc2CreateImage: %s\n", fc2ErrorToDescription(error)); printf("Error in fc2CreateImage: %s\n", fc2ErrorToDescription(error));
return -1; return -1;
} }
// Retrieve the image // Retrieve the image
error = fc2RetrieveBuffer(context, &rawImage); error = fc2RetrieveBuffer(context, &rawImage);
if (error != FC2_ERROR_OK) if (error != FC2_ERROR_OK){
{
printf("Error in retrieveBuffer: %s\n", fc2ErrorToDescription(error)); printf("Error in retrieveBuffer: %s\n", fc2ErrorToDescription(error));
return -1; return -1;
} }
// Convert image to gray // Convert image to gray
windowData *win = getWin();
if(win) pthread_mutex_lock(&win->mutex);
error = fc2ConvertImageTo(FC2_PIXEL_FORMAT_MONO8, &rawImage, convertedImage); 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)); printf("Error in fc2ConvertImageTo: %s\n", fc2ErrorToDescription(error));
return -1; return -1;
} }
fc2StopCapture(context);
fc2DestroyImage(&rawImage); fc2DestroyImage(&rawImage);
return 0; 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) * Convert gray (unsigned short) into RGB components (GLubyte)
* @argument L - gray level * @argument L - gray level
@ -127,26 +109,39 @@ static void gray2rgb(double gray, GLubyte *rgb){
typedef enum{ typedef enum{
COLORFN_LINEAR, // linear COLORFN_LINEAR, // linear
COLORFN_LOG, // ln COLORFN_LOG, // ln
COLORFN_SQRT // sqrt COLORFN_SQRT, // sqrt
COLORFN_MAX // end of list
} colorfn_type; } colorfn_type;
static colorfn_type ft = COLORFN_LINEAR;
static double linfun(double arg){ return arg; } // bung for PREVIEW_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 logfun(double arg){ return log(1.+arg); } // for PREVIEW_LOG
static double (*colorfun)(double) = linfun; // default function to convert color 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){ switch (f){
case COLORFN_LINEAR:
colorfun = linfun;
break;
case COLORFN_LOG: case COLORFN_LOG:
colorfun = logfun; colorfun = logfun;
ft = COLORFN_LOG;
break; break;
default: // sqrt case COLORFN_SQRT:
colorfun = 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){ static void change_displayed_image(windowData *win, fc2Image *convertedImage){
if(!win || !win->image) return; if(!win || !win->image) return;
rawimage *im = win->image; rawimage *im = win->image;
@ -210,6 +205,36 @@ static void saveImages(fc2Image *convertedImage, char *prefix){
// and save FITS here // 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 main(int argc, char **argv){
int ret = 0; int ret = 0;
initial_setup(); initial_setup();
@ -285,12 +310,9 @@ int main(int argc, char **argv){
VMESG("Set gain value to %gdB", G.gain); VMESG("Set gain value to %gdB", G.gain);
} }
FC2FNE(fc2StartCapture, context);
if(G.showimage){ if(G.showimage){
imageview_init(); imageview_init();
} }
// main cycle // main cycle
fc2Image convertedImage; fc2Image convertedImage;
FC2FNE(fc2CreateImage, &convertedImage); FC2FNE(fc2CreateImage, &convertedImage);
@ -308,41 +330,43 @@ int main(int argc, char **argv){
} }
if(G.showimage){ if(G.showimage){
if(!mainwin && start){ if(!mainwin && start){
DBG("Create window @ start");
mainwin = createGLwin("Sample window", convertedImage.cols, convertedImage.rows, NULL); mainwin = createGLwin("Sample window", convertedImage.cols, convertedImage.rows, NULL);
start = FALSE; start = FALSE;
if(!mainwin){ if(!mainwin){
WARNX("Can't open OpenGL window, image preview will be inaccessible"); WARNX("Can't open OpenGL window, image preview will be inaccessible");
}else }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 = getWin())){
if(mainwin->winevt & WINEVT_SAVEIMAGE){ // save image
DBG("Try to make screenshot");
saveImages(&convertedImage, "ScreenShot");
mainwin->winevt &= ~WINEVT_SAVEIMAGE;
}
DBG("change image"); DBG("change image");
if(mainwin->killthread) goto destr;
change_displayed_image(mainwin, &convertedImage); 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; }else break;
} }
if(--G.nimages <= 0) break; if(--G.nimages <= 0) break;
} }
FC2FNE(fc2DestroyImage, &convertedImage); if((mainwin = getWin())) mainwin->winevt |= WINEVT_PAUSE;
destr:
err = fc2StopCapture(context);
if(err != FC2_ERROR_OK){
fc2DestroyContext(context);
printf("Error in fc2StopCapture: %s\n", fc2ErrorToDescription(err));
signals(12);
}
destr:
fc2DestroyContext(context);
if(G.showimage){ if(G.showimage){
while(getWin()); while((mainwin = getWin())){
if(mainwin->killthread) break;
}
DBG("Close window"); DBG("Close window");
clear_GL_context(); clear_GL_context();
} }
FC2FNE(fc2DestroyImage, &convertedImage);
fc2StopCapture(context);
fc2DestroyContext(context);
signals(ret); signals(ret);
return ret; return ret;
} }

View File

@ -35,10 +35,15 @@ typedef struct{
int changed; // == 1 if data was changed outside (to redraw) int changed; // == 1 if data was changed outside (to redraw)
} rawimage; } rawimage;
// events from menu // events from menu:
// temporaly stop capture of regular sequence
#define WINEVT_PAUSE (1<<0) #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) #define WINEVT_SAVEIMAGE (1<<2)
// change color palette function
#define WINEVT_ROLLCOLORFUN (1<<3)
// flip image // flip image
#define WIN_FLIP_LR (1<<0) #define WIN_FLIP_LR (1<<0)