[comp.sys.amiga.tech] bitmaps with intuition...

hansb@ariel.unm.edu (Hans Bechtel) (06/09/88)

I am confused on how to use bitmaps.

I am familiar with intuition's way of using windows, with default
bitmaps created ready to draw into, but now I need to get access
to the default bitmap pointers so I can save and manipulate the
window.

Questions:

how do I convert planeptrs to window's bitmap to common x,y 
coordinates?

how do I get the correct offsets to the window's bitmaps?

This may all seem easy, but I have read and read the manuals until
the guru finally wins...

Please post the code to do the following:

read a x,y pixel on all bitplanes of a window (not the readpixel way)
write a x,y pixel "      "
get the offsets
etc....

Thanks...

Hans Bechtel
Trust the guru.  The guru is your friend.  

cmcmanis%pepper@Sun.COM (Chuck McManis) (06/11/88)

In article <3170@charon.unm.edu> hansb@ariel.unm.edu.UUCP (Hans Bechtel) writes:
>Questions:
>
>how do I convert planeptrs to window's bitmap to common x,y 
>coordinates?

Bitmaps are *always* an even multiple of 16 bits wide even when the image
they contain or are displaying is not. So the Address of a pixel in the 
plane pointer is y * the width in bytes of the bitmap. The width can be
calculated with the formula :
	ByteWidth = (BitMap->Width + 15)/8;
So the byte containing the pixel of interest is x + y * ByteWidth. The 
actual bit that is the pixel at X,Y is calculated using :
	PixelBit = x % 8;

>how do I get the correct offsets to the window's bitmaps?

Using the two formulas above you can get the bit using this formula
	MyBit = *(BitMap->PlanePtr[n] + ByteWidth*y + x) >> (7 - PixelBit);
This will return a value of one or zero depending on if the pixel has
a bit set in this bitplane.

>This may all seem easy, but I have read and read the manuals until
>the guru finally wins...

>Please post the code to do the following:
>
>read a x,y pixel on all bitplanes of a window (not the readpixel way)

I haven't tried this so take it with a grain of salt but here goes ...

To read a pixel, assuming the following defines and your bitmap is pointed
to by a BitMap structure named BitMap :

#define PIXEL(n,x,y) 	*(BitMap->PlanePtr[n]+ByteWidth*y+x)
#define ThisBit(n,x,y)	PIXEL(n,x,y) >> (7-(x % 8));

Assuming ByteWidth had already been calculated. Use the statement ...
  for (Pixel=0, i=0; i<BitMap->Depth; i++) 
	Pixel += ThisBit(i,x,y) * (1<<i);

to read a pixel.

>write a x,y pixel "      "

Assuming the same defines above, an additional define like the one below
and the value you are writing is already in the variable Pixel ...
#define MoveBit(from,to,byte) (((byte >> (7-from)) & 1) << to)

  for (i=0; i<BitMap->Depth; i++) {
	PIXEL(i,x,y) &= ~(MoveBit(7,(x%8),1)); /* Mask off old value */
 	PIXEL(i,x,y) |= MoveBit(i,(x%8),Pixel); /* Or in new value */
  }

>get the offsets

Offset = ByteWidth*y + x;

>etc....

Have fun ...

--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.

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (06/13/88)

In article <56215@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
>In article <3170@charon.unm.edu> hansb@ariel.unm.edu.UUCP (Hans Bechtel) writes:
>>Questions:
>>
>>how do I convert planeptrs to window's bitmap to common x,y 
>>coordinates?
>
>[ Chuck McManis attempts to help. ]

	Hans specifically said 'window'.  Chuck's dissertation is correct
for screens and BitMap structures.  However, a window is a superset of a
layer, and layers can be anywhere on the screen.  Layers can also be
obscured.  There is severe voodoo involved in figuring out what the status
of a window's position and visibility is.  For an example of what you're
looking at, check out 'DropShadow'.

	What precisely are you trying to accomplish?  You might be able to
fake it with some of the blit calls.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape  ihnp4!pacbell -\
 \_ -_		Recumbent Bikes:	      dual ---> !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Hmm, you're right.  Air is made up of suspended meat loaf."  -- Josh Siegel

blandy@cornell.UUCP (06/15/88)

In article <211@hor-res.UUCP> berry@hor-res.UUCP (No comment) writes:
>this case) x,y pixel value. The planes are stored sequentially in memory.
>Plane 1 first (8K), then plane 2 (8K more) and then plane three. So for
>our example, to display pixel 0,0 you would start at bitmap[0] combine it
>with the pixel 8,000 bytes away at bitmap[8000] and then finally with
>bitmap[16000]. This would get you the Value of the color register that
>will be displayed as the pixel color when the Amiga displays this pixel.

Uh, I may be wrong, but are the bitmaps GUARANTEED to be stored
one after the other in memory???  If you're lucky in allocation, they
might be.   The BitMap structure contains an array of pointers to the
tops of the bitplanes; if b is a BitMap, b.Planes[0] points to the
first bitplane, b.Planes[1] to the second, etc.  I think you'd be
better off using that...

Or am I wrong?
--
Jim Blandy - blandy@crnlcs.bitnet
"insects were insects when man was just a burbling whatsit."  - archie
How necessary ARE disclaimers, anyway?

cmcmanis%pepper@Sun.COM (Chuck McManis) (06/15/88)

In article <6261@well.UUCP> (Leo 'Bols Ewhac' Schwab) writes:
->In article <56215@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
->>[ Chuck McManis attempts to help. ]
->
->	Hans specifically said 'window'.  Chuck's dissertation is correct
->for screens and BitMap structures.  However, a window is a superset of a
->layer, and layers can be anywhere on the screen.  Layers can also be
->obscured.  There is severe voodoo involved in figuring out what the status
->of a window's position and visibility is.  For an example of what you're
->looking at, check out 'DropShadow'.

Well clearly the workaround is to call WindowToFront, wait for it, then
LockIBase and play with the bitmap pointers :-). 

>	What precisely are you trying to accomplish?  
>Leo L. Schwab -- The Guy in The Cape  ihnp4!pacbell -\

The best part of his response was the ultimate question. 

But then Berry chimes in with :
In article <211@hor-res.UUCP> berry@hor-res.UUCP (No comment) writes:
>Given: a 320x200 screen by 3 planes deep.
>Ok now, for each plane in memory there are 320 bits by 200 bits or
>64,000 bits. In bytes that is 8,000. For three planes that's 24,000. ...

This part is correct.

> ...you would start at bitmap[0] combine it with the pixel 8,000 bytes
> away at bitmap[8000] and then finally with bitmap[16000]. This would
> get you the Value of the color register that will be displayed as the
> pixel color when the Amiga displays this pixel.  Whew, a mouthfull
> that was.
>-Steve Berry- ...!bunny!hor-res!berry

This part is terribly flawed. Allocation of bitmap memory goes something
like :
	for (i=0; i<Depth; i++) {
	    bitmap.Planes[i] = (PLANEPTR)AllocMem(RASSIZE(x,y),MEMF_CHIP);
	    if (!bitmap.Planes[i]) barf_on_error("No chip RAM");
	}
Which can allocate the bitmap data areas *anywhere* in chip RAM where there
is room. Using Berry's technique of adding 8000 to the first plane pointer
is *not* reccomended. [Side note the RASSIZE macro is a nice thing and can
be used to determine the number of bytes per line with RASSIZE(x,y)/y .]

The rest of his posting was similar to mine in that it ignored the effects
of layers on where the window contents really were. These techniques do
work on screens an SuperBitmap windows but not on obscured 'regular' 
windows.

--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.

berry@hor-res.UUCP (No comment) (06/17/88)

In article <18336@cornell.UUCP>, blandy@marduk.cs.cornell.edu (Jim Blandy) writes:
> >... The planes are stored sequentially in memory.

> Uh, I may be wrong, but are the bitmaps GUARANTEED to be stored
> one after the other in memory???  If you're lucky in allocation, they

[ some correct stuff deleted ...]
> 
> Or am I wrong?
> --
> Jim Blandy - blandy@crnlcs.bitnet

No your right. I wrong. I think my head got stuck between two rastports
or somthing. Next time I'll get it right.

Anybody know how to make a humble face? :-] no. :-| maybe. :^o Nahh.

Enough of this foolishness. I do need more text though (I have to include
more original material than included stuff or I get trashed)



-- 
-Steve Berry- ...!bunny!hor-res!berry
"Dare to be gorgeous and unique. But don't ever be cryptic or otherwise
Unfathomable. Make it unforgettably great."
Intuition Reference Manual, pg 231.

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (06/18/88)

In article <56628@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
>In article <6261@well.UUCP> (Leo 'Bols Ewhac' Schwab) writes:
>->In article <56215@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
>->>[ Chuck McManis attempts to help. ]
>->
>->	Hans specifically said 'window'.  Chuck's dissertation is correct
>->for screens and BitMap structures.  However, a window is a superset of a
>->layer, and layers can be anywhere on the screen.  Layers can also be
>->obscured.  There is severe voodoo involved in figuring out what the status
>->of a window's position and visibility is.  For an example of what you're
>->looking at, check out 'DropShadow'.
>
>Well clearly the workaround is to call WindowToFront, wait for it, then
>     ^^^^^^^
>LockIBase and play with the bitmap pointers :-). 
>
	Clear as mud :-).

	The BitMap pointer in the Window's Layer structure points to the
master bitmap on which the layers exist, namely, the screen's bitmap.  You
can perform various kinds of r*pe with this pointer if you go to the
layers.library directly, but Intuition does the Natural Thing when dealing
with layers.

	Thus, when you access the bitmap pointed to by the Window's BitMap
pointer, you'll start hitting the screen directly.  Unless the window is
right at the upper left corner of the screen, you won't get what you want.
Hans wants to get at the "virtual bitmap" the window represents.  Short of
using a SUPERBITMAP window, there's no way you can do this easily.  It's
much less painful to go through the graphics.library, as Dale will tell you
:-).

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape  ihnp4!pacbell -\
 \_ -_		Recumbent Bikes:	      dual ---> !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Hmm, you're right.  Air is made up of suspended meat loaf."  -- Josh Siegel

peter@sugar.UUCP (Peter da Silva) (06/18/88)

SUPERBITMAP doesn't solve this, since the SUPERBITMAP isn't always up to
date with the screen image. You would have to make the window a BACKDROP
window and WindowToBack it behind the workbench. That would force the
layers library to update the SUPERBITMAP...

You'd be better off maintaining your own shadow bitmap or use ReadPixel.
-- 
-- `-_-' Peter (have you hugged your wolf today?) da Silva.
--   U   Mail to ...!uunet!sugar!peter, flames to /dev/null.
-- "A foolish consistancy is the hobgoblin of little minds".

dale@boing.UUCP (Dale Luck) (06/18/88)

One way to get right at the bits of a window, indirectly :) is to create
another bitmap and blit from the window to the offscree bitmap.
You will need to allocate your bit, initialize a bitmap, allocate and
initialize a rastport and then call ClipBlit(window->RPort,NewRastPort)
and then you will have all the bits extracted from the different places
of overlapping areas, wherever the window was on the shared screen
assembled in the NewRastPort's bitmap. You can then play with those bits
as you like, when done send them back to the windows RPort. Note that
you need to be careful about the stuff intuition puts in your borders
though.
Dale

-- 
Dale Luck     Boing, Inc.
Although I do contract work for Amiga-LosGatos, my opinions probably
don't represent those of Commodore or its management or its engineers,
but I think the world would be a better place if they did.

carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) (06/25/88)

In article <18336@cornell.UUCP> blandy@marduk (Jim Blandy) writes:
>
>Uh, I may be wrong, but are the bitmaps GUARANTEED to be stored
>one after the other in memory???  If you're lucky in allocation, they
>might be.   The BitMap structure contains an array of pointers to the
>tops of the bitplanes; if b is a BitMap, b.Planes[0] points to the
>first bitplane, b.Planes[1] to the second, etc.  I think you'd be
>better off using that...
>
>Or am I wrong?

You're right.  There is absolutely no guarantee that bitplanes are
right after each other in memory.

You MUST use each plane's bitmap.Planes[] pointer as the base address
of each bitplane.  You can not extrapolate the address of plnae[n]
with a calculation off plane[0].

-- 
==========================================================================
  Carolyn Scheppner -- CATS  Commodore Amiga Technical Support
  PHONE 215-431-9180   UUCP  ...{uunet,allegra,rutgers}!cbmvax!carolyn 

 Signed characters are xenophobic.  
==========================================================================