9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] libdraw and friends
@ 2006-04-19  4:53 lucio
  2006-04-19 15:26 ` Russ Cox
  0 siblings, 1 reply; 2+ messages in thread
From: lucio @ 2006-04-19  4:53 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 2424 bytes --]

I need a leg-up with my understanding of Plan 9 graphics.

Given

	i = allocimage (display, r, ARGB32, 1, 0);

and a "pixel" with 0xFFs splattered in the various bytes which I have
multiplicated as the contents of an image buffer, I seem unable to
make sense of its RGB and α meanings.  No matter how I swing that cat,
I can't get an output image that resembles what I would expect.

I know I'm getting indianness and other things confused, so perhaps
someone can point out where I'm going wrong (in fact, even where I'm
going _right_ seems to be a problem).

Here is some code I lifted from /sys/src/cmd/jpg/png.c and adjusted to
experiment with:

	initdraw (0, 0, 0);
	einit (Ekeyboard | Emouse);
	if ((m = allocimage (display, r, outchan, 1, 0)) == 0) {
		sysfatal ("No image");
	}
	if (loadimage (m, m->r, buf, size) < 0) {
		sysfatal ("Image load failed: %r");
	}
	if ((m2 = allocimage (display, r, outchan, 1, 0)) == 0) {
		sysfatal ("No backup image");
	}
	draw (m2, r, display->white, nil, ZP);
	draw (m2, m2->r, m, nil, m->r.min);
	image = m2;
	eresized(0);
	if ((ch = ekbd()) == 'q' || ch == 0x7F || ch == 0x04)
		return;
	draw (screen, screen->clipr, display->white, nil, ZP);
	image = nil;
	freeimage (m);

Having filled "buf" with the right number of "pixels", created using
something along the lines of

		ch = 15;
		pixel[R] = (ch & 0x01) ? 0xFF : 0x00;
		pixel[G] = (ch & 0x02) ? 0xFF : 0x00;
		pixel[B] = (ch & 0x04) ? 0xFF : 0x00;
		pixel[A] = (ch & 0x08) ? 0xFF : 0x00;

by modifying the "ch" value or, when the frustration got too much, the
"0xFF" value, I get white boxes, magenta boxes and cyan boxes.  Never
any othe colours.  Maybe I did get some of the arguments wrong.  but I
don't know which:

	enum {
		B = 0,
		G = 1,
		R = 2,
		A = 3,
	};

	unsigned long outchan = ARGB32;

Can I add anything to the above so someone with a fresh outlook and
better understanding can explain where I'm going wrong?

I actually have a working, improved "png" utility using code similar
to the above (APE with libpng, with a view to dropping the APE bit),
but there are some corner cases (only a few from a large collection of
maybe trivial PNG images) that fail dismally.  One seems to get by
with some shortcomings, but then one gets badly bitten, too.

Just in case, I have attached the full test program, as most recently
used.

++L

[-- Attachment #2: deep.c --]
[-- Type: text/plain, Size: 2463 bytes --]

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

enum {
	B = 0,
	G = 1,
	R = 2,
	A = 3,
};

static Image *image = nil;

enum{
	Border	= 2,
	Edge	= 5
};

void
eresized (int new) {
	Rectangle r;

	if (new && getwindow (display, Refnone) < 0) {
		sysfatal ("png: can't reattach to window");
	}
	if(image == nil)
		return;
	r = insetrect (screen->clipr, Edge + Border);
	r.max.x = r.min.x + Dx (image->r);
	r.max.y = r.min.y + Dy (image->r);
	border (screen, r, -Border, nil, ZP);
	draw (screen, r, image, nil, image->r.min);
	flushimage (display, 1);
}

void
main (int, char **) {
	Rectangle r;
	Image *m, *m2;
	int ch, size;
	char pixel[4];
	unsigned long outchan = ARGB32;
	unsigned char *buf, *bp;

	r.min = Pt (0, 0);
	r.max = Pt (160, 160);

	size = Dx (r) * Dy(r) * sizeof (pixel);
	bp = buf = (unsigned char *) malloc (size);
	ch = -1;
	while (bp < buf + size) {
		// ch = (ch + 1) % 16;
		ch = 15;
		pixel[R] = (ch & 0x01) ? 0x00 : 0x00;
		pixel[G] = (ch & 0x02) ? 0xFF : 0x00;
		pixel[B] = (ch & 0x04) ? 0xFF : 0x00;
		pixel[A] = (ch & 0x08) ? 0xFF : 0x00;
		*((unsigned long *) bp) = *((unsigned long *) pixel);
		bp += sizeof (pixel);
	}
fprint (2, "R: %#02x G: %#02x B: %#02x A: %#02x\n", pixel[R] & 0xFF, pixel[G] & 0xFF, pixel[B] & 0xFF, pixel[A] & 0xFF);
	while (bp < buf + size) {
		*((unsigned long *) bp) = *((unsigned long *) pixel);
		bp += sizeof (pixel);
	}

if (1) {
	initdraw (0, 0, 0);
	einit (Ekeyboard | Emouse);
	if ((m = allocimage (display, r, outchan, 1, 0)) == 0) {
		sysfatal ("No image");
	}
	if (loadimage (m, m->r, buf, size) < 0) {
		sysfatal ("Image load failed: %r");
	}
	if ((m2 = allocimage (display, r, outchan, 1, 0)) == 0) {
		sysfatal ("No backup image");
	}
	draw (m2, r, display->white, nil, ZP);
	draw (m2, m2->r, m, nil, m->r.min);
	image = m2;
	eresized(0);
	if ((ch = ekbd()) == 'q' || ch == 0x7F || ch == 0x04)
		return;
	draw (screen, screen->clipr, display->white, nil, ZP);
	image = nil;
	freeimage (m);
} else {
			char chan[10];
			int row, row_bytes = Dy(r) * sizeof (pixel);
			chantostr ((char *) chan, outchan);
			chan[9] = '\0';
			print ("%11s %11d %11d %11d %11d ", chan, 0, 0, Dx (r), Dy (r));
			bp = buf;
			for (row = 0; row < Dy (r); ++row) {
				if (write (1, bp, row_bytes) != row_bytes) {
					sysfatal ("Write error: %r");
				}
				bp += row_bytes;
			}
}
	return;
}

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-04-19 15:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-19  4:53 [9fans] libdraw and friends lucio
2006-04-19 15:26 ` Russ Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).