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