6. Generate PBM
6.1. Write Block PBM
An initial PBM generator that writes a block to disk.
<<funcdefs>>=
void kuf_write_block_pbm(const char *filename,
uint16_t w, uint16_t x,
uint16_t y, uint16_t z);
<<funcs>>=
static void print_side(FILE *fp, uint8_t side)
{
fputc((side & 1) ? '1' : '0', fp);
fputc(' ', fp);
fputc((side & 2) ? '1' : '0', fp);
fputc(' ', fp);
}
void kuf_write_block_pbm(const char *filename,
uint16_t w, uint16_t x,
uint16_t y, uint16_t z)
{
FILE *fp;
uint8_t s_a[4];
uint8_t s_b[4];
fp = fopen(filename, "w");
fprintf(fp, "P1\n# kuf block\n8 8\n");
/* print w + x squares */
s_a[0] = kuf_square_quad_get(w, KUF_QUAD_A);
s_a[1] = kuf_square_quad_get(w, KUF_QUAD_B);
s_a[2] = kuf_square_quad_get(w, KUF_QUAD_C);
s_a[3] = kuf_square_quad_get(w, KUF_QUAD_D);
s_b[0] = kuf_square_quad_get(x, KUF_QUAD_A);
s_b[1] = kuf_square_quad_get(x, KUF_QUAD_B);
s_b[2] = kuf_square_quad_get(x, KUF_QUAD_C);
s_b[3] = kuf_square_quad_get(x, KUF_QUAD_D);
/* row 1: W(A,N), W(B, N), X(A, N), X(B, N) */
print_side(fp, kuf_quad_side_get(s_a[0], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_a[1], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[0], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[1], KUF_NORTH));
fprintf(fp, "\n");
/* row 2: W(A,S), W(B, S), X(A, S), X(B, N) */
print_side(fp, kuf_quad_side_get(s_a[0], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_a[1], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[0], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[1], KUF_SOUTH));
fprintf(fp, "\n");
/* row 3: W(C,N), W(D, N), X(C, N), X(D, N) */
print_side(fp, kuf_quad_side_get(s_a[2], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_a[3], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[2], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[3], KUF_NORTH));
fprintf(fp, "\n");
/* row 4: W(C,S), W(D, S), X(C, S), X(D, S) */
print_side(fp, kuf_quad_side_get(s_a[2], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_a[3], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[2], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[3], KUF_SOUTH));
fprintf(fp, "\n");
/* print y + z squares */
s_a[0] = kuf_square_quad_get(y, KUF_QUAD_A);
s_a[1] = kuf_square_quad_get(y, KUF_QUAD_B);
s_a[2] = kuf_square_quad_get(y, KUF_QUAD_C);
s_a[3] = kuf_square_quad_get(y, KUF_QUAD_D);
s_b[0] = kuf_square_quad_get(z, KUF_QUAD_A);
s_b[1] = kuf_square_quad_get(z, KUF_QUAD_B);
s_b[2] = kuf_square_quad_get(z, KUF_QUAD_C);
s_b[3] = kuf_square_quad_get(z, KUF_QUAD_D);
/* row 5: Y(A,N), Y(B, N), Z(A, N), Z(B, N) */
print_side(fp, kuf_quad_side_get(s_a[0], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_a[1], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[0], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[1], KUF_NORTH));
fprintf(fp, "\n");
/* row 6: Y(A,S), Y(B, S), Z(A, S), Z(B, N) */
print_side(fp, kuf_quad_side_get(s_a[0], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_a[1], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[0], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[1], KUF_SOUTH));
fprintf(fp, "\n");
/* row 7: Y(C,N), Y(D, N), Z(C, N), Z(D, N) */
print_side(fp, kuf_quad_side_get(s_a[2], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_a[3], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[2], KUF_NORTH));
print_side(fp, kuf_quad_side_get(s_b[3], KUF_NORTH));
fprintf(fp,"\n");
/* row 8: Y(C,S), Y(D, S), Z(C, S), Z(D, S) */
print_side(fp, kuf_quad_side_get(s_a[2], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_a[3], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[2], KUF_SOUTH));
print_side(fp, kuf_quad_side_get(s_b[3], KUF_SOUTH));
fprintf(fp, "\n");
fclose(fp);
}
6.2. Write PBM
kuf_write_pbm
an NxM array of kufic squares to a PBM file.
This is the more generic pbm writer. n
and m
are the
width and height of the tessellation in units of kufic
squares. squares
expects to be an array of n*m
squares.
The resulting pbm file will have a width of n*4
pixels
and a height of m*4
pixels.
<<funcdefs>>=
void kuf_write_pbm(const char *filename,
int n, int m,
uint16_t *squares);
The PBM file is written one square row at a time. The square row consists of two pixel rows, so the north row is written followed by the southern row.
<<funcs>>=
static void write_row(FILE *fp, uint8_t w)
{
int i;
for (i = 0; i < 4; i++) {
if (i > 0) fprintf(fp, " ");
fprintf(fp, "%d", (w >> i) & 1);
}
}
void kuf_write_pbm(const char *filename,
int n, int m,
uint16_t *squares)
{
int x, y, r;
FILE *fp;
fp = fopen(filename, "w");
fprintf(fp, "P1\n# kuf block\n%d %d\n", n*4, m*4);
for (y = 0; y < m; y++) {
for (r = 0; r < 4; r++) {
for (x = 0; x < n; x++) {
uint8_t w;
uint16_t s;
w = 0;
s = squares[y * n + x];
if (r < 2) {
/* upper quads A + B */
uint8_t a, b;
a = kuf_square_quad_get(s, KUF_QUAD_A);
b = kuf_square_quad_get(s, KUF_QUAD_B);
if (r < 1) {
/* North side A + B */
w = kuf_quad_side_get(b, KUF_NORTH);
w <<= 2;
w |= kuf_quad_side_get(a, KUF_NORTH);
} else {
/* South side A + B */
w = kuf_quad_side_get(b, KUF_SOUTH);
w <<= 2;
w |= kuf_quad_side_get(a, KUF_SOUTH);
}
} else {
/* lower quads C + D */
uint8_t c, d;
c = kuf_square_quad_get(s, KUF_QUAD_C);
d = kuf_square_quad_get(s, KUF_QUAD_D);
if (r <= 2) {
/* North side C + D */
w = kuf_quad_side_get(d, KUF_NORTH);
w <<= 2;
w |= kuf_quad_side_get(c, KUF_NORTH);
} else {
/* South side C + D */
w = kuf_quad_side_get(d, KUF_SOUTH);
w <<= 2;
w |= kuf_quad_side_get(c, KUF_SOUTH);
}
}
write_row(fp, w);
if (x < (n - 1)) fprintf(fp, " ");
}
fprintf(fp, "\n");
}
}
fclose(fp);
}
prev | home | next