5
* Code to use Quicktime to load images/movies as texture.
7
2
* ***** BEGIN GPL LICENSE BLOCK *****
8
4
* This program is free software; you can redistribute it and/or
9
5
* modify it under the terms of the GNU General Public License
10
6
* as published by the Free Software Foundation; either version 2
60
58
#include "quicktime_import.h"
61
59
#include "quicktime_export.h"
63
#define RECT_WIDTH(r) (r.right-r.left)
64
#define RECT_HEIGHT(r) (r.bottom-r.top)
61
#define RECT_WIDTH(r) (r.right - r.left)
62
#define RECT_HEIGHT(r) (r.bottom - r.top)
66
64
#define QTIME_DEBUG 0
68
66
typedef struct _QuicktimeMovie {
70
GWorldPtr offscreenGWorld;
71
PixMapHandle offscreenPixMap;
76
int movWidth, movHeight;
85
TimeValue *frameIndex;
68
GWorldPtr offscreenGWorld;
69
PixMapHandle offscreenPixMap;
74
int movWidth, movHeight;
83
TimeValue *frameIndex;
89
int have_gw; /* ugly */
176
174
#endif /* _WIN32 */
179
int anim_is_quicktime (const char *name)
177
int anim_is_quicktime(const char *name)
182
char theFullPath[255];
180
char theFullPath[255];
184
Boolean isMovieFile = false;
185
AliasHandle myAlias = NULL;
186
Component myImporter = NULL;
182
Boolean isMovieFile = false;
183
AliasHandle myAlias = NULL;
184
Component myImporter = NULL;
196
194
// don't let quicktime movie import handle these
197
if ( BLI_testextensie(name, ".swf") ||
198
BLI_testextensie(name, ".txt") ||
199
BLI_testextensie(name, ".mpg") ||
200
BLI_testextensie(name, ".avi") || // wouldnt be appropriate ;)
201
BLI_testextensie(name, ".tga") ||
202
BLI_testextensie(name, ".png") ||
203
BLI_testextensie(name, ".bmp") ||
204
BLI_testextensie(name, ".jpg") ||
205
BLI_testextensie(name, ".wav") ||
206
BLI_testextensie(name, ".zip") ||
207
BLI_testextensie(name, ".mp3")) return 0;
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"))
209
210
if (QTIME_DEBUG) printf("qt: checking as movie: %s\n", name);
260
261
UnlockPixels(anim->qtime->offscreenPixMap);
262
263
if (anim->qtime->have_gw)
263
DisposeGWorld( anim->qtime->offscreenGWorld );
264
DisposeGWorld(anim->qtime->offscreenGWorld);
264
265
if (anim->qtime->ibuf)
265
266
IMB_freeImBuf(anim->qtime->ibuf);
267
DisposeMovie( anim->qtime->movie );
268
CloseMovieFile( anim->qtime->movieRefNum );
268
DisposeMovie(anim->qtime->movie);
269
CloseMovieFile(anim->qtime->movieRefNum);
270
if (anim->qtime->frameIndex) MEM_freeN (anim->qtime->frameIndex);
271
if (anim->qtime) MEM_freeN (anim->qtime);
271
if (anim->qtime->frameIndex) MEM_freeN(anim->qtime->frameIndex);
272
if (anim->qtime) MEM_freeN(anim->qtime);
273
274
anim->qtime = NULL;
279
280
static OSErr QT_get_frameIndexes(struct anim *anim)
283
OSType media = VideoMediaType;
284
OSType media = VideoMediaType;
284
285
TimeValue nextTime = 0;
285
TimeValue startPoint;
286
TimeValue tmpstartPoint;
286
TimeValue startPoint;
287
TimeValue tmpstartPoint;
287
288
long sampleCount = 0;
291
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample+nextTimeEdgeOK, (TimeValue)1, &media, 0,
292
1, &startPoint, NULL);
292
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample + nextTimeEdgeOK, (TimeValue)1, &media, 0,
293
1, &startPoint, NULL);
294
295
tmpstartPoint = startPoint;
322
ImBuf * qtime_fetchibuf (struct anim *anim, int position)
323
ImBuf *qtime_fetchibuf(struct anim *anim, int position)
324
PixMapHandle myPixMap = NULL;
328
register int boxsize;
330
register uint32_t *readPos;
331
register uint32_t *changePos;
325
PixMapHandle myPixMap = NULL;
329
register int boxsize;
331
register uint32_t *readPos;
332
register uint32_t *changePos;
333
334
ImBuf *ibuf = NULL;
334
335
unsigned int *rect;
346
ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect);
347
ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
347
348
rect = ibuf->rect;
349
350
SetMovieTimeValue(anim->qtime->movie, anim->qtime->frameIndex[position]);
368
369
// Swap alpha byte to the end, so ARGB become RGBA;
369
from= (unsigned char *)readPos;
370
to= (unsigned char *)changePos;
370
from = (unsigned char *)readPos;
371
to = (unsigned char *)changePos;
372
for ( index = 0; index < boxsize; index++, from+=4, to+=4 ) {
373
for (index = 0; index < boxsize; index++, from += 4, to += 4) {
381
for ( index = 0; index < boxsize; index++, changePos++, readPos++ )
382
*( changePos ) = *(readPos );
382
for (index = 0; index < boxsize; index++, changePos++, readPos++)
383
*(changePos) = *(readPos);
384
385
if (anim->qtime->depth < 32) {
385
386
//add alpha to ibuf
386
387
boxsize = anim->x * anim->y * 4;
387
388
crect = (unsigned char *) rect;
388
for ( index = 0; index < boxsize; index+=4, crect+=4 ) {
389
for (index = 0; index < boxsize; index += 4, crect += 4) {
394
ibuf->profile = IB_PROFILE_SRGB;
403
402
static int GetFirstVideoMedia(struct anim *anim)
408
407
numTracks = GetMovieTrackCount(anim->qtime->movie);
410
for (anim->qtime->trackIndex=1; anim->qtime->trackIndex<=numTracks; (anim->qtime->trackIndex)++) {
409
for (anim->qtime->trackIndex = 1; anim->qtime->trackIndex <= numTracks; (anim->qtime->trackIndex)++) {
411
410
anim->qtime->theTrack = GetMovieIndTrack(anim->qtime->movie, anim->qtime->trackIndex);
413
412
if (anim->qtime->theTrack)
414
413
anim->qtime->theMedia = GetTrackMedia(anim->qtime->theTrack);
416
415
if (anim->qtime->theMedia)
417
GetMediaHandlerDescription(anim->qtime->theMedia,&mediaType, nil, nil);
416
GetMediaHandlerDescription(anim->qtime->theMedia, &mediaType, nil, nil);
418
417
if (mediaType == VideoMediaType) return 1;
425
424
static short GetFirstVideoTrackPixelDepth(struct anim *anim)
427
SampleDescriptionHandle imageDescH = (SampleDescriptionHandle)NewHandle(sizeof(Handle));
426
SampleDescriptionHandle imageDescH = (SampleDescriptionHandle)NewHandle(sizeof(Handle));
428
427
// long trackIndex = 0; /*unused*/
430
429
if (!GetFirstVideoMedia(anim))
440
int startquicktime (struct anim *anim)
439
int startquicktime(struct anim *anim)
445
char theFullPath[255];
444
char theFullPath[255];
454
anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
453
anim->qtime = MEM_callocN(sizeof(QuicktimeMovie), "animqt");
455
454
anim->qtime->have_gw = FALSE;
457
456
if (anim->qtime == NULL) {
480
479
if (err == noErr) {
481
480
if (QTIME_DEBUG) printf("qt: movie opened\n");
482
481
err = NewMovieFromFile(&anim->qtime->movie,
483
anim->qtime->movieRefNum,
484
&anim->qtime->movieResId, NULL, newMovieActive, NULL);
482
anim->qtime->movieRefNum,
483
&anim->qtime->movieResId, NULL, newMovieActive, NULL);
508
anim->qtime->ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect);
507
anim->qtime->ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
511
510
err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
513
&anim->qtime->movieBounds,
515
(unsigned char *)anim->qtime->ibuf->rect,
512
&anim->qtime->movieBounds,
514
(unsigned char *)anim->qtime->ibuf->rect,
518
517
err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
520
&anim->qtime->movieBounds,
522
(unsigned char *)anim->qtime->ibuf->rect,
519
&anim->qtime->movieBounds,
521
(unsigned char *)anim->qtime->ibuf->rect,
524
523
#endif /* _WIN32 */
526
525
if (err == noErr) {
553
552
anim->curposition = 0;
555
554
if (QTIME_DEBUG) printf("qt: load %s %dx%dx%d frames %d\n", anim->name, anim->qtime->movWidth,
556
anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount);
555
anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount);
561
int imb_is_a_quicktime (char *name)
560
int imb_is_a_quicktime(char *name)
563
GraphicsImportComponent theImporter = NULL;
562
GraphicsImportComponent theImporter = NULL;
567
Str255 dst; /*unused*/
566
Str255 dst; /*unused*/
569
char theFullPath[255];
568
char theFullPath[255];
571
570
// Boolean isMovieFile = false; /*unused*/
572
571
// AliasHandle myAlias = NULL; /*unused*/
573
572
// Component myImporter = NULL; /*unused*/
575
574
// FInfo myFinderInfo; /*unused*/
580
579
if (!G.have_quicktime) return 0;
582
581
if (QTIME_DEBUG) printf("qt: checking as image %s\n", name);
584
583
// don't let quicktime image import handle these
585
if ( BLI_testextensie(name, ".swf") ||
586
BLI_testextensie(name, ".txt") ||
587
BLI_testextensie(name, ".mpg") ||
588
BLI_testextensie(name, ".wav") ||
589
BLI_testextensie(name, ".mov") || // not as image, doesn't work
590
BLI_testextensie(name, ".avi") ||
591
BLI_testextensie(name, ".mp3")) return 0;
584
if (BLI_testextensie(name, ".swf") ||
585
BLI_testextensie(name, ".txt") ||
586
BLI_testextensie(name, ".mpg") ||
587
BLI_testextensie(name, ".wav") ||
588
BLI_testextensie(name, ".mov") || // not as image, doesn't work
589
BLI_testextensie(name, ".avi") ||
590
BLI_testextensie(name, ".mp3"))
593
595
sprintf(theFullPath, "%s", name);
613
615
ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags)
617
GraphicsImportComponent gImporter = NULL;
619
ImageDescriptionHandle desc;
621
ComponentInstance dataHandler;
619
GraphicsImportComponent gImporter = NULL;
621
ImageDescriptionHandle desc;
623
ComponentInstance dataHandler;
622
624
PointerDataRef dataref;
625
627
int have_gw = FALSE;
626
628
ImBuf *ibuf = NULL;
627
629
// ImBuf *imbuf = NULL; /*unused*/
629
PixMapHandle myPixMap = NULL;
631
PixMapHandle myPixMap = NULL;
635
register int boxsize;
637
register uint32_t *readPos;
638
register uint32_t *changePos;
637
register int boxsize;
639
register uint32_t *readPos;
640
register uint32_t *changePos;
640
642
ImBuf *wbuf = NULL;
641
643
unsigned int *rect;
648
650
if (QTIME_DEBUG) printf("qt: attempt to load mem as image\n");
650
dataref= (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord));
652
dataref = (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord));
651
653
(**dataref).data = mem;
652
654
(**dataref).dataLength = size;
654
656
err = OpenADataHandler((Handle)dataref,
655
PointerDataHandlerSubType,
657
PointerDataHandlerSubType,
661
663
if (err != noErr) {
662
664
if (QTIME_DEBUG) printf("no datahandler\n");
689
691
ibuf = IMB_allocImBuf(x, y, depth, 0);
690
692
ibuf->ftype = QUICKTIME;
691
693
DisposeHandle((Handle)dataref);
692
if (gImporter != NULL) CloseComponent(gImporter);
694
if (gImporter != NULL) CloseComponent(gImporter);
697
ibuf = IMB_allocImBuf (x, y, 32, IB_rect);
698
wbuf = IMB_allocImBuf (x, y, 32, IB_rect);
699
ibuf = IMB_allocImBuf(x, y, 32, IB_rect);
700
wbuf = IMB_allocImBuf(x, y, 32, IB_rect);
700
702
err = NewGWorldFromPtr(&offGWorld,
702
&myRect, NULL, NULL, 0,
703
(unsigned char *)wbuf->rect, x * 4);
704
&myRect, NULL, NULL, 0,
705
(unsigned char *)wbuf->rect, x * 4);
706
ibuf = IMB_allocImBuf (x, y, 32, IB_rect);
708
ibuf = IMB_allocImBuf(x, y, 32, IB_rect);
708
710
err = NewGWorldFromPtr(&offGWorld,
710
&myRect, NULL, NULL, 0,
711
(unsigned char *)ibuf->rect, x * 4);
712
&myRect, NULL, NULL, 0,
713
(unsigned char *)ibuf->rect, x * 4);
714
716
if (err != noErr) {
740
742
changePos = (uint32_t *) rect;
742
744
// Swap alpha byte to the end, so ARGB become RGBA;
743
from= (unsigned char *)readPos;
744
to= (unsigned char *)changePos;
745
from = (unsigned char *)readPos;
746
to = (unsigned char *)changePos;
746
for ( index = 0; index < boxsize; index++, from+=4, to+=4 ) {
748
for (index = 0; index < boxsize; index++, from += 4, to += 4) {
785
787
unsigned char *arect = (unsigned char *) ibuf->rect;
787
if ( depth < 32 && (**desc).cType != kGIFCodecType) {
788
for (i = 0; i < box; i++, arect+=4)
789
if (depth < 32 && (**desc).cType != kGIFCodecType) {
790
for (i = 0; i < box; i++, arect += 4)