Krita Source Code Documentation
Loading...
Searching...
No Matches
RecorderWriter::Private Class Reference

Public Member Functions

quint32 avg (quint32 c1, quint32 c2)
 
quint32 blendSourceOver (const int alpha, const quint32 source, const quint32 destination)
 
void captureImage ()
 
void halfSizeImageBuffer ()
 
Privateoperator= (const Private &)=default
 
Privateoperator= (Private &&)=delete
 
 Private ()=delete
 
 Private (const Private &)=default
 
 Private (Private &&)=delete
 
 Private (QPointer< KisCanvas2 > c, const RecorderWriterSettings &s, const QDir &d)
 
void removeFrameTransparency ()
 
bool writeFrame ()
 

Public Attributes

QPointer< KisCanvas2canvas
 
QImage frame
 
int frameResolution = -1
 
QByteArray imageBuffer
 
int imageBufferHeight = 0
 
int imageBufferWidth = 0
 
const QDir * outputDir
 
int partIndex = 0
 
const RecorderWriterSettingssettings
 
const KoColorSpacetargetCs
 

Detailed Description

Definition at line 127 of file recorder_writer.cpp.

Constructor & Destructor Documentation

◆ Private() [1/4]

RecorderWriter::Private::Private ( QPointer< KisCanvas2 > c,
const RecorderWriterSettings & s,
const QDir & d )
inline

Definition at line 130 of file recorder_writer.cpp.

131 : canvas(c)
132 , settings(&s)
133 , outputDir(&d)
134 {}
QPointer< KisCanvas2 > canvas
const RecorderWriterSettings * settings
Private *const d

◆ Private() [2/4]

RecorderWriter::Private::Private ( )
delete

◆ Private() [3/4]

RecorderWriter::Private::Private ( const Private & )
default

◆ Private() [4/4]

RecorderWriter::Private::Private ( Private && )
delete

Member Function Documentation

◆ avg()

quint32 RecorderWriter::Private::avg ( quint32 c1,
quint32 c2 )
inline

Definition at line 215 of file recorder_writer.cpp.

216 {
217 return (((c1 ^ c2) & 0xfefefefeUL) >> 1) + (c1 & c2);
218 }

◆ blendSourceOver()

quint32 RecorderWriter::Private::blendSourceOver ( const int alpha,
const quint32 source,
const quint32 destination )
inline

Definition at line 243 of file recorder_writer.cpp.

244 {
245 // co = αs x Cs + αb x Cb x (1 – αs)
246 // αo = 1, αb = 1
247
248 const int inverseAlpha = 255 - alpha;
249 return qRgb(
250 (alpha * qRed(source) + inverseAlpha * qRed(destination)) >> 8,
251 (alpha * qGreen(source) + inverseAlpha * qGreen(destination)) >> 8,
252 (alpha * qBlue(source) + inverseAlpha * qBlue(destination)) >> 8
253 );
254 }
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)

References source().

◆ captureImage()

void RecorderWriter::Private::captureImage ( )
inline

Definition at line 156 of file recorder_writer.cpp.

