28#include <config-ocio.h>
30#define ORIGINAL_INDEX 0
31#define FIRST_NOT_ORIGINAL_INDEX 1
32#define SCALE_FROM_INDEX(idx) (1./qreal(1<<(idx)))
42#define ceiledSize(sz) QSize(ceil((sz).width()), ceil((sz).height()))
43#define isOdd(x) ((x) & 0x01)
51 qint32 mask = alignment - 1;
62 qint32 mask = alignment - 1;
72 qint32 mask = alignment - 1;
76inline void alignRectBy2(qint32 &x, qint32 &y, qint32 &w, qint32 &h)
91 , m_monitorColorSpace(0)
92 , m_pyramidHeight(pyramidHeight)
105 KoColorConversionTransformation::ConversionFlags conversionFlags)
122 int selectedChannels = 0;
176 if (rc.width() * rc.height() <= patchWidth * patchHeight) {
180 qint32 firstCol = rc.x() / patchWidth;
181 qint32 firstRow = rc.y() / patchHeight;
183 qint32 lastCol = (rc.x() + rc.width()) / patchWidth;
184 qint32 lastRow = (rc.y() + rc.height()) / patchHeight;
186 for(qint32 i = firstRow; i <= lastRow; i++) {
187 for(qint32 j = firstCol; j <= lastCol; j++) {
188 QRect maxPatchRect(j * patchWidth,
190 patchWidth, patchHeight);
191 QRect patchRect = rc & maxPatchRect;
220 quint32 numPixels =
rect.width() *
rect.height();
222 std::unique_ptr<quint8[]> originalBytes(
251 std::unique_ptr<quint8[]> dst(
new quint8[floatCs->
pixelSize() * numPixels]);
254 originalBytes.swap(dst);
258 std::unique_ptr<quint8[]> dst(
new quint8[modifiedMonitorCs->
pixelSize() * numPixels]);
260 originalBytes.swap(dst);
269 std::unique_ptr<quint8[]> dst(
new quint8[projectionCs->
pixelSize() * numPixels]);
279 originalBytes.swap(dst);
284 originalBytes.swap(dst);
294 QRect currentSrcRect = info->dirtyImageRectVar;
299 if (!currentSrcRect.isEmpty()) {
306 image.save(
"./PYRAMID_BASE.png");
309 image.save(
"./LEVEL1.png");
312 image.save(
"./LEVEL2.png");
314 image.save(
"./LEVEL3.png");
322 qint32 srcX, srcY, srcWidth, srcHeight;
323 srcRect.getRect(&srcX, &srcY, &srcWidth, &srcHeight);
327 if (srcWidth < 1)
return QRect();
328 if (srcHeight < 1)
return QRect();
330 qint32 dstX = srcX / 2;
331 qint32 dstY = srcY / 2;
332 qint32 dstWidth = srcWidth / 2;
333 qint32 dstHeight = srcHeight / 2;
339 int conseqPixels = 0;
340 for (
int row = 0; row < dstHeight; ++row) {
343 int dstItConseq = dstIt->nConseqPixels();
344 conseqPixels = qMin(srcItConseq, dstItConseq * 2);
346 Q_ASSERT(!
isOdd(conseqPixels));
349 dstIt->rawData(), conseqPixels);
353 dstIt->nextPixels(conseqPixels / 2);
361 return QRect(dstX, dstY, dstWidth, dstHeight);
365 const quint8 *srcRow1,
378 static const qint32 pixelSize = 4;
380 for (qint32 i = 0; i < numSrcPixels / 2; i++) {
381 b = srcRow0[0] + srcRow1[0] + srcRow0[4] + srcRow1[4];
382 g = srcRow0[1] + srcRow1[1] + srcRow0[5] + srcRow1[5];
383 r = srcRow0[2] + srcRow1[2] + srcRow0[6] + srcRow1[6];
384 a = srcRow0[3] + srcRow1[3] + srcRow0[7] + srcRow1[7];
392 srcRow0 += 2 * pixelSize;
393 srcRow1 += 2 * pixelSize;
404 if (planeScale < scale) {
405 if (originalSize*scale == originalSize*planeScale)
416 dbgRender <<
"First good plane:" << nearest <<
"(sc:" << scale <<
")";
423 qint32 alignment = 1 << index;
431 Q_ASSERT(
rect.left() >= 0 &&
rect.top() >= 0);
433 qint32 x1, y1, x2, y2;
434 rect.getCoords(&x1, &y1, &x2, &y2);
446 rect.setCoords(x1, y1, x2, y2);
454 info->imageRect.size());
456 qint32 alignment = 1 << index;
461 planeScale, planeScale);
471 patch.
drawMe(gc, info->viewportRect, info->renderHints);
475 const QRect& unscaledRect)
478 unscaledRect.getRect(&x, &y, &w, &h);
480 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"))
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())