acidcamGL/source/plugin/square_resize/square.cpp
Source: acidcamGL/source/plugin/square_resize/square.cpp
#include"ac.h"
#include<cstdlib>
#include<ctime>
static constexpr int MAX = 8;
unsigned char wrapToChar(double d) {
if(d < 255) {
unsigned long x = static_cast<unsigned long>(d);
return static_cast<unsigned char>(x);
}
unsigned long x = static_cast<unsigned long>(d);
return static_cast<unsigned char>(x%255);
}
void stutter_filter(cv::Mat &frame) {
static cv::Mat stored;
static cv::Size stored_size;
if(stored_size != frame.size()) {
srand(static_cast<int>(time(0)));
stored = frame.clone();
stored_size = frame.size();
} else {
if(stored.empty())
stored = frame.clone();
static bool on = true;
if(on == true) {
if((rand()%3)==0) {
stored = frame.clone();
on = !on;
}
frame = stored.clone();
} else {
if((rand()%4) == 0)
on = !on;
}
}
}
class Square {
public:
int size_x, size_y;
int offset;
Square() : size_x{0},size_y{0}, offset{0} {}
Square(int sx, int sy, int o) : size_x{sx},size_y{sy}, offset{o} {}
};
class Squares {
cv::Size size_val;
public:
Squares() : square{nullptr} {
}
~Squares() {
release();
}
void init(cv::Size s) {
size_val = s;
if(square != nullptr)
release();
square = new Square*[s.width];
for(int i = 0; i < s.width; ++i) {
square[i] = new Square[s.height];
for(int z = 0; z < s.height; ++z) {
square[i][z] = Square(4+rand()%28, 4+rand()%28, rand()%(MAX-1));
}
}
}
Square &operator()(int x, int y) {
return square[x][y];
}
void release() {
if(square != nullptr) {
for(int i = 0; i < size_val.width; ++i)
delete[] square[i];
delete [] square;
square = nullptr;
}
}
protected:
Square **square;
};
extern "C" void filter(cv::Mat &frame) {
static ac::MatrixCollection<MAX> collection;
static Squares squarez;
static cv::Size size_val;
if(collection.empty()) {
srand(static_cast<unsigned int>(time(0)));
collection.shiftFrames(frame);
}
if(size_val != frame.size()) {
squarez.init(frame.size());
size_val = frame.size();
}
stutter_filter(frame);
collection.shiftFrames(frame);
int square_size_x = squarez(0, 0).size_x;
int square_size_y = squarez(0, 0).size_y;
static int offset = squarez(0, 0).offset;
for(int z = 0; z < frame.rows-square_size_y; z += square_size_y) {
for(int i = 0; i < frame.cols-square_size_x; i += square_size_x) {
for(int x = 0; x+i < frame.cols && x < square_size_x; ++x) {
for(int y = 0; z+y < frame.rows && y < square_size_y; ++y) {
cv::Vec3b &pixel = ac::pixelAt(frame,z+y, i+x);
cv::Vec3b pix = collection.frames[offset].at<cv::Vec3b>(z+y, i+x);
for(int j = 0; j < 3; ++j)
pixel[j] = wrapToChar((0.5 * pixel[j]) + (0.5 * pix[j]));
}
square_size_x = squarez(i, z).size_x;
square_size_y = squarez(i, z).size_y;
offset = squarez(i, z).offset;
}
}
}
}