File indexing completed on 2025-01-05 03:56:48
0001 /* -*- C++ -*- 0002 * File: halt_mt_win32.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 * Win32 version 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 <windows.h> 0026 #include "libraw/libraw.h" 0027 0028 #ifdef LIBRAW_WIN32_CALLS 0029 #define snprintf _snprintf 0030 #endif 0031 0032 #define HANDLE_ERRORS(ret) \ 0033 do \ 0034 { \ 0035 if (ret) \ 0036 { \ 0037 fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \ 0038 if (LIBRAW_FATAL_ERROR(ret)) \ 0039 { \ 0040 libraw_close(iprc); \ 0041 return -1; \ 0042 } \ 0043 } \ 0044 } while (0) 0045 0046 // global settings 0047 int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0; 0048 0049 // global file queue 0050 HANDLE qmutex; 0051 char **queue = NULL; 0052 size_t qsize = 0, qptr = 0; 0053 0054 char *get_next_file() 0055 { 0056 char *ret; 0057 DWORD dwWaitResult; 0058 if (!queue) 0059 return NULL; 0060 if (qptr >= qsize) 0061 return NULL; 0062 0063 dwWaitResult = WaitForSingleObject(qmutex, // handle to mutex 0064 INFINITE); // no time-out interval 0065 switch (dwWaitResult) 0066 { 0067 // The thread got ownership of the mutex 0068 case WAIT_OBJECT_0: 0069 ret = queue[qptr++]; 0070 ReleaseMutex(qmutex); 0071 break; 0072 case WAIT_ABANDONED: 0073 return NULL; // cannot obtain the lock 0074 }; 0075 return ret; 0076 } 0077 0078 // thread routine 0079 int process_files(void *q) 0080 { 0081 int ret; 0082 int count = 0; 0083 char outfn[1024], *fn; 0084 libraw_data_t *iprc = libraw_init(0); 0085 0086 if (!iprc) 0087 { 0088 fprintf(stderr, "Cannot create libraw handle\n"); 0089 return -1; 0090 } 0091 0092 while ((fn = get_next_file())) 0093 { 0094 0095 iprc->params.half_size = 1; /* dcraw -h */ 0096 iprc->params.use_camera_wb = use_camera_wb; 0097 iprc->params.use_auto_wb = use_auto_wb; 0098 iprc->params.output_tiff = tiff_mode; 0099 0100 ret = libraw_open_file(iprc, fn); 0101 if (verbose) 0102 fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model); 0103 HANDLE_ERRORS(ret); 0104 0105 ret = libraw_unpack(iprc); 0106 HANDLE_ERRORS(ret); 0107 0108 ret = libraw_dcraw_process(iprc); 0109 HANDLE_ERRORS(ret); 0110 0111 snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tif" : "ppm"); 0112 0113 if (verbose) 0114 fprintf(stderr, "Writing file %s\n", outfn); 0115 ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); 0116 HANDLE_ERRORS(ret); 0117 count++; 0118 } 0119 libraw_close(iprc); 0120 printf("Processed %d files\n", count); 0121 return 0; 0122 } 0123 0124 void usage(const char *p) 0125 { 0126 printf("Options:\n" 0127 "-J n - set parallel job count (default 2)\n" 0128 "-v - verbose\n" 0129 "-w - use camera white balance\n" 0130 "-T - output TIFF instead of PPM\n" 0131 "-a - average image for white balance\n"); 0132 exit(1); 0133 } 0134 0135 int show_files(void *q) 0136 { 0137 char *p; 0138 int cnt = 0; 0139 while (p = get_next_file()) 0140 { 0141 printf("%s\n", p); 0142 cnt++; 0143 } 0144 return cnt; 0145 } 0146 0147 int main(int ac, char *av[]) 0148 { 0149 int i, max_threads = 2; 0150 HANDLE *threads; 0151 DWORD ThreadID; 0152 0153 if (ac < 2) 0154 usage(av[0]); 0155 0156 queue = calloc(ac - 1, sizeof(queue[0])); 0157 0158 for (i = 1; i < ac; i++) 0159 { 0160 if (av[i][0] == '-') 0161 { 0162 if (av[i][1] == 'w') 0163 use_camera_wb = 1; 0164 if (av[i][1] == 'a') 0165 use_auto_wb = 1; 0166 if (av[i][1] == 'v') 0167 verbose = 1; 0168 if (av[i][1] == 'T') 0169 tiff_mode = 1; 0170 if (av[i][1] == 'J') 0171 { 0172 max_threads = atoi(av[++i]); 0173 if (max_threads < 1) 0174 { 0175 fprintf(stderr, "Job count should be at least 1\n"); 0176 exit(1); 0177 } 0178 } 0179 } 0180 else 0181 queue[qsize++] = av[i]; 0182 } 0183 qmutex = CreateMutex(NULL, FALSE, NULL); 0184 threads = calloc(max_threads, sizeof(threads[0])); 0185 for (i = 0; i < max_threads; i++) 0186 { 0187 0188 if (NULL == 0189 (threads[i] = CreateThread(NULL, // default security attributes 0190 0, // default stack size 0191 (LPTHREAD_START_ROUTINE)process_files, 0192 NULL, // no thread function arguments 0193 0, // default creation flags 0194 &ThreadID) // receive thread identifier 0195 )) 0196 { 0197 printf("CreateThread error: %d\n", GetLastError()); 0198 return 1; 0199 } 0200 } 0201 0202 WaitForMultipleObjects(max_threads, threads, TRUE, INFINITE); 0203 0204 // Close thread and mutex handles 0205 0206 for (i = 0; i < max_threads; i++) 0207 CloseHandle(threads[i]); 0208 0209 CloseHandle(qmutex); 0210 0211 return 0; 0212 }