16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn///////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  this license.  If you do not agree to this license, do not download,
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  install, copy or use the software.
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                           License Agreement
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2008, Google, all rights reserved.
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// modification, are permitted provided that the following conditions are met:
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  * Redistribution's of source code must retain the above copyright notice,
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  * Redistribution's in binary form must reproduce the above copyright notice,
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  * The name of Intel Corporation or contributors may not be used to endorse
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     or promote products derived from this software without specific
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     prior written permission.
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is"
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and any express or implied warranties, including, but not limited to, the
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// implied warranties of merchantability and fitness for a particular purpose
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are disclaimed. In no event shall the Intel Corporation or contributors be
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// liable for any direct, indirect, incidental, special, exemplary, or
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////////////////////////////////////////////////////////////////
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Image class which provides a thin layer around an IplImage.  The goals
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// of the class design are:
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    1. All the data has explicit ownership to avoid memory leaks
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    2. No hidden allocations or copies for performance.
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    3. Easy access to OpenCV methods (which will access IPP if available)
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    4. Can easily treat external data as an image
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    5. Easy to create images which are subsets of other images
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    6. Fast pixel access which can take advantage of number of channels
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          if known at compile time.
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// The WImage class is the image class which provides the data accessors.
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// The 'W' comes from the fact that it is also a wrapper around the popular
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// but inconvenient IplImage class. A WImage can be constructed either using a
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// WImageBuffer class which allocates and frees the data,
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or using a WImageView class which constructs a subimage or a view into
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// external data.  The view class does no memory management.  Each class
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// actually has two versions, one when the number of channels is known at
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// compile time and one when it isn't.  Using the one with the number of
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// channels specified can provide some compile time optimizations by using the
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// fact that the number of channels is a constant.
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// We use the convention (c,r) to refer to column c and row r with (0,0) being
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the upper left corner.  This is similar to standard Euclidean coordinates
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// with the first coordinate varying in the horizontal direction and the second
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// coordinate varying in the vertical direction.
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Thus (c,r) is usually in the domain [0, width) X [0, height)
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Example usage:
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// WImageBuffer3_b  im(5,7);  // Make a 5X7 3 channel image of type uchar
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// WImageView3_b  sub_im(im, 2,2, 3,3); // 3X3 submatrix
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// vector<float> vec(10, 3.0f);
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// WImageView1_f user_im(&vec[0], 2, 5);  // 2X5 image w/ supplied data
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// im.SetZero();  // same as cvSetZero(im.Ipl())
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// *im(2, 3) = 15;  // Modify the element at column 2, row 3
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// MySetRand(&sub_im);
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// // Copy the second row into the first.  This can be done with no memory
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// // allocation and will use SSE if IPP is available.
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// int w = im.Width();
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1));
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// // Doesn't care about source of data since using WImage
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// void MySetRand(WImage_b* im) { // Works with any number of channels
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   for (int r = 0; r < im->Height(); ++r) {
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     float* row = im->Row(r);
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     for (int c = 0; c < im->Width(); ++c) {
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//        for (int ch = 0; ch < im->Channels(); ++ch, ++row) {
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          *row = uchar(rand() & 255);
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//        }
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     }
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   }
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// }
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Functions that are not part of the basic image allocation, viewing, and
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// access should come from OpenCV, except some useful functions that are not
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// part of OpenCV can be found in wimage_util.h
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifndef _CV_WIMAGE_H_
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_WIMAGE_H_
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "cxcore.h"
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef __cplusplus
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennnamespace cv {
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate <typename T> class WImage;
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate <typename T> class WImageBuffer;
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate <typename T> class WImageView;
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C> class WImageC;
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C> class WImageBufferC;
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C> class WImageViewC;
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Commonly used typedefs.
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImage<uchar>            WImage_b;
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageView<uchar>        WImageView_b;
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBuffer<uchar>      WImageBuffer_b;
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<uchar, 1>        WImage1_b;
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<uchar, 1>    WImageView1_b;
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<uchar, 1>  WImageBuffer1_b;
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<uchar, 3>        WImage3_b;
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<uchar, 3>    WImageView3_b;
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<uchar, 3>  WImageBuffer3_b;
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImage<float>            WImage_f;
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageView<float>        WImageView_f;
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBuffer<float>      WImageBuffer_f;
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<float, 1>        WImage1_f;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<float, 1>    WImageView1_f;
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<float, 1>  WImageBuffer1_f;
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<float, 3>        WImage3_f;
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<float, 3>    WImageView3_f;
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<float, 3>  WImageBuffer3_f;
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// There isn't a standard for signed and unsigned short so be more
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// explicit in the typename for these cases.
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImage<short>            WImage_16s;
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageView<short>        WImageView_16s;
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBuffer<short>      WImageBuffer_16s;
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<short, 1>        WImage1_16s;
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<short, 1>    WImageView1_16s;
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<short, 1>  WImageBuffer1_16s;
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<short, 3>        WImage3_16s;
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<short, 3>    WImageView3_16s;
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<short, 3>  WImageBuffer3_16s;
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImage<ushort>            WImage_16u;
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageView<ushort>        WImageView_16u;
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBuffer<ushort>      WImageBuffer_16u;
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<ushort, 1>        WImage1_16u;
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<ushort, 1>    WImageView1_16u;
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<ushort, 1>  WImageBuffer1_16u;
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageC<ushort, 3>        WImage3_16u;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageViewC<ushort, 3>    WImageView3_16u;
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef WImageBufferC<ushort, 3>  WImageBuffer3_16u;
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// WImage definitions
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This WImage class gives access to the data it refers to.  It can be
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// constructed either by allocating the data with a WImageBuffer class or
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// using the WImageView class to refer to a subimage or outside data.
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T>
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass WImage
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    typedef T BaseType;
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // WImage is an abstract class with no other virtual methods so make the
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // destructor virtual.
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    virtual ~WImage() = 0;
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Accessors
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    IplImage* Ipl() {return image_; }
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const IplImage* Ipl() const {return image_; }
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    T* ImageData() { return reinterpret_cast<T*>(image_->imageData); }
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const T* ImageData() const {
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return reinterpret_cast<const T*>(image_->imageData);
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Width() const {return image_->width; }
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Height() const {return image_->height; }
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // WidthStep is the number of bytes to go to the pixel with the next y coord
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int WidthStep() const {return image_->widthStep; }
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Channels() const {return image_->nChannels; }
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ChannelSize() const {return sizeof(T); }  // number of bytes per channel
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Number of bytes per pixel
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int PixelSize() const {return Channels() * ChannelSize(); }
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // of bits per channel and with the signed bit set.
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // This is known at compile time using specializations.
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Depth() const;
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    inline const T* Row(int r) const {
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    inline T* Row(int r) {
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Pixel accessors which returns a pointer to the start of the channel
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    inline T* operator() (int c, int r)  {
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c*Channels();
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    inline const T* operator() (int c, int r) const  {
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c*Channels();
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Copy the contents from another image which is just a convenience to cvCopy
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void CopyFrom(const WImage<T>& src) { cvCopy(src.Ipl(), image_); }
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Set contents to zero which is just a convenient to cvSetZero
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void SetZero() { cvSetZero(image_); }
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Construct a view into a region of this image
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageView<T> View(int c, int r, int width, int height);
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprotected:
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Disallow copy and assignment
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImage(const WImage&);
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void operator=(const WImage&);
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    explicit WImage(IplImage* img) : image_(img) {
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert(!img || img->depth == Depth());
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void SetIpl(IplImage* image) {
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert(!image || image->depth == Depth());
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        image_ = image;
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    IplImage* image_;
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Image class when both the pixel type and number of channels
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are known at compile time.  This wrapper will speed up some of the operations
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// like accessing individual pixels using the () operator.
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass WImageC : public WImage<T>
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    typedef typename WImage<T>::BaseType BaseType;
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    enum { kChannels = C };
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    explicit WImageC(IplImage* img) : WImage<T>(img) {
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert(!img || img->nChannels == Channels());
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Construct a view into a region of this image
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC<T, C> View(int c, int r, int width, int height);
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Copy the contents from another image which is just a convenience to cvCopy
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void CopyFrom(const WImageC<T, C>& src) {
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvCopy(src.Ipl(), WImage<T>::image_);
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // WImageC is an abstract class with no other virtual methods so make the
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // destructor virtual.
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    virtual ~WImageC() = 0;
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Channels() const {return C; }
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprotected:
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Disallow copy and assignment
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageC(const WImageC&);
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void operator=(const WImageC&);
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void SetIpl(IplImage* image) {
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert(!image || image->depth == WImage<T>::Depth());
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImage<T>::SetIpl(image);
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// WImageBuffer definitions
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Image class which owns the data, so it can be allocated and is always
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// freed.  It cannot be copied but can be explicity cloned.
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T>
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass WImageBuffer : public WImage<T>
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    typedef typename WImage<T>::BaseType BaseType;
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Default constructor which creates an object that can be
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageBuffer() : WImage<T>(0) {}
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageBuffer(int width, int height, int nchannels) : WImage<T>(0) {
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Allocate(width, height, nchannels);
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Constructor which takes ownership of a given IplImage so releases
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // the image on destruction.
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    explicit WImageBuffer(IplImage* img) : WImage<T>(img) {}
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Allocate an image.  Does nothing if current size is the same as
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // the new size.
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void Allocate(int width, int height, int nchannels);
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Set the data to point to an image, releasing the old data
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void SetIpl(IplImage* img) {
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ReleaseImage();
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImage<T>::SetIpl(img);
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Clone an image which reallocates the image if of a different dimension.
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void CloneFrom(const WImage<T>& src) {
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Allocate(src.Width(), src.Height());
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CopyFrom(src);
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ~WImageBuffer() {
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ReleaseImage();
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Release the image if it isn't null.
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void ReleaseImage() {
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (WImage<T>::image_) {
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage* image = WImage<T>::image_;
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvReleaseImage(&image);
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            WImage<T>::SetIpl(0);
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool IsNull() const {return WImage<T>::image_ == NULL; }
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprivate:
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Disallow copy and assignment
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageBuffer(const WImageBuffer&);
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void operator=(const WImageBuffer&);
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Like a WImageBuffer class but when the number of channels is known
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// at compile time.
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass WImageBufferC : public WImageC<T, C>
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    typedef typename WImage<T>::BaseType BaseType;
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    enum { kChannels = C };
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Default constructor which creates an object that can be
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageBufferC() : WImageC<T, C>(0) {}
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageBufferC(int width, int height) : WImageC<T, C>(0) {
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Allocate(width, height);
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Constructor which takes ownership of a given IplImage so releases
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // the image on destruction.
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    explicit WImageBufferC(IplImage* img) : WImageC<T, C>(img) {}
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Allocate an image.  Does nothing if current size is the same as
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // the new size.
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void Allocate(int width, int height);
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Set the data to point to an image, releasing the old data
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void SetIpl(IplImage* img) {
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ReleaseImage();
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImageC<T, C>::SetIpl(img);
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Clone an image which reallocates the image if of a different dimension.
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void CloneFrom(const WImageC<T, C>& src) {
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Allocate(src.Width(), src.Height());
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CopyFrom(src);
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ~WImageBufferC() {
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ReleaseImage();
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Release the image if it isn't null.
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void ReleaseImage() {
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (WImage<T>::image_) {
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage* image = WImage<T>::image_;
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvReleaseImage(&image);
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            WImageC<T, C>::SetIpl(0);
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool IsNull() const {return WImage<T>::image_ == NULL; }
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprivate:
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Disallow copy and assignment
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageBufferC(const WImageBufferC&);
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void operator=(const WImageBufferC&);
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// WImageView definitions
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// View into an image class which allows treating a subimage as an image
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or treating external data as an image
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T>
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass WImageView : public WImage<T>
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    typedef typename WImage<T>::BaseType BaseType;
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Construct a subimage.  No checks are done that the subimage lies
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // completely inside the original image.
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageView(WImage<T>* img, int c, int r, int width, int height);
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Refer to external data.
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // If not given width_step assumed to be same as width.
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageView(T* data, int width, int height, int channels, int width_step = -1);
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Refer to external data.  This does NOT take ownership
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // of the supplied IplImage.
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageView(IplImage* img) : WImage<T>(img) {}
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Copy constructor
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageView(const WImage<T>& img) : WImage<T>(0) {
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_ = *(img.Ipl());
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImage<T>::SetIpl(&header_);
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageView& operator=(const WImage<T>& img) {
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_ = *(img.Ipl());
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImage<T>::SetIpl(&header_);
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return *this;
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprotected:
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    IplImage header_;
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass WImageViewC : public WImageC<T, C>
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    typedef typename WImage<T>::BaseType BaseType;
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    enum { kChannels = C };
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Default constructor needed for vectors of views.
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC();
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    virtual ~WImageViewC() {}
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Construct a subimage.  No checks are done that the subimage lies
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // completely inside the original image.
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC(WImageC<T, C>* img,
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int c, int r, int width, int height);
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Refer to external data
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC(T* data, int width, int height, int width_step = -1);
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Refer to external data.  This does NOT take ownership
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // of the supplied IplImage.
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC(IplImage* img) : WImageC<T, C>(img) {}
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Copy constructor which does a shallow copy to allow multiple views
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // of same data.  gcc-4.1.1 gets confused if both versions of
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // the constructor and assignment operator are not provided.
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC(const WImageC<T, C>& img) : WImageC<T, C>(0) {
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_ = *(img.Ipl());
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImageC<T, C>::SetIpl(&header_);
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC(const WImageViewC<T, C>& img) : WImageC<T, C>(0) {
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_ = *(img.Ipl());
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImageC<T, C>::SetIpl(&header_);
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC& operator=(const WImageC<T, C>& img) {
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_ = *(img.Ipl());
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImageC<T, C>::SetIpl(&header_);
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return *this;
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageViewC& operator=(const WImageViewC<T, C>& img) {
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_ = *(img.Ipl());
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImageC<T, C>::SetIpl(&header_);
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return *this;
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprotected:
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    IplImage header_;
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Specializations for depth
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<>
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int WImage<uchar>::Depth() const {return IPL_DEPTH_8U; }
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<>
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int WImage<schar>::Depth() const {return IPL_DEPTH_8S; }
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<>
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int WImage<short>::Depth() const {return IPL_DEPTH_16S; }
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<>
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int WImage<ushort>::Depth() const {return IPL_DEPTH_16U; }
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<>
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int WImage<int>::Depth() const {return IPL_DEPTH_32S; }
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<>
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int WImage<float>::Depth() const {return IPL_DEPTH_32F; }
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<>
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int WImage<double>::Depth() const {return IPL_DEPTH_64F; }
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Pure virtual destructors still need to be defined.
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T> inline WImage<T>::~WImage() {}
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C> inline WImageC<T, C>::~WImageC() {}
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Allocate ImageData
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T>
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline void WImageBuffer<T>::Allocate(int width, int height, int nchannels)
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (IsNull() || WImage<T>::Width() != width ||
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImage<T>::Height() != height || WImage<T>::Channels() != nchannels) {
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ReleaseImage();
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImage<T>::image_ = cvCreateImage(cvSize(width, height),
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            WImage<T>::Depth(), nchannels);
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline void WImageBufferC<T, C>::Allocate(int width, int height)
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (IsNull() || WImage<T>::Width() != width || WImage<T>::Height() != height) {
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ReleaseImage();
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        WImageC<T, C>::SetIpl(cvCreateImage(cvSize(width, height),WImage<T>::Depth(), C));
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// ImageView methods
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T>
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennWImageView<T>::WImageView(WImage<T>* img, int c, int r, int width, int height)
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        : WImage<T>(0)
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_ = *(img->Ipl());
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.imageData = reinterpret_cast<char*>((*img)(c, r));
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.width = width;
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.height = height;
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImage<T>::SetIpl(&header_);
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T>
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennWImageView<T>::WImageView(T* data, int width, int height, int nchannels, int width_step)
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          : WImage<T>(0)
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), nchannels);
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.imageData = reinterpret_cast<char*>(data);
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (width_step > 0) {
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_.widthStep = width_step;
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImage<T>::SetIpl(&header_);
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennWImageViewC<T, C>::WImageViewC(WImageC<T, C>* img, int c, int r, int width, int height)
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        : WImageC<T, C>(0)
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_ = *(img->Ipl());
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.imageData = reinterpret_cast<char*>((*img)(c, r));
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.width = width;
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.height = height;
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageC<T, C>::SetIpl(&header_);
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennWImageViewC<T, C>::WImageViewC() : WImageC<T, C>(0) {
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvInitImageHeader(&header_, cvSize(0, 0), WImage<T>::Depth(), C);
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.imageData = reinterpret_cast<char*>(0);
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageC<T, C>::SetIpl(&header_);
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennWImageViewC<T, C>::WImageViewC(T* data, int width, int height, int width_step)
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    : WImageC<T, C>(0)
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), C);
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    header_.imageData = reinterpret_cast<char*>(data);
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (width_step > 0) {
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        header_.widthStep = width_step;
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    WImageC<T, C>::SetIpl(&header_);
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Construct a view into a region of an image
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T>
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennWImageView<T> WImage<T>::View(int c, int r, int width, int height) {
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return WImageView<T>(this, c, r, width, height);
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntemplate<typename T, int C>
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennWImageViewC<T, C> WImageC<T, C>::View(int c, int r, int width, int height) {
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return WImageViewC<T, C>(this, c, r, width, height);
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}  // end of namespace
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif // __cplusplus
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif  // _CV_WIMAGE_H_
622