Skip to content

Commit

Permalink
Use ImageMagick for the flattening of layers, this will need to be
Browse files Browse the repository at this point in the history
reorganized for threads, i.e. only one Image::Magick Image is used for tiles
right now, each tile must an image on it's own to allow easily writing to
each of them in parallel.  Fixed how opacity values are translated between
Qt and ImageMagick.

svn path=/trunk/koffice/; revision=151035
  • Loading branch information
Patrick Julien committed Apr 21, 2002
1 parent 304fc2e commit 00eac05
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 92 deletions.
28 changes: 28 additions & 0 deletions krita/core/kis_color_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <string.h>

#include <Magick++.h>

#include "kis_color_utils.h"
#include "kis_pixel_packet.h"
#include "kis_global.h"

namespace KisColorUtils {
using namespace Magick;

QRgb bytes2rgb(const uchar* bytes, int /*bpp*/)
{
// XXX
Expand All @@ -36,5 +43,26 @@ namespace KisColorUtils {
bytes[PIXEL_BLUE] = qBlue(rgb);
bytes[PIXEL_ALPHA] = qAlpha(rgb);
}

void blendOver(KisPixelPacket *dst, const KisPixelPacket *src)
{
if (!dst || !src)
return;

if (src -> opacity != TransparentOpacity) {
if (src -> opacity == OpaqueOpacity) {
memcpy(dst, src, sizeof(KisPixelPacket));
} else if (src -> opacity != TransparentOpacity) {
Quantum opacity = (MaxRGB - src -> opacity) + src -> opacity * (MaxRGB - dst -> opacity) / MaxRGB;
Quantum invSrcOpacity = MaxRGB - src -> opacity;
Quantum invDstOpacity = MaxRGB - dst -> opacity;

dst -> red = ((invSrcOpacity * src -> red + src -> opacity * invDstOpacity * dst -> red / MaxRGB) / opacity);
dst -> green = ((invSrcOpacity * src -> green + src -> opacity * invDstOpacity * dst -> green / MaxRGB) / opacity);
dst -> blue = ((invSrcOpacity * src -> blue + src -> opacity * invDstOpacity * dst -> blue / MaxRGB) / opacity);
dst -> opacity = MaxRGB - opacity;
}
}
}
}

3 changes: 3 additions & 0 deletions krita/core/kis_color_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@

#include <qcolor.h>

class KisPixelPacket;

namespace KisColorUtils {
QRgb bytes2rgb(const uchar* bytes, int bpp);
void rgb2bytes(const QRgb& rgb, uchar* bytes, int bpp);
void blendOver(KisPixelPacket *dst, const KisPixelPacket *src);
}

#endif // KIS_COLOR_UTILS_H_
Expand Down
100 changes: 20 additions & 80 deletions krita/core/kis_image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <klocale.h>

#include "kis_brush.h"
#include "kis_color_utils.h"
#include "kis_doc.h"
#include "kis_image.h"
#include "kis_factory.h"
Expand All @@ -47,40 +48,6 @@

using namespace Magick;

/*
* Very experimental thread test, only for experimenting
*/

#if 1
class KisRenderThread : public QThread {
public:
KisRenderThread(KisImage *img, QWaitCondition *wcDirty)
{
m_img = img;
m_wcDirty = wcDirty;
}

protected:
virtual void run()
{
kdDebug() << "Thread running.\n";

while (1) {
m_wcDirty -> wait();
m_img -> slotUpdateTimeOut();
}
}

KisImage *m_img;
QWaitCondition *m_wcDirty;
};

QWaitCondition wcDirty;
QPtrQueue<QPoint> dirtyTiles;
QMutex dirtyTilesMutex;

#endif

class KisCommandLayerActive : public KNamedCommand {
typedef KNamedCommand super;

Expand Down Expand Up @@ -346,7 +313,7 @@ void KisImage::addLayer(const QRect& rect, const KoColor& c, bool /*tr*/, const
QRgb defaultColor;

if (getCurrentLayer())
defaultColor = qRgba(CHANNEL_MAX, CHANNEL_MAX, CHANNEL_MAX, OPACITY_TRANSPARENT);
defaultColor = qRgba(0, 0, 0, 0);
else
defaultColor = c.color().rgb();

Expand Down Expand Up @@ -422,13 +389,6 @@ void KisImage::markDirty(const QRect& r)

if (m_autoUpdate)
compositeImage(QRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE));
#if 0
else {
dirtyTilesMutex.lock();
dirtyTiles.enqueue(new QPoint(x, y));
dirtyTilesMutex.unlock();
}
#endif
}
}

Expand Down Expand Up @@ -542,50 +502,24 @@ void KisImage::paintPixmap(QPainter *p, const QRect& area)

