Initial import

This commit is contained in:
Justine Tunney 2020-06-15 07:18:57 -07:00
commit c91b3c5006
14915 changed files with 590219 additions and 0 deletions

88
test/dsp/core/dct_test.c Normal file
View file

@ -0,0 +1,88 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "libc/math.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
TEST(dct, test) {
float M[8][8] /* clang-format off */ = {
{.509804, .513725, .094118, .219608, .027451, .294118, .172549, .658824},
{.019608, .070588, .196078, .015686, .172549, .458824, .713725, .294118},
{.380392, .341176, .235294, .737255, .741176, .968627, .607843, .12549},
{.560784, .843137, .639216, .929412, .756863, .113725, .643137, .435294},
{.878431, .576471, .737255, .356863, .8, .878431, .682353, .866667},
{.780392, .070588, .866667, .607843, .792157, .47451, .427451, .043137},
{.133333, .976471, .698039, .662745, .035294, .207843, .831373, .627451},
{.313725, .580392, .858824, .631373, .784314, .972549, .27451, .94902},
} /* clang-format on */;
dctjpeg(M);
EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\
32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\
-9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\
-6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\
-2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\
4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\
-.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\
.64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\
.61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237");
}
/* TEST(dct, test2) { */
/* float M[8][8] /\* clang-format off *\/ = { */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
/* } /\* clang-format on *\/; */
/* dctjpeg(M); */
/* EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\ */
/* 32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\ */
/* -9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\ */
/* -6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\ */
/* -2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\ */
/* 4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\ */
/* -.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\ */
/* .64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\ */
/* .61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237"); */
/* } */
BENCH(dct, bench) {
float M[8][8] /* clang-format off */ = {
{.101961, .486275, .082353, .082353, .937255, .321569, .14902, .270588},
{.384314, .062745, .152941, .003922, .921569, .015686, .247059, 0},
{.760784, .023529, .411765, .443137, .862745, .85098, .435294, .631373},
{.309804, .141176, .54902, .984314, .478431, .6, .364706, .643137},
{.780392, .811765, .458824, .964706, .439216, .941176, .321569, .313725},
{.596078, .207843, .133333, .345098, .278431, .192157, .52549, .627451},
{.952941, .090196, .290196, .717647, .686275, .713725, .54902, .411765},
{.109804, .121569, .403922, .27451, .470588, .007843, .168627, .105882},
} /* clang-format on */;
void *data = tgc(tmalloc(sizeof(M)));
EZBENCH2("dct", memcpy(data, M, sizeof(M)), EXPROPRIATE(dctjpeg(data)));
}

View file

@ -0,0 +1,65 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/xmmintrin.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "third_party/blas/blas.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
TEST(dgemm, test) {
double alpha, beta;
long m, n, k, lda, ldb, ldc;
double A[3][3] = {{1 / 8.}, {6 / 8.}, {1 / 8.}};
double B[1][3] = {{1 / 8., 6 / 8., 1 / 8.}};
double C[3][3] = {0};
m = 3;
n = 3;
k = 1;
lda = 3;
ldb = 3;
ldc = 3;
beta = 1;
alpha = 1;
dgemm_("T", "T", &m, &n, &k, &alpha, &A[0][0], &lda, &B[0][0], &ldb, &beta,
&C[0][0], &ldc);
EXPECT_DBLMATRIXEQ(6, rint, 3, 3, C, "\n\
.015625 .09375 .015625\n\
.09375 .5625 .09375\n\
.015625 .09375 .015625");
}
void dgemmer(long m, long n, long k, void *A, long lda, void *B, long ldb,
void *C, long ldc) {
double alpha, beta;
beta = 1;
alpha = 1;
dgemm_("N", "N", &m, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
}
BENCH(dgemm, bench) {
double(*A)[128][128] = tgc(tmalloc(128 * 128 * 8));
double(*B)[128][128] = tgc(tmalloc(128 * 128 * 8));
double(*C)[128][128] = tgc(tmalloc(128 * 128 * 8));
EZBENCH2("dgemm_", donothing, dgemmer(128, 128, 128, A, 128, B, 128, C, 128));
}

View file

@ -0,0 +1,84 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "dsp/mpeg/mpeg.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/rand/rand.h"
#include "libc/runtime/buffer.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
short pcm[8][8];
float binary32[8][8];
struct GuardedBuffer b1, b2;
TEST(float2short, test) {
binary32[0][0] = -0.5;
binary32[0][1] = 0.0;
binary32[0][2] = 0.5;
float2short(8, pcm, binary32);
EXPECT_EQ(-16384, pcm[0][0]);
EXPECT_EQ(0, pcm[0][1]);
EXPECT_EQ(16384, pcm[0][2]);
}
TEST(float2short, testOverflow) {
binary32[0][0] = -1.1;
binary32[0][1] = -1.0;
binary32[0][2] = 1.0;
binary32[0][3] = 1.1;
float2short(8, pcm, binary32);
EXPECT_EQ(-32768, pcm[0][0]);
EXPECT_EQ(-32768, pcm[0][1]);
EXPECT_EQ(32767, pcm[0][2]);
EXPECT_EQ(32767, pcm[0][3]);
}
void unclamped(size_t n, short pcm16[n][8], const float binary32[n][8]) {
size_t i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < 8; ++j) {
pcm16[i][j] = binary32[i][j] * 32768;
}
}
}
plm_samples_t samps;
void randomizeaudio(void) {
size_t i;
for (i = 0; i < ARRAYLEN(samps.interleaved); ++i) {
samps.interleaved[i] = randf();
}
}
void float2short_pure(void) {
float2short(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved);
}
void float2short_unclamped(void) {
unclamped(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved);
}
BENCH(float2short, audioframe) {
EZBENCH(randomizeaudio(), float2short_pure());
EZBENCH(randomizeaudio(), float2short_unclamped());
}

View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "libc/math.h"
#include "libc/testlib/testlib.h"
TEST(gamma, test) {
int i;
double g, x, a, b;
g = 2.4;
for (i = 0; i < 256; ++i) {
x = i;
x /= 255;
a = rgb2stdpc(x, g);
b = tv2pcgamma(rgb2stdtv(x), g);
ASSERT_EQ(true, fabs(a - b) < .000000001, "%d %f %f %f", i, x, a, b);
}
}

View file

@ -0,0 +1,62 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "dsp/core/q.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
long I[8];
TEST(GetIntegerCoefficients8, testBt601Vectors) {
const struct {
int m, L, H;
double r[8];
long n[8];
} V[] = {
{8, 16, 235, {.299, .587, .114}, {77, 150, 29}},
{9, 16, 235, {.299, .587, .114}, {153, 301, 58}},
{10, 16, 235, {.299, .587, .114}, {306, 601, 117}},
{11,
16,
235,
{.299, .587, .114, 1, 1, 1},
{612, 1202, 234, 2048, 2048, 2048}},
{12, 16, 235, {.299, .587, .114}, {1225, 2404, 467}},
{13, 16, 235, {.299, .587, .114}, {2449, 4809, 934}},
{14, 16, 235, {.299, .587, .114}, {4899, 9617, 1868}},
{15, 16, 235, {.299, .587, .114}, {9798, 19235, 3735}},
{16, 16, 235, {.299, .587, .114}, {19595, 38470, 7471}},
};
long i, got[8];
for (i = 0; i < ARRAYLEN(V); ++i) {
GetIntegerCoefficients8(got, V[i].r, V[i].m, V[i].L, V[i].H);
EXPECT_EQ(0, memcmp(V[i].n, got, sizeof(got)),
"got={%ld,%ld,%ld,%ld,%ld,%ld}, want={%ld,%ld,%ld,%ld,%ld,%ld}",
got[0], got[1], got[2], got[3], got[4], got[5], V[i].n[0],
V[i].n[1], V[i].n[2], V[i].n[3], V[i].n[4], V[i].n[5]);
}
}
BENCH(GetIntegerCoefficients8, bench) {
double C[8] = {.299, .587, .114, .299, .587, .114, .114, .114};
EZBENCH2("GetIntegerCoefficients8", donothing,
GetIntegerCoefficients8(I, C, 11, 16, 232));
}

View file

