1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7
8 #include <QScopedPointer>
9
10 #include "lcms2.h"
11 #include "paletteloader_cxf.h"
12
13 #include "cxfcolor.h"
14 #include "cxfobject.h"
15 #include "sccolor.h"
16 #include "scribuscore.h"
17 #include "scribusdoc.h"
18 #include "util.h"
19 #include "util_formats.h"
20
21 #include "colormgmt/sce308tables.h"
22 #include "ui/cxfimportdialog.h"
23
PaletteLoader_CxF()24 PaletteLoader_CxF::PaletteLoader_CxF()
25 : m_spectrumConvertor(ScE308Table5_D50_2deg())
26 {
27
28 }
29
isFileSupported(const QString & fileName) const30 bool PaletteLoader_CxF::isFileSupported(const QString & fileName) const
31 {
32 QFileInfo fi = QFileInfo(fileName);
33 QString ext = fi.suffix().toLower();
34 if (ext != "cxf")
35 return false;
36
37 QFile file(fileName);
38 if (!file.open(QIODevice::ReadOnly))
39 return false;
40
41 QByteArray bytes = file.read(1024);
42 if (bytes.indexOf("<?xml") < 0)
43 return false;
44 return (bytes.indexOf("CxF") >= 0);
45 }
46
getAvailableColorspaces() const47 QList<eColorSpaceType> PaletteLoader_CxF::getAvailableColorspaces() const
48 {
49 bool importableAsRgb = false;
50 bool importableAsCmyk = false;
51 bool importableAsLab = false;
52
53 int objectCount = m_cxfDoc.objectCount();
54 for (int i = 0; i < objectCount; ++i)
55 {
56 const CxfObject* object = m_cxfDoc.objectAt(i);
57
58 if (!importableAsRgb)
59 importableAsRgb = canImportObjectAsRgb(object);
60 if (!importableAsCmyk)
61 importableAsCmyk = canImportObjectAsCmyk(object);
62 if (!importableAsLab)
63 importableAsLab = canImportObjectAsLab(object);
64
65 if (importableAsRgb && importableAsCmyk && importableAsLab)
66 break;
67 }
68
69 QList<eColorSpaceType> colorspaces;
70 if (importableAsLab)
71 colorspaces.append(ColorSpace_Lab);
72 if (importableAsCmyk)
73 colorspaces.append(ColorSpace_Cmyk);
74 if (importableAsRgb)
75 colorspaces.append(ColorSpace_Rgb);
76 return colorspaces;
77 }
78
importFile(const QString & fileName,bool)79 bool PaletteLoader_CxF::importFile(const QString& fileName, bool /*merge*/)
80 {
81 if (!m_cxfDoc.parse(fileName))
82 return false;
83
84 QList<eColorSpaceType> colorspaces = getAvailableColorspaces();
85 if (colorspaces.count() <= 0)
86 return false;
87
88 if (colorspaces.count() > 1)
89 {
90 QScopedPointer<CxfImportDialog> cxfImportDia(new CxfImportDialog(ScCore->primaryMainWindow()));
91 cxfImportDia->setPriorities(colorspaces);
92 if (cxfImportDia->exec() != QDialog::Accepted)
93 return true;
94 colorspaces = cxfImportDia->priorities();
95 }
96
97 QList<PaletteLoader_CxF::ColorImportFunction> importFunctions;
98 for (int i = 0; i < colorspaces.count(); ++i)
99 {
100 eColorSpaceType colorspace = colorspaces.at(i);
101 if (colorspace == ColorSpace_Rgb)
102 importFunctions.append(&PaletteLoader_CxF::importObjectAsRgbColor);
103 else if (colorspace == ColorSpace_Cmyk)
104 importFunctions.append(&PaletteLoader_CxF::importObjectAsCmykColor);
105 else if (colorspace == ColorSpace_Lab)
106 importFunctions.append(&PaletteLoader_CxF::importObjectAsLabColor);
107 }
108
109 ColorImportFunction singleImportFunc = nullptr;
110 if (importFunctions.count() == 1)
111 singleImportFunc = importFunctions.at(0);
112
113 int importCount = 0;
114 int objectCount = m_cxfDoc.objectCount();
115
116 for (int i = 0; i < objectCount; ++i)
117 {
118 const CxfObject* object = m_cxfDoc.objectAt(i);
119
120 if (singleImportFunc)
121 {
122 if ((this->*singleImportFunc)(object))
123 ++importCount;
124 continue;
125 }
126
127 for (int j = 0; j < importFunctions.count(); ++j)
128 {
129 ColorImportFunction importFunc = importFunctions.at(j);
130 if ((this->*importFunc)(object))
131 {
132 ++importCount;
133 break;
134 }
135 }
136 }
137
138 return (importCount > 0);
139 }
140
canImportObjectAsRgb(const CxfObject * object) const141 bool PaletteLoader_CxF::canImportObjectAsRgb(const CxfObject* object) const
142 {
143 if (object->hasColor(cxfColorRGB))
144 return true;
145 if (object->hasColor(cxfColorSRGB))
146 return true;
147 if (object->hasColor(cxfColorAdobeRGB))
148 return true;
149 if (object->hasColor(cxfColorHTML))
150 return true;
151 return false;
152 }
153
canImportObjectAsCmyk(const CxfObject * object) const154 bool PaletteLoader_CxF::canImportObjectAsCmyk(const CxfObject* object) const
155 {
156 return object->hasColor(cxfColorCMYK);
157 }
158
canImportObjectAsLab(const CxfObject * object) const159 bool PaletteLoader_CxF::canImportObjectAsLab(const CxfObject* object) const
160 {
161 if (object->hasColor(cxfReflectanceSpectrum))
162 return true;
163 if (object->hasColor(cxfColorCIELab))
164 return true;
165 if (object->hasColor(cxfColorCIELCh))
166 return true;
167 if (object->hasColor(cxfColorCIEXYZ))
168 return true;
169 return false;
170 }
171
importObjectAsRgbColor(const CxfObject * object)172 bool PaletteLoader_CxF::importObjectAsRgbColor(const CxfObject* object)
173 {
174 ScColor color;
175
176 const CxfColorRGB* cxfRgbColor = dynamic_cast<const CxfColorRGB*>(object->color(cxfColorRGB));
177 if (cxfRgbColor)
178 {
179 double range = cxfRgbColor->maxRange();
180 double red = cxfRgbColor->red() / range;
181 double green = cxfRgbColor->green() / range;
182 double blue = cxfRgbColor->blue() / range;
183 color.setRgbColorF(red, green, blue);
184 color.setSpotColor(false);
185 color.setRegistrationColor(false);
186 m_colors->tryAddColor(object->name(), color);
187 return true;
188 }
189
190 const CxfColorSRGB* cxfsRgbColor = dynamic_cast<const CxfColorSRGB*>(object->color(cxfColorSRGB));
191 if (cxfsRgbColor)
192 {
193 double range = cxfsRgbColor->maxRange();
194 double red = cxfsRgbColor->red() / range;
195 double green = cxfsRgbColor->green() / range;
196 double blue = cxfsRgbColor->blue() / range;
197 color.setRgbColorF(red, green, blue);
198 color.setSpotColor(false);
199 color.setRegistrationColor(false);
200 m_colors->tryAddColor(object->name(), color);
201 return true;
202 }
203
204 const CxfColorAdobeRGB* cxfAdobeRgbColor = dynamic_cast<const CxfColorAdobeRGB*>(object->color(cxfColorAdobeRGB));
205 if (cxfAdobeRgbColor)
206 {
207 double range = cxfAdobeRgbColor->maxRange();
208 double red = cxfAdobeRgbColor->red() / range;
209 double green = cxfAdobeRgbColor->green() / range;
210 double blue = cxfAdobeRgbColor->blue() / range;
211 color.setRgbColorF(red, green, blue);
212 color.setSpotColor(false);
213 color.setRegistrationColor(false);
214 m_colors->tryAddColor(object->name(), color);
215 return true;
216 }
217
218 const CxfColorHTML* cxfHTMLColor = dynamic_cast<const CxfColorHTML*>(object->color(cxfColorHTML));
219 if (cxfHTMLColor)
220 {
221 double red = cxfHTMLColor->red() / 255.0;
222 double green = cxfHTMLColor->green() / 255.0;
223 double blue = cxfHTMLColor->blue() / 255.0;
224 color.setRgbColorF(red, green, blue);
225 color.setSpotColor(false);
226 color.setRegistrationColor(false);
227 m_colors->tryAddColor(object->name(), color);
228 return true;
229 }
230
231 return false;
232 }
233
importObjectAsCmykColor(const CxfObject * object)234 bool PaletteLoader_CxF::importObjectAsCmykColor(const CxfObject* object)
235 {
236 ScColor color;
237
238 const CxfColorCMYK* cxfCmykColor = dynamic_cast<const CxfColorCMYK*>(object->color(cxfColorCMYK));
239 if (cxfCmykColor)
240 {
241 double c = cxfCmykColor->cyan() / 100.0;
242 double m = cxfCmykColor->magenta() / 100.0;
243 double y = cxfCmykColor->yellow() / 100.0;
244 double k = cxfCmykColor->black() / 100.0;
245 color.setCmykColorF(c, m, y, k);
246 color.setSpotColor(false);
247 color.setRegistrationColor(false);
248 m_colors->tryAddColor(object->name(), color);
249 return true;
250 }
251
252 return false;
253 }
254
importObjectAsLabColor(const CxfObject * object)255 bool PaletteLoader_CxF::importObjectAsLabColor(const CxfObject* object)
256 {
257 ScColor color;
258
259 const CxfReflectanceSpectrum* spectrum = dynamic_cast<const CxfReflectanceSpectrum*>(object->color(cxfReflectanceSpectrum));
260 if (spectrum)
261 {
262 ScLab labVal = m_spectrumConvertor.toLab(spectrum->wavelengths(), spectrum->values());
263 color.setLabColor(labVal.L, labVal.a, labVal.b);
264 color.setSpotColor(false);
265 color.setRegistrationColor(false);
266 m_colors->tryAddColor(object->name(), color);
267 return true;
268 }
269
270 const CxfColorCIELab* cxfLabColor = dynamic_cast<const CxfColorCIELab*>(object->color(cxfColorCIELab));
271 if (cxfLabColor)
272 {
273 const CxfColorSpecification* colorSpec = cxfLabColor->colorSpecification();
274 const CxfTristimulusSpec& tristimulusSpec = colorSpec->tristimulusSpec();
275 if (tristimulusSpec.isD50_2degree())
276 {
277 color.setLabColor(cxfLabColor->L(), cxfLabColor->a(), cxfLabColor->b());
278 color.setSpotColor(false);
279 color.setRegistrationColor(false);
280 m_colors->tryAddColor(object->name(), color);
281 return true;
282 }
283 }
284
285 const CxfColorCIELCh* cxfLChColor = dynamic_cast<const CxfColorCIELCh*>(object->color(cxfColorCIELCh));
286 if (cxfLChColor)
287 {
288 const CxfColorSpecification* colorSpec = cxfLChColor->colorSpecification();
289 const CxfTristimulusSpec& tristimulusSpec = colorSpec->tristimulusSpec();
290 if (tristimulusSpec.isD50_2degree())
291 {
292 ScLab labVal = cxfLChColor->lab();
293 color.setLabColor(labVal.L, labVal.a, labVal.b);
294 color.setSpotColor(false);
295 color.setRegistrationColor(false);
296 m_colors->tryAddColor(object->name(), color);
297 return true;
298 }
299 }
300
301 const CxfColorCIEXYZ* cxfXYZColor = dynamic_cast<const CxfColorCIEXYZ*>(object->color(cxfColorCIEXYZ));
302 if (cxfXYZColor)
303 {
304 const CxfColorSpecification* colorSpec = cxfXYZColor->colorSpecification();
305 const CxfTristimulusSpec& tristimulusSpec = colorSpec->tristimulusSpec();
306 if (tristimulusSpec.isD50_2degree())
307 {
308 cmsCIELab cmsLab;
309 cmsCIEXYZ cmsXYZ = { cxfXYZColor->X(), cxfXYZColor->Y(), cxfXYZColor->Z() };
310 cmsXYZ2Lab(cmsD50_XYZ(), &cmsLab, &cmsXYZ);
311 color.setLabColor(cmsLab.L, cmsLab.a, cmsLab.b);
312 color.setSpotColor(false);
313 color.setRegistrationColor(false);
314 m_colors->tryAddColor(object->name(), color);
315 return true;
316 }
317 }
318
319 return false;
320 }
321