From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <2fff89fd0f7b20fc4bb4425940dd77f9@proxima.alt.za> To: 9fans@cse.psu.edu Date: Wed, 19 Apr 2006 06:53:32 +0200 From: lucio@proxima.alt.za MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-hxhtsjutdijprgawxdshpkhhet" Subject: [9fans] libdraw and friends Topicbox-Message-UUID: 3ef3c9d4-ead1-11e9-9d60-3106f5b1d025 This is a multi-part message in MIME format. --upas-hxhtsjutdijprgawxdshpkhhet Content-Disposition: ainline Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable I need a leg-up with my understanding of Plan 9 graphics. Given i =3D 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 =CE=B1 meanings. No matter how I swing that ca= t, 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 =3D allocimage (display, r, outchan, 1, 0)) =3D=3D 0) { sysfatal ("No image"); } if (loadimage (m, m->r, buf, size) < 0) { sysfatal ("Image load failed: %r"); } if ((m2 =3D allocimage (display, r, outchan, 1, 0)) =3D=3D 0) { sysfatal ("No backup image"); } draw (m2, r, display->white, nil, ZP); draw (m2, m2->r, m, nil, m->r.min); image =3D m2; eresized(0); if ((ch =3D ekbd()) =3D=3D 'q' || ch =3D=3D 0x7F || ch =3D=3D 0x04) return; draw (screen, screen->clipr, display->white, nil, ZP); image =3D nil; freeimage (m); Having filled "buf" with the right number of "pixels", created using something along the lines of ch =3D 15; pixel[R] =3D (ch & 0x01) ? 0xFF : 0x00; pixel[G] =3D (ch & 0x02) ? 0xFF : 0x00; pixel[B] =3D (ch & 0x04) ? 0xFF : 0x00; pixel[A] =3D (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 =3D 0, G =3D 1, R =3D 2, A =3D 3, }; unsigned long outchan =3D 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 --upas-hxhtsjutdijprgawxdshpkhhet Content-Disposition: attachment; filename=deep.c Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit #include #include #include #include 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; } --upas-hxhtsjutdijprgawxdshpkhhet--