rawbmp.h

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C头文件 代码 · 共 726 行 · 第 1/2 页

H
726
字号
            // absolutely must) version
            Iterator operator++(int)
            {
                Iterator p(*this);
                ++*this;
                return p;
            }

            // move x pixels to the right and y down
            //
            // note that the rows don't wrap!
            void Offset(const PixelData& data, int x, int y)
            {
                m_pRGB += data.GetRowStride()*y + PixelFormat::SizePixel*x;
                if ( m_pAlpha )
                    m_pAlpha += data.GetWidth() + x;
            }

            // move x pixels to the right (again, no row wrapping)
            void OffsetX(const PixelData& WXUNUSED(data), int x)
            {
                m_pRGB += PixelFormat::SizePixel*x;
                if ( m_pAlpha )
                    m_pAlpha += x;
            }

            // move y rows to the bottom
            void OffsetY(const PixelData& data, int y)
            {
                m_pRGB += data.GetRowStride()*y;
                if ( m_pAlpha )
                    m_pAlpha += data.GetWidth();
            }

            // go to the given position
            void MoveTo(const PixelData& data, int x, int y)
            {
                Reset(data);
                Offset(data, x, y);
            }


            // data access
            // -----------

            // access to invidividual colour components
            ChannelType& Red() { return m_pRGB[PixelFormat::RED]; }
            ChannelType& Green() { return m_pRGB[PixelFormat::GREEN]; }
            ChannelType& Blue() { return m_pRGB[PixelFormat::BLUE]; }
            ChannelType& Alpha() { return *m_pAlpha; }

        // private: -- see comment in the beginning of the file

            // pointer into RGB buffer
            unsigned char *m_pRGB;

            // pointer into alpha buffer or NULL if alpha isn't used
            unsigned char *m_pAlpha;
        };

        // initializes us with the data of the given image
        wxPixelDataIn(ImageType& image) : m_image(image), m_pixels(image)
        {
            m_width = image.GetWidth();
            m_height = image.GetHeight();
            m_stride = Iterator::SizePixel * m_width;
        }

        // initializes us with the given region of the specified image
        wxPixelDataIn(ImageType& image,
                      const wxPoint& pt,
                      const wxSize& sz) : m_image(image), m_pixels(image)
        {
            m_stride = Iterator::SizePixel * m_width;

            InitRect(pt, sz);
        }

        // initializes us with the given region of the specified image
        wxPixelDataIn(ImageType& image,
                      const wxRect& rect) : m_image(image), m_pixels(image)
        {
            m_stride = Iterator::SizePixel * m_width;

            InitRect(rect.GetPosition(), rect.GetSize());
        }

        // we evaluate to true only if we could get access to bitmap data
        // successfully
        operator bool() const { return m_pixels.IsOk(); }

        // get the iterator pointing to the origin
        Iterator GetPixels() const { return m_pixels; }

    private:
        void InitRect(const wxPoint& pt, const wxSize& sz)
        {
            m_width = sz.x;
            m_height = sz.y;

            m_ptOrigin = pt;
            m_pixels.Offset(*this, pt.x, pt.y);
        }

        // the image we're working with
        ImageType& m_image;

        // the iterator pointing to the image origin
        Iterator m_pixels;
    };
};
#endif //wxUSE_IMAGE

#if wxUSE_GUI
// wxPixelData specialization for wxBitmap: here things are more interesting as
// we also have to support different pixel formats
template <>
struct wxPixelDataOut<wxBitmap>
{
    template <class Format>
    class wxPixelDataIn : public wxPixelDataBase
    {
    public:
        // the type of the class we're working with
        typedef wxBitmap ImageType;

        class Iterator
        {
        public:
            // the pixel format we use
            typedef Format PixelFormat;

            // the type of the pixel components
            typedef typename PixelFormat::ChannelType ChannelType;

            // the pixel data we're working with
            typedef wxPixelDataOut<wxBitmap>::wxPixelDataIn<Format> PixelData;


            // go back to (0, 0)
            void Reset(const PixelData& data)
            {
                *this = data.GetPixels();
            }

            // initializes the iterator to point to the origin of the given
            // pixel data
            Iterator(PixelData& data)
            {
                Reset(data);
            }

            // initializes the iterator to point to the origin of the given
            // bitmap
            Iterator(wxBitmap& bmp, PixelData& data)
            {
                // using cast here is ugly but it should be safe as
                // GetRawData() real return type should be consistent with
                // BitsPerPixel (which is in turn defined by ChannelType) and
                // this is the only thing we can do without making GetRawData()
                // a template function which is undesirable
                m_ptr = (ChannelType *)
                            bmp.GetRawData(data, PixelFormat::BitsPerPixel);
            }

            // return true if this iterator is valid
            bool IsOk() const { return m_ptr != NULL; }


            // navigation
            // ----------

            // advance the iterator to the next pixel, prefix version
            Iterator& operator++()
            {
                m_ptr += PixelFormat::SizePixel;

                return *this;
            }

            // postfix (hence less efficient -- don't use it unless you
            // absolutely must) version
            Iterator operator++(int)
            {
                Iterator p(*this);
                ++*this;
                return p;
            }

            // move x pixels to the right and y down
            //
            // note that the rows don't wrap!
            void Offset(const PixelData& data, int x, int y)
            {
                m_ptr += data.GetRowStride()*y + PixelFormat::SizePixel*x;
            }

