Creating Image Transcoder Components

Image transcoder components are standard Component Manager components. An example component is provided in this chapter.

Image transcoder components have a type of 'imtc'.

The subtype field of the component defines the compressed image data format that the transcoder accepts as an input. The manufacturer field of the component defines the compressed image data format that the transcoder generates as output.

For example, a transcoder from Motion JPEG Format A to Motion JPEG Format B would have a subtype of 'mjpg' and a manufacturer code of 'mjpb'. No component-specific flags are currently defined for transcoders; they should be set to 0.

An Example

The example code in Listing 17-1 shows an image transcoder component. It converts an imaginary compressed data format 'bgr ' to uncompressed RGB pixels. The transcoding process simply copies the source data to the destination and inverts each byte in the process. This example shows the format of how an image transcoder might work without getting into the details of a particular image transcoding operation.

Listing 17-1  An image transcoder component that converts a compressed data format to uncompressed RGB pixels

#include <ImageCompression.h>
pascal ComponentResult main(ComponentParameters *params, Handle storage );
pascal ComponentResult TestTranscoderBeginSequence (Handle storage, ImageDescriptionHandle
srcDesc, ImageDescriptionHandle *dstDesc, void *data, long dataSize);
pascal ComponentResult TestTranscoderConvert (Handle storage, void *srcData, long srcDataSize,
void **dstData, long *dstDataSize);
pascal ComponentResult TestTranscoderDisposeData (Handle storage, void *dstData);
pascal ComponentResult TestTranscoderEndSequence (Handle storage);
pascal ComponentResult main(ComponentParameters *params, Handle storage )
{
    ComponentFunctionUPP proc = nil;
    ComponentResult err = noErr;
    switch (params->what) {
        case kComponentOpenSelect:
        case kComponentCloseSelect:
            break;
        case kImageTranscoderBeginSequenceSelect:
            proc = (ComponentFunctionUPP) TestTranscoderBeginSequence;
            break;
        case kImageTranscoderConvertSelect:
            proc = (ComponentFunctionUPP)TestTranscoderConvert;
            break;
        case kImageTranscoderDisposeDataSelect:
            proc = (ComponentFunctionUPP) TestTranscoderDisposeData;
            break;
        case kImageTranscoderEndSequenceSelect:
            proc = (ComponentFunctionUPP) TestTranscoderEndSequence;
            break;
        default:
            err = badComponentSelect;
            break;
    }
    if (proc)
        err = CallComponentFunctionWithStorage(storage,
                        params, proc);
    return err;
}
pascal ComponentResult TestTranscoderBeginSequence (Handle storage, ImageDescriptionHandle
srcDesc, ImageDescriptionHandle *dstDesc, void *data, long dataSize)
{
    *dstDesc = srcDesc;
    HandToHand((Handle *)dstDesc);
    (***dstDesc).cType = 'raw ';
    return noErr;
}
pascal ComponentResult TestTranscoderConvert (Handle storage, void *srcData, long srcDataSize,
void **dstData, long *dstDataSize)
{
    Ptr p;
    OSErr err;
    if (!srcDataSize)
        return paramErr;
    p = NewPtr(srcDataSize);
    err = MemError();
    if (err) return err;
    {
        Ptr p1 = srcData, p2 = p;
        long counter = srcDataSize;
        while (counter--)
            *p2++ = ~*p1++;
    }
    *dstData = p;
    *dstDataSize = srcDataSize;
    return noErr;
}
pascal ComponentResult TestTranscoderDisposeData (Handle storage, void *dstData)
{
    DisposePtr((Ptr)dstData);
    return noErr;
}
pascal ComponentResult TestTranscoderEndSequence (Handle storage)
{
    return noErr;
}