Blender V2.61 - r43446

quicktime_import.c

Go to the documentation of this file.
00001 /*
00002  *
00003  * quicktime_import.c
00004  *
00005  * Code to use Quicktime to load images/movies as texture.
00006  *
00007  * ***** BEGIN GPL LICENSE BLOCK *****
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License
00010  * as published by the Free Software Foundation; either version 2
00011  * of the License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software Foundation,
00020  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021  *
00022  *
00023  * The Original Code is written by Rob Haarsma (phase)
00024  *
00025  * Contributor(s): Stefan Gartner (sgefant)
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00034 #ifdef WITH_QUICKTIME
00035 
00036 #if defined(_WIN32) || defined(__APPLE__)
00037 #ifndef USE_QTKIT
00038 
00039 #include "MEM_guardedalloc.h"
00040 #include "IMB_anim.h"
00041 #include "BLO_sys_types.h"
00042 #include "BKE_global.h"
00043 #include "BLI_dynstr.h"
00044 
00045 #ifdef __APPLE__
00046 #include <QuickTime/Movies.h>
00047 #include <QuickTime/QuickTimeComponents.h>
00048 #endif
00049 
00050 #ifdef _WIN32
00051 #include <Movies.h>
00052 #include <QTML.h>
00053 #include <TextUtils.h>
00054 #include <QuickTimeComponents.h>
00055 #include <QTLoadLibraryUtils.h>
00056 #endif /* _WIN32 */
00057 
00058 
00059 #include "quicktime_import.h"
00060 #include "quicktime_export.h"
00061 
00062 #define RECT_WIDTH(r)   (r.right-r.left)
00063 #define RECT_HEIGHT(r)  (r.bottom-r.top)
00064 
00065 #define QTIME_DEBUG 0
00066 
00067 typedef struct _QuicktimeMovie {
00068 
00069     GWorldPtr   offscreenGWorld;
00070     PixMapHandle    offscreenPixMap;
00071     Movie       movie;
00072     Rect        movieBounds;
00073     short       movieRefNum;
00074     short       movieResId;
00075     int         movWidth, movHeight;
00076 
00077     
00078     int         framecount;
00079     
00080     
00081     ImBuf       *ibuf;
00082     
00083 
00084     TimeValue   *frameIndex;
00085     Media       theMedia;
00086     Track       theTrack;
00087     long        trackIndex;
00088     short       depth;
00089     
00090     int         have_gw;    //ugly
00091 } QuicktimeMovie;
00092 
00093 
00094 
00095 void quicktime_init(void)
00096 {
00097     OSErr nerr;
00098 #ifdef _WIN32
00099     QTLoadLibrary("QTCF.dll");
00100     nerr = InitializeQTML(0);
00101     if (nerr != noErr) {
00102         G.have_quicktime = FALSE;
00103     }
00104     else
00105         G.have_quicktime = TRUE;
00106 #endif /* _WIN32 */
00107 
00108     /* Initialize QuickTime */
00109 #if defined(_WIN32) || defined (__APPLE__)
00110     nerr = EnterMovies();
00111     if (nerr != noErr)
00112         G.have_quicktime = FALSE;
00113     else
00114 #endif /* _WIN32 || __APPLE__ */
00115 #ifdef __linux__
00116     /* inititalize quicktime codec registry */
00117         lqt_registry_init();
00118 #endif
00119     G.have_quicktime = TRUE;
00120 }
00121 
00122 
00123 void quicktime_exit(void)
00124 {
00125 #if defined(_WIN32) || defined(__APPLE__)
00126 #ifdef WITH_QUICKTIME
00127     if(G.have_quicktime) {
00128         free_qtcomponentdata();
00129         ExitMovies();
00130 #ifdef _WIN32
00131         TerminateQTML();
00132 #endif /* _WIN32 */
00133     }
00134 #endif /* WITH_QUICKTIME */
00135 #endif /* _WIN32 || __APPLE__ */
00136 }
00137 
00138 
00139 #ifdef _WIN32
00140 char *get_valid_qtname(char *name)
00141 {
00142     TCHAR Buffer[MAX_PATH];
00143     DWORD dwRet;
00144     char *qtname;
00145     DynStr *ds= BLI_dynstr_new();
00146 
00147     dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
00148 
00149     if(name[1] != ':') {
00150         char drive[2];
00151 
00152         if(name[0] == '/' || name[0] == '\\') {
00153             drive[0] = Buffer[0];
00154             drive[1] = '\0';
00155 
00156             BLI_dynstr_append(ds, drive);
00157             BLI_dynstr_append(ds, ":");
00158             BLI_dynstr_append(ds, name);
00159         } else {
00160             BLI_dynstr_append(ds, Buffer);
00161             BLI_dynstr_append(ds, "/");
00162             BLI_dynstr_append(ds, name);
00163         }
00164     } else {
00165         BLI_dynstr_append(ds, name);
00166     }
00167 
00168     qtname= BLI_dynstr_get_cstring(ds);
00169     BLI_dynstr_free(ds);
00170 
00171     return qtname;
00172 }
00173 #endif /* _WIN32 */
00174 
00175 
00176 int anim_is_quicktime (const char *name)
00177 {
00178     FSSpec  theFSSpec;
00179     char    theFullPath[255];
00180 
00181     Boolean                     isMovieFile = false;
00182     AliasHandle                 myAlias = NULL;
00183     Component                   myImporter = NULL;
00184 #ifdef __APPLE__
00185     FInfo                       myFinderInfo;
00186     FSRef                       myRef;
00187 #else
00188     char *qtname;
00189     Str255  dst;
00190 #endif
00191     OSErr                       err = noErr;
00192             
00193     // dont let quicktime movie import handle these
00194     if( BLI_testextensie(name, ".swf") ||
00195         BLI_testextensie(name, ".txt") ||
00196         BLI_testextensie(name, ".mpg") ||
00197         BLI_testextensie(name, ".avi") ||   // wouldnt be appropriate ;)
00198         BLI_testextensie(name, ".tga") ||
00199         BLI_testextensie(name, ".png") ||
00200         BLI_testextensie(name, ".bmp") ||
00201         BLI_testextensie(name, ".jpg") ||
00202         BLI_testextensie(name, ".wav") ||
00203         BLI_testextensie(name, ".zip") ||
00204         BLI_testextensie(name, ".mp3")) return 0;
00205 
00206     if(QTIME_DEBUG) printf("qt: checking as movie: %s\n", name);
00207 
00208 #ifdef __APPLE__
00209     sprintf(theFullPath, "%s", name);
00210 
00211     err = FSPathMakeRef(theFullPath, &myRef, 0);
00212     err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
00213 #else
00214     qtname = get_valid_qtname(name);
00215     sprintf(theFullPath, "%s", qtname);
00216     MEM_freeN(qtname);
00217 
00218     CopyCStringToPascal(theFullPath, dst);
00219     err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
00220 #endif
00221 
00222 #ifdef __APPLE__
00223     // see whether the file type is MovieFileType; to do this, get the Finder information
00224     err = FSpGetFInfo(&theFSSpec, &myFinderInfo);
00225     if (err == noErr) {
00226         if (myFinderInfo.fdType == kQTFileTypeMovie) {
00227             return(true);
00228         }
00229     }
00230 #endif
00231 
00232 /* on mac os x this results in using quicktime for other formats as well
00233  * not sure whether this is intended
00234  */
00235     // if it isn't a movie file, see whether the file can be imported as a movie
00236     err = QTNewAlias(&theFSSpec, &myAlias, true);
00237     if (err == noErr) {
00238         if (myAlias != NULL) {
00239             err = GetMovieImporterForDataRef(rAliasType, (Handle)myAlias, kGetMovieImporterDontConsiderGraphicsImporters, &myImporter);
00240             DisposeHandle((Handle)myAlias);
00241         }
00242     }
00243     
00244     if ((err == noErr) && (myImporter != NULL)) {       // this file is a movie file
00245         isMovieFile = true;
00246     }
00247 
00248     return(isMovieFile);
00249 }
00250 
00251 
00252 void free_anim_quicktime (struct anim *anim)
00253 {
00254     if (anim == NULL) return;
00255     if (anim->qtime == NULL) return;
00256 
00257     UnlockPixels(anim->qtime->offscreenPixMap);
00258 
00259     if(anim->qtime->have_gw)
00260         DisposeGWorld( anim->qtime->offscreenGWorld );
00261     if(anim->qtime->ibuf)
00262         IMB_freeImBuf(anim->qtime->ibuf);
00263 
00264     DisposeMovie( anim->qtime->movie );
00265     CloseMovieFile( anim->qtime->movieRefNum );
00266 
00267     if(anim->qtime->frameIndex) MEM_freeN (anim->qtime->frameIndex);
00268     if(anim->qtime) MEM_freeN (anim->qtime);
00269 
00270     anim->qtime = NULL;
00271 
00272     anim->duration = 0;
00273 }
00274 
00275 
00276 static OSErr QT_get_frameIndexes(struct anim *anim)
00277 {
00278     int i;
00279     OSErr   anErr = noErr;
00280     OSType  media = VideoMediaType;
00281     TimeValue nextTime = 0;
00282     TimeValue   startPoint;
00283     TimeValue   tmpstartPoint;
00284     long sampleCount = 0;
00285 
00286     startPoint = -1;
00287 
00288     GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample+nextTimeEdgeOK, (TimeValue)1, &media, 0, 
00289                                 1, &startPoint, NULL);
00290 
00291     tmpstartPoint = startPoint;
00292 
00293     anim->qtime->framecount = 0;
00294 
00295     sampleCount = GetMediaSampleCount(anim->qtime->theMedia);
00296     anErr = GetMoviesError();
00297     if (anErr != noErr) return anErr;
00298 
00299     anim->qtime->framecount = sampleCount;
00300 
00301     anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex");
00302 
00303     //rewind
00304     GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, (TimeValue)1, 0, &tmpstartPoint, NULL);
00305 
00306     anim->qtime->frameIndex[0] = startPoint;
00307     for(i = 1; i < anim->qtime->framecount; i++) {
00308         nextTime = 0;
00309         GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, startPoint, 0, &nextTime, NULL);
00310         startPoint = nextTime;
00311         anim->qtime->frameIndex[i] = nextTime;
00312     }
00313 
00314     anErr = GetMoviesError();
00315     return anErr;
00316 }
00317 
00318 
00319 ImBuf * qtime_fetchibuf (struct anim *anim, int position)
00320 {
00321     PixMapHandle            myPixMap = NULL;
00322     Ptr                     myPtr;
00323 
00324     register int        index;
00325     register int        boxsize;
00326 
00327     register uint32_t   *readPos;
00328     register uint32_t   *changePos;
00329 
00330     ImBuf *ibuf = NULL;
00331     unsigned int *rect;
00332 #ifdef __APPLE__
00333     unsigned char *from, *to;
00334 #endif
00335 #ifdef _WIN32
00336     unsigned char *crect;
00337 #endif
00338 
00339     if (anim == NULL) {
00340         return (NULL);
00341     }
00342 
00343     ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect);
00344     rect = ibuf->rect;
00345 
00346     SetMovieTimeValue(anim->qtime->movie, anim->qtime->frameIndex[position]);
00347     UpdateMovie(anim->qtime->movie);
00348     MoviesTask(anim->qtime->movie, 0);
00349 
00350 
00351     myPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
00352     myPtr = GetPixBaseAddr(myPixMap);
00353 
00354     if (myPtr == NULL) {
00355         printf ("Error reading frame from Quicktime");
00356         IMB_freeImBuf (ibuf);
00357         return NULL;
00358     }
00359 
00360     boxsize = anim->x * anim->y;
00361     readPos = (uint32_t *) myPtr;
00362     changePos = (uint32_t *) rect; //textureIMBuf *THE* data pointerrr
00363 
00364 #ifdef __APPLE__
00365     // Swap alpha byte to the end, so ARGB become RGBA;
00366     from= (unsigned char *)readPos;
00367     to= (unsigned char *)changePos;
00368     
00369     for( index = 0; index < boxsize; index++, from+=4, to+=4 ) {
00370         to[3] = from[0];
00371         to[0] = from[1];
00372         to[1] = from[2];
00373         to[2] = from[3];
00374     }
00375 #endif
00376 
00377 #ifdef _WIN32
00378     for( index = 0; index < boxsize; index++, changePos++, readPos++ )
00379         *( changePos ) =  *(readPos );
00380 
00381     if(anim->qtime->depth < 32) {
00382         //add alpha to ibuf
00383         boxsize = anim->x * anim->y * 4;
00384         crect = (unsigned char *) rect;
00385         for( index = 0; index < boxsize; index+=4, crect+=4 ) {
00386             crect[3] = 0xFF;
00387         }
00388     }
00389 #endif
00390 
00391     ibuf->profile = IB_PROFILE_SRGB;
00392     
00393     IMB_flipy(ibuf);
00394     return ibuf;
00395 }
00396 
00397 
00398 // following two functions only here to get movie pixeldepth
00399 
00400 static int GetFirstVideoMedia(struct anim *anim)
00401 {
00402     long    numTracks;
00403     OSType  mediaType;
00404 
00405     numTracks = GetMovieTrackCount(anim->qtime->movie);
00406 
00407     for (anim->qtime->trackIndex=1; anim->qtime->trackIndex<=numTracks; (anim->qtime->trackIndex)++) {
00408         anim->qtime->theTrack = GetMovieIndTrack(anim->qtime->movie, anim->qtime->trackIndex);
00409 
00410         if (anim->qtime->theTrack)
00411             anim->qtime->theMedia = GetTrackMedia(anim->qtime->theTrack);
00412 
00413         if (anim->qtime->theMedia)
00414             GetMediaHandlerDescription(anim->qtime->theMedia,&mediaType, nil, nil);
00415         if (mediaType == VideoMediaType) return 1;
00416     }
00417 
00418     anim->qtime->trackIndex = 0;  // trackIndex can't be 0
00419     return 0;      // went through all tracks and no video
00420 }
00421 
00422 static short GetFirstVideoTrackPixelDepth(struct anim *anim)
00423 {
00424     SampleDescriptionHandle imageDescH =    (SampleDescriptionHandle)NewHandle(sizeof(Handle));
00425 //  long    trackIndex = 0; /*unused*/
00426     
00427     if(!GetFirstVideoMedia(anim))
00428         return -1;
00429 
00430     if (!anim->qtime->trackIndex || !anim->qtime->theMedia) return -1;  // we need both
00431     GetMediaSampleDescription(anim->qtime->theMedia, anim->qtime->trackIndex, imageDescH);
00432 
00433     return (*(ImageDescriptionHandle)imageDescH)->depth;
00434 }
00435 
00436 
00437 int startquicktime (struct anim *anim)
00438 {
00439     FSSpec      theFSSpec;
00440 
00441     OSErr       err = noErr;
00442     char        theFullPath[255];
00443 #ifdef __APPLE__
00444     FSRef       myRef;
00445 #else
00446     char        *qtname;
00447     Str255      dst;
00448 #endif
00449     short depth = 0;
00450 
00451     anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
00452     anim->qtime->have_gw = FALSE;
00453 
00454     if (anim->qtime == NULL) {
00455         if(QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
00456         return -1;
00457     }
00458 
00459     if(QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name);
00460     
00461 #ifdef __APPLE__
00462     sprintf(theFullPath, "%s", anim->name);
00463 
00464     err = FSPathMakeRef(theFullPath, &myRef, 0);
00465     err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
00466 #else
00467     qtname = get_valid_qtname(anim->name);
00468     sprintf(theFullPath, "%s", qtname);
00469     MEM_freeN(qtname);
00470 
00471     CopyCStringToPascal(theFullPath, dst);
00472     FSMakeFSSpec(0, 0L, dst, &theFSSpec);
00473 #endif
00474     
00475     err = OpenMovieFile(&theFSSpec, &anim->qtime->movieRefNum, fsRdPerm);
00476 
00477     if (err == noErr) {
00478         if(QTIME_DEBUG) printf("qt: movie opened\n");
00479         err = NewMovieFromFile(&anim->qtime->movie,
00480                            anim->qtime->movieRefNum,
00481                            &anim->qtime->movieResId, NULL, newMovieActive, NULL);
00482     }
00483 
00484     if (err) {
00485         if(QTIME_DEBUG) printf("qt: bad movie %s\n", anim->name);
00486         if (anim->qtime->movie) {
00487             DisposeMovie(anim->qtime->movie);
00488             MEM_freeN(anim->qtime);
00489             if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
00490             return -1;
00491         }
00492     }
00493 
00494     GetMovieBox(anim->qtime->movie, &anim->qtime->movieBounds);
00495     anim->x = anim->qtime->movWidth = RECT_WIDTH(anim->qtime->movieBounds);
00496     anim->y = anim->qtime->movHeight = RECT_HEIGHT(anim->qtime->movieBounds);
00497     if(QTIME_DEBUG) printf("qt: got bounds %s\n", anim->name);
00498 
00499     if(anim->x == 0 && anim->y == 0) {
00500         if(QTIME_DEBUG) printf("qt: error, no dimensions\n");
00501         free_anim_quicktime(anim);
00502         return -1;
00503     }
00504 
00505     anim->qtime->ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect);
00506 
00507 #ifdef _WIN32
00508     err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
00509          k32RGBAPixelFormat,
00510          &anim->qtime->movieBounds,
00511          NULL, NULL, 0,
00512         (unsigned char *)anim->qtime->ibuf->rect,
00513         anim->x * 4);
00514 #else
00515     err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
00516          k32ARGBPixelFormat,
00517          &anim->qtime->movieBounds,
00518          NULL, NULL, 0,
00519         (unsigned char *)anim->qtime->ibuf->rect,
00520         anim->x * 4);
00521 #endif /* _WIN32 */
00522 
00523     if(err == noErr) {
00524         anim->qtime->have_gw = TRUE;
00525 
00526         SetMovieGWorld(anim->qtime->movie,
00527                        anim->qtime->offscreenGWorld,
00528                        GetGWorldDevice(anim->qtime->offscreenGWorld));
00529         SetMoviePlayHints(anim->qtime->movie, hintsHighQuality, hintsHighQuality);
00530         
00531         // sets Media and Track!
00532         depth = GetFirstVideoTrackPixelDepth(anim);
00533 
00534         QT_get_frameIndexes(anim);
00535     }
00536 
00537     anim->qtime->offscreenPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
00538     LockPixels(anim->qtime->offscreenPixMap);
00539 
00540     //fill blender's anim struct
00541     anim->qtime->depth = depth;
00542     
00543     anim->duration = anim->qtime->framecount;
00544     anim->params = 0;
00545 
00546     anim->interlacing = 0;
00547     anim->orientation = 0;
00548     anim->framesize = anim->x * anim->y * 4;
00549 
00550     anim->curposition = 0;
00551 
00552     if(QTIME_DEBUG) printf("qt: load %s %dx%dx%d frames %d\n", anim->name, anim->qtime->movWidth,
00553         anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount);
00554 
00555     return 0;
00556 }
00557 
00558 int imb_is_a_quicktime (char *name)
00559 {
00560     GraphicsImportComponent     theImporter = NULL;
00561 
00562     FSSpec  theFSSpec;
00563 #ifdef _WIN32
00564     Str255  dst; /*unused*/
00565 #endif
00566     char    theFullPath[255];
00567 
00568 //  Boolean                     isMovieFile = false; /*unused*/
00569 //  AliasHandle                 myAlias = NULL; /*unused*/
00570 //  Component                   myImporter = NULL; /*unused*/
00571 #ifdef __APPLE__
00572 //  FInfo                       myFinderInfo; /*unused*/
00573     FSRef                       myRef;
00574 #endif
00575     OSErr                       err = noErr;
00576 
00577     if(!G.have_quicktime) return 0;
00578 
00579     if(QTIME_DEBUG) printf("qt: checking as image %s\n", name);
00580 
00581     // dont let quicktime image import handle these
00582     if( BLI_testextensie(name, ".swf") ||
00583         BLI_testextensie(name, ".txt") ||
00584         BLI_testextensie(name, ".mpg") ||
00585         BLI_testextensie(name, ".wav") ||
00586         BLI_testextensie(name, ".mov") ||   // not as image, doesn't work
00587         BLI_testextensie(name, ".avi") ||
00588         BLI_testextensie(name, ".mp3")) return 0;
00589 
00590     sprintf(theFullPath, "%s", name);
00591 #ifdef __APPLE__
00592     err = FSPathMakeRef(theFullPath, &myRef, 0);
00593     err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
00594 #else
00595     CopyCStringToPascal(theFullPath, dst);
00596     err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
00597 #endif
00598 
00599     GetGraphicsImporterForFile(&theFSSpec, &theImporter);
00600 
00601     if (theImporter != NULL) {
00602         if(QTIME_DEBUG) printf("qt: %s valid\n", name);
00603         CloseComponent(theImporter);
00604         return 1;
00605     }
00606 
00607     return 0;
00608 }
00609 
00610 ImBuf  *imb_quicktime_decode(unsigned char *mem, int size, int flags)
00611 {
00612     Rect                        myRect;
00613     OSErr                       err = noErr;
00614     GraphicsImportComponent     gImporter = NULL;
00615 
00616     ImageDescriptionHandle      desc;
00617 
00618     ComponentInstance           dataHandler;
00619     PointerDataRef dataref;
00620 
00621     int x, y, depth;
00622     int have_gw = FALSE;
00623     ImBuf *ibuf = NULL;
00624 //  ImBuf *imbuf = NULL; /*unused*/
00625     GWorldPtr   offGWorld;
00626     PixMapHandle        myPixMap = NULL;
00627 
00628 #ifdef __APPLE__
00629     Ptr                 myPtr;
00630 
00631     register int        index;
00632     register int        boxsize;
00633 
00634     register uint32_t   *readPos;
00635     register uint32_t   *changePos;
00636 
00637     ImBuf *wbuf = NULL;
00638     unsigned int *rect;
00639     unsigned char *from, *to;
00640 #endif
00641 
00642     if (mem == NULL || !G.have_quicktime)
00643         goto bail;
00644     
00645     if(QTIME_DEBUG) printf("qt: attempt to load mem as image\n");
00646 
00647     dataref= (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord));
00648     (**dataref).data = mem;
00649     (**dataref).dataLength = size;
00650 
00651     err = OpenADataHandler((Handle)dataref,
00652                             PointerDataHandlerSubType,
00653                             nil,
00654                             (OSType)0,
00655                             nil,
00656                             kDataHCanRead,
00657                             &dataHandler);
00658     if (err != noErr) {
00659         if(QTIME_DEBUG) printf("no datahandler\n");
00660         goto bail;
00661     }
00662 
00663     err = GetGraphicsImporterForDataRef((Handle)dataref, PointerDataHandlerSubType, &gImporter);
00664     if (err != noErr) {
00665         if(QTIME_DEBUG) printf("no graphimport\n");
00666         goto bail;
00667     }
00668 
00669     err = GraphicsImportGetNaturalBounds(gImporter, &myRect);
00670     if (err != noErr) {
00671         if(QTIME_DEBUG) printf("no bounds\n");
00672         goto bail;
00673     }
00674 
00675     err = GraphicsImportGetImageDescription (gImporter, &desc );
00676     if (err != noErr) {
00677         if(QTIME_DEBUG) printf("no imagedescription\n");
00678         goto bail;
00679     }
00680 
00681     x = RECT_WIDTH(myRect);
00682     y = RECT_HEIGHT(myRect);
00683     depth = (**desc).depth;
00684 
00685     if (flags & IB_test) {
00686         ibuf = IMB_allocImBuf(x, y, depth, 0);
00687         ibuf->ftype = QUICKTIME;
00688         DisposeHandle((Handle)dataref);
00689         if (gImporter != NULL)  CloseComponent(gImporter);
00690         return ibuf;
00691     }
00692 
00693 #ifdef __APPLE__
00694     ibuf = IMB_allocImBuf (x, y, 32, IB_rect);
00695     wbuf = IMB_allocImBuf (x, y, 32, IB_rect);
00696 
00697     err = NewGWorldFromPtr(&offGWorld,
00698                         k32ARGBPixelFormat,
00699                         &myRect, NULL, NULL, 0,
00700                         (unsigned char *)wbuf->rect, x * 4);
00701 #else
00702 
00703     ibuf = IMB_allocImBuf (x, y, 32, IB_rect);  
00704 
00705     err = NewGWorldFromPtr(&offGWorld,
00706                             k32RGBAPixelFormat,
00707                             &myRect, NULL, NULL, 0,
00708                             (unsigned char *)ibuf->rect, x * 4);
00709 #endif
00710     
00711     if (err != noErr) {
00712         if(QTIME_DEBUG) printf("no newgworld\n");
00713         goto bail;
00714     } else {
00715         have_gw = TRUE;
00716     }
00717 
00718     GraphicsImportSetGWorld(gImporter, offGWorld, NULL);
00719     GraphicsImportDraw(gImporter);
00720 
00721 #ifdef __APPLE__
00722     rect = ibuf->rect;
00723 
00724     myPixMap = GetGWorldPixMap(offGWorld);
00725     LockPixels(myPixMap);
00726     myPtr = GetPixBaseAddr(myPixMap);
00727 
00728     if (myPtr == NULL) {
00729         printf ("Error reading frame from Quicktime");
00730         IMB_freeImBuf (ibuf);
00731         return NULL;
00732     }
00733 
00734     boxsize = x * y;
00735     readPos = (uint32_t *) myPtr;
00736     changePos = (uint32_t *) rect;
00737 
00738     // Swap alpha byte to the end, so ARGB become RGBA;
00739     from= (unsigned char *)readPos;
00740     to= (unsigned char *)changePos;
00741     
00742     for( index = 0; index < boxsize; index++, from+=4, to+=4 ) {
00743         to[3] = from[0];
00744         to[0] = from[1];
00745         to[1] = from[2];
00746         to[2] = from[3];
00747     }
00748 #endif
00749 
00750 bail:
00751 
00752     DisposeHandle((Handle)dataref);
00753     UnlockPixels(myPixMap);
00754     if(have_gw) DisposeGWorld(offGWorld);
00755 
00756 #ifdef __APPLE__
00757     if (wbuf) {
00758         IMB_freeImBuf (wbuf);
00759         wbuf = NULL;
00760     }
00761 #endif
00762 
00763     if (gImporter != NULL)  CloseComponent(gImporter);
00764 
00765     if (err != noErr) {
00766         if(QTIME_DEBUG) printf("quicktime import unsuccesfull\n");
00767         if (ibuf) {
00768             IMB_freeImBuf (ibuf);
00769             ibuf = NULL;
00770         }
00771     }
00772 
00773     if(ibuf) {
00774 
00775 #ifdef _WIN32
00776 // add non transparent alpha layer, so images without alpha show up in the sequence editor
00777 // exception for GIF images since these can be transparent without being 32 bit
00778 // (might also be nescessary for OSX)
00779         int i;
00780         int box = x * y;
00781         unsigned char *arect = (unsigned char *) ibuf->rect;
00782 
00783         if( depth < 32 && (**desc).cType != kGIFCodecType) {
00784             for(i = 0; i < box; i++, arect+=4)
00785                 arect[3] = 0xFF;
00786         }
00787 #endif
00788 
00789         IMB_flipy(ibuf);
00790         ibuf->ftype = QUICKTIME;
00791     }
00792     return ibuf;
00793 }
00794 
00795 #endif /* USE_QTKIT */
00796 #endif /* _WIN32 || __APPLE__ */
00797 
00798 #endif /* WITH_QUICKTIME */
00799 
00800 
00801 #if 0
00802 
00803 struct ImageDescription {
00804     long         idSize;
00805     CodecType    cType;
00806     long         resvd1;
00807     short        resvd2;
00808     short        dataRefIndex;
00809     short        version;
00810     short        revisionLevel;
00811     long         vendor;
00812     CodecQ       temporalQuality;
00813     CodecQ       spatialQuality;
00814     short        width;
00815     short        height;
00816     Fixed        hRes;
00817     Fixed        vRes;
00818     long         dataSize;
00819     short        frameCount;
00820     Str31        name;
00821     short        depth;
00822     short        clutID;
00823 };
00824 
00825 #endif // 0