157 {
158 KisImageSP image = canvas->image();
159
160 // Create detached paint device that can be converted to target colorspace
161 KisPaintDeviceSP device = new KisPaintDevice(image->colorSpace());
162
163 // we don't want image->barrierLock() because it will wait until the full stroke is finished
165 device->makeCloneFromRough(image->projection(), image->bounds());
166 image->unlock();
167
168 const bool needSrgbConversion = [&]() {
170 || image->colorSpace()->colorModelId() != RGBAColorModelID) {
171 return true;
172 }
173 const bool hasPrimaries = image->colorSpace()->profile()->hasColorants();
175 if (hasPrimaries) {
176 const ColorPrimaries primaries = image->colorSpace()->profile()->getColorPrimaries();
177 if (gamma == TRC_IEC_61966_2_1 && primaries == PRIMARIES_ITU_R_BT_709_5) {
178 return false;
179 }
180 }
181 return true;
182 }();
183
184 if (targetCs && needSrgbConversion) {
185 device->convertTo(targetCs);
186 }
187
188 // truncate uneven image width/height making it even for subdivided size too
189 const quint32 bitmask = ~(0xFFFFFFFFu >> (31 - settings->resolution));
190 const quint32 width = image->width() & bitmask;
191 const quint32 height = image->height() & bitmask;
192 const int bufferSize = device->pixelSize() * width * height;
193
194 bool resize = imageBuffer.size() != bufferSize;
195 if (resize)
196 imageBuffer.resize(bufferSize);
197
198 if (resize || frameResolution != settings->resolution) {
199 const int divider = 1 << settings->resolution;
200 const int outWidth = width / divider;
201 const int outHeight = height / divider;
202 uchar *outData = reinterpret_cast<uchar *>(imageBuffer.data());
203
204 frame = QImage(outData, outWidth, outHeight, QImage::Format_ARGB32);
205 }
206
207 device->readBytes(reinterpret_cast<quint8 *>(imageBuffer.data()), 0, 0, width, height);
208
209 imageBufferWidth = width;
210 imageBufferHeight = height;
211 }
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
ColorPrimaries
The colorPrimaries enum Enum of colorants, follows ITU H.273 for values 0 to 255, and has extra known...
@ PRIMARIES_ITU_R_BT_709_5
TransferCharacteristics
The transferCharacteristics enum Enum of transfer characteristics, follows ITU H.273 for values 0 to ...
@ TRC_IEC_61966_2_1
const KoColorSpace * colorSpace() const
void unlock()
Definition kis_image.cc:805
KisPaintDeviceSP projection() const
qint32 width() const
void immediateLockForReadOnly()
Definition kis_image.cc:793
qint32 height() const
QRect bounds() const override
quint32 pixelSize() const
void makeCloneFromRough(KisPaintDeviceSP src, const QRect &minimalRect)
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h) const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
const KoColorSpace * targetCs
virtual ColorPrimaries getColorPrimaries() const
getColorPrimaries
virtual bool hasColorants() const =0
virtual TransferCharacteristics getTransferCharacteristics() const
getTransferCharacteristics This function should be subclassed at some point so we can get the value f...

References KisImage::bounds(), canvas, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KisImage::colorSpace(), KisPaintDevice::convertTo(), frame, frameResolution, KoColorProfile::getColorPrimaries(), KoColorProfile::getTransferCharacteristics(), KoColorProfile::hasColorants(), KisImage::height(), imageBuffer, imageBufferHeight, imageBufferWidth, KisImage::immediateLockForReadOnly(), Integer8BitsColorDepthID, KisPaintDevice::makeCloneFromRough(), KisPaintDevice::pixelSize(), PRIMARIES_ITU_R_BT_709_5, KoColorSpace::profile(), KisImage::projection(), KisPaintDevice::readBytes(), RecorderWriterSettings::resolution, RGBAColorModelID, settings, targetCs, TRC_IEC_61966_2_1, KisImage::unlock(), and KisImage::width().

◆ halfSizeImageBuffer()

void RecorderWriter::Private::halfSizeImageBuffer ( )
inline

Definition at line 220 of file recorder_writer.cpp.

221 {
222 quint32 *buffer = reinterpret_cast<quint32 *>(imageBuffer.data());
223 quint32 *out = buffer;
224
225 for (int y = 0; y < imageBufferHeight; y += 2) {
226 const quint32 *in1 = buffer + y * imageBufferWidth;
227 const quint32 *in2 = in1 + imageBufferWidth;
228
229 for (int x = 0; x < imageBufferWidth; x += 2) {
230 *out = avg(
231 avg(in1[x], in1[x + 1]),
232 avg(in2[x], in2[x + 1])
233 );
234
235 ++out;
236 }
237 }
238
239 imageBufferWidth /= 2;
241 }
quint32 avg(quint32 c1, quint32 c2)

References avg(), imageBuffer, imageBufferHeight, and imageBufferWidth.

◆ operator=() [1/2]

Private & RecorderWriter::Private::operator= ( const Private & )
default

◆ operator=() [2/2]

Private & RecorderWriter::Private::operator= ( Private && )
delete

◆ removeFrameTransparency()

void RecorderWriter::Private::removeFrameTransparency ( )
inline

Definition at line 256 of file recorder_writer.cpp.

257 {
258 const quint32 background = 0xFFFFFFFF;
259 quint32 *buffer = reinterpret_cast<quint32 *>(imageBuffer.data());
260 const quint32 *end = buffer + imageBufferWidth * imageBufferHeight;
261 while (buffer != end) {
262 const int alpha = qAlpha(*buffer);
263 switch (alpha) {
264 case 0xFF: // fully opaque
265 break;
266 case 0x00: // fully transparent - just replace to background
267 *buffer = background;
268 break;
269 default: // partly transparent - do color blending
270 *buffer = blendSourceOver(alpha, *buffer, background);
271 break;
272 }
273 ++buffer;
274 }
275 }
quint32 blendSourceOver(const int alpha, const quint32 source, const quint32 destination)

References blendSourceOver(), imageBuffer, imageBufferHeight, and imageBufferWidth.

◆ writeFrame()

bool RecorderWriter::Private::writeFrame ( )
inline

Definition at line 277 of file recorder_writer.cpp.

278 {
279 if (!outputDir->exists() && !outputDir->mkpath(settings->outputDirectory))
280 return false;
281
282 const QString fileName = QString("%1").arg(partIndex, 7, 10, QLatin1Char('0'));
283 const QString &filePath = QString("%1%2.%3").arg(settings->outputDirectory, fileName,
285
286 int factor = -1; // default value
287 switch (settings->format) {
289 factor = settings->quality; // 0...100
290 break;
292 factor = qBound(0, 100 - (settings->compression * 10), 100); // 0..10 -> 100..0
293 break;
294 }
295
296 bool result = frame.save(filePath, RecorderFormatInfo::fileFormat(settings->format).data(), factor);
297 if (!result)
298 QFile(filePath).remove(); // remove corrupted frame
299 return result;
300 }
QLatin1String fileFormat(RecorderFormat format)
QLatin1String fileExtension(RecorderFormat format)

References RecorderWriterSettings::compression, RecorderFormatInfo::fileExtension(), RecorderFormatInfo::fileFormat(), RecorderWriterSettings::format, frame, JPEG, outputDir, RecorderWriterSettings::outputDirectory, partIndex, PNG, RecorderWriterSettings::quality, and settings.

Member Data Documentation

◆ canvas

QPointer<KisCanvas2> RecorderWriter::Private::canvas

Definition at line 141 of file recorder_writer.cpp.

◆ frame

QImage RecorderWriter::Private::frame

Definition at line 145 of file recorder_writer.cpp.

◆ frameResolution

int RecorderWriter::Private::frameResolution = -1

Definition at line 146 of file recorder_writer.cpp.

◆ imageBuffer

QByteArray RecorderWriter::Private::imageBuffer

Definition at line 142 of file recorder_writer.cpp.

◆ imageBufferHeight

int RecorderWriter::Private::imageBufferHeight = 0

Definition at line 144 of file recorder_writer.cpp.

◆ imageBufferWidth

int RecorderWriter::Private::imageBufferWidth = 0

Definition at line 143 of file recorder_writer.cpp.

◆ outputDir

const QDir* RecorderWriter::Private::outputDir

Definition at line 149 of file recorder_writer.cpp.

◆ partIndex

int RecorderWriter::Private::partIndex = 0

Definition at line 147 of file recorder_writer.cpp.

◆ settings

const RecorderWriterSettings* RecorderWriter::Private::settings

Definition at line 148 of file recorder_writer.cpp.

◆ targetCs

const KoColorSpace* RecorderWriter::Private::targetCs
Initial value:
=
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

Definition at line 151 of file recorder_writer.cpp.


The documentation for this class was generated from the following file: