Реализовать класс Image для работы с изображениями c применением техники
reference counting.
Класс представляет собой многоканальный двумерный массив из unsigned char
для хранения пикселей изображения.
Цифровые изображения состоят из пикселей, а пиксели состоят из комбинаций основных цветов. Набор основных цветов называются каналами. Например, RGB изображения состоят из 3-х каналов: R (red), G (green), B (blue), а изображения в градациях серого являются одноканальными.
Реализовать основной класс Image и вспомогательный класс Range.
public и protected методы классов фиксированы,
кроме спецификаторов.
Т.е. нельзя менять названия методов, а также типы и количество аргументов.
НО в этих методах отсутствуют спецификаторы const и static,
которые были удалены намеренно. Их необходимо вернуть на место.
private поля и private методы можно добавлять в класс Image.
Класс Range cамодостаточен и не нуждается в дополнительных полях и методах.
//Range.hpp
class Range
{
int _start, _end;
public:
Range();
Range(int _start, int _end);
int size();
bool empty();
int start();
int end();
Range all();
};
Класс Range используется для указания полуоткрытого
диапазона значений строк или столбцов. Т.е [a,b) = {a <= x < b}.
Range() -- конструктор по умолчанию. Инициализация нулями.
Range(int _start, int _end) -- конструктор
с заданием полуоткрытого диапазона [_start, _end).
Если _start < 0 || _start >= _end, то поля инициализируются нулями.
int size() -- возвращает
размер (длину) диапазона.
bool empty() -- возвращает true или false
в зависимости от того, является диапазон
пустым или нет.
int start() -- возращает значение _start.
int end() -- возращает значение _end.
Range all() -- возвращает специальную переменную Range, которая означает
"весь диапазон". Данный метод не зависит от значений полей start и end.
int _start - приватное поле класса, содержащее значение инклюзивной левой границы диапазона.
int _end - приватное поле класса, содержащее значение исключительной правой границы диапазона.
//Image.hpp
#include "Range.h"
class Image {
public:
Image();
Image(int rows, int cols, int channels);
Image(int rows, int cols, int channels, unsigned char* data);
Image(const Image& image);
Image(const Image& image, const Range& rowRange, const Range& colRange);
virtual ~Image();
Image& operator=(const Image& image);
Image operator()(const Range& rowRange, const Range& colRange);
Image clone();
void copyTo(Image& image);
void create(int rows, int cols, int channels);
bool empty();
void release();
Image col(int x);
Image colRange(const Range& range);
Image row(int y);
Image rowRange(const Range& range);
const unsigned char* data() const;
unsigned char* data();
int rows();
int cols();
int total();
int channels();
unsigned char& at(int index);
const unsigned char& at(int index) const;
Image zeros(int rows, int cols, int channels);
Image values(int rows, int cols, int channels, unsigned char value);
size_t countRef();
};
Image() -- конструктор по умолчанию.Image(int rows, int cols, int channels) -- конструктор с заданием
количества строк rows, столбцов cols и каналов channels.Image(int rows, int cols, int channels, unsigned char* data) --
конструктор, который отличается от вышеуказанного дополнительным параметром,
указателем на пользовательские данные data.
Данный конструктор не выделяет новую память и не копирует данные,
а просто использует переданный указатель на данные (пиксели).
Эта операция очень эффективна и может использоваться для обработки внешних данных.
Внешние данные не освобождаются в деструкторе, поскольку за них ответственен пользователь.Image(const Image& image) -- конструктор копий.
Данный конструктор не выделяет новую память, а применяет технику reference counting.
Сложность создания копии объекта O(1).Image(const Image& image, const Range& rowRange, const Range& colRange) --
конструктор копий, который отличается от вышеуказанного дополнительными параметрами
rowRange и colRange, которые задают прямоугольную область.
Дополнительные параметры позволяют создать копию не всего изображения,
а только части изображения. Данный конструктор также не выделяет новую память,
а применяет технику reference counting. Сложность создания копии объекта O(1).
Если range выходит за область изображения, то он обрезается до границы изображения.
~Image() -- деструктор.
operator=(const Image& image) -- оператор присваивания. В некотором роде
похож на конструктор. Т.е. не выделяет новую память, а применяет технику reference counting.
Сложность данной операции O(1).
operator()(const Range& rowRange, const Range& colRange) --
выделяет прямоугольное под-изображение. Данный оператор возвращает то изображение, которое
находится в заданной (с помощью параметров rowRange и colRange) области.
Сложность операции O(1), копирования и выделения новой памяти не требуется. Используется
техника reference counting. Если range выходит за область изображения, то он обрезается до границы изображения.
clone() -- создает полную копию изображения. Выделяет новую память и производит копирование пикселей.
Сложность операции O(n), где n - количество пикселей.
copyTo(Image& image) -- метод производит полное копирование изображения в объект
image. Сложность операции O(n).
create(int rows, int cols, int channels) -- метод задает новые размеры
текущего изображения.
empty() -- возвращает true или false
в зависимости от того, является изображение пустым или нет.
release() -- декрементирует счетчик ссылок и в случае необходимости освобождает ресурсы (память).
col(int x) -- возвращает новое изображение, которое содержит один столбец по индексу x.
Сложность операции O(1). Память не выделяется, используется reference counting.
Если x превышает ширину изображения, то метод должен вернуть
пустое изображение.
colRange(const Range& range) -- возвращает новое изображение, которое содержит
диапазон столбцов range.
Сложность операции O(1). Память не выделяется, используется reference counting.
Если range выходит за область изображения, то он обрезается до границы изображения.
row(int y) -- аналог метода col(int x) для строк.
rowRange(const Range& range) -- аналог метода
colRange(const Range& range) для строк.
data() const -- возвращет указатель на константные данные (пиксели).
data() -- возвращет указатель на данные (пиксели).
rows() -- возвращает общее количество строк в изображении.
cols() -- возвращает общее количество столбцов в изображении (без учета каналов).
total() -- возвращает общее количество пикселей в изображении.
channels() -- возвращает количество каналов в пикселе.
at(int index) -- возвращает ссылку на компоненту пикселя изображения
(не на весь пиксель, а на часть) по индексу.
at(int index) -- возвращает константную ссылку на компоненту пикселя изображения
(не на весь пиксель, а на часть) по индексу.
zeros(int rows, int cols, int channels) -- создает новое изображение, которое
инициализируется нулями.
values(int rows, int cols, int channels) -- создает новое изображение, которое
инициализируется значением value.
countRef() -- возвращает текущее количество ссылок на изображение. Т.е.
количество объектов, которые ссылаются на данное изображение. Этот метод нужен для
unit test'ов.
public методам, классов Range и Image,
необходимо добавить спецификаторы static и const.
Но только в те места, где это необходимо.public и protected методы классов фиксированы, кроме спецификаторов.
Т.е. нельзя менять названия методов, а также типы и количество аргументов.Image.hpp, Image.cpp, Range.hpp, Range.cpp.