File indexing completed on 2025-01-05 03:56:48
0001 /* -*- C++ -*- 0002 * File: halt_mt.c 0003 * Copyright 2008-2021 LibRaw LLC (info@libraw.org) 0004 * Created: Sat Mar 8, 2008 0005 * 0006 * LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a] 0007 [-v]" 0008 * 0009 0010 LibRaw is free software; you can redistribute it and/or modify 0011 it under the terms of the one of two licenses as you choose: 0012 0013 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0014 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0015 0016 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0017 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0018 0019 0020 */ 0021 #include <stdio.h> 0022 #include <string.h> 0023 #include <stdlib.h> 0024 #include <math.h> 0025 #include <pthread.h> 0026 0027 #include "libraw/libraw.h" 0028 0029 #define HANDLE_ERRORS(ret) \ 0030 do \ 0031 { \ 0032 if (ret) \ 0033 { \ 0034 fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \ 0035 if (LIBRAW_FATAL_ERROR(ret)) \ 0036 { \ 0037 libraw_close(iprc); \ 0038 return NULL; \ 0039 } \ 0040 } \ 0041 } while (0) 0042 0043 int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0; 0044 0045 pthread_mutex_t qm; 0046 char **queue = NULL; 0047 size_t qsize = 0, qptr = 0; 0048 0049 char *get_next_file() 0050 { 0051 char *ret; 0052 if (!queue) 0053 return NULL; 0054 if (qptr >= qsize) 0055 return NULL; 0056 pthread_mutex_lock(&qm); 0057 ret = queue[qptr++]; 0058 pthread_mutex_unlock(&qm); 0059 return ret; 0060 } 0061 0062 void *process_files(void *q) 0063 { 0064 int ret; 0065 int count = 0; 0066 char outfn[1024], *fn; 0067 libraw_data_t *iprc = libraw_init(0); 0068 0069 if (!iprc) 0070 { 0071 fprintf(stderr, "Cannot create libraw handle\n"); 0072 return NULL; 0073 } 0074 0075 while ((fn = get_next_file())) 0076 { 0077 0078 iprc->params.half_size = 1; /* dcraw -h */ 0079 iprc->params.use_camera_wb = use_camera_wb; 0080 iprc->params.use_auto_wb = use_auto_wb; 0081 iprc->params.output_tiff = tiff_mode; 0082 0083 ret = libraw_open_file(iprc, fn); 0084 if (verbose) 0085 fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model); 0086 HANDLE_ERRORS(ret); 0087 0088 ret = libraw_unpack(iprc); 0089 HANDLE_ERRORS(ret); 0090 0091 ret = libraw_dcraw_process(iprc); 0092 HANDLE_ERRORS(ret); 0093 0094 snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tiff" : "ppm"); 0095 0096 if (verbose) 0097 fprintf(stderr, "Writing file %s\n", outfn); 0098 ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); 0099 HANDLE_ERRORS(ret); 0100 count++; 0101 } 0102 libraw_close(iprc); 0103 return NULL; 0104 } 0105 0106 void usage(const char *p) 0107 { 0108 printf("%s: Multi-threaded LibRaw sample app. Emulates dcraw -h [-w] [-a]\n", 0109 p); 0110 printf("Options:\n" 0111 "-J n - set parallel job count (default 2)\n" 0112 "-v - verbose\n" 0113 "-w - use camera white balance\n" 0114 "-a - average image for white balance\n"); 0115 exit(1); 0116 } 0117 0118 int show_files(void *q) 0119 { 0120 char *p; 0121 int cnt = 0; 0122 while ((p = get_next_file())) 0123 { 0124 printf("%s\n", p); 0125 cnt++; 0126 } 0127 return cnt; 0128 } 0129 0130 int main(int ac, char *av[]) 0131 { 0132 int i, max_threads = 2; 0133 pthread_t *threads; 0134 if (ac < 2) 0135 usage(av[0]); 0136 0137 queue = calloc(ac - 1, sizeof(queue[0])); 0138 0139 for (i = 1; i < ac; i++) 0140 { 0141 if (av[i][0] == '-') 0142 { 0143 if (av[i][1] == 'w') 0144 use_camera_wb = 1; 0145 if (av[i][1] == 'a') 0146 use_auto_wb = 1; 0147 if (av[i][1] == 'v') 0148 verbose = 1; 0149 if (av[i][1] == 'T') 0150 tiff_mode = 1; 0151 if (av[i][1] == 'J') 0152 { 0153 max_threads = atoi(av[++i]); 0154 if (max_threads < 1) 0155 { 0156 fprintf(stderr, "Job count should be at least 1\n"); 0157 exit(1); 0158 } 0159 } 0160 } 0161 else 0162 queue[qsize++] = av[i]; 0163 } 0164 pthread_mutex_init(&qm, NULL); 0165 threads = calloc(max_threads, sizeof(threads[0])); 0166 for (i = 0; i < max_threads; i++) 0167 pthread_create(&threads[i], NULL, process_files, NULL); 0168 for (i = 0; i < max_threads; i++) 0169 { 0170 int *iptr; 0171 if (threads[i]) 0172 { 0173 pthread_join(threads[i], (void *)&iptr); 0174 } 0175 } 0176 0177 return 0; 0178 }