Skip to content

Instantly share code, notes, and snippets.

@orlp

orlp/.cpp Secret

Created October 29, 2015 04:12
Show Gist options
  • Save orlp/3506c002f3651d1b7b0a to your computer and use it in GitHub Desktop.
Save orlp/3506c002f3651d1b7b0a to your computer and use it in GitHub Desktop.
#include <vector>
#include <algorithm>
#include <cstdint>
void scale(std::vector<uint8_t>& data, uint8_t in_lo, uint8_t in_hi, uint8_t out_lo, uint8_t out_hi) {
int in_range = in_hi - in_lo;
int out_range = out_hi - out_lo;
// Should all fit in L1.
uint8_t lutnorm[256];
uint64_t lut0[256]; uint64_t lut1[256]; uint64_t lut2[256]; uint64_t lut3[256];
uint64_t lut4[256]; uint64_t lut5[256]; uint64_t lut6[256]; uint64_t lut7[256];
for (int i = 0; i < 256; ++i) {
uint8_t x = std::min(std::max<uint8_t>(i, in_lo), in_hi);
uint64_t o = out_lo + (x - in_lo) * out_range / in_range;
lutnorm[i] = o;
lut0[i] = o << (8*0);
lut1[i] = o << (8*1);
lut2[i] = o << (8*2);
lut3[i] = o << (8*3);
lut4[i] = o << (8*4);
lut5[i] = o << (8*5);
lut6[i] = o << (8*6);
lut7[i] = o << (8*7);
}
size_t i = 0;
size_t sz = data.size();
while (i < (sz - 8)) {
uint64_t x = *reinterpret_cast<uint64_t*>(&data[i]);
uint64_t o = 0;
o ^= lut0[(x >> (8*0)) & 0xff];
o ^= lut1[(x >> (8*1)) & 0xff];
o ^= lut2[(x >> (8*2)) & 0xff];
o ^= lut3[(x >> (8*3)) & 0xff];
o ^= lut4[(x >> (8*4)) & 0xff];
o ^= lut5[(x >> (8*5)) & 0xff];
o ^= lut6[(x >> (8*6)) & 0xff];
o ^= lut7[(x >> (8*7)) & 0xff];
*reinterpret_cast<uint64_t*>(&data[i]) = o;
i += 8;
}
while (i < sz) {
data[i] = lutnorm[data[i]];
++i;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment