diff --git a/events.c b/events.c index e91ad20..9550885 100644 --- a/events.c +++ b/events.c @@ -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')}, diff --git a/grasshopper.c b/grasshopper.c index dab3c3b..259af1a 100644 --- a/grasshopper.c +++ b/grasshopper.c @@ -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; } diff --git a/imageview.h b/imageview.h index 621b4c1..cccb0a2 100644 --- a/imageview.h +++ b/imageview.h @@ -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)