1
2 /*
3 * Argyll Color Correction System
4 * x11 style .txt to ICC Named Color converter
5 *
6 * Author: Graeme W. Gill
7 * Date: 24/20/2014
8 *
9 * Copyright 2014 Graeme W. Gill
10 * All rights reserved.
11 *
12 * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
13 * see the License.txt file for licencing details.
14 */
15
16 /*
17 * TTBD
18 */
19
20 #undef DEBUG
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
25 #include <sys/types.h>
26 #include <time.h>
27 #include "copyright.h"
28 #include "aconfig.h"
29 #ifndef SALONEINSTLIB
30 #include "numlib.h"
31 #include "icc.h"
32 #else
33 #include "numsup.h"
34 #endif
35 #include "xspect.h"
36 #include "ui.h"
37
usage(char * diag,...)38 void usage(char *diag, ...) {
39 fprintf(stderr,"x11 .txt to ICC Named Colors\n");
40 fprintf(stderr,"Author: Graeme W. Gill\n");
41 if (diag != NULL) {
42 va_list args;
43 fprintf(stderr," Diagnostic: ");
44 va_start(args, diag);
45 vfprintf(stderr, diag, args);
46 va_end(args);
47 fprintf(stderr,"\n");
48 }
49 fprintf(stderr,"usage: txt2iccNC [-v level] description infile outfile\n");
50 exit(1);
51 }
52
53 int
main(int argc,char * argv[])54 main(int argc, char *argv[]) {
55 int fa,nfa; /* argument we're looking at */
56 int verb = 0;
57 char desc[MAXNAMEL+1];
58 char inname[MAXNAMEL+1];
59 char outname[MAXNAMEL+1];
60 FILE *ifp;
61 #define BUFSZ 512
62 char buf[BUFSZ];
63 icmFile *wr_fp;
64 icc *wr_icco;
65 int i, rv;
66
67 /* Process the arguments */
68 for(fa = 1;fa < argc;fa++) {
69 nfa = fa; /* skip to nfa if next argument is used */
70 if (argv[fa][0] == '-') { /* Look for any flags */
71 char *na = NULL; /* next argument after flag, null if none */
72
73 if (argv[fa][2] != '\000')
74 na = &argv[fa][2]; /* next is directly after flag */
75 else {
76 if ((fa+1) < argc) {
77 if (argv[fa+1][0] != '-') {
78 nfa = fa + 1;
79 na = argv[nfa]; /* next is seperate non-flag argument */
80 }
81 }
82 }
83
84 if (argv[fa][1] == '?')
85 usage(NULL);
86
87 else if (argv[fa][1] == 'v')
88 verb = 1;
89
90 else
91 usage("Unknown option '%c'",argv[fa][1]);
92 }
93 else
94 break;
95 }
96
97 if (fa >= argc || argv[fa][0] == '-') usage("Missing description");
98 strncpy(desc,argv[fa++],MAXNAMEL); desc[MAXNAMEL] = '\000';
99
100 if (fa >= argc || argv[fa][0] == '-') usage("Missing input filename");
101 strncpy(inname,argv[fa++],MAXNAMEL); inname[MAXNAMEL] = '\000';
102
103 if (fa >= argc || argv[fa][0] == '-') usage("Missing output filename");
104 strncpy(outname,argv[fa++],MAXNAMEL); outname[MAXNAMEL] = '\000';
105
106 if ((ifp = fopen(inname,"r"))==NULL) {
107 error("Read: Can't open file '%s'",inname);
108 }
109
110 /* Open up the file for writing */
111 if ((wr_fp = new_icmFileStd_name(outname,"w")) == NULL)
112 error ("Write: Can't open file '%s'",outname);
113
114 if ((wr_icco = new_icc()) == NULL)
115 error ("Write: Creation of ICC object failed");
116
117 /* Values that must be set before writing */
118 wr_icco->header->deviceClass = icSigNamedColorClass;
119 wr_icco->header->colorSpace = icSigRgbData;
120 wr_icco->header->pcs = icSigLabData;
121 wr_icco->header->renderingIntent = icRelativeColorimetric;
122
123 /* Add the description tag */
124 {
125 icmTextDescription *wo;
126 if ((wo = (icmTextDescription *)wr_icco->add_tag(
127 wr_icco, icSigProfileDescriptionTag, icSigTextDescriptionType)) == NULL)
128 error("Failed to add icmTextDescription");
129
130 wo->size = strlen(desc)+1; /* Allocated and used size of desc, inc null */
131 wo->allocate((icmBase *)wo);/* Allocate space */
132 strcpy(wo->desc, desc); /* Copy the string in */
133 }
134
135 /* Copyright Tag: */
136 {
137 icmText *wo;
138 char *crt;
139
140 crt = "";
141
142 if ((wo = (icmText *)wr_icco->add_tag(
143 wr_icco, icSigCopyrightTag, icSigTextType)) == NULL)
144 error("add_tag failed: %d, %s",wr_icco->errc,wr_icco->err);
145
146 wo->size = strlen(crt)+1; /* Allocated and used size of text, inc null */
147 wo->allocate((icmBase *)wo);/* Allocate space */
148 strcpy(wo->data, crt); /* Copy the text in */
149 }
150
151 /* White Point Tag: */
152 /* Use the orgininal, non PCS adapted white point */
153 {
154 icmXYZArray *wo;
155 /* Note that tag types icSigXYZType and icSigXYZArrayType are identical */
156 if ((wo = (icmXYZArray *)wr_icco->add_tag(
157 wr_icco, icSigMediaWhitePointTag, icSigXYZArrayType)) == NULL)
158 error("add_tag failed: %d, %s",wr_icco->errc,wr_icco->err);
159
160 wo->size = 1;
161 wo->allocate((icmBase *)wo); /* Allocate space */
162 wo->data[0] = icmD65; /* sRGB is D65 */
163 }
164
165 /* Add a named color tag */
166 {
167 icmNamedColor *wo;
168
169 if ((wo = (icmNamedColor *)wr_icco->add_tag(
170 wr_icco, icSigNamedColor2Tag, icSigNamedColor2Type)) == NULL)
171 error("Adding icmNamedColor tag failed");
172
173 wo->count = 0;
174
175 /* Read lines and count the colors */
176 for (;;) {
177 double rgb[3];
178 char s1[BUFSZ];
179 char s2[BUFSZ];
180 char s3[BUFSZ];
181
182 if (fgets(buf, BUFSZ, ifp) == NULL)
183 break;
184
185 if ((rv = sscanf(buf, " %lf %lf %lf %s %s %s\n",&rgb[0], &rgb[1], &rgb[2], s1, s2, s3)) >= 4) {
186 wo->count++;
187 }
188 }
189
190 wo->nDeviceCoords = 3; /* Num of device coordinates */
191 strcpy(wo->prefix,""); /* Prefix for each color name, max 32, null terminated */
192 strcpy(wo->suffix,""); /* Suffix for each color name, max 32, null terminated */
193
194 wo->allocate((icmBase *)wo); /* Allocate named color structures */
195
196 if (verb)
197 printf("Counted %d colors\n",wo->count);
198
199 /* Read lines and colors */
200 rewind(ifp);
201 for (i = 0; i < wo->count; i++) {
202 double rgb[3], lab[3];
203 char s1[BUFSZ];
204 char s2[BUFSZ];
205 char s3[BUFSZ];
206 unsigned int j;
207
208 if (fgets(buf, BUFSZ, ifp) == NULL)
209 break;
210
211 if ((rv = sscanf(buf, " %lf %lf %lf %s %s %s\n",&rgb[0], &rgb[1], &rgb[2], s1, s2, s3)) >= 4) {
212 rgb[0] /= 255.0;
213 rgb[1] /= 255.0;
214 rgb[2] /= 255.0;
215 if (rv >= 5) {
216 strcat(s1, " ");
217 strcat(s1, s2);
218 }
219 if (rv >= 6) {
220 strcat(s1, " ");
221 strcat(s1, s3);
222 }
223 /* Convert from sRGB to Bradford adapted D50 */
224 icx_sRGB2XYZ(lab, icmD50_ary3, rgb);
225 icmXYZ2Lab(&icmD50, lab, lab);
226
227 if (verb)
228 printf("Got %f %f %f '%s'\n",rgb[0], rgb[1], rgb[2], s1);
229
230 strncpy(wo->data[i].root,s1,31);
231 wo->data[i].root[31] = '\000';
232
233 for (j = 0; j < wo->nDeviceCoords; j++)
234 wo->data[i].deviceCoords[j] = rgb[j];
235 for (j = 0; j < 3; j++)
236 wo->data[i].pcsCoords[j] = lab[j];
237 }
238 }
239 fclose(ifp);
240 }
241
242 if ((rv = wr_icco->write(wr_icco, wr_fp, 0)) != 0)
243 error ("Write file: %d, %s",rv,wr_icco->err);
244
245 wr_icco->del(wr_icco);
246 wr_fp->del(wr_fp);
247
248 return 0;
249 }
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274