/* See LICENSE file for copyright and license details. */
#include "common.h"
#ifndef TEST
static void
vstrips(double **outputs_, const double *restrict input, size_t output_rowsize, size_t output_cellsize,
size_t input_rowsize, size_t width, size_t height, const uint8_t *restrict cellmap)
{
double *outputs[3];
size_t y, x, output_y, output_i, input_blanking;
outputs[0] = outputs_[cellmap[0]];
outputs[1] = outputs_[cellmap[1]];
outputs[2] = outputs_[cellmap[2]];
output_rowsize *= output_cellsize;
input_blanking = input_rowsize - width * 3;
for (y = 0, output_y = 0; y < height; y++, output_y += output_rowsize) {
for (x = 0, output_i = output_y; x < width; x++, output_i += output_cellsize) {
outputs[0][output_i] = input[0];
outputs[1][output_i] = input[1];
outputs[2][output_i] = input[2];
input = &input[3];
}
input = &input[input_blanking];
}
}
static void
hstrips(double **outputs_, const double *restrict input, size_t output_rowsize, size_t output_cellsize,
size_t input_rowsize, size_t width, size_t height, const uint8_t *restrict cellmap)
{
double *outputs[3];
size_t y, x, output_y, output_i, input_blanking;
outputs[0] = outputs_[cellmap[0]];
outputs[1] = outputs_[cellmap[1]];
outputs[2] = outputs_[cellmap[2]];
output_rowsize *= output_cellsize;
input_blanking = input_rowsize * 3 - width;
for (y = 0, output_y = 0; y < height; y++, output_y += output_rowsize) {
for (x = 0, output_i = output_y; x < width; x++, output_i += output_cellsize) {
outputs[0][output_i] = input[0 * input_rowsize];
outputs[1][output_i] = input[1 * input_rowsize];
outputs[2][output_i] = input[2 * input_rowsize];
input = &input[1];
}
input = &input[input_blanking];
}
}
# ifndef ONLY_INT_COMPATIBLE
static void
generic(double **outputs, size_t noutputs, const double *restrict input,
size_t output_rowsize, size_t output_cellsize, size_t input_rowsize,
size_t width, size_t height, size_t widthmul, size_t heightmul,
const uint8_t *restrict cellmap, const double *restrict cellweights)
{
size_t y, x, iy, ix, i, output_y, output_i, input_blanking;
uint8_t channel;
double value;
output_rowsize *= output_cellsize;
input_blanking = input_rowsize * heightmul - width * widthmul;
for (y = 0, output_y = 0; y < height; y++, output_y += output_rowsize) {
for (x = 0, output_i = output_y; x < width; x++, output_i += output_cellsize) {
for (i = 0; i < noutputs; i++)
outputs[i][output_i] = 0;
for (iy = 0; iy < heightmul; iy++) {
for (ix = 0; ix < widthmul; ix++) {
channel = cellmap[iy * widthmul + ix];
value = input[iy * input_rowsize + ix];
value *= cellweights[channel];
outputs[channel][output_i] += value;
}
}
input = &input[widthmul];
}
input = &input[input_blanking];
}
}
void
libglitter_compose_double(double **outputs, const double *restrict input, size_t output_rowsize, size_t output_cellsize,
size_t width, size_t height, const LIBGLITTER_RENDER_CONTEXT *render_ctx)
{
if (render_ctx->render_method == RENDER_METHOD_VSTRIPS) {
vstrips(outputs, input, output_rowsize, output_cellsize, render_ctx->rowsize, width, height, render_ctx->cellmap);
} else if (render_ctx->render_method == RENDER_METHOD_HSTRIPS) {
hstrips(outputs, input, output_rowsize, output_cellsize, render_ctx->rowsize, width, height, render_ctx->cellmap);
} else {
generic(outputs, render_ctx->noutputs, input, output_rowsize, output_cellsize, render_ctx->rowsize, width, height,
render_ctx->widthmul, render_ctx->heightmul, render_ctx->cellmap, render_ctx->cellweights_double);
}
}
# endif
#else
# ifndef ONLY_INT_COMPATIBLE
int
main(void)
{
return 0; /* TODO add test */
}
# endif
#endif