Skip to content

Instantly share code, notes, and snippets.

@tjb0607
Last active August 29, 2015 14:20
Show Gist options
  • Save tjb0607/ed27e2743c723c531dc6 to your computer and use it in GitHub Desktop.
Save tjb0607/ed27e2743c723c531dc6 to your computer and use it in GitHub Desktop.
literally no documentation lmao
/*
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
*/
#include <stdio.h>
#include <stdlib.h>
FILE* OpenFile(int argc, char** argv);
int GetHeaders(FILE* fp, int* w, int* h);
char* GetRaw(FILE* fp, int bytes);
int Pad(int num, int bits);
void PutBraille(char* rawBraille, int row, int col, int wchars);
char* BmpToBraille(char* bmp, int w, int h, int wbytes, int bytes, int* wchars, int* hchars);
char* RawToUnicodeBraille(char* rawBraille, int wchars, int hchars);
const char* BRAILLE = "⠀";
int main(int argc, char** argv)
{
FILE* fp = OpenFile(argc, argv);
if (fp == NULL) {
perror("Failed to open stream");
return EXIT_FAILURE;
}
int w = 0,
h = 0,
wbytes = 0,
bytes = 0;
char* bitmap;
if ( !GetHeaders(fp, &w, &h) ) {
fputs("Error: not a valid PBM file!\n", stderr);
return EXIT_FAILURE;
}
wbytes = Pad(w, 8);
bytes = wbytes * h;
if ( (bitmap = GetRaw(fp, bytes)) == NULL ) {
fputs("Error: not a valid PBM file!\n", stderr);
return EXIT_FAILURE;
}
int wchars,
hchars;
char* rawBraille = BmpToBraille(bitmap, w, h, wbytes, bytes, &wchars, &hchars);
char* braille = RawToUnicodeBraille(rawBraille, wchars, hchars);
printf("%s\n", braille);
free(bitmap);
free(rawBraille);
free(braille);
fclose(fp);
return 0;
}
FILE* OpenFile(int argc, char** argv)
{
if (argc == 2) {
return fopen(argv[1], "r");
} else {
return stdin;
}
}
int GetHeaders(FILE* fp, int* w, int* h)
{
int word = 0;
while (word < 3) {
int c = getc(fp);
if (c == EOF) {
return 0;
}
if (c == '#') {
while (c != '\n')
c = getc(fp);
} else if (c == ' ' || c == '\n') {
word++;
} else if (word) {
int* num = word == 1 ? w : h;
*num *= 10;
*num += c - 48;
}
}
return 1;
}
char* GetRaw(FILE* fp, int bytes)
{
char* bitmap = (char*)malloc(bytes);
for (int i = 0; i < bytes; i++) {
int c = getc(fp);
if (c == EOF) {
free(bitmap);
return NULL;
} else {
bitmap[i] = c;
}
}
return bitmap;
}
int Pad(int num, int bits)
{
return (num + bits - 1) / bits;
}
void PutBraille(char* rawBraille, int row, int col, int wchars)
{
int posX = col % 2;
int posY = row % 4;
int pos = 0;
/*
0 3
1 4
2 5
6 7
*/
if (posY != 3) {
pos = posY + 3 * posX;
} else {
pos = 6 + posX;
}
rawBraille[(row / 4) * wchars + (col / 2)] |= 1 << pos;
}
char* BmpToBraille(char* bmp, int w, int h, int wbytes, int bytes, int* wchars, int* hchars)
{
*wchars = Pad(w, 2);
*hchars = Pad(h, 4);
int chars = *wchars * *hchars;
char* rawBraille = (char*)malloc(chars);
for (int i = 0; i < chars; i++) {
rawBraille[i] = 0;
}
for (int bytei = 0; bytei < bytes; bytei++) {
int bytecol = bytei % wbytes;
int row = bytei / wbytes;
for (int bitcol = 0; bitcol < 8; bitcol++) {
if (bmp[bytei] & (char)(1 << bitcol)) {
int col = bytecol * 8 + 7 - bitcol;
PutBraille(rawBraille, row, col, *wchars);
}
}
}
return rawBraille;
}
char* RawToUnicodeBraille(char* rawBraille, int wchars, int hchars)
{
int chars = wchars * hchars;
int destChars = chars * 3 + hchars;
char* braille = (char*)malloc(destChars);
int strIndex = 0;
for (int i = 0; i < chars; i++) {
if ((i % wchars == 0) && i) {
braille[strIndex] = '\n';
strIndex++;
}
braille[strIndex] = BRAILLE[0];
strIndex++;
braille[strIndex] = BRAILLE[1] | ((unsigned char)rawBraille[i] / (1 << 6));
strIndex++;
braille[strIndex] = BRAILLE[2] | ((unsigned char)rawBraille[i] % (1 << 6));
strIndex++;
}
braille[destChars - 1] = '\0';
return braille;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment