Pack bitmap bytes into native-endian 32bit int

L

luser- -droog

I'm trying to convert byte-oriented bitmap data into
32bit words matching the endianness of the machine;
And I'm very confused. The crux is the triple for-loop
here.

compile with -I/usr/include/cairo -lcairo
mask.c:

#include <stdint.h>
#include <stdlib.h>

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

int main (int argc, char *argv[])
{
int width = 240;
int height = 230;
Display *dis;
int scr;
int depth;
Visual *vis;
XSetWindowAttributes attr;
unsigned long attrmask;
Window win;
cairo_surface_t *surface;
cairo_t *cr;

dis = XOpenDisplay(NULL);
scr = DefaultScreen(dis);
depth = DefaultDepth(dis, scr);
vis = DefaultVisual(dis, scr);
attr.background_pixel = WhitePixel(dis, scr);
attr.border_pixel = BlackPixel(dis, scr);
attr.event_mask = ExposureMask | StructureNotifyMask |
ButtonPressMask;
attrmask = CWColormap | CWBackPixel | CWBorderPixel | CWEventMask;
win = XCreateWindow(dis, RootWindow(dis, scr),
200, 10, //pos
width, height, 5, //width height border
depth,
InputOutput,
vis,
attrmask, &attr);
XMapWindow(dis, win);
surface = cairo_xlib_surface_create(dis, win, vis, width, height);
cr = cairo_create(surface);
cairo_scale(cr, 10, 10); /* make a big turkey */

cairo_set_source_rgb(cr, 0, 0, 1);

{
unsigned char samp[] = {
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 };
int w = 24, h = 23, stride;
cairo_surface_t *mask;
unsigned char *data;
int i,j,k;
uint32_t u;

stride = cairo_format_stride_for_width(CAIRO_FORMAT_A1, w);
data = malloc(h * stride);

#if 0
/* try to make a vertical line */
u = 16;
for (i = 0; i < h * (stride/4); i++) {
*((unsigned long *)(data + i * stride)) = u;
}
#endif

/* convert bytes to 32bit quantities matching
endianness of the machine */
for (i = 0; i < h; i++) { /* each row */
for (j = 0; j < stride/4; j++) { /* each 32bit int in row
*/
u = 0;
for (k = 0; k < w/8; k++) { /* each 8bit byte in 32bit
int */
u << 8;
u |= samp[i*(w/8) + k];
}
*((uint32_t *)(data + i*stride + j*4)) = u;
}
}

mask = cairo_image_surface_create_for_data(data,
CAIRO_FORMAT_A1, w, h, stride);
cairo_mask_surface(cr, mask, 0, 0);
}

XFlush(dis);

sleep(20);

cairo_destroy(cr);
cairo_surface_destroy(surface);

return 0;
}
 
N

Nobody

I'm trying to convert byte-oriented bitmap data into
32bit words matching the endianness of the machine;
And I'm very confused. The crux is the triple for-loop
here.
for (i = 0; i < h; i++) { /* each row */
for (j = 0; j < stride/4; j++) { /* each 32bit int in row */
u = 0;
for (k = 0; k < w/8; k++) { /* each 8bit byte in 32bit int */

This should be:
for (k = 0; k < 4; k++) {

Otherwise, you're iterating over the columns twice.

But you also need to allow for:

1. any padding at the end of each row (i.e. if w < stride*4).

2. According to the documentation, cairo expects the *bits* to be swapped
based upon the byte order.

For 1, either:

a) use e.g. "if (j*4+k < stride)" around the code which reads the bytes,
or
b) iterate over the bytes rather than the words, then push an extra 0-3
zero bytes into the final word at the end of each row.

For 2, either:

a) change the inner loop to iterate over the individual bits, or
b) create a look-up table to reverse the bits.
 
L

luser- -droog

This should be:


Otherwise, you're iterating over the columns twice.

I tried that, but my sample data only has three bytes
per row.
But you also need to allow for:

1. any padding at the end of each row (i.e. if w < stride*4).

2. According to the documentation, cairo expects the *bits* to be swapped
based upon the byte order.

For 1, either:

