26#include <config-ocio.h>
28#define ORIGINAL_INDEX 0
29#define FIRST_NOT_ORIGINAL_INDEX 1
30#define SCALE_FROM_INDEX(idx) (1./qreal(1<<(idx)))
40#define ceiledSize(sz) QSize(ceil((sz).width()), ceil((sz).height()))
41#define isOdd(x) ((x) & 0x01)
49 qint32 mask = alignment - 1;
60 qint32 mask = alignment - 1;
70 qint32 mask = alignment - 1;
74inline void alignRectBy2(qint32 &x, qint32 &y, qint32 &w, qint32 &h)
89 , m_monitorColorSpace(0)
90 , m_pyramidHeight(pyramidHeight)
103 KoColorConversionTransformation::ConversionFlags conversionFlags)
120 int selectedChannels = 0;
174 if (rc.width() * rc.height() <= patchWidth * patchHeight) {
178 qint32 firstCol = rc.x() / patchWidth;
179 qint32 firstRow = rc.y() / patchHeight;
181 qint32 lastCol = (rc.x() + rc.width()) / patchWidth;
182 qint32 lastRow = (rc.y() + rc.height()) / patchHeight;
184 for(qint32 i = firstRow; i <= lastRow; i++) {
185 for(qint32 j = firstCol; j <= lastCol; j++) {
186 QRect maxPatchRect(j * patchWidth,
188 patchWidth, patchHeight);
189 QRect patchRect = rc & maxPatchRect;
218 quint32 numPixels =
rect.width() *
rect.height();
220 QScopedArrayPointer<quint8> originalBytes(
249 QScopedArrayPointer<quint8> dst(
new quint8[floatCs->
pixelSize() * numPixels]);
252 originalBytes.swap(dst);
256 QScopedArrayPointer<quint8> dst(
new quint8[modifiedMonitorCs->
pixelSize() * numPixels]);
258 originalBytes.swap(dst);
267 QScopedArrayPointer<quint8> dst(
new quint8[projectionCs->
pixelSize() * numPixels]);
277 originalBytes.swap(dst);
282 originalBytes.swap(dst);
292 QRect currentSrcRect = info->dirtyImageRectVar;
297 if (!currentSrcRect.isEmpty()) {
304 image.save(
"./PYRAMID_BASE.png");
307 image.save(
"./LEVEL1.png");
310 image.save(
"./LEVEL2.png");
312 image.save(
"./LEVEL3.png");
320 qint32 srcX, srcY, srcWidth, srcHeight;
321 srcRect.getRect(&srcX, &srcY, &srcWidth, &srcHeight);
325 if (srcWidth < 1)
return QRect();
326 if (srcHeight < 1)
return QRect();
328 qint32 dstX = srcX / 2;
329 qint32 dstY = srcY / 2;
330 qint32 dstWidth = srcWidth / 2;
331 qint32 dstHeight = srcHeight / 2;
337 int conseqPixels = 0;
338 for (
int row = 0; row < dstHeight; ++row) {
341 int dstItConseq = dstIt->nConseqPixels();
342 conseqPixels = qMin(srcItConseq, dstItConseq * 2);
344 Q_ASSERT(!
isOdd(conseqPixels));
347 dstIt->rawData(), conseqPixels);
351 dstIt->nextPixels(conseqPixels / 2);
359 return QRect(dstX, dstY, dstWidth, dstHeight);
363 const quint8 *srcRow1,
376 static const qint32 pixelSize = 4;
378 for (qint32 i = 0; i < numSrcPixels / 2; i++) {
379 b = srcRow0[0] + srcRow1[0] + srcRow0[4] + srcRow1[4];
380 g = srcRow0[1] + srcRow1[1] + srcRow0[5] + srcRow1[5];
381 r = srcRow0[2] + srcRow1[2] + srcRow0[6] + srcRow1[6];
382 a = srcRow0[3] + srcRow1[3] + srcRow0[7] + srcRow1[7];
390 srcRow0 += 2 * pixelSize;
391 srcRow1 += 2 * pixelSize;
402 if (planeScale < scale) {
403 if (originalSize*scale == originalSize*planeScale)
414 dbgRender <<
"First good plane:" << nearest <<
"(sc:" << scale <<
")";
421 qint32 alignment = 1 << index;
429 Q_ASSERT(
rect.left() >= 0 &&
rect.top() >= 0);
431 qint32 x1, y1, x2, y2;
432 rect.getCoords(&x1, &y1, &x2, &y2);
444 rect.setCoords(x1, y1, x2, y2);
452 info->imageRect.size());
454 qint32 alignment = 1 << index;
459 planeScale, planeScale);
469 patch.
drawMe(gc, info->viewportRect, info->renderHints);
473 const QRect& unscaledRect)
476 unscaledRect.getRect(&x, &y, &w, &h);
478 QImage image = QImage(w, h, QImage::Format_ARGB32);
float value(const T *src, size_t ch)
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
virtual const quint8 * oldRawData() const =0
virtual qint32 nConseqPixels() const =0
virtual bool nextPixels(qint32 n)=0
static KisConfigNotifier * instance()
bool useOcio(bool defaultValue=false) const
bool showSingleChannelAsColor(bool defaultValue=false) const
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h, qint32 dataRowStride=-1) const
int updatePatchWidth() const
int updatePatchHeight() const
void drawMe(QPainter &gc, const QRectF &dstRect, QPainter::RenderHints renderHints)
void setImage(QImage image)
QImage convertToQImageFast(KisPaintDeviceSP paintDevice, const QRect &unscaledRect)
KisImagePyramid(qint32 pyramidHeight)
void downsamplePixels(const quint8 *srcRow0, const quint8 *srcRow1, quint8 *dstRow, qint32 numSrcPixels)
QRect downsampleByFactor2(const QRect &srcRect, KisPaintDevice *src, KisPaintDevice *dst)
void updateCache(const QRect &dirtyImageRect) override
bool m_allChannelsSelected
int findFirstGoodPlaneIndex(qreal scale, QSize originalSize)
void setDisplayFilter(QSharedPointer< KisDisplayFilter > displayFilter) override
KisImageWSP m_originalImage
QVector< KisPaintDeviceSP > m_pyramid
QSharedPointer< KisDisplayFilter > m_displayFilter
void setImage(KisImageWSP newImage) override
void alignSourceRect(QRect &rect, qreal scale) override
void setImageSize(qint32 w, qint32 h) override
void drawFromOriginalImage(QPainter &gc, KisPPUpdateInfoSP info) override
KoColorConversionTransformation::Intent m_renderingIntent
int m_selectedChannelIndex
~KisImagePyramid() override
void retrieveImageData(const QRect &rect)
bool m_onlyOneChannelSelected
KoColorConversionTransformation::ConversionFlags m_conversionFlags
void setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) override
const KoColorSpace * m_monitorColorSpace
void setChannelFlags(const QBitArray &channelFlags) override
KisImagePatch getNearestPatch(KisPPUpdateInfoSP info) override
void recalculateCache(KisPPUpdateInfoSP info) override
const KoColorProfile * m_monitorProfile
KisPaintDeviceSP projection() const
QRect exactBounds() const
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
const KoColorSpace * colorSpace() const
KisDataManagerSP dataManager() const
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h) const
@ COLOR
The channel represents a color.
virtual quint32 pixelSize() const =0
virtual void convertChannelToVisualRepresentation(const quint8 *src, quint8 *dst, quint32 nPixels, const qint32 selectedChannelIndex) const =0
QList< KoChannelInfo * > channels
virtual KoID colorModelId() const =0
virtual quint32 channelCount() const =0
virtual KoID colorDepthId() const =0
virtual bool convertPixelsTo(const quint8 *src, quint8 *dst, const KoColorSpace *dstColorSpace, quint32 numPixels, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
virtual const KoColorProfile * profile() const =0
void alignRectBy2(qint32 &x, qint32 &y, qint32 &w, qint32 &h)
#define FIRST_NOT_ORIGINAL_INDEX
void alignByPow2Lo(qint32 &value, qint32 alignment)
void alignByPow2ButOneHi(qint32 &value, qint32 alignment)
#define SCALE_FROM_INDEX(idx)
void alignByPow2Hi(qint32 &value, qint32 alignment)
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())