MoofEncoder/PICTMask.cp

/*
    File:       PICTMask.cp
 
    Contains:   
 
    Written by: Timothy Carroll 
 
    Copyright:  Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/1/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                2/23/98     Timothy Carroll When we created the PICT, we weren't setting
                                            the clip rectangle.  The default clipping region
                                            would cause problems if we ever scaled the PICT 
                                            when we draw it.
                2/24/97     Timothy Carroll Now explicitly include main.h
                8/15/96     Timothy Carroll Initial Release
                
                
                
 
*/
#include <Resources.h>
#include "Main.h"
#include "Color Search Procs.h"
#include "PICTMask.h"
 
OSStatus GeneratePICTMasks (short inputFileResNum, short outputFileResNum)
{
    OSStatus        theErr;
 
    UInt16          numPicts, loop;
    
    // we pass these to GetResInfo so that we can get the actual resource ID.
    SInt16          resID;
    ResType         resType;
    Str255          resName;
 
    // Holds the last value on the resource chain since we change the top resource a lot
    SInt16          saveResNum;
    
    // The current picture being worked on, along with its GWorld and Pixmap
    PicHandle       thePicture = NULL;
    GWorldPtr       pictGWorld = NULL;
    PixMapHandle    pictPixMap = NULL;
    OpenCPicParams  theParams; // used to build the output picture
    Rect            pictRect, drawRect, sourceRect;
    
    // Saves port info while we draw into the GWorld
    CGrafPtr        savePort;
    GDHandle        saveDevice;
    
    SInt16          offset;
    
    Boolean         pictIsResource = false; // Determines if we call ReleaseResource or DisposeHandle
    
    // Save off the current resource chain so that we can restore it later
    saveResNum = CurResFile();
 
    UseResFile (inputFileResNum);
 
 
 
    // First thing is to copy the color table resource to the output.
    theErr = CopyResource (inputFileResNum, outputFileResNum,'clut', kAppColorTableResID);
    FAIL_OSERR (theErr, "\pFailed to copy the color table to the destination file")
    
    // get the color table
    gAppColorTable = GetCTable( kAppColorTableResID );
    FAIL_NIL (gAppColorTable, "\pFailed to open the color table")
 
    // determine the number of icon resources
    numPicts = Count1Resources( 'PICT' );
    
    // get each one,
    for( loop = 1; loop <= numPicts; loop++ )
    {
    // *********************************************************************
    // Load the PICT and get the resource information
    // *********************************************************************
        UseResFile (inputFileResNum);
        pictIsResource = true;
        thePicture = (PicHandle) Get1IndResource ('PICT', loop);
        theErr = ResError();
        FAIL_NIL (thePicture, "\pFailed to load the picture")
        FAIL_OSERR (theErr, "\pFailed to load the picture")
        
        GetResInfo( (Handle) thePicture, &resID, &resType, resName );
        theErr = ResError();
        FAIL_OSERR( theErr, "\pFailed to get info on the resource")
        
    // *********************************************************************
    // Create a GWorld, erase it, and draw our pictures and masks into it
    // We'll have three images across, left to right, in the GWorld
    // *********************************************************************
        pictRect = (**thePicture).picFrame;
        OffsetRect (&pictRect, -pictRect.left, -pictRect.top);
        drawRect = pictRect;
        pictRect.right *= 3;
        offset = drawRect.right;
    
        theErr = NewGWorld(&pictGWorld, kPreferredDepth, &pictRect, gAppColorTable, NULL, 0);
        FAIL_OSERR (theErr, "\pFailed to allocate the GWorld")
        FAIL_NIL (pictGWorld, "\pFailed to allocate the GWorld")
    
        pictPixMap  = GetGWorldPixMap(pictGWorld);
        FAIL_NIL (pictPixMap, "\pCouldn't get the pixmap")
        FAIL_FALSE ( LockPixels(pictPixMap), "\pCouldn't lock the pixmap")
        
        GetGWorld (&savePort, &saveDevice);
        SetGWorld (pictGWorld, NULL);
    
        EraseRect (&pictRect);
        DrawPicture (thePicture, &drawRect);
        
        sourceRect = drawRect;
        
        drawRect.left +=offset;
        drawRect.right +=offset;
        
        // The top left corner of the picture is always assumed to be the Mask color!
        // We set our mask color and insert our search proc, then we copy the mask.
        
        GetCPixel (0,0, &gMaskColor);
        AddSearch (MaskSearchProcUPP);
        CopyBits ((BitMap *) *pictPixMap, (BitMap *) *pictPixMap,
                &sourceRect, &drawRect, srcCopy, NULL);
        DelSearch (MaskSearchProcUPP);
        
        sourceRect = drawRect;
        drawRect.left+=offset;
        drawRect.right+=offset;
        
        // The second is just a copy of the first.  No search is necessary
        CopyBits ((BitMap *) *pictPixMap, (BitMap *) *pictPixMap,
        &sourceRect, &drawRect, srcCopy, NULL);
 
    // *********************************************************************
    // We're done with the old picture, so we can release it and build the
    // new picture to add to the output file.
    // *********************************************************************
        ReleaseResource ((Handle) thePicture);
        thePicture = NULL;
    
        pictIsResource = false;
        
        theParams.srcRect = pictRect;
        theParams.hRes = 0x00480000;
        theParams.vRes = 0x00480000;
        theParams.version = -2;
        theParams.reserved1 = 0;
        theParams.reserved2 = 0;
    
        thePicture = OpenCPicture (&theParams);
        ClipRect (&pictRect);
        CopyBits ((BitMap *) *pictPixMap, (BitMap *) *pictPixMap, &pictRect, &pictRect, srcCopy, NULL);
        ClosePicture();
        theErr = QDError();
        FAIL_NIL (thePicture, "\pFailed to create the new picture")
        FAIL_OSERR (theErr, "\pFailed to create the new picture")
        
        SetGWorld (savePort, saveDevice);
    
    // *********************************************************************
    // Add the new PICT to the resource file
    // *********************************************************************
    // We're done with the GWorld
        DisposeGWorld (pictGWorld);
        pictGWorld = NULL;
    
        UseResFile (outputFileResNum);
        AddResource( (Handle) thePicture, 'PICT', resID, resName );
        theErr = ResError();
        FAIL_OSERR (theErr,"\pFailed to add the resource to the output file")
    
        pictIsResource = true;
    
        WriteResource( (Handle) thePicture );
        theErr = ResError();
        FAIL_OSERR (theErr,"\pFailed to write the resource to the output file")
    
        ReleaseResource( (Handle) thePicture );
        thePicture = NULL;
    }
    
    goto cleanup;
    
error:
    
    if (theErr == noErr)
        theErr = paramErr;
        
cleanup:
    
    UseResFile (saveResNum);
    
    if (pictGWorld != NULL)
        DisposeGWorld (pictGWorld);
    
    if (thePicture != NULL)
        if (pictIsResource)
            ReleaseResource ((Handle) thePicture);
        else
            DisposeHandle ((Handle) thePicture);
    
    if (gAppColorTable != NULL)
        DisposeCTable (gAppColorTable);
    gAppColorTable = NULL;
    return theErr;
}