/* * This function is called after a frame has been rendered. If the * cached frame is invalid we'll copy the newly rendered frame into the * cache. * Input: timestep - a timestep in [0,NumTimes-1] * Return: 1 = the cache was loaded with a new image * 0 = the cache was unchanged */ int save_frame( Display_Context dtx, int timestep ) { if (!dtx->cache[timestep]) { printf("saving frame %d\n", timestep ); #ifdef HAVE_XMESAGETBACKBUFFER dtx->cache[timestep] = mesa_read_image(); #endif dtx->all_invalid = 0; return 1; } else { return 0; } }
/* Download a raw Bayer image from the camera and return it in a malloced buffer */ static uint8_t * Dimera_Get_Full_Image (int picnum, long *size, int *width, int *height, Camera *camera, GPContext *context) { static struct mesa_image_arg ia; int32_t r; uint8_t *b, *rbuffer = NULL; int hires, s, retry; unsigned int id; *size = 0; *width = 0; *height = 0; if ( picnum != RAM_IMAGE_NUM ) { GP_DEBUG("Getting Image Info"); if ( (r = mesa_read_image_info( camera->port, picnum, NULL )) < 0 ) { ERROR("Can't get Image Info"); gp_context_error (context, _("Problem getting image information")); return NULL; } if ( r ) { hires = FALSE; *height = 240; *width = 320; } else { hires = TRUE; *height = 480; *width = 640; } GP_DEBUG("Loading Image"); if ( mesa_load_image( camera->port, picnum ) != GP_OK ) { ERROR("Image Load failed"); gp_context_error (context, _("Problem reading image from flash")); return NULL; } } else { /* load the snapped image */ hires = TRUE; *height = 480; *width = 640; } *size = *height * *width; /* 8 bits per pixel in raw CCD format */ GP_DEBUG("Downloading Image"); rbuffer = (uint8_t *)malloc( *size ); if ( rbuffer == NULL ) { gp_context_error (context, _("Out of memory")); return NULL; } ia.start = 28; ia.send = 4; ia.skip = 0; ia.repeat = ( hires ? 160 : 80 ); ia.row_cnt = 40; ia.inc1 = 1; ia.inc2 = 128; ia.inc3 = ia.inc4 = 0; /* due to reports of mesa_read_image not working for some cameras */ /* this is changed to use mesa_read_row */ #if 0 id = gp_context_progress_start (context, *height + 4, _("Downloading image...")); for ( ia.row = 4, b = rbuffer; ia.row < (height + 4) ; ia.row += ia.row_cnt, b += s ) { GP_DEBUG("Downloading Image"); for ( retry = 10;; ) { s = mesa_read_image( camera->port, b, &ia ); if( s > 0) break; if ( (s == GP_ERROR_TIMEOUT || s == GP_ERROR_CORRUPTED_DATA) && --retry > 0) { GP_DEBUG( "Dimera_Get_Full_Image: retrans"); continue; } GP_DEBUG( "Dimera_Get_Full_Image: read error %d (retry %d)",s,retry); /* retry count exceeded, or other error */ free( rbuffer ); *size = 0; gp_context_error (context, _("Problem downloading image")); return NULL; } gp_context_progress_update (context, id, ia.row); if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { free( rbuffer ); *size = 0; gp_context_error (context, _("User canceled download")); return NULL; } } #else id = gp_context_progress_start (context, *height + 4, _("Downloading image...")); for ( ia.row = 4, b = rbuffer; ia.row < (*height + 4) ; ia.row++, b += s ) { GP_DEBUG("Downloading Image"); for ( retry = 10;; ) { s = mesa_read_row( camera->port, b, &ia ); if( s > 0) break; if ( (s == GP_ERROR_TIMEOUT || s == GP_ERROR_CORRUPTED_DATA) && --retry > 0) { GP_DEBUG("Dimera_Get_Full_Image: retrans"); continue; } GP_DEBUG( "Dimera_Get_Full_Image: read error %d (retry %d)",s,retry); /* retry count exceeded, or other error */ free( rbuffer ); *size = 0; gp_context_error (context, _("Problem downloading image")); return NULL; } gp_context_progress_update (context, id, ia.row); if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { free( rbuffer ); *size = 0; return NULL; } } gp_context_progress_stop (context, id); #endif return (rbuffer); }
/* * return and image with raw pixels expanded. */ uint16_t * mesa_get_image( GPPort *port, int image ) { static uint8_t buffer[640*480L]; static struct mesa_image_info info; static struct mesa_image_arg ia; uint8_t *b = buffer; uint16_t *rbuffer; int r, res; unsigned long size, i; if ( image != RAM_IMAGE_NUM ) { if ( mesa_load_image( port, image ) != GP_OK ) { mesa_flush( port, 100 ); return NULL; } if ( mesa_read_image_info( port, image, &info ) < 0 ) { mesa_flush( port, 100 ); return NULL; } if ( info.standard_res ) { res = 1; size = 320*240; } else { res = 0; size = 640*480; } } else { res = 0; size = 640*480; } rbuffer = (uint16_t *)malloc( size*(sizeof (uint16_t)) ); if ( rbuffer == NULL ) return NULL; ia.start = 28; ia.send = 4; ia.skip = 0; ia.repeat = (res ? 80 : 160); ia.row_cnt = 40; ia.inc1 = 1; ia.inc2 = 128; ia.inc3 = ia.inc4 = 0; for ( ia.row = 4; ia.row < (res ? 244 : 484) ; ia.row += ia.row_cnt ) { if ( (r = mesa_read_image( port, b, &ia )) < 0 ) { free( rbuffer ); return NULL; } b += r; } for ( i = 0; i < size; i++ ) { *rbuffer++ = pixelTable[*b++]; } return rbuffer; }
/* * return and raw image retransmit on errors */ uint8_t * mesa_get_image( GPPort *port, int image ) { static struct mesa_image_info info; static struct mesa_image_arg ia; uint8_t *rbuffer, *b; int r, res, retry; unsigned long size; if ( image != RAM_IMAGE_NUM ) { if ( mesa_load_image( port, image ) < 0 ) { mesa_flush( port, 100 ); return NULL; } if ( mesa_read_image_info( port, image, &info ) < 0 ) { mesa_flush( port, 100 ); return NULL; } if ( info.standard_res ) { res = 1; size = 320*240; } else { res = 0; size = 640*480; } } else { res = 0; size = 640*480; } rbuffer = (uint8_t *)malloc( size ); if ( rbuffer == NULL ) return NULL; b = rbuffer; ia.start = 28; ia.send = 4; ia.skip = 0; ia.repeat = (res ? 80 : 160); ia.row_cnt = 40; ia.inc1 = 1; ia.inc2 = 128; ia.inc3 = ia.inc4 = 0; for ( ia.row = 4; ia.row < (res ? 244 : 484) ; ia.row += ia.row_cnt ) { for ( retry = 10;; ) { if ( (r = mesa_read_image( port, b, &ia )) > 0) break; /* if checksum error count retries */ if ( r == -2 && --retry > 0) continue; /* not exceeded, try again */ /* error, exit */ free( rbuffer ); return NULL; } b += r; } return rbuffer; }