home *** CD-ROM | disk | FTP | other *** search
- /* NoiseFill.c
- © 1989-1994 Denis G. Pelli.
- error=NoiseFill(window,&rect,dx,dy,randomPhase);
- Fills the rect in the window with noise. The noise is made up of black & white
- checks, each dx pixels wide by dy pixels high. Random phase is optional. (dx and
- dy are doubles, and need not be integral. The noise is synthesized with 1-pixel
- checks and expanded by CopyBits, which is capable of expansion by non-integral
- amounts.)
-
- error=NoiseFillBits(pixmapPtr,&rect,dx,dy,randomPhase);
- Same, but accepts a pix/bitmap ptr in place of the window.
-
- error=MakeNoise1(dx,dy,randomPhase,pixmapPtr);
- Same, but fills the whole pix/bitmap, i.e. uses pixmapPtr->bounds as the rect.
- Obsolete, retained solely for compatibility.
-
- We use the current port's ForeColor and BackColor to make the noise. (If
- baseAddr==NULL, we share the color table of the current device.) Apple's
- GetGWorld and SetGWorld calls are a convenient way of getting, changing, and
- restoring the current port and device.
-
- If pixmapPtr->baseAddr==NULL then the data area will be allocated for you. You
- must set pixmapPtr->bounds and pixmapPtr->pixelSize; the rest of the PixMap
- struct will be filled in by NoiseFillBits. It will install a handle to the
- current device's color table. The values filled into the fields are necessarily
- somewhat arbitrary. For more control, fill in the fields yourself, using
- NewPixMap(), and allocate the data area yourself before calling NoiseFillBits().
-
- HISTORY:
- 6/21/89 dgp changed frameBytes and bufferBytes to long so that this code won't crash
- if the pixelSize is greater than 1 bit.
- 8/5/89 dgp wrote and installed randU(), which yields two random bytes per call, instead
- of rand() which yields only one, allowing the noise generation to go twice
- as fast.
- 3/11/90 dgp Changed dx and dy from int to double. This allows nonuniform cell size,
- which arises when CopyBits expands by these nonintegral factors. Results
- will be same as before when integral values are supplied.
- Made the cosmetic change of replacing "unsigned long" by "size_t".
- 3/20/90 dgp make compatible with MPW C.
- 3/31/90 dgp set pmVersion to zero for compatibility with QD32
- 8/7/90 dgp Now uses the current ForeColor and BackColor to make the noise.
- For future compatibility, now zeroes the packType, etc. fields.
- 10/1/90 dgp Cosmetic changes: replaced two OffsetRect calls by CenterRectInRect call.
- 11/16/90 dgp Added RANDOM_PHASE.
- 4/20/91 dgp Added new MakeNoise1() that accepts a single PixMap, and allocates
- its data area only if baseAddr==NULL, otherwise assuming that it already
- exists. I rewrote MakeNoise() to simply call MakeNoise1() repeatedly.
- MakeNoise() now seems obsolete, but is retained for compatibility with old
- programs.
- 4/24/91 dgp Fixed bug introduced into MakeNoise() on 4/20, which resulted in all the
- PixMaps using the same buffer.
- 8/6/91 dgp Replaced use of randU() by RandFill(), which is twice as fast.
- 8/24/91 dgp Made compatible with THINK C 5.0.
- 4/17/92 dgp Removed hidden assumption that bits->bounds.top and bits->bounds.left
- were both zero. If they were negative MakeNoise1 would allocate too
- little space, and then overwrite memory and crash.
- 4/27/92 dgp Initialize all remaining fields of the *bits PixMap, and copy the current
- device's color table handle.
- 10/22/92 dgp Check for error in CopyBits.
- 9/5/94 dgp removed assumption in printf's that int==short.
- 11/21/94 dgp in response to note from Marty Wachter, improve centering algorithm, so
- that if dx & dy are integral the final image is made of whole checks.
- 11/21/94 dgp renamed NoiseFill.c and added new calling interfaces, analogous to those
- for CopyWindows and CopyBits.
- */
- #include "VideoToolbox.h"
- int MakeNoise1(double dx,double dy,Boolean randomPhase,PixMap *bits)
- {
- return NoiseFillBits(bits,&bits->bounds,dx,dy,randomPhase);
- }
-
- int NoiseFill(CWindowPtr window,Rect *r,double dx,double dy,Boolean randomPhase)
- {
- Boolean error,ok;
-
- if(IsGWorldPtr(window)){
- ok=LockPixels(window->portPixMap);
- if(!ok)return 2;
- }
- if(IsGrafPtr(window))
- error=NoiseFillBits((PixMap *)&((WindowPtr)window)->portBits,r,dx,dy,randomPhase);
- else{
- HLock((Handle)window->portPixMap);
- error=NoiseFillBits(*window->portPixMap,r,dx,dy,randomPhase);
- HUnlock((Handle)window->portPixMap);
- }
- if(IsGWorldPtr(window))UnlockPixels(window->portPixMap);
- return error;
- }
-
- int NoiseFillBits(PixMap *bits,Rect *r,double dx,double dy,Boolean randomPhase)
- {
- BitMap buffer,bigBuffer;
- Rect srcRect;
- size_t frameBytes,bufferBytes;
- static const RGBColor blackRGB={0,0,0},whiteRGB={0xffff,0xffff,0xffff};
- RGBColor backRGB,foreRGB;
- int error;
-
- if(dx<=0 || dy<=0)return 3;
- srandU((unsigned int)rand()); /* seed our unsigned random number generator */
- GetBackColor(&backRGB);
- GetForeColor(&foreRGB);
-
- /* allocate buffer BitMap */
- SetRect(&buffer.bounds,0,0,ceil((r->right - r->left)/dx),ceil((r->bottom - r->top)/dy));
- if(randomPhase){
- buffer.bounds.right++;
- buffer.bounds.bottom++;
- }
- buffer.rowBytes=(buffer.bounds.right + 31 & ~31)/8; /* round up to multiple of 32 bits */
- bufferBytes=(size_t) buffer.rowBytes * (size_t) buffer.bounds.bottom;
- buffer.baseAddr=(Ptr) NewPtr(bufferBytes);
- if(buffer.baseAddr == NULL)return 4;
-
- /* allocate bigBuffer BitMap */
- SetRect (&bigBuffer.bounds,0,0,(int)round(buffer.bounds.right*dx),
- (int)round(buffer.bounds.bottom*dy));
- bigBuffer.rowBytes=(bigBuffer.bounds.right + 31 & ~31)/8; /* round up to multiple of 32 bits */
- bigBuffer.baseAddr=(Ptr) NewPtr((size_t) bigBuffer.rowBytes * (size_t) bigBuffer.bounds.bottom);
- if(bigBuffer.baseAddr == NULL){
- DisposePtr(buffer.baseAddr);
- return 5;
- }
- /* if necessary, fill in pixmap's fields and allocate its data area */
- if(bits->baseAddr == NULL){
- // If we're allocating, assume *bits is a PixMap, not a Bitmap.
- bits->hRes=bits->vRes=0x480000; // 72 dpi
- bits->pmVersion=bits->packType=bits->packSize=0;
- bits->planeBytes=bits->pmReserved=0;
- bits->cmpCount=1;
- bits->cmpSize=bits->pixelSize;
- bits->pmTable=(**(**GetGDevice()).gdPMap).pmTable;
- bits->rowBytes=((bits->bounds.right-bits->bounds.left)*bits->pixelSize + 31 & ~31)/8; /* round up to multiple of 32 bits */
- frameBytes=(size_t) bits->rowBytes * (bits->bounds.bottom-bits->bounds.top);
- bits->rowBytes |= 0x8000; /* mark it as a PixMap */
- bits->baseAddr=(char *) NewPtr(frameBytes);
- if(bits->baseAddr == NULL)return 6;
- }
- if((size_t)bits->baseAddr%4 != 0L){
- printf("WARNING: Frame buffer address is not long aligned. %s\007\n",__FILE__);
- }
-
- /* create random noise */
- /* First create a random bit image, all bits uncorrelated. */
- RandFill(buffer.baseAddr,bufferBytes);
- /* Now expand image so that each random bit becomes a dx by dy rectangle. */
- RGBBackColor(&whiteRGB);
- RGBForeColor(&blackRGB);
- CopyBits(&buffer,&bigBuffer,&buffer.bounds,&bigBuffer.bounds,srcCopy,NULL);
- error=QDError();
- if(error)printf("MakeNoise1:a: CopyBits error %d\n",error);
- /* Finally copy it into the bit/pixmap, trimming it down to the correct size. */
- RGBBackColor(&backRGB);
- RGBForeColor(&foreRGB);
- srcRect=*r;
- OffsetRect(&srcRect,-srcRect.left,-srcRect.top);
- if(randomPhase) OffsetRect(&srcRect,nrand(dx),nrand(dy));
- else CenterRectInRect(&srcRect,&bigBuffer.bounds);
- CopyBits(&bigBuffer,(BitMap *)bits,&srcRect,r,srcCopy,NULL);
- error=QDError();
- DisposPtr((void *) buffer.baseAddr);
- DisposPtr((void *) bigBuffer.baseAddr);
- return error;
- }
-
-
-