aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-01-31 17:41:21 +0100
committerMattias Andrée <maandree@kth.se>2023-01-31 17:41:21 +0100
commit028da0c98201140f2b0cc6dfdae39da61b3cebaf (patch)
treeb98adf43713e46a48a72e1ba291d2b242e98fd71
parentAdd libglitter_redistribute_energy_double stub (diff)
downloadlibglitter-028da0c98201140f2b0cc6dfdae39da61b3cebaf.tar.gz
libglitter-028da0c98201140f2b0cc6dfdae39da61b3cebaf.tar.bz2
libglitter-028da0c98201140f2b0cc6dfdae39da61b3cebaf.tar.xz
Implement libglitter_redistribute_energy_double
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile2
-rw-r--r--libglitter.h85
-rw-r--r--libglitter_redistribute_energy_double.c64
3 files changed, 80 insertions, 71 deletions
diff --git a/Makefile b/Makefile
index cb23ead..78ba8ee 100644
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,7 @@ libglitter_compose_uint64.o: libglitter_compose_double.c
libglitter_compose_uint8.o: libglitter_compose_uint64.c libglitter_compose_double.c
libglitter_desaturate_float.o: libglitter_desaturate_double.c
libglitter_per_channel_desaturate_float.o: libglitter_per_channel_desaturate_double.c
+libglitter_redistribute_energy_float.o: libglitter_redistribute_energy_double.c
libglitter_split_uint32_raster.o: libglitter_split_uint64_raster.c
$(TESTS): $(HDR) libglitter.a
libglitter_compose_float.test: libglitter_compose_double.c
@@ -71,6 +72,7 @@ libglitter_compose_uint64.test: libglitter_compose_double.c
libglitter_compose_uint8.test: libglitter_compose_uint64.c libglitter_compose_double.c
libglitter_desaturate_float.test: libglitter_desaturate_double.c
libglitter_per_channel_desaturate_float.test: libglitter_per_channel_desaturate_double.c
+libglitter_redistribute_energy_float.test: libglitter_redistribute_energy_double.c
libglitter_split_uint32_raster.test: libglitter_split_uint64_raster.c
libglitter_get_colour_model_conversion_matrix_float.test: libglitter_get_colour_model_conversion_matrix_double.c
diff --git a/libglitter.h b/libglitter.h
index 277b7e4..b7d409a 100644
--- a/libglitter.h
+++ b/libglitter.h
@@ -231,39 +231,56 @@ void libglitter_update_render_context(LIBGLITTER_RENDER_CONTEXT *, size_t);
* (both are optional) to kernel to blur the text in
* order to reduce colour fringing
*
- * Each raster shall be row-major ordered an shall
- * have horizontally adjacent cells adjacent in memory:
- * the is no space between the cells' memory areas if
+ * The raster shall be row-major ordered an shall have
+ * horizontally adjacent cells adjacent in memory: the
+ * is no space between the cells' memory areas if
* there is no horizontal space between them in the
* raster
*
- * @param output Output subpixel raster, need not be initialised;
- * this raster is latter used as the input raster
- * for the `libglitter_compose_double` function.
- * This raster is assumed to have the height
- * `height + (vkernelsize - 1)` and the width
- * `width + (hkernelsize - 1)`; the text will be
- * offset from the top by `(vkernelsize - 1) / 2`
- * cells downward and and from the left by
- * `(hkernelsize - 1) / 2` cells rightward
- * @param input Input subpixel raster; this raster must have
- * a left padding and a right padding of
- * `hkernel - 1` zero-initialised cells, as well
- * as a top padding and a bottom padding of
- * `vkernel - 1` zero-initialised cells. The
- * the pointer itself shall point to the first
- * pixel, the topmost and leftmost pixel that
- * is not part of the padding.
- * @param output_rowsize The number of cells a pointer to cell in
- * `output` must be offset with to get to the
- * cell on the next row but in the same column
- * @param input_rowsize The number of cells a pointer to cell in
- * `input` must be offset with to get to the
+ * This function will extend the image in raster by
+ * `(hkernelsize - 1) / 2` cells to the left and to
+ * the right, and `(vkernelsize - 1) / 2` cells to
+ * the up as well as down. The caller is responsible
+ * for furthering extending the image by `widthmul`
+ * - (hkernelsize - 1) / 2 % widthmul` cells both to
+ * on the left and on the right, and by `heightmul`
+ * - (vkernelsize - 1) / 2 % heightmul` cells both
+ * up and down (where `widthmul` and `heightmul` are
+ * arguments to the `libglitter_create_render_context`
+ * function); so that the raster can be input to
+ * `libglitter_compose_double`.
+ *
+ * @param raster The subpixel raster. The must be padded with
+ * zero-initialised cells on the left side and
+ * on the top. This padding must `(hkernelsize - 1)`
+ * cells wide the left side and `(vkernelsize - 1)`
+ * cells tall on the top. The new image will be
+ * written to this raster must shiften upwards
+ * `(vkernelsize - 1) / 2` cells and to the left
+ * `(hkernelsize - 1) / 2` cells. The image will
+ * also be extended by `(hkernelsize - 1) / 2`
+ * cells on both the left side and the right size
+ * and by `(vkernelsize - 1) / 2` cells both above
+ * and below. The input pointer shall point to
+ * the image location in the pointer, that is
+ * the first cell after the padding, but once
+ * the function returns the pointer to first
+ * cell is in the padding shall be used as the
+ * first cell in the new image; however the image
+ * will be offset by `(vkernelsize - 1) / 2` cells
+ * vertically and `(hkernelsize - 1) / 2` cells
+ * horizontally.
+ * @param rowsize The number of cells a pointer to cell in
+ * `raster` must be offset with to get to the
* cell on the next row but in the same column
- * @param width The width of the input raster, excluding
- * padding, in cells
- * @param height The height of the input raster, excluding
- * padding, in cells
+ * @param width The width of the input raster (excluding
+ * padding), in cells. The function extends the
+ * image by `(hkernelsize - 1) / 2` cells
+ * vertically.
+ * @param height The height of the input raster (excluding
+ * padding), in cells. The function extends the
+ * image by `(hkernelsize - 1) / 2` cells
+ * horizontally.
* @param hkernelsize The size (number of elements) of `hkernel`;
* must be odd; if 1, `hkernel` is not applied
* @param vkernelsize The size (number of elements) of `vkernel`;
@@ -287,9 +304,8 @@ void libglitter_update_render_context(LIBGLITTER_RENDER_CONTEXT *, size_t);
* `vkernel` is `{1/3., 1/3., 1/3.}`. Of course user
* experimentation is required to find the best kernel.
*/
-LIBGLITTER_GCC_ATTRS__(nonnull(1, 2))
-void libglitter_redistribute_energy_double(double *restrict output, const double *restrict input,
- size_t output_rowsize, size_t input_rowsize, size_t width,
+LIBGLITTER_GCC_ATTRS__(nonnull(1))
+void libglitter_redistribute_energy_double(double *restrict raster, size_t rowsize, size_t width,
size_t height, size_t hkernelsize, size_t vkernelsize,
const double *hkernel, const double *vkernel);
@@ -298,9 +314,8 @@ void libglitter_redistribute_energy_double(double *restrict output, const double
* apart from it parameter types, see `libglitter_redistribute_energy_double`
* for details about this function
*/
-LIBGLITTER_GCC_ATTRS__(nonnull(1, 2))
-void libglitter_redistribute_energy_float(float *restrict output, const float *restrict input,
- size_t output_rowsize, size_t input_rowsize, size_t width,
+LIBGLITTER_GCC_ATTRS__(nonnull(1))
+void libglitter_redistribute_energy_float(float *restrict raster, size_t rowsize, size_t width,
size_t height, size_t hkernelsize, size_t vkernelsize,
const float *hkernel, const float *vkernel);
diff --git a/libglitter_redistribute_energy_double.c b/libglitter_redistribute_energy_double.c
index 3eb39e0..9f97ed3 100644
--- a/libglitter_redistribute_energy_double.c
+++ b/libglitter_redistribute_energy_double.c
@@ -4,56 +4,48 @@
static void
-hselfconvolute(double *restrict raster, size_t rowsize, size_t width, size_t height, size_t kernelsize, const double *hkernel)
+vconvolute(double *restrict raster, size_t rowsize, size_t width, size_t height, size_t kernelsize, const double *kernel)
{
- /* TODO */
-}
-
-
-static void
-hconvolute(double *restrict output, const double *restrict input, size_t output_rowsize, size_t input_rowsize,
- size_t width, size_t height, size_t kernelsize, const double *kernel)
-{
- /* TODO */
-}
-
-
-static void
-vconvolute(double *restrict output, const double *restrict input, size_t output_rowsize, size_t input_rowsize,
- size_t width, size_t height, size_t kernelsize, const double *kernel)
-{
- /* TODO */
+ size_t y, x, i;
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ raster[x] *= kernel[0];
+ for (i = 1; i < kernelsize; i++)
+ for (x = 0; x < width; x++)
+ raster[x] = fma(raster[i * rowsize + x], kernel[i], raster[x]);
+ raster = &raster[rowsize];
+ }
}
static void
-copyraster(double *restrict output, const double *restrict input, size_t output_rowsize,
- size_t input_rowsize, size_t width, size_t height)
+hconvolute(double *restrict raster, size_t rowsize, size_t width, size_t height, size_t kernelsize, const double *kernel)
{
- size_t y;
+ size_t y, x, i;
for (y = 0; y < height; y++) {
- memcpy(output, input, width * sizeof(double));
- output = &output[output_rowsize];
- input = &input[input_rowsize];
+ for (x = 0; x < width; x++) {
+ raster[x] *= kernel[0];
+ for (i = 1; i < kernelsize; i++)
+ raster[x] = fma(raster[x + i], kernel[i], raster[x]);
+ }
+ raster = &raster[rowsize];
}
}
void
-libglitter_redistribute_energy_double(double *restrict output, const double *restrict input, /* TODO add man page */
- size_t output_rowsize, size_t input_rowsize, size_t width,
- size_t height, size_t hkernelsize, size_t vkernelsize,
- const double *hkernel, const double *vkernel)
+libglitter_redistribute_energy_double(double *restrict raster, size_t rowsize, size_t width, size_t height, /* TODO add man page */
+ size_t hkernelsize, size_t vkernelsize, const double *hkernel, const double *vkernel)
{
- /* TODO Can we allow output==input ? */
if (vkernelsize > 1) {
- vconvolute(output, input, output_rowsize, input_rowsize, width, height, vkernelsize, vkernel);
- if (hkernelsize > 1)
- hselfconvolute(output, output_rowsize, width, height, hkernelsize, hkernel);
- } else if (hkernelsize > 1) {
- vconvolute(output, input, output_rowsize, input_rowsize, width, height, hkernelsize, hkernel);
- } else {
- copyraster(output, input, output_rowsize, input_rowsize, width, height);
+ raster -= (hkernelsize - 1) * rowsize;
+ vconvolute(raster, rowsize, width, height, vkernelsize, vkernel);
+ height += hkernelsize - 1;
+ }
+ if (hkernelsize > 1) {
+ raster -= hkernelsize - 1;
+ hconvolute(raster, rowsize, width, height, hkernelsize, hkernel);
+ width += hkernelsize - 1;
}
}