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