47
48
#include <KoDocumentInfo.h>
48
49
#include <KoColorSpace.h>
49
50
#include <KoColorSpaceRegistry.h>
51
#include <KoColorProfile.h>
51
53
#include <kis_doc2.h>
52
54
#include <kis_image.h>
53
55
#include <kis_iterators_pixel.h>
54
56
#include <kis_paint_layer.h>
57
#include <kis_transaction.h>
55
58
#include <kis_group_layer.h>
56
59
#include <kis_meta_data_entry.h>
57
60
#include <kis_meta_data_value.h>
62
65
#include <kis_jpeg_source.h>
63
66
#include <kis_jpeg_destination.h>
65
#include <colorprofiles/KoIccColorProfile.h>
68
#include <KoColorProfile.h>
69
#include <KoColorModelStandardIds.h>
67
71
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
68
72
#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
93
97
return JCS_UNKNOWN;
96
QString getColorSpaceForColorType(J_COLOR_SPACE color_type)
100
QString getColorSpaceModelForColorType(J_COLOR_SPACE color_type)
98
102
dbgFile << "color_type =" << color_type;
99
103
if (color_type == JCS_GRAYSCALE) {
104
return GrayAColorModelID.id();
101
105
} else if (color_type == JCS_RGB) {
106
return RGBAColorModelID.id();
103
107
} else if (color_type == JCS_CMYK) {
108
return CMYKAColorModelID.id();
131
135
Q_ASSERT(uri.isLocalFile());
134
QFile file(QFile::encodeName(uri.toLocalFile()));
138
QFile file(uri.toLocalFile());
135
139
if (!file.exists()) {
136
140
return (KisImageBuilder_RESULT_NOT_EXIST);
138
142
if (!file.open(QIODevice::ReadOnly)) {
139
143
return (KisImageBuilder_RESULT_BAD_FETCH);
142
146
KisJPEGSource::setSource(&cinfo, &file);
144
148
jpeg_save_markers(&cinfo, JPEG_COM, 0xFFFF);
155
159
jpeg_start_decompress(&cinfo);
157
161
// Get the colorspace
158
QString csName = getColorSpaceForColorType(cinfo.out_color_space);
159
if (csName.isEmpty()) {
162
QString modelId = getColorSpaceModelForColorType(cinfo.out_color_space);
163
if (modelId.isEmpty()) {
160
164
dbgFile << "unsupported colorspace :" << cinfo.out_color_space;
161
165
jpeg_destroy_decompress(&cinfo);
162
166
return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE;
164
168
uchar* profile_data;
165
169
uint profile_len;
166
KoColorProfile* profile = 0;
170
const KoColorProfile* profile = 0;
167
171
QByteArray profile_rawdata;
168
172
if (read_icc_profile(&cinfo, &profile_data, &profile_len)) {
169
173
profile_rawdata.resize(profile_len);
171
175
cmsHPROFILE hProfile = cmsOpenProfileFromMem(profile_data, (DWORD)profile_len);
173
177
if (hProfile != (cmsHPROFILE) NULL) {
174
profile = new KoIccColorProfile(profile_rawdata);
178
profile = KoColorSpaceRegistry::instance()->createColorProfile(modelId, Integer8BitsColorDepthID.id(), profile_rawdata);
175
179
Q_CHECK_PTR(profile);
176
// dbgFile <<"profile name:" << profile->productName() <<" profile description:" << profile->productDescription() <<" information sur le produit:" << profile->productInfo();
180
dbgFile <<"profile name:" << profile->name() <<" product information:" << profile->info();
177
181
if (!profile->isSuitableForOutput()) {
178
182
dbgFile << "the profile is not suitable for output and therefore cannot be used in krita, we need to convert the image to a standard profile"; // TODO: in ko2 popup a selection menu to inform the user
187
// Check that the profile is used by the color space
188
if (profile && !KoColorSpaceRegistry::instance()->colorSpaceFactory(
189
KoColorSpaceRegistry::instance()->colorSpaceId(
190
modelId, Integer8BitsColorDepthID.id()))->profileIsCompatible(profile)) {
191
warnFile << "The profile " << profile->name() << " is not compatible with the color space model " << modelId;
183
196
// Retrieve a pointer to the colorspace
184
197
const KoColorSpace* cs;
185
198
if (profile && profile->isSuitableForOutput()) {
186
199
dbgFile << "image has embedded profile:" << profile -> name() << "";
187
cs = KoColorSpaceRegistry::instance()->colorSpace(csName, profile);
200
cs = KoColorSpaceRegistry::instance()->colorSpace(modelId, Integer8BitsColorDepthID.id(), profile);
189
cs = KoColorSpaceRegistry::instance()->colorSpace(KoID(csName, ""), "");
202
cs = KoColorSpaceRegistry::instance()->colorSpace(modelId, Integer8BitsColorDepthID.id(), "");
192
205
dbgFile << "unknown colorspace";
199
212
KoColorTransformation* transform = 0;
200
213
if (profile && !profile->isSuitableForOutput()) {
201
transform = KoColorSpaceRegistry::instance()->colorSpace(csName, profile)->createColorConverter(cs);
214
transform = KoColorSpaceRegistry::instance()->colorSpace(modelId, Integer8BitsColorDepthID.id(), profile)->createColorConverter(cs);
204
217
// Creating the KisImageWSP
206
m_img = new KisImage(m_doc->undoAdapter(), cinfo.image_width, cinfo.image_height, cs, "built image");
219
m_image = new KisImage(m_doc->undoAdapter(), cinfo.image_width, cinfo.image_height, cs, "built image");
220
Q_CHECK_PTR(m_image);
208
222
if (profile && !profile->isSuitableForOutput()) {
209
m_img -> addAnnotation(KisAnnotationSP(new KisAnnotation(profile->name(), "", profile_rawdata)));
223
m_image -> addAnnotation(KisAnnotationSP(new KisAnnotation(profile->name(), "", profile_rawdata)));
213
227
// Set resolution
215
if (cinfo.density_unit == 0)
220
else if ( cinfo.density_unit == 1 )
228
double xres = 72, yres = 72;
229
if (cinfo.density_unit == 1) {
222
230
xres = cinfo.X_density;
223
231
yres = cinfo.Y_density;
225
else if ( cinfo.density_unit == 2 )
232
} else if (cinfo.density_unit == 2) {
227
233
xres = cinfo.X_density * 2.54;
228
234
yres = cinfo.Y_density * 2.54;
230
m_img->setResolution(xres / 72, yres / 72);
236
m_image->setResolution(POINT_TO_INCH(xres), POINT_TO_INCH(yres)); // It is the "invert" macro because we convert from pointer-per-inchs to points
233
KisPaintLayerSP layer = KisPaintLayerSP(new KisPaintLayer(m_img.data(), m_img -> nextLayerName(), quint8_MAX));
239
KisPaintLayerSP layer = KisPaintLayerSP(new KisPaintLayer(m_image.data(), m_image -> nextLayerName(), quint8_MAX));
240
KisTransaction("", layer->paintDevice());
236
243
JSAMPROW row_pointer = new JSAMPLE[cinfo.image_width*cinfo.num_components];
412
419
if (uri.isEmpty())
413
420
return KisImageBuilder_RESULT_NO_URI;
415
if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) {
422
if (!KIO::NetAccess::exists(uri, KIO::NetAccess::SourceSide, QApplication::activeWindow())) {
416
423
return KisImageBuilder_RESULT_NOT_EXIST;
420
427
KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE;
423
if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) {
430
if (KIO::NetAccess::download(uri, tmpFile, QApplication::activeWindow())) {
425
432
uriTF.setPath(tmpFile);
426
433
result = decode(uriTF);
458
465
return (KisImageBuilder_RESULT_FAILURE);
461
uint height = img->height();
462
uint width = img->width();
468
uint height = image->height();
469
uint width = image->width();
463
470
// Initialize structure
464
471
struct jpeg_compress_struct cinfo;
465
472
jpeg_create_compress(&cinfo);
469
476
// Initialize output stream
470
477
KisJPEGDestination::setDestination(&cinfo, &file);
472
const KoColorSpace * cs = img->colorSpace();
479
const KoColorSpace * cs = image->colorSpace();
474
481
cinfo.image_width = width; // image width and height, in pixels
475
482
cinfo.image_height = height;
540
547
// Save resolution
541
cinfo.X_density = img->xRes() * 72;
542
cinfo.Y_density = img->yRes() * 72;
548
cinfo.X_density = INCH_TO_POINT(image->xRes()); // It is the "invert" macro because we convert from pointer-per-inchs to points
549
cinfo.Y_density = INCH_TO_POINT(image->yRes()); // It is the "invert" macro because we convert from pointer-per-inchs to points
543
550
cinfo.density_unit = 1;
544
551
cinfo.write_JFIF_header = 1;