svn merge -r 22628:22753 https://svn.blender.org/svnroot/bf-blender/branches/blender2...
[blender.git] / source / blender / quicktime / apple / quicktime_import.c
1 /**
2  * $Id$
3  *
4  * quicktime_import.c
5  *
6  * Code to use Quicktime to load images/movies as texture.
7  *
8  * ***** BEGIN GPL LICENSE BLOCK *****
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  *
24  * The Original Code is written by Rob Haarsma (phase)
25  *
26  * Contributor(s): Stefan Gartner (sgefant)
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30 #ifdef WITH_QUICKTIME
31
32 #if defined(_WIN32) || defined(__APPLE__)
33
34 #include "IMB_anim.h"
35 #include "BLO_sys_types.h"
36 #include "BKE_global.h"
37 #include "BLI_dynstr.h"
38
39 #ifdef __APPLE__
40 #include <QuickTime/Movies.h>
41 #include <QuickTime/QuickTimeComponents.h>
42 #endif
43
44 #ifdef _WIN32
45 #include <Movies.h>
46 #include <QTML.h>
47 #include <TextUtils.h>
48 #include <QuickTimeComponents.h>
49 #endif /* _WIN32 */
50
51
52 #include "quicktime_import.h"
53 #include "quicktime_export.h"
54
55
56 #define RECT_WIDTH(r)   (r.right-r.left)
57 #define RECT_HEIGHT(r)  (r.bottom-r.top)
58
59 #define QTIME_DEBUG 0
60
61
62 void quicktime_init(void)
63 {
64 #ifdef _WIN32
65         if (InitializeQTML(0) != noErr)
66                 G.have_quicktime = FALSE;
67         else
68                 G.have_quicktime = TRUE;
69 #endif /* _WIN32 */
70
71         /* Initialize QuickTime */
72 #if defined(_WIN32) || defined (__APPLE__)
73         if (EnterMovies() != noErr)
74                 G.have_quicktime = FALSE;
75         else
76 #endif /* _WIN32 || __APPLE__ */
77 #ifdef __linux__
78         /* inititalize quicktime codec registry */
79                 lqt_registry_init();
80 #endif
81         G.have_quicktime = TRUE;
82 }
83
84
85 void quicktime_exit(void)
86 {
87 #if defined(_WIN32) || defined(__APPLE__)
88 #ifdef WITH_QUICKTIME
89         if(G.have_quicktime) {
90                 free_qtcomponentdata();
91                 ExitMovies();
92 #ifdef _WIN32
93                 TerminateQTML();
94 #endif /* _WIN32 */
95         }
96 #endif /* WITH_QUICKTIME */
97 #endif /* _WIN32 || __APPLE__ */
98 }
99
100
101 #ifdef _WIN32
102 char *get_valid_qtname(char *name)
103 {
104         TCHAR Buffer[MAX_PATH];
105         DWORD dwRet;
106         char *qtname;
107         DynStr *ds= BLI_dynstr_new();
108
109         dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
110
111         if(name[1] != ':') {
112                 char drive[2];
113
114                 if(name[0] == '/' || name[0] == '\\') {
115                         drive[0] = Buffer[0];
116                         drive[1] = '\0';
117
118                         BLI_dynstr_append(ds, drive);
119                         BLI_dynstr_append(ds, ":");
120                         BLI_dynstr_append(ds, name);
121                 } else {
122                         BLI_dynstr_append(ds, Buffer);
123                         BLI_dynstr_append(ds, "/");
124                         BLI_dynstr_append(ds, name);
125                 }
126         } else {
127                 BLI_dynstr_append(ds, name);
128         }
129
130         qtname= BLI_dynstr_get_cstring(ds);
131         BLI_dynstr_free(ds);
132
133         return qtname;
134 }
135 #endif /* _WIN32 */
136
137
138 int anim_is_quicktime (char *name)
139 {
140         FSSpec  theFSSpec;
141         char    theFullPath[255];
142
143         Boolean                                         isMovieFile = false;
144         AliasHandle                                     myAlias = NULL;
145         Component                                       myImporter = NULL;
146 #ifdef __APPLE__
147         FInfo                                           myFinderInfo;
148         FSRef                                           myRef;
149 #else
150         char *qtname;
151         Str255  dst;
152 #endif
153         OSErr                                           err = noErr;
154                         
155         // dont let quicktime movie import handle these
156         if( BLI_testextensie(name, ".swf") ||
157                 BLI_testextensie(name, ".txt") ||
158                 BLI_testextensie(name, ".mpg") ||
159                 BLI_testextensie(name, ".avi") ||       // wouldnt be appropriate ;)
160                 BLI_testextensie(name, ".tga") ||
161                 BLI_testextensie(name, ".png") ||
162                 BLI_testextensie(name, ".bmp") ||
163                 BLI_testextensie(name, ".jpg") ||
164                 BLI_testextensie(name, ".wav") ||
165                 BLI_testextensie(name, ".zip") ||
166                 BLI_testextensie(name, ".mp3")) return 0;
167
168         if(QTIME_DEBUG) printf("qt: checking as movie: %s\n", name);
169
170 #ifdef __APPLE__
171         sprintf(theFullPath, "%s", name);
172
173         err = FSPathMakeRef(theFullPath, &myRef, 0);
174         err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
175 #else
176         qtname = get_valid_qtname(name);
177         sprintf(theFullPath, "%s", qtname);
178         MEM_freeN(qtname);
179
180         CopyCStringToPascal(theFullPath, dst);
181         err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
182 #endif
183
184 #ifdef __APPLE__
185         // see whether the file type is MovieFileType; to do this, get the Finder information
186         err = FSpGetFInfo(&theFSSpec, &myFinderInfo);
187         if (err == noErr) {
188                 if (myFinderInfo.fdType == kQTFileTypeMovie) {
189                         return(true);
190                 }
191         }
192 #endif
193
194 /* on mac os x this results in using quicktime for other formats as well
195  * not sure whether this is intended
196  */
197         // if it isn't a movie file, see whether the file can be imported as a movie
198         err = QTNewAlias(&theFSSpec, &myAlias, true);
199         if (err == noErr) {
200                 if (myAlias != NULL) {
201                         err = GetMovieImporterForDataRef(rAliasType, (Handle)myAlias, kGetMovieImporterDontConsiderGraphicsImporters, &myImporter);
202                         DisposeHandle((Handle)myAlias);
203                 }
204         }
205         
206         if ((err == noErr) && (myImporter != NULL)) {           // this file is a movie file
207                 isMovieFile = true;
208         }
209
210         return(isMovieFile);
211 }
212
213
214 void free_anim_quicktime (struct anim *anim) {
215         if (anim == NULL) return;
216         if (anim->qtime == NULL) return;
217
218         UnlockPixels(anim->qtime->offscreenPixMap);
219
220         if(anim->qtime->have_gw)
221                 DisposeGWorld( anim->qtime->offscreenGWorld );
222         if(anim->qtime->ibuf)
223                 IMB_freeImBuf(anim->qtime->ibuf);
224
225         DisposeMovie( anim->qtime->movie );
226         CloseMovieFile( anim->qtime->movieRefNum );
227
228         if(anim->qtime->frameIndex) MEM_freeN (anim->qtime->frameIndex);
229         if(anim->qtime) MEM_freeN (anim->qtime);
230
231         anim->qtime = NULL;
232
233         anim->duration = 0;
234 }
235
236
237 static OSErr QT_get_frameIndexes(struct anim *anim)
238 {
239         int i;
240         OSErr   anErr = noErr;
241         OSType  media = VideoMediaType;
242         TimeValue nextTime = 0;
243         TimeValue       startPoint;
244         TimeValue       tmpstartPoint;
245         long sampleCount = 0;
246
247         startPoint = -1;
248
249         GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample+nextTimeEdgeOK, (TimeValue)1, &media, 0, 
250                                                                 1, &startPoint, NULL);
251
252         tmpstartPoint = startPoint;
253
254         anim->qtime->framecount = 0;
255
256         sampleCount = GetMediaSampleCount(anim->qtime->theMedia);
257         anErr = GetMoviesError();
258         if (anErr != noErr) return anErr;
259
260         anim->qtime->framecount = sampleCount;
261
262         anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex");
263
264         //rewind
265         GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, (TimeValue)1, 0, &tmpstartPoint, NULL);
266
267         anim->qtime->frameIndex[0] = startPoint;
268         for(i = 1; i < anim->qtime->framecount; i++) {
269                 nextTime = 0;
270                 GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, startPoint, 0, &nextTime, NULL);
271                 startPoint = nextTime;
272                 anim->qtime->frameIndex[i] = nextTime;
273         }
274
275         anErr = GetMoviesError();
276         return anErr;
277 }
278
279
280 ImBuf * qtime_fetchibuf (struct anim *anim, int position)
281 {
282         PixMapHandle                    myPixMap = NULL;
283         Ptr                                             myPtr;
284
285         register int            index;
286         register int            boxsize;
287
288         register uint32_t       *readPos;
289         register uint32_t       *changePos;
290
291         ImBuf *ibuf = NULL;
292         unsigned int *rect;
293         unsigned char *from, *to;
294 #ifdef _WIN32
295         unsigned char *crect;
296 #endif
297
298         if (anim == NULL) {
299                 return (NULL);
300         }
301
302         ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect, 0);
303         rect = ibuf->rect;
304
305         SetMovieTimeValue(anim->qtime->movie, anim->qtime->frameIndex[position]);
306         UpdateMovie(anim->qtime->movie);
307         MoviesTask(anim->qtime->movie, 0);
308
309
310         myPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
311         myPtr = GetPixBaseAddr(myPixMap);
312
313         if (myPtr == NULL) {
314                 printf ("Error reading frame from Quicktime");
315                 IMB_freeImBuf (ibuf);
316                 return NULL;
317         }
318
319         boxsize = anim->x * anim->y;
320         readPos = (uint32_t *) myPtr;
321         changePos = (uint32_t *) rect; //textureIMBuf *THE* data pointerrr
322
323 #ifdef __APPLE__
324         // Swap alpha byte to the end, so ARGB become RGBA;
325         from= (unsigned char *)readPos;
326         to= (unsigned char *)changePos;
327         
328         for( index = 0; index < boxsize; index++, from+=4, to+=4 ) {
329                 to[3] = from[0];
330                 to[0] = from[1];
331                 to[1] = from[2];
332                 to[2] = from[3];
333         }
334 #endif
335
336 #ifdef _WIN32
337         for( index = 0; index < boxsize; index++, changePos++, readPos++ )
338                 *( changePos ) =  *(readPos );
339
340         if(anim->qtime->depth < 32) {
341                 //add alpha to ibuf
342                 boxsize = anim->x * anim->y * 4;
343                 crect = (unsigned char *) rect;
344                 for( index = 0; index < boxsize; index+=4, crect+=4 )
345                          crect[3] = 0xFF;
346         }
347 #endif
348
349         IMB_flipy(ibuf);
350         return ibuf;
351 }
352
353
354 // following two functions only here to get movie pixeldepth
355
356 static int GetFirstVideoMedia(struct anim *anim)
357 {
358         long    numTracks;
359         OSType  mediaType;
360
361         numTracks = GetMovieTrackCount(anim->qtime->movie);
362
363         for (anim->qtime->trackIndex=1; anim->qtime->trackIndex<=numTracks; (anim->qtime->trackIndex)++) {
364                 anim->qtime->theTrack = GetMovieIndTrack(anim->qtime->movie, anim->qtime->trackIndex);
365
366                 if (anim->qtime->theTrack)
367                         anim->qtime->theMedia = GetTrackMedia(anim->qtime->theTrack);
368
369                 if (anim->qtime->theMedia)
370                         GetMediaHandlerDescription(anim->qtime->theMedia,&mediaType, nil, nil);
371                 if (mediaType == VideoMediaType) return 1;
372         }
373
374         anim->qtime->trackIndex = 0;  // trackIndex can't be 0
375         return 0;      // went through all tracks and no video
376 }
377
378 static short GetFirstVideoTrackPixelDepth(struct anim *anim)
379 {
380         SampleDescriptionHandle imageDescH =    (SampleDescriptionHandle)NewHandle(sizeof(Handle));
381 //      long    trackIndex = 0; /*unused*/
382         
383         if(!GetFirstVideoMedia(anim))
384                 return -1;
385
386         if (!anim->qtime->trackIndex || !anim->qtime->theMedia) return -1;  // we need both
387         GetMediaSampleDescription(anim->qtime->theMedia, anim->qtime->trackIndex, imageDescH);
388
389         return (*(ImageDescriptionHandle)imageDescH)->depth;
390 }
391
392
393 int startquicktime (struct anim *anim)
394 {
395         FSSpec          theFSSpec;
396
397         OSErr           err = noErr;
398         char            theFullPath[255];
399 #ifdef __APPLE__
400         FSRef           myRef;
401 #else
402         char            *qtname;
403         Str255          dst;
404 #endif
405         short depth = 0;
406
407         anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
408         anim->qtime->have_gw = FALSE;
409
410         if (anim->qtime == NULL) {
411                 if(QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
412                 return -1;
413         }
414
415         if(QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name);
416         
417 #ifdef __APPLE__
418         sprintf(theFullPath, "%s", anim->name);
419
420         err = FSPathMakeRef(theFullPath, &myRef, 0);
421         err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
422 #else
423         qtname = get_valid_qtname(anim->name);
424         sprintf(theFullPath, "%s", qtname);
425         MEM_freeN(qtname);
426
427         CopyCStringToPascal(theFullPath, dst);
428         FSMakeFSSpec(0, 0L, dst, &theFSSpec);
429 #endif
430         
431         err = OpenMovieFile(&theFSSpec, &anim->qtime->movieRefNum, fsRdPerm);
432
433         if (err == noErr) {
434                 if(QTIME_DEBUG) printf("qt: movie opened\n");
435                 err = NewMovieFromFile(&anim->qtime->movie,
436                                                    anim->qtime->movieRefNum,
437                                                    &anim->qtime->movieResId, NULL, newMovieActive, NULL);
438         }
439
440         if (err) {
441                 if(QTIME_DEBUG) printf("qt: bad movie %s\n", anim->name);
442                 if (anim->qtime->movie) {
443                         DisposeMovie(anim->qtime->movie);
444                         MEM_freeN(anim->qtime);
445                         if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
446                         return -1;
447                 }
448         }
449
450         GetMovieBox(anim->qtime->movie, &anim->qtime->movieBounds);
451         anim->x = anim->qtime->movWidth = RECT_WIDTH(anim->qtime->movieBounds);
452         anim->y = anim->qtime->movHeight = RECT_HEIGHT(anim->qtime->movieBounds);
453         if(QTIME_DEBUG) printf("qt: got bounds %s\n", anim->name);
454
455         if(anim->x == 0 && anim->y == 0) {
456                 if(QTIME_DEBUG) printf("qt: error, no dimensions\n");
457                 free_anim_quicktime(anim);
458                 return -1;
459         }
460
461         anim->qtime->ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect, 0);
462
463 #ifdef _WIN32
464         err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
465                  k32RGBAPixelFormat,
466                  &anim->qtime->movieBounds,
467                  NULL, NULL, 0,
468                 (unsigned char *)anim->qtime->ibuf->rect,
469                 anim->x * 4);
470 #else
471         err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
472                  k32ARGBPixelFormat,
473                  &anim->qtime->movieBounds,
474                  NULL, NULL, 0,
475                 (unsigned char *)anim->qtime->ibuf->rect,
476                 anim->x * 4);
477 #endif /* _WIN32 */
478
479         if(err == noErr) {
480                 anim->qtime->have_gw = TRUE;
481
482                 SetMovieGWorld(anim->qtime->movie,
483                                  anim->qtime->offscreenGWorld,
484                                  GetGWorldDevice(anim->qtime->offscreenGWorld));
485                 SetMoviePlayHints(anim->qtime->movie, hintsHighQuality, hintsHighQuality);
486                 
487                 // sets Media and Track!
488                 depth = GetFirstVideoTrackPixelDepth(anim);
489
490                 QT_get_frameIndexes(anim);
491         }
492
493         anim->qtime->offscreenPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
494         LockPixels(anim->qtime->offscreenPixMap);
495
496         //fill blender's anim struct
497         anim->qtime->depth = depth;
498         
499         anim->duration = anim->qtime->framecount;
500         anim->params = 0;
501
502         anim->interlacing = 0;
503         anim->orientation = 0;
504         anim->framesize = anim->x * anim->y * 4;
505
506         anim->curposition = 0;
507
508         if(QTIME_DEBUG) printf("qt: load %s %dx%dx%d frames %d\n", anim->name, anim->qtime->movWidth,
509                 anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount);
510
511         return 0;
512 }
513
514 int imb_is_a_quicktime (char *name)
515 {
516         GraphicsImportComponent         theImporter = NULL;
517
518         FSSpec  theFSSpec;
519 #ifdef _WIN32
520         Str255  dst; /*unused*/
521 #endif
522         char    theFullPath[255];
523
524 //      Boolean                                         isMovieFile = false; /*unused*/
525 //      AliasHandle                                     myAlias = NULL; /*unused*/
526 //      Component                                       myImporter = NULL; /*unused*/
527 #ifdef __APPLE__
528 //      FInfo                                           myFinderInfo; /*unused*/
529         FSRef                                           myRef;
530 #endif
531         OSErr                                           err = noErr;
532
533         if(QTIME_DEBUG) printf("qt: checking as image %s\n", name);
534
535         // dont let quicktime image import handle these
536         if( BLI_testextensie(name, ".swf") ||
537                 BLI_testextensie(name, ".txt") ||
538                 BLI_testextensie(name, ".mpg") ||
539                 BLI_testextensie(name, ".wav") ||
540                 BLI_testextensie(name, ".mov") ||       // not as image, doesn't work
541                 BLI_testextensie(name, ".avi") ||
542                 BLI_testextensie(name, ".mp3")) return 0;
543
544         sprintf(theFullPath, "%s", name);
545 #ifdef __APPLE__
546         err = FSPathMakeRef(theFullPath, &myRef, 0);
547         err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
548 #else
549         CopyCStringToPascal(theFullPath, dst);
550         err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
551 #endif
552
553         GetGraphicsImporterForFile(&theFSSpec, &theImporter);
554
555         if (theImporter != NULL) {
556                 if(QTIME_DEBUG) printf("qt: %s valid\n", name);
557                 CloseComponent(theImporter);
558                 return 1;
559         }
560
561         return 0;
562 }
563
564 ImBuf  *imb_quicktime_decode(unsigned char *mem, int size, int flags)
565 {
566         Rect                                            myRect;
567         OSErr                                           err = noErr;
568         GraphicsImportComponent         gImporter = NULL;
569
570         ImageDescriptionHandle          desc;
571
572         ComponentInstance                       dataHandler;
573         PointerDataRef dataref = (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord));
574
575         int x, y, depth;
576         int have_gw = FALSE;
577         ImBuf *ibuf = NULL;
578 //      ImBuf *imbuf = NULL; /*unused*/
579         GWorldPtr       offGWorld;
580         PixMapHandle            myPixMap = NULL;
581
582 #ifdef __APPLE__
583         Ptr                                     myPtr;
584
585         register int            index;
586         register int            boxsize;
587
588         register uint32_t       *readPos;
589         register uint32_t       *changePos;
590
591         ImBuf *wbuf = NULL;
592         unsigned int *rect;
593         unsigned char *from, *to;
594 #endif
595
596         if (mem == NULL)
597                 goto bail;
598         
599         if(QTIME_DEBUG) printf("qt: attempt to load mem as image\n");
600
601         (**dataref).data = mem;
602         (**dataref).dataLength = size;
603
604         err = OpenADataHandler((Handle)dataref,
605                                                         PointerDataHandlerSubType,
606                                                         nil,
607                                                         (OSType)0,
608                                                         nil,
609                                                         kDataHCanRead,
610                                                         &dataHandler);
611         if (err != noErr) {
612                 if(QTIME_DEBUG) printf("no datahandler\n");
613                 goto bail;
614         }
615
616         err = GetGraphicsImporterForDataRef((Handle)dataref, PointerDataHandlerSubType, &gImporter);
617         if (err != noErr) {
618                 if(QTIME_DEBUG) printf("no graphimport\n");
619                 goto bail;
620         }
621
622         err = GraphicsImportGetNaturalBounds(gImporter, &myRect);
623         if (err != noErr) {
624                 if(QTIME_DEBUG) printf("no bounds\n");
625                 goto bail;
626         }
627
628         err = GraphicsImportGetImageDescription (gImporter, &desc );
629         if (err != noErr) {
630                 if(QTIME_DEBUG) printf("no imagedescription\n");
631                 goto bail;
632         }
633
634         x = RECT_WIDTH(myRect);
635         y = RECT_HEIGHT(myRect);
636         depth = (**desc).depth;
637
638         if (flags & IB_test) {
639                 ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
640                 ibuf->ftype = QUICKTIME;
641                 DisposeHandle((Handle)dataref);
642                 if (gImporter != NULL)  CloseComponent(gImporter);
643                 return ibuf;
644         }
645
646 #ifdef __APPLE__
647         ibuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);
648         wbuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);
649
650         err = NewGWorldFromPtr(&offGWorld,
651                                                 k32ARGBPixelFormat,
652                                                 &myRect, NULL, NULL, 0,
653                                                 (unsigned char *)wbuf->rect, x * 4);
654 #else
655
656         ibuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);   
657
658         err = NewGWorldFromPtr(&offGWorld,
659                                                         k32RGBAPixelFormat,
660                                                         &myRect, NULL, NULL, 0,
661                                                         (unsigned char *)ibuf->rect, x * 4);
662 #endif
663         
664         if (err != noErr) {
665                 if(QTIME_DEBUG) printf("no newgworld\n");
666                 goto bail;
667         } else {
668                 have_gw = TRUE;
669         }
670
671         GraphicsImportSetGWorld(gImporter, offGWorld, NULL);
672         GraphicsImportDraw(gImporter);
673
674 #ifdef __APPLE__
675         rect = ibuf->rect;
676
677         myPixMap = GetGWorldPixMap(offGWorld);
678         LockPixels(myPixMap);
679         myPtr = GetPixBaseAddr(myPixMap);
680
681         if (myPtr == NULL) {
682                 printf ("Error reading frame from Quicktime");
683                 IMB_freeImBuf (ibuf);
684                 return NULL;
685         }
686
687         boxsize = x * y;
688         readPos = (uint32_t *) myPtr;
689         changePos = (uint32_t *) rect;
690
691         // Swap alpha byte to the end, so ARGB become RGBA;
692         from= (unsigned char *)readPos;
693         to= (unsigned char *)changePos;
694         
695         for( index = 0; index < boxsize; index++, from+=4, to+=4 ) {
696                 to[3] = from[0];
697                 to[0] = from[1];
698                 to[1] = from[2];
699                 to[2] = from[3];
700         }
701 #endif
702
703 bail:
704
705         DisposeHandle((Handle)dataref);
706         UnlockPixels(myPixMap);
707         if(have_gw) DisposeGWorld(offGWorld);
708
709 #ifdef __APPLE__
710         if (wbuf) {
711                 IMB_freeImBuf (wbuf);
712                 wbuf = NULL;
713         }
714 #endif
715
716         if (gImporter != NULL)  CloseComponent(gImporter);
717
718         if (err != noErr) {
719                 if(QTIME_DEBUG) printf("quicktime import unsuccesfull\n");
720                 if (ibuf) {
721                         IMB_freeImBuf (ibuf);
722                         ibuf = NULL;
723                 }
724         }
725
726         if(ibuf) {
727
728 #ifdef _WIN32
729 // add non transparent alpha layer, so images without alpha show up in the sequence editor
730 // exception for GIF images since these can be transparent without being 32 bit
731 // (might also be nescessary for OSX)
732                 int i;
733                 int box = x * y;
734                 unsigned char *arect = (unsigned char *) ibuf->rect;
735
736                 if( depth < 32 && (**desc).cType != kGIFCodecType) {
737                         for(i = 0; i < box; i++, arect+=4)
738                                  arect[3] = 0xFF;
739                 }
740 #endif
741
742                 IMB_flipy(ibuf);
743                 ibuf->ftype = QUICKTIME;
744         }
745         return ibuf;
746 }
747
748 #endif /* _WIN32 || __APPLE__ */
749
750 #endif /* WITH_QUICKTIME */
751
752
753 #if 0
754
755 struct ImageDescription {
756      long         idSize;
757      CodecType    cType;
758      long         resvd1;
759      short        resvd2;
760      short        dataRefIndex;
761      short        version;
762      short        revisionLevel;
763      long         vendor;
764      CodecQ       temporalQuality;
765      CodecQ       spatialQuality;
766      short        width;
767      short        height;
768      Fixed        hRes;
769      Fixed        vRes;
770      long         dataSize;
771      short        frameCount;
772      Str31        name;
773      short        depth;
774      short        clutID;
775 };
776
777 #endif // 0