a) use e.g. "if (j*4+k < stride)" around the code which reads the bytes,
or
b) iterate over the bytes rather than the words, then push an extra 0-3
zero bytes into the final word at the end of each row.

I think I've got that issue addressed by zeroing the word
first and masking the bytes into it. The padding's already
there.
For 2, either:

a) change the inner loop to iterate over the individual bits, or
b) create a look-up table to reverse the bits.

Thank you so much! Corrected version follows.

/* test program for cairo bit mask
makes a big blue turkey */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

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

enum { little, big } endian = little;

unsigned char invertbits (unsigned char b) {
return ( ((b & 0x01)?1:0) <<7)
| ( ((b & 0x02)?1:0) <<6)
| ( ((b & 0x04)?1:0) <<5)
| ( ((b & 0x08)?1:0) <<4)
| ( ((b & 0x10)?1:0) <<3)
| ( ((b & 0x20)?1:0) <<2)
| ( ((b & 0x40)?1:0) <<1)
| ( ((b & 0x80)?1:0) )
;
}

int main (int argc, char *argv[])
{
int width = 240;
int height = 230;
Display *dis;
int scr;
int depth;
Visual *vis;
XSetWindowAttributes attr;
unsigned long attrmask;
Window win;
cairo_surface_t *surface;
cairo_t *cr;

dis = XOpenDisplay(NULL);
scr = DefaultScreen(dis);
depth = DefaultDepth(dis, scr);
vis = DefaultVisual(dis, scr);
attr.background_pixel = WhitePixel(dis, scr);
attr.border_pixel = BlackPixel(dis, scr);
attr.event_mask = ExposureMask | StructureNotifyMask |
ButtonPressMask;
attrmask = CWColormap | CWBackPixel | CWBorderPixel | CWEventMask;
win = XCreateWindow(dis, RootWindow(dis, scr),
200, 10, //pos
width, height, 5, //width height border
depth,
InputOutput,
vis,
attrmask, &attr);
XMapWindow(dis, win);
surface = cairo_xlib_surface_create(dis, win, vis, width, height);
cr = cairo_create(surface);
cairo_scale(cr, 10, 10);

cairo_set_source_rgb(cr, 0, 0, 1);

{
unsigned char samp[] = {
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 };
int w = 24, h = 23, stride;
cairo_surface_t *mask;
unsigned char *data;
int i,j,k;
uint32_t u;

stride = cairo_format_stride_for_width(CAIRO_FORMAT_A1, w);
printf("stride = %d\n", stride);
data = malloc(h * stride);

/* convert bytes to 32bit quantities matching
endianness of the machine */
/* each row */
for (i = 0; i < h; i++) {
/* each 32bit int in row */
for (j = 0; j < stride/4; j++) {
u = 0;
/* each 8bit byte in 32bit int */
for (k = 0; k < w/8; k++) {
uint8_t b;
if (endian == big) b = samp[i*(w/8) + k];
else b = samp[(i+1)*(w/8) - (k+1)];
u <<= 8;
if (endian == big) u |= b;
else u |= invertbits(b);
//printf("%X\n", u);
}
//printf("%08X\n", u);
*((uint32_t *)(data + i*stride + j*4)) = u;
}
}

mask = cairo_image_surface_create_for_data(data,
CAIRO_FORMAT_A1, w, h, stride);
cairo_mask_surface(cr, mask, 0, 0);
}

XFlush(dis);

sleep(20);

cairo_destroy(cr);
cairo_surface_destroy(surface);

return 0;
}
 
N

Nobody

I tried that, but my sample data only has three bytes per row.

So? However much data you have, there are always 4 8-bit bytes in a
32-bit word.

As I said before:
But you also need to allow for:

1. any padding at the end of each row (i.e. if w < stride*4). ....
For 1, either:

a) use e.g. "if (j*4+k < stride)" around the code which reads the bytes,
or
b) iterate over the bytes rather than the words, then push an extra 0-3
zero bytes into the final word at the end of each row.

Either way, you need to "create" 0-3 extra zero bytes at the end of each
row. If you iterate over the words, the innermost level needs a check to
use the created zeros rather than trying to read non-existent source
bytes. If you iterate over the bytes, you need to "complete" the last word
after the loop.
 
