Created
August 22, 2012 17:12
-
-
Save ekovac/3427632 to your computer and use it in GitHub Desktop.
Tool to create an ESC/P custom character stream from a monochrome image to enable graphical printing on some printers which fail to do so using the CUPS ESC/P driver.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <pam.h> | |
#define CELL_HEIGHT 8 | |
#define CELL_WIDTH 11 | |
typedef struct | |
{ | |
char* c; | |
int width; | |
int height; | |
} raw_image; | |
typedef struct | |
{ | |
unsigned char cell_bytes[CELL_WIDTH]; | |
} cell; | |
typedef struct | |
{ | |
cell* cells; | |
int width; | |
int height; | |
} image; | |
image cellify_image(raw_image raw) | |
{ | |
image img; | |
int ceil,x,y,subx, suby; | |
unsigned char imgbyte; | |
unsigned char tmpbyte; | |
size_t cell_location, global_location, tmp_location; | |
ceil = raw.width % CELL_WIDTH ? 1 : 0; | |
img.width = raw.width/CELL_WIDTH+ceil; | |
ceil = raw.height % CELL_HEIGHT ? 1 : 0; | |
img.height = raw.height/CELL_HEIGHT+ceil; | |
img.cells = malloc(img.height*img.width*sizeof(cell)); | |
for (y = 0; y < img.height; y++) | |
{ | |
for (x=0; x < img.width; x++) | |
{ | |
cell_location = (size_t)(y*img.width+x); | |
global_location = (size_t)(y*CELL_HEIGHT*raw.width+CELL_WIDTH*x); | |
for (subx = 0; subx < CELL_WIDTH; subx++) | |
{ | |
imgbyte = 0x00; | |
for (suby = CELL_HEIGHT - 1; suby > -1; suby--) | |
{ | |
if (((suby+CELL_HEIGHT*y) >= raw.height)|| | |
((subx+CELL_WIDTH*x) >= raw.width)) | |
continue; | |
tmp_location = global_location +suby*raw.width+subx; | |
if (raw.c[tmp_location] == 0) imgbyte = imgbyte | (1 << (7-suby)); | |
} | |
img.cells[cell_location].cell_bytes[subx] = imgbyte; | |
fprintf(stderr, "%x\n", imgbyte); | |
} | |
} | |
} | |
fprintf(stderr, "Cells %dx%d\n", img.width, img.height); | |
return img; | |
} | |
void printreset() | |
{ | |
static unsigned char resetbytes[2] = {0x1b, 0x40}; | |
fwrite(resetbytes, 2, 1, stdout); | |
} | |
void println() | |
{ | |
static unsigned char newline[4] = { 0x1b, 0x41, 0x08, 0x0a }; | |
fwrite(newline, 4, 1, stdout); | |
return; | |
} | |
void printcell(cell c) | |
{ | |
int i; | |
unsigned char defineandprint[21] = | |
{ | |
0x1b, 0x26, 0x00, 0x41, 0x41, 0x0b, /* Begin define */ | |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* char data */ | |
0x1b, 0x25, 0x01, /* switch to user-defined */ | |
0x41, }; /* printing the defined character */ | |
for (i = 0; i < CELL_WIDTH; i++) | |
{ | |
defineandprint[6+i] = c.cell_bytes[i]; | |
} | |
fwrite(defineandprint, 21, 1, stdout); | |
return; | |
} | |
void printimage(image img) | |
{ | |
int x, y; | |
printreset(); | |
for (y=0; y < img.height; y++) | |
{ | |
for (x=0; x < img.width; x++) | |
{ | |
printcell(img.cells[y*img.width+x]); | |
} | |
println(); | |
} | |
printreset(); | |
} | |
raw_image parse_image_to_array(FILE* f) | |
{ | |
struct pam inpam, outpam; | |
tuple* tuplerow; | |
unsigned int row, column; | |
int x,y; | |
pm_init("./a.out", 0); | |
pnm_readpaminit(f, &inpam, PAM_PGM_TUPLETYPE); | |
tuplerow = pnm_allocpamrow(&inpam); | |
raw_image img; | |
img.c = (char*)malloc(inpam.height*inpam.width*sizeof(char)); | |
for (y = 0; y < inpam.height; y++) | |
{ | |
pnm_readpamrow(&inpam, tuplerow); | |
for (x = 0; x < inpam.width; x++) | |
{ | |
img.c[y*inpam.width+x] = tuplerow[x][0]; | |
// fprintf(stderr, "%x\n", tuplerow[x][0]); | |
} | |
} | |
img.height = inpam.height; | |
img.width = inpam.width; | |
fprintf(stderr, "Raw %dx%d\n", img.width, img.height); | |
fflush(stderr); | |
return img; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
FILE* f = NULL; | |
int width; | |
char* image; | |
if (argc != 2) | |
{ | |
fprintf(stderr, "You need to pass a file as an argument.\n"); | |
return 1; | |
} | |
f = fopen(argv[1], "r"); | |
if (f == NULL) | |
{ | |
fprintf(stderr, "It broke.\n"); | |
} | |
printimage(cellify_image(parse_image_to_array(f))); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment