// -*- c++ -*-
/***************************************************************************
                           kdetvimage.h
                           ------------
    begin                : Sat Jun 12 2004
    copyright            : (C) 2004 by Dirk Ziegelmeier
    email                : dziegel@gmx.de
 ***************************************************************************/

/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef KDETVIMAGE_H
#define KDETVIMAGE_H

#include <qsize.h>
#include <QString>
#include <QImage>
#include "libkdetv_export.h"

class LIBKDETV_EXPORT KdetvImage
{
public:
    typedef enum {
        FORMAT_NONE     =       0,
        FORMAT_GREY     =  (1<<0),
        FORMAT_HI240    =  (1<<1),
        FORMAT_RGB15_LE =  (1<<2),
        FORMAT_RGB15_BE =  (1<<3),
        FORMAT_RGB16_LE =  (1<<4),
        FORMAT_RGB16_BE =  (1<<5),
        FORMAT_RGB32    =  (1<<6),
        FORMAT_BGR32    =  (1<<7),
        FORMAT_RGB24    =  (1<<8),
        FORMAT_BGR24    =  (1<<9),
        FORMAT_YUYV     = (1<<10),
        FORMAT_UYVY     = (1<<11),
        FORMAT_YUV422P  = (1<<12),
        FORMAT_YUV420P  = (1<<13),
        FORMAT_ALL      = 0x00003FFF
    } ImageFormat;

    typedef enum {
        TYPE_PROGRESSIVE     = 0,
        TYPE_INTERLACED_ODD  = 1,
        TYPE_INTERLACED_EVEN = 2
    } ImageType;

    KdetvImage();
    virtual ~KdetvImage();

    bool toQImage(QImage& img);

    // Size in pixels
    QSize size() const { return _size; };
    QSize setSize(QSize size);

    ImageFormat format() const { return _format; };
    ImageFormat setFormat(ImageFormat format);

    void setType(ImageType type);
    ImageType type() const { return _type; };

    // Gap behind a line of pixels (in bytes)
    void setStride(unsigned int stride);
    unsigned int stride() const { return _stride; };

    void setBuffer(unsigned char* buf, unsigned int size, bool owner=false);
    void deleteBuffer();
    void createBuffer(unsigned int size);
    unsigned char* buffer() { return _buf; };
    unsigned int bufferSize() { return _bufSize; };

    unsigned int bytesPerPixel() const { return bytesppForFormat(_format);        };
    unsigned int bytesPerLine()  const { return bytesPerPixel() * size().width(); };

    const QString toString() const { return toString(_format); };
    static const QString toString(ImageFormat fmt);

    static unsigned int bytesppForFormat(ImageFormat fmt);


protected:
    QSize        _size;
    ImageFormat  _format;
    ImageType    _type;
    unsigned int _stride;


private:
    unsigned int   _bufSize;
    unsigned char* _buf;
    bool           _bufowner;
};

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

// You cannot delete these directly. Use deleteRef().
class KdetvSharedImage : public KdetvImage
{
public:
    KdetvSharedImage();

    KdetvSharedImage& newRef();
    virtual void deleteRef();


protected:
    virtual ~KdetvSharedImage();

    unsigned int _refCount;
};

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

class KdetvImagePool;

// You cannot create these directly. Get them from a KdetvImagePool.
// You cannot delete these directly. Use deleteRef().
class KdetvPooledImage : public KdetvSharedImage
{
private:
    virtual ~KdetvPooledImage();

    friend class KdetvImagePool;

    KdetvPooledImage(KdetvImagePool* pool);
    void* operator new(size_t, KdetvImagePool* pool);
    void operator delete(void* instance);

    KdetvPooledImage* _next;
    KdetvImagePool*   _pool;
};

#endif //KDETVIMAGE_H

