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