Esempio n. 1
0
static void ApplyChannel (GPtr globals,
						  ReadChannelDesc *source,
						  PixelMemoryDesc *sDesc,
						  ReadChannelDesc *mask, 
						  PixelMemoryDesc *mDesc,
						  WriteChannelDesc *dest, 
						  ChannelReadPort destRead,
						  PixelMemoryDesc *dDesc,
						  PixelMemoryDesc *rDesc,
						  size_t *done,
						  size_t total)
	{
	
	VRect limit;
	int32 row, col, row2, col2;
	unsigned8 *s, *m, *d;
	unsigned8 *r = (unsigned8 *)rDesc->data;
	Boolean initRandom = (*r == kInitRandom);
		
	limit = source->bounds;
	TrimVRect (&limit, &dest->bounds);
	if (mask != NULL) TrimVRect (&limit, &mask->bounds);
		
	if (limit.right <= limit.left || limit.bottom <= limit.top) return;
	
	for (row = limit.top; row < limit.bottom; row += kBlockRows)
		for (col = limit.left; col < limit.right; col += kBlockCols)
			{
			
			VRect area;
			PSScaling scaling;
			VRect wrote;
			
			if (TestAbort ())
				{
				gResult = userCanceledErr;
				return;
				}
			
			area.top = row;  area.bottom = row + kBlockRows;
			area.left = col; area.right  = col + kBlockCols;
			
			if (limit.bottom < area.bottom) area.bottom = limit.bottom;
			if (limit.right  < area.right ) area.right  = limit.right;
			
			scaling.sourceRect = area;
			scaling.destinationRect = area;
			
			gResult = ReadPixels (destRead, &scaling, &area, dDesc, &wrote);
			if (gResult != noErr) return;
			
			if (!EqualVRects (&area, &wrote))
				{
				gResult = -1;
				return;
				}
				
			gResult = ReadPixels (source->port, &scaling, &area, sDesc, &wrote);
			if (gResult != noErr) return;
			
			if (!EqualVRects (&area, &wrote))
				{
				gResult = -1;
				return;
				}
				
			if (mask != NULL)
				{
				
				gResult = ReadPixels (mask->port, &scaling, &area, mDesc, &wrote);
				if (gResult != noErr) return;
				
				if (!EqualVRects (&area, &wrote))
					{
					gResult = -1;
					return;
					}
				}
				m = (unsigned8 *) mDesc->data;
				/* mask all set and ready to go */
									
			/* heart of the routine.  Compares source pixel and destination
			   pixel and, if destination is smaller, replaces it with
			   source */

			s = (unsigned8 *) sDesc->data;
			d = (unsigned8 *) dDesc->data;
			r = (unsigned8 *) rDesc->data;
						
			for (row2 = kBlockRows; row2 > 0; --row2)
				for (col2 = kBlockCols; col2 > 0; --col2)
				{
					
					switch (gWhatArea)
					{
						case iSelectMin:
							if (mask != NULL && *m < *s ) *s = *m;
							if (*s > 127) *d = *s;
							else *d = 0;
							break;
						case iSelectMax:
							if (mask != NULL && *m < *s ) *s = *m;
							if (*s < 128) *d = 255 - *s; // if (*d < *s) *d = *s;
							else *d = 0;
							break;
						case iSelectRandom:
							if (initRandom)
							{
								if ((((unsigned16) rand ()) % 100) < gPercent)
									*r = kRandomOn; // flag as picked
								else *r = kRandomOff; // flag as off
							}
							if (*r == kRandomOn)
								*d = 255;
							else *d = 0;
							break;
					}
					++s;
					++d;
					++r;
					if (mask != NULL) ++m;
				}
					
			gResult = WritePixels (dest->port, &area, dDesc);
			if (gResult != noErr) return;
			
			*done += (area.right - area.left) * (area.bottom - area.top);
			
			PIUpdateProgress ((int32)*done, (int32)total);
				
			}
	
	}
Esempio n. 2
0
void DoEffect(GPtr globals)
{
	// Get a buffer to hold each channel as we process
	char *pLayerData = gPSBufferSuite64->New(NULL, 
										   VSIZE * HSIZE * gXFactor * gXFactor);
	if (pLayerData == NULL)
		return;
		
	// Start with the first target composite channel
	ReadChannelDesc *pChannel = gDocDesc->targetCompositeChannels;

	// we may have a multichannel document
	if (pChannel == NULL)
		pChannel = gDocDesc->alphaChannels;
	
	// Get some information for the progress bar
	int32 done = 0;
	int32 total = NumberOfChannels(globals) + 1;
	
	// Loop through each of the channels
	while (pChannel != NULL && gResult == 0)
	{
		// Update the progress bar
		PIUpdateProgress(done++, total);
		
		// Read in this channel data, we actually don't need this data
	 	// but I will read it in anyway, it is an example you know
		ReadLayerData(globals, pChannel, pLayerData, false);
		
		// Stamp the "Hello World" into the data buffer
		HelloWorldData(globals, pLayerData);
		
		// Decide if we should blur our effect or just write out the
		// data. GaussianBlurEffect() will use a new channel port
		if (gGaussianBlurData)
			{
			Rect write_rect;
			write_rect.top = gPointV;
			write_rect.left = gPointH;
			write_rect.bottom = (short)(gPointV + VSIZE * gXFactor);
			write_rect.right = (short)(gPointH + HSIZE * gXFactor);
			GaussianBlurEffect(globals, &write_rect, pLayerData);
			}
		WriteLayerData(globals, pChannel, pLayerData);
			
		// off to the next channel
		pChannel = pChannel->next;
	}

	// Update the progress bar
	PIUpdateProgress(done++, total);
	
	// now update the transparency information
	// this will be non null for layered data
	pChannel = gDocDesc->targetTransparency;
	if (gResult == 0)
	{
		// Read in this channel data, we actually don't need this data
	 	// but I will read it in anyway, it is an example you know
		ReadLayerData(globals, pChannel, pLayerData, false);

		// Stamp the "Hello World" into the data buffer
		HelloWorldMaskData(globals, pLayerData);

		// write out the channel mask
		WriteLayerData(globals, pChannel, pLayerData);
	}

	// Update the progress bar
	PIUpdateProgress(done++, total);
	
	// dispose of that temp buffer we have been using
	gPSBufferSuite64->Dispose((char**)&pLayerData);
}