ref: 54d0561599f831b9babc4ca8d847139177fe8f7d
parent: 231b9d446d132a28ef1b7f0f3dd9d2e7a9e53183
author: Sigrid Haflínudóttir <[email protected]>
date: Wed Mar 25 19:34:13 EDT 2020
waveform: 64px-wide version
--- a/waveform/waveform.c
+++ b/waveform/waveform.c
@@ -60,6 +60,29 @@
}
static u64int *
+rotate9064(u64int *b, int h)
+{
+ u64int *p;
+ int i, j;
+ u64int v, i7;
+
+ p = calloc(1, 64*h/8);
+
+ for (i = 0; i < h; i++) {
+ i7 = 1ULL<<(i^7);
+ v = b[i];
+ for (j = 0; j < 64; j++) {
+ if (v & (1ULL<<(j^56)))
+ p[j*h/64 + i/64] |= i7;
+ }
+ }
+ for (i = 0; i < h; i++)
+ p[i] = ~p[i];
+
+ return p;
+}
+
+static u64int *
rotate90128(u64int *b, int h)
{
u64int *p;
@@ -86,6 +109,60 @@
}
static int
+wvimage64(Waveform *w, int offset, Rectangle r, float zoom)
+{
+ float m, i;
+ u64int *b, *p;
+ int x, x2, y, incy, y2;
+
+ offset = MIN(offset, w->nvalid);
+ r = Rect(0, 0, 64, Dx(r));
+ if (badrect(r))
+ return -1;
+ y = (Dy(r)+63) & ~63;
+ b = calloc(1, 64*y);
+ m = MAX(abs(w->min), abs(w->max));
+ m = m > 1.0f ? 31.0f/m : 31.0f;
+
+ for (y = 0, i = offset; y < Dy(r) && i < w->nvalid;) {
+ x = 31 + m*w->samples[(int)i];
+ i += zoom;
+ x2 = i < w->nvalid ? 31 + m*w->samples[(int)i] : x;
+ incy = (x2 + x)/2;
+ y2 = y + 1;
+ do {
+ b[y+1] |= 1ULL<<(x^7);
+ if (x == x2)
+ break;
+ else if (x < x2)
+ x++;
+ else if (x > x2)
+ x--;
+ else if (x == incy)
+ y++;
+ } while (1);
+ y = y2;
+ }
+
+ y = (y+63) & ~63;
+ p = rotate9064(b, y);
+ free(b);
+ r.max.x = y;
+ r.max.y = 64;
+ if (w->image == nil || !eqrect(r, w->image->r)) {
+ freeimage(w->image);
+ if ((w->image = allocimage(display, r, GREY1, 0, DNofill)) == nil)
+ return -1;
+ }
+
+ if (loadimage(w->image, r, (void*)p, 64*y) < 0)
+ fprint(2, "failed: %r\n");
+ free(p);
+
+ return 0;
+}
+
+static int
wvimage128(Waveform *w, int offset, Rectangle r, float zoom)
{
float m, i;
@@ -154,9 +231,9 @@
r = screen->r;
r.min.y += Dy(r)/4;
r.max.y -= Dy(r)/4;
- wvimage128(w, offset, r, zoom);
draw(screen, screen->r, display->white, nil, ZP);
- draw(screen, r, w->image, nil, ZP);
+ if (wvimage64(w, offset, r, zoom) == 0)
+ draw(screen, r, w->image, nil, ZP);
flushimage(display, 1);
unlockdisplay(display);
}