@ -0,0 +1,89 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "dsp/core/q.h"
#include "libc/macros.h"
#include "libc/runtime/gc.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
long I[6];
TEST(GetIntegerCoefficients, testBt601Vectors) {
const struct {
int m, L, H;
double r[6];
long n[6];
} V[] = {
{8, 16, 235, {.299, .587, .114}, {77, 150, 29}},
{9, 16, 235, {.299, .587, .114}, {153, 301, 58}},
{10, 16, 235, {.299, .587, .114}, {306, 601, 117}},
{11,
16,
235,
{.299, .587, .114, 1, 1, 1},
{612, 1202, IsTiny() ? 233 : 234, 2048, 2048, 2048}},
{12, 16, 235, {.299, .587, .114}, {1225, 2404, 467}},
{13, 16, 235, {.299, .587, .114}, {2449, 4809, 934}},
{14, 16, 235, {.299, .587, .114}, {4899, 9617, 1868}},
{15, 16, 235, {.299, .587, .114}, {9798, 19235, IsTiny() ? 3736 : 3735}},
{16, 16, 235, {.299, .587, .114}, {19595, 38470, 7471}},
};
long i, got[6];
for (i = 0; i < ARRAYLEN(V); ++i) {
GetIntegerCoefficients(got, V[i].r, V[i].m, V[i].L, V[i].H);
EXPECT_EQ(0, memcmp(V[i].n, got, sizeof(got)),
"got={%ld,%ld,%ld,%ld,%ld,%ld}, want={%ld,%ld,%ld,%ld,%ld,%ld}",
got[0], got[1], got[2], got[3], got[4], got[5], V[i].n[0],
V[i].n[1], V[i].n[2], V[i].n[3], V[i].n[4], V[i].n[5]);
}
}
TEST(GetIntegerCoefficients, testForYCbCr2Rgb) {
double C[6] = {.299, .587, .114};
GetIntegerCoefficients(I, C, 11, 16, 232);
EXPECT_EQ(612, I[0]);
EXPECT_EQ(1202, I[1]);
EXPECT_EQ(IsTiny() ? 233 : 234, I[2]);
}
TEST(GetIntegerCoefficients, testForGaussian) {
#define G(A, B, C, D, E) lrint((A + 4 * B + 6 * C + 4 * D + E) / 16.)
double C[6] = {1 / 16., 4 / 16., 6 / 16., 4 / 16., 1 / 16.};
long M = 22, N[6], B[6] = {12, 191, 174, 205, 35};
GetIntegerCoefficients(N, C, M, 0, 255);
EXPECT_EQ(262144, N[0]);
EXPECT_EQ(1048576, N[1]);
EXPECT_EQ(1572864, N[2]);
EXPECT_EQ(1048576, N[3]);
EXPECT_EQ(262144, N[4]);
EXPECT_EQ(G(B[0], B[1], B[2], B[3], B[4]),
(N[0] * B[0] + N[1] * B[1] + N[2] * B[2] + N[3] * B[3] +
N[4] * B[4] + N[5] * B[5] + (1l << (M - 1))) >>
M);
}
BENCH(GetIntegerCoefficients, bench) {
double C[6] = {.299, .587, .114};
EZBENCH2("getintegercoefficients", donothing,
GetIntegerCoefficients(I, C, 11, 16, 232));
}

View file

@ -0,0 +1,50 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "dsp/core/illumination.h"
#include "libc/log/log.h"
#include "libc/math.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
TEST(GetChromaticAdaptationMatrix, testSuperiorIlluminationBannedInCalifornia) {
double M[3][3];
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA);
EXPECT_DBLMATRIXEQ(5, rint, 3, 3, M, "\n\
1.21646 .11099 -.15493\n\
.15333 .91523 -.056\n\
-.02395 .0359 .31475");
}
TEST(GetChromaticAdaptationMatrix, testD65ToD50_soWeCanCieLab) {
double M[3][3];
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantD50);
EXPECT_DBLMATRIXEQ(6, rint, 3, 3, M, "\n\
1.047811 .022887 -.050127\n\
.029542 .990484 -.017049\n\
-.009234 .015044 .752132");
}
BENCH(GetChromaticAdaptationMatrix, bench) {
double M[3][3];
EZBENCH2("GetChromaticAdaptationMatrix", donothing,
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA));
}

40
test/dsp/core/inv3_test.c Normal file
View file

@ -0,0 +1,40 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "dsp/core/illumination.h"
#include "libc/math.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
TEST(inv3, test) {
double M[3][3];
inv3(M, kBradford, det3(kBradford));
EXPECT_DBLMATRIXEQ(7, rint, 3, 3, M, "\n\
.9869929 -.1470543 .1599627\n\
.4323053 .5183603 .0492912\n\
-.0085287 .0400428 .9684867");
}
BENCH(inv3, bench) {
double M[3][3], d;
EZBENCH2("det3", donothing, EXPROPRIATE((d = det3(kBradford))));
EZBENCH2("inv3", donothing, EXPROPRIATE(inv3(M, kBradford, d)));
}

View file

@ -0,0 +1,108 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "dsp/mpeg/mpeg.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/rand/rand.h"
#include "libc/runtime/buffer.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
void addsw$pure(size_t n, short x[n][8], const short y[n][8]) {
size_t i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < 8; ++j) {
x[i][j] = MIN(MAX(x[i][j] + y[i][j], INT16_MIN), INT16_MAX);
}
}
}
short *pcm1;
short *pcm2;
struct GuardedBuffer b1, b2;
TEST(sad16x8n, test) {
CHECK_NOTNULL((pcm1 = balloc(&b1, 32, 128 * 2)));
CHECK_NOTNULL((pcm2 = balloc(&b2, 32, 128 * 2)));
pcm1[0] = 0;
pcm2[0] = 0;
pcm1[1] = 23;
pcm2[1] = 10;
pcm1[2] = 23;
pcm2[2] = -10;
pcm1[3] = 23;
pcm2[3] = -46;
pcm1[120 + 0] = 0;
pcm2[120 + 0] = 0;
pcm1[120 + 1] = 23;
pcm2[120 + 1] = 10;
pcm1[120 + 2] = 23;
pcm2[120 + 2] = -10;
pcm1[120 + 3] = 23;
pcm2[120 + 3] = -46;
sad16x8n(128 / 8, (void *)pcm1, (void *)pcm2);
EXPECT_EQ(0, pcm1[0]);
EXPECT_EQ(33, pcm1[1]);
EXPECT_EQ(13, pcm1[2]);
EXPECT_EQ(-23, pcm1[3]);
EXPECT_EQ(0, pcm1[120 + 0]);
EXPECT_EQ(33, pcm1[120 + 1]);
EXPECT_EQ(13, pcm1[120 + 2]);
EXPECT_EQ(-23, pcm1[120 + 3]);
bfree(&b1);
bfree(&b2);
}
//////////////////////////////////////////////////////////////////////
// audio frame mixing latency: ~60ns (sse2 10x faster than pure)
//
// 1f ~= 14ms (cd quality)
// (1.0 / 41000) * (1.0 / 2) * (1152 / 1.0)
//
// 1f ~= 845µs (dolby truehd)
// (1.0 / 192000) * (1.0 / 7.1) * (1152 / 1.0)
//
// @note plm frame always has exactly 1152 floats
void randomizeaudio(void) {
size_t i;
for (i = 0; i < PLM_AUDIO_SAMPLES_PER_FRAME; ++i) {
pcm1[i] = (rand() - INT_MAX / 2) % INT16_MAX;
pcm2[i] = (rand() - INT_MAX / 2) % INT16_MAX;
}
}
void sad16x8n_sse2(void) {
sad16x8n(PLM_AUDIO_SAMPLES_PER_FRAME / 8, (void *)pcm1, (void *)pcm2);
}
void sad16x8n_pure(void) {
addsw$pure(PLM_AUDIO_SAMPLES_PER_FRAME / 8, (void *)pcm1, (void *)pcm2);
}
BENCH(sad16x8n, audioframe) {
CHECK_NOTNULL((pcm1 = balloc(&b1, 32, PLM_AUDIO_SAMPLES_PER_FRAME * 2)));
CHECK_NOTNULL((pcm2 = balloc(&b2, 32, PLM_AUDIO_SAMPLES_PER_FRAME * 2)));
EZBENCH(randomizeaudio(), sad16x8n_pure());
EZBENCH(randomizeaudio(), sad16x8n_sse2());
bfree(&b1);
bfree(&b2);
}

View file

