654 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			654 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
 * $Id$
 | 
						|
 *
 | 
						|
 * quicktime_import.c
 | 
						|
 *
 | 
						|
 * Code to use Quicktime to load images/movies as texture.
 | 
						|
 *
 | 
						|
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License
 | 
						|
 * as published by the Free Software Foundation; either version 2
 | 
						|
 * of the License, or (at your option) any later version. The Blender
 | 
						|
 * Foundation also sells licenses for use in proprietary software under
 | 
						|
 * the Blender License.  See http://www.blender.org/BL/ for information
 | 
						|
 * about this.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; if not, write to the Free Software Foundation,
 | 
						|
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 | 
						|
 *
 | 
						|
 *
 | 
						|
 * The Original Code is written by Rob Haarsma (phase)
 | 
						|
 *
 | 
						|
 * Contributor(s): Stefan Gartner (sgefant)
 | 
						|
 *
 | 
						|
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 | 
						|
 */
 | 
						|
#ifdef WITH_QUICKTIME
 | 
						|
 | 
						|
#if defined(_WIN32) || defined(__APPLE__)
 | 
						|
 | 
						|
#include "IMB_anim.h"
 | 
						|
#include "BLO_sys_types.h"
 | 
						|
 | 
						|
#ifdef __APPLE__
 | 
						|
#include <QuickTime/Movies.h>
 | 
						|
#include <QuickTime/QuickTimeComponents.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef _WIN32
 | 
						|
#include <Movies.h>
 | 
						|
#include <QTML.h>
 | 
						|
#include <TextUtils.h>
 | 
						|
#include <QuickTimeComponents.h>
 | 
						|
#endif /* _WIN32 */
 | 
						|
 | 
						|
#include "quicktime_import.h"
 | 
						|
 | 
						|
 | 
						|
#define	RECT_WIDTH(r)	(r.right-r.left)
 | 
						|
#define	RECT_HEIGHT(r)	(r.bottom-r.top)
 | 
						|
 | 
						|
#define QTIME_DEBUG 0
 | 
						|
 | 
						|
 | 
						|
int anim_is_quicktime (char *name)
 | 
						|
{
 | 
						|
	FSSpec	theFSSpec;
 | 
						|
	Str255  dst;
 | 
						|
	char	theFullPath[255];
 | 
						|
 | 
						|
	Boolean						isMovieFile = false;
 | 
						|
	AliasHandle					myAlias = NULL;
 | 
						|
	Component					myImporter = NULL;
 | 
						|
#ifdef __APPLE__
 | 
						|
	FInfo						myFinderInfo;
 | 
						|
	FSRef						myRef;
 | 
						|
#endif
 | 
						|
	OSErr						err = noErr;
 | 
						|
			
 | 
						|
	// dont let quicktime movie import handle these
 | 
						|
	if( BLI_testextensie(name, ".swf") ||
 | 
						|
		BLI_testextensie(name, ".txt") ||
 | 
						|
		BLI_testextensie(name, ".mpg") ||
 | 
						|
		BLI_testextensie(name, ".avi") ||	// wouldnt be appropriate ;)
 | 
						|
		BLI_testextensie(name, ".wav") ||
 | 
						|
		BLI_testextensie(name, ".zip") ||
 | 
						|
		BLI_testextensie(name, ".mp3")) return 0;
 | 
						|
 | 
						|
	if(QTIME_DEBUG) printf("qt: checking as movie\n");
 | 
						|
 | 
						|
	sprintf(theFullPath, "%s", name);
 | 
						|
#ifdef __APPLE__
 | 
						|
	err = FSPathMakeRef(theFullPath, &myRef, 0);
 | 
						|
	err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
 | 
						|
#else
 | 
						|
	CopyCStringToPascal(theFullPath, dst);
 | 
						|
	err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef __APPLE__
 | 
						|
	// see whether the file type is MovieFileType; to do this, get the Finder information
 | 
						|
	err = FSpGetFInfo(&theFSSpec, &myFinderInfo);
 | 
						|
	if (err == noErr) {
 | 
						|
		if (myFinderInfo.fdType == kQTFileTypeMovie) {
 | 
						|
			return(true);
 | 
						|
		}
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
/* on mac os x this results in using quicktime for other formats as well
 | 
						|
 * not sure whether this is intended
 | 
						|
 */
 | 
						|
	// if it isn't a movie file, see whether the file can be imported as a movie
 | 
						|
	err = QTNewAlias(&theFSSpec, &myAlias, true);
 | 
						|
	if (err == noErr) {
 | 
						|
		if (myAlias != NULL) {
 | 
						|
			err = GetMovieImporterForDataRef(rAliasType, (Handle)myAlias, kGetMovieImporterDontConsiderGraphicsImporters, &myImporter);
 | 
						|
			DisposeHandle((Handle)myAlias);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	if ((err == noErr) && (myImporter != NULL)) {		// this file is a movie file
 | 
						|
		isMovieFile = true;
 | 
						|
	}
 | 
						|
 | 
						|
	return(isMovieFile);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void free_anim_quicktime (struct anim *anim) {
 | 
						|
	if (anim == NULL) return;
 | 
						|
	if (anim->qtime == NULL) return;
 | 
						|
 | 
						|
	UnlockPixels(anim->qtime->offscreenPixMap);
 | 
						|
 | 
						|
	if(anim->qtime->have_gw)
 | 
						|
		DisposeGWorld( anim->qtime->offscreenGWorld );
 | 
						|
	if(anim->qtime->ibuf)
 | 
						|
		IMB_freeImBuf(anim->qtime->ibuf);
 | 
						|
 | 
						|
	DisposeMovie( anim->qtime->movie );
 | 
						|
	CloseMovieFile( anim->qtime->movieRefNum );
 | 
						|
 | 
						|
	if(anim->qtime->frameIndex) MEM_freeN (anim->qtime->frameIndex);
 | 
						|
	if(anim->qtime) MEM_freeN (anim->qtime);
 | 
						|
 | 
						|
	anim->qtime = NULL;
 | 
						|
 | 
						|
	anim->duration = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
OSErr QT_get_frameIndexes(struct anim *anim)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	OSErr	anErr = noErr;
 | 
						|
	OSType	media = VideoMediaType;
 | 
						|
	TimeValue nextTime = 0;
 | 
						|
	TimeValue	startPoint;
 | 
						|
	TimeValue	tmpstartPoint;
 | 
						|
 | 
						|
	startPoint = -1;
 | 
						|
 | 
						|
	GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample+nextTimeEdgeOK, (TimeValue)1, &media, 0, 
 | 
						|
								1, &startPoint, NULL);
 | 
						|
 | 
						|
	tmpstartPoint = startPoint;
 | 
						|
 | 
						|
	anim->qtime->framecount = 0;
 | 
						|
 | 
						|
	while(tmpstartPoint != -1) {
 | 
						|
		nextTime = 0;
 | 
						|
		GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, tmpstartPoint, 0, &nextTime, NULL);
 | 
						|
		tmpstartPoint = nextTime;
 | 
						|
		anim->qtime->framecount ++;
 | 
						|
	}
 | 
						|
	anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex");
 | 
						|
 | 
						|
	//rewind
 | 
						|
	GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, (TimeValue)1, 0, &tmpstartPoint, NULL);
 | 
						|
 | 
						|
	anim->qtime->frameIndex[0] = startPoint;
 | 
						|
	for(i = 1; i < anim->qtime->framecount; i++) {
 | 
						|
		nextTime = 0;
 | 
						|
		GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, startPoint, 0, &nextTime, NULL);
 | 
						|
		startPoint = nextTime;
 | 
						|
		anim->qtime->frameIndex[i] = nextTime;
 | 
						|
	}
 | 
						|
 | 
						|
	anErr = GetMoviesError();
 | 
						|
	return anErr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
ImBuf * qtime_fetchibuf (struct anim *anim, int position)
 | 
						|
{
 | 
						|
	PixMapHandle			myPixMap = NULL;
 | 
						|
	Ptr						myPtr;
 | 
						|
 | 
						|
	register int		index;
 | 
						|
	register int		boxsize;
 | 
						|
 | 
						|
	register uint32_t	*readPos;
 | 
						|
	register uint32_t	*changePos;
 | 
						|
 | 
						|
	ImBuf *ibuf = NULL;
 | 
						|
	unsigned int *rect;
 | 
						|
	unsigned char *crect;
 | 
						|
 | 
						|
	if (anim == NULL) {
 | 
						|
		return (NULL);
 | 
						|
	}
 | 
						|
 | 
						|
	ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect, 0);
 | 
						|
	rect = ibuf->rect;
 | 
						|
 | 
						|
	SetMovieTimeValue(anim->qtime->movie, anim->qtime->frameIndex[position]);
 | 
						|
	UpdateMovie(anim->qtime->movie);
 | 
						|
	MoviesTask(anim->qtime->movie, 0);
 | 
						|
 | 
						|
 | 
						|
	myPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
 | 
						|
	myPtr = GetPixBaseAddr(myPixMap);
 | 
						|
 | 
						|
	if (myPtr == NULL) {
 | 
						|
		printf ("Error reading frame from Quicktime");
 | 
						|
		IMB_freeImBuf (ibuf);
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	boxsize = anim->x * anim->y;
 | 
						|
	readPos = (uint32_t *) myPtr;
 | 
						|
	changePos = (uint32_t *) rect; //textureIMBuf *THE* data pointerrr
 | 
						|
 | 
						|
#ifdef __APPLE__
 | 
						|
	// Swap alpha byte to the end, so ARGB become RGBA; note this is
 | 
						|
 // big endian-centric.
 | 
						|
	for( index = 0; index < boxsize; index++, changePos++, readPos++ )
 | 
						|
		*( changePos ) = ( ( *readPos & 0xFFFFFF ) << 8 ) |
 | 
						|
			( ( *readPos >> 24 ) & 0xFF );
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef _WIN32
 | 
						|
	for( index = 0; index < boxsize; index++, changePos++, readPos++ )
 | 
						|
		*( changePos ) =  *(readPos );
 | 
						|
 | 
						|
	if(anim->qtime->depth < 32) {
 | 
						|
		//add alpha to ibuf
 | 
						|
		boxsize = anim->x * anim->y * 4;
 | 
						|
		crect = (unsigned char *) rect;
 | 
						|
		for( index = 0; index < boxsize; index+=4, crect+=4 )
 | 
						|
			 crect[3] = 0xFF;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
	IMB_flipy(ibuf);
 | 
						|
	return ibuf;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// following two functions only here to get movie pixeldepth
 | 
						|
 | 
						|
int GetFirstVideoMedia(struct anim *anim)
 | 
						|
{
 | 
						|
	long    numTracks;
 | 
						|
	OSType  mediaType;
 | 
						|
 | 
						|
	numTracks = GetMovieTrackCount(anim->qtime->movie);
 | 
						|
 | 
						|
	for (anim->qtime->trackIndex=1; anim->qtime->trackIndex<=numTracks; (anim->qtime->trackIndex)++) {
 | 
						|
		anim->qtime->theTrack = GetMovieIndTrack(anim->qtime->movie, anim->qtime->trackIndex);
 | 
						|
 | 
						|
		if (anim->qtime->theTrack)
 | 
						|
			anim->qtime->theMedia = GetTrackMedia(anim->qtime->theTrack);
 | 
						|
 | 
						|
		if (anim->qtime->theMedia)
 | 
						|
			GetMediaHandlerDescription(anim->qtime->theMedia,&mediaType, nil, nil);
 | 
						|
		if (mediaType = VideoMediaType) return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	anim->qtime->trackIndex = 0;  // trackIndex can't be 0
 | 
						|
	return 0;      // went through all tracks and no video
 | 
						|
}
 | 
						|
 | 
						|
short GetFirstVideoTrackPixelDepth(struct anim *anim)
 | 
						|
{
 | 
						|
	SampleDescriptionHandle imageDescH =	(SampleDescriptionHandle)NewHandle(sizeof(Handle));
 | 
						|
	long	trackIndex = 0;
 | 
						|
	
 | 
						|
	if(!GetFirstVideoMedia(anim))
 | 
						|
		return -1;
 | 
						|
 | 
						|
	if (!anim->qtime->trackIndex || !anim->qtime->theMedia) return -1;  // we need both
 | 
						|
	GetMediaSampleDescription(anim->qtime->theMedia, anim->qtime->trackIndex, imageDescH);
 | 
						|
 | 
						|
	return (*(ImageDescriptionHandle)imageDescH)->depth;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int startquicktime (struct anim *anim)
 | 
						|
{
 | 
						|
	FSSpec		theFSSpec;
 | 
						|
 | 
						|
	OSErr		err = noErr;
 | 
						|
	Str255		dst;
 | 
						|
	char		theFullPath[255];
 | 
						|
#ifdef __APPLE__
 | 
						|
	FSRef		myRef;
 | 
						|
#endif
 | 
						|
 | 
						|
	anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
 | 
						|
	anim->qtime->have_gw = FALSE;
 | 
						|
 | 
						|
	if (anim->qtime == NULL) {
 | 
						|
		if(QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	if(QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name);
 | 
						|
	sprintf(theFullPath, "%s", anim->name);
 | 
						|
	
 | 
						|
#ifdef __APPLE__
 | 
						|
	err = FSPathMakeRef(theFullPath, &myRef, 0);
 | 
						|
	err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
 | 
						|
#else
 | 
						|
	CopyCStringToPascal(theFullPath, dst);
 | 
						|
	FSMakeFSSpec(0, 0L, dst, &theFSSpec);
 | 
						|
#endif
 | 
						|
	
 | 
						|
	err = OpenMovieFile(&theFSSpec, &anim->qtime->movieRefNum, fsRdPerm);
 | 
						|
 | 
						|
	if (err == noErr) {
 | 
						|
		if(QTIME_DEBUG) printf("qt: movie opened\n");
 | 
						|
		err = NewMovieFromFile(&anim->qtime->movie,
 | 
						|
						   anim->qtime->movieRefNum,
 | 
						|
						   &anim->qtime->movieResId, NULL, newMovieActive, NULL);
 | 
						|
	}
 | 
						|
 | 
						|
	if (err) {
 | 
						|
		if(QTIME_DEBUG) printf("qt: bad movie\n", anim->name);
 | 
						|
		if (anim->qtime->movie) {
 | 
						|
			DisposeMovie(anim->qtime->movie);
 | 
						|
			MEM_freeN(anim->qtime);
 | 
						|
			if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	GetMovieBox(anim->qtime->movie, &anim->qtime->movieBounds);
 | 
						|
	anim->x = anim->qtime->movWidth = RECT_WIDTH(anim->qtime->movieBounds);
 | 
						|
	anim->y = anim->qtime->movHeight = RECT_HEIGHT(anim->qtime->movieBounds);
 | 
						|
	if(QTIME_DEBUG) printf("qt: got bounds\n", anim->name);
 | 
						|
 | 
						|
	if(anim->x == 0 && anim->y == 0) {
 | 
						|
		if(QTIME_DEBUG) printf("qt: error, no dimensions\n");
 | 
						|
		free_anim_quicktime(anim);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	anim->qtime->ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect, 0);
 | 
						|
 | 
						|
#ifdef _WIN32
 | 
						|
	err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
 | 
						|
		 k32RGBAPixelFormat,
 | 
						|
		 &anim->qtime->movieBounds,
 | 
						|
		 NULL, NULL, 0,
 | 
						|
		(unsigned char *)anim->qtime->ibuf->rect,
 | 
						|
		anim->x * 4);
 | 
						|
#else
 | 
						|
	err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
 | 
						|
		 k32ARGBPixelFormat,
 | 
						|
		 &anim->qtime->movieBounds,
 | 
						|
		 NULL, NULL, 0,
 | 
						|
		(unsigned char *)anim->qtime->ibuf->rect,
 | 
						|
		anim->x * 4);
 | 
						|
#endif /* _WIN32 */
 | 
						|
 | 
						|
	if(err == noErr) {
 | 
						|
		anim->qtime->have_gw = TRUE;
 | 
						|
 | 
						|
		SetMovieGWorld(anim->qtime->movie,
 | 
						|
				 anim->qtime->offscreenGWorld,
 | 
						|
				 GetGWorldDevice(anim->qtime->offscreenGWorld));
 | 
						|
 | 
						|
		QT_get_frameIndexes(anim);
 | 
						|
	}
 | 
						|
 | 
						|
	anim->qtime->offscreenPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
 | 
						|
	LockPixels(anim->qtime->offscreenPixMap);
 | 
						|
 | 
						|
	//fill blender's anim struct
 | 
						|
	anim->qtime->depth = GetFirstVideoTrackPixelDepth(anim);
 | 
						|
	
 | 
						|
	anim->duration = anim->qtime->framecount;
 | 
						|
	anim->params = 0;
 | 
						|
 | 
						|
	anim->interlacing = 0;
 | 
						|
	anim->orientation = 0;
 | 
						|
	anim->framesize = anim->x * anim->y * 4;
 | 
						|
 | 
						|
	anim->curposition = 0;
 | 
						|
 | 
						|
	if(QTIME_DEBUG) printf("qt: load %s %dx%dx%d frames %d\n", anim->name, anim->qtime->movWidth,
 | 
						|
		anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int imb_is_a_quicktime (char *name)
 | 
						|
{
 | 
						|
	GraphicsImportComponent		theImporter = NULL;
 | 
						|
 | 
						|
	FSSpec	theFSSpec;
 | 
						|
	Str255  dst;
 | 
						|
	char	theFullPath[255];
 | 
						|
 | 
						|
	Boolean						isMovieFile = false;
 | 
						|
	AliasHandle					myAlias = NULL;
 | 
						|
	Component					myImporter = NULL;
 | 
						|
#ifdef __APPLE__
 | 
						|
	FInfo						myFinderInfo;
 | 
						|
	FSRef						myRef;
 | 
						|
#endif
 | 
						|
	OSErr						err = noErr;
 | 
						|
 | 
						|
	if(QTIME_DEBUG) printf("qt: checking as image %s\n", name);
 | 
						|
 | 
						|
	// dont let quicktime image import handle these
 | 
						|
	if( BLI_testextensie(name, ".swf") ||
 | 
						|
		BLI_testextensie(name, ".txt") ||
 | 
						|
		BLI_testextensie(name, ".mpg") ||
 | 
						|
		BLI_testextensie(name, ".wav") ||
 | 
						|
		BLI_testextensie(name, ".mov") ||	// not as image, doesn't work
 | 
						|
		BLI_testextensie(name, ".avi") ||
 | 
						|
		BLI_testextensie(name, ".mp3")) return 0;
 | 
						|
 | 
						|
	sprintf(theFullPath, "%s", name);
 | 
						|
#ifdef __APPLE__
 | 
						|
	err = FSPathMakeRef(theFullPath, &myRef, 0);
 | 
						|
	err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
 | 
						|
#else
 | 
						|
	CopyCStringToPascal(theFullPath, dst);
 | 
						|
	err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
 | 
						|
#endif
 | 
						|
 | 
						|
	GetGraphicsImporterForFile(&theFSSpec, &theImporter);
 | 
						|
 | 
						|
	if (theImporter != NULL) {
 | 
						|
		if(QTIME_DEBUG) printf("qt: %s valid\n", name);
 | 
						|
		CloseComponent(theImporter);
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
ImBuf  *imb_quicktime_decode(unsigned char *mem, int size, int flags)
 | 
						|
{
 | 
						|
	Rect						myRect;
 | 
						|
	OSErr						err = noErr;
 | 
						|
	GraphicsImportComponent		gImporter = NULL;
 | 
						|
 | 
						|
	ImageDescriptionHandle		desc;
 | 
						|
 | 
						|
	ComponentInstance			dataHandler;
 | 
						|
	PointerDataRef dataref = (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord));
 | 
						|
 | 
						|
	int x, y, depth;
 | 
						|
	int have_gw = FALSE;
 | 
						|
	ImBuf *ibuf = NULL;
 | 
						|
	ImBuf *imbuf = NULL;
 | 
						|
	GWorldPtr	offGWorld;
 | 
						|
	PixMapHandle		myPixMap = NULL;
 | 
						|
 | 
						|
#ifdef __APPLE__
 | 
						|
	Ptr					myPtr;
 | 
						|
 | 
						|
	register int		index;
 | 
						|
	register int		boxsize;
 | 
						|
 | 
						|
	register uint32_t	*readPos;
 | 
						|
	register uint32_t	*changePos;
 | 
						|
 | 
						|
	ImBuf *wbuf = NULL;
 | 
						|
	unsigned int *rect;
 | 
						|
#endif
 | 
						|
 | 
						|
	if (mem == NULL)
 | 
						|
		goto bail;
 | 
						|
	
 | 
						|
	if(QTIME_DEBUG) printf("qt: attempt to load mem as image\n");
 | 
						|
 | 
						|
	(**dataref).data = mem;
 | 
						|
	(**dataref).dataLength = size;
 | 
						|
 | 
						|
	err = OpenADataHandler((Handle)dataref,
 | 
						|
							PointerDataHandlerSubType,
 | 
						|
							nil,
 | 
						|
							(OSType)0,
 | 
						|
							nil,
 | 
						|
							kDataHCanRead,
 | 
						|
							&dataHandler);
 | 
						|
	if (err != noErr) {
 | 
						|
		if(QTIME_DEBUG) printf("no datahandler\n");
 | 
						|
		goto bail;
 | 
						|
	}
 | 
						|
 | 
						|
	err = GetGraphicsImporterForDataRef((Handle)dataref, PointerDataHandlerSubType, &gImporter);
 | 
						|
	if (err != noErr) {
 | 
						|
		if(QTIME_DEBUG) printf("no graphimport\n");
 | 
						|
		goto bail;
 | 
						|
	}
 | 
						|
 | 
						|
	err = GraphicsImportGetNaturalBounds(gImporter, &myRect);
 | 
						|
	if (err != noErr) {
 | 
						|
		if(QTIME_DEBUG) printf("no bounds\n");
 | 
						|
		goto bail;
 | 
						|
	}
 | 
						|
 | 
						|
	err = GraphicsImportGetImageDescription (gImporter, &desc );
 | 
						|
	if (err != noErr) {
 | 
						|
		if(QTIME_DEBUG) printf("no imagedescription\n");
 | 
						|
		goto bail;
 | 
						|
	}
 | 
						|
 | 
						|
	x = RECT_WIDTH(myRect);
 | 
						|
	y = RECT_HEIGHT(myRect);
 | 
						|
	depth = (**desc).depth;
 | 
						|
 | 
						|
	if (flags & IB_test) {
 | 
						|
		ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
 | 
						|
		ibuf->ftype = QUICKTIME;
 | 
						|
		DisposeHandle((Handle)dataref);
 | 
						|
		if (gImporter != NULL)	CloseComponent(gImporter);
 | 
						|
		return ibuf;
 | 
						|
	}
 | 
						|
 | 
						|
#ifdef __APPLE__
 | 
						|
	ibuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);
 | 
						|
	wbuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);
 | 
						|
 | 
						|
	err = NewGWorldFromPtr(&offGWorld,
 | 
						|
						k32ARGBPixelFormat,
 | 
						|
						&myRect, NULL, NULL, 0,
 | 
						|
						(unsigned char *)wbuf->rect, x * 4);
 | 
						|
#else
 | 
						|
 | 
						|
	ibuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);	
 | 
						|
 | 
						|
	err = NewGWorldFromPtr(&offGWorld,
 | 
						|
							k32RGBAPixelFormat,
 | 
						|
							&myRect, NULL, NULL, 0,
 | 
						|
							(unsigned char *)ibuf->rect, x * 4);
 | 
						|
#endif
 | 
						|
	
 | 
						|
	if (err != noErr) {
 | 
						|
		if(QTIME_DEBUG) printf("no newgworld\n");
 | 
						|
		goto bail;
 | 
						|
	} else {
 | 
						|
		have_gw = TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
	GraphicsImportSetGWorld(gImporter, offGWorld, NULL);
 | 
						|
	GraphicsImportDraw(gImporter);
 | 
						|
 | 
						|
#ifdef __APPLE__
 | 
						|
	rect = ibuf->rect;
 | 
						|
 | 
						|
	myPixMap = GetGWorldPixMap(offGWorld);
 | 
						|
	LockPixels(myPixMap);
 | 
						|
	myPtr = GetPixBaseAddr(myPixMap);
 | 
						|
 | 
						|
	if (myPtr == NULL) {
 | 
						|
		printf ("Error reading frame from Quicktime");
 | 
						|
		IMB_freeImBuf (ibuf);
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	boxsize = x * y;
 | 
						|
	readPos = (uint32_t *) myPtr;
 | 
						|
	changePos = (uint32_t *) rect;
 | 
						|
 | 
						|
	for( index = 0; index < boxsize; index++, changePos++, readPos++ )
 | 
						|
		*( changePos ) = ( ( *readPos & 0xFFFFFF ) << 8 ) |
 | 
						|
			( ( *readPos >> 24 ) & 0xFF );
 | 
						|
#endif
 | 
						|
 | 
						|
bail:
 | 
						|
 | 
						|
	DisposeHandle((Handle)dataref);
 | 
						|
	UnlockPixels(myPixMap);
 | 
						|
	if(have_gw) DisposeGWorld(offGWorld);
 | 
						|
 | 
						|
#ifdef __APPLE__
 | 
						|
	if (wbuf) {
 | 
						|
		IMB_freeImBuf (wbuf);
 | 
						|
		wbuf = NULL;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
	if (gImporter != NULL)	CloseComponent(gImporter);
 | 
						|
 | 
						|
	if (err != noErr) {
 | 
						|
		if(QTIME_DEBUG) printf("quicktime import unsuccesfull\n");
 | 
						|
		if (ibuf) {
 | 
						|
			IMB_freeImBuf (ibuf);
 | 
						|
			ibuf = NULL;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if(ibuf) {
 | 
						|
#ifdef _WIN32
 | 
						|
		// add alpha layer, might also be nescessary for OSX
 | 
						|
		int i;
 | 
						|
		int box = x * y;
 | 
						|
		unsigned char *arect = (unsigned char *) ibuf->rect;
 | 
						|
 | 
						|
		if(depth < 32)
 | 
						|
			for(i = 0; i < box; i++, arect+=4)
 | 
						|
				 arect[3] = 0xFF;
 | 
						|
#endif
 | 
						|
		IMB_flipy(ibuf);
 | 
						|
		ibuf->ftype = QUICKTIME;
 | 
						|
	}
 | 
						|
	return ibuf;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* _WIN32 || __APPLE__ */
 | 
						|
 | 
						|
#endif /* WITH_QUICKTIME */
 | 
						|
 | 
						|
 | 
						|
#if 0
 | 
						|
 | 
						|
struct ImageDescription {
 | 
						|
     long         idSize;
 | 
						|
     CodecType    cType;
 | 
						|
     long         resvd1;
 | 
						|
     short        resvd2;
 | 
						|
     short        dataRefIndex;
 | 
						|
     short        version;
 | 
						|
     short        revisionLevel;
 | 
						|
     long         vendor;
 | 
						|
     CodecQ       temporalQuality;
 | 
						|
     CodecQ       spatialQuality;
 | 
						|
     short        width;
 | 
						|
     short        height;
 | 
						|
     Fixed        hRes;
 | 
						|
     Fixed        vRes;
 | 
						|
     long         dataSize;
 | 
						|
     short        frameCount;
 | 
						|
     Str31        name;
 | 
						|
     short        depth;
 | 
						|
     short        clutID;
 | 
						|
};
 | 
						|
 | 
						|
#endif // 0
 |