/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: fauxcodec.cpp,v 1.3.20.1 2004/07/09 01:59:02 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

/****************************************************************************
 * 
 *  This program contains proprietary 
 *  information of RealNetworks, Inc, and is licensed
 *  subject to restrictions on use and distribution.
 *
 *  Platform-specific hardware acceleration (overlay)
 *  implementation for Macintosh.
 *
 *  On the Macintosh, in order to access accelerated
 *  video hardware, we must pretend we're an Image
 *  Compression Manager codec. It's a pretty trivial
 *  codec since all we need to do is advertise that
 *  we output yuv data. Then we "register" ourself and
 *  that automagically inserts us into the codec chain
 *  and the OS will take our yuv "output" and blit it
 *  however it thinks best. Which is to accelerated
 *  hardware on both ATI and nVidia on OS 9, and ought
 *  to work on OS X as well, although OS X's success
 *  hasn't been verified as of this writing.
 *
 *  See the ElectricImageComponent sample code sample
 *  at <http://developer.apple.com/samplecode/Sample_Code/
 *  QuickTime/Importers_and_Exporters/ElectricImageComponent.htm>
 *  for more information about how this fake codec was
 *  constructed.
 */



#include "fauxcodec.h"
#include "platform/mac/hx_moreprocesses.h"

// xxxbobclark all these includes are simply to
// call the static CMacSurface::CleanUpOverlay.
#include "hxcom.h"
#include "hxwintyp.h"
#include "hxthread.h"
#include "platform/mac/macsurf.h"



// The high word is the codecInterfaceVersion
#define kFauxCodecVersion		(0x00020001)
#define kFauxCodecVersionPPC		(0x00020002)		// PPC is +1

// Data structures
#pragma options align=mac68k

typedef struct	{
	ComponentInstance		self;
	ComponentInstance		delegateComponent;
	ComponentInstance		target;
	ImageCodecMPDrawBandUPP drawBandUPP;
} Codec_GlobalsRecord, *Codec_Globals;

typedef struct {
	long		width;
	long		height;
	long		depth;
} FauxCodecDecompressRecord;



typedef struct {
	UInt16 imageVersion;						/* Image file version (5) */
	UInt32 imageFrames;							/* Number of frames in the file (1..?) */
} ImageHeader, *ImageHeaderPtr;

typedef struct {
	QTFloatSingle frameTime;					/* Time of frame (0.0) */
	Rect frameRect;								/* Frame Rectangle */
	UInt8 frameBitDepth;						/* Bits Per Pixel (not including alpha) */
	UInt8 frameType;							/* Pixel Type (0=Direct; 1=Indexed) */
	Rect framePackRect;							/* Packing rectangle */
	UInt8 framePacking;							/* Packing Mode (0=Not Packed; 1=RL Encoding) */
	UInt8 frameAlpha;							/* Alpha Bits per pixel */
	UInt32 frameSize;							/* Size in bytes of the body of the image */
	UInt16 framePalettes;						/* Number of entries in the color table (1..256) */
	UInt16 frameBackground;						/* The index of the background color (0) */
} ImageFrame, *ImageFramePtr;


#pragma options align=reset

Handle gWantedDestinationPixelTypes = nil;

// Setup required for ComponentDispatchHelper.c
#define IMAGECODEC_BASENAME() 		FauxCodecImageCodec
#define IMAGECODEC_GLOBALS() 		Codec_Globals storage

#define CALLCOMPONENT_BASENAME()	IMAGECODEC_BASENAME()
#define	CALLCOMPONENT_GLOBALS()		IMAGECODEC_GLOBALS()

#define COMPONENT_UPP_PREFIX()		uppImageCodec
#define COMPONENT_DISPATCH_FILE		"FauxCodecDispatch.h"
#define COMPONENT_SELECT_PREFIX()  	kImageCodec

#define	GET_DELEGATE_COMPONENT()	(storage->delegateComponent)

//#include "ImageCodec.k.h"



// was in components.k.h

#ifdef CALLCOMPONENT_BASENAME
	#ifndef CALLCOMPONENT_GLOBALS
		#define CALLCOMPONENT_GLOBALS() 
		#define ADD_CALLCOMPONENT_COMMA 
	#else
		#define ADD_CALLCOMPONENT_COMMA ,
	#endif
	#define CALLCOMPONENT_GLUE(a,b) a##b
	#define CALLCOMPONENT_STRCAT(a,b) CALLCOMPONENT_GLUE(a,b)
	#define ADD_CALLCOMPONENT_BASENAME(name) CALLCOMPONENT_STRCAT(CALLCOMPONENT_BASENAME(),name)

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(Open) (CALLCOMPONENT_GLOBALS() ADD_CALLCOMPONENT_COMMA ComponentInstance  self);

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(Close) (CALLCOMPONENT_GLOBALS() ADD_CALLCOMPONENT_COMMA ComponentInstance  self);

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(CanDo) (CALLCOMPONENT_GLOBALS() ADD_CALLCOMPONENT_COMMA short  ftnNumber);

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(Version) (CALLCOMPONENT_GLOBALS());

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(Register) (CALLCOMPONENT_GLOBALS());

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(Target) (CALLCOMPONENT_GLOBALS() ADD_CALLCOMPONENT_COMMA ComponentInstance  target);

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(Unregister) (CALLCOMPONENT_GLOBALS());

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(GetMPWorkFunction) (CALLCOMPONENT_GLOBALS() ADD_CALLCOMPONENT_COMMA ComponentMPWorkFunctionUPP * workFunction, void ** refCon);

	EXTERN_API( ComponentResult  ) ADD_CALLCOMPONENT_BASENAME(GetPublicResource) (CALLCOMPONENT_GLOBALS() ADD_CALLCOMPONENT_COMMA OSType  resourceType, short  resourceID, Handle * resource);

#endif	/* CALLCOMPONENT_BASENAME */



// was in ImageCodec.k.h



#ifdef IMAGECODEC_BASENAME
	#ifndef IMAGECODEC_GLOBALS
		#define IMAGECODEC_GLOBALS() 
		#define ADD_IMAGECODEC_COMMA 
	#else
		#define ADD_IMAGECODEC_COMMA ,
	#endif
	#define IMAGECODEC_GLUE(a,b) a##b
	#define IMAGECODEC_STRCAT(a,b) IMAGECODEC_GLUE(a,b)
	#define ADD_IMAGECODEC_BASENAME(name) IMAGECODEC_STRCAT(IMAGECODEC_BASENAME(),name)

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetCodecInfo) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecInfo * info);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetCompressionTime) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA PixMapHandle  src, const Rect * srcRect, short  depth, CodecQ * spatialQuality, CodecQ * temporalQuality, unsigned long * time);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetMaxCompressionSize) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA PixMapHandle  src, const Rect * srcRect, short  depth, CodecQ  quality, long * size);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(PreCompress) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecCompressParams * params);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(BandCompress) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecCompressParams * params);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(PreDecompress) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * params);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(BandDecompress) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * params);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(Busy) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageSequence  seq);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetCompressedImageSize) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageDescriptionHandle  desc, Ptr  data, long  bufferSize, ICMDataProcRecordPtr  dataProc, long * dataSize);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetSimilarity) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA PixMapHandle  src, const Rect * srcRect, ImageDescriptionHandle  desc, Ptr  data, Fixed * similarity);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(TrimImage) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageDescriptionHandle  Desc, Ptr  inData, long  inBufferSize, ICMDataProcRecordPtr  dataProc, Ptr  outData, long  outBufferSize, ICMFlushProcRecordPtr  flushProc, Rect * trimRect, ICMProgressProcRecordPtr  progressProc);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(RequestSettings) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Handle  settings, Rect * rp, ModalFilterUPP  filterProc);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetSettings) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Handle  settings);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(SetSettings) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Handle  settings);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(Flush) (IMAGECODEC_GLOBALS());

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(SetTimeCode) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA void * timeCodeFormat, void * timeCodeTime);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(IsImageDescriptionEquivalent) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageDescriptionHandle  newDesc, Boolean * equivalent);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(NewMemory) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Ptr * data, Size  dataSize, long  dataUse, ICMMemoryDisposedUPP  memoryGoneProc, void * refCon);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(DisposeMemory) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Ptr  data);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(HitTestData) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageDescriptionHandle  desc, void * data, Size  dataSize, Point  where, Boolean * hit);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(NewImageBufferMemory) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * params, long  flags, ICMMemoryDisposedUPP  memoryGoneProc, void * refCon);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(ExtractAndCombineFields) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA long  fieldFlags, void * data1, long  dataSize1, ImageDescriptionHandle  desc1, void * data2, long  dataSize2, ImageDescriptionHandle  desc2, void * outputData, long * outDataSize, ImageDescriptionHandle  descOut);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetMaxCompressionSizeWithSources) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA PixMapHandle  src, const Rect * srcRect, short  depth, CodecQ  quality, CDSequenceDataSourcePtr  sourceData, long * size);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(SetTimeBase) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA void * base);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(SourceChanged) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA UInt32  majorSourceChangeSeed, UInt32  minorSourceChangeSeed, CDSequenceDataSourcePtr  sourceData, long * flagsOut);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(FlushFrame) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA UInt32  flags);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetSettingsAsText) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Handle * text);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetParameterListHandle) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Handle * parameterDescriptionHandle);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetParameterList) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA QTAtomContainer * parameterDescription);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(CreateStandardParameterDialog) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA QTAtomContainer  parameterDescription, QTAtomContainer  parameters, QTParameterDialogOptions  dialogOptions, DialogPtr  existingDialog, short  existingUserItem, QTParameterDialog * createdDialog);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(IsStandardParameterDialogEvent) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA EventRecord * pEvent, QTParameterDialog  createdDialog);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(DismissStandardParameterDialog) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA QTParameterDialog  createdDialog);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(StandardParameterDialogDoAction) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA QTParameterDialog  createdDialog, long  action, void * params);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(NewImageGWorld) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * params, GWorldPtr * newGW, long  flags);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(DisposeImageGWorld) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA GWorldPtr  theGW);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(HitTestDataWithFlags) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageDescriptionHandle  desc, void * data, Size  dataSize, Point  where, long * hit, long  hitFlags);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(ValidateParameters) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA QTAtomContainer  parameters, QTParameterValidationOptions  validationFlags, StringPtr  errorString);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetBaseMPWorkFunction) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ComponentMPWorkFunctionUPP * workFunction, void ** refCon, ImageCodecMPDrawBandUPP  drawProc, void * drawProcRefCon);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(RequestGammaLevel) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Fixed  srcGammaLevel, Fixed  dstGammaLevel, long * codecCanMatch);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetSourceDataGammaLevel) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA Fixed * sourceDataGammaLevel);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(GetDecompressLatency) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA TimeRecord * latency);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(Preflight) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * params);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(Initialize) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageSubCodecDecompressCapabilities * cap);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(BeginBand) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * params, ImageSubCodecDecompressRecord * drp, long  flags);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(DrawBand) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageSubCodecDecompressRecord * drp);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EndBand) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA ImageSubCodecDecompressRecord * drp, OSErr  result, long  flags);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(QueueStarting) (IMAGECODEC_GLOBALS());

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(QueueStopping) (IMAGECODEC_GLOBALS());

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(DroppingFrame) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA const ImageSubCodecDecompressRecord * drp);

//	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(ScheduleFrame) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA const ImageSubCodecDecompressRecord * drp, ImageCodecTimeTriggerUPP  triggerProc, void * triggerProcRefCon);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(CancelTrigger) (IMAGECODEC_GLOBALS());


	/* MixedMode ProcInfo constants for component calls */
	enum {
		uppImageCodecGetCodecInfoProcInfo = 0x000003F0,
		uppImageCodecGetCompressionTimeProcInfo = 0x000FEFF0,
		uppImageCodecGetMaxCompressionSizeProcInfo = 0x0003EFF0,
		uppImageCodecPreCompressProcInfo = 0x000003F0,
		uppImageCodecBandCompressProcInfo = 0x000003F0,
		uppImageCodecPreDecompressProcInfo = 0x000003F0,
		uppImageCodecBandDecompressProcInfo = 0x000003F0,
		uppImageCodecBusyProcInfo = 0x000003F0,
		uppImageCodecGetCompressedImageSizeProcInfo = 0x0003FFF0,
		uppImageCodecGetSimilarityProcInfo = 0x0003FFF0,
		uppImageCodecTrimImageProcInfo = 0x03FFFFF0,
		uppImageCodecRequestSettingsProcInfo = 0x00003FF0,
		uppImageCodecGetSettingsProcInfo = 0x000003F0,
		uppImageCodecSetSettingsProcInfo = 0x000003F0,
		uppImageCodecFlushProcInfo = 0x000000F0,
		uppImageCodecSetTimeCodeProcInfo = 0x00000FF0,
		uppImageCodecIsImageDescriptionEquivalentProcInfo = 0x00000FF0,
		uppImageCodecNewMemoryProcInfo = 0x0003FFF0,
		uppImageCodecDisposeMemoryProcInfo = 0x000003F0,
		uppImageCodecHitTestDataProcInfo = 0x0003FFF0,
		uppImageCodecNewImageBufferMemoryProcInfo = 0x0000FFF0,
		uppImageCodecExtractAndCombineFieldsProcInfo = 0x0FFFFFF0,
		uppImageCodecGetMaxCompressionSizeWithSourcesProcInfo = 0x000FEFF0,
		uppImageCodecSetTimeBaseProcInfo = 0x000003F0,
		uppImageCodecSourceChangedProcInfo = 0x0000FFF0,
		uppImageCodecFlushFrameProcInfo = 0x000003F0,
		uppImageCodecGetSettingsAsTextProcInfo = 0x000003F0,
		uppImageCodecGetParameterListHandleProcInfo = 0x000003F0,
		uppImageCodecGetParameterListProcInfo = 0x000003F0,
		uppImageCodecCreateStandardParameterDialogProcInfo = 0x000EFFF0,
		uppImageCodecIsStandardParameterDialogEventProcInfo = 0x00000FF0,
		uppImageCodecDismissStandardParameterDialogProcInfo = 0x000003F0,
		uppImageCodecStandardParameterDialogDoActionProcInfo = 0x00003FF0,
		uppImageCodecNewImageGWorldProcInfo = 0x00003FF0,
		uppImageCodecDisposeImageGWorldProcInfo = 0x000003F0,
		uppImageCodecHitTestDataWithFlagsProcInfo = 0x000FFFF0,
		uppImageCodecValidateParametersProcInfo = 0x00003FF0,
		uppImageCodecGetBaseMPWorkFunctionProcInfo = 0x0000FFF0,
		uppImageCodecRequestGammaLevelProcInfo = 0x00003FF0,
		uppImageCodecGetSourceDataGammaLevelProcInfo = 0x000003F0,
		uppImageCodecGetDecompressLatencyProcInfo = 0x000003F0,
		uppImageCodecPreflightProcInfo = 0x000003F0,
		uppImageCodecInitializeProcInfo = 0x000003F0,
		uppImageCodecBeginBandProcInfo = 0x00003FF0,
		uppImageCodecDrawBandProcInfo = 0x000003F0,
		uppImageCodecEndBandProcInfo = 0x00003BF0,
		uppImageCodecQueueStartingProcInfo = 0x000000F0,
		uppImageCodecQueueStoppingProcInfo = 0x000000F0,
		uppImageCodecDroppingFrameProcInfo = 0x000003F0,
		uppImageCodecScheduleFrameProcInfo = 0x00003FF0,
		uppImageCodecCancelTriggerProcInfo = 0x000000F0
	};

#endif	/* IMAGECODEC_BASENAME */

/*
	Example usage:

		#define QTPHOTO_BASENAME()	Fred
		#define QTPHOTO_GLOBALS()	FredGlobalsHandle
		#include <ImageCodec.k.h>

	To specify that your component implementation does not use globals, do not #define QTPHOTO_GLOBALS
*/
#ifdef QTPHOTO_BASENAME
	#ifndef QTPHOTO_GLOBALS
		#define QTPHOTO_GLOBALS() 
		#define ADD_QTPHOTO_COMMA 
	#else
		#define ADD_QTPHOTO_COMMA ,
	#endif
	#define QTPHOTO_GLUE(a,b) a##b
	#define QTPHOTO_STRCAT(a,b) QTPHOTO_GLUE(a,b)
	#define ADD_QTPHOTO_BASENAME(name) QTPHOTO_STRCAT(QTPHOTO_BASENAME(),name)

	EXTERN_API( ComponentResult  ) ADD_QTPHOTO_BASENAME(SetSampling) (QTPHOTO_GLOBALS() ADD_QTPHOTO_COMMA short  yH, short  yV, short  cbH, short  cbV, short  crH, short  crV);

	EXTERN_API( ComponentResult  ) ADD_QTPHOTO_BASENAME(SetRestartInterval) (QTPHOTO_GLOBALS() ADD_QTPHOTO_COMMA unsigned short  restartInterval);

	EXTERN_API( ComponentResult  ) ADD_QTPHOTO_BASENAME(DefineHuffmanTable) (QTPHOTO_GLOBALS() ADD_QTPHOTO_COMMA short  componentNumber, Boolean  isDC, unsigned char * lengthCounts, unsigned char * values);

	EXTERN_API( ComponentResult  ) ADD_QTPHOTO_BASENAME(DefineQuantizationTable) (QTPHOTO_GLOBALS() ADD_QTPHOTO_COMMA short  componentNumber, unsigned char * table);


	/* MixedMode ProcInfo constants for component calls */
	enum {
		uppQTPhotoSetSamplingProcInfo = 0x000AAAF0,
		uppQTPhotoSetRestartIntervalProcInfo = 0x000002F0,
		uppQTPhotoDefineHuffmanTableProcInfo = 0x0000F6F0,
		uppQTPhotoDefineQuantizationTableProcInfo = 0x00000EF0
	};

#endif	/* QTPHOTO_BASENAME */

/*
	Example usage:

		#define IMAGECODEC_BASENAME()	Fred
		#define IMAGECODEC_GLOBALS()	FredGlobalsHandle
		#include <ImageCodec.k.h>

	To specify that your component implementation does not use globals, do not #define IMAGECODEC_GLOBALS
*/
#ifdef IMAGECODEC_BASENAME
	#ifndef IMAGECODEC_GLOBALS
		#define IMAGECODEC_GLOBALS() 
		#define ADD_IMAGECODEC_COMMA 
	#else
		#define ADD_IMAGECODEC_COMMA ,
	#endif
	#define IMAGECODEC_GLUE(a,b) a##b
	#define IMAGECODEC_STRCAT(a,b) IMAGECODEC_GLUE(a,b)
	#define ADD_IMAGECODEC_BASENAME(name) IMAGECODEC_STRCAT(IMAGECODEC_BASENAME(),name)

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectSetup) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * p);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectBegin) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA CodecDecompressParams * p, EffectsFrameParamsPtr  ePtr);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectRenderFrame) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA EffectsFrameParamsPtr  p);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectConvertEffectSourceToFormat) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA EffectSourcePtr  sourceToConvert, ImageDescriptionHandle  requestedDesc);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectCancel) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA EffectsFrameParamsPtr  p);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectGetSpeed) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA QTAtomContainer  parameters, Fixed * pFPS);

#if defined(_CARBON) || defined(_MAC_UNIX)

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectPrepareSMPTEFrame) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA PixMapPtr  destPixMap, SMPTEFrameReference * returnValue);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectDisposeSMPTEFrame) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA SMPTEFrameReference  frameRef);

	EXTERN_API( ComponentResult  ) ADD_IMAGECODEC_BASENAME(EffectRenderSMPTEFrame) (IMAGECODEC_GLOBALS() ADD_IMAGECODEC_COMMA PixMapPtr  destPixMap, SMPTEFrameReference  frameRef, Fixed  effectPercentageEven, Fixed  effectPercentageOdd, Rect * pSourceRect, MatrixRecord * pMatrix, SMPTEWipeType  effectNumber, long  xRepeat, long  yRepeat, SMPTEFlags  flags, Fixed  penWidth, long  strokeValue);

#endif

	/* MixedMode ProcInfo constants for component calls */
	enum {
		uppImageCodecEffectSetupProcInfo = 0x000003F0,
		uppImageCodecEffectBeginProcInfo = 0x00000FF0,
		uppImageCodecEffectRenderFrameProcInfo = 0x000003F0,
		uppImageCodecEffectConvertEffectSourceToFormatProcInfo = 0x00000FF0,
		uppImageCodecEffectCancelProcInfo = 0x000003F0,
		uppImageCodecEffectGetSpeedProcInfo = 0x00000FF0,
		uppImageCodecEffectPrepareSMPTEFrameProcInfo = 0x00000FF0,
		uppImageCodecEffectDisposeSMPTEFrameProcInfo = 0x000003F0,
		uppImageCodecEffectRenderSMPTEFrameProcInfo = 0xFFFFFFF0
	};

#endif	/* IMAGECODEC_BASENAME */

// here's the contents of ComponentDispatchHelper.c




// **** BEGIN: Error Checking the Required Macros

// Make sure BASENAME is defined
#ifndef COMPONENT_BASENAME
	#ifdef CALLCOMPONENT_BASENAME
		#define COMPONENT_BASENAME() 	CALLCOMPONENT_BASENAME()
	#else
		#error "COMPONENT_BASENAME or CALLCOMPONENT_BASENAME must be defined for ComponentDispatchHelper.c"
	#endif
#endif

// Make sure GLOBALS is defined
#ifndef COMPONENT_GLOBALS
	#ifdef CALLCOMPONENT_GLOBALS
		#define COMPONENT_GLOBALS() 	CALLCOMPONENT_GLOBALS()
	#else
		#error "COMPONENT_GLOBALS or CALLCOMPONENT_GLOBALS must be defined for ComponentDispatchHelper.c"
	#endif
#endif

// Make sure DISPATCH_FILE is defined
#ifndef COMPONENT_DISPATCH_FILE
	#error "COMPONENT_DISPATCH_FILE must be defined for ComponentDispatchHelper.c"
#endif


// Make sure UPP_PREFIX and SELECT_PREFIX are defined
#if !defined(COMPONENT_UPP_SELECT_ROOT)  && !defined(COMPONENT_UPP_PREFIX) && !defined(COMPONENT_SELECT_PREFIX)
	#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
#endif
#ifdef COMPONENT_UPP_SELECT_ROOT
	#if defined(COMPONENT_UPP_PREFIX) || defined(COMPONENT_SELECT_PREFIX)
		#error "use only COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) for ComponentDispatchHelper.c"
	#endif
#else
	#if !defined(COMPONENT_UPP_PREFIX) || !defined(COMPONENT_SELECT_PREFIX)
		#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
	#endif
#endif
#ifndef COMPONENT_UPP_PREFIX
	#ifndef COMPONENT_UPP_SELECT_ROOT
		#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
	#else 
		#define COMPONENT_UPP_PREFIX()		cdh_GLUE2(upp,COMPONENT_UPP_SELECT_ROOT())
	#endif
#endif
#ifndef COMPONENT_SELECT_PREFIX
	#ifndef COMPONENT_UPP_SELECT_ROOT
		#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
	#else 
		#define COMPONENT_SELECT_PREFIX()	cdh_GLUE2(k,COMPONENT_UPP_SELECT_ROOT())
	#endif
#endif
	
// Make sure SUBTYPE UPP_PREFIX and SELECT_PREFIX are defined correctly if they are used at all
#if defined(COMPONENT_SUBTYPE_UPP_SELECT_ROOT) || defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
	#ifdef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
		#if defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
			#error "use only COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT for ComponentDispatchHelper.c"
		#endif
	#else
		#if !defined(COMPONENT_SUBTYPE_UPP_PREFIX) || !defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
			#error "COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
		#endif
	#endif
	#ifndef COMPONENT_SUBTYPE_UPP_PREFIX
		#ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
			#error "COMPONENT_SUBTYPE_UPP_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
		#else 
			#define COMPONENT_SUBTYPE_UPP_PREFIX()		cdh_GLUE2(upp,COMPONENT_SUBTYPE_UPP_SELECT_ROOT())
		#endif
	#endif
	#ifndef COMPONENT_SUBTYPE_SELECT_PREFIX
		#ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
			#error "COMPONENT_SUBTYPE_SELECT_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
		#else 
			#define COMPONENT_SUBTYPE_SELECT_PREFIX()	cdh_GLUE2(k,COMPONENT_SUBTYPE_UPP_SELECT_ROOT())
		#endif
	#endif
#endif

// **** END: Error Checking the Required Macros

#if TARGET_API_MAC_OSX
#define	CDHCONST	const
#else
#define	CDHCONST
#endif

#if TARGET_OS_MAC
	#define PASCAL_RTN	pascal
#else
	#define PASCAL_RTN
#endif
#if !TARGET_OS_MAC || TARGET_CPU_PPC
	#define C_DISPATCH_WITH_GLOBALS	1
	#define C_DISPATCH_WITH_SWITCH	0
#elif TARGET_CPU_68K
	#ifdef COMPONENT_C_DISPATCHER
		#define C_DISPATCH_WITH_GLOBALS	0
		#define C_DISPATCH_WITH_SWITCH	1
	#else
		#define C_DISPATCH_WITH_GLOBALS	0
		#define C_DISPATCH_WITH_SWITCH	0
	#endif
#else
	#error "I have no idea what kind of machine you are using"
#endif

/*
	C_DISPATCH_WITH_GLOBALS implies global storage for dispatch information 
							and procinfos returned by COMPONENTSELECTORLOOKUP
	C_DISPATCH_WITH_SWITCH  implies no global storage, dispatch by switch
							and no procinfos returned by COMPONENTSELECTORLOOKUP
*/

	#define COMPONENTSELECTORLOOKUP ADD_BASENAME(FindRoutineUPP)

#ifdef COMPONENT_DISPATCH_MAIN
	#define COMPONENT_DISPATCH_ENTRY main
#else
	#define COMPONENT_DISPATCH_ENTRY ADD_BASENAME(ComponentDispatch)
#endif

#ifndef __COMPONENTS_K__
//	#include "Components.k.h"
#endif

#define	kCOMPONENT_NOERROR	((ComponentFunctionUPP)-2)
#define	kCOMPONENT_ERROR	((ComponentFunctionUPP)-1)
#define	kCOMPONENT_DELEGATE	((ComponentFunctionUPP)0)

#ifndef cdh_GLUE
	#define cdh_GLUE(a,b)		a##b
#endif
#ifndef cdh_GLUE2
	#define cdh_GLUE2(a,b)		cdh_GLUE(a,b)
#endif
#ifndef cdh_GLUE3
	#define cdh_GLUE3(a,b,c)	cdh_GLUE2(cdh_GLUE2(a,b),c)
#endif

#if TARGET_RT_LITTLE_ENDIAN
	#define ComponentCallLittleEndian 		ComponentCall
#else
	#define ComponentCallLittleEndian 		ComponentDelegate
#endif

#ifdef forPublicQTiRelease
	#define ComponentQTiCall(procName)				ComponentCall(procName)
	#define QTIComponentCall(procName)				ComponentCall(procName)
#endif

#define ADD_BASENAME(name) cdh_GLUE2(COMPONENT_BASENAME(),name)

#if C_DISPATCH_WITH_GLOBALS
	PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS());
	static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo);

	#if TARGET_OS_MAC && TARGET_CPU_PPC && !TARGET_API_MAC_CARBON
		// entry point for PowerPC native components
		struct RoutineDescriptor ADD_BASENAME(ComponentDispatchRD) =
		  BUILD_ROUTINE_DESCRIPTOR((kPascalStackBased | RESULT_SIZE (kFourByteCode) |
									STACK_ROUTINE_PARAMETER (1, kFourByteCode) |
									STACK_ROUTINE_PARAMETER (2, kFourByteCode)),COMPONENT_DISPATCH_ENTRY);
	#endif
	
	PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params,COMPONENT_GLOBALS())
	{
		ComponentFunctionUPP theProc;
		ComponentResult result = badComponentSelector;
		ProcInfoType theProcInfo;
		
		theProc = COMPONENTSELECTORLOOKUP(params->what, &theProcInfo);

		if (theProc) {
			if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) {
				if (theProcInfo != 0) {
					result = CallComponentFunctionWithStorageProcInfo((Handle) storage, params, (ProcPtr)theProc, theProcInfo);
				}
			}
			else if ( theProc == kCOMPONENT_NOERROR ) {
				result = noErr;
			}
		}
	#ifdef GET_DELEGATE_COMPONENT
		else
			return DelegateComponentCall(params, GET_DELEGATE_COMPONENT());
	#endif
		return result;
	}
#elif C_DISPATCH_WITH_SWITCH
	PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS());
	static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num);

	PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY( ComponentParameters *params, COMPONENT_GLOBALS() )
		{
		ComponentFunctionUPP theProc;
		
		ComponentResult result = badComponentSelector;
		theProc = COMPONENTSELECTORLOOKUP(params->what);

		if (theProc) {
			if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) {
				result = CallComponentFunctionWithStorage((Handle) storage, params, theProc);
			}
			else if ( theProc == kCOMPONENT_NOERROR ) {
				result = noErr;
			}
		}
	#ifdef GET_DELEGATE_COMPONENT
		else
			result = DelegateComponentCall(params, GET_DELEGATE_COMPONENT());
	#endif
		return result;
		}
#endif

#if C_DISPATCH_WITH_GLOBALS
	typedef struct {
		ComponentFunctionUPP	theProc;
		ProcInfoType			theProcInfo;
	} cdhDispatchInfoRecord;
	
	typedef struct {
		short					rangeMax;
		CDHCONST cdhDispatchInfoRecord	*cdhDispatchInfoP;
	} cdhRangeDispatchInfoRecord;
	
	#define ComponentSelectorOffset(theOffset)	enum {SelOffset = theOffset};
	
	#define ComponentRangeCount(theCount)		enum {RangeCount = theCount};
	#define ComponentRangeShift(theShift)		enum {RangeShift = theShift};
	#define ComponentRangeMask(theMask)			enum {RangeMask = cdh_GLUE2(0x,theMask)};
	
	#define ComponentStorageType(theType)
	#define ComponentDelegateByteOffset(theOffset)


	#define StdComponentCall(procName)	\
		(ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(uppCallComponent,procName,ProcInfo),
	
	#define ComponentCall(procName)	\
		(ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_UPP_PREFIX(),procName,ProcInfo),

	#define ComponentSubTypeCall(procName)	\
		(ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_SUBTYPE_UPP_PREFIX(),procName,ProcInfo),

	#define ComponentError(procName)			kCOMPONENT_ERROR, 0,
	
	#define StdComponentNoError(procName) 		kCOMPONENT_NOERROR, 0,
	#define ComponentNoError(procName)			kCOMPONENT_NOERROR, 0,
	#define ComponentSubTypeNoError(procName) 	kCOMPONENT_NOERROR, 0,
	
	#define ComponentDelegate(procName)			kCOMPONENT_DELEGATE, 0,
	
	
	#define ComponentRangeUnused(rangeNum) \
		static CDHCONST cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[1] = { 0 };	\
		enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = 0};
		
	#define ComponentRangeBegin(rangeNum)	\
		static CDHCONST cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[] = {
		
	#define ComponentRangeEnd(rangeNum)				\
		};		\
		enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = sizeof(cdh_GLUE2(cdhDispatchInfo,rangeNum)) / sizeof(cdhDispatchInfoRecord)};
	
	#define ComponentComment(theComment)

	// define the static dispatch tables
	#include COMPONENT_DISPATCH_FILE
	
	#undef ComponentSelectorOffset
	#undef ComponentRangeCount
	#undef ComponentRangeShift
	#undef ComponentRangeMask
	#undef StdComponentCall
	#undef ComponentCall
	#undef ComponentSubTypeCall
	#undef ComponentError
	#undef StdComponentNoError
	#undef ComponentNoError
	#undef ComponentSubTypeNoError
	#undef ComponentDelegate
	#undef ComponentRangeUnused
	#undef ComponentRangeBegin
	#undef ComponentRangeEnd	
	
	#define ComponentSelectorOffset(theOffset)
	#define ComponentRangeCount(theCount)
	#define ComponentRangeShift(theShift)
	#define ComponentRangeMask(theMask)
	#define StdComponentCall(procName)
	#define ComponentCall(procName)
	#define ComponentSubTypeCall(procName)
	#define ComponentError(procName)
	#define StdComponentNoError(procName)
	#define ComponentNoError(procName)
	#define ComponentSubTypeNoError(procName)
	#define ComponentDelegate(procName)
	
	#define ComponentRangeUnused(rangeNum) \
		{ 0, nil },
	#define ComponentRangeBegin(rangeNum)		\
		{ cdh_GLUE2(cdhDispatchMax,rangeNum), cdh_GLUE2(cdhDispatchInfo,rangeNum) },
	#define ComponentRangeEnd(rangeNum)
	
	// define the static range tables (max per range and point to dispatch tables)
	static CDHCONST cdhRangeDispatchInfoRecord cdhRangeDispatch[RangeCount+1] = {
		#include COMPONENT_DISPATCH_FILE
	};
	
	ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo)
	{
		ProcInfoType pinfo = 0;
		ComponentFunctionUPP result = kCOMPONENT_DELEGATE;
		CDHCONST cdhDispatchInfoRecord *infoP = nil;
		short theRange;
		
		theRange = selector_num >> RangeShift;
		if (theRange < 0) {
			selector_num += SelOffset;
			if (selector_num >= 0) {
				infoP = &(cdhRangeDispatch[0].cdhDispatchInfoP)[selector_num];
			}
		} else {
			if (theRange < RangeCount) {
				selector_num &= RangeMask;
				if (selector_num < cdhRangeDispatch[theRange+1].rangeMax)
					infoP = &(cdhRangeDispatch[theRange+1].cdhDispatchInfoP)[selector_num];
			}
		}
		
		if (infoP) {
			*procInfo = infoP->theProcInfo;
			result = infoP->theProc;
		} 
		return result;
	}

#elif C_DISPATCH_WITH_SWITCH
	ComponentFunctionUPP COMPONENTSELECTORLOOKUP( short selector_num )
	{
		ComponentFunctionUPP aProc = (ComponentFunctionUPP) kCOMPONENT_DELEGATE;
	
		#define ComponentSelectorOffset(theOffset)

		#define	case_ComponentCall(kPrefix,procName)	case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)ADD_BASENAME(procName); break;
		#define StdComponentCall(procName)				case_ComponentCall(kComponent,procName)
		#define ComponentCall(procName)					case_ComponentCall(COMPONENT_SELECT_PREFIX(),procName)
		#define ComponentSubTypeCall(procName)			case_ComponentCall(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName)

		#define	case_ComponentNoError(kPrefix,procName)	case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)kCOMPONENT_NOERROR; break;
		#define StdComponentNoError(procName)			case_ComponentNoError(kComponent,procName)
		#define ComponentNoError(procName)				case_ComponentNoError(COMPONENT_SELECT_PREFIX(),procName)
		#define ComponentSubTypeNoError(procName)		case_ComponentNoError(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName)

		#define ComponentError(procName)				//ComponentError for C_DISPATCH_WITH_SWITCH uses default case (delegate if we can)

		#define ComponentDelegate(procName)				//The default case for C_DISPATCH_WITH_SWITCH is to delegate if we can, error if we can't
		
		#define ComponentRangeCount(theCount)
		#define ComponentRangeShift(theShift)
		#define ComponentRangeMask(theMask)
		#define ComponentRangeBegin(rangeNum)
		#define ComponentRangeEnd(rangeNum)
		#define ComponentRangeUnused(rangeNum)
		#define ComponentStorageType(theType)
		#define ComponentDelegateByteOffset(theOffset)
		#define ComponentComment(theComment)

		switch (selector_num) {
			#include COMPONENT_DISPATCH_FILE
			}
	
		return aProc;
	}
#endif

#ifdef OVERRIDE_CANDO
	ComponentResult OVERRIDE_CANDO( COMPONENT_GLOBALS(), short ftnNumber, ComponentResult result);
#endif

#ifndef TOUCH_UNUSED_ARG
	// a macro to avoid "unused variable" warnings
	#define	TOUCH_UNUSED_ARG(arg)	((void)arg)
#endif

PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber );
PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber )
{
	ComponentResult	result;
#if C_DISPATCH_WITH_GLOBALS
	ProcInfoType ignore;
	result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber, &ignore);
#else
	result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber);
#endif
	
	/* check for a ComponentError */
	if ( result == (ComponentResult) kCOMPONENT_ERROR )
		result = false;
	else if ( result == (ComponentResult) kCOMPONENT_DELEGATE )
		result = false;
	else
		result = true;

#ifdef GET_DELEGATE_COMPONENT
	/* if we're delegated, then keep looking */
	if (!result)
		{
		if (GET_DELEGATE_COMPONENT())
			result = CallComponentCanDo( GET_DELEGATE_COMPONENT(), ftnNumber );
		}
#endif

#ifdef OVERRIDE_CANDO
	result = OVERRIDE_CANDO( storage, ftnNumber, result);
#else
	TOUCH_UNUSED_ARG(storage);
#endif

	return result;
}






/* -- This Image Decompressor User the Base Image Decompressor Component --
	The base image decompressor is an Apple-supplied component
	that makes it easier for developers to create new decompressors.
	The base image decompressor does most of the housekeeping and
	interface functions required for a QuickTime decompressor component,
	including scheduling for asynchronous decompression.
*/

// Component Open Request - Required
pascal ComponentResult FauxCodecImageCodecOpen(Codec_Globals glob, ComponentInstance self)
{
	ComponentResult err;

	// Allocate memory for our globals, set them up and inform the component manager that we've done so
	glob = (Codec_Globals)NewPtrClear(sizeof(Codec_GlobalsRecord));
	err = MemError();
	if (err) goto bail;

	SetComponentInstanceStorage(self, (Handle)glob);

	glob->self = self;
	glob->target = self;
	glob->drawBandUPP = NULL;
	
	// Open and target an instance of the base decompressor as we delegate
	// most of our calls to the base decompressor instance
	err = OpenADefaultComponent(decompressorComponentType, kBaseCodecType, &glob->delegateComponent);
	if (err) goto bail;

	ComponentSetTarget(glob->delegateComponent, self);

bail:
	return err;
}

// Component Close Request - Required
pascal ComponentResult FauxCodecImageCodecClose(Codec_Globals glob, ComponentInstance self)
{
	// Make sure to close the base component and dealocate our storage
	if (glob) {
		if (glob->delegateComponent) {
			CloseComponent(glob->delegateComponent);
		}
		
		if (glob->drawBandUPP) {
#if defined(_CARBON) || defined(_MAC_UNIX)
			DisposeImageCodecMPDrawBandUPP(glob->drawBandUPP);
#else
			DisposeRoutineDescriptor(glob->drawBandUPP);
#endif
		}

		DisposePtr((Ptr)glob);
	}

	return noErr;
}

// Component Version Request - Required
pascal ComponentResult FauxCodecImageCodecVersion(Codec_Globals glob)
{
#pragma unused(glob)

	#if TARGET_CPU_68K || TARGET_OS_WIN32
		return kFauxCodecVersion;
	#else
		return kFauxCodecVersionPPC;
	#endif
}

// Component Target Request
// 		Allows another component to "target" you i.e., you call another component whenever
// you would call yourself (as a result of your component being used by another component)
pascal ComponentResult FauxCodecImageCodecTarget(Codec_Globals glob, ComponentInstance target)
{
	glob->target = target;
	return noErr;
}

// Component GetMPWorkFunction Request
//		Allows your image decompressor component to perform asynchronous decompression
// in a single MP task by taking advantage of the Base Decompressor. If you implement
// this selector, your DrawBand function must be MP-safe. MP safety means not
// calling routines that may move or purge memory and not calling any routines which
// might cause 68K code to be executed. Ideally, your DrawBand function should not make
// any API calls whatsoever. Obviously don't implement this if you're building a 68k component.
#if !TARGET_CPU_68K
pascal ComponentResult FauxCodecImageCodecGetMPWorkFunction(Codec_Globals glob, ComponentMPWorkFunctionUPP *workFunction, void **refCon)
{
	if (NULL == glob->drawBandUPP)
		#if !TARGET_API_MAC_CARBON
			glob->drawBandUPP = NewImageCodecMPDrawBandProc(FauxCodecImageCodecDrawBand);
		#else
			glob->drawBandUPP = NewImageCodecMPDrawBandUPP((ImageCodecMPDrawBandProcPtr)FauxCodecImageCodecDrawBand);
		#endif
		
	return ImageCodecGetBaseMPWorkFunction(glob->delegateComponent, workFunction, refCon, glob->drawBandUPP, glob);
}
#endif // !TARGET_CPU_68K

#pragma mark-

// ImageCodecInitialize
//		The first function call that your image decompressor component receives from the base image
// decompressor is always a call to ImageCodecInitialize . In response to this call, your image decompressor
// component returns an ImageSubCodecDecompressCapabilities structure that specifies its capabilities.
pascal ComponentResult FauxCodecImageCodecInitialize(Codec_Globals glob, ImageSubCodecDecompressCapabilities *cap)
{
#pragma unused(glob)

	// Secifies the size of the ImageSubCodecDecompressRecord structure
	// and say we can support asyncronous decompression
	// With the help of the base image decompressor, any image decompressor
	// that uses only interrupt-safe calls for decompression operations can
	// support asynchronous decompression.
	cap->decompressRecordSize = sizeof(FauxCodecDecompressRecord);
	cap->canAsync = true;

	return noErr;
}


long gCodecFrameWidth = 0;
long gCodecFrameHeight = 0;

// ImageCodecPreflight
// 		The base image decompressor gets additional information about the capabilities of your image
// decompressor component by calling ImageCodecPreflight. The base image decompressor uses this
// information when responding to a call to the ImageCodecPredecompress function,
// which the ICM makes before decompressing an image. You are required only to provide values for
// the wantedDestinationPixelSize and wantedDestinationPixelTypes fields and can also modify other
// fields if necessary.
pascal ComponentResult FauxCodecImageCodecPreflight(Codec_Globals glob, CodecDecompressParams *p)
{
#pragma unused(glob)

    CodecCapabilities *capabilities = p->capabilities;

    if (!p->wantedDestinationPixelTypes)
    {

	if (!IsMacInCooperativeThread())
	{
	    p->wantedDestinationPixelTypes = (unsigned long**)gWantedDestinationPixelTypes;
	}
	else
	{
	    p->wantedDestinationPixelTypes = (unsigned long**)NewHandle(8);
	    (*p->wantedDestinationPixelTypes)[0] = 'yuvs';
	    (*p->wantedDestinationPixelTypes)[1] = 0;
	}
    }

    capabilities->bandMin = (**p->imageDescription).height;
    capabilities->bandInc = capabilities->bandMin;

    // Specify the number of pixels the image must be extended in width and height if
    // the component cannot accommodate the image at its given width and height
    capabilities->extendWidth = 0;
    capabilities->extendHeight = 0;

    // xxxbobclark VERY IMPORTANT! This MUST be zero. Otherwise it will try
    // to hook itself in to an RGB codec chain. Only if this is zero will
    // it successfully hook itself in to a YUV codec chain.
    capabilities->wantedPixelSize = 0;

    return noErr;
}

// ImageCodecBeginBand
// 		The ImageCodecBeginBand function allows your image decompressor component to save information about
// a band before decompressing it. This function is never called at interrupt time. The base image decompressor
// preserves any changes your component makes to any of the fields in the ImageSubCodecDecompressRecord
// or CodecDecompressParams structures. If your component supports asynchronous scheduled decompression, it
// may receive more than one ImageCodecBeginBand call before receiving an ImageCodecDrawBand call.
pascal ComponentResult FauxCodecImageCodecBeginBand(Codec_Globals glob, CodecDecompressParams *p, ImageSubCodecDecompressRecord *drp, long flags)
{
#pragma unused(glob)
	
	long offsetH, offsetV;
	FauxCodecDecompressRecord *myDrp = (FauxCodecDecompressRecord *)drp->userDecompressRecord;

	offsetH = (long)(p->dstRect.left - p->dstPixMap.bounds.left) * (long)(p->dstPixMap.pixelSize >> 3);
	offsetV = (long)(p->dstRect.top - p->dstPixMap.bounds.top) * (long)drp->rowBytes;

	drp->baseAddr = p->dstPixMap.baseAddr + offsetH + offsetV;

	myDrp->width = (**p->imageDescription).width;
	myDrp->height = (**p->imageDescription).height;
	myDrp->depth = (**p->imageDescription).depth;

	return noErr;
}


// ImageCodecDrawBand
//		The base image decompressor calls your image decompressor component's ImageCodecDrawBand function
// to decompress a band or frame. Your component must implement this function. If the ImageSubCodecDecompressRecord
// structure specifies a progress function or data-loading function, the base image decompressor will never call ImageCodecDrawBand
// at interrupt time. If the ImageSubCodecDecompressRecord structure specifies a progress function, the base image decompressor
// handles codecProgressOpen and codecProgressClose calls, and your image decompressor component must not implement these functions.
// If not, the base image decompressor may call the ImageCodecDrawBand function at interrupt time.
// When the base image decompressor calls your ImageCodecDrawBand function, your component must perform the decompression specified
// by the fields of the ImageSubCodecDecompressRecord structure. The structure includes any changes your component made to it
// when performing the ImageCodecBeginBand function. If your component supports asynchronous scheduled decompression,
// it may receive more than one ImageCodecBeginBand call before receiving an ImageCodecDrawBand call.
pascal ComponentResult FauxCodecImageCodecDrawBand(Codec_Globals glob, ImageSubCodecDecompressRecord *drp)
{
#pragma unused(glob)

    OSErr err = noErr;

    FauxCodecDecompressRecord *myDrp = (FauxCodecDecompressRecord *)drp->userDecompressRecord;
    unsigned char *dataPtr = (unsigned char *)drp->codecData;
    ICMDataProcRecordPtr dataProc = drp->dataProcRecord.dataProc ? &drp->dataProcRecord : NULL;
    ImageFramePtr framePtr = (ImageFramePtr)dataPtr;

    for (long i = 0; i < myDrp->height; i++)
    {
	void* srcP = (void*)((long)dataPtr + i * myDrp->width * 2);
	void* dstP = (void*)((long)drp->baseAddr + i * drp->rowBytes);

	BlockMoveData(srcP, dstP, myDrp->width*2);
    }
    return noErr;
}

// ImageCodecEndBand
//		The ImageCodecEndBand function notifies your image decompressor component that decompression of a band has finished or
// that it was terminated by the Image Compression Manager. Your image decompressor component is not required to implement
// the ImageCodecEndBand function. The base image decompressor may call the ImageCodecEndBand function at interrupt time.
// After your image decompressor component handles an ImageCodecEndBand call, it can perform any tasks that are required
// when decompression is finished, such as disposing of data structures that are no longer needed. Because this function
// can be called at interrupt time, your component cannot use this function to dispose of data structures; this
// must occur after handling the function. The value of the result parameter should be set to noErr if the band or frame was
// drawn successfully. If it is any other value, the band or frame was not drawn.
pascal ComponentResult FauxCodecImageCodecEndBand(Codec_Globals glob, ImageSubCodecDecompressRecord *drp, OSErr result, long flags)
{
#pragma unused(glob, drp,result, flags)
	
    return noErr;
}

// ImageCodecQueueStarting
// 		If your component supports asynchronous scheduled decompression, the base image decompressor calls your image decompressor component's
// ImageCodecQueueStarting function before decompressing the frames in the queue. Your component is not required to implement this function.
// It can implement the function if it needs to perform any tasks at this time, such as locking data structures.
// The base image decompressor never calls the ImageCodecQueueStarting function at interrupt time.
pascal ComponentResult FauxCodecImageCodecQueueStarting(Codec_Globals glob)
{
#pragma unused(glob)
	
	return noErr;
}

// ImageCodecQueueStopping
//		 If your image decompressor component supports asynchronous scheduled decompression, the ImageCodecQueueStopping function notifies
// your component that the frames in the queue have been decompressed. Your component is not required to implement this function.
// After your image decompressor component handles an ImageCodecQueueStopping call, it can perform any tasks that are required when decompression
// of the frames is finished, such as disposing of data structures that are no longer needed. 
// The base image decompressor never calls the ImageCodecQueueStopping function at interrupt time.
pascal ComponentResult FauxCodecImageCodecQueueStopping(Codec_Globals glob)
{
#pragma unused(glob)
	
	return noErr;
}

// ImageCodecGetCompressedImageSize
// 		Your component receives the ImageCodecGetCompressedImageSize request whenever an application calls the ICM's GetCompressedImageSize function.
// You can use the ImageCodecGetCompressedImageSize function when you are extracting a single image from a sequence; therefore, you don't have an
// image description structure and don't know the exact size of one frame. In this case, the Image Compression Manager calls the component to determine
// the size of the data. Your component should return a long integer indicating the number of bytes of data in the compressed image. You may want to store
// the image size somewhere in the image description structure, so that you can respond to this request quickly. Only decompressors receive this request.
pascal ComponentResult FauxCodecImageCodecGetCompressedImageSize(Codec_Globals glob, ImageDescriptionHandle desc, Ptr data, long dataSize, ICMDataProcRecordPtr dataProc, long *size)
{
#pragma	unused(glob,dataSize,dataProc)
	ImageFramePtr framePtr = (ImageFramePtr)data;

	if (size == NULL) 
		return paramErr;

	// xxxbobclark gotta fix this
	*size = EndianU32_BtoN(framePtr->frameSize) + sizeof(ImageFrame);

	return noErr;
}

// ImageCodecGetCodecInfo
//		Your component receives the ImageCodecGetCodecInfo request whenever an application calls the Image Compression Manager's GetCodecInfo function.
// Your component should return a formatted compressor information structure defining its capabilities.
// Both compressors and decompressors may receive this request.
pascal ComponentResult FauxCodecImageCodecGetCodecInfo(Codec_Globals glob, CodecInfo *info)
{
    OSErr err = noErr;

    if (info == NULL)
    {
	err = paramErr;
    }
    else
    {
	BlockMoveData("\pRealNetworks", info->typeName, 13);
	info->version = 1;
	info->revisionLevel = 1;
	info->vendor = 'RNWK';
	info->decompressFlags = 0; // no flags for YUV-type of pixel maps
	info->formatFlags = 0; // no flags for YUV-type of pixel maps
	info->compressionAccuracy = 128;
	info->decompressionAccuracy = 128;
	info->compressionSpeed = 200;
	info->decompressionSpeed = 200;
	info->compressionLevel = 128;
	info->resvd = 0;
	info->minimumHeight = 2;
	info->minimumWidth = 2;
	info->decompressPipelineLatency = 0;
	info->compressPipelineLatency = 0;
	info->privateData = 0;
    }

    return err;
}

#pragma mark-

Component gFauxCodecComponent = NULL;

// When building the *Application Version Only* make our component available for use by applications (or other clients).
// Once the Component Manager has registered a component, applications can find and open the component using standard
// Component Manager routines.
void FauxCodecRegister(void)
{
    ComponentDescription td;
#if defined(_CARBON) || defined(_MAC_UNIX)
    ComponentRoutineUPP componentEntryPoint = NewComponentRoutineUPP((ComponentRoutineProcPtr)FauxCodecImageCodecComponentDispatch);
#else
    ComponentRoutineUPP componentEntryPoint = NewComponentRoutineProc(FauxCodecImageCodecComponentDispatch);
#endif

    td.componentType = decompressorComponentType;
    td.componentSubType = FOUR_CHAR_CODE('yuvs');
    td.componentManufacturer = 'RNWK';
    td.componentFlags = codecInfoDoes32;
    td.componentFlagsMask = 0;

    gFauxCodecComponent = RegisterComponent(&td,componentEntryPoint, 0, NULL, NULL, NULL);

    // xxxbobclark set up a wanted destination pixel types handle in
    // case I need an existing one at interrupt time.
    gWantedDestinationPixelTypes = NewHandle(8);
    unsigned long* typeArray = (unsigned long*)gWantedDestinationPixelTypes;
    
    // end the type array with zero
    
    //typeArray[0] = '2vuy';
    typeArray[0] = 'yuvs';
    typeArray[1] = 0;
}

void FauxCodecUnregister(void)
{
    if (gFauxCodecComponent)
    {
        // be sure that the sequence ID has been deallocated!
        CMacSurface::CleanUpOverlay();
        
        UnregisterComponent(gFauxCodecComponent);
        gFauxCodecComponent = NULL;
    }
}
