Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_tiff_base_writer.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me>
3 * SPDX-FileCopyrightText: 2024 Lucas Chollet <lucas.chollet@serenityos.org>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9#include <KoColorSpace.h>
11#include <KoID.h>
12#include <kis_iterator_ng.h>
13
15#include "kis_tiff_converter.h"
16
18 : m_image(image)
19 , m_options(options)
20{
21}
22
24{
25 return depth == Float16BitsColorDepthID || depth == Float32BitsColorDepthID || depth == Float64BitsColorDepthID;
26}
27
29 const KoColorSpace *cs,
30 uint16_t &color_type,
31 uint16_t &sample_format,
32 const KoColorSpace *&destColorSpace)
33{
34 const KoID id = cs->colorModelId();
35 const KoID depth = cs->colorDepthId();
36 // destColorSpace should be reassigned to a proper color space to convert to
37 // if the return value of this function is false
38 destColorSpace = nullptr;
39
40 // sample_format and color_type should be assigned to the destination color
41 // space, not /always/ the one we get here
42
43 if (id == RGBAColorModelID) {
44 color_type = PHOTOMETRIC_RGB;
45 if (isBitDepthFloat(depth)) {
46 sample_format = SAMPLEFORMAT_IEEEFP;
47 }
48 return true;
49
50 } else if (id == CMYKAColorModelID) {
51 color_type = PHOTOMETRIC_SEPARATED;
52 TIFFSetField(image, TIFFTAG_INKSET, INKSET_CMYK);
53
54 if (isBitDepthFloat(depth)) {
55 sample_format = SAMPLEFORMAT_IEEEFP;
56 }
57 return true;
58
59 } else if (id == LABAColorModelID) {
60 color_type = PHOTOMETRIC_ICCLAB;
61
62 if (isBitDepthFloat(depth)) {
63 sample_format = SAMPLEFORMAT_IEEEFP;
64 }
65 return true;
66
67 } else if (id == GrayAColorModelID) {
68 color_type = PHOTOMETRIC_MINISBLACK;
69 if (isBitDepthFloat(depth)) {
70 sample_format = SAMPLEFORMAT_IEEEFP;
71 }
72 return true;
73 } else if (id == YCbCrAColorModelID) {
74 color_type = PHOTOMETRIC_YCBCR;
75 if (isBitDepthFloat(depth)) {
76 sample_format = SAMPLEFORMAT_IEEEFP;
77 }
78 return true;
79 } else {
80 color_type = PHOTOMETRIC_RGB;
81 destColorSpace =
83 depth.id(),
85 if (isBitDepthFloat(depth)) {
86 sample_format = SAMPLEFORMAT_IEEEFP;
87 }
88 return false;
89 }
90}
91
93 tdata_t buff,
94 uint32_t depth,
95 uint16_t sample_format,
96 uint8_t nbcolorssamples,
97 const std::array<quint8, 5> &poses)
98{
99 if (depth == 32) {
100 Q_ASSERT(sample_format == SAMPLEFORMAT_IEEEFP);
101 float *dst = reinterpret_cast<float *>(buff);
102 do {
103 const float *d = reinterpret_cast<const float *>(it->oldRawData());
104 for (uint8_t i = 0; i < nbcolorssamples; i++) {
105 *(dst++) = d[poses.at(i)];
106 }
107 if (m_options->alpha)
108 *(dst++) = d[poses.at(nbcolorssamples)];
109 } while (it->nextPixel());
110 return true;
111 } else if (depth == 16) {
112 if (sample_format == SAMPLEFORMAT_IEEEFP) {
113#ifdef HAVE_OPENEXR
114 half *dst = reinterpret_cast<half *>(buff);
115 do {
116 const half *d = reinterpret_cast<const half *>(it->oldRawData());
117 for (uint8_t i = 0; i < nbcolorssamples; i++) {
118 *(dst++) = d[poses.at(i)];
119 }
120 if (m_options->alpha)
121 *(dst++) = d[poses.at(nbcolorssamples)];
122
123 } while (it->nextPixel());
124 return true;
125#endif
126 } else {
127 quint16 *dst = reinterpret_cast<quint16 *>(buff);
128 do {
129 const quint16 *d = reinterpret_cast<const quint16 *>(it->oldRawData());
130 for (uint8_t i = 0; i < nbcolorssamples; i++) {
131 *(dst++) = d[poses.at(i)];
132 }
133 if (m_options->alpha)
134 *(dst++) = d[poses.at(nbcolorssamples)];
135
136 } while (it->nextPixel());
137 return true;
138 }
139 } else if (depth == 8) {
140 quint8 *dst = reinterpret_cast<quint8 *>(buff);
141 do {
142 const quint8 *d = it->oldRawData();
143 for (uint8_t i = 0; i < nbcolorssamples; i++) {
144 *(dst++) = d[poses.at(i)];
145 }
146 if (m_options->alpha)
147 *(dst++) = d[poses.at(nbcolorssamples)];
148
149 } while (it->nextPixel());
150 return true;
151 }
152 return false;
153}
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID YCbCrAColorModelID("YCbCrA", ki18n("YCbCr/Alpha"))
const KoID Float64BitsColorDepthID("F64", ki18n("64-bit float/channel"))
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
virtual const quint8 * oldRawData() const =0
virtual bool nextPixel()=0
static bool isBitDepthFloat(const KoID depth)
bool copyDataToStrips(KisHLineConstIteratorSP it, tdata_t buff, uint32_t depth, uint16_t sample_format, uint8_t nbcolorssamples, const std::array< quint8, 5 > &poses)
KisTIFFOptions * m_options
static bool writeColorSpaceInformation(TIFF *image, const KoColorSpace *cs, uint16_t &color_type, uint16_t &sample_format, const KoColorSpace *&destColorSpace)
KisTIFFBaseWriter(TIFF *image, KisTIFFOptions *options)
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
const KoColorProfile * p709SRGBProfile() const