Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

imagemask revisited

7 views
Skip to first unread message

luser- -droog

unread,
Mar 8, 2011, 6:34:37 AM3/8/11
to
Here's my new prototype to translate between postscript's
byte-oriented bitmap and cairo's uint32-oriented bitmap.
I don't have a big-endian machine to test on, but the
debugging data looks correct to me.

Now the challenge is to patch this into the interpreter,
so it calls a new instance of the interpreter to fetch
string data.

689(1)05:25 AM:proto 0> !m
make mask CFLAGS=-I/usr/include/cairo LDLIBS='-lX11 -lcairo' && mask
cc -I/usr/include/cairo mask.c -lX11 -lcairo -o mask
690(1)05:25 AM:proto 0> !v
vi mask.c
691(1)05:26 AM:proto 0> cat mask.c

enum { DEBUG = 0, WID = 24, HGT = 23, SCALE = 18 };
enum { BIG, LITTLE } endian = LITTLE;
unsigned char bsamp[(WID*HGT)/8] = {
0x00, 0x3B, 0x00, 0x00, 0x27, 0x00, 0x00, 0x24, 0x80, 0x0E, 0x49,
0x40, 0x11, 0x49, 0x20,
0x14, 0xB2, 0x20, 0x3C, 0xB6, 0x50, 0x75, 0xFE, 0x88, 0x17, 0xFF,
0x8C, 0x17, 0x5F, 0x14,
0x1C, 0x07, 0xE2, 0x38, 0x03, 0xC4, 0x70, 0x31, 0x82, 0xF8, 0xED,
0xFC, 0xB2, 0xBB, 0xC2,
0xBB, 0x6F, 0x84, 0x31, 0xBF, 0xC2, 0x18, 0xEA, 0x3C, 0x0E, 0x3E,
0x00, 0x07, 0xFC, 0x00,
0x03, 0xF8, 0x00, 0x1E, 0x18, 0x00, 0x1F, 0xF8, 0x00,
};

unsigned char csamp[(2*2*WID*HGT)/8] = {
0x00, 0x3B, 0x00, 0x00, 0x3B, 0x00,
0x00, 0x27, 0x00, 0x00, 0x27, 0x00,
0x00, 0x24, 0x80, 0x00, 0x24, 0x80,
0x0E, 0x49, 0x40, 0x0E, 0x49, 0x40,
0x11, 0x49, 0x20, 0x11, 0x49, 0x20,
0x14, 0xB2, 0x20, 0x14, 0xB2, 0x20,
0x3C, 0xB6, 0x50, 0x3C, 0xB6, 0x50,
0x75, 0xFE, 0x88, 0x75, 0xFE, 0x88,
0x17, 0xFF, 0x8C, 0x17, 0xFF, 0x8C,
0x17, 0x5F, 0x14, 0x17, 0x5F, 0x14,
0x1C, 0x07, 0xE2, 0x1C, 0x07, 0xE2,
0x38, 0x03, 0xC4, 0x38, 0x03, 0xC4,
0x70, 0x31, 0x82, 0x70, 0x31, 0x82,
0xF8, 0xED, 0xFC, 0xF8, 0xED, 0xFC,
0xB2, 0xBB, 0xC2, 0xB2, 0xBB, 0xC2,
0xBB, 0x6F, 0x84, 0xBB, 0x6F, 0x84,
0x31, 0xBF, 0xC2, 0x31, 0xBF, 0xC2,
0x18, 0xEA, 0x3C, 0x18, 0xEA, 0x3C,
0x0E, 0x3E, 0x00, 0x0E, 0x3E, 0x00,
0x07, 0xFC, 0x00, 0x07, 0xFC, 0x00,
0x03, 0xF8, 0x00, 0x03, 0xF8, 0x00,
0x1E, 0x18, 0x00, 0x1E, 0x18, 0x00,
0x1F, 0xF8, 0x00, 0x1F, 0xF8, 0x00,
0x00, 0x3B, 0x00, 0x00, 0x3B, 0x00,
0x00, 0x27, 0x00, 0x00, 0x27, 0x00,
0x00, 0x24, 0x80, 0x00, 0x24, 0x80,
0x0E, 0x49, 0x40, 0x0E, 0x49, 0x40,
0x11, 0x49, 0x20, 0x11, 0x49, 0x20,
0x14, 0xB2, 0x20, 0x14, 0xB2, 0x20,
0x3C, 0xB6, 0x50, 0x3C, 0xB6, 0x50,
0x75, 0xFE, 0x88, 0x75, 0xFE, 0x88,
0x17, 0xFF, 0x8C, 0x17, 0xFF, 0x8C,
0x17, 0x5F, 0x14, 0x17, 0x5F, 0x14,
0x1C, 0x07, 0xE2, 0x1C, 0x07, 0xE2,
0x38, 0x03, 0xC4, 0x38, 0x03, 0xC4,
0x70, 0x31, 0x82, 0x70, 0x31, 0x82,
0xF8, 0xED, 0xFC, 0xF8, 0xED, 0xFC,
0xB2, 0xBB, 0xC2, 0xB2, 0xBB, 0xC2,
0xBB, 0x6F, 0x84, 0xBB, 0x6F, 0x84,
0x31, 0xBF, 0xC2, 0x31, 0xBF, 0xC2,
0x18, 0xEA, 0x3C, 0x18, 0xEA, 0x3C,
0x0E, 0x3E, 0x00, 0x0E, 0x3E, 0x00,
0x07, 0xFC, 0x00, 0x07, 0xFC, 0x00,
0x03, 0xF8, 0x00, 0x03, 0xF8, 0x00,
0x1E, 0x18, 0x00, 0x1E, 0x18, 0x00,
0x1F, 0xF8, 0x00, 0x1F, 0xF8, 0x00,
};

