1 /*
2 Copyright (c) 2019 Ferhat Kurtulmuş
3 Boost Software License - Version 1.0 - August 17th, 2003
4 Permission is hereby granted, free of charge, to any person or organization
5 obtaining a copy of the software and accompanying documentation covered by
6 this license (the "Software") to use, reproduce, display, distribute,
7 execute, and transmit the Software, and to prepare derivative works of the
8 Software, and to permit third-parties to whom the Software is furnished to
9 do so, all subject to the following:
10 The copyright notices in the Software and this entire statement, including
11 the above license grant, this restriction and the following disclaimer,
12 must be included in all copies of the Software, in whole or in part, and
13 all derivative works of the Software, unless such copies or derivative
14 works are solely in the form of machine-executable object code generated by
15 a source language processor.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
19 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
20 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24 
25 module opencvd.cvcore;
26 
27 import core.stdc.stdint;
28 import core.stdc.stdlib;
29 
30 import std.conv;
31 
32 struct Size {
33     int width;
34     int height;
35     
36     alias rows = height;
37     alias cols = width;
38 }
39 
40 struct ByteArray {
41     ubyte* data;
42     int length;
43 }
44 
45 struct CStrings {
46     const char** strs;
47     int length;
48 }
49 
50 struct Scalar {
51     double val1;
52     double val2;
53     double val3;
54     double val4;
55     
56     static Scalar all(double val){
57         return Scalar(val,val,val,val);
58     }
59     
60     double opIndex(int i){
61         double[4] tmp = [val1, val2, val3, val4];
62         return tmp[i];
63     }
64     
65     void opIndexAssign(double val, int i){
66         double*[4] tmp = [&val1, &val2, &val3, &val4];
67         *tmp[i] = val;
68     }
69     
70     bool opEquals(Scalar b){
71         if (this is b) return true;
72         if ((this.val1 == b.val1)&&
73             (this.val1 == b.val1)&&
74             (this.val1 == b.val1)&&
75             (this.val1 == b.val1))
76                 return true;
77         return false;
78     }
79 }
80 
81 alias Color = Scalar;
82 
83 struct Vec4f {
84     float val1;
85     float val2;
86     float val3;
87     float val4;
88     
89     static Vec4f all(float val){
90         return Vec4f(val,val,val,val);
91     }
92     
93     float opIndex(int i){
94         float[4] tmp = [val1, val2, val3, val4];
95         return tmp[i];
96     }
97     
98     void opIndexAssign(float val, int i){
99         float*[4] tmp = [&val1, &val2, &val3, &val4];
100         *tmp[i] = val;
101     }
102 }
103 
104 struct Vec4fs {
105     Vec4f* vec4fs;
106     int length;
107     // alias vec4fs this;// todo for all
108     Vec4f opIndex(int i){
109         return vec4fs[i];
110     }
111 }
112 
113 struct Vec3f {
114     float val1;
115     float val2;
116     float val3;
117     
118     static Vec3f all(float val){
119         return Vec3f(val,val,val);
120     }
121     
122     float opIndex(int i){
123         float[3] tmp = [val1, val2, val3];
124         return tmp[i];
125     }
126     
127     void opIndexAssign(float val, int i){
128         float*[3] tmp = [&val1, &val2, &val3];
129         *tmp[i] = val;
130     }
131 }
132 
133 struct Vec3fs{
134     Vec3f* vec3fs;
135     int length;
136     
137     Vec3f opIndex(int i){
138         return vec3fs[i];
139     }
140 }
141 
142 struct Vec4i {
143     int val1;
144     int val2;
145     int val3;
146     int val4;
147     
148     static Vec4i all(int val){
149         return Vec4i(val,val,val,val);
150     }
151     
152     int opIndex(int i){
153         int[4] tmp = [val1, val2, val3, val4];
154         return tmp[i];
155     }
156     
157     void opIndexAssign(int val, int i){
158         int*[4] tmp = [&val1, &val2, &val3, &val4];
159         *tmp[i] = val;
160     }
161 }
162 
163 struct Vec4is{
164     Vec4i* vec4is;
165     int length;
166     
167     Vec4i opIndex(int i){
168         return vec4is[i];
169     }
170 }
171 
172 struct Vec3i {
173     int val1;
174     int val2;
175     int val3;
176     
177     static Vec3i all(int val){
178         return Vec3i(val,val,val);
179     }
180     
181     int opIndex(int i){
182         int[3] tmp = [val1, val2, val3];
183         return tmp[i];
184     }
185     
186     void opIndexAssign(int val, int i){
187         int*[3] tmp = [&val1, &val2, &val3];
188         *tmp[i] = val;
189     }
190 }
191 
192 struct Vec3is {
193     Vec3i* vec3is;
194     int length;
195     
196     Vec3i opIndex(int i){
197         return vec3is[i];
198     }
199 }
200 
201 struct Vec2f {
202     float val1;
203     float val2;
204     
205     static Vec2f all(float val){
206         return Vec2f(val,val);
207     }
208     
209     float opIndex(int i){
210         float[2] tmp = [val1, val2];
211         return tmp[i];
212     }
213     
214     void opIndexAssign(float val, int i){
215         float*[2] tmp = [&val1, &val2];
216         *tmp[i] = val;
217     }
218     
219 }
220 
221 struct Vec2fs {
222     Vec2f* vec2fs;
223     int length;
224     
225     Vec2f opIndex(int i){
226         return vec2fs[i];
227     }
228 }
229 
230 struct Vec6f {
231     float val1;
232     float val2;
233     float val3;
234     float val4;
235     float val5;
236     float val6;
237     
238     static Vec6f all(float val){
239         return Vec6f(val,val,val,val,val,val);
240     }
241     
242     float opIndex(int i){
243         float[6] tmp = [val1, val2, val3, val4, val5, val6];
244         return tmp[i];
245     }
246     
247     void opIndexAssign(float val, int i){
248         float*[6] tmp = [&val1, &val2, &val3, &val4, &val5, &val6];
249         *tmp[i] = val;
250     }
251 }
252 
253 struct Vec6fs {
254     Vec6f* vec6fs;
255     int length;
256     
257     Vec6f opIndex(int i){
258         return vec6fs[i];
259     }
260 }
261 
262 struct Hierarchy {
263     Scalar* scalars;
264     int length;
265     
266     Scalar opIndex(int i){
267         return scalars[i];
268     }
269 }
270 
271 alias Colors = Hierarchy;
272 
273 struct IntVector {
274     int* val;
275     int length;
276     
277     int opIndex(int i){
278         return val[i];
279     }
280 }
281 
282 struct FloatVector {
283     float* val;
284     int length;
285     
286     float opIndex(int i){
287         return val[i];
288     }
289 }
290 
291 struct DoubleVector {
292     double* val;
293     int length;
294     
295     double opIndex(int i){
296         return val[i];
297     }
298 }
299 
300 struct CharVector {
301     char* val;
302     int length;
303     
304     char opIndex(int i){
305         return val[i];
306     }
307 }
308 
309 struct Rect {
310     int x;
311     int y;
312     int width;
313     int height;
314 }
315 
316 bool contains(Rect r, Point p){
317     return Rect_Contains(r, p);
318 }
319 
320 struct Rects {
321     Rect* rects;
322     int length;
323     
324     Rect opIndex(int i){
325         return rects[i];
326     }
327 }
328 
329 struct RotatedRect {
330     Contour pts;
331     Rect boundingRect;
332     Point center;
333     Size size;
334     double angle;
335     
336     Point[] points(){
337         return pts.points[0..pts.length];
338     }
339     
340     static RotatedRect opCall(Point center, Size size, double angle){
341         RotatedRect rr = New_RotatedRect(center, size, angle);
342         Point[] ps = rr.pts.points[0..rr.pts.length].dup;
343         Points_Close(rr.pts);
344         RotatedRect ret = {Contour(ps.ptr, cast(int)ps.length), rr.boundingRect, rr.center, rr.size, rr.angle};
345         return ret;
346     }
347 }
348 
349 struct RotatedRects {
350     RotatedRect* rects;
351     int length;
352 }
353 
354 struct Point {
355     int x;
356     int y;
357 
358     int opCmp(Point rhs) {
359         if (x < rhs.x) return -1;
360         if (rhs.x < x) return 1;
361         return 0;
362     }
363     
364     void toString(scope void delegate(const(char)[]) sink) const {
365         import std.format;
366         sink("(");
367         formattedWrite(sink, "%d", x);
368         sink(",");
369         formattedWrite(sink, "%d", y);
370         sink(")");
371     }
372     
373     Point2f asFloat(){
374         return Point2f(x.to!float, y.to!float);
375     }
376     
377     Point opBinary(string op)(double a){
378         static if (op == "+"){
379             return Point((x+a).to!int,(y+a).to!int);
380         }
381         else static if (op == "-"){
382             return Point((x-a).to!int,(y-a).to!int);
383         }
384         else static if (op == "*"){
385             return Point((x*a).to!int,(y*a).to!int);
386         }
387     }
388     
389     Point opBinary(string op)(Point a){
390         static if (op == "+"){
391             return Point((x+a.x).to!int,(y+a.y).to!int);
392         }
393         else static if (op == "-"){
394             return Point((x-a.x).to!int,(y-a.y).to!int);
395         }
396     }
397 }
398 
399 struct Point2f {
400     float x;
401     float y;
402     
403     Point asInt(){
404         return Point(x.to!int, y.to!int);
405     }
406     
407     Point2f opBinary(string op)(double a){
408         static if (op == "+"){
409             return Point2f((x+a).to!float,(y+a).to!float);
410         }
411         else static if (op == "-"){
412             return Point2f((x-a).to!float,(y-a).to!float);
413         }else static if (op == "*"){
414             return Point2f(float(x*a),float(y*a));
415         }
416     }
417     
418     Point2f opBinary(string op)(Point2f a){
419         static if (op == "+"){
420             return Point2f((x+a.x).to!float,(y+a.y).to!float);
421         }
422         else static if (op == "-"){
423             return Point2f((x-a.x).to!float,(y-a.y).to!float);
424         }
425     }
426 }
427 
428 struct Point2fs {
429     Point2f* points;
430     int length;
431     
432     Point2f opIndex(int i){
433         return points[i];
434     }
435 }
436 
437 struct Point2fss {
438     Point2fs* point2fss;
439     int length;
440     
441     Point2fs opIndex(int i){
442         return point2fss[i];
443     }
444 }
445 
446 struct Points {
447     Point* points;
448     int length;
449     
450     Point opIndex(int i){
451         return points[i];
452     }
453 }
454 
455 struct Pointss {
456     Points* pointss;
457     int length;
458     
459     Points opIndex(int i){
460         return pointss[i];
461     }
462 }
463 
464 alias Contour = Points;
465 
466 Point[] asInt(Point2f[] ip){
467     
468     Point[] ret; ret.length = ip.length;
469     foreach(j; 0..ip.length){
470         Point p = Point(ip[j].x.to!int, ip[j].y.to!int);
471         ret[j] = p;
472     }
473     return ret;
474 }
475 
476 Point[][] asInt(Point2f[][] pts){
477     
478     Point[][] ret; ret.length = pts.length;
479     foreach(i; 0..pts.length){
480         Point2f[] ip = pts[i];
481         Point[] iip; iip.length = ip.length;
482         foreach(j; 0..ip.length){
483             Point p = Point(ip[j].x.to!int, ip[j].y.to!int);
484             iip[j] = p;
485         }
486         ret[i] = iip;
487     }
488     return ret;
489 }
490 
491 Point2f[] asFloat(Point[] ip){
492     
493     Point2f[] ret; ret.length = ip.length;
494     foreach(j; 0..ip.length){
495         Point2f p = Point2f(ip[j].x.to!float, ip[j].y.to!float);
496         ret[j] = p;
497     }
498     return ret;
499 }
500 
501 Point2f[][] asFloat(Point[][] pts){
502     
503     Point2f[][] ret; ret.length = pts.length;
504     foreach(i; 0..pts.length){
505         Point2f[] iip;
506         Point[] ip = pts[i];
507         iip.length = ip.length;
508         foreach(j; 0..ip.length){
509             Point2f p = Point2f(ip[j].x.to!float, ip[j].y.to!float);
510             iip[j] = p;
511         }
512         ret[i] = iip;
513     }
514     return ret;
515 }
516 
517 struct Point2d {
518     double x;
519     double y;
520     
521     Point asInt(){
522         return Point(x.to!int, y.to!int);
523     }
524     
525     Point2f asFloat(){
526         return Point2f(x.to!float, y.to!float);
527     }
528     
529     Point2d opBinary(string op)(double a){
530         static if(op == "*")
531             return Point2d(double(x*a),double(y*a));
532         else static assert(0, "Operator "~op~" not implemented");
533     }
534 }
535 
536 struct Contours {
537     Contour* contours;
538     int length;
539     
540     Contour opIndex(int i){
541         return contours[i];
542     }
543 }
544 
545 struct KeyPoint {
546     double x;
547     double y;
548     double size;
549     double angle;
550     double response;
551     int octave;
552     int classID;
553     
554     Point2f pt(){
555         return Point2f(x.to!float, y.to!float);
556     }
557 }
558 
559 struct KeyPoints {
560     KeyPoint* keypoints;
561     int length;
562     
563     KeyPoint opIndex(int i){
564         return keypoints[i];
565     }
566 }
567 
568 struct DMatch {
569     int queryIdx;
570     int trainIdx;
571     int imgIdx;
572     float distance;
573 }
574 
575 struct DMatches {
576     DMatch* dmatches;
577     int length;
578     
579     DMatch opIndex(int i){
580         return dmatches[i];
581     }
582 }
583 
584 struct MultiDMatches {
585     DMatches* dmatches;
586     int length;
587     
588     DMatches opIndex(int i){
589         return dmatches[i];
590     }
591 }
592 
593 struct Moment {
594     double m00;
595     double m10;
596     double m01;
597     double m20;
598     double m11;
599     double m02;
600     double m30;
601     double m21;
602     double m12;
603     double m03;
604 
605     double mu20;
606     double mu11;
607     double mu02;
608     double mu30;
609     double mu21;
610     double mu12;
611     double mu03;
612 
613     double nu20;
614     double nu11;
615     double nu02;
616     double nu30;
617     double nu21;
618     double nu12;
619     double nu03;
620 }
621 
622 struct Mat {
623     void* p;
624     
625     int rows() {return Mat_Rows(this);}
626     int cols() {return Mat_Cols(this);}
627     int type() {return Mat_Type(this);}
628     int channels(){return Mat_Channels(this);}
629     int step() {return Mat_Step(this);}
630     int dims() {return Mat_Dims(this);}
631     int height() {return rows();}
632     int width() {return cols();}
633     Size size() {return Size(width(), height());}
634     int size(int i){return Mat_SizeFromInd(this, i);}
635     int total() {return Mat_Total(this);}
636     int flatLength() {return Mat_FlatLength(this);}
637     void* rawDataPtr() {return Mat_DataPtrNoCast(this);}
638     ubyte* ptr(int i = 0) { return Mat_RowPtr(this, i);}
639     ubyte* ptr(int row, int col) { return Mat_RowPtr2(this, row, col);}
640     void* ptr(int i0, int i1, int i2) { return Mat_RowPtr3(this, i0, i1, i2);}
641     
642     Scalar mean() {return Mat_Mean(this);}
643     Mat sqrt() {return Mat_Sqrt(this);}
644     
645     bool isContinuous(){
646         return Mat_IsContinuous(this);
647     }
648     
649     bool isSubmatrix(){
650         return Mat_IsSubmatrix(this);
651     }
652     
653     void locateROI(Size* wholeSize, Point* ofs){
654         Mat_LocateROI(this, wholeSize, ofs);
655     }
656     
657     Mat opCall(Rect r){
658         return matFromRect(this, r);
659     }
660     
661     static Mat opCall(){
662         return newMat();
663     }
664     
665     static Mat opCall(int rows, int cols, int mt ){
666         return Mat_NewWithSize(rows, cols, mt);
667     }
668     
669     static Mat opCall(Size sz, int mt ){
670         return Mat_NewWithSize(sz.height, sz.width, mt);
671     }
672     
673     static Mat opCall( const Scalar ar, int type){
674         return Mat_NewFromScalar(ar, type);
675     }
676 
677     static Mat opCall(const Scalar ar, int rows, int cols, int type){
678         return Mat_NewWithSizeFromScalar(ar, rows, cols, type);
679     }
680 
681     static Mat opCall(int rows, int cols, int type, ByteArray buf){
682         return Mat_NewFromBytes(rows, cols, type, buf);
683     }
684 
685     static Mat opCall(Mat m, int rows, int cols, int type, int prows, int pcols){
686         return Mat_FromPtr(m, rows, cols, type, prows, pcols);
687     }
688 
689     static Mat opCall(int rows, int cols, int type, void* data){
690         return Mat_FromArrayPtr(rows, cols, type, data);
691     }
692     
693     static Mat opCall(Point[] points){
694         return newMatFromContour(points);
695     }
696     
697     static Mat opCall(int[] data){ 
698         return Mat_FromIntVector(IntVector(data.ptr, data.length.to!int));
699     }
700     
701     static Mat opCall(float[] data){ 
702         return Mat_FromFloatVector(FloatVector(data.ptr, data.length.to!int));
703     }
704     
705     Mat opCall(Range rowRange, Range colRange = Range.all()){
706         return Mat_FromRanges(this, rowRange, colRange);
707     }
708     
709     int opDollar(int dimension)() {
710         static if (dimension == 0) {
711             return this.rows;
712 
713         } else static if (dimension == 1){
714             return this.cols;
715         }
716     }
717     
718     Range opSlice(size_t dimension)(int start, int end){
719         return Range(start, end);
720     }
721     
722     /* syntactic sugar for Mat slicing
723      * Based on: http://ddili.org/ders/d.en/templates_more.html
724      * Mat m = img[0..$-50, 50 .. 200];
725     */
726     Mat opIndex(A...)(A arguments){
727         Range rowRange = Range(0, this.rows);
728         Range colRange = Range(0, this.cols);
729         
730         Range[2] ranges = [rowRange, colRange];
731         
732         foreach (dimension, a; arguments) {
733             static if (is (typeof(a) == Range)) {
734                 ranges[dimension] = a;
735             } else
736             static if (is (typeof(a) : int) || is (typeof(a) : size_t)) {
737                 ranges[dimension] = Range(a, a + 1);
738             }
739             else {
740                 static assert( false, "Invalid index type!");
741             }
742         }
743         
744         return Mat_FromRanges(this, ranges[0], ranges[1]);
745     }
746     
747     Mat opIndexAssign(A...)(Scalar value, A arguments){
748         Mat subMatrix = opIndex(arguments);
749         subMatrix = value;
750         return subMatrix;
751     }
752     
753     Mat opCall(Range[] ranges){
754         return Mat_FromMultiRanges(this, RangeVector(ranges.ptr, ranges.length.to!int));
755     }
756     
757     Mat row(int y){
758         return Mat_HeaderFromRow(this, y);
759     }
760     
761     Mat col(int x){
762         return Mat_HeaderFromCol(this, x);
763     }
764     
765     void opAssign(Color c){
766         this.setTo(c);
767     }
768     
769     Mat opBinary(string op, V)(V a){
770         static if (op == "*"){
771             static if (is(V == ubyte)){
772                 multiplyUChar(this, a);
773             } else
774             static if (is(V == int)){
775                 Mat_MultiplyInt(this, a);
776             } else
777             static if (is(V == float)){
778                 Mat_MultiplyFloat(this, a);
779             } else
780             static if (is(V == double)){
781                 Mat_MultiplyDouble(this, a);
782             }
783             static if (is(V == Mat)){
784                 Mat_Multiply(this, a, this);
785             }
786             return this;
787         } else
788         static if (op == "/"){
789             static if (is(V == float)){
790                 Mat_MultiplyFloat(this, 1.0f/a);
791             } else
792             static if (is(V == int)){
793                 Mat_DivideInt(this, a);
794             } else
795             static if (is(V == double)){
796                 Mat_MultiplyDouble(this, 1.0/a);
797             }
798             return this;
799         } else
800         static if (op == "+"){
801             static if (is(V == int)){
802                 Mat_AddInt(this, a);
803             } else
804             static if (is(V == float)){
805                 Mat_AddFloat(this, a);
806             }else
807             static if (is(V == Mat)){
808                 add(this, a, this);
809             } else
810             static if (is(V == Scalar)){
811                 Mat_AddScalar(this, a);
812             }
813             return this;
814         } else
815         static if (op == "-"){
816             static if (is(V == int)){
817                 Mat_SubtractInt(this, a);
818             } else
819             static if (is(V == float)){
820                 Mat_SubtractFloat(this, a);
821             } else
822             static if (is(V == Mat)){
823                 matSubtract(this, a, this);
824             } else
825             static if (is(V == Scalar)){
826                 Mat_AddScalar(this, Scalar(-a.val1, -a.val2, -a.val3, -a.val4));
827             }
828             return this;
829         } else
830         static assert(0, "Operator "~op~" not implemented for type " ~ V.stringof);
831     }
832 
833     // so sad that the D does not support struct > 5
834     Mat EQInt(int a){
835         return Mat_EQInt(this, a);
836     }
837     
838     Mat GTInt(int a){
839         return Mat_GTInt(this, a);
840     }
841     
842     Mat GEInt(int a){
843         return Mat_GEInt(this, a);
844     }
845     
846     Mat LTInt(int a){
847         return Mat_LTInt(this, a);
848     }
849     
850     Mat LEInt(int a){
851         return Mat_LEInt(this, a);
852     }
853     Mat NEInt(int a){
854         return Mat_NEInt(this, a);
855     }
856     
857     Mat EQDouble(double a){
858         return Mat_EQDouble(this, a);
859     }
860     
861     Mat GTDouble(double a){
862         return Mat_GTDouble(this, a);
863     }
864     
865     Mat GEDouble(double a){
866         return Mat_GEDouble(this, a);
867     }
868     
869     Mat LTDouble(double a){
870         return Mat_LTDouble(this, a);
871     }
872     
873     Mat LEDouble(double a){
874         return Mat_LEDouble(this, a);
875     }
876     
877     Mat NEDouble(double a){
878         return Mat_NEDouble(this, a);
879     }
880     
881     string type2str(){
882         import std.conv;
883         import core.stdc.stdlib;
884         
885         auto chr = _type2str(type());
886         string stype = chr.to!string.dup;
887         free(chr);
888         return stype;
889     }
890 
891     ByteArray byteArray(){ // no reason to use this now. will be removed soon.
892         return Mat_DataPtr(this);
893     }
894 
895     // retuns d array. use it like: double[] myarray = mat.array!double;
896     T[] array(T)(){
897         T* ret = cast(T*)rawDataPtr();
898         return ret[0..flatLength()];
899     }
900     
901     Scalar opIndex(int row, int col){
902         return at(row, col);
903     }
904     
905     /* Setters */
906     void opIndexAssign(Scalar color, int row, int col){
907         setColorAt(color, row, col);
908     }
909     
910     void opIndexAssign(T)(T val, int row, int col){
911         assert(this.channels == 1, "This is only allowed for single-channel Mat types!");
912         this.set!T(row, col, cast(T)val);
913     }
914     
915     void setColorAt(Scalar color, int row, int col){
916         assert(this.channels > 1, "Color assignment is only allowed for multi-channel Mat types!");
917         Mat_SetColorAt(this, color, row, col);
918     }
919     
920     void set(T)(int row, int col, T val){
921         static if (is(T == float)){
922             setFloatAt(row, col, val);
923         } else static if (is(T == double)){
924             setDoubleAt(row, col, val);
925         } else static if (is(T == int)){
926             setIntAt(row, col, val);
927         } else static if (is(T == ubyte)){
928             setUCharAt(row, col, val);
929         } else static if (is(T == byte)){
930             setSCharAt(row, col, val);
931         } else static if (is(T == short)){
932             setShortAt(row, col, val);
933         }
934     }
935     
936     void setUCharAt(int row, int col, ubyte val){
937         Mat_SetUChar(this, row, col, val);
938     }
939 
940     void setUChar3At( int x, int y, int z, ubyte val){
941         Mat_SetUChar3(this, x, y, z, val);
942     }
943 
944     void setSCharAt(int row, int col, byte val){
945         Mat_SetSChar(this, row, col, val);
946     }
947 
948     void setSChar3At(int x, int y, int z, byte val){
949         Mat_SetSChar3(this, x, y, z, val);
950     }
951     
952     void setShortAt(int row, int col, short val){
953         Mat_SetShort(this, row, col, val);    
954     }
955     
956     void setShort3At(int x, int y, int z, short val){
957         Mat_SetShort3(this, x, y, z, val);   
958     }
959     
960     void setIntAt(int row, int col, int val){
961         Mat_SetInt(this, row, col, val);
962     }
963     
964     void setInt3At(int x, int y, int z, int val){
965         Mat_SetInt3(this, x, y, z, val);
966     }
967     
968     void setFloatAt(int row, int col, float val){
969         Mat_SetFloat(this, row, col, val);
970     }
971     
972     void setFloat3At(int x, int y, int z, float val){
973         Mat_SetFloat3(this, x, y, z, val);
974     }
975     
976     void setDoubleAt(int row, int col, double val){
977         Mat_SetDouble(this, row, col, val);
978     }
979 
980     void setDouble3At(int x, int y, int z, double val){
981         Mat_SetDouble3(this, x, y, z, val);
982     }
983 
984     /* Getters */
985     
986     T at(T)(int row, int col){
987         static if (is(T == float)){
988             return getFloatAt(row, col);
989         } else static if (is(T == double)){
990             return getDoubleAt(row, col);
991         } else static if (is(T == int)){
992             return getIntAt(row, col);
993         } else static if (is(T == ubyte)){
994             return getUCharAt(row, col);
995         } else static if (is(T == byte)){
996             return getSCharAt(row, col);
997         } else static if (is(T == short)){
998             return getShortAt(row, col);
999         }
1000     }
1001     
1002     T at(T)(int flatInd){
1003         T* ret = cast(T*)rawDataPtr();
1004         return ret[flatInd];
1005     }
1006     
1007     Color at(int row, int col){
1008         return Mat_ColorAt(this, row, col);
1009     }
1010     
1011     ubyte getUCharAt(int row, int col){
1012         return Mat_GetUChar(this, row, col);
1013     }
1014 
1015     ubyte getUChar3At(int x, int y, int z){
1016         return Mat_GetUChar3(this, x, y, z);
1017     }
1018 
1019     byte getSCharAt(int row, int col){
1020         return Mat_GetSChar(this, row, col);
1021     }
1022 
1023     byte getSChar3At(int x, int y, int z){
1024         return Mat_GetSChar3(this, x, y, z);
1025     }
1026 
1027     short getShortAt(int row, int col){
1028         return Mat_GetShort(this, row, col);
1029     }
1030 
1031     short getShort3At(int x, int y, int z){
1032         return Mat_GetShort3(this, x, y, z);
1033     }
1034 
1035     int getIntAt(int row, int col){
1036         return Mat_GetInt(this, row, col);
1037     }
1038 
1039     int getInt3At(int x, int y, int z){
1040         return Mat_GetInt3(this, x, y, z);
1041     }
1042 
1043     float getFloatAt(int row, int col){
1044         return Mat_GetFloat(this, row, col);
1045     }
1046 
1047     float getFloat3At(int x, int y, int z){
1048         return Mat_GetFloat3(this, x, y, z);
1049     }
1050 
1051     double getDoubleAt(int row, int col){
1052         return Mat_GetDouble(this, row, col);
1053     }
1054 
1055     double getDouble3At(int x, int y, int z){
1056         return Mat_GetDouble3(this, x, y, z);
1057     }
1058     
1059     Mat rowRange(int startrow, int endrow){
1060         return Mat_RowRange1(this, startrow, endrow);
1061     }
1062     
1063 }
1064 
1065 struct Mats {
1066     Mat* mats;
1067     int length;
1068     
1069     Mat opIndex(int i){
1070         return mats[i];
1071     }
1072 }
1073 
1074 enum: int {
1075     // MatChannels1 is a single channel Mat.
1076     MatChannels1 = 0,
1077 
1078     // MatChannels2 is 2 channel Mat.
1079     MatChannels2 = 8,
1080 
1081     // MatChannels3 is 3 channel Mat.
1082     MatChannels3 = 16,
1083 
1084     // MatChannels4 is 4 channel Mat.
1085     MatChannels4 = 24
1086 }
1087 
1088 enum: int {
1089     // CV8U is a Mat of 8-bit unsigned int
1090     CV8U = 0,
1091 
1092     // CV8S is a Mat of 8-bit signed int
1093     CV8S = 1,
1094 
1095     // CV16U is a Mat of 16-bit unsigned int
1096     CV16U = 2,
1097 
1098     // CV16S is a Mat of 16-bit signed int
1099     CV16S = 3,
1100 
1101     // CV16SC2 is a Mat of 16-bit signed int with 2 channels
1102     CV16SC2 = CV16S + MatChannels2,
1103 
1104     // CV32S is a Mat of 32-bit signed int
1105     CV32S = 4,
1106 
1107     // CV32F is a Mat of 32-bit float
1108     CV32F = 5,
1109 
1110     // CV64F is a Mat of 64-bit float
1111     CV64F = 6,
1112 
1113     // CV8UC1 is a Mat of 8-bit unsigned int with a single channel
1114     CV8UC1 = CV8U + MatChannels1,
1115 
1116     // CV8UC2 is a Mat of 8-bit unsigned int with 2 channels
1117     CV8UC2 = CV8U + MatChannels2,
1118 
1119     // MatTypeCV8UC3 is a Mat of 8-bit unsigned int with 3 channels
1120     CV8UC3 = CV8U + MatChannels3,
1121 
1122     // MatTypeCV8UC4 is a Mat of 8-bit unsigned int with 4 channels
1123     CV8UC4 = CV8U + MatChannels4
1124 }
1125 
1126 alias CV_8U = CV8U;
1127 alias CV_8S = CV8S;
1128 alias CV_16U = CV16U;
1129 alias CV_16S = CV16S;
1130 alias CV_16SC2 = CV16SC2;
1131 alias CV_32S = CV32S;
1132 alias CV_32F = CV32F;
1133 alias CV_64F = CV64F;
1134 alias CV_8UC1 = CV8UC1;
1135 alias CV_8UC2 = CV8UC2;
1136 alias CV_8UC3 = CV8UC3;
1137 alias CV_8UC4 = CV8UC4;
1138 
1139 alias MatType = int;
1140 
1141 extern (C) {
1142     void Close_Vec6fs(Vec6fs vec6fs);
1143     void Close_Vec4fs(Vec4fs vec4fs);
1144     void Close_Vec3fs(Vec3fs vec3fs);
1145     void Close_Vec2fs(Vec2fs vec2fs);
1146     void Close_Vec4is(Vec4is vec4is);
1147     void Close_Vec3is(Vec3is vec3is);
1148     void Close_IntVector(IntVector iv);
1149     void Close_DoubleVector(DoubleVector iv);
1150     void Close_FloatVector(FloatVector iv);
1151     
1152     void Contours_Close(Contours cs);
1153     void KeyPoints_Close(KeyPoints ks);
1154     void Rects_Close(Rects rs);
1155     void Mats_Close(Mats mats);
1156     void Point_Close(Point p);
1157     void Points_Close(Points ps);
1158     void DMatches_Close(DMatches ds);
1159     void MultiDMatches_Close(MultiDMatches mds);
1160 }
1161 
1162 private extern (C) {
1163     
1164     Mat Mat_New();
1165     Mat Mat_NewWithSize(int rows, int cols, int type);
1166     Mat Mat_NewFromScalar(const Scalar ar, int type);
1167     Mat Mat_NewWithSizeFromScalar(const Scalar ar, int rows, int cols, int type);
1168     Mat Mat_NewFromBytes(int rows, int cols, int type, ByteArray buf);
1169     Mat Mat_FromPtr(Mat m, int rows, int cols, int type, int prows, int pcols);
1170     Mat Mat_FromArrayPtr(int rows, int cols, int type, void* data);
1171     Mat Mat_FromFloatVector(FloatVector vec);
1172     Mat Mat_FromIntVector(IntVector vec);
1173     Mat Mat_HeaderFromRow(Mat src, int y);
1174     Mat Mat_HeaderFromCol(Mat src, int x);
1175     Mat Mat_RowRange1(Mat src, int startrow, int endrow);
1176     Mat Mat_FromRanges(Mat src, Range rowRange, Range colRange);
1177     Mat Mat_FromMultiRanges(Mat src, RangeVector rngs);
1178     Mat Mat_FromContour(Contour points);
1179     ubyte* Mat_RowPtr(Mat m, int i);
1180     ubyte* Mat_RowPtr2(Mat m, int row, int col);
1181     void* Mat_RowPtr3(Mat m, int i0, int i1, int i2);
1182     int Mat_CV_MAKETYPE(int depth, int cn);
1183     
1184     int Mat_Rows(Mat m);
1185     int Mat_Cols(Mat m);
1186     int Mat_Type(Mat m);
1187     int Mat_Channels(Mat m);
1188     int Mat_Step(Mat m);
1189     int Mat_Dims(Mat m);
1190     int Mat_SizeFromInd(Mat m, int i);
1191     bool Mat_IsContinuous(Mat src);
1192     bool Mat_IsSubmatrix(Mat src);
1193     void Mat_LocateROI(Mat src, Size* wholeSize, Point* ofs);
1194     
1195     char* _type2str(int type);
1196 
1197     ByteArray Mat_DataPtr(Mat m);
1198     int Mat_FlatLength(Mat src);
1199     void* Mat_DataPtrNoCast(Mat src);
1200     Scalar Mat_ColorAt(Mat src, int row, int col);
1201     
1202     Mat Mat_Reshape(Mat m, int cn, int rows);
1203 
1204     void Mat_Close(Mat m);
1205     int Mat_Empty(Mat m);
1206     Mat Mat_Clone(Mat m);
1207     void Mat_CopyTo(Mat m, Mat dst);
1208     void Mat_CopyToWithMask(Mat m, Mat dst, Mat mask);
1209     void Mat_ConvertTo(Mat m, Mat dst, int type);
1210     void Mat_convertTo2(Mat m, Mat dst, int rtype, double alpha, double beta);
1211 
1212     int Mat_Total(Mat m);
1213     Scalar Mat_Mean(Mat m);
1214     Mat Mat_Sqrt(Mat m);
1215     
1216     void Mat_SetColorAt(Mat src, Scalar color, int row, int col);
1217     void Mat_SetTo(Mat m, Scalar value);
1218     void Mat_SetToWithMask(Mat m, Scalar value, Mat mask);
1219     void Mat_SetUChar(Mat m, int row, int col, uint8_t val);
1220     void Mat_SetUChar3(Mat m, int x, int y, int z, uint8_t val);
1221     void Mat_SetSChar(Mat m, int row, int col, int8_t val);
1222     void Mat_SetSChar3(Mat m, int x, int y, int z, int8_t val);
1223     void Mat_SetShort(Mat m, int row, int col, int16_t val);
1224     void Mat_SetShort3(Mat m, int x, int y, int z, int16_t val);
1225     void Mat_SetInt(Mat m, int row, int col, int32_t val);
1226     void Mat_SetInt3(Mat m, int x, int y, int z, int32_t val);
1227     void Mat_SetFloat(Mat m, int row, int col, float val);
1228     void Mat_SetFloat3(Mat m, int x, int y, int z, float val);
1229     void Mat_SetDouble(Mat m, int row, int col, double val);
1230     void Mat_SetDouble3(Mat m, int x, int y, int z, double val);
1231 
1232     uint8_t Mat_GetUChar(Mat m, int row, int col);
1233     uint8_t Mat_GetUChar3(Mat m, int x, int y, int z);
1234     int8_t Mat_GetSChar(Mat m, int row, int col);
1235     int8_t Mat_GetSChar3(Mat m, int x, int y, int z);
1236     int16_t Mat_GetShort(Mat m, int row, int col);
1237     int16_t Mat_GetShort3(Mat m, int x, int y, int z);
1238     int32_t Mat_GetInt(Mat m, int row, int col);
1239     int32_t Mat_GetInt3(Mat m, int x, int y, int z);
1240     float Mat_GetFloat(Mat m, int row, int col);
1241     float Mat_GetFloat3(Mat m, int x, int y, int z);
1242     double Mat_GetDouble(Mat m, int row, int col);
1243     double Mat_GetDouble3(Mat m, int x, int y, int z);
1244 
1245     Mat Mat_Region(Mat m, Rect r);
1246     void Mat_PatchNaNs(Mat m);
1247     
1248     void Mat_MultiplyInt(Mat m, int val);
1249     void Mat_DivideInt(Mat m, int val);
1250     void Mat_AddDouble(Mat m, double val);
1251     void Mat_SubtractDouble(Mat m, double val);
1252     void Mat_AddInt(Mat m, int val);
1253     void Mat_SubtractInt(Mat m, int val);
1254     void Mat_AddScalar(Mat m, Scalar s);
1255     
1256     Mat Mat_EQInt(Mat m, int a);
1257     Mat Mat_GTInt(Mat m, int a);
1258     Mat Mat_GEInt(Mat m, int a);
1259     Mat Mat_LTInt(Mat m, int a);
1260     Mat Mat_LEInt(Mat m, int a);
1261     Mat Mat_NEInt(Mat m, int a);
1262 
1263     Mat Mat_EQDouble(Mat m, double a);
1264     Mat Mat_GTDouble(Mat m, double a);
1265     Mat Mat_GEDouble(Mat m, double a);
1266     Mat Mat_LTDouble(Mat m, double a);
1267     Mat Mat_LEDouble(Mat m, double a);
1268     Mat Mat_NEDouble(Mat m, double a);
1269     
1270     void Mat_AddUChar(Mat m, uint8_t val);
1271     void Mat_SubtractUChar(Mat m, uint8_t val);
1272     void Mat_MultiplyUChar(Mat m, uint8_t val);
1273     void Mat_DivideUChar(Mat m, uint8_t val);
1274     void Mat_AddFloat(Mat m, float val);
1275     void Mat_SubtractFloat(Mat m, float val);
1276     void Mat_MultiplyFloat(Mat m, float val);
1277     void Mat_MultiplyDouble(Mat m, double val);
1278     void Mat_DivideFloat(Mat m, float val);
1279 
1280     void LUT(Mat src, Mat lut, Mat dst);
1281 
1282     void Mat_AbsDiff(Mat src1, Mat src2, Mat dst);
1283     void Mat_Add(Mat src1, Mat src2, Mat dst);
1284     void Mat_AddWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat dst);
1285     void Mat_BitwiseAnd(Mat src1, Mat src2, Mat dst);
1286     void Mat_BitwiseAndWithMask(Mat src1, Mat src2, Mat dst, Mat mask);
1287     void Mat_BitwiseNot(Mat src1, Mat dst);
1288     void Mat_BitwiseNotWithMask(Mat src1, Mat dst, Mat mask);
1289     void Mat_BitwiseOr(Mat src1, Mat src2, Mat dst);
1290     void Mat_BitwiseOrWithMask(Mat src1, Mat src2, Mat dst, Mat mask);
1291     void Mat_BitwiseXor(Mat src1, Mat src2, Mat dst);
1292     void Mat_BitwiseXorWithMask(Mat src1, Mat src2, Mat dst, Mat mask);
1293     void Mat_Compare(Mat src1, Mat src2, Mat dst, int ct);
1294     void Mat_CompareWithScalar(Mat src1, Scalar src2, Mat dst, int ct);
1295     void Mat_BatchDistance(Mat src1, Mat src2, Mat dist, int dtype, Mat nidx, int normType, int K, Mat mask, int update, bool crosscheck);
1296     int Mat_BorderInterpolate(int p, int len, int borderType);
1297     void Mat_CalcCovarMatrix(Mat samples, Mat covar, Mat mean, int flags, int ctype);
1298     void Mat_CartToPolar(Mat x, Mat y, Mat magnitude, Mat angle, bool angleInDegrees);
1299     bool Mat_CheckRange(Mat m);
1300     void Mat_CompleteSymm(Mat m, bool lowerToUpper);
1301     void Mat_ConvertScaleAbs(Mat src, Mat dst, double alpha, double beta);
1302     void Mat_CopyMakeBorder(Mat src, Mat dst, int top, int bottom, int left, int right, int borderType, Scalar value);
1303     int Mat_CountNonZero(Mat src);
1304     void Mat_DCT(Mat src, Mat dst, int flags);
1305     double Mat_Determinant(Mat m);
1306     void Mat_DFT(Mat m, Mat dst, int flags);
1307     void Mat_Divide(Mat src1, Mat src2, Mat dst);
1308     bool Mat_Eigen(Mat src, Mat eigenvalues, Mat eigenvectors);
1309     void Mat_EigenNonSymmetric(Mat src, Mat eigenvalues, Mat eigenvectors);
1310     void Mat_Exp(Mat src, Mat dst);
1311     void Mat_ExtractChannel(Mat src, Mat dst, int coi);
1312     void Mat_FindNonZero(Mat src, Mat idx);
1313     void Mat_Flip(Mat src, Mat dst, int flipCode);
1314     void Mat_Gemm(Mat src1, Mat src2, double alpha, Mat src3, double beta, Mat dst, int flags);
1315     int Mat_GetOptimalDFTSize(int vecsize);
1316     void Mat_Hconcat(Mat src1, Mat src2, Mat dst);
1317     void Mat_Vconcat(Mat src1, Mat src2, Mat dst);
1318     void Rotate(Mat src, Mat dst, int rotationCode);
1319     void Mat_Idct(Mat src, Mat dst, int flags);
1320     void Mat_Idft(Mat src, Mat dst, int flags, int nonzeroRows);
1321     void Mat_InRange(Mat src, Mat lowerb, Mat upperb, Mat dst);
1322     void Mat_InRangeWithScalar(Mat src, const Scalar lowerb, const Scalar upperb, Mat dst);
1323     void Mat_InsertChannel(Mat src, Mat dst, int coi);
1324     double Mat_Invert(Mat src, Mat dst, int flags);
1325     void Mat_Log(Mat src, Mat dst);
1326     void Mat_Magnitude(Mat x, Mat y, Mat magnitude);
1327     void Mat_Max(Mat src1, Mat src2, Mat dst);
1328     void Mat_MeanStdDev(Mat src, Mat dstMean, Mat dstStdDev);
1329     void Mat_Merge(Mats mats, Mat dst);
1330     void Mat_Merge2(Mats mats, int count, Mat dst);
1331     void Mat_Min(Mat src1, Mat src2, Mat dst);
1332     void Mat_MinMaxIdx(Mat m, double* minVal, double* maxVal, int* minIdx, int* maxIdx);
1333     void Mat_MinMaxLoc(Mat m, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc);
1334     void Mat_MinMaxLoc2(Mat a, double* minVal, double* maxVal, int* minIdx, int* maxIdx);
1335     void Mat_MulSpectrums(Mat a, Mat b, Mat c, int flags);
1336     void Mat_Multiply(Mat src1, Mat src2, Mat dst);
1337     void Mat_Normalize(Mat src, Mat dst, double alpha, double beta, int typ);
1338     double Norm(Mat src1, int normType);
1339     void Mat_PerspectiveTransform(Mat src, Mat dst, Mat tm);
1340     bool Mat_Solve(Mat src1, Mat src2, Mat dst, int flags);
1341     int Mat_SolveCubic(Mat coeffs, Mat roots);
1342     double Mat_SolvePoly(Mat coeffs, Mat roots, int maxIters);
1343     void Mat_Reduce(Mat src, Mat dst, int dim, int rType, int dType);
1344     void Mat_Repeat(Mat src, int nY, int nX, Mat dst);
1345     void Mat_ScaleAdd(Mat src1, double alpha, Mat src2, Mat dst);
1346     void Mat_Sort(Mat src, Mat dst, int flags);
1347     void Mat_SortIdx(Mat src, Mat dst, int flags);
1348     void Mat_Split(Mat src, Mats* mats);
1349     Mats Mat_Split2(Mat src);
1350     void Mat_Subtract(Mat src1, Mat src2, Mat dst);
1351     Scalar Mat_Trace(Mat src);
1352     void Mat_Transform(Mat src, Mat dst, Mat tm);
1353     void Mat_Transpose(Mat src, Mat dst);
1354     void Mat_PolarToCart(Mat magnitude, Mat degree, Mat x, Mat y, bool angleInDegrees);
1355     void Mat_Pow(Mat src, double power, Mat dst);
1356     void Mat_Phase(Mat x, Mat y, Mat angle, bool angleInDegrees);
1357     Scalar Mat_Sum(Mat src1);
1358     
1359     RotatedRect New_RotatedRect(Point center, Size size, double angle);
1360     
1361     TermCriteria TermCriteria_New(int typ, int maxCount, double epsilon);
1362     double Get_TermCriteria_Epsilon(TermCriteria tc);
1363     int Get_TermCriteria_MaxCount(TermCriteria tc);
1364     int Get_TermCriteria_Type(TermCriteria tc);
1365     void TermCriteria_Close(TermCriteria tc);
1366     
1367     int64_t GetCVTickCount();
1368     double GetTickFrequency();
1369     
1370     Mat Mat_ZerosFromRC(int rows, int cols, int type);
1371     Mat Mat_ZerosFromSize(Size sz, int type);
1372     Mat Mat_OnesFromRC(int rows, int cols, int type);
1373     Mat Mat_OnesFromSize(Size sz, int type);
1374     
1375     double Mat_Dot(Mat m1, Mat m2);
1376     Mat Mat_Diag(Mat src, int d);
1377     Mat Mat_EyeFromRC(int rows, int cols, int type);
1378     
1379     bool Rect_Contains(Rect r, Point p);
1380     
1381     PCA PCA_New();
1382     PCA PCA_NewWithMaxComp(Mat data, Mat mean, int flags, int maxComponents);
1383     PCA PCA_NewWithRetVar(Mat data, Mat mean, int flags, double retainedVariance);
1384     void PCA_BackProject(PCA pca, Mat vec, Mat result);
1385     void PCA_Project(PCA pca, Mat vec, Mat result);
1386     Mat PCA_Eigenvalues(PCA pca);
1387     Mat PCA_Eigenvectors(PCA pca);
1388     Mat PCA_Mean(PCA pca);
1389     
1390     double Kmeans(Mat data, int K, Mat bestLabels,
1391         TermCriteria criteria, int attempts, int flags, Mat centers);
1392     double Kmeans2(Mat data, int K, Mat bestLabels,
1393         TermCriteria criteria, int attempts, int flags, Point2fs* centers);
1394     void Mat_Fill_Random(uint64_t state, Mat mat, int distType, Scalar a, Scalar b, bool saturateRange);
1395     void Mat_RandShuffle(uint64_t state, Mat dst, double iterFactor);
1396     
1397     Range Range_New();
1398     Range Range_NewWithParams(int _start, int _end);
1399     Range Range_All();
1400     bool Range_Empty(Range rng);
1401     int Range_Size(Range rng);
1402     int Range_GetStart(Range rng);
1403     int Range_GetEnd(Range rng);
1404 }
1405 
1406 
1407 Mat newMat(){
1408     return Mat_New();
1409 }
1410 
1411 Mat newMatWithSize( int rows, int cols, int mt ){
1412     return Mat_NewWithSize(rows, cols, mt);
1413 }
1414 
1415 Mat newMatFromScalar( const Scalar ar, int type){
1416     return Mat_NewFromScalar(ar, type);
1417 }
1418 
1419 Mat newMatWithSizeFromScalar(const Scalar ar, int rows, int cols, int type){
1420     return Mat_NewWithSizeFromScalar(ar, rows, cols, type);
1421 }
1422 
1423 Mat newMatFromBytes(int rows, int cols, int type, ByteArray buf){
1424     return Mat_NewFromBytes(rows, cols, type, buf);
1425 }
1426 
1427 Mat newMatFromPtr(Mat m, int rows, int cols, int type, int prows, int pcols){
1428     return Mat_FromPtr(m, rows, cols, type, prows, pcols);
1429 }
1430 
1431 Mat newMatFromArrayPtr(int rows, int cols, int type, void* data){
1432     return Mat_FromArrayPtr(rows, cols, type, data);
1433 }
1434 
1435 Mat newMatFromContour(Point[] pts){
1436     return Mat_FromContour(Contour(pts.ptr, pts.length.to!int));
1437 }
1438 
1439 Mat zeros(int rows, int cols, int type){
1440     return Mat_ZerosFromRC(rows, cols, type);
1441 }
1442 
1443 Mat zeros(Size sz, int type){
1444     return Mat_ZerosFromSize(sz, type);
1445 }
1446 
1447 Mat ones(int rows, int cols, int type){
1448     return Mat_OnesFromRC(rows, cols, type);
1449 }
1450 Mat ones(Size sz, int type){
1451     return Mat_OnesFromSize(sz, type);
1452 }
1453 
1454 int CV_MAKETYPE(int depth, int cn){
1455     return Mat_CV_MAKETYPE(depth, cn);
1456 }
1457 
1458 Size getSize(Mat m){
1459     return Size(m.rows, m.cols);
1460 }
1461 
1462 Mat reshape(Mat m, int cn, int rows){
1463     return Mat_Reshape( m, cn, rows);
1464 }
1465 
1466 void Destroy(Mat m){
1467     Mat_Close(m);
1468 }
1469 
1470 bool isEmpty(Mat m){
1471     return Mat_Empty(m) == 0 ? false: true;
1472 }
1473 
1474 alias empty = isEmpty;
1475 
1476 Mat clone(Mat m){
1477     return Mat_Clone(m);
1478 }
1479 
1480 void copyTo(Mat m, Mat dst){
1481     Mat_CopyTo(m, dst);
1482 }
1483 
1484 void copyToWithMask(Mat m, Mat dst, Mat mask){
1485     Mat_CopyToWithMask(m, dst, mask);
1486 }
1487 
1488 void convertTo(Mat m, Mat dst, int type){
1489     Mat_ConvertTo(m, dst, type);
1490 }
1491 
1492 void convertTo(Mat m, Mat dst, int rtype, double alpha = 1, double beta = 0 ){
1493     Mat_convertTo2(m, dst, rtype, alpha, beta);
1494 }
1495 
1496 void setTo(Mat m, Scalar s){
1497     Mat_SetTo(m, s);
1498 }
1499 
1500 void setTo(Mat m, Scalar s, Mat mask){
1501     Mat_SetToWithMask(m, s, mask);
1502 }
1503 
1504 void patchNaNs(Mat m){
1505     Mat_PatchNaNs(m);
1506 }
1507 
1508 Mat matFromRect(Mat m, Rect r){
1509     return Mat_Region(m, r);
1510 }
1511 
1512 alias subImageFromROI = matFromRect;
1513 
1514 void addUChar(Mat m, ubyte val){
1515     Mat_AddUChar(m, val);
1516 }
1517 
1518 void subtractUChar(Mat m, ubyte val){
1519     Mat_SubtractUChar(m, val);
1520 }
1521 
1522 void multiplyUChar(Mat m, ubyte val){
1523     Mat_MultiplyUChar(m, val);
1524 }
1525 
1526 void divideUChar(Mat m, ubyte val){
1527     Mat_DivideUChar(m, val);
1528 }
1529 
1530 void addFloat(Mat m, float val){
1531     Mat_AddFloat(m, val);
1532 }
1533 
1534 void subtractFloat(Mat m, float val){
1535     Mat_SubtractFloat(m, val);
1536 }
1537 
1538 void multiplyFloat(Mat m, float val){
1539     multiplyFloat(m, val);
1540 }
1541 
1542 void multiplyDouble(Mat m, double val){
1543     Mat_MultiplyDouble(m, val);
1544 }
1545 
1546 void divideFloat(Mat m, float val){
1547     Mat_DivideFloat(m, val);
1548 }
1549 
1550 void multiplyInt(Mat m, int val){
1551     Mat_MultiplyInt(m, val);
1552 }
1553 
1554 void divideInt(Mat m, int val){
1555     Mat_DivideInt(m, val);
1556 }
1557 
1558 void addDouble(Mat m, double val){
1559     Mat_AddDouble(m, val);
1560 }
1561 
1562 void subtractDouble(Mat m, double val){
1563     Mat_SubtractDouble(m, val);
1564 }
1565 
1566 void addInt(Mat m, int val){
1567     Mat_AddInt(m, val);
1568 }
1569 
1570 void subtractInt(Mat m, int val){
1571     Mat_SubtractInt(m, val);
1572 }
1573 
1574 
1575 void performLUT(Mat src, Mat lut, Mat dst){
1576     LUT(src, lut, dst);
1577 }
1578 
1579 void absDiff(Mat src1, Mat src2, Mat dst){
1580     Mat_AbsDiff(src1, src2, dst);
1581 }
1582 
1583 void add(Mat src1, Mat src2, Mat dst){
1584     Mat_Add(src1, src2, dst);
1585 }
1586 
1587 void addScalar(Mat m, Scalar s){
1588     Mat_AddScalar(m, s);
1589 }
1590 
1591 void addWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat dst){
1592     Mat_AddWeighted(src1, alpha, src2, beta, gamma, dst);
1593 }
1594 
1595 void bitwiseAnd(Mat src1, Mat src2, Mat dst){
1596     Mat_BitwiseAnd(src1, src2, dst);
1597 }
1598 
1599 void bitwiseAndWithMask(Mat src1, Mat src2, Mat dst, Mat mask){
1600     Mat_BitwiseAndWithMask(src1, src2, dst, mask);
1601 }
1602 
1603 void bitwiseNot(Mat src1, Mat dst){
1604     Mat_BitwiseNot(src1, dst);
1605 }
1606 
1607 void bitwiseNotWithMask(Mat src1, Mat dst, Mat mask){
1608     Mat_BitwiseNotWithMask(src1, dst, mask);
1609 }
1610 
1611 void bitwiseOr(Mat src1, Mat src2, Mat dst){
1612     Mat_BitwiseOr(src1, src2, dst);
1613 }
1614 
1615 void bitwiseOrWithMask(Mat src1, Mat src2, Mat dst, Mat mask){
1616     Mat_BitwiseOrWithMask(src1, src2, dst, mask);
1617 }
1618 
1619 void bitwiseXor(Mat src1, Mat src2, Mat dst){
1620     Mat_BitwiseXor(src1, src2, dst);
1621 }
1622 
1623 void bitwiseXorWithMask(Mat src1, Mat src2, Mat dst, Mat mask){
1624     Mat_BitwiseXorWithMask(src1, src2, dst, mask);
1625 }
1626 
1627 enum: int {
1628     // enum cv::CmpTypes
1629     CMP_EQ,
1630     CMP_GT,
1631     CMP_GE,
1632     CMP_LT,
1633     CMP_LE,
1634     CMP_NE,
1635 }
1636 
1637 void compare(Mat src1, Mat src2, Mat dst, int ct){
1638     Mat_Compare(src1, src2, dst, ct);
1639 }
1640 
1641 void compare(Mat src1, Scalar src2, Mat dst, int ct){
1642     Mat_CompareWithScalar(src1, src2, dst, ct);
1643 }
1644 
1645 void batchDistance(Mat src1, Mat src2, Mat dist, int dtype, Mat nidx, int normType, int K, Mat mask, int update, bool crosscheck){
1646     Mat_BatchDistance(src1, src2, dist, dtype, nidx, normType, K, mask, update, crosscheck);
1647 }
1648 
1649 enum: int {
1650 	// CovarScrambled indicates to scramble the results.
1651 	CovarScrambled = 0,
1652 
1653 	// CovarNormal indicates to use normal covariation.
1654 	CovarNormal = 1,
1655 
1656 	// CovarUseAvg indicates to use average covariation.
1657 	CovarUseAvg = 2,
1658 
1659 	// CovarScale indicates to use scaled covariation.
1660 	CovarScale = 4,
1661 
1662 	// CovarRows indicates to use covariation on rows.
1663 	CovarRows = 8,
1664 
1665 	// CovarCols indicates to use covariation on columns.
1666 	CovarCols = 16,
1667 }
1668 alias CovarFlags = int;
1669 
1670 int borderInterpolate(int p, int len, CovarFlags borderType){
1671     return Mat_BorderInterpolate(p, len, borderType);
1672 }
1673 
1674 void calcCovarMatrix(Mat samples, Mat covar, Mat mean, CovarFlags flags, int ctype){
1675     Mat_CalcCovarMatrix(samples, covar, mean, flags, ctype);
1676 }
1677 
1678 void cartToPolar(Mat x, Mat y, Mat magnitude, Mat angle, bool angleInDegrees){
1679     Mat_CartToPolar(x, y, magnitude, angle, angleInDegrees);
1680 }
1681 
1682 bool checkRange(Mat m){
1683     return Mat_CheckRange(m);
1684 }
1685 
1686 void completeSymm(Mat m, bool lowerToUpper){
1687     Mat_CompleteSymm(m, lowerToUpper);
1688 }
1689 
1690 void convertScaleAbs(Mat src, Mat dst, double alpha = 1, double beta = 0){
1691     Mat_ConvertScaleAbs(src, dst, alpha, beta);
1692 }
1693 
1694 void copyMakeBorder(Mat src, Mat dst, int top, int bottom, int left, int right, CovarFlags borderType, Scalar value){
1695     Mat_CopyMakeBorder(src, dst, top, bottom, left, right, borderType, value);
1696 }
1697 
1698 enum: int {
1699     // DftForward performs forward 1D or 2D dft or dct.
1700     DftForward  = 0,
1701 
1702     // DftInverse performs an inverse 1D or 2D transform.
1703     DftInverse = 1,
1704 
1705     // DftScale scales the result: divide it by the number of array elements. Normally, it is combined with DFT_INVERSE.
1706     DftScale = 2,
1707 
1708     // DftRows performs a forward or inverse transform of every individual row of the input matrix.
1709     DftRows = 4,
1710 
1711     // DftComplexOutput performs a forward transformation of 1D or 2D real array; the result, though being a complex array, has complex-conjugate symmetry
1712     DftComplexOutput = 16,
1713 
1714     // DftRealOutput performs an inverse transformation of a 1D or 2D complex array; the result is normally a complex array of the same size,
1715     // however, if the input array has conjugate-complex symmetry (for example, it is a result of forward transformation with DFT_COMPLEX_OUTPUT flag),
1716     // the output is a real array.
1717     DftRealOutput = 32,
1718 
1719     // DftComplexInput specifies that input is complex input. If this flag is set, the input must have 2 channels.
1720     DftComplexInput = 64,
1721 
1722     // DctInverse performs an inverse 1D or 2D dct transform.
1723     DctInverse = DftInverse,
1724 
1725     // DctRows performs a forward or inverse dct transform of every individual row of the input matrix.
1726     DctRows = DftRows
1727 }
1728 
1729 alias DftFlags = int;
1730 
1731 int countNonZero(Mat src){
1732     return Mat_CountNonZero(src);
1733 }
1734 
1735 void DCT(Mat src, Mat dst, int flags){
1736     Mat_DCT(src, dst, flags);
1737 }
1738 
1739 double determinant(Mat m){
1740     return Mat_Determinant(m);
1741 }
1742 
1743 void DFT(Mat m, Mat dst, DftFlags flags){
1744     Mat_DFT(m, dst, flags);
1745 }
1746 
1747 void divide(Mat src1, Mat src2, Mat dst){
1748     Mat_Divide(src1, src2, dst);
1749 }
1750 
1751 bool eigen(Mat src, Mat eigenvalues, Mat eigenvectors){
1752     return Mat_Eigen(src, eigenvalues, eigenvectors);
1753 }
1754 
1755 void eigenNonSymmetric(Mat src, Mat eigenvalues, Mat eigenvectors){
1756     Mat_EigenNonSymmetric(src, eigenvalues, eigenvectors);
1757 }
1758 
1759 void matExp(Mat src, Mat dst){
1760     Mat_Exp(src, dst);
1761 }
1762 
1763 void extractChannel(Mat src, Mat dst, int coi){
1764     Mat_ExtractChannel(src, dst, coi);
1765 }
1766 
1767 void findNonZero(Mat src, Mat idx){
1768     Mat_FindNonZero(src, idx);
1769 }
1770 
1771 void flip(Mat src, Mat dst, int flipCode){
1772     Mat_Flip(src, dst, flipCode);
1773 }
1774 
1775 void gemm(Mat src1, Mat src2, double alpha, Mat src3, double beta, Mat dst, int flags){
1776     Mat_Gemm(src1, src2, alpha, src3, beta, dst, flags);
1777 }
1778 
1779 int getOptimalDFTSize(int vecsize){
1780     return Mat_GetOptimalDFTSize(vecsize);
1781 }
1782 
1783 void hconcat(Mat src1, Mat src2, Mat dst){
1784     Mat_Hconcat(src1, src2, dst);
1785 }
1786 
1787 void vconcat(Mat src1, Mat src2, Mat dst){
1788     Mat_Vconcat(src1, src2, dst);
1789 }
1790 
1791 void rotate(Mat src, Mat dst, int rotationCode){
1792     Rotate(src, dst, rotationCode);
1793 }
1794 
1795 void idct(Mat src, Mat dst, int flags){
1796     Mat_Idct(src, dst, flags);
1797 }
1798 
1799 void idft(Mat src, Mat dst, int flags, int nonzeroRows){
1800     Mat_Idft(src, dst, flags, nonzeroRows);
1801 }
1802 
1803 void inRange(Mat src, Mat lowerb, Mat upperb, Mat dst){
1804     Mat_InRange(src, lowerb, upperb, dst);
1805 }
1806 
1807 void inRange(Mat src, const Scalar lowerb, const Scalar upperb, Mat dst){
1808     Mat_InRangeWithScalar(src, lowerb, upperb, dst);
1809 }
1810 
1811 void insertChannel(Mat src, Mat dst, int coi){
1812     Mat_InsertChannel(src, dst, coi);
1813 }
1814 
1815 double invert(Mat src, Mat dst, int flags){
1816     return Mat_Invert(src, dst, flags);
1817 }
1818 
1819 void matLog(Mat src, Mat dst){
1820     Mat_Log(src, dst);
1821 }
1822 
1823 void magnitude(Mat x, Mat y, Mat magnitude){
1824     Mat_Magnitude(x, y, magnitude);
1825 }
1826 
1827 void matMax(Mat src1, Mat src2, Mat dst){
1828     Mat_Max(src1, src2, dst);
1829 }
1830 
1831 void meanStdDev(Mat src, Mat dstMean, Mat dstStdDev){
1832     Mat_MeanStdDev(src, dstMean, dstStdDev);
1833 }
1834 
1835 void merge(Mats mats, Mat dst){
1836     Mat_Merge(mats, dst);
1837 }
1838 
1839 void merge(Mat[] mats, Mat dst){
1840     Mat_Merge(Mats(mats.ptr, cast(int)mats.length), dst);
1841 }
1842 
1843 void matMin(Mat src1, Mat src2, Mat dst){
1844     Mat_Min(src1, src2, dst);
1845 }
1846 
1847 void minMaxIdx(Mat m, double* minVal, double* maxVal, int* minIdx, int* maxIdx){
1848     Mat_MinMaxIdx(m, minVal, maxVal, minIdx, maxIdx);
1849 }
1850 
1851 void minMaxLoc(Mat m, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc){
1852     Mat_MinMaxLoc(m, minVal, maxVal, minLoc, maxLoc);
1853 }
1854 
1855 void minMaxLoc(Mat a, double* minVal, double* maxVal, int* minIdx, int* maxIdx){
1856     Mat_MinMaxLoc2(a, minVal, maxVal, minIdx, maxIdx);
1857 }
1858 
1859 void mulSpectrums(Mat a, Mat b, Mat c, int flags){
1860     Mat_MulSpectrums(a, b, c, flags);
1861 }
1862 
1863 void multiply(Mat src1, Mat src2, Mat dst){
1864     Mat_Multiply(src1, src2, dst);
1865 }
1866 
1867 void subtract(Mat src1, Mat src2, Mat dst){
1868     Mat_Subtract(src1, src2, dst);
1869 }
1870 
1871 enum: int {// cv::NormTypes
1872     NORM_INF = 1, 
1873     NORM_L1 = 2, 
1874     NORM_L2 = 4, 
1875     NORM_L2SQR = 5, 
1876     NORM_HAMMING = 6, 
1877     NORM_HAMMING2 = 7, 
1878     NORM_TYPE_MASK = 7, 
1879     NORM_RELATIVE = 8, 
1880     NORM_MINMAX = 32 
1881 }
1882 
1883 void normalize(Mat src, Mat dst, double alpha, double beta, int typ){
1884     Mat_Normalize(src, dst, alpha, beta, typ);
1885 }
1886 
1887 double norm(Mat src1, int normType){
1888     return Norm(src1, normType);
1889 }
1890 
1891 void perspectiveTransform(Mat src, Mat dst, Mat tm){
1892     Mat_PerspectiveTransform(src, dst, tm);
1893 }
1894 
1895 void perspectiveTransform(Point2f[] src, ref Point2f[] dst, Mat tm){
1896     
1897     Mat srcmat = zeros(src.length.to!int, 1, CV_MAKETYPE(CV_32F, 2));
1898     foreach(int i; 0..src.length.to!int){
1899         srcmat.set!float(i, 0, src[i].x);
1900         srcmat.set!float(i, 1, src[i].y);
1901     }
1902     
1903     Mat dstmat = zeros(src.length.to!int, 1, CV_MAKETYPE(CV_32F, 2));
1904     
1905     Mat_PerspectiveTransform(srcmat, dstmat, tm);
1906     
1907     dst.length = dstmat.rows.to!size_t; 
1908     foreach(int i; 0..dstmat.rows){
1909         float xx = dstmat.at!float(i, 0);
1910         float yy = dstmat.at!float(i, 1);
1911         dst[i] = Point2f(xx, yy);
1912     }
1913     
1914     Destroy(srcmat);
1915     Destroy(dstmat);
1916 }
1917 
1918 bool solve(Mat src1, Mat src2, Mat dst, int flags){
1919     return Mat_Solve(src1, src2, dst, flags);
1920 }
1921 
1922 int solveCubic(Mat coeffs, Mat roots){
1923     return Mat_SolveCubic(coeffs, roots);
1924 }
1925 
1926 double solvePoly(Mat coeffs, Mat roots, int maxIters){
1927     return Mat_SolvePoly(coeffs, roots, maxIters);
1928 }
1929 
1930 void reduce(Mat src, Mat dst, int dim, int rType, int dType){
1931     Mat_Reduce(src, dst, dim, rType, dType);
1932 }
1933 
1934 void repeat(Mat src, int nY, int nX, Mat dst){
1935     Mat_Repeat(src, nY, nX, dst);
1936 }
1937 
1938 void scaleAdd(Mat src1, double alpha, Mat src2, Mat dst){
1939     Mat_ScaleAdd(src1, alpha, src2, dst);
1940 }
1941 
1942 void matSort(Mat src, Mat dst, int flags){
1943     Mat_Sort(src, dst, flags);
1944 }
1945 
1946 void matSortIdx(Mat src, Mat dst, int flags){
1947     Mat_SortIdx(src, dst, flags);
1948 }
1949 
1950 void matSplit(Mat src, Mats* mats){
1951     Mats _mats = Mat_Split2(src);
1952     mats = &_mats;
1953 }
1954 
1955 void matSplit(Mat src, ref Mat[] _mats){
1956     Mats mats = Mat_Split2(src);
1957     _mats = mats.mats[0..mats.length];
1958 }
1959 
1960 alias split = matSplit;
1961 
1962 void matSubtract(Mat src1, Mat src2, Mat dst){
1963     Mat_Subtract(src1, src2, dst);
1964 }
1965 
1966 Scalar matTrace(Mat src){
1967     return Mat_Trace(src);
1968 }
1969 
1970 void transform(Mat src, Mat dst, Mat tm){
1971     Mat_Transform(src, dst, tm);
1972 }
1973 
1974 void transpose(Mat src, Mat dst){
1975     Mat_Transpose(src, dst);
1976 }
1977 
1978 void polarToCart(Mat magnitude, Mat degree, Mat x, Mat y, bool angleInDegrees){
1979     Mat_PolarToCart(magnitude, degree, x, y, angleInDegrees);
1980 }
1981 
1982 void matPow(Mat src, double power, Mat dst){
1983     Mat_Pow(src, power, dst);
1984 }
1985 
1986 void phase(Mat x, Mat y, Mat angle, bool angleInDegrees){
1987     Mat_Phase(x, y, angle, angleInDegrees);
1988 }
1989 
1990 Scalar matSum(Mat src1){
1991     return Mat_Sum(src1);
1992 }
1993 
1994 struct TermCriteria {
1995     void* p;
1996     
1997     enum: int { 
1998         COUNT =1, 
1999         MAX_ITER =COUNT, 
2000         EPS =2 
2001     }
2002     
2003     static TermCriteria opCall(int typ, int maxCount, double epsilon){
2004         return TermCriteria_New(typ, maxCount, epsilon);
2005     }
2006     
2007     double epsilon(){
2008         return Get_TermCriteria_Epsilon(this);
2009     }
2010     
2011     int maxCount(){
2012         return Get_TermCriteria_MaxCount(this);
2013     }
2014     
2015     int type(){
2016         return Get_TermCriteria_Type(this);
2017     }
2018 }
2019 
2020 TermCriteria newTermCriteria(int typ, int maxCount, double epsilon){
2021     return TermCriteria_New(typ, maxCount, epsilon);
2022 }
2023 
2024 void Destroy(TermCriteria tc){
2025     TermCriteria_Close(tc);
2026 }
2027 
2028 int64_t getCVTickCount(){
2029     return GetCVTickCount();
2030 }
2031 
2032 double getTickFrequency(){
2033     return GetTickFrequency();
2034 }
2035 
2036 double dot(Mat m1, Mat m2){
2037     return Mat_Dot(m1, m2);
2038 }
2039 
2040 Mat diag(Mat src, int d = 0){
2041     return Mat_Diag(src, d);
2042 }
2043 
2044 Mat eye(int rows, int cols, int type){
2045     return Mat_EyeFromRC(rows, cols, type);
2046 }
2047 
2048 Mat eye(Size sz, int type){
2049     return Mat_EyeFromRC(sz.height, sz.width, type);
2050 }
2051 
2052 struct PCA {
2053     void* p;
2054     
2055     static int DATA_AS_ROW = 0;
2056     static int DATA_AS_COL = 1;
2057     static int USE_AVG = 2;
2058     
2059     static PCA opCall(){
2060         return PCA_New();
2061     }
2062     
2063     static PCA opCall(Mat data, Mat mean, int flags, int maxComponents = 0){
2064         return PCA_NewWithMaxComp(data, mean, flags, maxComponents);
2065     }
2066     
2067     static PCA opCall(Mat data, Mat mean, int flags, double retainedVariance){
2068         return PCA_NewWithRetVar(data, mean, flags, retainedVariance);
2069     }
2070     
2071     void backProject(Mat vec, Mat result){
2072         PCA_BackProject(this, vec, result);
2073     }
2074     
2075     void project(Mat vec, Mat result){
2076         PCA_Project(this, vec, result);
2077     }
2078     
2079     Mat eigenvalues(){
2080         return PCA_Eigenvalues(this);
2081     }
2082     
2083     Mat eigenvectors(){
2084         return PCA_Eigenvectors(this);
2085     }
2086     
2087     Mat mean(){
2088         return PCA_Mean(this);
2089     }
2090 }
2091 
2092 enum: int { // cv::KmeansFlags
2093     KMEANS_RANDOM_CENTERS = 0, 
2094     KMEANS_PP_CENTERS = 2, 
2095     KMEANS_USE_INITIAL_LABELS = 1 
2096 }
2097 
2098 double kmeans(Mat data, int K, Mat bestLabels,
2099         TermCriteria criteria, int attempts, int flags, Mat centers = Mat()){
2100     return Kmeans(data, K, bestLabels, criteria, attempts, flags, centers);
2101 }
2102 
2103 double kmeans(Mat data, int K, Mat bestLabels,
2104         TermCriteria criteria, int attempts, int flags, ref Point2f[] centers){
2105     Point2fs _centers;
2106     double ret = Kmeans2(data, K, bestLabels, criteria, attempts, flags, &_centers);
2107     centers = _centers.points[0.._centers.length.to!int].dup;
2108     free(_centers.points);
2109     return ret;
2110 }
2111 
2112 enum { // 
2113     RNG_UNIFORM = 0, 
2114     RNG_NORMAL = 1
2115 }
2116 
2117 void fillRandom(uint64_t state, Mat mat, int distType, Scalar a, Scalar b, bool saturateRange = false){
2118     Mat_Fill_Random(state, mat, distType, a, b, saturateRange);
2119 }
2120 
2121 void randShuffle(uint64_t state, Mat dst, double iterFactor=1.0){
2122     Mat_RandShuffle(state, dst, iterFactor);
2123 }
2124 
2125 struct Range {
2126     void* p;
2127     
2128     static Range opCall(){
2129         return Range_New();
2130     }
2131     
2132     static Range opCall(int _start, int _end){
2133         return Range_NewWithParams(_start, _end);
2134     }
2135     
2136     static Range all(){
2137         return Range_All();
2138     }
2139     
2140     bool empty(){
2141         return Range_Empty(this);
2142     }
2143     
2144     int size(){
2145         return Range_Size(this);
2146     }
2147     
2148     int start(){
2149         return Range_GetStart(this);
2150     } 
2151      
2152     int end(){
2153         return Range_GetEnd(this);
2154     }
2155 }
2156 
2157 struct RangeVector {
2158     Range* ranges;
2159     int length;
2160 }