static void write_raw (UcaRingBuffer *buffer, Options *opts) { guint n_frames; gsize size; size = uca_ring_buffer_get_block_size (buffer); n_frames = uca_ring_buffer_get_num_blocks (buffer); for (gint i = 0; i < n_frames; i++) { FILE *fp; gchar *filename; gpointer data; if (opts->filename) filename = g_strdup_printf ("%s-%08i.raw", opts->filename, i); else filename = g_strdup_printf ("frame-%08i.raw", i); fp = fopen(filename, "wb"); data = uca_ring_buffer_get_read_pointer (buffer); fwrite (data, size, 1, fp); fclose (fp); g_free (filename); } }
static void write_tiff (UcaRingBuffer *buffer, Options *opts, guint width, guint height, guint bits_per_pixel) { TIFF *tif; guint32 rows_per_strip; guint n_frames; guint bits_per_sample; gsize bytes_per_pixel; if (opts->filename) tif = TIFFOpen (opts->filename, "w"); else tif = TIFFOpen ("frames.tif", "w"); n_frames = uca_ring_buffer_get_num_blocks (buffer); rows_per_strip = TIFFDefaultStripSize (tif, (guint32) - 1); bytes_per_pixel = get_bytes_per_pixel (bits_per_pixel); bits_per_sample = bits_per_pixel > 8 ? 16 : 8; /* Write multi page TIFF file */ TIFFSetField (tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE); for (guint i = 0; i < n_frames; i++) { gpointer data; gsize offset = 0; data = uca_ring_buffer_get_read_pointer (buffer); TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, width); TIFFSetField (tif, TIFFTAG_IMAGELENGTH, height); TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample); TIFFSetField (tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, rows_per_strip); TIFFSetField (tif, TIFFTAG_PAGENUMBER, i, n_frames); for (guint y = 0; y < height; y++, offset += width * bytes_per_pixel) TIFFWriteScanline (tif, data + offset, y, 0); TIFFWriteDirectory (tif); } TIFFClose (tif); }
/** * uca_camera_grab: * @camera: A #UcaCamera object * @data: (type gulong): Pointer to suitably sized data buffer. Must not be * %NULL. * @error: Location to store a #UcaCameraError error or %NULL * * Grab a frame a single frame and store the result in @data. * * You must have called uca_camera_start_recording() before, otherwise you will * get a #UCA_CAMERA_ERROR_NOT_RECORDING error. */ gboolean uca_camera_grab (UcaCamera *camera, gpointer data, GError **error) { UcaCameraClass *klass; gboolean result = FALSE; /* FIXME: this prevents accessing two independent cameras simultanously. */ static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_return_val_if_fail (UCA_IS_CAMERA(camera), FALSE); klass = UCA_CAMERA_GET_CLASS (camera); g_return_val_if_fail (klass != NULL, FALSE); g_return_val_if_fail (klass->grab != NULL, FALSE); g_return_val_if_fail (data != NULL, FALSE); if (!camera->priv->buffered) { g_static_mutex_lock (&mutex); if (!camera->priv->is_recording && !camera->priv->is_readout) { g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, "Camera is neither recording nor in readout mode"); } else { #ifdef WITH_PYTHON_MULTITHREADING if (Py_IsInitialized ()) { PyGILState_STATE state = PyGILState_Ensure (); Py_BEGIN_ALLOW_THREADS g_static_mutex_lock (&access_lock); result = (*klass->grab) (camera, data, error); g_static_mutex_unlock (&access_lock); Py_END_ALLOW_THREADS PyGILState_Release (state); } else { g_static_mutex_lock (&access_lock); result = (*klass->grab) (camera, data, error); g_static_mutex_unlock (&access_lock); } #else g_static_mutex_lock (&access_lock); result = (*klass->grab) (camera, data, error); g_static_mutex_unlock (&access_lock); #endif } g_static_mutex_unlock (&mutex); } else { gpointer buffer; if (camera->priv->ring_buffer == NULL) return FALSE; /* * Spin-lock until we can read something. This shouldn't happen to * often, as buffering is usually used in those cases when the camera is * faster than the software. */ while (!uca_ring_buffer_available (camera->priv->ring_buffer)) ; buffer = uca_ring_buffer_get_read_pointer (camera->priv->ring_buffer); if (buffer == NULL) { g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_END_OF_STREAM, "Ring buffer is empty"); } else { memcpy (data, buffer, uca_ring_buffer_get_block_size (camera->priv->ring_buffer)); result = TRUE; } } return result; }