15 Image() : Height(0), Width(0), data() {}
18 Image(
size_t h,
size_t w,
const T &value = T())
19 : Height(h), Width(w), data(h * w, value)
28 virtual ~
Image() =
default;
31 void Resize(
size_t h,
size_t w,
const T &value = T()) {
38 data.resize(Height * Width, value);
43 void Fill(
const T &value) {
44 for (
auto &pixel : data)
57 friend std::istream &operator>>(std::istream &is,
Image<T> &m) {
58 std::ios_base::sync_with_stdio(
false);
59 is.exceptions(std::ios_base::failbit | std::ios_base::badbit);
61 is >> m.Height >> m.Width;
62 m.data.resize(m.Height * m.Width);
64 for (
auto &pixel : m.data) {
75 friend std::ostream &operator<<(std::ostream &os, const Image<T> &m) {
76 std::ios_base::sync_with_stdio(
false);
77 os.exceptions(std::ios_base::failbit | std::ios_base::badbit);
79 os << m.getHeight() <<
' ' << m.getWidth() <<
'\n';
80 for (
size_t i = 0; i < m.getHeight(); ++i) {
81 for (
size_t j = 0; j < m.getWidth(); ++j) {
90 inline size_t getHeight()
const {
return Height; }
91 inline size_t getWidth()
const {
return Width; }
92 inline size_t getSize()
const {
93 assert(data.size() == Height * Width &&
94 "Image size is different than Height * Width!");
99 inline bool isEmpty()
const {
return data.empty(); }
110 swap(first.Height, second.Height);
111 swap(first.Width, second.Width);
112 swap(first.data, second.data);
120 for (
size_t i = 0; i < data.size(); ++i)
121 result[i] = static_cast<U>(data[i]);
127 bool operator==(
const Image<T> &other)
const {
129 if (isEmpty() != other.isEmpty())
131 if (Height != other.getHeight() || Width != other.getWidth())
134 for (
size_t i = 0; i < data.size(); ++i)
135 if (data[i] != other[i])
141 bool operator!=(
const Image<T> &other)
const {
142 return !(*
this == other);
147 assert(Height == other.getHeight() &&
"Height mismatch!");
148 assert(Width == other.getWidth() &&
"Width mismatch!");
150 for (
size_t i = 0; i < data.size(); ++i)
158 assert(Height == other.getHeight() &&
"Height mismatch!");
159 assert(Width == other.getWidth() &&
"Width mismatch!");
161 for (
size_t i = 0; i < data.size(); ++i)
187 auto operator()(
size_t i,
size_t j) -> decltype(data[0]) {
188 assert(i < Height &&
"i index out of range!");
189 assert(j < Width &&
"i index out of range!");
191 return data[i * Width + j];
195 auto operator()(
size_t i,
size_t j)
const -> decltype(data[0]) {
196 assert(i < Height &&
"i index out of range!");
197 assert(j < Width &&
"i index out of range!");
199 return data[i * Width + j];
203 auto operator[](
size_t i) -> decltype(data.at(i)) {
return data.at(i); }
204 auto operator[](
size_t i)
const -> decltype(data.at(i)) {
return data.at(i); }
206 auto begin() -> decltype(data.begin()) {
return data.begin(); }
207 auto begin()
const -> decltype(data.begin()) {
return data.begin(); }
208 auto end() -> decltype(data.end()) {
return data.end(); }
209 auto end()
const -> decltype(data.end()) {
return data.end(); }