1 /*
2 * PTblender $id$
3 *
4 * Based on the program PTStitcher by Helmut Dersch.
5 *
6 * Implements the colour and brightness correction originally found
7 * in PTStitcher.
8 *
9 * Jan 2006
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; see the file COPYING. If not, a copy
23 * can be downloaded from http://www.gnu.org/licenses/gpl.html, or
24 * obtained by writing to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 *
27 *
28 * Author: Daniel M German dmgerman at uvic doooot ca
29 *
30 */
31
32
33 #include <stdlib.h>
34 #include <assert.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <sys/types.h>
38 #include <errno.h>
39
40 #ifndef _MSC_VER
41 #include <unistd.h>
42 #else
43 #include "compat_win32/getopt.h"
44 #endif
45
46
47 #include "filter.h"
48 #include "panorama.h"
49 #include "PTcommon.h"
50 #include "ColourBrightness.h"
51 #include "pttiff.h"
52
53 #define DEFAULT_PREFIX "blended%04d"
54
55 #define PT_BLENDER_USAGE "PTblender [options] <tiffFiles>+\n\n"\
56 "Options:\n"\
57 " -p <prefix>\tPrefix for output filename. Defaults to blended%%4d\n"\
58 " -k <index>\tIndex to image to use as a reference (0-based, defaults to 0)\n"\
59 " -t [0,1,2]\tType of colour correction:\n"\
60 " \t\t\t 0 full (default), 1 brightness only, 2 colour only\n"\
61 " -c\t\tOutput curves smooth (Output 1 per each corrected file)\n"\
62 " -m\t\tOutput curves arbitrary map (Output 1 per each corrected file)\n"\
63 " -f\t\tForce processing (ignore warnings)\n"\
64 " -x\t\tDelete source files (use with care)\n"\
65 " -q\t\tQuiet run\n"\
66 " -h\t\tShow this message\n"\
67 "\n"
68
69 #define PT_BLENDER_VERSION "PTblender Version " VERSION ", originally written by Helmut Dersch, rewritten by Daniel M German\n"
70
71
main(int argc,char * argv[])72 int main(int argc,char *argv[])
73 {
74 int returnValue = -1;
75 int opt;
76 int referenceImage = 0;
77 fullPath *ptrInputFiles = NULL;
78 fullPath *ptrOutputFiles = NULL;
79
80 int counter;
81 char outputPrefix[MAX_PATH_LENGTH];
82 char *endPtr;
83 int filesCount = 0;
84 char tempString[MAX_PATH_LENGTH];
85 int base = 0;
86 int outputCurvesType = 0; // if 1 => create Photoshop curve files (.acv)
87 int typeCorrection = 0;
88 int ptForceProcessing = 0;
89 int ptDeleteSources = 0;
90
91 counter = 0;
92
93 printf(PT_BLENDER_VERSION);
94
95
96 strcpy(outputPrefix, DEFAULT_PREFIX);
97
98 while ((opt = getopt(argc, argv, "p:k:t:fqcmh")) != -1) {
99
100 // o and f -> set output file
101 // h -> help
102 // q -> quiet?
103 // k -> base image, defaults to first
104
105 switch(opt) { // fhoqs f: 102 h:104 111 113 115 o:f:hsq
106 case 'p':
107 if (strlen(optarg) < MAX_PATH_LENGTH) {
108 strcpy(outputPrefix, optarg);
109 } else {
110 PrintError("Illegal length for output prefix");
111 goto end;
112 }
113 break;
114 case 'k':
115 referenceImage = strtol(optarg, &endPtr, 10);
116 if (errno != 0) {
117 PrintError("Invalid integer in -k option");
118 goto end;
119 }
120 break;
121 case 't':
122 typeCorrection = strtol(optarg, &endPtr, 10);
123 if (errno != 0 || (typeCorrection < 0 || typeCorrection > 2)) {
124 PrintError("Invalid integer in -t option");
125 goto end;
126 }
127 break;
128 case 'f':
129 ptForceProcessing = 1;
130 case 'q':
131 ptQuietFlag = 1;
132 break;
133 case 'c':
134 if (outputCurvesType == CB_OUTPUT_CURVE_ARBITRARY) {
135 PrintError("Can't use both -c and -m options");
136 goto end;
137 }
138 outputCurvesType = CB_OUTPUT_CURVE_SMOOTH;
139 break;
140 case 'm':
141 if (outputCurvesType == CB_OUTPUT_CURVE_SMOOTH) {
142 PrintError("Can't use both -c and -m options");
143 goto end;
144 }
145 outputCurvesType = CB_OUTPUT_CURVE_ARBITRARY;
146 break;
147 case 'x':
148 ptDeleteSources = 1;
149 break;
150 case 'h':
151 printf(PT_BLENDER_USAGE);
152 returnValue = 0;
153 goto end;
154 default:
155 break;
156 }
157 }
158
159 filesCount = argc - optind;
160
161 if ((ptrInputFiles = calloc(filesCount, sizeof(fullPath))) == NULL ||
162 (ptrOutputFiles = calloc(filesCount, sizeof(fullPath))) == NULL) {
163 PrintError("Not enough memory");
164 goto end;
165 }
166
167 base = optind;
168 for (; optind < argc; optind++) {
169 char *currentParm;
170
171 currentParm = argv[optind];
172
173 if (StringtoFullPath(&ptrInputFiles[optind-base], currentParm) !=0) { // success
174 PrintError("Syntax error: Not a valid pathname");
175 goto end;
176 }
177 }
178
179 if (filesCount <= 0) {
180 PrintError("No files specified in the command line");
181 fprintf(stderr, PT_BLENDER_USAGE);
182 goto end;
183 }
184
185 if (referenceImage < 0 || referenceImage >= filesCount) {
186 PrintError(tempString, "Illegal reference image number %d. It should be between 0 and %d\n",
187 referenceImage, filesCount-1);
188 goto end;
189 }
190
191 //We can't output curves for type 1 or 2 corrections
192 if (outputCurvesType != 0) {
193 if (typeCorrection!= 0) {
194 PrintError("Output of curves is not supported for correction type %d", typeCorrection);
195 goto end;
196 }
197 }
198 if (panoFileOutputNamesCreate(ptrOutputFiles, filesCount, outputPrefix) == 0) {
199 goto end;
200 }
201
202
203
204 if (!ptForceProcessing) {
205 char *temp;
206 if ((temp = panoFileExists(ptrOutputFiles, filesCount)) != NULL) {
207 PrintError("Output filename(s) exists. Use -f to overwrite");
208 goto end;
209 }
210
211 if (!panoTiffVerifyAreCompatible(ptrInputFiles, filesCount, TRUE)) {
212 PrintError("TIFFs are not compatible");
213 goto end;
214 }
215 }
216
217 if (! ptQuietFlag) printf("Colour correcting photo using %d as a base type %d\n", referenceImage, typeCorrection);
218
219 ColourBrightness(ptrInputFiles, ptrOutputFiles, filesCount, referenceImage, typeCorrection, outputCurvesType);
220
221 returnValue = 0; // success
222
223 end:
224
225 if (ptDeleteSources && returnValue!=-1 && ptrInputFiles) {
226 int i;
227 for (i = 0; i < filesCount; i++) {
228 remove(ptrInputFiles[i].name);
229 }
230 }
231 free(ptrInputFiles);
232 free(ptrOutputFiles);
233
234 return returnValue;
235 }
236
237