Compression & Scaling.c

/*
    File:       Compression & Scaling.c
 
    Contains:   This example shows how to convert a version 2 PICT to a compressed QuickTime data buffer.
                Once the PICT is compressed, it is then decompressed to the window at one quarter 
                its original size.
 
    Written by: Edgar Lee   
 
    Copyright:  Copyright © 1991-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/28/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                12/4/94     khs             changed the format of the file to the new look and feel
 
*/
 
 
// INCLUDES
#include    <GestaltEqu.h>
#include    <ToolUtils.h>
#include    <SegLoad.h>
#include    <Fonts.h>
 
#include    <ImageCompression.h>
#include    <Movies.h>
 
/* Constant Declarations */
 
#define WLEFT( x )  (((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - x) / 2)
#define WTOP( x )   (((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - x) / 2)
#define PICTID 128
 
// GLOBALS
WindowPtr gWindow;
 
 
// FUNCTION PROTOTYPES
void InitMac();
void CheckForQuickTime();
void DoScaleTest();
void CreateWindow();
 
 
// MAIN
void main(void)
{
    InitMac();
    CheckForQuickTime();
 
    CreateWindow();
    DoScaleTest();
 
    while (!Button())
        ;
}
 
 
void InitMac()
{
    InitGraf(&qd.thePort);
    InitFonts();
    InitWindows();
    InitMenus();
    TEInit();
    InitDialogs(nil);
    InitCursor();
    FlushEvents(0, everyEvent);
}
 
 
void CheckForQuickTime()
{
    long version;
 
    if (Gestalt(gestaltQuickTime, &version) != noErr)
    {
        ParamText("\pQuickTime not installed.  Please install, then try again.", "\p", "\p", "\p");
        Alert(128, nil);
        ExitToShell();
    }
}
 
 
void CreateWindow()
{
    Rect bounds =
    {
        0,  0, 0, 0
    };
 
    gWindow = NewCWindow(0L, &bounds, "\pDecompression & Scaling", 
                            false, documentProc, (WindowPtr) - 1L, false, 0L);
 
    SetPort(gWindow);
}
 
 
void DoScaleTest()
{
    int i;
    GWorldPtr srcGWorld;
    PixMapHandle srcPixMap;
    PicHandle pict;
    Rect pictBounds;
    Rect finalBounds;
    CGrafPtr savedPort;
    GDHandle savedDevice;
    short scaleRatio = 4;
 
    ImageDescriptionHandle desc;
    Ptr imageData;
    long size;
 
    // Load the picture and define the source and dest rects.
    pict = GetPicture(PICTID);
 
    pictBounds = (**pict).picFrame;
    OffsetRect(&pictBounds, -pictBounds.left, -pictBounds.top);
 
    finalBounds = pictBounds;
    finalBounds.right = finalBounds.right / scaleRatio;
    finalBounds.bottom = finalBounds.bottom / scaleRatio;
 
    SizeWindow(gWindow, pictBounds.right + finalBounds.right, pictBounds.bottom, false);
    MoveWindow(gWindow, WLEFT(pictBounds.right + finalBounds.right), 
                        WTOP(pictBounds.bottom), false);
    ShowWindow(gWindow);
 
    /********************************************************/
    /* Create a temporary offscreen used to store the pict. */
    /********************************************************/
 
    if (NewGWorld(&srcGWorld, 8, &pictBounds, GetCTable(8), nil, 0) != noErr)
        ExitToShell();
 
    srcPixMap = GetGWorldPixMap(srcGWorld);
    LockPixels(srcPixMap);
 
    /********************************************************/
    /* Draw the picture into the temporary gworld & window. */
    /********************************************************/
 
    GetGWorld(&savedPort, &savedDevice);
    SetGWorld(srcGWorld, nil);
    DrawPicture(pict, &pictBounds);
 
    SetGWorld(savedPort, savedDevice);
    DrawPicture(pict, &pictBounds);
 
    /*************************************************/
    /* Now, compress the picture into a data buffer, */
    /*   then dispose the temporary gworld.          */
    /*************************************************/
 
    if (GetMaxCompressionSize(srcPixMap, &(**srcPixMap).bounds, 8, codecMaxQuality, 
                                'raw ', bestSpeedCodec, &size))
        ExitToShell();
 
    imageData = NewPtr(size);
    desc = (ImageDescriptionHandle)NewHandle((Size)1);
 
    if (CompressImage(srcPixMap, &(**srcPixMap).bounds, codecMaxQuality, 
                        'raw ', desc, imageData))
        ExitToShell();
 
    DisposeGWorld(srcGWorld);
 
    /**********************************************************/
    /* Decompress the data buffer to the window with scaling. */
    /**********************************************************/
 
    OffsetRect(&finalBounds, pictBounds.right, 0);
 
    for (i = 0; i < scaleRatio; i++)
    {
        DecompressImage(imageData, desc, (*(CWindowPtr)gWindow).portPixMap, 
                            &pictBounds, &finalBounds, srcCopy + ditherCopy, nil);
 
        OffsetRect(&finalBounds, 0, finalBounds.bottom - finalBounds.top);
    }
}