Blender V2.61 - r43446
|
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