/* Camicro - Microscope camera viewer. * * Copyright (C) 2019 Nicolas Schodet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contact : * Web: http://ni.fr.eu.org/ * Email: */ #include #include "cli.h" #include "device.h" #include "utils.h" static bool cli_read_images(libusb_context *usb, struct device *device, int count, bool raw, const char *out, GError **error) { g_return_val_if_fail(error == NULL || *error == NULL, false); if (!device_start(device, error)) return false; bool ret = true; for (int i = 0; ret && i < count;) { /* Read image. */ GError *image_error = NULL; struct image *image = device_read(device, &image_error); if (!image && image_error) { g_propagate_error(error, image_error); ret = false; } else if (!image) { /* No image yet, handle events. */ int r = libusb_handle_events(usb); if (r) utils_fatal("unable to handle libusb events: %s", libusb_strerror(r)); } else { /* Image received. */ if (!raw && image->format != IMAGE_FORMAT_XBGR32) { struct image *cimage = image_new(image->width, image->height, image->width * 4, IMAGE_FORMAT_XBGR32); image_convert(cimage, image); image_unref(image); image = cimage; } char *name = g_strdup_printf(out, i); utils_info("write %s", name); if (!image_save(image, name, error)) ret = false; g_free(name); image_unref(image); i++; } } if (!device_stop(device, ret ? error : NULL)) return false; return ret; } int cli_run(struct options *options) { libusb_context *usb; int r = libusb_init(&usb); if (r) utils_fatal("unable to initialize libusb: %s", libusb_strerror(r)); GError *error = NULL; struct device *device = device_open(usb, &error); if (!device) utils_fatal("unable to find device: %s", error->message); const struct device_info *info = device_get_info(device); if (options->exposure_ms > 0.0) device_set_exposure(device, options->exposure_ms); if (options->gain > 0.0) device_set_gain(device, options->gain); int width = -1, height = -1; for (int i = 0; width == -1 && i < info->resolutions; i++) { const struct device_info_resolution *ir = &info->resolution[i]; if ((options->width == -1 || options->width == ir->width) && (options->height == -1 || options->height == ir->height)) { width = ir->width; height = ir->height; } } if (width == -1) utils_fatal("no matching resolution"); device_set_resolution(device, width, height, 0); if (!cli_read_images(usb, device, options->count, options->raw, options->out, &error)) utils_fatal("unable to read images: %s", error->message); if (!device_close(device, &error)) utils_fatal("unable to close device: %s", error->message); libusb_exit(usb); return EXIT_SUCCESS; }