A small tool that creates a textual representation of a PBM file using half and full-height block drawing characters.
#include<stdlib.h>
#include<stdio.h>
#include<wchar.h>
#include<stdint.h>
#include<string.h>
#include<locale.h>
#include<ctype.h>
static const wchar_t full_width_blocks[] = { 0x0020, 0x2580, 0x2584, 0x2588 };
int main(int argc, char **argv)
{
uint64_t width,
,
height;
width_in_bytes
uint8_t *top,
*bottom,
;
white_space
(LC_ALL, "");
setlocale
// Read header.
if (scanf("P4 %d %d%c", &width, &height, &white_space) != 3) {
(
fprintf,
stderr"Unable to read header. "
"Is there a comment in the file? We don't support that, yet.\n"
);
}
if (!isspace(white_space)) {
(
fprintf,
stderr"This almost looks like a netpbm file. "
"But the delimeter was not whitespace?\n"
);
}
// Allocate memory
= (width >> 3) + (width & 7 ? 1 : 0);
width_in_bytes = malloc(width_in_bytes << 1);
top = top + width_in_bytes;
bottom
if (top == NULL) {
(stderr, "Out of memory.\n");
fprintf}
while (height) {
// Read first row.
if (fread(top, width_in_bytes, 1, stdin) != 1) {
(
fprintf,
stderr"Tried to read %d bytes for an even line but failed.\n",
width_in_bytes);
}
if (--height) {
// Read second row
if (fread(bottom, width_in_bytes, 1, stdin) != 1) {
(
fprintf,
stderr"Tried to read %d bytes for an odd line but failed.\n",
width_in_bytes);
}
--height;
} else {
// There are no more rows, blank the bottom row.
(bottom, 0, width_in_bytes);
memset}
// Write the row.
for (uint64_t bit = 0; bit < width; ++bit) {
uint8_t top_byte = top[bit >> 3],
= bottom[bit >> 3],
bottom_byte = 128 >> (bit&7);
mask
(
printf"%lc",
[
full_width_blocks(top_byte & mask ? 1 : 0) |
(bottom_byte & mask ? 2 : 0)
]
);
}
("");
puts}
return 0;
}
This page is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.