Some of code review feedbacks addressed: CvType moved from Mat, new Mat c-tor, samples updated.
This commit is contained in:
parent
ec6fb0bee2
commit
2cce7a87b8
@ -245,8 +245,12 @@ public class %(module)s {
|
|||||||
static {
|
static {
|
||||||
System.loadLibrary("opencv_java");
|
System.loadLibrary("opencv_java");
|
||||||
}
|
}
|
||||||
|
""" % {"module" : module} )
|
||||||
|
|
||||||
public static final int
|
if module == "core":
|
||||||
|
self.java_code.write(\
|
||||||
|
"""
|
||||||
|
private static final int
|
||||||
CV_8U = 0,
|
CV_8U = 0,
|
||||||
CV_8S = 1,
|
CV_8S = 1,
|
||||||
CV_16U = 2,
|
CV_16U = 2,
|
||||||
@ -254,15 +258,21 @@ public class %(module)s {
|
|||||||
CV_32S = 4,
|
CV_32S = 4,
|
||||||
CV_32F = 5,
|
CV_32F = 5,
|
||||||
CV_64F = 6,
|
CV_64F = 6,
|
||||||
CV_USRTYPE1 = 7,
|
CV_USRTYPE1 = 7;
|
||||||
|
|
||||||
|
""" )
|
||||||
|
|
||||||
|
if module == "imgproc":
|
||||||
|
self.java_code.write(\
|
||||||
|
"""
|
||||||
|
public static final int
|
||||||
IPL_BORDER_CONSTANT = 0,
|
IPL_BORDER_CONSTANT = 0,
|
||||||
IPL_BORDER_REPLICATE = 1,
|
IPL_BORDER_REPLICATE = 1,
|
||||||
IPL_BORDER_REFLECT = 2,
|
IPL_BORDER_REFLECT = 2,
|
||||||
IPL_BORDER_WRAP = 3,
|
IPL_BORDER_WRAP = 3,
|
||||||
IPL_BORDER_REFLECT_101 = 4,
|
IPL_BORDER_REFLECT_101 = 4,
|
||||||
IPL_BORDER_TRANSPARENT = 5;
|
IPL_BORDER_TRANSPARENT = 5;
|
||||||
""" % {"module" : module} )
|
""" )
|
||||||
|
|
||||||
# cpp module header
|
# cpp module header
|
||||||
self.cpp_code.write(\
|
self.cpp_code.write(\
|
||||||
"""// This file is auto-generated, please don't edit!
|
"""// This file is auto-generated, please don't edit!
|
||||||
|
130
modules/java/src/java/CvType.java
Normal file
130
modules/java/src/java/CvType.java
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package org.opencv;
|
||||||
|
|
||||||
|
|
||||||
|
public final class CvType {
|
||||||
|
|
||||||
|
// predefined type constants
|
||||||
|
public static final CvType
|
||||||
|
CV_8UC1 = CV_8UC(1), CV_8UC2 = CV_8UC(2), CV_8UC3 = CV_8UC(3), CV_8UC4 = CV_8UC(4),
|
||||||
|
CV_8SC1 = CV_8SC(1), CV_8SC2 = CV_8SC(2), CV_8SC3 = CV_8SC(3), CV_8SC4 = CV_8SC(4),
|
||||||
|
CV_16UC1 = CV_16UC(1), CV_16UC2 = CV_16UC(2), CV_16UC3 = CV_16UC(3), CV_16UC4 = CV_16UC(4),
|
||||||
|
CV_16SC1 = CV_16SC(1), CV_16SC2 = CV_16SC(2), CV_16SC3 = CV_16SC(3), CV_16SC4 = CV_16SC(4),
|
||||||
|
CV_32SC1 = CV_32SC(1), CV_32SC2 = CV_32SC(2), CV_32SC3 = CV_32SC(3), CV_32SC4 = CV_32SC(4),
|
||||||
|
CV_32FC1 = CV_32FC(1), CV_32FC2 = CV_32FC(2), CV_32FC3 = CV_32FC(3), CV_32FC4 = CV_32FC(4),
|
||||||
|
CV_64FC1 = CV_64FC(1), CV_64FC2 = CV_64FC(2), CV_64FC3 = CV_64FC(3), CV_64FC4 = CV_64FC(4);
|
||||||
|
|
||||||
|
// type depth constants
|
||||||
|
public static final int CV_8U = 0,
|
||||||
|
CV_8S = 1,
|
||||||
|
CV_16U = 2,
|
||||||
|
CV_16S = 3,
|
||||||
|
CV_32S = 4,
|
||||||
|
CV_32F = 5,
|
||||||
|
CV_64F = 6,
|
||||||
|
CV_USRTYPE1=7;
|
||||||
|
|
||||||
|
private static final int CV_CN_MAX = 512, CV_CN_SHIFT = 3, CV_DEPTH_MAX = (1 << CV_CN_SHIFT);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
protected CvType(int depth, int channels) {
|
||||||
|
if(channels<=0 || channels>=CV_CN_MAX) {
|
||||||
|
throw new java.lang.UnsupportedOperationException(
|
||||||
|
"Channels count should be 1.." + (CV_CN_MAX-1) );
|
||||||
|
}
|
||||||
|
if(depth<0 || depth>=CV_DEPTH_MAX) {
|
||||||
|
throw new java.lang.UnsupportedOperationException(
|
||||||
|
"Data type depth should be 0.." + (CV_DEPTH_MAX-1) );
|
||||||
|
}
|
||||||
|
value = (depth & (CV_DEPTH_MAX-1)) + ((channels-1) << CV_CN_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CvType(int val) { value = val; }
|
||||||
|
|
||||||
|
public static final CvType CV_8UC(int ch) { return new CvType(CV_8U, ch); }
|
||||||
|
|
||||||
|
public static final CvType CV_8SC(int ch) { return new CvType(CV_8S, ch); }
|
||||||
|
|
||||||
|
public static final CvType CV_16UC(int ch) { return new CvType(CV_16U, ch); }
|
||||||
|
|
||||||
|
public static final CvType CV_16SC(int ch) { return new CvType(CV_16S, ch); }
|
||||||
|
|
||||||
|
public static final CvType CV_32SC(int ch) { return new CvType(CV_32S, ch); }
|
||||||
|
|
||||||
|
public static final CvType CV_32FC(int ch) { return new CvType(CV_32F, ch); }
|
||||||
|
|
||||||
|
public static final CvType CV_64FC(int ch) { return new CvType(CV_64F, ch); }
|
||||||
|
|
||||||
|
public final int toInt() { return value; }
|
||||||
|
|
||||||
|
public final int channels() { return (value >> CV_CN_SHIFT) + 1; }
|
||||||
|
|
||||||
|
public final int depth() { return value & (CV_DEPTH_MAX-1); }
|
||||||
|
|
||||||
|
public final boolean isInteger() { return depth() < CV_32F; }
|
||||||
|
|
||||||
|
public final int CV_ELEM_SIZE() {
|
||||||
|
switch (depth()) {
|
||||||
|
case CV_8U:
|
||||||
|
case CV_8S:
|
||||||
|
return channels();
|
||||||
|
case CV_16U:
|
||||||
|
case CV_16S:
|
||||||
|
return 2 * channels();
|
||||||
|
case CV_32S:
|
||||||
|
case CV_32F:
|
||||||
|
return 4 * channels();
|
||||||
|
case CV_64F:
|
||||||
|
return 8 * channels();
|
||||||
|
default:
|
||||||
|
throw new java.lang.UnsupportedOperationException(
|
||||||
|
"Unsupported CvType value: " + value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String toString() {
|
||||||
|
String s;
|
||||||
|
switch (depth()) {
|
||||||
|
case CV_8U:
|
||||||
|
s = "CV_8U";
|
||||||
|
break;
|
||||||
|
case CV_8S:
|
||||||
|
s = "CV_8S";
|
||||||
|
break;
|
||||||
|
case CV_16U:
|
||||||
|
s = "CV_16U";
|
||||||
|
break;
|
||||||
|
case CV_16S:
|
||||||
|
s = "CV_16S";
|
||||||
|
break;
|
||||||
|
case CV_32S:
|
||||||
|
s = "CV_32S";
|
||||||
|
break;
|
||||||
|
case CV_32F:
|
||||||
|
s = "CV_32F";
|
||||||
|
break;
|
||||||
|
case CV_64F:
|
||||||
|
s = "CV_64F";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s = "CV_USRTYPE1";
|
||||||
|
}
|
||||||
|
|
||||||
|
int ch = channels();
|
||||||
|
if(ch<=4) return s + "C" + ch;
|
||||||
|
else return s + "C(" + ch + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
// hashCode() has to be overridden if equals() is
|
||||||
|
@Override
|
||||||
|
public final int hashCode() { return value; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if ( !(obj instanceof CvType) ) return false;
|
||||||
|
CvType other = (CvType) obj;
|
||||||
|
return value == other.value;
|
||||||
|
}
|
||||||
|
}
|
@ -1,135 +1,7 @@
|
|||||||
package org.opencv;
|
package org.opencv;
|
||||||
|
|
||||||
//import android.util.Log;
|
|
||||||
|
|
||||||
public class Mat {
|
public class Mat {
|
||||||
|
|
||||||
public static class CvType {
|
|
||||||
|
|
||||||
// predefined type constants
|
|
||||||
public static final CvType
|
|
||||||
CV_8UC1 = CV_8UC(1), CV_8UC2 = CV_8UC(2), CV_8UC3 = CV_8UC(3), CV_8UC4 = CV_8UC(4),
|
|
||||||
CV_8SC1 = CV_8SC(1), CV_8SC2 = CV_8SC(2), CV_8SC3 = CV_8SC(3), CV_8SC4 = CV_8SC(4),
|
|
||||||
CV_16UC1 = CV_16UC(1), CV_16UC2 = CV_16UC(2), CV_16UC3 = CV_16UC(3), CV_16UC4 = CV_16UC(4),
|
|
||||||
CV_16SC1 = CV_16SC(1), CV_16SC2 = CV_16SC(2), CV_16SC3 = CV_16SC(3), CV_16SC4 = CV_16SC(4),
|
|
||||||
CV_32SC1 = CV_32SC(1), CV_32SC2 = CV_32SC(2), CV_32SC3 = CV_32SC(3), CV_32SC4 = CV_32SC(4),
|
|
||||||
CV_32FC1 = CV_32FC(1), CV_32FC2 = CV_32FC(2), CV_32FC3 = CV_32FC(3), CV_32FC4 = CV_32FC(4),
|
|
||||||
CV_64FC1 = CV_64FC(1), CV_64FC2 = CV_64FC(2), CV_64FC3 = CV_64FC(3), CV_64FC4 = CV_64FC(4);
|
|
||||||
|
|
||||||
// type depth constants
|
|
||||||
public static final int CV_8U = 0,
|
|
||||||
CV_8S = 1,
|
|
||||||
CV_16U = 2,
|
|
||||||
CV_16S = 3,
|
|
||||||
CV_32S = 4,
|
|
||||||
CV_32F = 5,
|
|
||||||
CV_64F = 6,
|
|
||||||
CV_USRTYPE1=7;
|
|
||||||
|
|
||||||
private static final int CV_CN_MAX = 512, CV_CN_SHIFT = 3, CV_DEPTH_MAX = (1 << CV_CN_SHIFT);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
protected CvType(int depth, int channels) {
|
|
||||||
if(channels<=0 || channels>=CV_CN_MAX) {
|
|
||||||
throw new java.lang.UnsupportedOperationException(
|
|
||||||
"Channels count should be 1.." + (CV_CN_MAX-1) );
|
|
||||||
}
|
|
||||||
if(depth<0 || depth>=CV_DEPTH_MAX) {
|
|
||||||
throw new java.lang.UnsupportedOperationException(
|
|
||||||
"Data type depth should be 0.." + (CV_DEPTH_MAX-1) );
|
|
||||||
}
|
|
||||||
value = (depth & (CV_DEPTH_MAX-1)) + ((channels-1) << CV_CN_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected CvType(int val) { value = val; }
|
|
||||||
|
|
||||||
public static final CvType CV_8UC(int ch) { return new CvType(CV_8U, ch); }
|
|
||||||
|
|
||||||
public static final CvType CV_8SC(int ch) { return new CvType(CV_8S, ch); }
|
|
||||||
|
|
||||||
public static final CvType CV_16UC(int ch) { return new CvType(CV_16U, ch); }
|
|
||||||
|
|
||||||
public static final CvType CV_16SC(int ch) { return new CvType(CV_16S, ch); }
|
|
||||||
|
|
||||||
public static final CvType CV_32SC(int ch) { return new CvType(CV_32S, ch); }
|
|
||||||
|
|
||||||
public static final CvType CV_32FC(int ch) { return new CvType(CV_32F, ch); }
|
|
||||||
|
|
||||||
public static final CvType CV_64FC(int ch) { return new CvType(CV_64F, ch); }
|
|
||||||
|
|
||||||
public final int toInt() { return value; }
|
|
||||||
|
|
||||||
public final int channels() { return (value >> CV_CN_SHIFT) + 1; }
|
|
||||||
|
|
||||||
public final int depth() { return value & (CV_DEPTH_MAX-1); }
|
|
||||||
|
|
||||||
public final boolean isInteger() { return depth() < CV_32F; }
|
|
||||||
|
|
||||||
public final int CV_ELEM_SIZE() {
|
|
||||||
int depth = value & (CV_DEPTH_MAX-1);
|
|
||||||
switch (depth) {
|
|
||||||
case CV_8U:
|
|
||||||
case CV_8S:
|
|
||||||
return channels();
|
|
||||||
case CV_16U:
|
|
||||||
case CV_16S:
|
|
||||||
return 2 * channels();
|
|
||||||
case CV_32S:
|
|
||||||
case CV_32F:
|
|
||||||
return 4 * channels();
|
|
||||||
case CV_64F:
|
|
||||||
return 8 * channels();
|
|
||||||
default:
|
|
||||||
throw new java.lang.UnsupportedOperationException(
|
|
||||||
"Unsupported CvType value: " + value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final String toString() {
|
|
||||||
String s;
|
|
||||||
switch (depth()) {
|
|
||||||
case CV_8U:
|
|
||||||
s = "CV_8U";
|
|
||||||
break;
|
|
||||||
case CV_8S:
|
|
||||||
s = "CV_8S";
|
|
||||||
break;
|
|
||||||
case CV_16U:
|
|
||||||
s = "CV_16U";
|
|
||||||
break;
|
|
||||||
case CV_16S:
|
|
||||||
s = "CV_16S";
|
|
||||||
break;
|
|
||||||
case CV_32S:
|
|
||||||
s = "CV_32S";
|
|
||||||
break;
|
|
||||||
case CV_32F:
|
|
||||||
s = "CV_32F";
|
|
||||||
break;
|
|
||||||
case CV_64F:
|
|
||||||
s = "CV_64F";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
s = "CV_USRTYPE1";
|
|
||||||
}
|
|
||||||
|
|
||||||
return s + "C(" + channels() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
// hashCode() has to be overridden if equals() is
|
|
||||||
@Override
|
|
||||||
public final int hashCode() { return value; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean equals(Object obj) {
|
|
||||||
if (this == obj) return true;
|
|
||||||
if ( !(obj instanceof CvType) ) return false;
|
|
||||||
CvType other = (CvType) obj;
|
|
||||||
return value == other.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Mat(long nativeMat) {
|
protected Mat(long nativeMat) {
|
||||||
/*if(nativeMat == 0)
|
/*if(nativeMat == 0)
|
||||||
@ -145,6 +17,10 @@ public class Mat {
|
|||||||
this( nCreateMat(rows, cols, type.toInt()) );
|
this( nCreateMat(rows, cols, type.toInt()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Mat(int rows, int cols, int depth) {
|
||||||
|
this( rows, cols, new CvType(depth, 1) );
|
||||||
|
}
|
||||||
|
|
||||||
public Mat(int rows, int cols, CvType type, double v0, double v1, double v2, double v3) {
|
public Mat(int rows, int cols, CvType type, double v0, double v1, double v2, double v3) {
|
||||||
this( nCreateMat(rows, cols, type.toInt(), v0, v1, v2, v3) );
|
this( nCreateMat(rows, cols, type.toInt(), v0, v1, v2, v3) );
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import android.util.Log;
|
|||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
|
||||||
|
import org.opencv.CvType;
|
||||||
import org.opencv.Mat;
|
import org.opencv.Mat;
|
||||||
import org.opencv.Point;
|
import org.opencv.Point;
|
||||||
import org.opencv.Scalar;
|
import org.opencv.Scalar;
|
||||||
@ -64,16 +65,16 @@ class Sample1View extends SurfaceView implements SurfaceHolder.Callback, Runnabl
|
|||||||
|
|
||||||
// initialize all required Mats before usage to minimize number of auxiliary jni calls
|
// initialize all required Mats before usage to minimize number of auxiliary jni calls
|
||||||
if(mYuv != null) mYuv.dispose();
|
if(mYuv != null) mYuv.dispose();
|
||||||
mYuv = new Mat(mFrameHeight+mFrameHeight/2, mFrameWidth, Mat.CvType.CV_8UC1);
|
mYuv = new Mat(mFrameHeight+mFrameHeight/2, mFrameWidth, CvType.CV_8UC1);
|
||||||
|
|
||||||
if(mRgba != null) mRgba.dispose();
|
if(mRgba != null) mRgba.dispose();
|
||||||
mRgba = new Mat(mFrameHeight, mFrameWidth, Mat.CvType.CV_8UC4);
|
mRgba = new Mat(mFrameHeight, mFrameWidth, CvType.CV_8UC4);
|
||||||
|
|
||||||
if(mGraySubmat != null) mGraySubmat.dispose();
|
if(mGraySubmat != null) mGraySubmat.dispose();
|
||||||
mGraySubmat = mYuv.submat(0, mFrameHeight, 0, mFrameWidth);
|
mGraySubmat = mYuv.submat(0, mFrameHeight, 0, mFrameWidth);
|
||||||
|
|
||||||
if(mIntermediateMat != null) mIntermediateMat.dispose();
|
if(mIntermediateMat != null) mIntermediateMat.dispose();
|
||||||
mIntermediateMat = new Mat(mFrameHeight, mFrameWidth, Mat.CvType.CV_8UC1);
|
mIntermediateMat = new Mat(mFrameHeight, mFrameWidth, CvType.CV_8UC1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ class Sample1View extends SurfaceView implements SurfaceHolder.Callback, Runnabl
|
|||||||
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
||||||
break;
|
break;
|
||||||
case Sample1Java.VIEW_MODE_SOBEL:
|
case Sample1Java.VIEW_MODE_SOBEL:
|
||||||
imgproc.Sobel(mGraySubmat, mIntermediateMat, core.CV_8U, 1, 1);
|
imgproc.Sobel(mGraySubmat, mIntermediateMat, CvType.CV_8U, 1, 1);
|
||||||
core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 8);
|
core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 8);
|
||||||
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
||||||
break;
|
break;
|
||||||
|
@ -9,6 +9,7 @@ import android.util.Log;
|
|||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
|
||||||
|
import org.opencv.CvType;
|
||||||
import org.opencv.Mat;
|
import org.opencv.Mat;
|
||||||
import org.opencv.Size;
|
import org.opencv.Size;
|
||||||
import org.opencv.core;
|
import org.opencv.core;
|
||||||
@ -62,16 +63,16 @@ class Sample4View extends SurfaceView implements SurfaceHolder.Callback, Runnabl
|
|||||||
|
|
||||||
// initialize all required Mats before usage to minimize number of auxiliary jni calls
|
// initialize all required Mats before usage to minimize number of auxiliary jni calls
|
||||||
if(mYuv != null) mYuv.dispose();
|
if(mYuv != null) mYuv.dispose();
|
||||||
mYuv = new Mat(mFrameHeight+mFrameHeight/2, mFrameWidth, Mat.CvType.CV_8UC1);
|
mYuv = new Mat(mFrameHeight+mFrameHeight/2, mFrameWidth, CvType.CV_8UC1);
|
||||||
|
|
||||||
if(mRgba != null) mRgba.dispose();
|
if(mRgba != null) mRgba.dispose();
|
||||||
mRgba = new Mat(mFrameHeight, mFrameWidth, Mat.CvType.CV_8UC4);
|
mRgba = new Mat(mFrameHeight, mFrameWidth, CvType.CV_8UC4);
|
||||||
|
|
||||||
if(mGraySubmat != null) mGraySubmat.dispose();
|
if(mGraySubmat != null) mGraySubmat.dispose();
|
||||||
mGraySubmat = mYuv.submat(0, mFrameHeight, 0, mFrameWidth);
|
mGraySubmat = mYuv.submat(0, mFrameHeight, 0, mFrameWidth);
|
||||||
|
|
||||||
if(mIntermediateMat != null) mIntermediateMat.dispose();
|
if(mIntermediateMat != null) mIntermediateMat.dispose();
|
||||||
mIntermediateMat = new Mat(mFrameHeight, mFrameWidth, Mat.CvType.CV_8UC1);
|
mIntermediateMat = new Mat(mFrameHeight, mFrameWidth, CvType.CV_8UC1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ class Sample4View extends SurfaceView implements SurfaceHolder.Callback, Runnabl
|
|||||||
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
||||||
break;
|
break;
|
||||||
case Sample4Mixed.VIEW_MODE_SOBEL:
|
case Sample4Mixed.VIEW_MODE_SOBEL:
|
||||||
imgproc.Sobel(mGraySubmat, mIntermediateMat, core.CV_8U, 1, 1);
|
imgproc.Sobel(mGraySubmat, mIntermediateMat, CvType.CV_8U, 1, 1);
|
||||||
core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 8);
|
core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 8);
|
||||||
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user