1 /*
2 * The MIT License (MIT)
3 * This file is part of waifu2x-converter-cpp
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include "cvwrap.hpp"
27
~W2Mat()28 W2Mat::~W2Mat()
29 {
30 if (data_owner)
31 {
32 data_owner=false;
33 free(data);
34 data = nullptr;
35 }
36 }
37
38
W2Mat()39 W2Mat::W2Mat()
40 : data_owner(false),
41 data(nullptr),
42 data_byte_width(0),
43 data_height(0),
44 view_top(0),
45 view_left(0),
46 view_width(0),
47 view_height(0)
48 {
49 }
50
W2Mat(int width,int height,int type)51 W2Mat::W2Mat(int width, int height, int type)
52 : data_owner(true),
53 data_byte_width(width*CV_ELEM_SIZE(type)),
54 data_height(height),
55 view_top(0),
56 view_left(0),
57 view_width(width),
58 view_height(height),
59 type(type)
60 {
61 this->data = (char*)calloc(height, data_byte_width);
62 }
63
W2Mat(int width,int height,int type,void * data,int data_step)64 W2Mat::W2Mat(int width, int height, int type, void *data, int data_step)
65 : data_owner(true),
66 data_byte_width(data_step),
67 data_height(height),
68 view_top(0),
69 view_left(0),
70 view_width(width),
71 view_height(height),
72 type(type)
73 {
74 this->data = (char*)calloc(height, data_byte_width);
75 memcpy(this->data, data, height * data_byte_width);
76 }
77
78
operator =(W2Mat && rhs)79 W2Mat & W2Mat::operator=(W2Mat &&rhs)
80 {
81 this->data_owner = rhs.data_owner;
82 this->data = rhs.data;
83 this->data_byte_width = rhs.data_byte_width;
84 this->data_height = rhs.data_height;
85 this->view_top = rhs.view_top;
86 this->view_left = rhs.view_left;
87 this->view_width = rhs.view_width;
88 this->view_height= rhs.view_height;
89 this->type = rhs.type;
90
91 rhs.data_owner = false;
92 rhs.data = NULL;
93
94 return *this;
95 }
96
W2Mat(const W2Mat & rhs,int view_left_offset,int view_top_offset,int view_width,int view_height)97 W2Mat::W2Mat(const W2Mat & rhs, int view_left_offset, int view_top_offset, int view_width, int view_height)
98 {
99 this->data_owner = false;
100 this->data = rhs.data;
101 this->data_byte_width = rhs.data_byte_width;
102 this->data_height = rhs.data_height;
103
104 this->view_left = rhs.view_left + view_left_offset;
105 this->view_top = rhs.view_top + view_top_offset;
106 this->view_width = view_width;
107 this->view_height = view_height;
108
109 this->type = rhs.type;
110 }
111
copyTo(W2Mat * target)112 void W2Mat::copyTo(W2Mat* target)
113 {
114 W2Mat ret(this->view_width, this->view_height, this->type);
115
116 int elem_size = CV_ELEM_SIZE(this->type);
117 int w = this->view_width;
118 int h = this->view_height;
119
120 for (int yi = 0; yi < h; yi++)
121 {
122 char *out = ret.ptr<char>(yi);
123 char *in = this->ptr<char>(yi);
124
125 memcpy(out, in, w * elem_size);
126 }
127 *target = std::move(ret);
128 }
129
130 #ifdef HAVE_OPENCV
W2Mat(cv::Mat & m)131 W2Mat::W2Mat(cv::Mat &m) : data_owner(true), view_top(0), view_left(0)
132 {
133 int w = m.size().width;
134 int h = m.size().height;
135
136 this->data_byte_width = w * CV_ELEM_SIZE(m.type());
137 this->data_height = h;
138 this->view_width = w;
139 this->view_height = h;
140 this->type = m.type();
141 this->data = (char*)calloc(h, this->data_byte_width);
142
143
144 for (int yi = 0; yi < h; yi++)
145 {
146 void *in = m.ptr(yi);
147 char *out = this->ptr<char>(yi);
148
149 memcpy(out, in, this->data_byte_width);
150 }
151 }
152
to_cvmat(cv::Mat * target)153 void W2Mat::to_cvmat(cv::Mat *target)
154 {
155 int w = this->view_width;
156 int h = this->view_height;
157
158 cv::Mat ret = cv::Mat::zeros(cv::Size(w, h), this->type);
159 int elem_size = CV_ELEM_SIZE(this->type);
160
161 for (int yi = 0; yi < h; yi++)
162 {
163 void *out = ret.ptr(yi);
164 void *in = this->ptr<char>(yi);
165
166 memcpy(out, in, w * elem_size);
167 }
168 *target = ret.clone();
169 }
170
171 // DO NOT USE IN NORMAL SITUAYION. Return wm is not own their data.
extract_view_from_cvmat(W2Mat & wm,cv::Mat & m)172 void extract_view_from_cvmat(W2Mat &wm, cv::Mat &m)
173 {
174 wm.data_owner = false;
175 wm.data = (char*) m.data;
176 wm.data_byte_width = (int) m.step;
177 wm.data_height = m.size().height;
178
179 wm.view_top = 0;
180 wm.view_left = 0;
181 wm.view_width = m.size().width;
182 wm.view_height = m.size().height;
183 wm.type = m.type();
184
185 }
186
extract_view_to_cvmat(cv::Mat & m,W2Mat & wm)187 void extract_view_to_cvmat(cv::Mat &m, W2Mat &wm)
188 {
189 int w = wm.view_width;
190 int h = wm.view_height;
191
192 char *data = (char*) wm.data;
193
194 int byte_offset = 0;
195 byte_offset += wm.view_top * wm.data_byte_width;
196 byte_offset += wm.view_left * CV_ELEM_SIZE(wm.type);
197
198 cv::Mat ret(cv::Size(w,h), wm.type, data + byte_offset, wm.data_byte_width);
199
200 ret.copyTo(m);
201 }
202
203 // DO NOT USE IN NORMAL SITUAYION. Return wm is not own their data.
extract_view_from_cvmat_offset(W2Mat & wm,cv::Mat & m,int view_left_offset,int view_top_offset,int view_width,int view_height)204 void extract_view_from_cvmat_offset
205 (
206 W2Mat &wm,
207 cv::Mat &m,
208 int view_left_offset,
209 int view_top_offset,
210 int view_width,
211 int view_height
212 )
213 {
214 extract_view_from_cvmat(wm, m);
215
216 wm.view_top = view_top_offset;
217 wm.view_left = view_left_offset;
218 wm.view_width = view_width;
219 wm.view_height = view_height;
220 }
221
extract_viewlist_from_cvmat(std::vector<W2Mat> & list,std::vector<cv::Mat> & cvmat)222 void extract_viewlist_from_cvmat(std::vector<W2Mat> &list, std::vector<cv::Mat> &cvmat)
223 {
224 std::for_each(cvmat.begin(), cvmat.end(),
225 [&list](cv::Mat &cv) {
226 W2Mat w2;
227 extract_view_from_cvmat(w2, cv);
228 list.push_back(std::move(w2));
229 });
230 }
231
extract_viewlist_to_cvmat(std::vector<cv::Mat> & cvmat,std::vector<W2Mat> & list)232 void extract_viewlist_to_cvmat(std::vector<cv::Mat> &cvmat, std::vector<W2Mat> &list)
233 {
234 std::for_each(list.begin(), list.end(),
235 [&cvmat](W2Mat &wm) {
236 cv::Mat cv;
237 extract_view_to_cvmat(cv, wm);
238 cvmat.push_back(cv.clone());
239 });
240 }
241
242 #endif
243