[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    Re: nativeColor and endianness
From:       Boudewijn Rempt <boud () valdyas ! org>
Date:       2003-10-24 5:11:13
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


On Friday 24 October 2003 02:01, Patrick Julien wrote:
> Having the header file would be useful too :). 

Oh! Inlcuded the header of the interface...

> However, I remind you that
> the color strategies we're deemed to be flyweights, you should initialized
> the entire array instead of building it progressively.  

I was rather afraid that an array for a whole colourspace would become very 
big -- even if using flyweights (as I understand them). This way you get a 
nice speedup anyway. And, more importantly, once that little radio button for 
CMYK is selectable, people coding for Krita will _have_ to take care that 
they don't blithely assume RGBA -- even if the implementation of CMYK isn't 
perfect yet.

I'm slowly discovering what premultiplied alpha means, too :-).

>You see, you might
> even optimize this by saving the color array after the first run of the
> application.

Perhaps something for the future...

>
> In other words, the first time you need a translated color, simply
> initialize all the colors.
>
> Yes, CMYKA is perfectly possible.
>
> I don't have the definition of a Color lut either.  Anyway, I will wait for
> more code since I don't actually have the code to read :)
>

This time, I've added the header, too.

-- 
Boudewijn Rempt | http://www.valdyas.org/index2.html

["kis_strategy_colorspace_cmyk.h" (text/x-chdr)]

/*
 *  Copyright (c) 2003 Boudewijn Rempt (boud@valdyas.org)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
#if !defined KIS_STRATEGY_COLORSPACE_CMYK_H_
#define KIS_STRATEGY_COLORSPACE_CMYK_H_

#include <qcolor.h>
#include <qpixmap.h>
#include <qmap.h>

#include <kpixmapio.h>
#include <koColor.h>

#include "kis_global.h"
#include "kis_strategy_colorspace.h"

/**
   This class implements the conversion of the Krita images that contain cmy + \
transparency  data to rbg for screen rendering.

 */

class CMYK {
 public:
    QUANTUM c;
    QUANTUM m;
    QUANTUM y;
    QUANTUM k;

    bool operator< (const CMYK &) const;
};

inline bool CMYK::operator<(const CMYK &other) const
{ return c < other.c; }


class RGB {
 public:
    QUANTUM r;
    QUANTUM g;
    QUANTUM b;
};

// Map cmyka to rgba
//   Todo: pre-multiply the rgb with the alpha value. But then, the rest of
//         Krita needs to know about that, too.
typedef QMap<CMYK, RGB> ColorLUT;

class KisStrategyColorSpaceCMYK : public KisStrategyColorSpace {
public:
	KisStrategyColorSpaceCMYK();
	virtual ~KisStrategyColorSpaceCMYK();

public:
	virtual void nativeColor(const KoColor& c, QUANTUM *dst);
	virtual void nativeColor(const KoColor& c, QUANTUM opacity, QUANTUM *dst);
	virtual void nativeColor(const QColor& c, QUANTUM *dst);
	virtual void nativeColor(const QColor& c, QUANTUM opacity, QUANTUM *dst);
	virtual void nativeColor(QRgb rgb, QUANTUM *dst);
	virtual void nativeColor(QRgb rgb, QUANTUM opacity, QUANTUM *dst);
	virtual void render(KisImageSP projection, QPainter& painter, Q_INT32 x, Q_INT32 y, \
Q_INT32 width, Q_INT32 height);

private:

	KPixmapIO m_pixio;
	QPixmap m_pixmap;

	QUANTUM *m_buf;

        static ColorLUT m_rgbLUT;
};

#endif // KIS_STRATEGY_COLORSPACE_CMYK_H_


["kis_strategy_colorspace_cmyk.cc" (text/x-c++src)]

/*
 *  Copyright (c) 2003 Boudewijn Rempt (boud@valdyas.org)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
#include <limits.h>

#include <qimage.h>
#include <qpainter.h>
#include <qpixmap.h>

#include <kdebug.h>

#include "kis_image.h"
#include "kis_strategy_colorspace_cmyk.h"
#include "tiles/kispixeldata.h"

namespace {
    const Q_INT32 MAX_CHANNEL_CMYK = 4;
    // Is it actually possible to have transparency with CMYK?
    const Q_INT32 MAX_CHANNEL_CMYKA = 5;
}

// Init static data
ColorLUT KisStrategyColorSpaceCMYK::m_rgbLUT = ColorLUT();


KisStrategyColorSpaceCMYK::KisStrategyColorSpaceCMYK() : m_pixmap(RENDER_WIDTH * 2, \
RENDER_HEIGHT * 2) {
    m_buf = new QUANTUM[RENDER_WIDTH * RENDER_HEIGHT * MAX_CHANNEL_CMYKA];
}

KisStrategyColorSpaceCMYK::~KisStrategyColorSpaceCMYK()
{
    delete[] m_buf;
}

void KisStrategyColorSpaceCMYK::nativeColor(const KoColor& c, QUANTUM *dst)
{
    dst[PIXEL_CYAN] = upscale( c.C() );
    dst[PIXEL_MAGENTA] = upscale( c.M() );
    dst[PIXEL_YELLOW] = upscale( c.Y() );
    dst[PIXEL_BLACK] = upscale( c.K() );
}

void KisStrategyColorSpaceCMYK::nativeColor(const KoColor& c, QUANTUM opacity, \
QUANTUM *dst) {
    dst[PIXEL_CYAN] = upscale( c.C() );
    dst[PIXEL_MAGENTA] = upscale( c.M() );
    dst[PIXEL_YELLOW] = upscale( c.Y() );
    dst[PIXEL_BLACK] = upscale( c.K() );
    dst[PIXEL_CMYK_ALPHA] = opacity;
}

void KisStrategyColorSpaceCMYK::nativeColor(const QColor& c, QUANTUM *dst)
{
    KoColor k = KoColor( c );

    dst[PIXEL_CYAN] = upscale( k.C() );
    dst[PIXEL_MAGENTA] = upscale( k.M() );
    dst[PIXEL_YELLOW] = upscale( k.Y() );
    dst[PIXEL_BLACK] = upscale( k.K() );
}

void KisStrategyColorSpaceCMYK::nativeColor(const QColor& c, QUANTUM opacity, QUANTUM \
*dst) {
    KoColor k = KoColor( c );

    dst[PIXEL_CYAN] = upscale( k.C() );
    dst[PIXEL_MAGENTA] = upscale( k.M() );
    dst[PIXEL_YELLOW] = upscale( k.Y() );
    dst[PIXEL_BLACK] = upscale( k.K() );
    dst[PIXEL_CMYK_ALPHA] = opacity;

}

void KisStrategyColorSpaceCMYK::nativeColor(QRgb rgb, QUANTUM *dst)
{
    KoColor k = KoColor(QColor( rgb ));

    dst[PIXEL_CYAN] = upscale( k.C() );
    dst[PIXEL_MAGENTA] = upscale( k.M() );
    dst[PIXEL_YELLOW] = upscale( k.Y() );
    dst[PIXEL_BLACK] = upscale( k.K() );
}

void KisStrategyColorSpaceCMYK::nativeColor(QRgb rgb, QUANTUM opacity, QUANTUM *dst)
{
    KoColor k = KoColor(QColor( rgb ));

    dst[PIXEL_CYAN] = upscale( k.C() );
    dst[PIXEL_MAGENTA] = upscale( k.M() );
    dst[PIXEL_YELLOW] = upscale( k.Y() );
    dst[PIXEL_BLACK] = upscale( k.K() );
    dst[PIXEL_CMYK_ALPHA] = opacity;
}

void KisStrategyColorSpaceCMYK::render(KisImageSP projection, QPainter& painter, \
Q_INT32 x, Q_INT32 y, Q_INT32 width, Q_INT32 height) {
    if (projection) {
        KisTileMgrSP tm = projection -> tiles();
        KisPixelDataSP pd = new KisPixelData;
        QImage img;

        pd -> mgr = 0;
        pd -> tile = 0;
        pd -> mode = TILEMODE_READ;
        pd -> x1 = x;
        pd -> x2 = x + width - 1;
        pd -> y1 = y;
        pd -> y2 = y + height - 1;
        pd -> width = pd -> x2 - pd -> x1 + 1;
        pd -> height = pd -> y2 - pd -> y1 + 1;
        pd -> depth = projection -> depth();
        pd -> stride = pd -> depth * pd -> width;
        pd -> owner = false;
        pd -> data = m_buf;
        tm -> readPixelData(pd);
#if 0
        kdDebug() << "ARG: x " << x
                  << ", y " << y
                  << ", w " << width
                  << ", h " << height
                  << endl;
        kdDebug() << "PD: x1 " << pd->x1
                  << ", y1 " << pd->y1
                  << ", x2 " << pd->x2
                  << ", y2  " << pd->y2
                  << ", w " << pd->width
                  << ", h " << pd->height
                  << endl;
#endif
        img = QImage(pd->width,  pd->height,  32); // 32 is the max depth of QImage; \
we have more in CMYK

        Q_INT32 i = 0;

        uchar *j = img.bits();

        while ( i < pd ->stride * pd -> height ) {

            RGB r;
            // Check in LUT whether k already exists; if so, grab it, else
            CMYK c;
            c.c = *( pd->data + i + PIXEL_CYAN );
            c.m = *( pd->data + i + PIXEL_MAGENTA );
            c.y = *( pd->data + i + PIXEL_YELLOW );
            c.k = *( pd->data + i + PIXEL_BLACK );


            if ( i == 0 ) {
            kdDebug() << "cmyk: "
                          << c.c << ", "
                          << c.m << ", "
                          << c.y << ", "
                          << c.k << endl;
            }


            if ( m_rgbLUT.contains ( c ) ) {
                r =  m_rgbLUT[c];
            }
            else {
                // Accessing the rgba of KoColor automatically converts
                // from cmyk to rgb and caches the result
                KoColor k = KoColor(c.c,
                                    c.m,
                                    c.y,
                                    c.k );
                // Store as little as possible
                r.r = upscale( k.R() );
                r.g = upscale( k.G() );
                r.b = upscale( k.B() );

                if ( i == 0 ) {
                    kdDebug() << "rgb: "
                              << r.r << ", "
                              << r.g << ", "
                              << r.b << endl;
                }

                m_rgbLUT[c] = r;
            }

            // fix the pixel in QImage.
             *( j + PIXEL_ALPHA ) = *( pd->data + i + PIXEL_CMYK_ALPHA );
             *( j + PIXEL_RED ) = r.r;
             *( j + PIXEL_GREEN ) = r.g;
             *( j + PIXEL_BLUE ) = r.b;

             i += MAX_CHANNEL_CMYKA;
             j += 4; // Because we're hard-coded 32 bits deep, 4 bytes

        }
        m_pixio.putImage(&m_pixmap, 0, 0, &img);
        painter.drawPixmap(x, y, m_pixmap, 0, 0, width, height);
    }
}


[Attachment #9 (application/pgp-signature)]

_______________________________________________
kimageshop mailing list
kimageshop@mail.kde.org
http://mail.kde.org/mailman/listinfo/kimageshop


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic