ahinds@hvrunix.UUCP (Alexander Hinds) (01/28/88)
I've been trying to read the bit values of a BitMap in a particular plane and store them in an array. I've looked throught the RKM's and haven't found anything too helpful. Can anybody tell me how the bits are stored and how one can read them out of memory? I thank you in advance. Sincerely, Alexander Hinds USENET:ahinds@hvrford BITNET:A_HINDS@HVRFORD
cmcmanis%pepper@Sun.COM (Chuck McManis) (01/29/88)
[ I know it's long, consider it an effort to get the technical stuff back into this newsgroup.] In article <396@hvrunix.UUCP> ahinds@hvrunix.UUCP (Alexander Hinds) writes: > I've been trying to read the bit values of a BitMap in a particular >plane and store them in an array. I've looked throught the RKM's and haven't >found anything too helpful. Can anybody tell me how the bits are stored and >how one can read them out of memory? Bitmaps, being bit plane oriented, are a bit different on the Amiga :-). But they are still pretty easy to get to. The simplest way is to initialize a RastPort to point to a particular BitMap and use ReadPixel(). But since you asked about the organization, here goes ... The BitMap has an array of Planes pointers, there are 8 but the current Amigas only use a maximum of six. Each one is a pointer to a bunch of Unsigned Bytes (UBYTEs). [Important note, even if the image maybe only 17 pixels wide, it needs a integral number of WORDS per line and you have to take this into account when allocating memory and doing calculations on where the bits are in memory.] Each Plane Pointer points to one bitplane of the image in question. So graphically for a 25 X 12 BitMap that is two bits 'Deep' (4 colors) ... 0 0 1 1 2 2 Filler X = 0....5....0....5....0...4 XXXXXX Planes[0] -> 0x10 0x00 0x08 0x00 /* ...*................*........... */ Y = 0 0x18 0x00 0x0c 0x00 /* ...**...............**.......... */ Y = 1 0x14 0x00 0x0e 0x00 /* ...*.*..............***......... */ Y = 2 0x12 0x00 0x0f 0x00 /* ...*..*.............****........ */ Y = 3 0x11 0xff 0xff 0x80 /* ...*...******************....... */ Y = 4 0x11 0xff 0xff 0x80 /* ...*...******************....... */ Y = 5 0x12 0x00 0x0f 0x00 /* ...*..*.............****........ */ Y = 6 0x14 0x00 0x0e 0x00 /* ...*.*..............***......... */ Y = 7 0x18 0x00 0x0c 0x00 /* ...**...............**.......... */ Y = 8 0x10 0x00 0x08 0x00 /* ...*................*........... */ Y = 9 0 0 1 1 2 2 Filler X = 0....5....0....5....0...4 XXXXXX Planes[1] -> 0x10 0x00 0x08 0x00 /* ...*................*........... */ Y = 0 0x18 0x00 0x0c 0x00 /* ...**...............**.......... */ Y = 1 0x1c 0x00 0x0a 0x00 /* ...***..............*.*......... */ Y = 2 0x1e 0x00 0x09 0x00 /* ...****.............*..*........ */ Y = 3 0x1f 0xff 0xf8 0x80 /* ...******************...*....... */ Y = 4 0x1f 0xff 0xf8 0x80 /* ...******************...*....... */ Y = 5 0x1e 0x00 0x09 0x00 /* ...****.............*..*........ */ Y = 6 0x1c 0x00 0x0a 0x00 /* ...***..............*.*......... */ Y = 7 0x18 0x00 0x0c 0x00 /* ...**...............**.......... */ Y = 8 0x10 0x00 0x08 0x00 /* ...*................*........... */ Y = 9 The color register that a given pixel will use can be calculated by taking one bit from each bitplane and assembling them into a byte (remember there could be 8 bitplanes) and using the value of that byte to index into the color map. So in our image above the Pixel at [0,0] has a 0 in bitplane 0 and and a zero in bitplane one, or graphically : Bitplane Number 7 6 5 4 3 2 1 0 -+-+-+-+-+-+-+- Pixel[ 0,0] x x x x x x 0 0 = 0 = ColorMap[0] Pixel[21,2] x x x x x x 0 1 = 1 = ColorMap[1] Pixel[ 4,2] x x x x x x 1 0 = 2 = ColorMap[2] Pixel[10,4] x x x x x x 1 1 = 3 = ColorMap[3] Getting to an individual pixel in memory is a function of calculating where it exists and then adding together all of the bits in question. The three required parameters to find the desired bit are the width of the bitmap and the x and y co-ordinates. You will also need a pointer to each of the bitplanes that make up the image. So some C code to do this the hard way... /* Method for finding the number of UBYTES per line in the bitplane */ #define BytesPerLine(w) (((w + 15) >> 3) & ~1) /* Returns a BYTE offset into the bitplane to find the required byte. */ USHORT Offset(w,x,y) USHORT w,x,y; /* Width, and Pixel co-ordinates */ { return(((x >> 3) % BytesPerLine(w)) + (y * BytesPerLine(w))); } /* Builds a byte with the 'value' of the pixel at x,y */ UBYTE PixelValue(planes,n,w,x,y) UBYTE *planes[]; /* An Array of pointers to the bitplanes */ short n; /* Number of bitplanes 1 < n < 9 */ USHORT w,x,y; /* Width of the bitplane, and pixel coord */ { UBYTE B,T; short i; B = 0; for (i=0; i<n; i++) { /* Fetch the byte, isolate the desired bit, and shift it into Bit 0 */ T = (*(planes[i]+Offset(x,y)) >> (7 - (x % 8))) & 1; /* Add it into the pixel we are building */ B += T << i; } return(B); /* Return it to the Caller. */ } Now, that is the tough way, but it will work. Consider that the BitMap structure has the following definition ... struct BitMap { UWORD BytesPerRow; UWORD Rows; UBYTE Flags; UBYTE Depth; UWORD pad; PLANEPTR Planes[8]; }; You can probably see how the above routines can be coalesed into one smaller routine requiring only a pointer to a BitMap structure and the co-ordinates of the pixel of interest. This is left as an exercise for the reader... :-) --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you.
ahinds@hvrunix.UUCP (Alexander Hinds) (01/31/88)
In article <40367@sun.uucp>, cmcmanis%pepper@Sun.COM (Chuck McManis) writes: > In article <396@hvrunix.UUCP> ahinds@hvrunix.UUCP (Alexander Hinds) writes: > > I've been trying to read the bit values of a BitMap in a particular > >plane and store them in an array. I've looked throught the RKM's and haven't > >found anything too helpful. Can anybody tell me how the bits are stored and > >how one can read them out of memory? > > Bitmaps, being bit plane oriented, are a bit different on the Amiga :-). But > they are still pretty easy to get to. The simplest way is to initialize a > RastPort to point to a particular BitMap and use ReadPixel(). But since you > asked about the organization, here goes .. What I was trying to do was to grab the screen via Gfx->ActiView and store the screen data. I tried to use intuition by initializing a RastPort and setting the BitMap pointer to the one in ActiView->ViewPort->RasInfo->BitMapThen, I tried to use ReadPixel. And, of course, during this, I surrounded this block of code with a Forbid() Permit(). However, the machine crashed on me every time, most of the time with an Adrress Out of Range or an Opcode 1111 error. I couldn't figure out why, so I stopped trying that method. Was I doing something wrong, or overlooking something? Anyway, thanks for your help. I hope I can get it to work this time! Alexander Hinds USENET:ahinds@hvrford BITNET:A_HINDS@HVRFORD