aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libglitter_colour_model_convert_rasters_double.35
-rw-r--r--libglitter_colour_model_convert_rasters_double.c164
2 files changed, 166 insertions, 3 deletions
diff --git a/libglitter_colour_model_convert_rasters_double.3 b/libglitter_colour_model_convert_rasters_double.3
index 329b638..0ac525b 100644
--- a/libglitter_colour_model_convert_rasters_double.3
+++ b/libglitter_colour_model_convert_rasters_double.3
@@ -120,7 +120,10 @@ shall be column-major conversion matrix from the source
colour model (the output's colour model) to the target
colour model (the application's colour model).
.PP
-All rasters are in row-major order and must be distinct.
+All rasters are in row-major order and must be distinct,
+except the input rasters are allowed to the same, with
+the same offsets, as the output rasters: they must overlap
+exactly or not at all.
.PP
By default, these functions do not use hardware acceleration,
they run on the CPU. However the
diff --git a/libglitter_colour_model_convert_rasters_double.c b/libglitter_colour_model_convert_rasters_double.c
index 143cd4e..242a738 100644
--- a/libglitter_colour_model_convert_rasters_double.c
+++ b/libglitter_colour_model_convert_rasters_double.c
@@ -79,11 +79,171 @@ libglitter_colour_model_convert_rasters_double(size_t n, size_t m, double **outp
#else
+static void
+check(int same_rasters)
+{
+ double input1[4 * 15 * 3], input2[4 * 15 * 3], input3[4 * 15 * 3];
+ double output1[4 * 14 * 4], output2[4 * 14 * 4], output3[4 * 14 * 4];
+ double *inputs[3], *outputs[3], matrix[3][3], zeroes[4 * 15 * 4];
+
+ memset(zeroes, 0, sizeof(zeroes));
+
+#define RESET\
+ do {\
+ inputs[0] = input1;\
+ inputs[1] = input2;\
+ inputs[2] = input3;\
+ outputs[0] = same_rasters ? input1 : output1;\
+ outputs[1] = same_rasters ? input2 : output2;\
+ outputs[2] = same_rasters ? input3 : output3;\
+ memset(input1, 0, sizeof(input1));\
+ memset(input2, 0, sizeof(input2));\
+ memset(input3, 0, sizeof(input3));\
+ memset(output1, 0, sizeof(output1));\
+ memset(output2, 0, sizeof(output2));\
+ memset(output3, 0, sizeof(output3));\
+ } while (0)
+
+#define IPOS(Y, X) ((Y) * 15 * 3 + (X) * 3)
+#define OPOS(Y, X) (same_rasters ? IPOS(Y, X) : (Y) * 14 * 4 + (X) * 4)
+
+#define SET_(BUF, POS, R1C1, R1C2, R1C3, R1C4, R1C5, R2C1, R2C2, R2C3, R2C4, R2C5, R3C1, R3C2, R3C3, R3C4, R3C5)\
+ do {\
+ (BUF)[POS(0, 0)] = R1C1;\
+ (BUF)[POS(0, 1)] = R1C2;\
+ (BUF)[POS(0, 2)] = R1C3;\
+ (BUF)[POS(0, 3)] = R1C4;\
+ (BUF)[POS(0, 4)] = R1C5;\
+ (BUF)[POS(1, 0)] = R2C1;\
+ (BUF)[POS(1, 1)] = R2C2;\
+ (BUF)[POS(1, 2)] = R2C3;\
+ (BUF)[POS(1, 3)] = R2C4;\
+ (BUF)[POS(1, 4)] = R2C5;\
+ (BUF)[POS(2, 0)] = R3C1;\
+ (BUF)[POS(2, 1)] = R3C2;\
+ (BUF)[POS(2, 2)] = R3C3;\
+ (BUF)[POS(2, 3)] = R3C4;\
+ (BUF)[POS(2, 4)] = R3C5;\
+ } while (0)
+
+#define SET(IBUF, R1C1, R1C2, R1C3, R1C4, R1C5, R2C1, R2C2, R2C3, R2C4, R2C5, R3C1, R3C2, R3C3, R3C4, R3C5)\
+ SET_(IBUF, IPOS, R1C1, R1C2, R1C3, R1C4, R1C5, R2C1, R2C2, R2C3, R2C4, R2C5, R3C1, R3C2, R3C3, R3C4, R3C5)\
+
+#define CHECK(OBUF, R1C1, R1C2, R1C3, R1C4, R1C5, R2C1, R2C2, R2C3, R2C4, R2C5, R3C1, R3C2, R3C3, R3C4, R3C5)\
+ do {\
+ ASSERT((OBUF)[OPOS(0, 0)] == R1C1);\
+ ASSERT((OBUF)[OPOS(0, 1)] == R1C2);\
+ ASSERT((OBUF)[OPOS(0, 2)] == R1C3);\
+ ASSERT((OBUF)[OPOS(0, 3)] == R1C4);\
+ ASSERT((OBUF)[OPOS(0, 4)] == R1C5);\
+ ASSERT((OBUF)[OPOS(1, 0)] == R2C1);\
+ ASSERT((OBUF)[OPOS(1, 1)] == R2C2);\
+ ASSERT((OBUF)[OPOS(1, 2)] == R2C3);\
+ ASSERT((OBUF)[OPOS(1, 3)] == R2C4);\
+ ASSERT((OBUF)[OPOS(1, 4)] == R2C5);\
+ ASSERT((OBUF)[OPOS(2, 0)] == R3C1);\
+ ASSERT((OBUF)[OPOS(2, 1)] == R3C2);\
+ ASSERT((OBUF)[OPOS(2, 2)] == R3C3);\
+ ASSERT((OBUF)[OPOS(2, 3)] == R3C4);\
+ ASSERT((OBUF)[OPOS(2, 4)] == R3C5);\
+ SET_(OBUF, OPOS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\
+ ASSERT(!memcmp((OBUF), zeroes, same_rasters ? sizeof(*input1) : sizeof(*output1)));\
+ } while (0)
+
+#define RUN(NINPUTS, NOUTPUTS)\
+ do {\
+ double mat[NOUTPUTS][NINPUTS];\
+ size_t i, j;\
+ for (i = 0; i < (NOUTPUTS); i++)\
+ for (j = 0; j < (NINPUTS); j++)\
+ mat[i][j] = matrix[i][j];\
+ libglitter_colour_model_convert_rasters_double(NINPUTS, NOUTPUTS, outputs, (void *)inputs,\
+ same_rasters ? 15 : 14, same_rasters ? 3 : 4,\
+ 15, 3, 5, 3, mat);\
+ inputs[0] = input1;\
+ inputs[1] = input2;\
+ inputs[2] = input3;\
+ outputs[0] = same_rasters ? input1 : output1;\
+ outputs[1] = same_rasters ? input2 : output2;\
+ outputs[2] = same_rasters ? input3 : output3;\
+ } while (0)
+
+
+ RESET;
+ SET(inputs[0], 1, 5, 2, 6, 3, 9, 6, 4, 3, 1, 8, 7, 4, 9, 5);
+ matrix[0][0] = 3;
+ RUN(1, 1);
+ CHECK(outputs[0], 1*3, 5*3, 2*3, 6*3, 3*3, 9*3, 6*3, 4*3, 3*3, 1*3, 8*3, 7*3, 4*3, 9*3, 5*3);
+
+
+ RESET;
+ SET(inputs[0], 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7);
+ SET(inputs[1], 4, 5, 6, 7, 8, 5, 6, 7, 8, 9, 6, 7, 8, 9, 1);
+ SET(inputs[2], 7, 8, 9, 1, 2, 8, 9, 1, 2, 3, 9, 1, 2, 3, 4);
+ matrix[0][0] = 1, matrix[1][0] = 3;
+ matrix[0][1] = 4, matrix[1][1] = 2;
+ matrix[0][2] = 2, matrix[1][2] = 6;
+ RUN(3, 2);
+#define X(A, B, C) ((A) * 1 + (B) * 4 + (C) * 2)
+ CHECK(outputs[0], X(1,4,7), X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2),
+ X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3),
+ X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3), X(7,1,4));
+#undef X
+#define X(A, B, C) ((A) * 3 + (B) * 2 + (C) * 6)
+ CHECK(outputs[1], X(1,4,7), X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2),
+ X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3),
+ X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3), X(7,1,4));
+#undef X
+
+
+ RESET;
+ SET(inputs[0], 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7);
+ SET(inputs[1], 4, 5, 6, 7, 8, 5, 6, 7, 8, 9, 6, 7, 8, 9, 1);
+ matrix[0][0] = 7, matrix[1][0] = 4;
+ matrix[0][1] = 3, matrix[1][1] = 9;
+ RUN(2, 2);
+#define X(A, B) ((A) * 7 + (B) * 3)
+ CHECK(outputs[0], X(1,4), X(2,5), X(3,6), X(4,7), X(5,8),
+ X(2,5), X(3,6), X(4,7), X(5,8), X(6,9),
+ X(3,6), X(4,7), X(5,8), X(6,9), X(7,1));
+#undef X
+#define X(A, B) ((A) * 4 + (B) * 9)
+ CHECK(outputs[1], X(1,4), X(2,5), X(3,6), X(4,7), X(5,8),
+ X(2,5), X(3,6), X(4,7), X(5,8), X(6,9),
+ X(3,6), X(4,7), X(5,8), X(6,9), X(7,1));
+#undef X
+
+
+ RESET;
+ SET(inputs[0], 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7);
+ SET(inputs[1], 4, 5, 6, 7, 8, 5, 6, 7, 8, 9, 6, 7, 8, 9, 1);
+ SET(inputs[2], 7, 8, 9, 1, 2, 8, 9, 1, 2, 3, 9, 1, 2, 3, 4);
+ matrix[0][0] = 7, matrix[1][0] = 1, matrix[2][0] = 4;
+ matrix[0][1] = 2, matrix[1][1] = 8, matrix[2][1] = 5;
+ matrix[0][2] = 6, matrix[1][2] = 7, matrix[2][2] = 6;
+ RUN(3, 3);
+#define X(A, B, C) ((A) * 7 + (B) * 2 + (C) * 6)
+ CHECK(outputs[0], X(1,4,7), X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2),
+ X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3),
+ X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3), X(7,1,4));
+#undef X
+#define X(A, B, C) ((A) * 1 + (B) * 8 + (C) * 7)
+ CHECK(outputs[1], X(1,4,7), X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2),
+ X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3),
+ X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3), X(7,1,4));
+#undef X
+#define X(A, B, C) ((A) * 4 + (B) * 5 + (C) * 6)
+ CHECK(outputs[2], X(1,4,7), X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2),
+ X(2,5,8), X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3),
+ X(3,6,9), X(4,7,1), X(5,8,2), X(6,9,3), X(7,1,4));
+#undef X
+}
+
int
main(void)
{
- return 0; /* TODO add test */
+ check(0);
+ check(1);
}
-
#endif