Streamtools: Rescaler to change the vertical/horizontal stacking
[jpcrr.git] / streamtools / rescalers / changestack.cpp
blob9f7ebc59be3e40027c254a4ab1d44a37266bdf0c
1 #include "rescalers/simple.hpp"
2 #include <stdint.h>
3 #include <cmath>
4 #include <stdexcept>
6 namespace
8 void do_changestack(uint8_t* target, uint32_t twidth, uint32_t theight,
9 const uint8_t* source, uint32_t swidth, uint32_t sheight)
11 uint32_t* __restrict__ src = (uint32_t*)source;
12 uint32_t* __restrict__ dest = (uint32_t*)target;
13 bool horizontal_to_vertical;
14 uint32_t ratio;
16 if(swidth < twidth) {
17 //Vertical to horizontal.
18 horizontal_to_vertical = false;
19 if(twidth % swidth || sheight % theight)
20 throw std::runtime_error("Bad size change for stacking change");
21 ratio = twidth / swidth;
22 if(theight * ratio != sheight)
23 throw std::runtime_error("Bad size change for stacking change");
24 } else {
25 //Horizontal to vertical.
26 horizontal_to_vertical = true;
27 if(swidth % twidth || theight % sheight)
28 throw std::runtime_error("Bad size change for stacking change");
29 ratio = swidth / twidth;
30 if(sheight * ratio != theight)
31 throw std::runtime_error("Bad size change for stacking change");
34 for(uint32_t y = 0; y < sheight; y++)
35 for(uint32_t x = 0; x < swidth; x++) {
36 uint32_t _x, _y;
37 if(horizontal_to_vertical) {
38 _x = x % twidth;
39 _y = y + x / twidth * sheight;
40 } else {
41 _x = x + y / theight * swidth;
42 _y = y % theight;
44 dest[_y * twidth + _x] = src[y * swidth + x];
48 simple_rescaler factory("changestacking", make_bound_method(do_changestack));