#include <cairo.h>
#include <X11/Xlib.h>
#include <cairo-xlib.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

struct state {
int width, height;
Display *dis;
int scr, depth;
Visual *vis;
XSetWindowAttributes attr;
int attrmask;
Window win;

cairo_t *cr;
cairo_surface_t *surface;
} sta;


inline unsigned char reverse(unsigned char b) {
return (b&1 ? 0x80: 0)
| (b&2 ? 0x40: 0)
| (b&4 ? 0x20: 0)
| (b&8 ? 0x10: 0)
| (b&0x10 ? 8: 0)
| (b&0x20 ? 4: 0)
| (b&0x40 ? 2: 0)
| (b&0x80 ? 1: 0);
}

inline unsigned long wreverse(unsigned long w) {
return ( (w&0xFF) << 24)
| ( ((w>>8)&0xFF) << 16)
| ( ((w>>16)&0xFF) << 8)
| ( ((w>>24)&0xFF) );
}

int drawmask(struct state *st, int wid, int hgt, unsigned char *bsamp)
{
int stride;
stride = cairo_format_stride_for_width(CAIRO_FORMAT_A1, wid);
unsigned char *data;
data = calloc(stride*hgt, 1);

int x,y;
int wb = wid/8 + (wid%8?1:0);
unsigned long samp, *ldata = (void *)data;
for (y=0; y < hgt; y++) {
samp = 0; if (DEBUG) putchar('0');
for (x=0; x < wb; x++) { /* bytes in row */
if ( !(x%4) && x) { /* filled a word */
if (endian == LITTLE) samp = wreverse(samp);
if (DEBUG) printf(" 1[%d]%08lX ", y*stride/4+x/4 - 1,
samp);
ldata[y*stride/4 + x/4 - 1] = samp; samp = 0; if
(DEBUG) putchar('0'); }

samp <<= 8; if (DEBUG) putchar('<');
if (endian == LITTLE) {
samp |= reverse(bsamp[y*wb + x]); if (DEBUG)
putchar('|');
} else {
samp |= bsamp[y*wb + x]; if (DEBUG) putchar('|');
}
}

for ( ; x < stride; x++) { /* no more samples in row, pad to
stride */
samp <<= 8; if (DEBUG) putchar('<');
/* if ( !(x%4) && x) {
if (endian == LITTLE) samp = wreverse(samp);
printf(" 2[%d]%08lX", y*stride/4+x/4 - 1, samp);
ldata[y*stride/4 + x/4 - 1] = samp; samp = 0;
putchar('0'); } */
}
if ( !(x%4) && x) { /* filled a word */
if (endian == LITTLE) samp = wreverse(samp);
if (DEBUG) printf(" 3[%d]%08lX ", y*stride/4+x/4 - 1,
samp);
ldata[y*stride/4 + x/4 - 1] = samp; samp = 0; if (DEBUG)
putchar('0'); }
if (DEBUG) puts("");
}

if (DEBUG) for (y=0; y < hgt; y++) { /* double check */
for (x=0; x < stride/4; x++) {
printf("%08lX ", ldata[y*stride/4 + x]);
}
puts("");
}

cairo_surface_t *surf;
surf = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_A1,
wid, hgt, stride);
cairo_set_source_rgb(st->cr, 0, 0, 0);
cairo_scale(st->cr, SCALE, SCALE);
cairo_mask_surface(st->cr, surf, 0, 0);
cairo_surface_flush(st->surface);
XFlush(st->dis);
}

int wopen(struct state *st, int wid, int hgt) {

st->width = wid * SCALE;
st->height = hgt * SCALE;

st->dis = XOpenDisplay(NULL);
st->scr = DefaultScreen(st->dis);
st->depth = DefaultDepth(st->dis, st->scr);
st->vis = DefaultVisual(st->dis, st->scr);

st->attr.background_pixel = WhitePixel(st->dis, st->scr);
st->attr.border_pixel = BlackPixel(st->dis, st->scr);
st->attr.event_mask = ExposureMask | StructureNotifyMask |
ButtonPressMask;
st->attrmask = CWColormap | CWBackPixel | CWBorderPixel |
CWEventMask;

st->win = XCreateWindow(st->dis, RootWindow(st->dis, st->scr),
200, 10, /* pos */
st->width, st->height, 5, /* width height border */
st->depth,
InputOutput,
st->vis,
st->attrmask, &st->attr);
XMapWindow(st->dis, st->win);

st->surface = cairo_xlib_surface_create(st->dis, st->win,
st->vis, st->width, st->height);
st->cr = cairo_create(st->surface);
}

int main(void) {
//wopen(&sta,WID,HGT);
//drawmask(&sta,WID,HGT,bsamp);
wopen(&sta,2*WID,2*HGT);
drawmask(&sta,2*WID,2*HGT,csamp);
sleep(10);
}

0 new messages