@ -0,0 +1,161 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/core.h"
#include "dsp/mpeg/mpeg.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/rand/rand.h"
#include "libc/runtime/buffer.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
short pcm[8][8];
TEST(scalevolume, testIncreaseVolumeByOneIncrement) {
pcm[0][0] = INT16_MIN;
pcm[0][1] = INT16_MIN / 2;
pcm[0][2] = -2;
pcm[0][3] = -1;
pcm[0][4] = 0;
pcm[0][5] = 1;
pcm[0][6] = 2;
pcm[0][7] = INT16_MAX / 2;
pcm[1][0] = INT16_MAX;
scalevolume(ARRAYLEN(pcm), pcm, 1);
EXPECT_EQ(INT16_MIN, pcm[0][0]);
EXPECT_EQ(INT16_MIN, pcm[0][1]);
EXPECT_EQ(-4, pcm[0][2]);
EXPECT_EQ(-2, pcm[0][3]);
EXPECT_EQ(0, pcm[0][4]);
EXPECT_EQ(2, pcm[0][5]);
EXPECT_EQ(4, pcm[0][6]);
EXPECT_EQ(INT16_MAX - 1, pcm[0][7]);
EXPECT_EQ(INT16_MAX, pcm[1][0]);
}
TEST(scalevolume, testDecreaseVolumeByOneIncrement) {
pcm[0][0] = INT16_MIN;
pcm[0][1] = INT16_MIN / 2;
pcm[0][2] = -2;
pcm[0][3] = -1;
pcm[0][4] = 0;
pcm[0][5] = 1;
pcm[0][6] = 2;
pcm[0][7] = INT16_MAX / 2;
pcm[1][0] = INT16_MAX;
scalevolume(ARRAYLEN(pcm), pcm, -1);
EXPECT_EQ(INT16_MIN / 2, pcm[0][0]);
EXPECT_EQ(INT16_MIN / 4, pcm[0][1]);
EXPECT_EQ(-1, pcm[0][2]);
EXPECT_EQ(-1, pcm[0][3]);
EXPECT_EQ(0, pcm[0][4]);
EXPECT_EQ(0, pcm[0][5]);
EXPECT_EQ(1, pcm[0][6]);
EXPECT_EQ(INT16_MAX / 4, pcm[0][7]);
EXPECT_EQ(INT16_MAX / 2, pcm[1][0]);
}
TEST(scalevolume, testScaleByZero_doesNothing) {
pcm[0][0] = INT16_MIN;
pcm[0][1] = INT16_MIN / 2;
pcm[0][2] = -2;
pcm[0][3] = -1;
pcm[0][4] = 0;
pcm[0][5] = 1;
pcm[0][6] = 2;
pcm[0][7] = INT16_MAX / 2;
pcm[1][0] = INT16_MAX;
scalevolume(ARRAYLEN(pcm), pcm, 0);
EXPECT_EQ(INT16_MIN, pcm[0][0]);
EXPECT_EQ(INT16_MIN / 2, pcm[0][1]);
EXPECT_EQ(-2, pcm[0][2]);
EXPECT_EQ(-1, pcm[0][3]);
EXPECT_EQ(0, pcm[0][4]);
EXPECT_EQ(1, pcm[0][5]);
EXPECT_EQ(2, pcm[0][6]);
EXPECT_EQ(INT16_MAX / 2, pcm[0][7]);
EXPECT_EQ(INT16_MAX, pcm[1][0]);
}
TEST(scalevolume, testBiggestScale_justSaturates) {
pcm[0][0] = INT16_MIN;
pcm[0][1] = INT16_MIN / 2;
pcm[0][2] = -2;
pcm[0][3] = -1;
pcm[0][4] = 0;
pcm[0][5] = 1;
pcm[0][6] = 2;
pcm[0][7] = INT16_MAX / 2;
pcm[1][0] = INT16_MAX;
scalevolume(ARRAYLEN(pcm), pcm, 123);
EXPECT_EQ(INT16_MIN, pcm[0][0]);
EXPECT_EQ(INT16_MIN, pcm[0][1]);
EXPECT_EQ(INT16_MIN, pcm[0][2]);
EXPECT_EQ(INT16_MIN, pcm[0][3]);
EXPECT_EQ(0, pcm[0][4]);
EXPECT_EQ(INT16_MAX, pcm[0][5]);
EXPECT_EQ(INT16_MAX, pcm[0][6]);
EXPECT_EQ(INT16_MAX, pcm[0][7]);
EXPECT_EQ(INT16_MAX, pcm[1][0]);
}
TEST(scalevolume, testSmallestScale_justSaturates) {
pcm[0][0] = INT16_MIN;
pcm[0][1] = INT16_MIN / 2;
pcm[0][2] = -2;
pcm[0][3] = -1;
pcm[0][4] = 0;
pcm[0][5] = 1;
pcm[0][6] = 2;
pcm[0][7] = INT16_MAX / 2;
pcm[1][0] = INT16_MAX;
scalevolume(ARRAYLEN(pcm), pcm, -123);
EXPECT_EQ(-1, pcm[0][0]);
EXPECT_EQ(-1, pcm[0][1]);
EXPECT_EQ(-1, pcm[0][2]);
EXPECT_EQ(-1, pcm[0][3]);
EXPECT_EQ(0, pcm[0][4]);
EXPECT_EQ(0, pcm[0][5]);
EXPECT_EQ(0, pcm[0][6]);
EXPECT_EQ(0, pcm[0][7]);
EXPECT_EQ(0, pcm[1][0]);
}
//////////////////////////////////////////////////////////////////////
// audio volume adjustment latency:
// - ~1µs w/ -Os
// - ~500ns w/ -O3
// - ~200ns w/ -O3 -march=skylake MODE=rel
void randomizeaudio(void) {
rngset(pcm, sizeof(pcm), rand64, -1);
}
void scalevolume_pure(int amt) {
scalevolume(ARRAYLEN(pcm), pcm, amt);
}
BENCH(scalevolume, audioframe) {
EZBENCH(randomizeaudio(), scalevolume_pure(0));
EZBENCH(randomizeaudio(), scalevolume_pure(1));
EZBENCH(randomizeaudio(), scalevolume_pure(15));
}

51
test/dsp/core/test.mk Normal file
View file

@ -0,0 +1,51 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_DSP_CORE
TEST_DSP_CORE_SRCS := $(wildcard test/dsp/core/*.c)
TEST_DSP_CORE_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_CORE_SRCS))
TEST_DSP_CORE_COMS = $(TEST_DSP_CORE_OBJS:%.o=%.com)
TEST_DSP_CORE_BINS = $(TEST_DSP_CORE_COMS) $(TEST_DSP_CORE_COMS:%=%.dbg)
TEST_DSP_CORE_OBJS = \
$(TEST_DSP_CORE_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_DSP_CORE_SRCS:%.c=o/$(MODE)/%.o)
TEST_DSP_CORE_TESTS = \
$(TEST_DSP_CORE_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_DSP_CORE_CHECKS = \
$(TEST_DSP_CORE_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_DSP_CORE_DIRECTDEPS = \
DSP_CORE \
DSP_MPEG \
LIBC_TINYMATH \
LIBC_LOG \
LIBC_RUNTIME \
LIBC_RAND \
LIBC_TESTLIB \
TOOL_VIZ_LIB \
THIRD_PARTY_BLAS \
THIRD_PARTY_COMPILER_RT
TEST_DSP_CORE_DEPS := \
$(call uniq,$(foreach x,$(TEST_DSP_CORE_DIRECTDEPS),$($(x))))
o/$(MODE)/test/dsp/core/core.pkg: \
$(TEST_DSP_CORE_OBJS) \
$(foreach x,$(TEST_DSP_CORE_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/dsp/core/%.com.dbg: \
$(TEST_DSP_CORE_DEPS) \
o/$(MODE)/test/dsp/core/%.o \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
.PHONY: o/$(MODE)/test/dsp/core
o/$(MODE)/test/dsp/core: \
$(TEST_DSP_CORE_BINS) \
$(TEST_DSP_CORE_CHECKS)

View file

@ -0,0 +1,155 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/scale/scale.h"
#include "libc/fmt/bing.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
TEST(magikarp, testConvolve) {
signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1};
EXPECT_BINEQ(
u"λλ  λλ  λλ  λλ  "
u"λλ  λλ  λλ  λλ  "
u"λλ  λλ  λλ  λλ  ",
cDecimate2xUint8x8(32 * 3,
tgc(tunbing(u"λλλλ    λλλλ    λλλλ    λλλλ    "
u"λλλλ    λλλλ    λλλλ    λλλλ    "
u"λλλλ    λλλλ    λλλλ    λλλλ    ")),
K));
}
TEST(magikarp, testConvolveMin1) {
signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1};
EXPECT_BINEQ(
u"λλ  λλ  λλ  λλ  "
u"λλ  λλ  λλ  λλ  "
u"λλ  λλ  λλ  λλ  ",
cDecimate2xUint8x8(32 * 3 - 1,
tgc(tunbing(u"λλλλ    λλλλ    λλλλ    λλλλ    "
u"λλλλ    λλλλ    λλλλ    λλλλ    "
u"λλλλ    λλλλ    λλλλ    λλλλ   ")),
K));
}
TEST(magikarp, testConvolve2) {
signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1};
EXPECT_BINEQ(
u" ☻♣•○♂♪☼◄‼§↨↓←↔▼"
u"!#%)+-/13579;=⁇"
u"ACEGIKMOQSUWY[]_"
u"acegikmoqsuwy{}⌂"
u"üâàçëïìÅæôòùÖ¢¥ƒ"
u"íúѺ⌐½¡»▒│╡╖╣╗╜┐"
u"┴├┼╟╔╦═╧╤╙╒╫┘█▌▀"
u"ßπστΘδφ∩±≤⌡≈∙√²λ",
cDecimate2xUint8x8(256,
tgc(tunbing(u" ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼"
u" !“#$%&()*+,-./0123456789:;<=>⁇"
u"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[╲]^_"
u"`abcdefghijklmnopqrstuvwxyz{|}~⌂"
u"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥€ƒ"
u"áíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐"
u"└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀"
u"αßΓπΣσμτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■λ")),
K));
}
const char kDieWelle[] = "\
nnooooooppppppppppqqqqqqqqqqqqqqqqqqqqqqqqqppppppppppoooooonn\
ooooooppppppppqqqqqqqqqqpppppppppppppqqqqqqqqqqppppppppoooooo\
oooopppppppqqqqqqqpppppppppppppppppppppppppqqqqqqqpppppppoooo\
oopppppppqqqqqqppppppppppoooooooooooppppppppppqqqqqqpppppppoo\
pppppppqqqqqpppppppoooooooonnnnnnnoooooooopppppppqqqqqppppppp\
pppppqqqqqppppppooooonnnnnnnmmmmmnnnnnnnoooooppppppqqqqqppppp\
ppppqqqqppppppooonnnnnmmmmmmmmmmmmmmmmmnnnnnoooppppppqqqqpppp\
ppqqqqqpppppooonnnmmmmmlllllllllllllllmmmmmnnnooopppppqqqqqpp\
pqqqqqppppooonnnmmmmlllllllllllllllllllllmmmmnnnoooppppqqqqqp\
qqqqpppppooonnmmmlllllllllllllllllllllllllllmmmnnooopppppqqqq\
qqqqppppooonnmmmllllllllllllmmmmmllllllllllllmmmnnoooppppqqqq\
qqqppppooonnmmmlllllllllmmmnnnnnnnmmmlllllllllmmmnnoooppppqqq\
qqpppppoonnmmmllllllllmmnoopqqqqqpoonmmllllllllmmmnnoopppppqq\
qqppppooonnmmllllllllmnnpqrsuvvvusrqpnnmllllllllmmnnoooppppqq\
qqppppoonnmmmlllllllmmnpqsuxyyyyyxusqpnmmlllllllmmmnnooppppqq\
qqppppoonnmmmlllllllmnoprtxyyyyyyyxtrponmlllllllmmmnnooppppqq\
qqppppoonnmmmlllllllmnoprtwyyyyyyywtrponmlllllllmmmnnooppppqq\
qqppppoonnnmmlllllllmmnoprtvxyyyxvtrponmmlllllllmmnnnooppppqq\
qqppppooonnmmllllllllmmnopqrsssssrqponmmllllllllmmnnoooppppqq\
qqqppppoonnnmmlllllllllmmnnoopppoonnmmlllllllllmmnnnooppppqqq\
qqqpppppoonnmmmllllllllllmmmmmmmmmmmllllllllllmmmnnoopppppqqq\
qqqqppppooonnnmmmlllllllllllllllllllllllllllmmmnnnoooppppqqqq\
pqqqqpppppoonnnmmmlllllllllllllllllllllllllmmmnnnoopppppqqqqp\
ppqqqqpppppooonnnmmmmlllllllllllllllllllmmmmnnnooopppppqqqqpp\
pppqqqqppppppooonnnnmmmmmlllllllllllmmmmmnnnnoooppppppqqqqppp\
ppppqqqqqppppppoooonnnnnmmmmmmmmmmmmmnnnnnooooppppppqqqqqpppp\
ppppppqqqqqpppppppooooonnnnnnnnnnnnnnnooooopppppppqqqqqpppppp\
opppppppqqqqqppppppppoooooooooooooooooooppppppppqqqqqpppppppo\
ooopppppppqqqqqqpppppppppppppppppppppppppppppqqqqqqpppppppooo\
ooooopppppppqqqqqqqqqpppppppppppppppppppqqqqqqqqqpppppppooooo\
noooooopppppppppqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpppppppppoooooon\
nnnooooooopppppppppppqqqqqqqqqqqqqqqqqqqpppppppppppooooooonnn";
TEST(magikarp, testHalfYX) {
static unsigned char M[32][61];
memcpy(M, kDieWelle, sizeof(M));
Magikarp2xY(32, 61, M, 32, 61);
Magikarp2xX(32, 61, M, 16, 61);
EXPECT_STREQ(u"\n\
nooppppqqqqqqqqqqqqqqqqqpppooon\n\
opppqqqqqppppoppoppppqqqqqppppo\n\
ppqqqqpppooooommmoooopppqqqqppp\n\
pqqqppponmmllllllllmmmnpppqqqqp\n\
qqqppoomllllllllllllllmnoppqqqq\n\
qqppoomlllllllmmmllllllmnoppqqq\n\
qppponlllllmoqttspnlllllmnoppqq\n\
qpponmllllmosyzz{vqnllllmmoppqq\n\
qpponmllllmorwzzyupnllllmmoppqq\n\
qqpponlllllloprrqomlllllmnoppqq\n\
qqpponnmlllllllllllllllmnnppqqq\n\
qqqppponmlllllllllllllnooppqqqp\n\
pqqqqpppoommmlllllmmmoopppqqqpp\n\
pppqqqqpppooooooooooppppqqqqppp\n\
oopppqqqqqqpppppppppqqqqqqpppoo\n\
noopopppqqqqqqqqqqqqqqqppoooonn",
gc(bingblit(32, 61, M, 16, 31)));
}
#define HDX (1920 / 4)
#define HDY (1080 / 4)
BENCH(magikarp, bench) { /* 30ms */
unsigned char kMagkern[16] = {4, 12, 12, 4};
signed char kMagikarp[16] = {-1, -3, 3, 17, 17, 3, -3, -1};
unsigned char(*Me)[HDY][HDX] = tgc(tmalloc((HDX + 1) * (HDY + 1)));
unsigned char(*Mo)[HDY][HDX] = tgc(tmalloc((HDX + 1) * (HDY + 1)));
if (X86_HAVE(AVX)) {
EZBENCH2("Decimate2xUint8x8", donothing,
cDecimate2xUint8x8((HDX * HDY - 16 - 8) / 2 / 8 * 8, (void *)Me,
kMagikarp));
}
EZBENCH2("cDecimate2xUint8x8", donothing,
cDecimate2xUint8x8((HDX * HDY - 16 - 8) / 2 / 8 * 8, (void *)Me,
kMagikarp));
EZBENCH2("Magikarp2xY", donothing, Magikarp2xY(HDY, HDX, *Me, HDY, HDX));
EZBENCH2("Magikarp2xX", donothing, Magikarp2xX(HDY, HDX, *Mo, HDY, HDX));
}

423
test/dsp/scale/scale_test.c Normal file
View file

@ -0,0 +1,423 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/c1331.h"
#include "dsp/core/c161.h"
#include "dsp/core/core.h"
#include "dsp/core/half.h"
#include "dsp/scale/scale.h"
#include "libc/fmt/bing.h"
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
void *AbsoluteDifference(int yn, int xn, unsigned char C[yn][xn], int ays,
int axs, const unsigned char A[ays][axs], int bys,
int bxs, const unsigned char B[bys][bxs]) {
int y, x;
for (y = 0; y < yn; ++y) {
for (x = 0; x < xn; ++x) {
C[y][x] = ABS(A[y][x] - B[y][x]);
}
}
return C;
}
const char kDieWelle[] = "\
pppppppppppppppppoooooooooooooooooooooooooooppppppppppppppppp\
pmpppppppppppooooooonnnnnnnnnnnnnnnnnnnnnooooooopppppppppppsp\
ppppppppppoooooonnnnnnnnmmmmmmmmmmmmmnnnnnnnnoooooopppppppppp\
ppppppppooooonnnnnnmmmmmmmmmmmmmmmmmmmmmmmnnnnnnooooopppppppp\
ppppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooopppppp\
ppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooopppp\
pppoooonnnnmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmnnnnooooppp\
ppooonnnnmmmmmmmmmmmmnnnnnnooooooonnnnnnmmmmmmmmmmmmnnnnooopp\
pooonnnnmmmmmmmmmmnnnnoooopppppppppoooonnnnmmmmmmmmmmnnnnooop\
ooonnnnmmmmmmmmmnnnooopppqqqqrrrqqqqpppooonnnmmmmmmmmmnnnnooo\
oonnnnmmmmmmmmmnnnooppqqrrsssssssssrrqqppoonnnmmmmmmmmmnnnnoo\
oonnnmmmmmmmmmnnooppqrrssttuuuuuuuttssrrqppoonnmmmmmmmmmnnnoo\
onnnnmmmmmmmmnnoopqqrsstuuvvvvvvvvvuutssrqqpoonnmmmmmmmmnnnno\
onnnmmmmmmmmnnnoppqrsttuvvwwwxxxwwwvvuttsrqpponnnmmmmmmmmnnno\
onnnmmmmmmmmnnoopqrrstuvvwxxxyyyxxxwvvutsrrqpoonnmmmmmmmmnnno\
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\
onnnmmmmmmmmnnoopqqrstuuvwwxxxxxxxwwvuutsrqqpoonnmmmmmmmmnnno\
onnnmmmmmmmmmnnoopqrrstuuvvwwwwwwwvvuutsrrqpoonnmmmmmmmmmnnno\
oonnnmmmmmmmmnnnoppqqrssttuuvvvvvuuttssrqqpponnnmmmmmmmmnnnoo\
oonnnmmmmmmmmmnnnooppqrrssstttttttsssrrqppoonnnmmmmmmmmmnnnoo\
ooonnnmmmmmmmmmmnnoooppqqrrrrrrrrrrrqqppooonnmmmmmmmmmmnnnooo\
oooonnnmmmmmmmmmmnnnnoooppppqqqqqppppooonnnnmmmmmmmmmmnnnoooo\
poooonnnnmmmmmmmmmmmnnnnooooooooooooonnnnmmmmmmmmmmmnnnnoooop\
ppoooonnnnmmmmmmmmmmmmmnnnnnnnnnnnnnnnmmmmmmmmmmmmmnnnnoooopp\
ppppoooonnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnoooopppp\
pppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnooooppppp\
pppppppooooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooooppppppp\
pppppppppooooonnnnnnnmmmmmmmmmmmmmmmmmmmnnnnnnnoooooppppppppp\
pppppppppppooooooonnnnnnnnnnnnnnnnnnnnnnnnnoooooooppppppppppp\
prpppppppppppppoooooooonnnnnnnnnnnnnnnooooooooppppppppppppptp\
pppppppppppppppppppoooooooooooooooooooooooppppppppppppppppppp";
TEST(gyarados, testIdentityDifference) {
unsigned char A[1][32][62];
unsigned char B[1][32][62];
memcpy(A, kDieWelle, sizeof(A));
EzGyarados(1, 32, 61, B, 1, 32, 61, A, 0, 1, 32, 61, 32, 61, 1, 1, 0, 0);
AbsoluteDifference(32, 62, B[0], 32, 62, B[0], 32, 62, A[0]);
EXPECT_STREQ(u"\n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                            \n\
                                                             ",
gc(bingblit(32, 61, B[0], 32, 61)));
}
TEST(gyarados, testHalfYX) {
static unsigned char M[1][32][61];
memcpy(M, kDieWelle, sizeof(M));
EzGyarados(1, 32, 61, M, 1, 32, 61, M, 0, 1, 16, 31, 32, 61, 2, 2, 0, 0);
EXPECT_STREQ(u"\n\
ppppppppoooooooooooooopppppppqp\n\
pppppoonnnmmmmmmmmmmmnnoooppppp\n\
ppponnnmmmmmmmmmmmmmmmmmnnooppp\n\
poonnmmmmmmmmnnnnnmmmmmmmmnnopp\n\
oonnmmmmmnnoppqqppoonnmmmmmnnop\n\
onnmmmmnooqrsttttsrqponmmmmmnno\n\
onmmmmnopqstvwwwwvutrqonmmmmnno\n\
onmmmmnoqrtvwxyyyxwusrpommmmmno\n\
onmmmmnoprtvwxyyyxvusqpnmmmmmno\n\
onmmmmmnpqrtuvwwvutsrponmmmmnno\n\
onnmmmmmnopqrssssrrqoonmmmmmnoo\n\
oonnmmmmmmnnoopppponnmmmmmmnoop\n\
pponnmmmmmmmmmmmmmmmmmmmmnnoopp\n\
pppoonnmmmmmmmmmmmmmmmmnnoopppp\n\
pppppooonnnmmmmmmmmnnnooopppppp\n\
pppppppppooooooooooooppppppppqp",
gc(bingblit(32, 61, M[0], 16, 31)));
}
TEST(gyarados, testHalfY) {
static unsigned char M[1][32][61];
memcpy(M, kDieWelle, sizeof(M));
EzGyarados(1, 32, 61, M, 1, 32, 61, M, 0, 1, 16, 61, 32, 61, 2, 1, 0, 0);
EXPECT_STREQ(u"\n\
popppppppppppppppooooooooooooooooooooooooooopppppppppppppppqp\n\
ppppppppppooononnnnnmmmmmmmmmmmmmmmmmmmmmnnnnnonooopppppppppp\n\
ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\
pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\
poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\
oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\
onnnnmmmmmmmnnnoppqqsttuvvwwwwwwwwwvvuttsqqpponnnmmmmmmmnnnno\n\
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\
oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\
ooonnmmmmmmmmmmmnooooqqqrrrsssssssrrrqqqoooonmmmmmmmmmmmnnooo\n\
pooonnnmmmmmmmmmmmmmnnnnopoopppppooponnnnmmmmmmmmmmmmmnnnooop\n\
ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\
pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\
pppppppppppoooooonnnnnnmmmmmmmmmmmmmmmnnnnnnoooooopppppppppqp\n\
pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp",
gc(bingblit(32, 61, M[0], 16, 61)));
}
TEST(Magikarp2xY, testDecimateY) {
static unsigned char M[1][32][61], G[1][16][61], D[1][16][61];
memcpy(M, kDieWelle, sizeof(M));
EzGyarados(1, 32, 61, G, 1, 32, 61, M, 0, 1, 16, 61, 32, 61, 2, 1, 0, 0);
EXPECT_STREQ(u"\n\
popppppppppppppppooooooooooooooooooooooooooopppppppppppppppqp\n\
ppppppppppooononnnnnmmmmmmmmmmmmmmmmmmmmmnnnnnonooopppppppppp\n\
ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\
pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\
poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\
oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\
onnnnmmmmmmmnnnoppqqsttuvvwwwwwwwwwvvuttsqqpponnnmmmmmmmnnnno\n\
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\
oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\
ooonnmmmmmmmmmmmnooooqqqrrrsssssssrrrqqqoooonmmmmmmmmmmmnnooo\n\
pooonnnmmmmmmmmmmmmmnnnnopoopppppooponnnnmmmmmmmmmmmmmnnnooop\n\
ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\
pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\
pppppppppppoooooonnnnnnmmmmmmmmmmmmmmmnnnnnnoooooopppppppppqp\n\
pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp",
gc(bingblit(16, 61, G[0], 16, 61)));
Magikarp2xY(32, 61, M[0], 32, 61);
AbsoluteDifference(16, 61, D[0], 16, 61, G[0], 16, 61, M[0]);
EXPECT_STREQ(u"\n\
pnpppppppppppppppoooooooooooooooooooooooooooppppppppppppppprp\n\
ppppppppppooooonnnnmmmmmmmmmmmmmmmmmmmmmmmnnnnooooopppppppppp\n\
ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\
pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\
poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\
oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\
onnnnmmmmmmmnnnoppqrsttuvvwwwwwwwwwvvuttsrqpponnnmmmmmmmnnnno\n\
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\
oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\
ooonnmmmmmmmmmmmnoopoqqqrrsssssssssrrqqqopoonmmmmmmmmmmmnnooo\n\
pooonnnmmmmmmmmmmmmmnnnnoooopppppoooonnnnmmmmmmmmmmmmmnnnooop\n\
ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\
pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\
pppppppppppoooooonnnnmmmmmmmmmmmmmmmmmmmnnnnooooooppppppppppp\n\
pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp",
gc(bingblit(16, 61, M[0], 16, 61)));
EXPECT_STREQ(u"\n\
                                                           \n\
                                                         \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                           \n\
                                                             \n\
                                                             \n\
                                                             \n\
                                                         \n\
                                                           \n\
                                                             \n\
                                                             \n\
                                                        \n\
                                                             ",
gc(bingblit(16, 61, D[0], 16, 61)));
}
TEST(Magikarp2xX, testDecimateX) {
static unsigned char M[1][32][61], G[1][32][31], D[32][31];
memcpy(M, kDieWelle, sizeof(M));
EzGyarados(1, 32, 31, G, 1, 32, 61, M, 0, 1, 32, 31, 32, 61, 1, 2, 0, 0);
EXPECT_STREQ(u"\n\
pppppppppoooooooooooooppppppppp\n\
oppppppooonnnnnnnnnnooooppppprp\n\
pppppooonnnnmmmmmmmnnnooopppppp\n\
ppppooonnmmmmmmmmmmmmnnnooppppp\n\
pppoonnmmmmmmmmmmmmmmmmnnnopppp\n\
ppoonnmmmmmmmmmmmmmmmmmmnnooppp\n\
ppoonnmmmmmmmnnnnmmmmmmmmnnoopp\n\
ponnnmmmmmmnnnooonnnmmmmmmnnopp\n\
ponnmmmmmnnooppppoonnmmmmmnnnop\n\
oonnmmmmnoopqqrrqqpoonmmmmmnnoo\n\
onnmmmmmnopqrsssssqponnmmmmnnoo\n\
onmmmmmnopqstuuuutsrqoommmmmnoo\n\
onnmmmmnpqrtuvvvvvtsrponmmmmnno\n\
onmmmmnopqtuvwxxwwutsqonmmmmmno\n\
onmmmmnoqrsvwxyyxxvusqpnmmmmmno\n\
onmmmmnopstvwxyyyxwutronmmmmmno\n\
onmmmmnopstvwxyyyxwtsrpnmmmmmno\n\
onmmmmnoprtuvxxxxwvurqpnmmmmmno\n\
onmmmmmnpqsuvwwwwvutrqonmmmmmno\n\
onmmmmmnoqrstuvvvutrqponmmmmnoo\n\
onmmmmmnnoqrsttttssqponmmmmmnoo\n\
oonmmmmmnooqrrrrrrqpoommmmmmnoo\n\
oonmmmmmmnnoppqqppoonnmmmmmnooo\n\
poonnmmmmmnnoooooonnmmmmmmnnoop\n\
poonnmmmmmmmnnnnnnnmmmmmmnnoopp\n\
ppoonnmmmmmmmmmmmmmmmmmmmnooppp\n\
pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\
ppppoonnmmmmmmmmmmmmmmnnooopppp\n\
pppppoonnnmmmmmmmmmmnnnoooppppp\n\
ppppppooonnnnnnnnnnnnoooopppppp\n\
qpppppppoooonnnnnnnoooopppppprp\n\
ppppppppppooooooooooopppppppppp",
gc(bingblit(32, 31, G[0], 32, 31)));
Magikarp2xX(32, 61, M[0], 32, 61);
EXPECT_STREQ(u"\n\
pppppppppoooooooooooooppppppppp\n\
nppppppooonnnnnnnnnnooooppppprp\n\
pppppooonnnnmmmmmmnnnnooopppppp\n\
ppppooonnnmmmmmmmmmmmnnnooppppp\n\
pppoonnnmmmmmmmmmmmmmmmnnoopppp\n\
ppoonnnmmmmmmmmmmmmmmmmmnnooppp\n\
ppoonnmmmmmmmnnnnnmmmmmmmnnoopp\n\
ponnnmmmmmnnnoooonnnmmmmmmnnopp\n\
ponnmmmmmnnoopppppoonnmmmmnnnop\n\
oonnmmmmnoopqqrrqqpponmmmmmnnoo\n\
onnmmmmmnopqrsssssrqpnnmmmmnnoo\n\
onmmmmmnopqstuuuutsrqoommmmmnoo\n\
onnmmmmnpqrtuvvvvvtsrponmmmmnno\n\
onmmmmnnpqtuvwxxwwutsponmmmmmno\n\
onmmmmnoqrsvwxyyxxvurronmmmmmno\n\
onmmmmnopstvwxyyyxwutronmmmmmno\n\
onmmmmnopssvwxyyyxwtsronmmmmmno\n\
onmmmmnopqtuvxxxxwvurqpnmmmmmno\n\
onmmmmmnorsuvwwwwvutrqonmmmmmno\n\
onmmmmmnoqrstuvvvutrqpnnmmmmnoo\n\
onmmmmmnnoqrsttttssqponmmmmmnoo\n\
oonmmmmmnooqrrrrrrqpoommmmmmnoo\n\
oonmmmmmnnnoppqqqpponnmmmmmnooo\n\
poonnmmmmmnnooooooonnmmmmmnnoop\n\
poonnmmmmmmnnnnnnnnmmmmmmnnoopp\n\
ppoonnmmmmmmmmmmmmmmmmmmnnooppp\n\
pppoonnmmmmmmmmmmmmmmmmnnnooppp\n\
ppppoonnnmmmmmmmmmmmmmnnooopppp\n\
pppppoonnnnmmmmmmmmmnnnoooppppp\n\
ppppppooonnnnnnnnnnnnoooopppppp\n\
qpppppppoooonnnnnnnoooopppppprp\n\
ppppppppppooooooooooopppppppppp",
gc(bingblit(32, 61, M[0], 32, 31)));
AbsoluteDifference(32, 31, D, 32, 31, G[0], 32, 61, M[0]);
EXPECT_STREQ(u"\n\
                               \n\
                              \n\
                              \n\
                              \n\
                             \n\
                              \n\
                              \n\
                             \n\
                            \n\
                              \n\
                            \n\
                               \n\
                               \n\
                             \n\
                            \n\
                               \n\
                             \n\
                              \n\
                             \n\
                              \n\
                               \n\
                               \n\
                            \n\
                             \n\
                              \n\
                              \n\
                              \n\
                              \n\
                              \n\
                               \n\
                               \n\
                               ",
gc(bingblit(32, 31, D, 32, 31)));
}
TEST(magikarp_vs_gyarados, testHalf) {
static unsigned char M[1][32][61], G[1][16][31], D[16][31];
memcpy(M, kDieWelle, sizeof(M));
EzGyarados(1, 16, 31, G, 1, 32, 61, M, 0, 1, 16, 31, 32, 61, 32. / 16.,
61. / 31., 0, 0);
Magikarp2xY(32, 61, M[0], 32, 61);
Magikarp2xX(32, 61, M[0], 16, 61);
AbsoluteDifference(16, 31, D, 16, 32, G[0], 32, 61, M[0]);
EXPECT_STREQ(u"\n\
oppppppppooooooooooooopppppppqp\n\
pppppooonnmmmmmmmmmmmnnoopppppp\n\
ppponnmmmmmmmmmmmmmmmmmmnnnpppp\n\
ppnommmmmmmmmnnnnnmmmmmmmmnoopp\n\
pnnnmmmmmnnoppqqpponnnmmmmmnnop\n\
onnmmmmmopqrstttttsrqpnmmmmnnoo\n\
onnmmmnnpqtuvwwwwwutsponmmmmnno\n\
onmmmmnopstvwxyyyxwutronmmmmmno\n\
onmmmmnopssvwxyyyxwtsronmmmmmno\n\
onmmmmmooqstuvwwwvusrponmmmmnoo\n\
oommmmmmnopqrsssssqqpommmmmmnoo\n\
ponmmmmmmmnnoopppoonnmmmmmmnoop\n\
ppoonmmmmmmmmmmmmmmmmmmmmmonppp\n\
ppppnonmmmmmmmmmmmmmmmmmooopppp\n\
ppppppooonnmmmmmmmmmnnooopppppp\n\
qpppppppppoooooooooooppppppppqp",
gc(bingblit(32, 61, M[0], 16, 31)));
EXPECT_STREQ(u"\n\
ppppppppooooooooooooooopppppppp\n\
pppppoonnnmmmmmmmmmmmnnnooppppp\n\
pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\
poonnmmmmmmmmnnnnnmmmmmmmmnnoop\n\
oonnmmmmmnnoppqqqpponnmmmmmnnoo\n\
onnmmmmnnoqrstttttsrqonnmmmmnno\n\
onmmmmnnpqstuwwwwwutsqpnnmmmmno\n\
onmmmmnoprtuwxyzyxwutrponmmmmno\n\
onmmmmnoprsuwxyyyxwusrponmmmmno\n\
onmmmmmnoqrtuvwwwvutrqonmmmmmno\n\
onnmmmmmnopqrsssssrqponmmmmmnno\n\
oonnmmmmmmnnoopppoonnmmmmmmnnoo\n\
ppoonmmmmmmmmmmmmmmmmmmmmmnoopp\n\
pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\
pppppooonnnmmmmmmmmmnnnoooppppp\n\
pppppppppoooooooooooooppppppppq",
gc(bingblit(16, 31, G[0], 16, 31)));
EXPECT_STREQ(u"\n\
                           \n\
                          \n\
                     \n\
              \n\
    \n\
  \n\
   \n\
    \n\
     \n\
     \n\
     \n\
    \n\
         \n\
      \n\
 \n\
   oooooppppppppqp",
gc(bingblit(16, 31, D, 16, 31)));
}
#define HDX (1920 / 4)
#define HDY (1080 / 4)
#if 0
BENCH(Magikarp, bench) {
unsigned char(*Me)[HDY][HDX] = tgc(tmalloc(HDX * HDY));
unsigned char(*Mo)[HDY][HDX] = tgc(tmalloc(HDX * HDY));
EZBENCH2("Magikarp2xY [even]", donothing,
Magikarp2xY(HDX, HDY, *Me, HDX, HDY));
EZBENCH2("Magikarp2xY [odd]", donothing,
Magikarp2xY(HDX, HDY, *Mo, HDX, HDY));
EZBENCH2("Magikarp2xX [even]", donothing,
Magikarp2xX(HDX, HDY, *Me, HDX, HDY));
EZBENCH2("Magikarp2xX [odd]", donothing,
Magikarp2xX(HDX, HDY, *Mo, HDX, HDY));
}
#endif

57
test/dsp/scale/test.mk Normal file
View file

@ -0,0 +1,57 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_DSP_SCALE
TEST_DSP_SCALE_SRCS := $(wildcard test/dsp/scale/*.c)
TEST_DSP_SCALE_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_SCALE_SRCS))
TEST_DSP_SCALE_COMS = $(TEST_DSP_SCALE_OBJS:%.o=%.com)
TEST_DSP_SCALE_BINS = $(TEST_DSP_SCALE_COMS) $(TEST_DSP_SCALE_COMS:%=%.dbg)
TEST_DSP_SCALE_OBJS = \
$(TEST_DSP_SCALE_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_DSP_SCALE_SRCS:%.c=o/$(MODE)/%.o)
TEST_DSP_SCALE_TESTS = \
$(TEST_DSP_SCALE_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_DSP_SCALE_CHECKS = \
$(TEST_DSP_SCALE_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_DSP_SCALE_DIRECTDEPS = \
DSP_CORE \
DSP_SCALE \
LIBC_TINYMATH \
LIBC_LOG \
LIBC_RUNTIME \
LIBC_FMT \
LIBC_MEM \
LIBC_STDIO \
LIBC_X \
LIBC_RAND \
LIBC_NEXGEN32E \
LIBC_STR \
TOOL_VIZ_LIB \
LIBC_STUBS \
LIBC_TESTLIB
TEST_DSP_SCALE_DEPS := \
$(call uniq,$(foreach x,$(TEST_DSP_SCALE_DIRECTDEPS),$($(x))))
o/$(MODE)/test/dsp/scale/scale.pkg: \
$(TEST_DSP_SCALE_OBJS) \
$(foreach x,$(TEST_DSP_SCALE_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/dsp/scale/%.com.dbg: \
$(TEST_DSP_SCALE_DEPS) \
o/$(MODE)/test/dsp/scale/%.o \
o/$(MODE)/test/dsp/scale/scale.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
.PHONY: o/$(MODE)/test/dsp/scale
o/$(MODE)/test/dsp/scale: \
$(TEST_DSP_SCALE_BINS) \
$(TEST_DSP_SCALE_CHECKS)

7
test/dsp/test.mk Normal file
View file

@ -0,0 +1,7 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
.PHONY: o/$(MODE)/test/dsp
o/$(MODE)/test/dsp: o/$(MODE)/test/dsp/core \
o/$(MODE)/test/dsp/scale \
o/$(MODE)/test/dsp/tty

View file

@ -0,0 +1,65 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/tty/quant.h"
#include "libc/testlib/testlib.h"
struct TtyRgb res;
TEST(rgb2ansi, testDesaturatedPurple_isQuantizedBetterThanEuclideanDistance) {
ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode);
/*
* the challenge to the xterm256 palette is that it was likely
* intended for just syntax highlighting, rather than accurately
* modeling the natural phenomenon of illumination.
*
* as a syntax highlighting palette, it focuses mostly on bright
* saturated colors, while also providing a really good greyscale for
* everything else.
*
* as such, if one were to project the colors of this palette into a
* three-dimensional space, we might see something like an HSV cone,
* where all the color samples are projected mostly around the outside
* of the cone, and the greyscale dots tracing through the middle.
*
* if we want to convert an a real color into an xterm color, we can
* use euclidean distance functions to pick the closest color, such as
* sum of squared distance. however this will only work well if it's
* either a pure grey color, or a bright saturated one.
*
* but euclidean distance doesnt work well for the sorts of colors
* that are generally used for things like film, which conservatively
* edits for the colors more towards the middle of the space; and as
* such, which basically causes the distance function to pick greys
* for almost everything.
*/
res = rgb2tty(0x56, 0x38, 0x66);
/* EXPECT_NE(0x4e, res.r); */
/* EXPECT_NE(0x4e, res.g); */
/* EXPECT_NE(0x4e, res.b); */
/* EXPECT_NE(239, res.xt); */
/* EXPECT_EQ(0x5f, res.r); */
/* EXPECT_EQ(0x00, res.g); */
/* EXPECT_EQ(0x5f, res.b); */
/* EXPECT_EQ(53, res.xt); */
}

View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/tty/rgb2xterm256.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(rgb2xterm256, test) {
EXPECT_EQ(196, rgb2xterm256v2(0xff, 0x00, 0x00)); /* red */
EXPECT_EQ(46, rgb2xterm256v2(0x00, 0xff, 0x00)); /* green */
EXPECT_EQ(21, rgb2xterm256v2(0x00, 0x00, 0xff)); /* blue */
EXPECT_EQ(226, rgb2xterm256v2(0xff, 0xff, 0x00)); /* yellow */
EXPECT_EQ(208, rgb2xterm256v2(0xff, 0x80, 0x00)); /* orange */
}
TEST(rgb2xterm256, testRedBlack) {
EXPECT_EQ(16, rgb2xterm256v2(0, 0, 0));
EXPECT_EQ(16, rgb2xterm256v2(12, 0, 0));
EXPECT_EQ(232, rgb2xterm256v2(13, 0, 0));
EXPECT_EQ(233, rgb2xterm256v2(39, 0, 0));
EXPECT_EQ(233, rgb2xterm256v2(40, 0, 0));
EXPECT_EQ(52, rgb2xterm256v2(53, 0, 0));
EXPECT_EQ(88, rgb2xterm256v2(115, 0, 0));
EXPECT_EQ(88, rgb2xterm256v2(116, 0, 0));
}
////////////////////////////////////////////////////////////////////////////////
BENCH(rgb2xterm256v2, bench) {
EZBENCH(donothing, rgb2xterm256v2(0xff, 0x80, 0x00));
}

