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 }