1 // Tencent is pleased to support the open source community by making ncnn available.
2 //
3 // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
4 //
5 // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // https://opensource.org/licenses/BSD-3-Clause
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef IMREADWRITE_H
16 #define IMREADWRITE_H
17 
18 #include <limits.h>
19 #include <string.h>
20 #include "allocator.h"
21 #include "mat.h"
22 
23 #ifndef NCNN_XADD
24 using ncnn::NCNN_XADD;
25 #endif
26 
27 typedef unsigned char uchar;
28 
29 enum
30 {
31     CV_LOAD_IMAGE_UNCHANGED = -1,
32     CV_LOAD_IMAGE_GRAYSCALE = 0,
33     CV_LOAD_IMAGE_COLOR = 1,
34 };
35 
36 enum
37 {
38     CV_IMWRITE_JPEG_QUALITY = 1
39 };
40 
41 // minimal opencv style data structure implementation
42 namespace cv {
43 
44 #define CV_8UC1  1
45 #define CV_8UC3  3
46 #define CV_8UC4  4
47 #define CV_32FC1 4
48 
49 struct Mat
50 {
MatMat51     Mat()
52         : data(0), refcount(0), rows(0), cols(0), c(0)
53     {
54     }
55 
MatMat56     Mat(int _rows, int _cols, int flags)
57         : data(0), refcount(0)
58     {
59         create(_rows, _cols, flags);
60     }
61 
62     // copy
MatMat63     Mat(const Mat& m)
64         : data(m.data), refcount(m.refcount)
65     {
66         if (refcount)
67             NCNN_XADD(refcount, 1);
68 
69         rows = m.rows;
70         cols = m.cols;
71         c = m.c;
72     }
73 
MatMat74     Mat(int _rows, int _cols, int flags, void* _data)
75         : data((unsigned char*)_data), refcount(0)
76     {
77         rows = _rows;
78         cols = _cols;
79         c = flags;
80     }
81 
~MatMat82     ~Mat()
83     {
84         release();
85     }
86 
87     // assign
88     Mat& operator=(const Mat& m)
89     {
90         if (this == &m)
91             return *this;
92 
93         if (m.refcount)
94             NCNN_XADD(m.refcount, 1);
95 
96         release();
97 
98         data = m.data;
99         refcount = m.refcount;
100 
101         rows = m.rows;
102         cols = m.cols;
103         c = m.c;
104 
105         return *this;
106     }
107 
createMat108     void create(int _rows, int _cols, int flags)
109     {
110         release();
111 
112         rows = _rows;
113         cols = _cols;
114         c = flags;
115 
116         if (total() > 0)
117         {
118             // refcount address must be aligned, so we expand totalsize here
119             size_t totalsize = (total() + 3) >> 2 << 2;
120             data = (uchar*)ncnn::fastMalloc(totalsize + (int)sizeof(*refcount));
121             refcount = (int*)(((uchar*)data) + totalsize);
122             *refcount = 1;
123         }
124     }
125 
releaseMat126     void release()
127     {
128         if (refcount && NCNN_XADD(refcount, -1) == 1)
129             ncnn::fastFree(data);
130 
131         data = 0;
132 
133         rows = 0;
134         cols = 0;
135         c = 0;
136 
137         refcount = 0;
138     }
139 
cloneMat140     Mat clone() const
141     {
142         if (empty())
143             return Mat();
144 
145         Mat m(rows, cols, c);
146 
147         if (total() > 0)
148         {
149             memcpy(m.data, data, total());
150         }
151 
152         return m;
153     }
154 
emptyMat155     bool empty() const
156     {
157         return data == 0 || total() == 0;
158     }
159 
typeMat160     int type() const
161     {
162         return c;
163     }
164 
totalMat165     size_t total() const
166     {
167         return cols * rows * c;
168     }
169 
170     uchar* data;
171 
172     // pointer to the reference counter;
173     // when points to user-allocated data, the pointer is NULL
174     int* refcount;
175 
176     int rows;
177     int cols;
178 
179     int c;
180 };
181 
182 enum ImreadModes
183 {
184     IMREAD_UNCHANGED = -1,
185     IMREAD_GRAYSCALE = 0,
186     IMREAD_COLOR = 1
187 };
188 
189 Mat imread(const std::string& path, int flags = IMREAD_COLOR);
190 
191 enum ImwriteFlags
192 {
193     IMWRITE_JPEG_QUALITY = 1
194 };
195 
196 bool imwrite(const std::string& path, const Mat& m, const std::vector<int>& params = std::vector<int>());
197 
198 } // namespace cv
199 
200 #endif // IMREADWRITE_H
201