1///////////////////////////////////////////////////////////////////////////////
2//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
3//
4//  By downloading, copying, installing or using the software you agree to
5//  this license.  If you do not agree to this license, do not download,
6//  install, copy or use the software.
7//
8//                           License Agreement
9//                For Open Source Computer Vision Library
10//
11// Copyright (C) 2008, Google, all rights reserved.
12// Third party copyrights are property of their respective owners.
13//
14// Redistribution and use in source and binary forms, with or without
15// modification, are permitted provided that the following conditions are met:
16//
17//  * Redistribution's of source code must retain the above copyright notice,
18//     this list of conditions and the following disclaimer.
19//
20//  * Redistribution's in binary form must reproduce the above copyright notice,
21//     this list of conditions and the following disclaimer in the documentation
22//     and/or other materials provided with the distribution.
23//
24//  * The name of Intel Corporation or contributors may not be used to endorse
25//     or promote products derived from this software without specific
26//     prior written permission.
27//
28// This software is provided by the copyright holders and contributors "as is"
29// and any express or implied warranties, including, but not limited to, the
30// implied warranties of merchantability and fitness for a particular purpose
31// are disclaimed. In no event shall the Intel Corporation or contributors be
32// liable for any direct, indirect, incidental, special, exemplary, or
33// consequential damages
34// (including, but not limited to, procurement of substitute goods or services;
35// loss of use, data, or profits; or business interruption) however caused
36// and on any theory of liability, whether in contract, strict liability,
37// or tort (including negligence or otherwise) arising in any way out of
38// the use of this software, even if advised of the possibility of such damage.
39
40
41/////////////////////////////////////////////////////////////////////////////////
42//
43// Image class which provides a thin layer around an IplImage.  The goals
44// of the class design are:
45//    1. All the data has explicit ownership to avoid memory leaks
46//    2. No hidden allocations or copies for performance.
47//    3. Easy access to OpenCV methods (which will access IPP if available)
48//    4. Can easily treat external data as an image
49//    5. Easy to create images which are subsets of other images
50//    6. Fast pixel access which can take advantage of number of channels
51//          if known at compile time.
52//
53// The WImage class is the image class which provides the data accessors.
54// The 'W' comes from the fact that it is also a wrapper around the popular
55// but inconvenient IplImage class. A WImage can be constructed either using a
56// WImageBuffer class which allocates and frees the data,
57// or using a WImageView class which constructs a subimage or a view into
58// external data.  The view class does no memory management.  Each class
59// actually has two versions, one when the number of channels is known at
60// compile time and one when it isn't.  Using the one with the number of
61// channels specified can provide some compile time optimizations by using the
62// fact that the number of channels is a constant.
63//
64// We use the convention (c,r) to refer to column c and row r with (0,0) being
65// the upper left corner.  This is similar to standard Euclidean coordinates
66// with the first coordinate varying in the horizontal direction and the second
67// coordinate varying in the vertical direction.
68// Thus (c,r) is usually in the domain [0, width) X [0, height)
69//
70// Example usage:
71// WImageBuffer3_b  im(5,7);  // Make a 5X7 3 channel image of type uchar
72// WImageView3_b  sub_im(im, 2,2, 3,3); // 3X3 submatrix
73// vector<float> vec(10, 3.0f);
74// WImageView1_f user_im(&vec[0], 2, 5);  // 2X5 image w/ supplied data
75//
76// im.SetZero();  // same as cvSetZero(im.Ipl())
77// *im(2, 3) = 15;  // Modify the element at column 2, row 3
78// MySetRand(&sub_im);
79//
80// // Copy the second row into the first.  This can be done with no memory
81// // allocation and will use SSE if IPP is available.
82// int w = im.Width();
83// im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1));
84//
85// // Doesn't care about source of data since using WImage
86// void MySetRand(WImage_b* im) { // Works with any number of channels
87//   for (int r = 0; r < im->Height(); ++r) {
88//     float* row = im->Row(r);
89//     for (int c = 0; c < im->Width(); ++c) {
90//        for (int ch = 0; ch < im->Channels(); ++ch, ++row) {
91//          *row = uchar(rand() & 255);
92//        }
93//     }
94//   }
95// }
96//
97// Functions that are not part of the basic image allocation, viewing, and
98// access should come from OpenCV, except some useful functions that are not
99// part of OpenCV can be found in wimage_util.h
100#ifndef _CV_WIMAGE_H_
101#define _CV_WIMAGE_H_
102
103#include "cxcore.h"
104
105#ifdef __cplusplus
106
107namespace cv {
108
109template <typename T> class WImage;
110template <typename T> class WImageBuffer;
111template <typename T> class WImageView;
112
113template<typename T, int C> class WImageC;
114template<typename T, int C> class WImageBufferC;
115template<typename T, int C> class WImageViewC;
116
117// Commonly used typedefs.
118typedef WImage<uchar>            WImage_b;
119typedef WImageView<uchar>        WImageView_b;
120typedef WImageBuffer<uchar>      WImageBuffer_b;
121
122typedef WImageC<uchar, 1>        WImage1_b;
123typedef WImageViewC<uchar, 1>    WImageView1_b;
124typedef WImageBufferC<uchar, 1>  WImageBuffer1_b;
125
126typedef WImageC<uchar, 3>        WImage3_b;
127typedef WImageViewC<uchar, 3>    WImageView3_b;
128typedef WImageBufferC<uchar, 3>  WImageBuffer3_b;
129
130typedef WImage<float>            WImage_f;
131typedef WImageView<float>        WImageView_f;
132typedef WImageBuffer<float>      WImageBuffer_f;
133
134typedef WImageC<float, 1>        WImage1_f;
135typedef WImageViewC<float, 1>    WImageView1_f;
136typedef WImageBufferC<float, 1>  WImageBuffer1_f;
137
138typedef WImageC<float, 3>        WImage3_f;
139typedef WImageViewC<float, 3>    WImageView3_f;
140typedef WImageBufferC<float, 3>  WImageBuffer3_f;
141
142// There isn't a standard for signed and unsigned short so be more
143// explicit in the typename for these cases.
144typedef WImage<short>            WImage_16s;
145typedef WImageView<short>        WImageView_16s;
146typedef WImageBuffer<short>      WImageBuffer_16s;
147
148typedef WImageC<short, 1>        WImage1_16s;
149typedef WImageViewC<short, 1>    WImageView1_16s;
150typedef WImageBufferC<short, 1>  WImageBuffer1_16s;
151
152typedef WImageC<short, 3>        WImage3_16s;
153typedef WImageViewC<short, 3>    WImageView3_16s;
154typedef WImageBufferC<short, 3>  WImageBuffer3_16s;
155
156typedef WImage<ushort>            WImage_16u;
157typedef WImageView<ushort>        WImageView_16u;
158typedef WImageBuffer<ushort>      WImageBuffer_16u;
159
160typedef WImageC<ushort, 1>        WImage1_16u;
161typedef WImageViewC<ushort, 1>    WImageView1_16u;
162typedef WImageBufferC<ushort, 1>  WImageBuffer1_16u;
163
164typedef WImageC<ushort, 3>        WImage3_16u;
165typedef WImageViewC<ushort, 3>    WImageView3_16u;
166typedef WImageBufferC<ushort, 3>  WImageBuffer3_16u;
167
168//
169// WImage definitions
170//
171// This WImage class gives access to the data it refers to.  It can be
172// constructed either by allocating the data with a WImageBuffer class or
173// using the WImageView class to refer to a subimage or outside data.
174template<typename T>
175class WImage
176{
177public:
178    typedef T BaseType;
179
180    // WImage is an abstract class with no other virtual methods so make the
181    // destructor virtual.
182    virtual ~WImage() = 0;
183
184    // Accessors
185    IplImage* Ipl() {return image_; }
186    const IplImage* Ipl() const {return image_; }
187    T* ImageData() { return reinterpret_cast<T*>(image_->imageData); }
188    const T* ImageData() const {
189        return reinterpret_cast<const T*>(image_->imageData);
190    }
191
192    int Width() const {return image_->width; }
193    int Height() const {return image_->height; }
194
195    // WidthStep is the number of bytes to go to the pixel with the next y coord
196    int WidthStep() const {return image_->widthStep; }
197
198    int Channels() const {return image_->nChannels; }
199    int ChannelSize() const {return sizeof(T); }  // number of bytes per channel
200
201    // Number of bytes per pixel
202    int PixelSize() const {return Channels() * ChannelSize(); }
203
204    // Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number
205    // of bits per channel and with the signed bit set.
206    // This is known at compile time using specializations.
207    int Depth() const;
208
209    inline const T* Row(int r) const {
210        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
211    }
212
213    inline T* Row(int r) {
214        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
215    }
216
217    // Pixel accessors which returns a pointer to the start of the channel
218    inline T* operator() (int c, int r)  {
219        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
220            c*Channels();
221    }
222
223    inline const T* operator() (int c, int r) const  {
224        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
225            c*Channels();
226    }
227
228    // Copy the contents from another image which is just a convenience to cvCopy
229    void CopyFrom(const WImage<T>& src) { cvCopy(src.Ipl(), image_); }
230
231    // Set contents to zero which is just a convenient to cvSetZero
232    void SetZero() { cvSetZero(image_); }
233
234    // Construct a view into a region of this image
235    WImageView<T> View(int c, int r, int width, int height);
236
237protected:
238    // Disallow copy and assignment
239    WImage(const WImage&);
240    void operator=(const WImage&);
241
242    explicit WImage(IplImage* img) : image_(img) {
243        assert(!img || img->depth == Depth());
244    }
245
246    void SetIpl(IplImage* image) {
247        assert(!image || image->depth == Depth());
248        image_ = image;
249    }
250
251    IplImage* image_;
252};
253
254
255
256// Image class when both the pixel type and number of channels
257// are known at compile time.  This wrapper will speed up some of the operations
258// like accessing individual pixels using the () operator.
259template<typename T, int C>
260class WImageC : public WImage<T>
261{
262public:
263    typedef typename WImage<T>::BaseType BaseType;
264    enum { kChannels = C };
265
266    explicit WImageC(IplImage* img) : WImage<T>(img) {
267        assert(!img || img->nChannels == Channels());
268    }
269
270    // Construct a view into a region of this image
271    WImageViewC<T, C> View(int c, int r, int width, int height);
272
273    // Copy the contents from another image which is just a convenience to cvCopy
274    void CopyFrom(const WImageC<T, C>& src) {
275        cvCopy(src.Ipl(), WImage<T>::image_);
276    }
277
278    // WImageC is an abstract class with no other virtual methods so make the
279    // destructor virtual.
280    virtual ~WImageC() = 0;
281
282    int Channels() const {return C; }
283
284protected:
285    // Disallow copy and assignment
286    WImageC(const WImageC&);
287    void operator=(const WImageC&);
288
289    void SetIpl(IplImage* image) {
290        assert(!image || image->depth == WImage<T>::Depth());
291        WImage<T>::SetIpl(image);
292    }
293};
294
295//
296// WImageBuffer definitions
297//
298// Image class which owns the data, so it can be allocated and is always
299// freed.  It cannot be copied but can be explicity cloned.
300//
301template<typename T>
302class WImageBuffer : public WImage<T>
303{
304public:
305    typedef typename WImage<T>::BaseType BaseType;
306
307    // Default constructor which creates an object that can be
308    WImageBuffer() : WImage<T>(0) {}
309
310    WImageBuffer(int width, int height, int nchannels) : WImage<T>(0) {
311        Allocate(width, height, nchannels);
312    }
313
314    // Constructor which takes ownership of a given IplImage so releases
315    // the image on destruction.
316    explicit WImageBuffer(IplImage* img) : WImage<T>(img) {}
317
318    // Allocate an image.  Does nothing if current size is the same as
319    // the new size.
320    void Allocate(int width, int height, int nchannels);
321
322    // Set the data to point to an image, releasing the old data
323    void SetIpl(IplImage* img) {
324        ReleaseImage();
325        WImage<T>::SetIpl(img);
326    }
327
328    // Clone an image which reallocates the image if of a different dimension.
329    void CloneFrom(const WImage<T>& src) {
330        Allocate(src.Width(), src.Height());
331        CopyFrom(src);
332    }
333
334    ~WImageBuffer() {
335        ReleaseImage();
336    }
337
338    // Release the image if it isn't null.
339    void ReleaseImage() {
340        if (WImage<T>::image_) {
341            IplImage* image = WImage<T>::image_;
342            cvReleaseImage(&image);
343            WImage<T>::SetIpl(0);
344        }
345    }
346
347    bool IsNull() const {return WImage<T>::image_ == NULL; }
348
349private:
350    // Disallow copy and assignment
351    WImageBuffer(const WImageBuffer&);
352    void operator=(const WImageBuffer&);
353};
354
355// Like a WImageBuffer class but when the number of channels is known
356// at compile time.
357template<typename T, int C>
358class WImageBufferC : public WImageC<T, C>
359{
360public:
361    typedef typename WImage<T>::BaseType BaseType;
362    enum { kChannels = C };
363
364    // Default constructor which creates an object that can be
365    WImageBufferC() : WImageC<T, C>(0) {}
366
367    WImageBufferC(int width, int height) : WImageC<T, C>(0) {
368        Allocate(width, height);
369    }
370
371    // Constructor which takes ownership of a given IplImage so releases
372    // the image on destruction.
373    explicit WImageBufferC(IplImage* img) : WImageC<T, C>(img) {}
374
375    // Allocate an image.  Does nothing if current size is the same as
376    // the new size.
377    void Allocate(int width, int height);
378
379    // Set the data to point to an image, releasing the old data
380    void SetIpl(IplImage* img) {
381        ReleaseImage();
382        WImageC<T, C>::SetIpl(img);
383    }
384
385    // Clone an image which reallocates the image if of a different dimension.
386    void CloneFrom(const WImageC<T, C>& src) {
387        Allocate(src.Width(), src.Height());
388        CopyFrom(src);
389    }
390
391    ~WImageBufferC() {
392        ReleaseImage();
393    }
394
395    // Release the image if it isn't null.
396    void ReleaseImage() {
397        if (WImage<T>::image_) {
398            IplImage* image = WImage<T>::image_;
399            cvReleaseImage(&image);
400            WImageC<T, C>::SetIpl(0);
401        }
402    }
403
404    bool IsNull() const {return WImage<T>::image_ == NULL; }
405
406private:
407    // Disallow copy and assignment
408    WImageBufferC(const WImageBufferC&);
409    void operator=(const WImageBufferC&);
410};
411
412//
413// WImageView definitions
414//
415// View into an image class which allows treating a subimage as an image
416// or treating external data as an image
417//
418template<typename T>
419class WImageView : public WImage<T>
420{
421public:
422    typedef typename WImage<T>::BaseType BaseType;
423
424    // Construct a subimage.  No checks are done that the subimage lies
425    // completely inside the original image.
426    WImageView(WImage<T>* img, int c, int r, int width, int height);
427
428    // Refer to external data.
429    // If not given width_step assumed to be same as width.
430    WImageView(T* data, int width, int height, int channels, int width_step = -1);
431
432    // Refer to external data.  This does NOT take ownership
433    // of the supplied IplImage.
434    WImageView(IplImage* img) : WImage<T>(img) {}
435
436    // Copy constructor
437    WImageView(const WImage<T>& img) : WImage<T>(0) {
438        header_ = *(img.Ipl());
439        WImage<T>::SetIpl(&header_);
440    }
441
442    WImageView& operator=(const WImage<T>& img) {
443        header_ = *(img.Ipl());
444        WImage<T>::SetIpl(&header_);
445        return *this;
446    }
447
448protected:
449    IplImage header_;
450};
451
452
453template<typename T, int C>
454class WImageViewC : public WImageC<T, C>
455{
456public:
457    typedef typename WImage<T>::BaseType BaseType;
458    enum { kChannels = C };
459
460    // Default constructor needed for vectors of views.
461    WImageViewC();
462
463    virtual ~WImageViewC() {}
464
465    // Construct a subimage.  No checks are done that the subimage lies
466    // completely inside the original image.
467    WImageViewC(WImageC<T, C>* img,
468        int c, int r, int width, int height);
469
470    // Refer to external data
471    WImageViewC(T* data, int width, int height, int width_step = -1);
472
473    // Refer to external data.  This does NOT take ownership
474    // of the supplied IplImage.
475    WImageViewC(IplImage* img) : WImageC<T, C>(img) {}
476
477    // Copy constructor which does a shallow copy to allow multiple views
478    // of same data.  gcc-4.1.1 gets confused if both versions of
479    // the constructor and assignment operator are not provided.
480    WImageViewC(const WImageC<T, C>& img) : WImageC<T, C>(0) {
481        header_ = *(img.Ipl());
482        WImageC<T, C>::SetIpl(&header_);
483    }
484    WImageViewC(const WImageViewC<T, C>& img) : WImageC<T, C>(0) {
485        header_ = *(img.Ipl());
486        WImageC<T, C>::SetIpl(&header_);
487    }
488
489    WImageViewC& operator=(const WImageC<T, C>& img) {
490        header_ = *(img.Ipl());
491        WImageC<T, C>::SetIpl(&header_);
492        return *this;
493    }
494    WImageViewC& operator=(const WImageViewC<T, C>& img) {
495        header_ = *(img.Ipl());
496        WImageC<T, C>::SetIpl(&header_);
497        return *this;
498    }
499
500protected:
501    IplImage header_;
502};
503
504
505// Specializations for depth
506template<>
507inline int WImage<uchar>::Depth() const {return IPL_DEPTH_8U; }
508template<>
509inline int WImage<schar>::Depth() const {return IPL_DEPTH_8S; }
510template<>
511inline int WImage<short>::Depth() const {return IPL_DEPTH_16S; }
512template<>
513inline int WImage<ushort>::Depth() const {return IPL_DEPTH_16U; }
514template<>
515inline int WImage<int>::Depth() const {return IPL_DEPTH_32S; }
516template<>
517inline int WImage<float>::Depth() const {return IPL_DEPTH_32F; }
518template<>
519inline int WImage<double>::Depth() const {return IPL_DEPTH_64F; }
520
521//
522// Pure virtual destructors still need to be defined.
523//
524template<typename T> inline WImage<T>::~WImage() {}
525template<typename T, int C> inline WImageC<T, C>::~WImageC() {}
526
527//
528// Allocate ImageData
529//
530template<typename T>
531inline void WImageBuffer<T>::Allocate(int width, int height, int nchannels)
532{
533    if (IsNull() || WImage<T>::Width() != width ||
534        WImage<T>::Height() != height || WImage<T>::Channels() != nchannels) {
535        ReleaseImage();
536        WImage<T>::image_ = cvCreateImage(cvSize(width, height),
537            WImage<T>::Depth(), nchannels);
538    }
539}
540
541template<typename T, int C>
542inline void WImageBufferC<T, C>::Allocate(int width, int height)
543{
544    if (IsNull() || WImage<T>::Width() != width || WImage<T>::Height() != height) {
545        ReleaseImage();
546        WImageC<T, C>::SetIpl(cvCreateImage(cvSize(width, height),WImage<T>::Depth(), C));
547    }
548}
549
550//
551// ImageView methods
552//
553template<typename T>
554WImageView<T>::WImageView(WImage<T>* img, int c, int r, int width, int height)
555        : WImage<T>(0)
556{
557    header_ = *(img->Ipl());
558    header_.imageData = reinterpret_cast<char*>((*img)(c, r));
559    header_.width = width;
560    header_.height = height;
561    WImage<T>::SetIpl(&header_);
562}
563
564template<typename T>
565WImageView<T>::WImageView(T* data, int width, int height, int nchannels, int width_step)
566          : WImage<T>(0)
567{
568    cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), nchannels);
569    header_.imageData = reinterpret_cast<char*>(data);
570    if (width_step > 0) {
571        header_.widthStep = width_step;
572    }
573    WImage<T>::SetIpl(&header_);
574}
575
576template<typename T, int C>
577WImageViewC<T, C>::WImageViewC(WImageC<T, C>* img, int c, int r, int width, int height)
578        : WImageC<T, C>(0)
579{
580    header_ = *(img->Ipl());
581    header_.imageData = reinterpret_cast<char*>((*img)(c, r));
582    header_.width = width;
583    header_.height = height;
584    WImageC<T, C>::SetIpl(&header_);
585}
586
587template<typename T, int C>
588WImageViewC<T, C>::WImageViewC() : WImageC<T, C>(0) {
589    cvInitImageHeader(&header_, cvSize(0, 0), WImage<T>::Depth(), C);
590    header_.imageData = reinterpret_cast<char*>(0);
591    WImageC<T, C>::SetIpl(&header_);
592}
593
594template<typename T, int C>
595WImageViewC<T, C>::WImageViewC(T* data, int width, int height, int width_step)
596    : WImageC<T, C>(0)
597{
598    cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), C);
599    header_.imageData = reinterpret_cast<char*>(data);
600    if (width_step > 0) {
601        header_.widthStep = width_step;
602    }
603    WImageC<T, C>::SetIpl(&header_);
604}
605
606// Construct a view into a region of an image
607template<typename T>
608WImageView<T> WImage<T>::View(int c, int r, int width, int height) {
609    return WImageView<T>(this, c, r, width, height);
610}
611
612template<typename T, int C>
613WImageViewC<T, C> WImageC<T, C>::View(int c, int r, int width, int height) {
614    return WImageViewC<T, C>(this, c, r, width, height);
615}
616
617}  // end of namespace
618
619#endif // __cplusplus
620
621#endif  // _CV_WIMAGE_H_
622