Commit 0893c1a7 authored by Agata Cacko's avatar Agata Cacko

Add conversion of colorspace to tiff export

Not every colorspace supported by Krita is supported by tiff.
In case of exporting an image with an unsupported color space
it should convert to the closest one. This commit ensures that.

CCBUG:408177
parent 3525af5d
......@@ -356,10 +356,18 @@ KisImportExportErrorCode KisTIFFConverter::readTIFFDirectory(TIFF* image)
// Do not use the linear gamma profile for 16 bits/channel by default, tiff files are usually created with
// gamma correction. XXX: Should we ask the user?
if (!profile) {
dbgFile << "No profile found; trying to assign a default one.";
if (colorSpaceIdTag.first == RGBAColorModelID.id()) {
profile = KoColorSpaceRegistry::instance()->profileByName("sRGB-elle-V2-srgbtrc.icc");
} else if (colorSpaceIdTag.first == GrayAColorModelID.id()) {
profile = KoColorSpaceRegistry::instance()->profileByName("Gray-D50-elle-V2-srgbtrc.icc");
} else if (colorSpaceIdTag.first == CMYKAColorModelID.id()) {
profile = KoColorSpaceRegistry::instance()->profileByName("Chemical proof");
} else if (colorSpaceIdTag.first == LABAColorModelID.id()) {
profile = KoColorSpaceRegistry::instance()->profileByName("Lab identity build-in");
}
if (!profile) {
dbgFile << "No suitable default profile found.";
}
}
......
......@@ -22,6 +22,7 @@
#include <KoColorProfile.h>
#include <KoColorSpace.h>
#include <KoID.h>
#include <KoColorSpaceRegistry.h>
#include <KoConfig.h>
#ifdef HAVE_OPENEXR
......@@ -30,32 +31,66 @@
namespace
{
bool writeColorSpaceInformation(TIFF* image, const KoColorSpace * cs, uint16& color_type, uint16& sample_format)
bool isBitDepthFloat(QString depth) {
return depth.contains("F");
}
bool writeColorSpaceInformation(TIFF* image, const KoColorSpace * cs, uint16& color_type, uint16& sample_format, const KoColorSpace* &destColorSpace)
{
dbgKrita << cs->id();
if (cs->id() == "GRAYA" || cs->id() == "GRAYAU16") {
color_type = PHOTOMETRIC_MINISBLACK;
return true;
}
if (KoID(cs->id()) == KoID("RGBA") || KoID(cs->id()) == KoID("RGBA16")) {
QString id = cs->id();
QString depth = cs->colorDepthId().id();
// destColorSpace should be reassigned to a proper color space to convert to
// if the return value of this function is false
destColorSpace = 0;
// sample_format and color_type should be assigned to the destination color space,
// not /always/ the one we get here
if (id.contains("RGBA")) {
color_type = PHOTOMETRIC_RGB;
if (isBitDepthFloat(depth)) {
sample_format = SAMPLEFORMAT_IEEEFP;
}
return true;
}
if (KoID(cs->id()) == KoID("RGBAF16") || KoID(cs->id()) == KoID("RGBAF32")) {
color_type = PHOTOMETRIC_RGB;
sample_format = SAMPLEFORMAT_IEEEFP;
return true;
}
if (cs->id() == "CMYK" || cs->id() == "CMYKAU16") {
} else if (id.contains("CMYK")) {
color_type = PHOTOMETRIC_SEPARATED;
TIFFSetField(image, TIFFTAG_INKSET, INKSET_CMYK);
if (isBitDepthFloat(depth)) {
destColorSpace = KoColorSpaceRegistry::instance()->colorSpace(CMYKAColorModelID.id(), Integer16BitsColorDepthID.id(), cs->profile());
return false;
}
return true;
}
if (cs->id() == "LABA") {
} else if (id.contains("LABA")) {
color_type = PHOTOMETRIC_ICCLAB;
if (depth != "U16") {
destColorSpace = KoColorSpaceRegistry::instance()->colorSpace(LABAColorModelID.id(), Integer16BitsColorDepthID.id(), cs->profile());
return false;
}
return true;
} else if (id.contains("GRAYA")) {
color_type = PHOTOMETRIC_MINISBLACK;
QList<QString> possibleDepths;
possibleDepths << "U16" << "U8";
if (!possibleDepths.contains(depth)) {
destColorSpace = KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer16BitsColorDepthID.id(), cs->profile());
return false;
}
return true;
} else {
color_type = PHOTOMETRIC_RGB;
const QString profile = "sRGB-elle-V2-srgbtrc";
destColorSpace = KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(), depth, profile);
if (isBitDepthFloat(depth)) {
sample_format = SAMPLEFORMAT_IEEEFP;
}
return false;
}
return false;
}
}
......@@ -135,6 +170,19 @@ bool KisTIFFWriterVisitor::saveLayerProjection(KisLayer *layer)
{
dbgFile << "visiting on layer" << layer->name() << "";
KisPaintDeviceSP pd = layer->projection();
uint16 color_type;
uint16 sample_format = SAMPLEFORMAT_UINT;
const KoColorSpace* destColorSpace;
// Check colorspace
if (!writeColorSpaceInformation(image(), pd->colorSpace(), color_type, sample_format, destColorSpace)) { // unsupported colorspace
if (!destColorSpace) {
return false;
}
pd.attach(new KisPaintDevice(*pd));
pd->convertTo(destColorSpace);
}
// Save depth
int depth = 8 * pd->pixelSize() / pd->channelCount();
TIFFSetField(image(), TIFFTAG_BITSPERSAMPLE, depth);
......@@ -147,12 +195,8 @@ bool KisTIFFWriterVisitor::saveLayerProjection(KisLayer *layer)
TIFFSetField(image(), TIFFTAG_SAMPLESPERPIXEL, pd->channelCount() - 1);
TIFFSetField(image(), TIFFTAG_EXTRASAMPLES, 0);
}
// Save colorspace information
uint16 color_type;
uint16 sample_format = SAMPLEFORMAT_UINT;
if (!writeColorSpaceInformation(image(), pd->colorSpace(), color_type, sample_format)) { // unsupported colorspace
return false;
}
TIFFSetField(image(), TIFFTAG_PHOTOMETRIC, color_type);
TIFFSetField(image(), TIFFTAG_SAMPLEFORMAT, sample_format);
TIFFSetField(image(), TIFFTAG_IMAGEWIDTH, layer->image()->width());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment