📄 fauxcodec.cpp
字号:
#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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -