1 /*
2   Copyright 2008-2018 LibRaw LLC (info@libraw.org)
3 
4 LibRaw is free software; you can redistribute it and/or modify
5 it under the terms of the one of two licenses as you choose:
6 
7 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
8    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
9 
10 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
11    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
12 
13    This file is generated from Dave Coffin's dcraw.c
14    dcraw.c -- Dave Coffin's raw photo decoder
15    Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net
16 
17    Look into dcraw homepage (probably http://cybercom.net/~dcoffin/dcraw/)
18    for more information
19 */
20 
21 #include <math.h>
22 #define CLASS LibRaw::
23 #include "libraw/libraw_types.h"
24 #define LIBRAW_LIBRARY_BUILD
25 #include "libraw/libraw.h"
26 #include "internal/defines.h"
27 #include "internal/var_defines.h"
28 /*
29    Search from the current directory up to the root looking for
30    a ".badpixels" file, and fix those pixels now.
31  */
bad_pixels(const char * cfname)32 void CLASS bad_pixels(const char *cfname)
33 {
34   FILE *fp = NULL;
35 #ifndef LIBRAW_LIBRARY_BUILD
36   char *fname, *cp, line[128];
37   int len, time, row, col, r, c, rad, tot, n, fixed = 0;
38 #else
39   char *cp, line[128];
40   int time, row, col, r, c, rad, tot, n;
41 #ifdef DCRAW_VERBOSE
42   int fixed = 0;
43 #endif
44 #endif
45 
46   if (!filters)
47     return;
48 #ifdef LIBRAW_LIBRARY_BUILD
49   RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 0, 2);
50 #endif
51   if (cfname)
52     fp = fopen(cfname, "r");
53   if (!fp)
54   {
55 #ifdef LIBRAW_LIBRARY_BUILD
56     imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP;
57 #endif
58     return;
59   }
60   while (fgets(line, 128, fp))
61   {
62     cp = strchr(line, '#');
63     if (cp)
64       *cp = 0;
65     if (sscanf(line, "%d %d %d", &col, &row, &time) != 3)
66       continue;
67     if ((unsigned)col >= width || (unsigned)row >= height)
68       continue;
69     if (time > timestamp)
70       continue;
71     for (tot = n = 0, rad = 1; rad < 3 && n == 0; rad++)
72       for (r = row - rad; r <= row + rad; r++)
73         for (c = col - rad; c <= col + rad; c++)
74           if ((unsigned)r < height && (unsigned)c < width && (r != row || c != col) && fcol(r, c) == fcol(row, col))
75           {
76             tot += BAYER2(r, c);
77             n++;
78           }
79     BAYER2(row, col) = tot / n;
80 #ifdef DCRAW_VERBOSE
81     if (verbose)
82     {
83       if (!fixed++)
84         fprintf(stderr, _("Fixed dead pixels at:"));
85       fprintf(stderr, " %d,%d", col, row);
86     }
87 #endif
88   }
89 #ifdef DCRAW_VERBOSE
90   if (fixed)
91     fputc('\n', stderr);
92 #endif
93   fclose(fp);
94 #ifdef LIBRAW_LIBRARY_BUILD
95   RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 1, 2);
96 #endif
97 }
98 
subtract(const char * fname)99 void CLASS subtract(const char *fname)
100 {
101   FILE *fp;
102   int dim[3] = {0, 0, 0}, comment = 0, number = 0, error = 0, nd = 0, c, row, col;
103   ushort *pixel;
104 #ifdef LIBRAW_LIBRARY_BUILD
105   RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 0, 2);
106 #endif
107 
108   if (!(fp = fopen(fname, "rb")))
109   {
110 #ifdef DCRAW_VERBOSE
111     perror(fname);
112 #endif
113 #ifdef LIBRAW_LIBRARY_BUILD
114     imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_FILE;
115 #endif
116     return;
117   }
118   if (fgetc(fp) != 'P' || fgetc(fp) != '5')
119     error = 1;
120   while (!error && nd < 3 && (c = fgetc(fp)) != EOF)
121   {
122     if (c == '#')
123       comment = 1;
124     if (c == '\n')
125       comment = 0;
126     if (comment)
127       continue;
128     if (isdigit(c))
129       number = 1;
130     if (number)
131     {
132       if (isdigit(c))
133         dim[nd] = dim[nd] * 10 + c - '0';
134       else if (isspace(c))
135       {
136         number = 0;
137         nd++;
138       }
139       else
140         error = 1;
141     }
142   }
143   if (error || nd < 3)
144   {
145 #ifdef DCRAW_VERBOSE
146     fprintf(stderr, _("%s is not a valid PGM file!\n"), fname);
147 #endif
148     fclose(fp);
149     return;
150   }
151   else if (dim[0] != width || dim[1] != height || dim[2] != 65535)
152   {
153 #ifdef DCRAW_VERBOSE
154     fprintf(stderr, _("%s has the wrong dimensions!\n"), fname);
155 #endif
156 #ifdef LIBRAW_LIBRARY_BUILD
157     imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_DIM;
158 #endif
159     fclose(fp);
160     return;
161   }
162   pixel = (ushort *)calloc(width, sizeof *pixel);
163   merror(pixel, "subtract()");
164   for (row = 0; row < height; row++)
165   {
166     fread(pixel, 2, width, fp);
167     for (col = 0; col < width; col++)
168       BAYER(row, col) = MAX(BAYER(row, col) - ntohs(pixel[col]), 0);
169   }
170   free(pixel);
171   fclose(fp);
172   memset(cblack, 0, sizeof cblack);
173   black = 0;
174 #ifdef LIBRAW_LIBRARY_BUILD
175   RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 1, 2);
176 #endif
177 }
178 #ifndef NO_LCMS
apply_profile(const char * input,const char * output)179 void CLASS apply_profile(const char *input, const char *output)
180 {
181   char *prof;
182   cmsHPROFILE hInProfile = 0, hOutProfile = 0;
183   cmsHTRANSFORM hTransform;
184   FILE *fp;
185   unsigned size;
186 
187   if (strcmp(input, "embed"))
188     hInProfile = cmsOpenProfileFromFile(input, "r");
189   else if (profile_length)
190   {
191 #ifndef LIBRAW_LIBRARY_BUILD
192     prof = (char *)malloc(profile_length);
193     merror(prof, "apply_profile()");
194     fseek(ifp, profile_offset, SEEK_SET);
195     fread(prof, 1, profile_length, ifp);
196     hInProfile = cmsOpenProfileFromMem(prof, profile_length);
197     free(prof);
198 #else
199     hInProfile = cmsOpenProfileFromMem(imgdata.color.profile, profile_length);
200 #endif
201   }
202   else
203   {
204 #ifdef LIBRAW_LIBRARY_BUILD
205     imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
206 #endif
207 #ifdef DCRAW_VERBOSE
208     fprintf(stderr, _("%s has no embedded profile.\n"), ifname);
209 #endif
210   }
211   if (!hInProfile)
212   {
213 #ifdef LIBRAW_LIBRARY_BUILD
214     imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE;
215 #endif
216     return;
217   }
218   if (!output)
219     hOutProfile = cmsCreate_sRGBProfile();
220   else if ((fp = fopen(output, "rb")))
221   {
222     fread(&size, 4, 1, fp);
223     fseek(fp, 0, SEEK_SET);
224     oprof = (unsigned *)malloc(size = ntohl(size));
225     merror(oprof, "apply_profile()");
226     fread(oprof, 1, size, fp);
227     fclose(fp);
228     if (!(hOutProfile = cmsOpenProfileFromMem(oprof, size)))
229     {
230       free(oprof);
231       oprof = 0;
232     }
233   }
234 #ifdef DCRAW_VERBOSE
235   else
236     fprintf(stderr, _("Cannot open file %s!\n"), output);
237 #endif
238   if (!hOutProfile)
239   {
240 #ifdef LIBRAW_LIBRARY_BUILD
241     imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE;
242 #endif
243     goto quit;
244   }
245 #ifdef DCRAW_VERBOSE
246   if (verbose)
247     fprintf(stderr, _("Applying color profile...\n"));
248 #endif
249 #ifdef LIBRAW_LIBRARY_BUILD
250   RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 0, 2);
251 #endif
252   hTransform = cmsCreateTransform(hInProfile, TYPE_RGBA_16, hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
253   cmsDoTransform(hTransform, image, image, width * height);
254   raw_color = 1; /* Don't use rgb_cam with a profile */
255   cmsDeleteTransform(hTransform);
256   cmsCloseProfile(hOutProfile);
257 quit:
258   cmsCloseProfile(hInProfile);
259 #ifdef LIBRAW_LIBRARY_BUILD
260   RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 1, 2);
261 #endif
262 }
263 #endif
264