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