[comp.sys.mac.programmer] Off Screen Bit Maps

osborn@ux1 (James R Osborn) (07/19/89)

Hi folks,

I assume that what I have to say here is old hat to most mac
programmers.  However, I have used a piece of code given in
TN 41 for quite awhile without any problems and only recently
did I discover the problem.

The code I am refering to is that which calculates the necessary
rowbytes for your bitmap:

	{make it at least as big as we need}
	OffRowBytes:=((OffRight-OffLeft) div 8) +1;

	{make OffRowBytes even}
	If Odd(OffRowBytes) then
		OffRowBytes:= OffRowBytes -1;

This works great if you have a number ourRowBits which is:

	odd multiple of 8 bits <= ourRowBits <= even multiple of 8 bits

In this range, the row bits that are missed by the integer truncation
(from the division) are counted because of the extra byte needed to make
the row bytes even.

If you are unforunate enough to have a number ourRowBits which is:

	even multiple of 8 bits < ourRowBits < odd multiple of 8 bits

then, not enough bytes are allocated for the last few bits of your image.
I noticed this because things that were being drawn at the right edge of
my bitmap were "overflowing" to the beginning of the next row.


You could just add an extra rowbyte instead of subtracting, but this would
waste memory in certain cases.  Here is how I dealt with it (in C).  I make
no claims as to the efficiency of my code:

	int	numBytes, rowBits;

	rowBits = ourRect.right - ourRect.left;
	numBytes = rowBits / 8;

	if (odd(numBytes))		/* You must write your own odd() */
		numBytes += 1;
	else if (rowBits % 8)		/* % is mod for pascal people */
		numBytes += 2;

Now rowBytes should contain the proper (and even) number of bytes to contain
ourRect.

I hope this does some other people good.  It just goes to show you it's
always something.  Either it's incorrect tech notes or your mac is
smoking.  It's always something.

	|------------------------------|
	| James R. Osborn              |
	| Lawrence Berkeley Laboratory |
	| osborn@ux1.lbl.gov           |
	|------------------------------|

lsr@Apple.COM (Larry Rosenstein) (07/19/89)

In article <3023@helios.ee.lbl.gov> osborn@ux1 (James R Osborn) writes:
> The code I am refering to is that which calculates the necessary
> rowbytes for your bitmap:

The March 1, 1988 version of Tech Note 41 does the calculation as:
       rowBytes := (((right - left) + 15) div 16) * 2;
with the equivalent translation to C.

>         rowBits = ourRect.right - ourRect.left;
>         numBytes = rowBits / 8;
> 
>         if (odd(numBytes))              /* You must write your own odd() 
*/
>                 numBytes += 1;
>         else if (rowBits % 8)           /* % is mod for pascal people */
>                 numBytes += 2;

What if rowBits ends up being 35?  Your code seems to result in numBytes 
== 4, when it should be 6.

Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

zben@umd5.umd.edu (Ben Cranston) (07/20/89)

What's wrong with this?

  deep = (**MyGrafPort.portPixMap).pixelSize;
  rowsize = 2 * ( (15+width*deep) / 16 );
  (**MyGrafPort.portPixMap).rowbytes = 0x8000 | rowsize;

or

  deep = MyGrafPort.portPixMap^^.pixelSize;
  rowsize = ( (width*deep)+15 ) DIV 16 * 2;
  MyGrafPort.portPixMap^^.rowBytes = BitOr(RowSize,$8000);

Admittedly these are Color Quickdraw examples, but how is storage being
wasted if you just do a rounded divide by 16 then halve the result?
-- 
Sig     DS.L    ('ZBen')       ; Ben Cranston <zben@umd2.UMD.EDU>
* Computer Science Center Network Infrastructures Group
* University of Maryland at College Park

matherr@cs.glasgow.ac.uk (Ross M Mather) (11/24/89)

Has anyone ever converted the Apple Sample Source code on 
Offscreen Bitmaps (& Pixmaps) to work with Lightspeed
(or Think) Pascal ?

I Think the code is numbers 15 & 16 but I may be wrong.

Please either post replies or e-mail me.

Thanks
Ross


-- 
* USEnet   :  matherr!glasgow!mcvax!...  |  Senior Honours Comp. Sci. Dept.    *
* ARPAnet  :  matherr@cs.glasgow.ac.uk   |  University Of Glasgow, Scotland.   *
* From USA :  matherr%cs.glasgow.ac.uk@nsfnet-relay.ac.uk                      *
* "It rhymes with Clucking Bell" - Edmund BlackAdder (Episode 6- Blackadder IV)*

craig@pangea.Stanford.EDU (Craig Jarchow) (12/18/90)

Question: How can one use offscreen bit maps that appear and disappear during
a program and avoid heap fragmentation? I notice that 
offScreen.portBits.baseAddr must be a pointer, not a handle. Should I allocate
a handle anyway, and lock and dereference it when I need to draw on the
bit map or CopyBits() from it?

Any wisdom you might have would be appreciated.

        -Craig.

daven@svc.portal.com (12/19/90)

In article <1990Dec17.212129.27971@morrow.stanford.edu> craig@pangea.Stanford.EDU (Craig Jarchow) writes:
> Question: How can one use offscreen bit maps that appear and disappear during
> a program and avoid heap fragmentation? I notice that 
> offScreen.portBits.baseAddr must be a pointer, not a handle. Should I allocate
> a handle anyway, and lock and dereference it when I need to draw on the
> bit map or CopyBits() from it?
> 
> Any wisdom you might have would be appreciated.

Actually, there's a tech note somewhere that says that NewPtr is a kinder
call than IM I says it is. The memory mgr will allocate the non-relocatable
block as low as possible in the heap, even moving relocatable blocks if
necessary. So, if you're not going to be creating and destroying a lot of
bitmaps, NewPtr should be okay to use.

However, your message implied you would be, so using a handle is okay as
long as you remember to a) always lock the handle before derefrencing it,
b) always update the offScreen.portBits.baseAddr field with the recently
dereferenced pointer, c) make certain you always do a & b before any
calls that might manipulate the offscreen bitmap, d) unlock the handle
when you're done with the bitmap for any length of time.


-- 
-------------------------------------------------------------------------------
   Dave Newman              |  daven@svc.portal.com        |  AppleLink: D0025
   Sofware Ventures Corp.   |  AOL: MicroPhone             |  CIS: 76004,2161
   Berkeley, CA  94705      |  WELL: tinman@well.sf.ca.us  |  (415) 644-3232

oster@well.sf.ca.us (David Phillip Oster) (12/19/90)

In article <1990Dec17.212129.27971@morrow.stanford.edu> craig@pangea.Stanford.EDU (Craig Jarchow) writes:
_>Question: How can one use offscreen bit maps that appear and disappear during
_>a program and avoid heap fragmentation? I notice that 
_>offScreen.portBits.baseAddr must be a pointer, not a handle. Should I allocate
_>a handle anyway, and lock and dereference it when I need to draw on the
_>bit map or CopyBits() from it?

Yes, allocate it in a handle, and lock/unlock it while you are drawing/
copybitsing it. Free it the rest of the time. If you need to lock it for a long
time, 	(i.ew., while you want to do many other things) call MoveHHi()
on it before you lock it.

By the way, I've given up calling lock and unlock directly. I find my
programs are weasier to reason anbout if I say:

	SignedByte	state;
	state = HSetLockState(h);
	bits.baseAddr = *h;
	CopyBits(...
	HSetState(h, state);

where HSetLockState is my own routine, which is:
SignedByte	HSetLockState(h)Handle h;{
	SignedByte state;

	state = HGetState(h);
	HLock(h);
	return state;
}

This way, at every point, I can assume that my handles are still locked
if I locked them earlier. It is one less thing to worry about.

-- 
-- David Phillip Oster - At least the government doesn't make death worse.
-- oster@well.sf.ca.us = {backbone}!well!oster

emmayche@dhw68k.cts.com (Mark Hartman) (12/20/90)

In article <1990Dec17.212129.27971@morrow.stanford.edu> craig@pangea.Stanford.EDU (Craig Jarchow) writes:
>Question: How can one use offscreen bit maps that appear and disappear during
>a program and avoid heap fragmentation? I notice that 
>offScreen.portBits.baseAddr must be a pointer, not a handle. Should I allocate
>a handle anyway, and lock and dereference it when I need to draw on the
>bit map or CopyBits() from it?

Precisely.

-- 
Mark Hartman, N6BMO           "What are you just standing there for?  Where
Applelink: N1083 or BINARY.TREE      do you think you are, DIS-ney World??"
Internet: emmayche@dhw68k.cts.com                -- General Knowledge, from
uucp: ...{spsd,zardoz,felix}!dhw68k!emmayche                CRANIUM COMMAND