// Graphics Importer and Exporter Samples
// This example demonstrates how to extract image information
// using Graphics Importers
// Originally written by Sam Bushell for QuickTime "Live" '99
// WWDC 2000 Introduction to QuickTime
// Note: This application uses standard output (and SIOUX on the Mac)

#include "MacShell.h"

#ifndef __APPLE_CC__
    #include <SIOUX.h>
    #include <Console.h>
    #include <stdio.h>
#endif

void GetMoreInfo( void )
{  	
	OSErr err = noErr;
	Handle hOpenTypeList = NewHandle(0);
	long  numTypes = 0;
	FSSpec	theFSSpec;
	GraphicsImportComponent importer = 0;
	Str31 name;
	OSType udType;
	short count, i;
	Handle h = NULL;
	Ptr p;
	char nul = 0;
// Insert Variables.clp here...	


	MatrixRecord defaultMatrix;
	RGBColor defaultOpColor;
	Rect defaultSourceRect;
	Handle colorSyncProfile = NULL;
	RgnHandle defaultClip = NULL;
	long defaultGraphicsMode;
	short drawsAllPixels;
	
#ifndef __APPLE_CC__
	SIOUXSettings.standalone = false;
   	SIOUXSettings.initializeTB = false;
   	SIOUXSettings.setupmenus = false;
   	SIOUXSettings.autocloseonquit = true;
   	SIOUXSettings.asktosaveonclose = false;
   	SIOUXSetTitle( "\pGet More Info" );
#endif

	printf( "Choose an image file...\n\n" );

	BuildGraphicsImporterValidFileTypes( hOpenTypeList, &numTypes );
	HLock( hOpenTypeList );
	
	// prompt for an image file.
	err = GetOneFileWithPreview(numTypes, (OSTypePtr)*hOpenTypeList, &theFSSpec, NULL);
	DisposeHandle( hOpenTypeList );
	if (err) return;
	
	// locate and open a graphics importer component
	err = GetGraphicsImporterForFile( &theFSSpec, &importer );

	// get the file's image description.
// Step 1. Insert GetImageDescription.clp here...

	if( desc && *desc ) {
		// print basic statistics from the image description.
		printf( "Image width:   %d\n", (*desc)->width );
		printf( "Image height:  %d\n", (*desc)->height );
		printf( "Depth:         %d\n", (*desc)->depth );
		BlockMoveData( (*desc)->name, name, sizeof(name) );
		CopyPascalStringToC(name, (char *)name);
		printf( "Format:        %s\n", name);
		printf( "Resolution:    %.1f x %.1f dpi\n", Fix2X((*desc)->hRes), Fix2X((*desc)->vRes) );
		
		// an image description may contain a CLUT (Color Look Up Table)
		if( ((*desc)->depth < 16) || ((*desc)->depth > 32) ) {
			// get the CTable from the image description
// Step 2. Insert CTable.clp here...

			if( colorTable ) {
				printf( "\nImage has a color table.\n" );
				DisposeCTable( colorTable );
			}
		}
	}
		
	// NOTE: GraphicsImportGetNaturalBounds() is just shorthand that builds a 
	// rectangle from the image description's width and height.
	
	// get and print out the file's metadata
	
	// create a new user data structure  
// Step 3. Insert NewUserData.clp here...

	
	// extract metadata from an image and add it to an already alocated user data structure
// Step 4. Insert GetMetaData.clp here...
	
	h = NewHandle(0);
	
	//  retrieve the first user data type from the user data list
// Step 5. Insert GetNextUserDataType.clp here...

	if( 0 != udType ) {
		printf( "\nMeta-data:\n" );
		do {			
			// determine the number of items of a given type in a user data list
			count = CountUserDataType( userData, udType );
			for( i = 1; i <= count; i++ ) {
				// if the first letter of udType is 0xA9, the copyright symbol, 
				// then use GetUserDataText instead of GetUserData
				// there's a list of interesting user data types in <Movies.h>
				if( (udType>>24) == 0xA9 ) {
					// retrieve language-tagged text from an item
					err = GetUserDataText( userData,		// user data list
										   h,				// handle to recieve the data
										   udType,			// user item's type value
										   i,				// item's index value
										   langEnglish );	// language code of text to be retrieved	
					// nul-terminate the string in the handle.
					PtrAndHand( &nul, h, 1 );
					// turn any CRs into spaces (to work around SIOUX behavior).
					p = *h; while( *p ) { if( *p == 13 ) *p = ' '; p++; };
					HLock( h );
					printf( "  %c%c%c%c: %s\n", (char)(udType>>24), (char)(udType>>16), 
							(char)(udType>>8), (char)udType, *h );
					HUnlock( h );
				}
				else {
					// get a specified user data item
					err = GetUserData( userData,	// user data list
									   h,			// handle to recieve the data
									   udType,		// user item's type value
									   i );			// item's index value
					printf( "  %c%c%c%c: [%d bytes]\n", (char)(udType>>24), (char)(udType>>16), 
							(char)(udType>>8), (char)udType, GetHandleSize(h) );
				}
			}
			//  retrieve the next user data type from the user data list
			udType = GetNextUserDataType( userData, udType );
		} while( 0 != udType );
	}
	DisposeUserData( userData );
	DisposeHandle( h );
	printf( "\n" );
	
	// print out some more esoteric properties
// Insert Step6.clp here...

	
	// might this image have holes?  
	drawsAllPixels = graphicsImporterDrawsAllPixels;
	// find out if the graphics importer expects to draw every pixel
	// as some image file formats permit non-rectangular images or images
	// with transparent regions when such an image is drawn, not every
	// pixel in the boundary rectangle will be changed
	// ignore any error
// Step 7. Insert DoesDrawAllPixels.clp here...

	switch( drawsAllPixels ) {
		case graphicsImporterDrawsAllPixels:
			printf( "Image will overwrite every pixel in its DestRect.\n" );
			break;
		case graphicsImporterDoesntDrawAllPixels:
			printf( "Image will not overwrite every pixel in its DestRect.\n" );
			break;
		case graphicsImporterDontKnowIfDrawAllPixels:
			printf( "Image may or may not overwrite every pixel in its DestRect.\n" );
			break;
	}

	// Note: In a multiple-image file, the image description, metadata, 
	// default settings, etc. can be different for each image.
	
	CloseComponent( importer );
	DisposeHandle( (Handle)desc );
	if( defaultClip ) DisposeRgn( defaultClip );
	DisposeHandle( colorSyncProfile );
	
	pause();
}