void KisImage::compositeTile(KisPaintDevice *dstDevice, int tileNo, int x, int y)
{
#if 0
Magick::Geometry geo(TILE_SIZE, TILE_SIZE, x * TILE_SIZE, y * TILE_SIZE);
bool initial = true;
Image dstimg = dstDevice -> getImage();
Image *dstimg = dstDevice -> getImage();
Image tile(Geometry(TILE_SIZE, TILE_SIZE), Color(0, 0, 0, TransparentOpacity));

for (KisLayerSPLstConstIterator it = m_layers.begin(); it != m_layers.end(); it++) {
Q_ASSERT(dstimg);

for (KisLayerSPLstIterator it = m_layers.begin(); it != m_layers.end(); it++) {
KisLayerSP layer = *it;

if (layer && layer -> visible()) {
if (initial) {
initial = false;
KisPixelPacket *dst = dstDevice -> getPixels(0, 0);
const KisPixelPacket *src = layer -> getConstPixels(x, y);

memcpy(dst, src, TILE_SIZE * TILE_SIZE * sizeof(KisPixelPacket));
dstDevice -> syncPixels();
} else {
dstimg.compositeImage(layer -> getImage(), geo);
}
}
}
#else
const PixelPacket *src = layer -> getConstPixels(x, y);
PixelPacket *dst = tile.getPixels(0, 0, TILE_SIZE, TILE_SIZE);

KisPixelPacket *dst = dstDevice -> getPixels(0, 0);
const KisPixelPacket *bkgPacket = m_bgLayer -> getConstPixels(0, 0);

Q_ASSERT(dst);
memcpy(dst, bkgPacket, TILE_SIZE * TILE_SIZE * sizeof(KisPixelPacket));

for (KisLayerSPLstConstIterator it = m_layers.begin(); it != m_layers.end(); it++) {
KisLayerSP lay = *it;

if (lay && lay -> visible()) {
const KisPixelPacket *src = lay -> getConstPixels(x, y);

if (dst && src) {
// memcpy(dst, src, TILE_SIZE * TILE_SIZE * sizeof(KisPixelPacket));
renderTile(dst, src, lay);
}
memcpy(dst, src, sizeof(PixelPacket) * TILE_SIZE * TILE_SIZE);
tile.syncPixels();
// tile.opacity(TransparentOpacity - Upscale(layer -> opacity()));
dstimg -> composite(tile, tileNo * TILE_SIZE, tileNo * TILE_SIZE, OverCompositeOp);
}
}

dstDevice -> syncPixels();
#endif
}

void KisImage::compositeImage(const QRect& area, bool allDirty)
Expand All @@ -597,6 +531,11 @@ void KisImage::compositeImage(const QRect& area, bool allDirty)
if (!allDirty && m_dirty[y * m_xTiles + x] == false)
continue;

KisPixelPacket *dst = m_composeLayer -> getPixels(0, 0);
const KisPixelPacket *src = m_bgLayer -> getConstPixels(0, 0);

memcpy(dst, src, TILE_SIZE * TILE_SIZE * sizeof(KisPixelPacket));
m_composeLayer -> syncPixels();
compositeTile(m_composeLayer, 0, x * TILE_SIZE, y * TILE_SIZE);
convertTileToPixmap(m_composeLayer, 0, m_pixmapTiles[y * m_xTiles + x]);
m_dirty[y * m_xTiles + x] = false;
Expand Down Expand Up @@ -640,7 +579,7 @@ void KisImage::convertTileToPixmap(KisPaintDevice *dstDevice, int tileNo, QPixma
const KisPixelPacket *pixel = srcTile + row * m_imgTile.width() + column;
QRgb rgb;

rgb = qRgba(Downscale(pixel -> red), Downscale(pixel -> green), Downscale(pixel -> blue), Downscale(TransparentOpacity - pixel -> opacity));
rgb = *pixel;
m_imgTile.setPixel(column, row, rgb);
}
}
Expand Down Expand Up @@ -917,6 +856,7 @@ void KisImage::addChannel(const QRect& rc, uchar opacity, const QString& name)
m_channels.push_back(chan);
m_activeChannel = chan;
resizeImage(chan, rc);

#if 0
if (m_doUndo)
addCommand(new KisCommandLayerAdd(this, lay));
Expand Down
9 changes: 5 additions & 4 deletions krita/core/kis_paint_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ const int TILE_BYTES = TILE_SIZE * TILE_SIZE * sizeof(uint);

KisPaintDevice::KisPaintDevice(const QString& name, uint width, uint height, uchar bpp, const QRgb& defaultColor)
{
Color clr(Upscale(qRed(defaultColor)), Upscale(qGreen(defaultColor)), Upscale(qBlue(defaultColor)), Upscale(qAlpha(defaultColor)));
Color clr(Upscale(qRed(defaultColor)), Upscale(qGreen(defaultColor)), Upscale(qBlue(defaultColor)), TransparentOpacity - Upscale(qAlpha(defaultColor)));

m_bpp = bpp;
m_name = name;
m_imgRect = QRect(0, 0, width, height);
resize(m_imgRect.width(), m_imgRect.height(), bpp);
m_tileRect = KisUtil::findTileExtents(m_imgRect);
m_visible = true;
m_opacity = qAlpha(defaultColor);
m_tiles = new Image(Geometry(width, height), clr);
m_opacity = CHANNEL_MAX;
m_tiles = new Image(Geometry(m_tileRect.width(), m_tileRect.height()), clr);
m_tiles -> matte(true);
}

Expand Down Expand Up @@ -161,6 +161,7 @@ void KisPaintDevice::allocateRect(const QRect& rc, uchar bpp)

const KisPixelPacket* KisPaintDevice::getConstPixels(int x, int y, uint width, uint height) const
{
Q_ASSERT(m_tiles);
return static_cast<const KisPixelPacket*>(m_tiles -> getConstPixels(x, y, width, height));
}

Expand Down
2 changes: 1 addition & 1 deletion krita/core/kis_paint_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class KisPaintDevice : public QObject, public KShared {
inline int width() const;
inline int height() const;

Magick::Image getImage() { return *m_tiles; }
Magick::Image* getImage() { return m_tiles; }

protected:
uchar m_bpp;
Expand Down
14 changes: 7 additions & 7 deletions krita/core/kis_pixel_packet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ KisPixelPacket::KisPixelPacket(const QRgb& rgb)
red = Upscale(qRed(rgb));
green = Upscale(qGreen(rgb));
blue = Upscale(qBlue(rgb));
opacity = Upscale(qAlpha(rgb));
opacity = TransparentOpacity - Upscale(qAlpha(rgb));
}

KisPixelPacket::KisPixelPacket(const QColor& clr)
Expand All @@ -40,7 +40,7 @@ KisPixelPacket::KisPixelPacket(const QColor& clr)
red = Upscale(qRed(rgb));
green = Upscale(qGreen(rgb));
blue = Upscale(qBlue(rgb));
opacity = Upscale(qAlpha(rgb));
opacity = TransparentOpacity - Upscale(qAlpha(rgb));
}

KisPixelPacket::KisPixelPacket(const KoColor& clr)
Expand All @@ -51,7 +51,7 @@ KisPixelPacket::KisPixelPacket(const KoColor& clr)
red = Upscale(qRed(rgb));
green = Upscale(qGreen(rgb));
blue = Upscale(qBlue(rgb));
opacity = Upscale(qAlpha(rgb));
opacity = TransparentOpacity - Upscale(qAlpha(rgb));
}

KisPixelPacket::KisPixelPacket(const KisPixelPacket& rhs)
Expand Down Expand Up @@ -79,7 +79,7 @@ KisPixelPacket& KisPixelPacket::operator=(const QRgb& rgb)
red = Upscale(qRed(rgb));
green = Upscale(qGreen(rgb));
blue = Upscale(qBlue(rgb));
opacity = Upscale(qAlpha(rgb));
opacity = TransparentOpacity - Upscale(qAlpha(rgb));
return *this;
}

Expand All @@ -90,7 +90,7 @@ KisPixelPacket& KisPixelPacket::operator=(const QColor& clr)
red = Upscale(qRed(rgb));
green = Upscale(qGreen(rgb));
blue = Upscale(qBlue(rgb));
opacity = Upscale(qAlpha(rgb));
opacity = TransparentOpacity - Upscale(qAlpha(rgb));
return *this;
}

Expand All @@ -102,7 +102,7 @@ KisPixelPacket& KisPixelPacket::operator=(const KoColor& clr)
red = Upscale(qRed(rgb));
green = Upscale(qGreen(rgb));
blue = Upscale(qBlue(rgb));
opacity = Upscale(qAlpha(rgb));
opacity = TransparentOpacity - Upscale(qAlpha(rgb));
return *this;
}

Expand All @@ -124,7 +124,7 @@ KisPixelPacket& KisPixelPacket::operator=(const PixelPacket& rhs)

KisPixelPacket::operator QRgb() const
{
return qRgba(Downscale(red), Downscale(green), Downscale(blue), Downscale(opacity));
return qRgba(Downscale(red), Downscale(green), Downscale(blue), Downscale(TransparentOpacity - opacity));
}

KisPixelPacket::operator QColor() const
Expand Down

0 comments on commit 00eac05

Please sign in to comment.