[comp.sys.mac.programmer] COPYBITS

jurjen@cwi.nl (Jurjen N.E. Bos) (05/22/89)

Hi,
I have an offscreen bitmap of size about 300*500.  At an update event, this
whole stuff needs to be dumped on screen.
This seems easy--one CopyBits call does the trick.
But then I read in IM that is is considered to be bad practice to copy large
bitmaps (>3K), because they use up stack space as large as the bitmap.

The question is: is this still true in the following case:
no overlap between source and destination, no reduction, no mask region.

It would save me a lot of dirty code if I could still do it with a single call.
Help, anyone?

-- 
|                 | "Never image yourself not to be otherwise than what |
| Jurjen N.E. Bos | it might appear to others that what you were or     |
|                 | might have been was not otherwise than what you had |
|  jurjen@cwi.nl  | been would have appeared to them to be otherwise."  |

tim@hoptoad.uucp (Tim Maroney) (05/24/89)

In article <8134@boring.cwi.nl> jurjen@cwi.nl (Jurjen N.E. Bos) writes:
>I have an offscreen bitmap of size about 300*500.  At an update event, this
>whole stuff needs to be dumped on screen.
>This seems easy--one CopyBits call does the trick.
>But then I read in IM that is is considered to be bad practice to copy large
>bitmaps (>3K), because they use up stack space as large as the bitmap.
>
>The question is: is this still true in the following case:
>no overlap between source and destination, no reduction, no mask region.

I don't know; perhaps one of the kind people from Apple could let us
know.  It is possible this problem was fixed in the MacPlus ROMs.  I've
done CopyBits larger than the stack space on 128K ROMs and up and not
had a problem; never tried it on the 64K ROMs.  I was copying an entire
MacPaint file bitmap, so it should have cut a deep swath in my
application heap if things were still as described in IMvI.

>It would save me a lot of dirty code if I could still do it with a single call.
>Help, anyone?

I finally decided I was playing with fire by doing these large
CopyBits's, so I wrote a row-by-row copy routine that seems to run fast
enough.  It would be more efficient to compute how many rows would fit
in 3K, but there really didn't seem to be a speed problem with doing
things a row at a time, so I didn't bother.

void
CopyRows(in, out, inBounds, outBounds, mode, mask)
BitMap *in, *out;
Rect *inBounds, *outBounds;
short mode;
RgnHandle mask;
{
	short i = 0, rows = inBounds->bottom - inBounds->top;
	Rect ir, or;
	while (i < rows) {
		ir = *inBounds, or = *outBounds;
		ir.top += i; ir.bottom = ir.top + 1;
		or.top += i; or.bottom = or.top + 1;
		CopyBits(in, out, &ir, &or, mode, mask);
		i++;
	}
}
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"What's the ugliest part of your body?
 Some say your nose, some say your toes,
 But I think it's your mind."
-- Frank Zappa

allenb@cs.uoregon.edu (Allen F. Brookes) (08/23/90)

Does anyone know how copybits really works?  I thought I knew but in certain
situations it does not behave the way I think it should.  My understanding is
that it gets the rgb value from the clut of the source pixmap, looks up the
corresponding index in the current device inverse table and then deposits
the value in the destination pixmap.  This is the way it behaves when I am
copying from the screen to an offscreen pixmap.  When I copy the same image
from the offscreen pixmap to a window on another device it seems to copy
without the color translation.  It seems as though the pixel values are
transfered directly without the index -> rgb -> index translation.  The
only other possibility I can think of is that it is using the devices clut
instead of the clut for the source pixmap.

Another weird behavior is that when I copybits from the screen to the offscreen
pixmap and back it works fine.  However, when I copy from the screen to a
window on another device it uses the other device as the source too.  The
base addr of my window is the same as the other device but in all other cases
it uses the correct window.

If anyone can help me understand what is happening I would appreciate it.

Thanks,

Allen

crunch@well.sf.ca.us (John Draper) (11/22/90)

Does anyone know if it is possible to CopyBits from one off screen
Pixmap to another one??   So far,  nothing I have done has worked.

I made sure the bounds to both are set the same,  and the allocated
memory for both are identical,  but they have different buffers.

The reason for this is so I can do scaling of the PixMaps.   In this
case,  I want to scale the picture to a SMALLER size.   So I set the
following values.

SetRect(&srcRect,  0, 0, 108, 128);	/* Origional size		*/
SetRect(&destrect, 0, 0,  75, 100);	/* Want scaled down to this size*/

I tried the following:

srcPix is the source PixMap.   destPix is the one I want to scale down 
into.

   destMap = NewPixMap();  		/* To create a new Pixmap 	*/
   CopyPixMap(srcPix, destMap);		/* To clone Ctab and other stuff*/
   
Before I copyBits, I want to allocate a buffer size at least the same size 
as the source buffer.   I get this from RowBytes after masking off the hi bit
of course.

   /*-------------------------------------------------------*/
   /* I calculate the width using the recommended formula   */
   /* width is the scaled down width			    */
   /*-------------------------------------------------------*/
   xwidth = (((width * (**aPix).pixelSize) + 15) >> 4) << 1;
   srcBnds = (**srcPix).bounds;
   size = (long)xwidth * (long)(srcBnds.bottom - srcBnds.top);
   
   buff = NewPtr(size);
   (**destMap).baseAddr = buff;

   HLock(srcPix);
   HLock(destMap);
   CopyBits(	*srcPix,		/* Needs pointer,  not handle 	*/
   		*destMap,		/* Same here		     	*/
		&srcRect,		/* Source is origional size	*/
		&destrect,		/* Dest is to be scaled down    */
		patCopy,		/* Xfer mode			*/
		0L);			/* No region			*/
   		
   HUnlock(srcPix);
   HUnlock(destMap);
   
The "bounds" of both PixMaps are (0, 0, 108, 128).   Is there anything Else
I might have overlooked??

John D.

Please respond to:  crunch@well.sf.ca.us

kevin@crash.cts.com (Kevin Hill) (01/09/91)

 icon = GetIcon(id);
	SetRect(&box,0+x,0+y,32+x,32+y);
	
	themap1.baseAddr = (QDPtr)icon;
	themap1.rowBytes = 4;
	SetRect(&themap1.bounds,0,0,32,32);
	
	CopyMask(&themap1,&thewind->portBits,&themap1.bounds,&box,0,NULL);

 This is part of a program that I am making.  I am currently trying to make
a routine that will put icons in the window, under the SrcOr mode, and CopyBits
is the only routine that looks like it will let me do that.  PlotIcon, plotted
the icon with no Or, And etc. type copying to the window.
 The above, does not seem to work.  Could anyone out there shed some light on
the issue for me?  Please e-mail me a reply.  Thank you.

nuk@wpi.WPI.EDU (Jacob W Anderson) (02/22/91)

In a pascal program, I am using the CopyBits function to copy from an
offscreen port to a window, I am having problems in getting the data
from the offscreen port to the window. My code:

procedure DoStuff;
var
   MyMap:BitMap;
   SrcPort:GrafPtr;
   DestPort:GrafPtr;
   SrcRect:Rect;  {Predefined and initialized}
   DestRect:Rect; {Predefined and initialized}
   OffScreenPort:GrafPtr;
begin
  OffScreenPort:=NewPtr(SIZEOF(GrafPort));
  MyMap.baseAddr:=NewPtr(81000) {Size of rectangle to copy, bytes}
  MyMap.bounds:=SrcRect;
  MyMap.rowBytes:=(MyMap.bounds.right - MyMap.bounds.left) div 8);
  OpenPort(OffScreenPort);
  OffScreenPort.portBits:=MyMap;
	{draw stuff}
  CopyBit(OffScreenPort.portBits,VisibleWindow^.thePort.portBits,
 			SrcRect,DestRect,0,NIL);
  ClosePort(OffScreenPort);
end;

This copies junk from somewhere into the visible window properly, but the
junk is not what I desire to be in the window.  I am using THINK Pascal 3.0
on a MacSE.  Thanx

		Please respond via E-mail to
			nuk@wpi.wpi.edu
-jake

nv89-nun@alv.nada.kth.se (Nicklas Ungman) (02/23/91)

The problem might be that MyMap is not properly set up.
The following procedure shuold work ok.
Also see Macintosh Technical Notes #41:Drawing into an Offscreen Bitmap.

procedure DoStuff;
var
  OffscreenPort: GrafPort;
   ...
begin
  MyMap.bounds:=SrcRect;
  MyMap.rowBytes:=((SrcRect.right - SrcRect.left + 15) div 16)*2;
  MyMap.baseAddr:=NewPtr(MyMap.rowBytes*LongInt(SrcRect.bottom - SrcRect.top));

  OpenPort(@OffScreenPort);
  SetPortBits(MyMap);

	{draw stuff}

  CopyBit(OffScreenPort.portBits,VisibleWindow^.portBits,
 			SrcRect,DestRect,0,NIL);
  ClosePort(@OffScreenPort);
end;


/Nixxon