/***************************************************************************
                           linearblend.cpp
                           ---------------
    begin                : Sun Jun 13 2004
    copyright            : (C) 2004 by Dirk Ziegelmeier
    email                : dziegel@gmx.de
***************************************************************************/

/*
 * Taken from xawtv.
 *
 * Original authors:
 * Conrad Kreyling <conrad@conrad.nerdland.org>
 * Patrick Barrett <yebyen@nerdland.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.
 */

#include <kdebug.h>
#include <klocale.h>
#include <kconfig.h>

#include "linearblend.h"
#include "kdetvimagefilter.h"
#include "kdetvimagefiltercontext.h"


class LinearBlendImageFilter : public KdetvImageFilter
{
public:
    LinearBlendImageFilter()
        : KdetvImageFilter(i18n("Linear blend"))
    {
        _fullFrameRate = false;
    }

    virtual ~LinearBlendImageFilter()
    {
    }

    virtual KdetvImage::ImageFormat inputFormats()
    {
        return (KdetvImage::ImageFormat)(KdetvImage::FORMAT_BGR24    |
                                         KdetvImage::FORMAT_BGR32    |
                                         KdetvImage::FORMAT_RGB16_LE |
                                         KdetvImage::FORMAT_RGB15_LE |
                                         KdetvImage::FORMAT_GREY     |
                                         KdetvImage::FORMAT_YUYV       );
    };

    virtual KdetvImageFilterContext* operator<< (KdetvImageFilterContext* ctx)
    {
        KdetvSharedImage* img = ctx->out;
        unsigned int x, y, bytes = img->bytesPerLine();
        unsigned char* src;

        for (y = 1; y < (unsigned)img->size().height() - 8; y+=8) {
            for (x = 0; x < bytes; x+=8) {
                src = img->buffer() + x + y * bytes;
                linearBlend(src, bytes);
            }
        }

        return ctx;
    }

private:
    static inline void linearBlend(unsigned char *src, int stride)
    {
        int x;

        for (x=0; x<8; x++) {
            src[0       ] = (src[0       ] + 2*src[stride  ] + src[stride*2])>>2;
            src[stride  ] = (src[stride  ] + 2*src[stride*2] + src[stride*3])>>2;
            src[stride*2] = (src[stride*2] + 2*src[stride*3] + src[stride*4])>>2;
            src[stride*3] = (src[stride*3] + 2*src[stride*4] + src[stride*5])>>2;
            src[stride*4] = (src[stride*4] + 2*src[stride*5] + src[stride*6])>>2;
            src[stride*5] = (src[stride*5] + 2*src[stride*6] + src[stride*7])>>2;
            src[stride*6] = (src[stride*6] + 2*src[stride*7] + src[stride*8])>>2;
            src[stride*7] = (src[stride*7] + 2*src[stride*8] + src[stride*9])>>2;

            src++;
        }
    }
};

// -----------------------------------------------------------------------

LinearBlendPlugin::LinearBlendPlugin(Kdetv *ktv, const QString& cfgkey, QObject *parent, const char* name)
    : KdetvFilterPlugin(ktv, cfgkey, parent, name)
{
    _filter = new LinearBlendImageFilter();
}

LinearBlendPlugin::~LinearBlendPlugin()
{
    delete _filter;
}

extern "C" {
    LinearBlendPlugin* create_linearblend(Kdetv* ktv)
    {
        return new LinearBlendPlugin(ktv, "deinterlace-linearblend", 0, "LinearBlend deinterlacefilter");
    }
}

#include "linearblend.moc"
