Compressed PICT Info.c

/*
    File:       Compressed PICT Info.c
 
    Contains:   This snippet shows how to use the StdPix proc to        
                intercept and display the compression type and depth        
                of any compressed PICT within a PICT resource.  The         
                same procedure can be used to gather other information      
                about the compressed PICT.  Note that all compressed        
                PICTs get passed into StdPix before getting decom-      
                pressed and passed to StdBits.  
 
    Written by: Edgar Lee   
 
    Copyright:  Copyright © 1992-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/8/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
 
#include <ImageCompression.h>
#include <Movies.h>
#include <Fonts.h>
#include <Gestalt.h>
#include <Resources.h>
#include <TextUtils.h>
 
/* Constant Declarations */
 
#define WWIDTH  170
#define WHEIGHT 220
 
#define WLEFT   (((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - WWIDTH) / 2)
#define WTOP    (((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - WHEIGHT) / 2)
 
/* Global Variable Definitions */
 
CodecType   gCodec = 'unkn';
int         gDepth;
 
void initMac();
void checkForQuickTime();
 
void createWindow();
void doEventLoop();
 
void doBottleneckTest();
pascal void myStdPix( PixMapPtr src, Rect *srcRect, MatrixRecordPtr matrix,
                        short mode, RgnHandle mask, PixMapPtr matte,
                        Rect *matteRect, short flags );
pascal void myTextProc( short byteCount, Ptr textBuf, Point numer, Point denom );
pascal void myLineProc( Point newPt );
pascal void myRectProc( GrafVerb verb, Rect *r );
pascal void myRRectProc( GrafVerb verb, Rect *r, short ovalWidth, short ovalHeight );
pascal void myOvalProc( GrafVerb verb, Rect *r );
pascal void myArcProc( GrafVerb verb, Rect *r, short startAngle, short arcAngle );
pascal void myPolyProc( GrafVerb verb, PolyHandle poly );
pascal void myRgnProc( GrafVerb verb, RgnHandle rgn );
pascal void myBitsProc( BitMap *bitPtr, Rect *srcRect, Rect *dstRect,
                        short mode, RgnHandle maskRgn );
void DrawCompressionType( CodecType codec, int col, int row );
void DrawCompressionDepth( int depth, int col, int row );
        
 
void main()
{
    initMac();
    checkForQuickTime();
    
    createWindow();
    doEventLoop();
}
 
void initMac()
{
    MaxApplZone();
 
    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        rect;
    WindowPtr   window;
    
    SetRect( &rect, WLEFT, WTOP, WLEFT + WWIDTH, WTOP + WHEIGHT );
    window = NewCWindow( 0L, &rect, "\pStdPix", true, documentProc,
                            (WindowPtr)-1L, true, 0L );                     
    SetPort( window );
    
    TextMode( srcCopy );
    TextSize( 9 );
    TextFont( kFontIDGeneva );
}
 
pascal void myStdPix( PixMapPtr src, Rect *srcRect, MatrixRecordPtr matrix,
                        short mode, RgnHandle mask, PixMapPtr matte,
                        Rect *matteRect, short flags )
{
    #pragma unused(srcRect,matrix,mode,mask,matte,matteRect,flags)
    ImageDescriptionHandle      desc;
    Ptr                         data;
    long                        bufferSize;
    
    GetCompressedPixMapInfo( src, &desc, &data, &bufferSize, nil, nil );
    gCodec = (**desc).cType;
    gDepth = (**desc).depth;
}
 
pascal
 void myTextProc( short byteCount, Ptr textBuf, Point numer, Point denom )
{
    #pragma unused(byteCount,textBuf,numer,denom)
}
 
pascal void myLineProc( Point newPt )
{
    #pragma unused(newPt)
}
 
pascal void myRectProc( GrafVerb verb, Rect *r )
{
    #pragma unused(verb,r)
}
 
pascal void myRRectProc( GrafVerb verb, Rect *r, short ovalWidth, short ovalHeight )
{
    #pragma unused(verb,r,ovalWidth,ovalHeight)
}
 
pascal void myOvalProc( GrafVerb verb, Rect *r )
{
    #pragma unused(verb,r)
}
 
pascal void myArcProc( GrafVerb verb, Rect *r, short startAngle, short arcAngle )
{
    #pragma unused(verb,r,startAngle,arcAngle)
}
 
pascal void myPolyProc( GrafVerb verb, PolyHandle poly )
{
    #pragma unused(verb,poly)
}
 
pascal void myRgnProc( GrafVerb verb, RgnHandle rgn )
{
    #pragma unused(verb,rgn)
}
 
pascal void myBitsProc( BitMap *bitPtr, Rect *srcRect, Rect *dstRect,
                        short mode, RgnHandle maskRgn )
{
    #pragma unused(bitPtr,srcRect,dstRect,mode,maskRgn)
}
 
void DrawCompressionType( CodecType codec, int col, int row )
{
    MoveTo( col, row );
    
    if (codec == 'rpza')
        DrawString( "\pVideo Compression" );
    else if (codec == 'jpeg')
        DrawString( "\pJPEG Compression" );
    else if (codec == 'rle ')
        DrawString( "\pAnimation Compression" );
    else if (codec == 'raw ')
        DrawString( "\pRaw Compression" );
    else if (codec == 'smc ')
        DrawString( "\pGraphics Compression" );
    else
        DrawString( "\pUnknown Compression" );
}
 
void DrawCompressionDepth( int depth, int col, int row )
{
    Str255  string;
    
    NumToString( (long)depth, string );
    
    MoveTo( col, row );
    DrawString( "\pImage Depth:" );
    
    MoveTo( col + 70, row );
    DrawString( string );
}
 
void doBottleneckTest()
{
    int         i;
    PicHandle   picture;
    Rect        rect;
    CQDProcs    bottlenecks;
 
    /* Define our own bottlenecks to do nothing. */
    SetStdCProcs( &bottlenecks );
    
    bottlenecks.textProc    = NewQDTextProc(myTextProc);
    bottlenecks.lineProc    = NewQDLineProc(myLineProc);
    bottlenecks.rectProc    = NewQDRectProc(myRectProc);
    bottlenecks.rRectProc   = NewQDRRectProc(myRRectProc);
    bottlenecks.ovalProc    = NewQDOvalProc(myOvalProc);
    bottlenecks.arcProc     = NewQDArcProc(myArcProc);
    bottlenecks.polyProc    = NewQDPolyProc(myPolyProc);
    bottlenecks.rgnProc     = NewQDRgnProc(myRgnProc);
    bottlenecks.bitsProc    = NewQDBitsProc(myBitsProc);
    bottlenecks.newProc1    =NewQDPixProc(myStdPix);        /* pixProc */
    
    for (i = 0; i < Count1Resources( 'PICT' ); i++)
    {
        /* Load & draw pictures from resource. */
        picture = (PicHandle)Get1IndResource( 'PICT', i + 1 );
        
        rect = (**picture).picFrame;
        OffsetRect( &rect, -rect.left, -rect.top );
        OffsetRect( &rect, 10, ((rect.bottom - rect.top) + 10) * i + 10 );
                
        DrawPicture( picture, &rect );
        
        /* Install our custom bottlenecks to intercept any compressed images. */
        (*(qd.thePort)).grafProcs = (QDProcs *)&bottlenecks;
         DrawPicture( picture, &((**picture).picFrame) );
         
        /* Switch back to the default procs. */
        (*(qd.thePort)).grafProcs = 0L;
     
        /* Free any memory used by the picture. */
        ReleaseResource( (Handle)picture );
        
        /* Display the compression type. */
        DrawCompressionType( gCodec, rect.right + 10, rect.top + 10 );
        DrawCompressionDepth( gDepth, rect.right + 10, rect.top + 25 );
        gCodec = 'unkn';
    }
}
 
void doEventLoop()
{
    EventRecord event;
    WindowPtr   window;
    short       clickArea;
    Rect        screenRect;
 
    for (;;)
    {
        if (WaitNextEvent( everyEvent, &event, 0, nil ))
        {
            if (event.what == mouseDown)
            {
                clickArea = FindWindow( event.where, &window );
                
                if (clickArea == inDrag)
                {
                    screenRect = (**GetGrayRgn()).rgnBBox;
                    DragWindow( window, event.where, &screenRect );
                }
                else if (clickArea == inContent)
                {
                    if (window != FrontWindow())
                        SelectWindow( window );
                }
                else if (clickArea == inGoAway)
                    if (TrackGoAway( window, event.where ))
                        return;
            }
            else if (event.what == updateEvt)
            {
                window = (WindowPtr)event.message;  
                SetPort( window );
                
                BeginUpdate( window );
                doBottleneckTest();
                EndUpdate( window );
            }
        }
    }
}