L

luser- -droog

So? However much data you have, there are always 4 8-bit bytes in a
32-bit word.
Yebbut...

As I said before:






Either way, you need to "create" 0-3 extra zero bytes at the end of each
row. If you iterate over the words, the innermost level needs a check to
use the created zeros rather than trying to read non-existent source
bytes. If you iterate over the bytes, you need to "complete" the last word
after the loop.

I think I've got that covered.
I zero the word first and then mask and shift the
bytes into it. The padding is alredy there when I
copy the word into word-packed mask.

uint32_t u;

...

for (j = 0; j < stride/4; j++) {
u = 0;
/* each 8bit byte in 32bit int */
for (k = 0; k < w/8; k++) {
uint8_t b;
if (endian == big) b = samp[i*(w/8) + k];
else b = samp[(i+1)*(w/8) - (k+1)];
u <<= 8;
if (endian == big) u |= b;
else u |= invertbits(b);
//printf("%X\n", u);
}
//printf("%08X\n", u);
*((uint32_t *)(data + i*stride + j*4)) = u;
}
}
 
L

luser- -droog

So? However much data you have, there are always 4 8-bit bytes in a
32-bit word.
Yebbut...



As I said before:
Either way, you need to "create" 0-3 extra zero bytes at the end of each
row. If you iterate over the words, the innermost level needs a check to
use the created zeros rather than trying to read non-existent source
bytes. If you iterate over the bytes, you need to "complete" the last word
after the loop.

I think I've got that covered.
I zero the word first and then mask and shift the
bytes into it. The padding is alredy there when I
copy the word into word-packed mask.

        uint32_t u;

        ...

            for (j = 0; j < stride/4; j++) {
                u = 0;
                /* each 8bit byte in 32bit int */
                for (k = 0; k < w/8; k++) {
                    uint8_t b;
                    if (endian == big) b = samp[i*(w/8) + k];
                    else b = samp[(i+1)*(w/8) - (k+1)];
                    u <<= 8;
                    if (endian == big) u |= b;
                    else u |= invertbits(b);

Sorry, everyone! invertbits should really be called
reversebits. stinky red herring.
 
N

Nobody

for (j = 0; j < stride/4; j++) {
u = 0;
/* each 8bit byte in 32bit int */
for (k = 0; k < w/8; k++) {

You're still doing (stride/4)*(w/8) iterations, which is asymptotically
(w^2)/32 iterations.

This:
for (j = 0; j < stride/4; j++) {

performs one iteration per word. The inner loop should be performed either
4 or 32 times, depending upon whether it processes bits or bytes. As it
processes bytes, it should be performed 4 times. The width of the bitmap
doesn't affect the limit of the inner loop, as it's already affecting the
width of the outer loop (stride will be w/8, rounded up to some multiple
decided according to efficiency constraints).
 
L

luser- -droog

You're still doing (stride/4)*(w/8) iterations, which is asymptotically
(w^2)/32 iterations.

This:


performs one iteration per word. The inner loop should be performed either
4 or 32 times, depending upon whether it processes bits or bytes. As it
processes bytes, it should be performed 4 times. The width of the bitmap
doesn't affect the limit of the inner loop, as it's already affecting the
width of the outer loop (stride will be w/8, rounded up to some multiple
decided according to efficiency constraints).

Either I disagree for the reasons already stated or I still
don't understand for reasons I am unable to enunciate.
 
L

luser- -droog

Either I disagree for the reasons already stated or I still
don't understand for reasons I am unable to enunciate.

I take it back!
Whatever it is you're trying to tell me, you're probably right.
When I doubled the width of the sample, the output is quite wrong.

/* test program for cairo bit mask
makes a big blue turkey */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

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

enum { little, big } endian = little;

unsigned char reversebits (unsigned char b) {
return ( ((b & 0x01)?1:0) <<7)
| ( ((b & 0x02)?1:0) <<6)
| ( ((b & 0x04)?1:0) <<5)
| ( ((b & 0x08)?1:0) <<4)
| ( ((b & 0x10)?1:0) <<3)
| ( ((b & 0x20)?1:0) <<2)
| ( ((b & 0x40)?1:0) <<1)
| ( ((b & 0x80)?1:0) )
;
}

void paintmask(cairo_t *cr, unsigned char *samp, int w, int h) {
int stride;
cairo_surface_t *mask;
unsigned char *data;
int i,j,k;
uint32_t u;

stride = cairo_format_stride_for_width(CAIRO_FORMAT_A1, w);
printf("stride = %d\n", stride);
data = malloc(h * stride);

/* convert bytes to 32bit quantities matching
endianness of the machine */
/* each row */
for (i = 0; i < h; i++) {
/* each 32bit int in row */
for (j = 0; j < stride/4; j++) {
u = 0;
/* each 8bit byte in 32bit int */
for (k = 0; k < w/8; k++) {
uint8_t b;
if (endian == big) b = samp[i*(w/8) + k];
else b = samp[(i+1)*(w/8) - (k+1)];
u <<= 8;
if (endian == big) u |= b;
else u |= reversebits(b);
//printf("%X\n", u);
}
//printf("%08X\n", u);
*((uint32_t *)(data + i*stride + j*4)) = u;
}
}

mask = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_A1,
w, h, stride);
cairo_mask_surface(cr, mask, 0, 0);
}



int main (int argc, char *argv[])
{
int width = 480;
int height = 460;
Display *dis;
int scr;
int depth;
Visual *vis;
XSetWindowAttributes attr;
unsigned long attrmask;
Window win;
cairo_surface_t *surface;
cairo_t *cr;

dis = XOpenDisplay(NULL);
scr = DefaultScreen(dis);
depth = DefaultDepth(dis, scr);
vis = DefaultVisual(dis, scr);
attr.background_pixel = WhitePixel(dis, scr);
attr.border_pixel = BlackPixel(dis, scr);
attr.event_mask = ExposureMask | StructureNotifyMask |
ButtonPressMask;
attrmask = CWColormap | CWBackPixel | CWBorderPixel | CWEventMask;
win = XCreateWindow(dis, RootWindow(dis, scr),
200, 10, //pos
width, height, 5, //width height border
depth,
InputOutput,
vis,
attrmask, &attr);
XMapWindow(dis, win);
surface = cairo_xlib_surface_create(dis, win, vis, width, height);
cr = cairo_create(surface);
cairo_scale(cr, 10, 10);

cairo_set_source_rgb(cr, 0, 0, 1);

{

unsigned char samp[] = {
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 samp2[] = {
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 };

//paintmask(cr, samp, 24, 23);
paintmask(cr, samp2, 48, 23);
XFlush(dis);
}
sleep(20);

cairo_destroy(cr);
cairo_surface_destroy(surface);

return 0;
}
 
L

luser- -droog

Alright. I finally understood what Nobody was saying.
I've reasoned through each line and it *should* work.
But something's still not right!

Since the operation of shifting should automatically
follow the natural endianness, I should always read
the bytes from most- to least-significance, right?

Then all that's necessary is to reverse the byte
before masking IFF it's little-endian, right?


/* test program for cairo bit mask
makes a big blue turkey */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

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

enum { little, big } endian = little;

unsigned char reversebits (unsigned char b) {
return (b & 0x01? 0x80: 0)
| (b & 0x02? 0x40: 0)
| (b & 0x04? 0x20: 0)
| (b & 0x08? 0x10: 0)
| (b & 0x10? 0x08: 0)
| (b & 0x20? 0x04: 0)
| (b & 0x40? 0x02: 0)
| (b & 0x80? 0x01: 0)
;
}

void paintmask(cairo_t *cr, unsigned char *samp, int w, int h) {
int span; /* width in bytes */
int stride; /* width in words */
cairo_surface_t *mask;
unsigned char *data;
int i,j,k;
uint32_t u;

stride = cairo_format_stride_for_width(CAIRO_FORMAT_A1, w);
/* stride = (w/32) + (w%32 ? 1 : 0) */
span = w/8 + (w%8? 1: 0);
printf("stride = %d\n", stride);
data = malloc(h * stride);

/* convert bytes to 32bit quantities matching
endianness of the machine */
/* each row */
for (i = 0; i < h; i++) {

/* each 32bit int in row */
for (j = 0; j < stride/4; j++) {
u = 0; /* zero the word */

/* each 8bit byte in 32bit int from samples */
for (k = 0; k < 4; k++) {
uint8_t b;

u <<= 8;

if (j*4+k < span) {

/* postscript input is always big-endian */
/* so grab most-significant byte */
b = samp[i*span + j*4 + k];

if (endian == little) {
//b = samp[i*span + j*4 + (4-1-k)];
b = reversebits(b);
}

u |= b;
}
//printf("%X\n", u);
} /* k */

printf("%08X\n", u);
*((uint32_t *)(data + i*stride + j)) = u;

} /* j */
} /* i */

mask = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_A1,
w, h, stride);
cairo_mask_surface(cr, mask, 0, 0);
}



int main (int argc, char *argv[])
{
int width = 480;
int height = 460;
Display *dis;
int scr;
int depth;
Visual *vis;
XSetWindowAttributes attr;
unsigned long attrmask;
Window win;
cairo_surface_t *surface;
cairo_t *cr;

dis = XOpenDisplay(NULL);
scr = DefaultScreen(dis);
depth = DefaultDepth(dis, scr);
vis = DefaultVisual(dis, scr);
attr.background_pixel = WhitePixel(dis, scr);
attr.border_pixel = BlackPixel(dis, scr);
attr.event_mask = ExposureMask | StructureNotifyMask |
ButtonPressMask;
attrmask = CWColormap | CWBackPixel | CWBorderPixel | CWEventMask;
win = XCreateWindow(dis, RootWindow(dis, scr),
200, 10, //pos
width, height, 5, //width height border
depth,
InputOutput,
vis,
attrmask, &attr);
XMapWindow(dis, win);
surface = cairo_xlib_surface_create(dis, win, vis, width, height);
cr = cairo_create(surface);
cairo_scale(cr, 10, 10);

cairo_set_source_rgb(cr, 0, 0, 1);

{

unsigned char samp[] = {
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 samp2[] = {
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 };

//paintmask(cr, samp, 24, 23);
paintmask(cr, samp2, 48, 23);
XFlush(dis);
}
sleep(20);

cairo_destroy(cr);
cairo_surface_destroy(surface);

return 0;
}
 
B

Ben Bacarisse

luser- -droog said:
Alright. I finally understood what Nobody was saying.
I've reasoned through each line and it *should* work.
But something's still not right!

Since the operation of shifting should automatically
follow the natural endianness, I should always read
the bytes from most- to least-significance, right?

I can't answer this exactly since your code seems to have a very
different view of endianness to the conventional one. You seem to be
using the term to refer to bit order rather than byte order.

Shifting is defined to be like multiplying by a power of two the answer
seems to be "yes", but if the whole word need to be reversed (because
the bit-order needs to be changed) then reversing the bit in each byte
might not be enough.
Then all that's necessary is to reverse the byte
before masking IFF it's little-endian, right?

That's not a C question and I'm not a Cairo expert. All I can say is
that endianness does not usually refer to bit order but to byte order.
To know the correct transformation, one would need to know the byte and
bit order to Postscript bit masks and the same for the 32-bit Cairo bit
masks that you are building. I think a graphics group would get you
more informed audience.

<snip>
 
L

luser- -droog

I can't answer this exactly since your code seems to have a very
different view of endianness to the conventional one.  You seem to be
using the term to refer to bit order rather than byte order.

Shifting is defined to be like multiplying by a power of two the answer
seems to be "yes", but if the whole word need to be reversed (because
the bit-order needs to be changed) then reversing the bit in each byte
might not be enough.


That's not a C question and I'm not a Cairo expert.  All I can say is
that endianness does not usually refer to bit order but to byte order.
To know the correct transformation, one would need to know the byte and
bit order to Postscript bit masks and the same for the 32-bit Cairo bit
masks that you are building.  I think a graphics group would get you
more informed audience.

<snip>

Thanks. Hopefully, I've lurked on the Cairo list long enough to
hazard the question there.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top