Skip to content

Instantly share code, notes, and snippets.

@EddyLuten
Created November 24, 2016 01:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EddyLuten/bcf4ea3dfac5b1ae1f9ac28fe2a411e6 to your computer and use it in GitHub Desktop.
Save EddyLuten/bcf4ea3dfac5b1ae1f9ac28fe2a411e6 to your computer and use it in GitHub Desktop.
Resample using source area average (for downsampling)
#define UMAX(x, y) ((uint32_t)(x > y ? x : y))
#define UMIN(x, y) ((uint32_t)(x < y ? x : y))
static inline uint8_t* resample(
uint8_t* src,
uint32_t src_width,
uint32_t src_height,
uint32_t dest_width,
uint32_t dest_height
)
{
static const uint32_t components = 3;
const double x_ratio = src_width / (double)dest_width;
const double y_ratio = src_height / (double)dest_height;
const uint32_t x_stride = (uint32_t)ceil(x_ratio);
const uint32_t y_stride = (uint32_t)ceil(y_ratio);
uint8_t* dest = malloc(components * dest_width * dest_height);
double src_x_center, src_y_center;
uint32_t
dest_y, dest_x,
dest_index, src_index,
src_x_start, src_x_end, src_x,
src_y_start, src_y_end, src_y,
sum_r, sum_g, sum_b,
sample_count;
for (dest_y = 0; dest_y < dest_height; ++dest_y) {
for (dest_x = 0; dest_x < dest_width; ++dest_x) {
sample_count = 0;
sum_r = 0;
sum_g = 0;
sum_b = 0;
src_x_center = floor(dest_x * x_ratio);
src_y_center = floor(dest_y * y_ratio);
src_x_start = UMAX(src_x_center - (x_stride / 2.0), 0);
src_x_end = UMIN(src_x_center + (x_stride / 2.0), src_width);
src_y_start = UMAX(src_y_center - (y_stride / 2), 0);
src_y_end = UMIN(src_y_center + (y_stride / 2), src_height);
for (src_y = src_y_start; src_y < src_y_end; ++src_y) {
for (src_x = src_x_start; src_x < src_x_end; ++src_x) {
src_index = components * ((src_y * src_width) + src_x);
sum_r += src[0 + src_index];
sum_g += src[1 + src_index];
sum_b += src[2 + src_index];
++sample_count;
}
}
dest_index = components * ((dest_y * dest_width) + dest_x);
dest[0 + dest_index] = sum_r / sample_count;
dest[1 + dest_index] = sum_g / sample_count;
dest[2 + dest_index] = sum_b / sample_count;
}
}
return dest;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment