|
Blender
V2.59
|
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