51
test/dsp/tty/test.mk Normal file
View file

@ -0,0 +1,51 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_DSP_TTY
TEST_DSP_TTY_SRCS := $(wildcard test/dsp/tty/*.c)
TEST_DSP_TTY_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_TTY_SRCS))
TEST_DSP_TTY_COMS = $(TEST_DSP_TTY_OBJS:%.o=%.com)
TEST_DSP_TTY_BINS = $(TEST_DSP_TTY_COMS) $(TEST_DSP_TTY_COMS:%=%.dbg)
TEST_DSP_TTY_OBJS = \
$(TEST_DSP_TTY_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_DSP_TTY_SRCS:%.c=o/$(MODE)/%.o)
TEST_DSP_TTY_TESTS = \
$(TEST_DSP_TTY_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_DSP_TTY_CHECKS = \
$(TEST_DSP_TTY_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_DSP_TTY_DIRECTDEPS = \
DSP_TTY \
LIBC_TINYMATH \
LIBC_LOG \
LIBC_RUNTIME \
LIBC_RAND \
LIBC_NEXGEN32E \
LIBC_STR \
LIBC_STUBS \
LIBC_TESTLIB
TEST_DSP_TTY_DEPS := \
$(call uniq,$(foreach x,$(TEST_DSP_TTY_DIRECTDEPS),$($(x))))
o/$(MODE)/test/dsp/tty/tty.pkg: \
$(TEST_DSP_TTY_OBJS) \
$(foreach x,$(TEST_DSP_TTY_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/dsp/tty/%.com.dbg: \
$(TEST_DSP_TTY_DEPS) \
o/$(MODE)/test/dsp/tty/%.o \
o/$(MODE)/test/dsp/tty/tty.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
.PHONY: o/$(MODE)/test/dsp/tty
o/$(MODE)/test/dsp/tty: \
$(TEST_DSP_TTY_BINS) \
$(TEST_DSP_TTY_CHECKS)

191
test/dsp/tty/ttymove_test.c Normal file
View file

@ -0,0 +1,191 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/tty/tty.h"
#include "libc/bits/bits.h"
#include "libc/rand/rand.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
char p[16];
struct TtyCursor c;
void SetUp(void) { rngset(p, sizeof(p), rand64, -1); }
TEST(ttymove, sameCoord_doesNothing) {
c.y = 0;
c.x = 0;
EXPECT_EQ(0, ttymove(&c, p, 0, 0) - p);
EXPECT_STREQ("", p);
EXPECT_EQ(0, c.y);
EXPECT_EQ(0, c.x);
}
TEST(ttymove, crlf) {
c.y = 0;
c.x = 10;
EXPECT_EQ(2, ttymove(&c, p, 1, 0) - p);
EXPECT_STREQ("\r\n", p);
EXPECT_EQ(1, c.y);
EXPECT_EQ(0, c.x);
}
TEST(ttymove, cr) {
c.y = 7;
c.x = 10;
EXPECT_EQ(1, ttymove(&c, p, 7, 0) - p);
EXPECT_STREQ("\r", p);
EXPECT_EQ(7, c.y);
EXPECT_EQ(0, c.x);
}
TEST(ttymove, forwardOne) {
c.y = 0;
c.x = 10;
EXPECT_EQ(3, ttymove(&c, p, 0, 11) - p);
EXPECT_STREQ("\e[C", p);
EXPECT_EQ(0, c.y);
EXPECT_EQ(11, c.x);
}
TEST(ttymove, forwardTwo) {
c.y = 0;
c.x = 0;
EXPECT_EQ(4, ttymove(&c, p, 0, 2) - p);
EXPECT_STREQ("\e[2C", p);
EXPECT_EQ(0, c.y);
EXPECT_EQ(2, c.x);
}
TEST(ttymove, forwardHuge_moves255increments) {
c.y = 0;
c.x = 0;
EXPECT_EQ(6 + 3, ttymove(&c, p, 0, 256) - p);
EXPECT_STREQ("\e[255C\e[C", p);
EXPECT_EQ(0, c.y);
EXPECT_EQ(256, c.x);
}
TEST(ttymove, topleft) {
c.y = 1000;
c.x = 888;
EXPECT_EQ(3, ttymove(&c, p, 0, 0) - p);
EXPECT_STREQ("\e[H", p);
EXPECT_EQ(0, c.y);
EXPECT_EQ(0, c.x);
}
#define MOVE(WANT, Y, X) \
EXPECT_EQ(strlen(WANT), ttymove(&c, p, Y, X) - p); \
EXPECT_STREQ(WANT, p); \
EXPECT_EQ(Y, c.y); \
EXPECT_EQ(X, c.x)
TEST(ttymove, absoluteYandX_is1indexed) {
c.y = 1000;
c.x = 888;
MOVE("\e[4;3H", 3, 2);
}
TEST(ttymove, absoluteYandX_implicit1y) {
c.y = 1000;
c.x = 888;
MOVE("\e[;3H", 0, 2);
}
TEST(ttymove, absoluteYandX_implicit1x) {
c.y = 1000;
c.x = 888;
MOVE("\e[4H", 3, 0);
}
TEST(ttymove, up) {
c.y = 70, c.x = 70;
MOVE("\eM", 69, 70);
c.y = 70, c.x = 70;
MOVE("\e[2A", 68, 70);
}
TEST(ttymove, down) {
c.y = 70, c.x = 70;
MOVE("\eD", 71, 70);
c.y = 70, c.x = 70;
MOVE("\e[2B", 72, 70);
}
TEST(ttymove, right) {
c.y = 70, c.x = 70;
MOVE("\e[C", 70, 71);
c.y = 70, c.x = 70;
MOVE("\e[2C", 70, 72);
c.y = 70, c.x = 0;
MOVE("\e[123C", 70, 123);
}
TEST(ttymove, left) {
c.y = 70, c.x = 70;
MOVE("\e[D", 70, 69);
c.y = 70, c.x = 70;
MOVE("\e[2D", 70, 68);
}
/* TEST(ttymove, bench_absmove) { */
/* EZBENCH( */
/* { */
/* c.y = 70; */
/* c.x = 30; */
/* }, */
/* ttymove(&c, p, 7, 9)); */
/* ASSERT_STREQ("\e[8;10H", p); */
/* } */
/* TEST(ttymove, bench_crlf) { */
/* EZBENCH( */
/* { */
/* c.y = 0; */
/* c.x = 10; */
/* }, */
/* ttymove(&c, p, 1, 0)); */
/* ASSERT_STREQ("\r\n", p); */
/* } */
/* TEST(ttymove, bench_forward1) { */
/* EZBENCH( */
/* { */
/* c.y = 0; */
/* c.x = 10; */
/* }, */
/* ttymove(&c, p, 0, 11)); */
/* ASSERT_STREQ("\e[C", p); */
/* } */
/* TEST(ttymove, bench_forward2) { */
/* int y2, x2; */
/* EZBENCH( */
/* { */
/* y2 = rand32() & 127; */
/* x2 = rand32() & 127; */
/* c.y = rand32() & 127; */
/* c.x = rand32() & 127; */
/* }, */
/* ttymove(&c, p, y2, x2)); */
/* int z; */
/* EZBENCH(z = rand32() & 127, _memcpy(&z, "\e[2C", 4)); */
/* } */

View file

@ -0,0 +1,152 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/tty/quant.h"
#include "libc/bits/progn.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "net/http/csscolor.h"
/*TODO(jart): Re-enable me
static const struct TtyRgb kBlack = {0, 0, 0, 16};
static const struct TtyRgb kWhite = {255, 255, 255, 231};
static const struct TtyRgb kRed = {0xff, 0, 0, 196};
char vtbuf[128];
void ttyraster_true_setup(void) {
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
}
void ttyraster2x2_true(void) {
ttyraster(vtbuf,
(const struct TtyRgb *)(unsigned[2][2]){
{DARKRED, GRAY1},
{DARKRED, DARKRED},
},
2, 2, kBlack, kBlack);
}
TEST(ttyraster, testCorner) {
ttyraster_true_setup();
EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝",
PROGN(ttyraster2x2_true(), vtbuf));
}
TEST(ttyraster, testFullBlock_favorsSpace) {
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
ttyraster(vtbuf,
(struct TtyRgb *)(unsigned[2][2]){
{DARKRED, DARKRED},
{DARKRED, DARKRED},
},
2, 2, kBlack, kBlack);
EXPECT_STREQ("\e[48;2;139;0;0m ", vtbuf);
}
TEST(ttyraster, testFullBlock_favorsUnicodeWhenCurrenttFgMatchesButNotBg) {
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
ttyraster(vtbuf,
(struct TtyRgb *)(unsigned[2][4]){
{DARKRED, GRAY1, GRAY1, GRAY1},
{DARKRED, DARKRED, GRAY1, GRAY1},
},
2, 4, kBlack, kBlack);
EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝█", vtbuf);
}
TEST(ttyraster, testFullBlock_forcesSwitchBackToSpaceForRuns) {
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
ttyraster(vtbuf,
(struct TtyRgb *)(unsigned[2][8]){
{DARKRED, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1},
{DARKRED, DARKRED, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1},
},
2, 8, kBlack, kBlack);
EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝█\e[48;2;3;3;3m ", vtbuf);
}
////////////////////////////////////////////////////////////////////////////////
TEST(ttyraster_cp437, testSide) {
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksCp437);
ttyraster(vtbuf,
(const struct TtyRgb *)(unsigned[2][2]){
{DARKRED, GRAY1},
{DARKRED, GRAY1},
},
2, 2, kBlack, kBlack);
EXPECT_STREQ("\e[48;2;3;3;3;38;2;139;0;0m▌", vtbuf);
}
////////////////////////////////////////////////////////////////////////////////
void ttyraster_xterm256_setup(void) {
ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode);
}
void ttyraster2x2_xterm256(void) {
ttyraster(vtbuf,
(const struct TtyRgb *)(struct TtyRgb[2][2]){
{kBlack, kWhite},
{kBlack, kBlack},
},
2, 2, kRed, kRed);
}
TEST(ttyraster_xterm256, testCorner) {
ttyraster_xterm256_setup();
ttyraster2x2_xterm256();
EXPECT_STREQ("\e[48;5;16;38;5;231m▝", vtbuf);
}
void ttyraster6x2_xterm256(void) {
ttyraster(vtbuf,
(const struct TtyRgb *)(struct TtyRgb[2][6]){
{kBlack, kWhite, kBlack, kWhite, kBlack, kWhite},
{kBlack, kBlack, kBlack, kBlack, kBlack, kBlack},
},
2, 6, kRed, kRed);
}
TEST(ttyraster_xterm256, testCornerRepeat3) {
ttyraster_xterm256_setup();
ttyraster6x2_xterm256();
EXPECT_STREQ("\e[48;5;16;38;5;231m▝▝▝", vtbuf);
}
////////////////////////////////////////////////////////////////////////////////
BENCH(ttyraster_true, bench) {
ttyraster_true_setup();
EZBENCH(donothing, ttyraster2x2_true());
}
BENCH(ttyraster_xterm256, bench2) {
ttyraster_xterm256_setup();
EZBENCH(donothing, ttyraster2x2_xterm256());
}
BENCH(ttyraster_xterm256, bench6) {
ttyraster_xterm256_setup();
EZBENCH(donothing, ttyraster6x2_xterm256());
}
*/

130
test/dsp/tty/windex_test.c Normal file
View file

@ -0,0 +1,130 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/tty/windex.h"
#include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
unsigned windex$k8(short *, size_t) hidden;
unsigned windex$avx2(short *, size_t) hidden;
unsigned windex$sse4(short *, size_t) hidden;
const short kW[64] aligned(32) = {
8281, 3883, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33,
1085, 7806, 3248, 1186, 1357, 6738, 1311, 1092, 6195, 7089, 6631,
1261, 1364, 9007, 8289, 1409, 1090, 8358, 1502, 7658, 2668, 3522,
1730, 2041, 7707, 5096, 6876, 1324, 1242, 5283, 0x7fff,
};
const short kW2[32] aligned(32) = {
8281, 1, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915,
};
const short kW3[64] aligned(32) = {
8281, 0x7fff, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33,
1085, 7806, 3248, 1186, 1357, 6738, 1311, 1092, 6195, 7089, 6631,
1261, 1364, 9007, 8289, 1409, 1090, 8358, 1502, 7658, 2668, 3522,
1730, 2041, 7707, 5096, 6876, 1324, 1242, 7, 0x7fff,
};
#define TestIt(impl, index, value, n, array) \
({ \
short *a = memcpy(tgc(tmemalign(32, n * 2)), array, n * 2); \
unsigned res = impl(array, n); \
ASSERT_EQ(index, res); \
ASSERT_EQ(value, a[res]); \
})
TEST(windex, testRealWorldPicks) {
const short kPicks[96] aligned(32) = {
103, 85, 145, 146, 121, 103, 145, 187, 146, 189,
121, 103, 139, 121, 63, 105, 105, 147, 60, 103,
103, 146, 121, 103, 139, 121, 139, 121, 157, 139,
199, 200, 163, 223, 164, 225, 81, 141, 105, 165,
78, 139, 103, 164, 61, 103, 103, 145, 79, 139,
103, 163, 21, 63, 21, 81, 63, 45, 105, 106,
106, 107, 102, 103, 103, 104, 64, 107, 107, 150,
82, 143, 107, 168, 108, 109, 109, 110, 21, 64,
21, 82, 105, 106, 64, 46, 106, 107, 0x7fff, 0x7fff,
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
};
/* multiple valid answers are fine if it's deterministic */
TestIt(windex$k8, 52, 21, ARRAYLEN(kPicks), kPicks);
if (X86_HAVE(AVX2)) TestIt(windex$avx2, 78, 21, ARRAYLEN(kPicks), kPicks);
if (X86_HAVE(SSE4_2)) TestIt(windex$sse4, 80, 21, ARRAYLEN(kPicks), kPicks);
}
TEST(windex, test) {
TestIt(windex, 13, 32, ARRAYLEN(kW), kW);
TestIt(windex, 1, 1, ARRAYLEN(kW2), kW2);
TestIt(windex, 62, 7, ARRAYLEN(kW3), kW3);
}
TEST(windex$avx2, test) {
if (X86_HAVE(AVX2)) {
TestIt(windex$avx2, 13, 32, ARRAYLEN(kW), kW);
TestIt(windex$avx2, 1, 1, ARRAYLEN(kW2), kW2);
TestIt(windex$avx2, 62, 7, ARRAYLEN(kW3), kW3);
}
}
TEST(windex$sse4, test) {
if (X86_HAVE(SSE4_2)) {
TestIt(windex$sse4, 13, 32, ARRAYLEN(kW), kW);
TestIt(windex$sse4, 1, 1, ARRAYLEN(kW2), kW2);
TestIt(windex$sse4, 62, 7, ARRAYLEN(kW3), kW3);
}
}
TEST(windex$k8, test) {
TestIt(windex$k8, 13, 32, ARRAYLEN(kW), kW);
TestIt(windex$k8, 1, 1, ARRAYLEN(kW2), kW2);
TestIt(windex$k8, 62, 7, ARRAYLEN(kW3), kW3);
}
////////////////////////////////////////////////////////////////////////////////
BENCH(windex, bench) {
EZBENCH(donothing, windex(kW, ARRAYLEN(kW)));
}
BENCH(windex$k8, bench) {
EZBENCH(donothing, windex$k8(kW, ARRAYLEN(kW)));
}
BENCH(windex$avx2, bench) {
if (X86_HAVE(AVX2)) {
EZBENCH(donothing, windex$avx2(kW, ARRAYLEN(kW)));
}
}
BENCH(windex$sse4, bench) {
if (X86_HAVE(SSE4_2)) {
EZBENCH(donothing, windex$sse4(kW, ARRAYLEN(kW)));
}
}