1 /* -*- C++ -*-
2 * File: 4channels.cpp
3 * Copyright 2008-2021 LibRaw LLC (info@libraw.org)
4 * Created: Mon Feb 09, 2009
5 *
6 * LibRaw sample
7 * Generates 4 TIFF file from RAW data, one file per channel
8 *
9
10 LibRaw is free software; you can redistribute it and/or modify
11 it under the terms of the one of two licenses as you choose:
12
13 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
14 (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
15
16 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
17 (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
18
19
20 */
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include "libraw/libraw.h"
25
26 #ifndef LIBRAW_WIN32_CALLS
27 #include <netinet/in.h>
28 #else
29 #include <winsock2.h>
30 #endif
31
32 #ifdef LIBRAW_WIN32_CALLS
33 #define snprintf _snprintf
34 #endif
35
main(int ac,char * av[])36 int main(int ac, char *av[])
37 {
38 int i, ret;
39 int autoscale = 0, black_subtraction = 1, use_gamma = 0;
40 char outfn[1024];
41
42 LibRaw RawProcessor;
43 if (ac < 2)
44 {
45 usage:
46 printf("4channels - LibRaw %s sample. %d cameras supported\n"
47 "Usage: %s [-s N] [-g] [-A] [-B] [-N] raw-files....\n"
48 "\t-s N - select Nth image in file (default=0)\n"
49 "\t-g - use gamma correction with gamma 2.2 (not precise,use for "
50 "visual inspection only)\n"
51 "\t-A - autoscaling (by integer factor)\n"
52 "\t-B - no black subtraction\n",
53 LibRaw::version(), LibRaw::cameraCount(), av[0]);
54 return 0;
55 }
56
57 #define P1 RawProcessor.imgdata.idata
58 #define S RawProcessor.imgdata.sizes
59 #define C RawProcessor.imgdata.color
60 #define T RawProcessor.imgdata.thumbnail
61 #define P2 RawProcessor.imgdata.other
62 #define OUT RawProcessor.imgdata.params
63 #define OUTR RawProcessor.imgdata.rawparams
64
65 OUT.output_bps = 16;
66 OUT.output_tiff = 1;
67 OUT.user_flip = 0;
68 OUT.no_auto_bright = 1;
69 OUT.half_size = 1;
70
71 for (i = 1; i < ac; i++)
72 {
73 if (av[i][0] == '-')
74 {
75 if (av[i][1] == 's' && av[i][2] == 0)
76 {
77 i++;
78 OUTR.shot_select = av[i] ? atoi(av[i]) : 0;
79 }
80 else if (av[i][1] == 'g' && av[i][2] == 0)
81 use_gamma = 1;
82 else if (av[i][1] == 'A' && av[i][2] == 0)
83 autoscale = 1;
84 else if (av[i][1] == 'B' && av[i][2] == 0)
85 {
86 black_subtraction = 0;
87 }
88 else
89 goto usage;
90 continue;
91 }
92 if (!use_gamma)
93 OUT.gamm[0] = OUT.gamm[1] = 1;
94
95 int c;
96 printf("Processing file %s\n", av[i]);
97 if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
98 {
99 fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret));
100 continue; // no recycle b/c open file will recycle itself
101 }
102 if (P1.is_foveon)
103 {
104 printf("Cannot process Foveon image %s\n", av[i]);
105 continue;
106 }
107 if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
108 {
109 fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
110 continue;
111 }
112 RawProcessor.raw2image();
113 if (black_subtraction)
114 {
115 RawProcessor.subtract_black();
116 }
117
118 if (autoscale)
119 {
120 unsigned max = 0, scale = 1;
121 for (int j = 0; j < S.iheight * S.iwidth; j++)
122 for (int c = 0; c < 4; c++)
123 if (max < RawProcessor.imgdata.image[j][c])
124 max = RawProcessor.imgdata.image[j][c];
125 if (max > 0 && max < 1 << 15)
126 {
127 scale = (1 << 16) / max;
128 printf("Scaling with multiplier=%d (max=%d)\n", scale, max);
129 for (int j = 0; j < S.iheight * S.iwidth; j++)
130 for (c = 0; c < 4; c++)
131 RawProcessor.imgdata.image[j][c] *= scale;
132 }
133 printf("Black level (scaled)=%d\n", C.black * scale);
134 }
135 else
136 printf("Black level (unscaled)=%d\n", C.black);
137
138 // hack to make dcraw tiff writer happy
139 int isrgb = (P1.colors == 4 ? 0 : 1);
140 P1.colors = 1;
141 S.width = S.iwidth;
142 S.height = S.iheight;
143
144 for (int layer = 0; layer < 4; layer++)
145 {
146 if (layer > 0)
147 {
148 for (int rc = 0; rc < S.iheight * S.iwidth; rc++)
149 RawProcessor.imgdata.image[rc][0] =
150 RawProcessor.imgdata.image[rc][layer];
151 }
152 char lname[8];
153 if (isrgb)
154 {
155 snprintf(lname, 7, "%c", ((char *)("RGBG"))[layer]);
156 if (layer == 3)
157 strcat(lname, "2");
158 }
159 else
160 snprintf(lname, 7, "%c", ((char *)("GCMY"))[layer]);
161
162 if (OUTR.shot_select)
163 snprintf(outfn, sizeof(outfn), "%s-%d.%s.tiff", av[i], OUTR.shot_select,
164 lname);
165 else
166 snprintf(outfn, sizeof(outfn), "%s.%s.tiff", av[i], lname);
167
168 printf("Writing file %s\n", outfn);
169 if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
170 fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
171 }
172 }
173 return 0;
174 }
175