            // move x pixels to the right (again, no row wrapping)
            void OffsetX(const PixelData& WXUNUSED(data), int x)
            {
                m_ptr += PixelFormat::SizePixel*x;
            }

            // move y rows to the bottom
            void OffsetY(const PixelData& data, int y)
            {
                m_ptr += data.GetRowStride()*y;
            }

            // go to the given position
            void MoveTo(const PixelData& data, int x, int y)
            {
                Reset(data);
                Offset(data, x, y);
            }


            // data access
            // -----------

            // access to invidividual colour components
            ChannelType& Red() { return m_ptr[PixelFormat::RED]; }
            ChannelType& Green() { return m_ptr[PixelFormat::GREEN]; }
            ChannelType& Blue() { return m_ptr[PixelFormat::BLUE]; }
            ChannelType& Alpha() { return m_ptr[PixelFormat::ALPHA]; }

            // address the pixel contents directly
            //
            // warning: the format is platform dependent
            typename PixelFormat::PixelType& Data()
                { return *(typename PixelFormat::PixelType *)m_ptr; }

        // private: -- see comment in the beginning of the file

            // for efficiency reasons this class should not have any other
            // fields, otherwise it won't be put into a CPU register (as it
            // should inside the inner loops) by some compilers, notably gcc
            ChannelType *m_ptr;
        };

        // ctor associates this pointer with a bitmap and locks the bitmap for
        // raw access, it will be unlocked only by our dtor and so these
        // objects should normally be only created on the stack, i.e. have
        // limited life-time
        wxPixelDataIn(wxBitmap& bmp) : m_bmp(bmp), m_pixels(bmp, *this)
        {
        }

        wxPixelDataIn(wxBitmap& bmp, const wxRect& rect)
            : m_bmp(bmp), m_pixels(bmp, *this)
        {
            InitRect(rect.GetPosition(), rect.GetSize());
        }

        wxPixelDataIn(wxBitmap& bmp, const wxPoint& pt, const wxSize& sz)
            : m_bmp(bmp), m_pixels(bmp, *this)
        {
            InitRect(pt, sz);
        }

        // we evaluate to true only if we could get access to bitmap data
        // successfully
        operator bool() const { return m_pixels.IsOk(); }

        // get the iterator pointing to the origin
        Iterator GetPixels() const { return m_pixels; }

        // dtor unlocks the bitmap
        ~wxPixelDataIn()
        {
            m_bmp.UngetRawData(*this);
        }

        // call this to indicate that we should use the alpha channel
        void UseAlpha() { m_bmp.UseAlpha(); }

    // private: -- see comment in the beginning of the file

        // the bitmap we're associated with
        wxBitmap m_bmp;

        // the iterator pointing to the image origin
        Iterator m_pixels;

    private:
        void InitRect(const wxPoint& pt, const wxSize& sz)
        {
            m_pixels.Offset(*this, pt.x, pt.y);

            m_ptOrigin = pt;
            m_width = sz.x;
            m_height = sz.y;
        }
    };
};
#endif //wxUSE_GUI

#ifdef __VISUALC__
    // typedef-name 'foo' used as synonym for class-name 'bar'
    // (VC++ gives this warning each time wxPixelData::Base is used but it
    //  doesn't make any sense here -- what's wrong with using typedef instead
    //  of class, this is what it is here for!)
    #pragma warning(disable: 4097)
#endif // __VISUALC__

template <class Image, class PixelFormat = wxPixelFormatFor<Image> >
class wxPixelData :
    public wxPixelDataOut<Image>::template wxPixelDataIn<PixelFormat>
{
public:
    typedef
        typename wxPixelDataOut<Image>::template wxPixelDataIn<PixelFormat>
        Base;

    wxPixelData(Image& image) : Base(image) { }

    wxPixelData(Image& i, const wxRect& rect) : Base(i, rect) { }

    wxPixelData(Image& i, const wxPoint& pt, const wxSize& sz)
        : Base(i, pt, sz)
    {
    }
};


// some "predefined" pixel data classes
#if wxUSE_IMAGE
typedef wxPixelData<wxImage> wxImagePixelData;
#endif //wxUSE_IMAGE
#if wxUSE_GUI
typedef wxPixelData<wxBitmap, wxNativePixelFormat> wxNativePixelData;
typedef wxPixelData<wxBitmap, wxAlphaPixelFormat> wxAlphaPixelData;

#endif //wxUSE_GUI

// ----------------------------------------------------------------------------
// wxPixelIterator
// ----------------------------------------------------------------------------

/*
    wxPixel::Iterator represents something which points to the pixel data and
    allows us to iterate over it. In the simplest case of wxBitmap it is,
    indeed, just a pointer, but it can be something more complicated and,
    moreover, you are free to specialize it for other image classes and bitmap
    formats.

    Note that although it would have been much more intuitive to have a real
    class here instead of what we have now, this class would need two template
    parameters, and this can't be done because we'd need compiler support for
    partial template specialization then and neither VC6 nor VC7 provide it.
 */
template < class Image, class PixelFormat = wxPixelFormatFor<Image> >
struct wxPixelIterator : public wxPixelData<Image, PixelFormat>::Iterator
{
};

#ifdef __VISUALC__
    #pragma warning(pop)
#endif

#endif // _WX_RAWBMP_H_BASE_

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?