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