Added Quicktime support for OSX and Windows.

This code allows you to load Quicktime images and movies as textures
and render animations to Quicktime movies.
Note that the selected output codec is *not* saved in the blendfile.

To enable Quicktime functionality you need the SDK from Apple:
OSX: ftp://ftp.apple.com/developer/Development_Kits/QT6SDK_Mac.hqx
Win: ftp://ftp.apple.com/developer/Development_Kits/QT6SDK_Win.hqx
Add the \QTDevWin\CIncludes and \QTDevWin\Libraries directories
from this SDK to your build environment.

Enable the WITH_QUICKTIME compile flag in the following directories:
bf\blender\source\blender\imbuf
bf\blender\source\blender\src
bf\blender\source\blender\render
bf\blender\source\creator
This commit is contained in:
Rob Haarsma 2003-04-28 02:15:46 +00:00
parent 1ab53ee998
commit 706ccc0401
25 changed files with 2994 additions and 669 deletions

View File

@ -114,6 +114,10 @@ typedef struct Global {
struct Object *obpose; /* Current posable object */
struct ListBase edbo; /* Armature Editmode bones */
/* Rob's variables */
int have_quicktime;
int ui_international;
/* this variable is written to / read from FileGlobal->fileflags */
int fileflags;

View File

@ -93,7 +93,6 @@
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef IMB_IMBUF_H
#define IMB_IMBUF_H
@ -232,19 +231,27 @@ void IMB_close_anim(struct anim * anim);
*
* @attention Defined in anim.c
*/
int ismovie(char *name);
/**
*
* @attention Defined in anim.c
*/
struct ImBuf * IMB_anim_absolute(struct anim * anim, int position);
/**
*
* @attention Defined in anim.c
*/
void IMB_free_anim(struct anim * anim);
void IMB_free_anim_ibuf(struct anim * anim);
/**
*
* @attention Defined in anim.c
*/
int IMB_isanim(char * name);
void IMB_free_anim(struct anim * anim);
/**
*
@ -320,6 +327,18 @@ short IMB_png_encode(struct ImBuf *ibuf, int file, int flags);
*/
int IMB_ispic(char *name);
/**
*
* @attention Defined in util.c
*/
int IMB_isanim(char * name);
/**
*
* @attention Defined in util.c
*/
int imb_get_anim_type(char * name);
/**
*
* @attention Defined in divers.c
@ -334,6 +353,14 @@ void IMB_de_interlace(struct ImBuf *ibuf);
*/
void IMB_convert_rgba_to_abgr(int size, unsigned int *rect);
/**
* Change the ordering of the colour bytes pointed to by rect from
* rgba to abgr. size * 4 colour bytes are reordered.
*
* @attention Defined in imageprocess.c
*/
void IMB_convert_bgra_to_rgba(int size, unsigned int *rect);
/**
*
* @attention defined in scaling.c
@ -468,4 +495,3 @@ void IMB_freezbufImBuf(struct ImBuf * ibuf);
void IMB_rectfill(unsigned int *drect, unsigned int *srect, int x, int value);
#endif

View File

@ -111,6 +111,15 @@ typedef enum {
#define TGA (1 << 28)
#define JPG (1 << 27)
#define BMP (1 << 26)
#ifdef WITH_QUICKTIME
#define QUICKTIME (1 << 25)
#endif
#ifdef WITH_FREEIMAGE
#define FREEIMAGE (1 << 24)
#endif
#ifdef WITH_IMAGEMAGICK
#define IMAGEMAGICK (1 << 23)
#endif
#define RAWTGA (TGA | 1)

View File

@ -0,0 +1,182 @@
/**
* allocimbuf.h
*
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef IMB_ANIM_H
#define IMB_ANIM_H
#ifdef _WIN32
#define INC_OLE2
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <memory.h>
#include <commdlg.h>
#ifndef FREE_WINDOWS
#include <vfw.h>
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#undef AVIIF_KEYFRAME // redefined in AVI_avi.h
#undef AVIIF_LIST // redefined in AVI_avi.h
#define FIXCC(fcc) if (fcc == 0) fcc = mmioFOURCC('N', 'o', 'n', 'e'); \
if (fcc == BI_RLE8) fcc = mmioFOURCC('R', 'l', 'e', '8');
#endif
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef _WIN32
#include <dirent.h>
#else
#include <io.h>
#include "BLI_winstuff.h"
#endif
#include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail
BLI_countlist BLI_stringdec */
#include "imbuf.h"
#include "imbuf_patch.h"
#include "AVI_avi.h"
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
#include "quicktime_import.h"
#endif /* _WIN32 || __APPLE__ */
#ifdef linux
#include "quicktime_import_linux.h"
#endif /* linux */
#endif /* WITH_QUICKTIME */
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
#include "IMB_bitplanes.h"
/* actually hard coded endianness */
#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3])
#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0])
#define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff))
#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff))
/* more endianness... should move to a separate file... */
#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
#define GET_ID GET_BIG_LONG
#define LITTLE_LONG SWAP_LONG
#else
#define GET_ID GET_LITTLE_LONG
#define LITTLE_LONG ENDIAN_NOP
#endif
/****/
#define ANIM_NONE (0)
#define ANIM_SEQUENCE (1 << 0)
#define ANIM_DIR (1 << 1)
#define ANIM_ANIM5 (1 << 2)
#define ANIM_TGA (1 << 3)
#define ANIM_MOVIE (1 << 4)
#define ANIM_MDEC (1 << 5)
#define ANIM_AVI (1 << 6)
#define ANIM_QTIME (1 << 7)
#define ANIM5_MMAP 0
#define ANIM5_MALLOC 1
#define ANIM5_SNGBUF 2
#define ANIM5_XOR 4
#define MAXNUMSTREAMS 50
struct anim {
int ib_flags;
int curtype;
int curposition; /* index 0 = 1e, 1 = 2e, enz. */
int duration;
int x, y;
/* voor op nummer */
char name[256];
/* voor sequence */
char first[256];
/* anim5 */
struct ListBase anim5base;
void * anim5mmap;
int anim5len;
struct Anim5Delta *anim5curdlta;
void (*anim5decode)(struct ImBuf *, unsigned char *);
int anim5flags;
/* movie */
void *movie;
void *track;
void *params;
int orientation;
size_t framesize;
int interlacing;
/* data */
struct ImBuf * ibuf1, * ibuf2;
/* avi */
struct _AviMovie *avi;
#if defined(_WIN32) && !defined(FREE_WINDOWS)
/* windows avi */
int avistreams;
int firstvideo;
int pfileopen;
PAVIFILE pfile;
PAVISTREAM pavi[MAXNUMSTREAMS]; // the current streams
PGETFRAME pgf;
#endif
#ifdef WITH_QUICKTIME
/* quicktime */
struct _QuicktimeMovie *qtime;
#endif /* WITH_QUICKTIME */
};
#endif

View File

@ -0,0 +1,20 @@
/* IMB_anim.h */
#ifndef IMB_ANIM5_H
#define IMB_ANIM5_H
struct anim;
/**
*
* @attention Defined in anim5.c
*/
int nextanim5(struct anim * anim);
int rewindanim5(struct anim * anim);
int startanim5(struct anim * anim);
void free_anim_anim5(struct anim * anim);
struct ImBuf * anim5_fetchibuf(struct anim * anim);
#endif

View File

@ -39,10 +39,9 @@
#include <mmsystem.h>
#include <memory.h>
#include <commdlg.h>
#include <vfw.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#ifndef FREE_WINDOWS
#include <vfw.h>
#endif
#undef AVIIF_KEYFRAME // redefined in AVI_avi.h
@ -65,112 +64,32 @@
#include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail
BLI_countlist BLI_stringdec */
#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "imbuf.h"
#include "imbuf_patch.h"
#include "AVI_avi.h"
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
#include "quicktime_import.h"
#endif /* _WIN32 || __APPLE__ */
#ifdef linux
#include "quicktime_import_linux.h"
#endif /* linux */
#endif /* WITH_QUICKTIME */
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
#include "IMB_bitplanes.h"
#include "IMB_anim.h"
#include "IMB_anim5.h"
/* actually hard coded endianness */
#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3])
#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0])
#define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff))
#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff))
/* more endianness... should move to a separate file... */
#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
#define GET_ID GET_BIG_LONG
#define LITTLE_LONG SWAP_LONG
#else
#define GET_ID GET_LITTLE_LONG
#define LITTLE_LONG ENDIAN_NOP
#endif
/****/
typedef struct Anhd{
unsigned char type, mask;
unsigned short w, h;
unsigned short x, y;
unsigned short abs16, abs, reala6, real;
unsigned char interleave, pad0;
unsigned short bits16, bits;
unsigned char pad[16];
}Anhd;
typedef struct Anim5Delta {
struct Anim5Delta * next, * prev;
void * data;
int type;
}Anim5Delta;
#define ANIM_NONE (0)
#define ANIM_SEQUENCE (1 << 0)
#define ANIM_DIR (1 << 1)
#define ANIM_ANIM5 (1 << 2)
#define ANIM_TGA (1 << 3)
#define ANIM_MOVIE (1 << 4)
#define ANIM_MDEC (1 << 5)
#define ANIM_AVI (1 << 6)
#define ANIM5_MMAP 0
#define ANIM5_MALLOC 1
#define ANIM5_SNGBUF 2
#define ANIM5_XOR 4
#define MAXNUMSTREAMS 50
struct anim {
int ib_flags;
int curtype;
int curposition; /* index 0 = 1e, 1 = 2e, enz. */
int duration;
int x, y;
/* voor op nummer */
char name[256];
/* voor sequence */
char first[256];
/* anim5 */
struct ListBase anim5base;
void * anim5mmap;
int anim5len;
struct Anim5Delta *anim5curdlta;
void (*anim5decode)(struct ImBuf *, unsigned char *);
int anim5flags;
/* movie */
void *movie;
void *track;
void *params;
int orientation;
size_t framesize;
int interlacing;
/* data */
struct ImBuf * ibuf1, * ibuf2;
/* avi */
struct _AviMovie *avi;
#ifdef _WIN32
/* windows avi */
int avistreams;
int firstvideo;
int pfileopen;
PAVIFILE pfile;
PAVISTREAM pavi[MAXNUMSTREAMS]; // the current streams
PGETFRAME pgf;
#endif
};
/****/
#ifdef __sgi
@ -268,13 +187,13 @@ static void free_anim_movie(struct anim * anim) {
anim->duration = 0;
}
static int ismovie(char *name) {
int ismovie(char *name) {
return (mvIsMovieFile(name) == DM_TRUE);
}
#else
static int ismovie(char *name) {
int ismovie(char *name) {
return 0;
}
@ -334,87 +253,6 @@ unsigned short numlen, int pic) {
strcat(string,staart);
}
/* om anim5's te kunnen lezen, moet een aantal gegevens bijgehouden worden:
* Een lijst van pointers naar delta's, in geheugen of ge'mmap'ed
*
* Mogelijk kan er ook een 'skiptab' aangelegd worden, om sneller
* sprongen te kunnen maken.
*
* Er moeten niet direct al plaatjes gegenereed worden, dit maakt de
* routines onbruikbaar om snel naar het goede plaatje te springen.
* Een routine voert dus de delta's uit, een andere routine maakt van
* voorgrondplaatje een ibuf;
*/
/*
een aantal functie pointers moet geinporteerd worden, zodat er niet
nog meer library's / objects meegelinkt hoeven te worden.
Dezelfde structuur moet ook gebruikt kunnen worden voor het wegschrijven
van animaties. Hoe geef je dit aan ?
Hoe snel kunnen 10 .dlta's gedecomprimeerd worden
(zonder omzetten naar rect).
1 - zoek naar 1e plaatje, animatie die aan de eisen voldoet
2 - probeer volgende plaatje te vinden:
anim5 - decomprimeer
sequence - teller ophogen
directory - volgende entry
3 - geen succes ? ga naar 1.
*/
/*
1. Initialiseer routine met toegestane reeksen, en eerste naam
- series op naam (.0001)
- directories
- anim5 animaties
- TGA delta's
- iff 24bits delta's (.delta)
2. haal volgende (vorige ?) plaatje op.
3. vrijgeven
*/
/* selectie volgorde is:
1 - anim5()
2 - name
3 - dir
*/
static void free_anim_anim5(struct anim * anim) {
ListBase * animbase;
Anim5Delta * delta, * next;
if (anim == NULL) return;
animbase = &anim->anim5base;
delta = animbase->first;
while (delta) {
next = delta->next;
if (delta->type == ANIM5_MALLOC) free(delta->data);
BLI_remlink(animbase, delta);
free(delta);
delta = next;
}
if (anim->anim5mmap && anim->anim5len) {
MEM_freeN(anim->anim5mmap);
}
anim->anim5mmap = NULL;
anim->anim5len = 0;
anim->anim5curdlta = 0;
anim->duration = 0;
}
static void free_anim_avi (struct anim *anim) {
int i;
@ -426,7 +264,7 @@ static void free_anim_avi (struct anim *anim) {
MEM_freeN (anim->avi);
anim->avi = NULL;
#ifdef _WIN32
#if defined(_WIN32) && !defined(FREE_WINDOWS)
if (anim->pgf) {
AVIStreamGetFrameClose(anim->pgf);
@ -448,7 +286,7 @@ static void free_anim_avi (struct anim *anim) {
anim->duration = 0;
}
static void free_anim_ibuf(struct anim * anim) {
void IMB_free_anim_ibuf(struct anim * anim) {
if (anim == NULL) return;
if (anim->ibuf1) IMB_freeImBuf(anim->ibuf1);
@ -464,11 +302,15 @@ void IMB_free_anim(struct anim * anim) {
return;
}
free_anim_ibuf(anim);
IMB_free_anim_ibuf(anim);
free_anim_anim5(anim);
free_anim_movie(anim);
free_anim_avi(anim);
#ifdef WITH_QUICKTIME
free_anim_quicktime(anim);
#endif
free(anim);
}
@ -491,420 +333,10 @@ struct anim * IMB_open_anim(char * name, int ib_flags) {
}
static int isavi (char *name) {
return AVI_is_avi (name);
}
static int imb_get_anim_type(char * name) {
int type;
struct stat st;
if (ib_stat(name,&st) == -1) return(0);
if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
if (isavi(name)) return (ANIM_AVI);
if (ismovie(name)) return (ANIM_MOVIE);
type = IMB_ispic(name);
if (type == ANIM) return (ANIM_ANIM5);
if (type) return(ANIM_SEQUENCE);
return(0);
}
int IMB_isanim(char * name) {
int type= imb_get_anim_type(name);
return (type && type!=ANIM_SEQUENCE);
}
static void planes_to_rect(struct ImBuf * ibuf, int flags) {
if (ibuf == 0) return;
/* dit komt regelrecht uit de amiga.c */
if (flags & IB_rect && ibuf->rect == 0) {
imb_addrectImBuf(ibuf);
imb_bptolong(ibuf);
IMB_flipy(ibuf);
imb_freeplanesImBuf(ibuf);
if (ibuf->cmap){
if ((flags & IB_cmap) == 0) {
IMB_applycmap(ibuf);
IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect);
}
} else if (ibuf->depth == 18){
int i,col;
unsigned int *rect;
rect = ibuf->rect;
for(i=ibuf->x * ibuf->y ; i>0 ; i--){
col = *rect;
col = ((col & 0x3f000) << 6) + ((col & 0xfc0) << 4)
+ ((col & 0x3f) << 2);
col += (col & 0xc0c0c0) >> 6;
*rect++ = col;
}
ibuf->depth = 24;
} else if (ibuf->depth <= 8) {
/* geen colormap en geen 24 bits: zwartwit */
uchar *rect;
int size, shift;
if (ibuf->depth < 8){
rect = (uchar *) ibuf->rect;
rect += 3;
shift = 8 - ibuf->depth;
for (size = ibuf->x * ibuf->y; size > 0; size --){
rect[0] <<= shift;
rect += 4;
}
}
rect = (uchar *) ibuf->rect;
for (size = ibuf->x * ibuf->y; size > 0; size --){
rect[1] = rect[2] = rect[3];
rect += 4;
}
ibuf->depth = 8;
}
}
}
static void anim5decode(struct ImBuf * ibuf, uchar * dlta) {
uchar depth;
int skip;
int *ofspoint;
uchar **planes;
/* samenstelling delta:
lijst met ofsets voor delta's per bitplane (ofspoint)
per kolom in delta (point)
aantal handelingen (noops)
code
bijbehorende data
...
...
*/
dlta += 8;
ofspoint = (int *)dlta;
skip = ibuf->skipx * sizeof(int *);
planes = (uchar **)ibuf->planes;
for(depth=ibuf->depth ; depth>0 ; depth--){
if (GET_BIG_LONG(ofspoint)){
uchar *planestart;
uchar *point;
uchar x;
point = dlta + GET_BIG_LONG(ofspoint);
planestart = planes[0];
x = (ibuf->x + 7) >> 3;
do{
uchar noop;
if (noop = *(point++)){
uchar *plane;
uchar code;
plane = planestart;
do{
if ((code = *(point++))==0){
uchar val;
code = *(point++);
val = *(point++);
do {
plane[0] = val;
plane += skip;
} while(--code);
} else if (code & 128){
code &= 0x7f;
do{
plane[0] = *(point++);
plane += skip;
} while(--code);
} else plane += code * skip;
} while(--noop);
}
planestart++;
} while(--x);
}
ofspoint++;
planes++;
}
}
static void anim5xordecode(struct ImBuf * ibuf, uchar * dlta) {
uchar depth;
int skip;
int *ofspoint;
uchar **planes;
/* samenstelling delta:
lijst met ofsets voor delta's per bitplane (ofspoint)
per kolom in delta (point)
aantal handelingen (noops)
code
bijbehorende data
...
...
*/
dlta += 8;
ofspoint = (int *)dlta;
skip = ibuf->skipx * sizeof(int *);
planes = (uchar **)ibuf->planes;
for(depth=ibuf->depth ; depth>0 ; depth--){
if (GET_BIG_LONG(ofspoint)){
uchar *planestart;
uchar *point;
uchar x;
point = dlta + GET_BIG_LONG(ofspoint);
planestart = planes[0];
x = (ibuf->x + 7) >> 3;
do{
uchar noop;
if (noop = *(point++)){
uchar *plane;
uchar code;
plane = planestart;
do{
if ((code = *(point++))==0){
uchar val;
code = *(point++);
val = *(point++);
do{
plane[0] ^= val;
plane += skip;
}while(--code);
} else if (code & 128){
code &= 0x7f;
do{
plane[0] ^= *(point++);
plane += skip;
}while(--code);
} else plane += code * skip;
}while(--noop);
}
planestart++;
}while(--x);
}
ofspoint++;
planes++;
}
}
static int nextanim5(struct anim * anim) {
Anim5Delta * delta;
struct ImBuf * ibuf;
if (anim == 0) return(-1);
delta = anim->anim5curdlta;
if (delta == 0) return (-1);
if (anim->anim5flags & ANIM5_SNGBUF) {
ibuf = anim->ibuf1;
if (ibuf == 0) return (0);
anim->anim5decode(ibuf, delta->data);
} else {
ibuf = anim->ibuf2;
if (ibuf == 0) return (0);
anim->anim5decode(ibuf, delta->data);
anim->ibuf2 = anim->ibuf1;
anim->ibuf1 = ibuf;
}
anim->anim5curdlta = anim->anim5curdlta->next;
anim->curposition++;
return(0);
}
static int rewindanim5(struct anim * anim) {
Anim5Delta * delta;
struct ImBuf * ibuf;
if (anim == 0) return (-1);
free_anim_ibuf(anim);
delta = anim->anim5base.first;
if (delta == 0) return (-1);
ibuf = IMB_loadiffmem(delta->data, IB_planes);
if (ibuf == 0) return(-1);
anim->ibuf1 = ibuf;
if ((anim->anim5flags & ANIM5_SNGBUF) == 0) anim->ibuf2 = IMB_dupImBuf(ibuf);
anim->anim5curdlta = delta->next;
anim->curposition = 0;
return(0);
}
static int startanim5(struct anim * anim) {
int file, buf[20], totlen;
unsigned int len;
short * mem;
ListBase * animbase;
Anim5Delta * delta;
Anhd anhd;
/* Controles */
if (anim == 0) return(-1);
file = open(anim->name,O_BINARY|O_RDONLY);
if (file < 0) return (-1);
if (read(file, buf, 24) != 24) {
close(file);
return(-1);
}
if ((GET_ID(buf) != FORM) || (GET_ID(buf + 2) != ANIM)
|| (GET_ID(buf + 3) != FORM) || (GET_ID(buf + 5) != ILBM)){
printf("No anim5 file %s\n",anim->name);
close(file);
return (-1);
}
/* de hele file wordt in het geheugen gemapped */
totlen = BLI_filesize(file);
if (totlen && file>=0) {
lseek(file, 0L, SEEK_SET);
mem= MEM_mallocN(totlen, "mmap");
if (read(file, mem, totlen) != totlen) {
MEM_freeN(mem);
mem = NULL;
}
} else {
mem = NULL;
}
close (file);
if (!mem) return (-1);
anhd.interleave = 0;
anhd.bits = 0;
anhd.type = 5;
anim->anim5mmap = mem;
anim->anim5len = totlen;
anim->anim5flags = 0;
anim->duration = 0;
animbase = & anim->anim5base;
animbase->first = animbase->last = 0;
/* eerste plaatje inlezen */
mem = mem + 6;
totlen -= 12;
len = GET_BIG_LONG(mem + 2);
len = (len + 8 + 1) & ~1;
delta = NEW(Anim5Delta);
delta->data = mem;
delta->type = ANIM5_MMAP;
BLI_addtail(animbase, delta);
mem += (len >> 1);
totlen -= len;
while (totlen > 0) {
len = GET_BIG_LONG(mem + 2);
len = (len + 8 + 1) & ~1;
switch(GET_ID(mem)){
case FORM:
len = 12;
break;
case ANHD:
memcpy(&anhd, mem + 4, sizeof(Anhd));
break;
case DLTA:
delta = NEW(Anim5Delta);
delta->data = mem;
delta->type = ANIM5_MMAP;
BLI_addtail(animbase, delta);
break;
}
mem += (len >> 1);
totlen -= len;
}
if (anhd.interleave == 1) anim->anim5flags |= ANIM5_SNGBUF;
if (BIG_SHORT(anhd.bits) & 2) anim->anim5decode = anim5xordecode;
else anim->anim5decode = anim5decode;
/* laatste twee delta's wissen */
delta = animbase->last;
if (delta) {
BLI_remlink(animbase, delta);
free(delta);
}
if ((anim->anim5flags & ANIM5_SNGBUF) == 0) {
delta = animbase->last;
if (delta) {
BLI_remlink(animbase, delta);
free(delta);
}
}
anim->duration = BLI_countlist(animbase);
return(rewindanim5(anim));
}
static struct ImBuf * anim5_fetchibuf(struct anim * anim) {
struct ImBuf * ibuf;
if (anim == 0) return (0);
ibuf = IMB_dupImBuf(anim->ibuf1);
planes_to_rect(ibuf, anim->ib_flags);
return(ibuf);
}
static int startavi (struct anim *anim) {
AviError avierror;
#ifdef _WIN32
#if defined(_WIN32) && !defined(FREE_WINDOWS)
HRESULT hr;
int i, firstvideo = -1;
BYTE abFormat[1024];
@ -922,7 +354,7 @@ static int startavi (struct anim *anim) {
avierror = AVI_open_movie (anim->name, anim->avi);
#ifdef _WIN32
#if defined(_WIN32) && !defined(FREE_WINDOWS)
if (avierror == AVI_ERROR_COMPRESSION) {
AVIFileInit();
hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L);
@ -1006,7 +438,7 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) {
if (anim == NULL) return (NULL);
#ifdef _WIN32
#if defined(_WIN32) && !defined(FREE_WINDOWS)
if (anim->avistreams) {
LPBITMAPINFOHEADER lpbi;
@ -1014,6 +446,7 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) {
lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo]));
if (lpbi) {
ibuf = IMB_ibImageFromMemory((int *) lpbi, 100, IB_rect);
//Oh brother...
}
}
} else {
@ -1054,6 +487,9 @@ static struct ImBuf * anim_getnew(struct anim * anim) {
free_anim_anim5(anim);
free_anim_movie(anim);
free_anim_avi(anim);
#ifdef WITH_QUICKTIME
free_anim_quicktime(anim);
#endif
if (anim->curtype != 0) return (0);
anim->curtype = imb_get_anim_type(anim->name);
@ -1075,9 +511,18 @@ static struct ImBuf * anim_getnew(struct anim * anim) {
ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0); /* fake */
break;
case ANIM_AVI:
if (startavi(anim)) return (0);
if (startavi(anim)) {
printf("couldnt start avi\n");
return (0);
}
ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0);
break;
#ifdef WITH_QUICKTIME
case ANIM_QTIME:
if (startquicktime(anim)) return (0);
ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0);
break;
#endif
}
return(ibuf);
@ -1094,7 +539,9 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
if (anim->curtype == 0) {
ibuf = anim_getnew(anim);
if (ibuf == NULL) return (0);
if (ibuf == NULL) {
return (0);
}
IMB_freeImBuf(ibuf); /* ???? */
}
@ -1134,7 +581,13 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
ibuf = avi_fetchibuf(anim, position);
if (ibuf) anim->curposition = position;
break;
}
#ifdef WITH_QUICKTIME
case ANIM_QTIME:
ibuf = qtime_fetchibuf(anim, position);
if (ibuf) anim->curposition = position;
break;
#endif
}
if (ibuf) {
if (anim->ib_flags & IB_ttob) IMB_flipy(ibuf);

View File

@ -0,0 +1,532 @@
/**
* anim5.c
*
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): phase, code torn apart from anim.c
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail
BLI_countlist BLI_stringdec */
#include "imbuf.h"
#include "imbuf_patch.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_cmap.h"
#include "IMB_allocimbuf.h"
#include "IMB_bitplanes.h"
#include "IMB_amiga.h"
#include "IMB_anim.h"
typedef struct Anhd{
unsigned char type, mask;
unsigned short w, h;
unsigned short x, y;
unsigned short abs16, abs, reala6, real;
unsigned char interleave, pad0;
unsigned short bits16, bits;
unsigned char pad[16];
}Anhd;
typedef struct Anim5Delta {
struct Anim5Delta * next, * prev;
void * data;
int type;
}Anim5Delta;
/* om anim5's te kunnen lezen, moet een aantal gegevens bijgehouden worden:
* Een lijst van pointers naar delta's, in geheugen of ge'mmap'ed
*
* Mogelijk kan er ook een 'skiptab' aangelegd worden, om sneller
* sprongen te kunnen maken.
*
* Er moeten niet direct al plaatjes gegenereed worden, dit maakt de
* routines onbruikbaar om snel naar het goede plaatje te springen.
* Een routine voert dus de delta's uit, een andere routine maakt van
* voorgrondplaatje een ibuf;
*/
/*
een aantal functie pointers moet geinporteerd worden, zodat er niet
nog meer library's / objects meegelinkt hoeven te worden.
Dezelfde structuur moet ook gebruikt kunnen worden voor het wegschrijven
van animaties. Hoe geef je dit aan ?
Hoe snel kunnen 10 .dlta's gedecomprimeerd worden
(zonder omzetten naar rect).
1 - zoek naar 1e plaatje, animatie die aan de eisen voldoet
2 - probeer volgende plaatje te vinden:
anim5 - decomprimeer
sequence - teller ophogen
directory - volgende entry
3 - geen succes ? ga naar 1.
*/
/*
1. Initialiseer routine met toegestane reeksen, en eerste naam
- series op naam (.0001)
- directories
- anim5 animaties
- TGA delta's
- iff 24bits delta's (.delta)
2. haal volgende (vorige ?) plaatje op.
3. vrijgeven
*/
/* selectie volgorde is:
1 - anim5()
2 - name
3 - dir
*/
void free_anim_anim5(struct anim * anim) {
ListBase * animbase;
Anim5Delta * delta, * next;
if (anim == NULL) return;
animbase = &anim->anim5base;
delta = animbase->first;
while (delta) {
next = delta->next;
if (delta->type == ANIM5_MALLOC) free(delta->data);
BLI_remlink(animbase, delta);
free(delta);
delta = next;
}
if (anim->anim5mmap && anim->anim5len) {
MEM_freeN(anim->anim5mmap);
}
anim->anim5mmap = NULL;
anim->anim5len = 0;
anim->anim5curdlta = 0;
anim->duration = 0;
}
static void planes_to_rect(struct ImBuf * ibuf, int flags) {
if (ibuf == 0) return;
/* dit komt regelrecht uit de amiga.c */
if (flags & IB_rect && ibuf->rect == 0) {
imb_addrectImBuf(ibuf);
imb_bptolong(ibuf);
IMB_flipy(ibuf);
imb_freeplanesImBuf(ibuf);
if (ibuf->cmap){
if ((flags & IB_cmap) == 0) {
IMB_applycmap(ibuf);
IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect);
}
} else if (ibuf->depth == 18){
int i,col;
unsigned int *rect;
rect = ibuf->rect;
for(i=ibuf->x * ibuf->y ; i>0 ; i--){
col = *rect;
col = ((col & 0x3f000) << 6) + ((col & 0xfc0) << 4)
+ ((col & 0x3f) << 2);
col += (col & 0xc0c0c0) >> 6;
*rect++ = col;
}
ibuf->depth = 24;
} else if (ibuf->depth <= 8) {
/* geen colormap en geen 24 bits: zwartwit */
uchar *rect;
int size, shift;
if (ibuf->depth < 8){
rect = (uchar *) ibuf->rect;
rect += 3;
shift = 8 - ibuf->depth;
for (size = ibuf->x * ibuf->y; size > 0; size --){
rect[0] <<= shift;
rect += 4;
}
}
rect = (uchar *) ibuf->rect;
for (size = ibuf->x * ibuf->y; size > 0; size --){
rect[1] = rect[2] = rect[3];
rect += 4;
}
ibuf->depth = 8;
}
}
}
static void anim5decode(struct ImBuf * ibuf, uchar * dlta) {
uchar depth;
int skip;
int *ofspoint;
uchar **planes;
/* samenstelling delta:
lijst met ofsets voor delta's per bitplane (ofspoint)
per kolom in delta (point)
aantal handelingen (noops)
code
bijbehorende data
...
...
*/
dlta += 8;
ofspoint = (int *)dlta;
skip = ibuf->skipx * sizeof(int *);
planes = (uchar **)ibuf->planes;
for(depth=ibuf->depth ; depth>0 ; depth--){
if (GET_BIG_LONG(ofspoint)){
uchar *planestart;
uchar *point;
uchar x;
point = dlta + GET_BIG_LONG(ofspoint);
planestart = planes[0];
x = (ibuf->x + 7) >> 3;
do{
uchar noop;
if (noop = *(point++)){
uchar *plane;
uchar code;
plane = planestart;
do{
if ((code = *(point++))==0){
uchar val;
code = *(point++);
val = *(point++);
do {
plane[0] = val;
plane += skip;
} while(--code);
} else if (code & 128){
code &= 0x7f;
do{
plane[0] = *(point++);
plane += skip;
} while(--code);
} else plane += code * skip;
} while(--noop);
}
planestart++;
} while(--x);
}
ofspoint++;
planes++;
}
}
static void anim5xordecode(struct ImBuf * ibuf, uchar * dlta) {
uchar depth;
int skip;
int *ofspoint;
uchar **planes;
/* samenstelling delta:
lijst met ofsets voor delta's per bitplane (ofspoint)
per kolom in delta (point)
aantal handelingen (noops)
code
bijbehorende data
...
...
*/
dlta += 8;
ofspoint = (int *)dlta;
skip = ibuf->skipx * sizeof(int *);
planes = (uchar **)ibuf->planes;
for(depth=ibuf->depth ; depth>0 ; depth--){
if (GET_BIG_LONG(ofspoint)){
uchar *planestart;
uchar *point;
uchar x;
point = dlta + GET_BIG_LONG(ofspoint);
planestart = planes[0];
x = (ibuf->x + 7) >> 3;
do{
uchar noop;
if (noop = *(point++)){
uchar *plane;
uchar code;
plane = planestart;
do{
if ((code = *(point++))==0){
uchar val;
code = *(point++);
val = *(point++);
do{
plane[0] ^= val;
plane += skip;
}while(--code);
} else if (code & 128){
code &= 0x7f;
do{
plane[0] ^= *(point++);
plane += skip;
}while(--code);
} else plane += code * skip;
}while(--noop);
}
planestart++;
}while(--x);
}
ofspoint++;
planes++;
}
}
int nextanim5(struct anim * anim) {
Anim5Delta * delta;
struct ImBuf * ibuf;
if (anim == 0) return(-1);
delta = anim->anim5curdlta;
if (delta == 0) return (-1);
if (anim->anim5flags & ANIM5_SNGBUF) {
ibuf = anim->ibuf1;
if (ibuf == 0) return (0);
anim->anim5decode(ibuf, delta->data);
} else {
ibuf = anim->ibuf2;
if (ibuf == 0) return (0);
anim->anim5decode(ibuf, delta->data);
anim->ibuf2 = anim->ibuf1;
anim->ibuf1 = ibuf;
}
anim->anim5curdlta = anim->anim5curdlta->next;
anim->curposition++;
return(0);
}
int rewindanim5(struct anim * anim) {
Anim5Delta * delta;
struct ImBuf * ibuf;
if (anim == 0) return (-1);
IMB_free_anim_ibuf(anim);
delta = anim->anim5base.first;
if (delta == 0) return (-1);
ibuf = IMB_loadiffmem(delta->data, IB_planes);
if (ibuf == 0) return(-1);
anim->ibuf1 = ibuf;
if ((anim->anim5flags & ANIM5_SNGBUF) == 0) anim->ibuf2 = IMB_dupImBuf(ibuf);
anim->anim5curdlta = delta->next;
anim->curposition = 0;
return(0);
}
int startanim5(struct anim * anim) {
int file, buf[20], totlen;
unsigned int len;
short * mem;
ListBase * animbase;
Anim5Delta * delta;
Anhd anhd;
/* Controles */
if (anim == 0) return(-1);
file = open(anim->name,O_BINARY|O_RDONLY);
if (file < 0) return (-1);
if (read(file, buf, 24) != 24) {
close(file);
return(-1);
}
if ((GET_ID(buf) != FORM) || (GET_ID(buf + 2) != ANIM)
|| (GET_ID(buf + 3) != FORM) || (GET_ID(buf + 5) != ILBM)){
printf("No anim5 file %s\n",anim->name);
close(file);
return (-1);
}
/* de hele file wordt in het geheugen gemapped */
totlen = BLI_filesize(file);
if (totlen && file>=0) {
lseek(file, 0L, SEEK_SET);
mem= MEM_mallocN(totlen, "mmap");
if (read(file, mem, totlen) != totlen) {
MEM_freeN(mem);
mem = NULL;
}
} else {
mem = NULL;
}
close (file);
if (!mem) return (-1);
anhd.interleave = 0;
anhd.bits = 0;
anhd.type = 5;
anim->anim5mmap = mem;
anim->anim5len = totlen;
anim->anim5flags = 0;
anim->duration = 0;
animbase = & anim->anim5base;
animbase->first = animbase->last = 0;
/* eerste plaatje inlezen */
mem = mem + 6;
totlen -= 12;
len = GET_BIG_LONG(mem + 2);
len = (len + 8 + 1) & ~1;
delta = NEW(Anim5Delta);
delta->data = mem;
delta->type = ANIM5_MMAP;
BLI_addtail(animbase, delta);
mem += (len >> 1);
totlen -= len;
while (totlen > 0) {
len = GET_BIG_LONG(mem + 2);
len = (len + 8 + 1) & ~1;
switch(GET_ID(mem)){
case FORM:
len = 12;
break;
case ANHD:
memcpy(&anhd, mem + 4, sizeof(Anhd));
break;
case DLTA:
delta = NEW(Anim5Delta);
delta->data = mem;
delta->type = ANIM5_MMAP;
BLI_addtail(animbase, delta);
break;
}
mem += (len >> 1);
totlen -= len;
}
if (anhd.interleave == 1) anim->anim5flags |= ANIM5_SNGBUF;
if (BIG_SHORT(anhd.bits) & 2) anim->anim5decode = anim5xordecode;
else anim->anim5decode = anim5decode;
/* laatste twee delta's wissen */
delta = animbase->last;
if (delta) {
BLI_remlink(animbase, delta);
free(delta);
}
if ((anim->anim5flags & ANIM5_SNGBUF) == 0) {
delta = animbase->last;
if (delta) {
BLI_remlink(animbase, delta);
free(delta);
}
}
anim->duration = BLI_countlist(animbase);
return(rewindanim5(anim));
}
struct ImBuf * anim5_fetchibuf(struct anim * anim) {
struct ImBuf * ibuf;
if (anim == 0) return (0);
ibuf = IMB_dupImBuf(anim->ibuf1);
planes_to_rect(ibuf, anim->ib_flags);
return(ibuf);
}

View File

@ -46,9 +46,16 @@
#include "IMB_hamx.h"
#include "IMB_jpeg.h"
#include "IMB_bmp.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#include "BKE_global.h"
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined (__APPLE__)
#include "quicktime_import.h"
#elif defined (__linux__)
#include "quicktime_import_linux.h"
#endif
#endif
#ifdef WITH_FREEIMAGE
#include "IMB_freeimage.h"
#endif
/* actually hard coded endianness */
@ -58,7 +65,7 @@
#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff))
/* more endianness... should move to a separate file... */
#if defined(__sgi) || defined (__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
#define GET_ID GET_BIG_LONG
#define LITTLE_LONG SWAP_LONG
#else
@ -104,23 +111,49 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
if (GET_ID(mem) == FORM){
if (GET_ID(mem+2) == ILBM){
return (imb_loadamiga(mem, flags));
} else if (GET_ID(mem+5) == ILBM){ /* animations */
} else if (GET_ID(mem+5) == ILBM){ /* animaties */
return (imb_loadamiga(mem+3, flags));
} else if (GET_ID(mem+2) == ANIM){
return (imb_loadanim(mem, flags));
}
}
}
ibuf = imb_png_decode((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
/* let quicktime handle png's, skips error messages ;)
* but only on windows
*/
#ifdef _WIN32
if(G.have_quicktime == FALSE) {
#else
if(1) {
#endif
ibuf = imb_png_decode((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
}
ibuf = imb_bmp_decode((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
ibuf = imb_loadtarga((uchar *)mem, flags);
if (ibuf) return(ibuf);
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined (__APPLE__)
if(G.have_quicktime) {
ibuf = imb_quicktime_decode((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
}
#endif
#endif
#ifdef WITH_FREEIMAGE
ibuf = imb_freeimage_decode((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
#endif
#ifdef WITH_IMAGEMAGICK
ibuf = imb_imagick_decode((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
#endif
if (IB_verbose) fprintf(stderr, "Unknown fileformat\n");
}
@ -154,7 +187,7 @@ struct ImBuf *IMB_loadiffmem(int *mem, int flags) {
if (GET_ID(mem) == FORM){
if (GET_ID(mem+2) == ILBM){
return (imb_loadamiga(mem, flags));
} else if (GET_ID(mem+5) == ILBM){ /* animations */
} else if (GET_ID(mem+5) == ILBM){ /* animaties */
return (imb_loadamiga(mem+3, flags));
} else if (GET_ID(mem+2) == ANIM){
return (imb_loadanim(mem, flags));

View File

@ -34,6 +34,9 @@
#include "BLI_blenlib.h"
#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "imbuf.h"
#include "imbuf_patch.h"
#include "IMB_imbuf_types.h"
@ -43,9 +46,20 @@
#include "IMB_png.h"
#include "IMB_bmp.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#include "IMB_anim.h"
#ifdef WITH_QUICKTIME
#include "quicktime_import.h"
#endif
#ifdef WITH_FREEIMAGE
#include "IMB_freeimage.h"
#endif
#ifdef WITH_IMAGEMAGICK
#include "IMB_imagemagick.h"
#endif
#define UTIL_DEBUG 0
/* from misc_util: flip the bytes from x */
#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1])
@ -53,11 +67,13 @@
/* this one is only def-ed once, strangely... */
#define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0])
int IMB_ispic(char *name)
int IMB_ispic_name(char *name)
{
struct stat st;
int fp, buf[10];
int ofs = 0;
if(UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
if (ib_stat(name,&st) == -1) return(0);
if (((st.st_mode) & S_IFMT) == S_IFREG){
@ -84,11 +100,28 @@ int IMB_ispic(char *name)
/* if ((BIG_LONG(buf[0]) == 0x10000000) && ((BIG_LONG(buf[1]) & 0xf0ffffff) == 0)) return(TIM); */
}
if (imb_is_a_png(buf)) return(PNG);
if (imb_is_a_targa(buf)) return(TGA);
if (imb_is_a_png(buf)) return(PNG);
if (imb_is_a_targa(buf)) return(TGA);
/*
if (imb_is_a_bmp(buf)) return(BMP);
if (imb_is_a_bmp(buf)) return(BMP);
*/
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
if(G.have_quicktime) {
if (imb_is_a_quicktime(name)) return(QUICKTIME);
}
#endif
#endif
#ifdef WITH_FREEIMAGE
if (imb_is_a_freeimage(name)) return(FREEIMAGE);
#endif
#ifdef WITH_IMAGEMAGICK
if (imb_is_imagick(name)) return(IMAGEMAGICK);
#endif
return(FALSE);
}
close(fp);
@ -96,3 +129,148 @@ int IMB_ispic(char *name)
}
return(FALSE);
}
int IMB_ispic(char *filename)
{
if(U.uiflag & FILTERFILEEXTS) {
if (G.have_quicktime){
if( BLI_testextensie(filename, ".jpg")
|| BLI_testextensie(filename, ".jpeg")
|| BLI_testextensie(filename, ".tga")
|| BLI_testextensie(filename, ".rgb")
|| BLI_testextensie(filename, ".bmp")
|| BLI_testextensie(filename, ".png")
|| BLI_testextensie(filename, ".iff")
|| BLI_testextensie(filename, ".lbm")
|| BLI_testextensie(filename, ".gif")
|| BLI_testextensie(filename, ".psd")
|| BLI_testextensie(filename, ".tif")
|| BLI_testextensie(filename, ".tiff")
|| BLI_testextensie(filename, ".pct")
|| BLI_testextensie(filename, ".pict")
|| BLI_testextensie(filename, ".pntg") //macpaint
|| BLI_testextensie(filename, ".qtif")
#if defined(WITH_FREEIMAGE) || defined (WITH_IMAGEMAGICK) //nasty for now
|| BLI_testextensie(filename, ".jng")
|| BLI_testextensie(filename, ".mng")
|| BLI_testextensie(filename, ".pbm")
|| BLI_testextensie(filename, ".pgm")
|| BLI_testextensie(filename, ".ppm")
|| BLI_testextensie(filename, ".wbmp")
|| BLI_testextensie(filename, ".cut")
|| BLI_testextensie(filename, ".ico")
|| BLI_testextensie(filename, ".koa")
|| BLI_testextensie(filename, ".koala")
|| BLI_testextensie(filename, ".pcd")
|| BLI_testextensie(filename, ".pcx")
|| BLI_testextensie(filename, ".ras")
#endif
|| BLI_testextensie(filename, ".sgi")) {
return IMB_ispic_name(filename);
} else {
return(FALSE);
}
} else { // no quicktime
if( BLI_testextensie(filename, ".jpg")
|| BLI_testextensie(filename, ".jpeg")
|| BLI_testextensie(filename, ".tga")
|| BLI_testextensie(filename, ".rgb")
|| BLI_testextensie(filename, ".bmp")
|| BLI_testextensie(filename, ".png")
|| BLI_testextensie(filename, ".iff")
|| BLI_testextensie(filename, ".lbm")
#if defined(WITH_FREEIMAGE) || defined (WITH_IMAGEMAGICK) //nasty for now
|| BLI_testextensie(filename, ".jng")
|| BLI_testextensie(filename, ".mng")
|| BLI_testextensie(filename, ".pbm")
|| BLI_testextensie(filename, ".pgm")
|| BLI_testextensie(filename, ".ppm")
|| BLI_testextensie(filename, ".wbmp")
|| BLI_testextensie(filename, ".cut")
|| BLI_testextensie(filename, ".ico")
|| BLI_testextensie(filename, ".koa")
|| BLI_testextensie(filename, ".koala")
|| BLI_testextensie(filename, ".pcd")
|| BLI_testextensie(filename, ".pcx")
|| BLI_testextensie(filename, ".ras")
|| BLI_testextensie(filename, ".gif")
|| BLI_testextensie(filename, ".psd")
|| BLI_testextensie(filename, ".tif")
|| BLI_testextensie(filename, ".tiff")
#endif
|| BLI_testextensie(filename, ".sgi")) {
return IMB_ispic_name(filename);
}
else {
return(FALSE);
}
}
} else { // no FILTERFILEEXTS
return IMB_ispic_name(filename);
}
}
static int isavi (char *name) {
return AVI_is_avi (name);
}
#ifdef WITH_QUICKTIME
static int isqtime (char *name) {
return anim_is_quicktime (name);
}
#endif
int imb_get_anim_type(char * name) {
int type;
struct stat st;
if(UTIL_DEBUG) printf("in getanimtype: %s\n", name);
if (ib_stat(name,&st) == -1) return(0);
if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
if (isavi(name)) return (ANIM_AVI);
if (ismovie(name)) return (ANIM_MOVIE);
#ifdef WITH_QUICKTIME
if (isqtime(name)) return (ANIM_QTIME);
#endif
type = IMB_ispic(name);
if (type == ANIM) return (ANIM_ANIM5);
if (type) return(ANIM_SEQUENCE);
return(0);
}
int IMB_isanim(char *filename) {
int type;
if(U.uiflag & FILTERFILEEXTS) {
if (G.have_quicktime){
if( BLI_testextensie(filename, ".avi")
|| BLI_testextensie(filename, ".flc")
|| BLI_testextensie(filename, ".mov")
|| BLI_testextensie(filename, ".movie")
|| BLI_testextensie(filename, ".mv")) {
type = imb_get_anim_type(filename);
} else {
return(FALSE);
}
} else { // no quicktime
if( BLI_testextensie(filename, ".avi")
|| BLI_testextensie(filename, ".mv")) {
type = imb_get_anim_type(filename);
}
else {
return(FALSE);
}
}
} else { // no FILTERFILEEXTS
type = imb_get_anim_type(filename);
}
return (type && type!=ANIM_SEQUENCE);
}

View File

@ -38,7 +38,7 @@
void start_avi_codec(void);
void append_avi_codec(int frame);
void end_avi_codec(void);
int get_codec_settings(void);
int get_avicodec_settings(void);
#endif

View File

@ -290,6 +290,7 @@ typedef struct Scene {
#define R_AVIJPEG 16
#define R_PNG 17
#define R_AVICODEC 18
#define R_QUICKTIME 19
/* **************** RENDER ********************* */

View File

@ -395,6 +395,7 @@ typedef struct SpaceImaSel {
#define IMAGEFILE 16
#define MOVIEFILE 32
#define PYSCRIPTFILE 64
#define FTFONTFILE 128
#define SCROLLH 16 /* height scrollbar */
#define SCROLLB 16 /* width scrollbar */

View File

@ -49,7 +49,14 @@ typedef struct UserDef {
short versions, vrmlflag; // tmp for export, will be replaced by strubi
int gameflags;
int wheellinescroll;
short uiflag, pad2;
short uiflag, language;
int userpref;
short console_buffer; //console vars here for tuhopuu compat, --phase
short console_out;
int fontsize;
short encoding;
short transopts;
char fontname[64];
} UserDef;
extern UserDef U; /* from usiblender.c !!!! */
@ -79,7 +86,16 @@ extern UserDef U; /* from usiblender.c !!!! */
#define WHEELZOOMDIR 4
#define FILTERFILEEXTS 8
/* transopts */
#define TR_TOOLTIPS 1
#define TR_BUTTONS 2
#define TR_MENUS 4
#define TR_FILESELECT 8
#define TR_TEXTEDIT 16
/* dupflag */
#define DUPMESH 1
#define DUPCURVE 2
#define DUPSURF 4
@ -93,16 +109,15 @@ extern UserDef U; /* from usiblender.c !!!! */
#define DUPACT 1024
/* gameflags */
#define USERDEF_VERTEX_ARRAYS_BIT 0
#define USERDEF_DISABLE_SOUND_BIT 1
#define USERDEF_DISABLE_MIPMAP_BIT 2
#define USERDEF_VERTEX_ARRAYS (1 << USERDEF_VERTEX_ARRAYS_BIT)
#define USERDEF_DISABLE_SOUND (1 << USERDEF_DISABLE_SOUND_BIT)
#define USERDEF_DISABLE_MIPMAP (1 << USERDEF_DISABLE_MIPMAP_BIT)
/* vrml flag */
#define USERDEF_VRML_LAYERS 1

View File

@ -0,0 +1,758 @@
/**
* $Id$
*
* quicktime_export.c
*
* Code to create QuickTime Movies with Blender
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* The Original Code is written by Rob Haarsma (phase)
*
* Contributor(s): Stefan Gartner (sgefant)
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
/*
TODO:
- fix saving of compressionsettings
This should be fixed because:
- currently only one quicktime codec is used for all scenes
- this single codecsetting gets only initialised from the codec dialog
- the codecsettings have to get stored in the blendfile for background
rendering. blender -b crashes when it wants to popup the qt codec dialog
to retrieve a valid codec.
(quicktime isnt initialised yet when blender -b requests a rendering codec)
Some references to store the codec settings are placed at the end of this file.
DONE:
* structurize file & compression data
* fix 23.98, 29.97, 59.94 framerates
* fix framerate button
* fix mac compatibility
* fix fallthrough to codecselector // buttons.c
* fix playback qt movie // playanim.c
* fix setting fps thru blenderbutton as well as codec dialog
*/
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
/************************************************************
* *
* INCLUDE FILES *
* *
*************************************************************/
#include "BKE_global.h"
#include "BKE_scene.h"
#include "BLI_blenlib.h"
#include "BLO_sys_types.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "MEM_guardedalloc.h"
#include "render.h"
#include "quicktime_export.h"
#include <Movies.h>
#include <QuicktimeComponents.h>
#ifdef _WIN32
#include <FixMath.h>
#include <QTML.h>
#include <TextUtils.h>
#endif /* _WIN32 */
#ifdef __APPLE__
#include <fcntl.h> /* open() */
#include <unistd.h> /* close() */
#include <sys/stat.h> /* file permissions */
#endif /* __APPLE__ */
/************************************************************
* *
* FUNCTION PROTOTYPES *
* *
*************************************************************/
static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame);
static void QT_DoAddVideoSamplesToMedia (int frame);
static void QT_EndAddVideoSamplesToMedia (void);
static void QT_CreateMyVideoTrack (void);
static void QT_EndCreateMyVideoTrack (void);
static void check_renderbutton_framerate(void);
/************************************************************
* *
* STRUCTS *
* *
*************************************************************/
typedef struct _QuicktimeExport {
FSSpec theSpec;
short resRefNum;
short resId;
short movieResId;
Str255 qtfilename;
Media theMedia;
Movie theMovie;
Track theTrack;
GWorldPtr theGWorld;
PixMapHandle thePixMap;
ImageDescription **anImageDescription;
ImageSequence anImageSequence;
ImBuf *ibuf;
} QuicktimeExport;
typedef struct _QuicktimeCodecDataExt {
ComponentInstance theComponent;
SCTemporalSettings gTemporalSettings;
SCSpatialSettings gSpatialSettings;
SCDataRateSettings aDataRateSetting;
TimeValue duration;
long kVideoTimeScale;
} QuicktimeCodecDataExt;
struct _QuicktimeExport *qte;
struct _QuicktimeCodecDataExt *qcdx;
/************************************************************
* *
* VARIABLES *
* *
*************************************************************/
#define kMyCreatorType FOUR_CHAR_CODE('TVOD')
#define kPixelDepth 32 /* use 32-bit depth */
#define kTrackStart 0
#define kMediaStart 0
static int sframe;
/************************************************************
* *
* CheckError(OSErr err, char *msg) *
* *
* prints errors in console, doesnt interrupt Blender *
* *
*************************************************************/
void CheckError(OSErr err, char *msg)
{
if(err != noErr) printf("%s: %d\n", msg, err);
}
/************************************************************
* *
* QT_CreateMyVideoTrack() *
* QT_EndCreateMyVideoTrack() *
* *
* Creates/finishes a video track for the QuickTime movie *
* *
*************************************************************/
static void QT_CreateMyVideoTrack(void)
{
OSErr err = noErr;
Rect trackFrame;
trackFrame.top = 0;
trackFrame.left = 0;
trackFrame.bottom = R.recty;
trackFrame.right = R.rectx;
qte->theTrack = NewMovieTrack (qte->theMovie,
FixRatio(trackFrame.right,1),
FixRatio(trackFrame.bottom,1),
kNoVolume);
CheckError( GetMoviesError(), "NewMovieTrack error" );
qte->theMedia = NewTrackMedia (qte->theTrack,
VideoMediaType,
qcdx->kVideoTimeScale,
nil,
0);
CheckError( GetMoviesError(), "NewTrackMedia error" );
err = BeginMediaEdits (qte->theMedia);
CheckError( err, "BeginMediaEdits error" );
QT_StartAddVideoSamplesToMedia (&trackFrame);
}
static void QT_EndCreateMyVideoTrack(void)
{
OSErr err = noErr;
QT_EndAddVideoSamplesToMedia ();
err = EndMediaEdits (qte->theMedia);
CheckError( err, "EndMediaEdits error" );
err = InsertMediaIntoTrack (qte->theTrack,
kTrackStart,/* track start time */
kMediaStart,/* media start time */
GetMediaDuration (qte->theMedia),
fixed1);
CheckError( err, "InsertMediaIntoTrack error" );
}
/************************************************************
* *
* QT_StartAddVideoSamplesToMedia() *
* QT_DoAddVideoSamplesToMedia() *
* QT_EndAddVideoSamplesToMedia() *
* *
* Creates video samples for the media in a track *
* *
*************************************************************/
static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame)
{
OSErr err = noErr;
qte->ibuf = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);
err = NewGWorldFromPtr( &qte->theGWorld,
k32ARGBPixelFormat,
trackFrame,
NULL, NULL, 0,
(unsigned char *)qte->ibuf->rect,
R.rectx * 4 );
CheckError (err, "NewGWorldFromPtr error");
qte->thePixMap = GetGWorldPixMap(qte->theGWorld);
LockPixels(qte->thePixMap);
SCDefaultPixMapSettings (qcdx->theComponent, qte->thePixMap, true);
SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
SCSetInfo(qcdx->theComponent, scSpatialSettingsType, &qcdx->gSpatialSettings);
SCSetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);
err = SCCompressSequenceBegin(qcdx->theComponent, qte->thePixMap, NULL, &qte->anImageDescription);
CheckError (err, "SCCompressSequenceBegin error" );
}
static void QT_DoAddVideoSamplesToMedia (int frame)
{
OSErr err = noErr;
Rect imageRect;
register int index;
register int boxsize;
register uint32_t *readPos;
register uint32_t *changePos;
Ptr myPtr;
short syncFlag;
long dataSize;
Handle compressedData;
// flip rendered data for quicktime
// NOTE: we flip the original renderdata !
short x,y,backx;
unsigned int *top,*bottom,temp;
x = R.rectx; y = R.recty; backx = x<<1;
top = R.rectot; bottom = top + ((y-1) * x); y >>= 1;
for(;y>0;y--){
for(x = R.rectx; x > 0; x--){
temp = *top;
*(top++) = *bottom;
*(bottom++) = temp;
}
bottom -= backx;
}
//get pointers to parse bitmapdata
myPtr = GetPixBaseAddr(qte->thePixMap);
imageRect = (**qte->thePixMap).bounds;
boxsize = R.rectx * R.recty;
readPos = (uint32_t *) R.rectot;
changePos = (uint32_t *) myPtr;
#ifdef __APPLE__
// Swap alpha byte to the end, so ARGB become RGBA; note this is big endian-centric.
for( index = 0; index < boxsize; index++, changePos++, readPos++ )
*( changePos ) = ( ( *readPos & 0xFFFFFFFF ) >> 8 ) |
( ( *readPos << 24 ) & 0xFF );
#endif
#ifdef _WIN32
// poked around a little... this seems to work for windows, dunno if it's legal
for( index = 0; index < boxsize; index++, changePos++, readPos++ )
*( changePos ) = ( ( *readPos & 0xFFFFFFFF ) << 8 ) |
( ( *readPos >> 24 ) & 0xFF ); // & ( ( *readPos << 8 ) & 0xFF );
#endif
err = SCCompressSequenceFrame(qcdx->theComponent,
qte->thePixMap,
&imageRect,
&compressedData,
&dataSize,
&syncFlag);
CheckError(err, "SCCompressSequenceFrame error");
err = AddMediaSample(qte->theMedia,
compressedData,
0,
dataSize,
qcdx->duration,
(SampleDescriptionHandle)qte->anImageDescription,
1,
syncFlag,
NULL);
CheckError(err, "AddMediaSample error");
printf ("added frame %3d (frame %3d in movie): ", frame, frame-sframe);
}
static void QT_EndAddVideoSamplesToMedia (void)
{
SCCompressSequenceEnd(qcdx->theComponent);
UnlockPixels(qte->thePixMap);
if (qte->theGWorld) DisposeGWorld (qte->theGWorld);
if (qte->ibuf) IMB_freeImBuf(qte->ibuf);
}
/************************************************************
* *
* makeqtstring (char *string) *
* *
* Function to generate output filename *
* *
*************************************************************/
void makeqtstring (char *string) {
char txt[64];
if (string==0) return;
strcpy(string, G.scene->r.pic);
BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
RE_make_existing_file(string);
if (strcasecmp(string + strlen(string) - 4, ".mov")) {
sprintf(txt, "%04d_%04d.mov", (G.scene->r.sfra) , (G.scene->r.efra) );
strcat(string, txt);
}
}
/************************************************************
* *
* start_qt(void) *
* append_qt(int frame) *
* end_qt(int frame) *
* *
* Quicktime Export functions for Blender's initrender.c *
* *
************************************************************/
void start_qt(void) {
OSErr err = noErr;
char name[2048];
char theFullPath[255];
#ifdef __APPLE__
int myFile;
FSRef myRef;
#endif
if(qte == NULL) qte = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
if(qcdx == NULL || have_qtcodec == FALSE) get_qtcodec_settings();
if (G.afbreek != 1) {
sframe = (G.scene->r.sfra);
makeqtstring(name);
sprintf(theFullPath, "%s", name);
#ifdef __APPLE__
/* hack: create an empty file to make FSPathMakeRef() happy */
myFile = open(theFullPath, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRUSR|S_IWUSR);
if (myFile < 0) {
printf("error while creating file!\n");
/* do something? */
}
close(myFile);
err = FSPathMakeRef(theFullPath, &myRef, 0);
CheckError(err, "FsPathMakeRef error");
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qte->theSpec, NULL);
CheckError(err, "FsGetCatalogInfoRef error");
#else
CopyCStringToPascal(theFullPath, qte->qtfilename);
err = FSMakeFSSpec(0, 0L, qte->qtfilename, &qte->theSpec);
#endif
err = CreateMovieFile (&qte->theSpec,
kMyCreatorType,
smCurrentScript,
createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
&qte->resRefNum,
&qte->theMovie );
CheckError(err, "CreateMovieFile error");
printf("Created QuickTime movie: %s\n", name);
check_renderbutton_framerate();
QT_CreateMyVideoTrack();
}
}
void append_qt(int frame) {
QT_DoAddVideoSamplesToMedia(frame);
}
void end_qt(void) {
OSErr err = noErr;
short x,y,backx;
unsigned int *top,*bottom,temp;
if(qte->theMovie) {
QT_EndCreateMyVideoTrack ();
qte->resId = movieInDataForkResID;
err = AddMovieResource (qte->theMovie, qte->resRefNum, &qte->resId, qte->qtfilename);
CheckError(err, "AddMovieResource error");
if (qte->resRefNum) CloseMovieFile (qte->resRefNum);
DisposeMovie (qte->theMovie);
//flip back rendered data when done exporting quicktime
x = R.rectx; y = R.recty; backx = x<<1;
top = R.rectot; bottom = top + ((y-1) * x); y >>= 1;
for(;y>0;y--){
for(x = R.rectx; x > 0; x--){
temp = *top;
*(top++) = *bottom;
*(bottom++) = temp;
}
bottom -= backx;
}
}
if(qte) {
MEM_freeN(qte);
qte = NULL;
}
};
/************************************************************
* *
* free_qtcodecdataExt(void) *
* *
* Function to release codec memory, since it remains *
* resident after allocation. *
* *
*************************************************************/
void free_qtcodecdataExt(void) {
if(qcdx) {
MEM_freeN(qcdx);
qcdx = NULL;
}
}
/************************************************************
* *
* check_renderbutton_framerate ( void ) *
* *
* To keep float framerates consistent between the codec *
* dialog and frs/sec button. *
* *
*************************************************************/
static void check_renderbutton_framerate(void) {
OSErr err;
err = SCGetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
CheckError(err, "SCGetInfo error");
if( (G.scene->r.frs_sec == 24 || G.scene->r.frs_sec == 30 || G.scene->r.frs_sec == 60) &&
(qcdx->gTemporalSettings.frameRate == 1571553 ||
qcdx->gTemporalSettings.frameRate == 1964113 ||
qcdx->gTemporalSettings.frameRate == 3928227)) {;} else
qcdx->gTemporalSettings.frameRate = G.scene->r.frs_sec << 16;
err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
CheckError( err, "SCSetInfo error" );
if(qcdx->gTemporalSettings.frameRate == 1571553) { // 23.98 fps
qcdx->kVideoTimeScale = 2398;
qcdx->duration = 100;
} else if (qcdx->gTemporalSettings.frameRate == 1964113) { // 29.97 fps
qcdx->kVideoTimeScale = 2997;
qcdx->duration = 100;
} else if (qcdx->gTemporalSettings.frameRate == 3928227) { // 59.94 fps
qcdx->kVideoTimeScale = 5994;
qcdx->duration = 100;
} else {
qcdx->kVideoTimeScale = (qcdx->gTemporalSettings.frameRate >> 16) * 100;
qcdx->duration = 100;
}
}
/********************************************************************
* *
* get_qtcodec_settings() *
* *
* Displays Codec Dialog and retrieves Quicktime Codec settings. *
* *
********************************************************************/
int get_qtcodec_settings(void)
{
OSErr err = noErr;
// Component c = 0;
// ComponentDescription cd;
// cd.componentType = StandardCompressionType;
// cd.componentSubType = StandardCompressionSubType;
// cd.componentManufacturer = 0;
// cd.componentFlags = 0;
// cd.componentFlagsMask = 0;
if(qcdx == NULL) {
qcdx = MEM_callocN(sizeof(QuicktimeCodecDataExt), "QuicktimeCodecDataExt");
have_qtcodec = FALSE;
}
// configure the standard image compression dialog box
if (qcdx->theComponent == NULL) {
qcdx->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
// c = FindNextComponent(c, &cd);
// qcdx->theComponent = OpenComponent(c);
qcdx->gSpatialSettings.codecType = nil;
qcdx->gSpatialSettings.codec = anyCodec;
// qcdx->gSpatialSettings.depth;
qcdx->gSpatialSettings.spatialQuality = codecMaxQuality;
qcdx->gTemporalSettings.temporalQuality = codecMaxQuality;
// qcdx->gTemporalSettings.frameRate;
qcdx->gTemporalSettings.keyFrameRate = 24;
qcdx->aDataRateSetting.dataRate = 90 * 1024;
// qcdx->aDataRateSetting.frameDuration;
// qcdx->aDataRateSetting.minSpatialQuality;
// qcdx->aDataRateSetting.minTemporalQuality;
err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
CheckError(err, "SCSetInfo1 error");
err = SCSetInfo(qcdx->theComponent, scSpatialSettingsType, &qcdx->gSpatialSettings);
CheckError(err, "SCSetInfo2 error");
err = SCSetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);
CheckError(err, "SCSetInfo3 error");
}
check_renderbutton_framerate();
// put up the dialog box
err = SCRequestSequenceSettings(qcdx->theComponent);
if (err == scUserCancelled) {
G.afbreek = 1;
return 0;
}
have_qtcodec = TRUE;
// get user selected data
SCGetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
SCGetInfo(qcdx->theComponent, scSpatialSettingsType, &qcdx->gSpatialSettings);
SCGetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);
// framerate jugglin'
if(qcdx->gTemporalSettings.frameRate == 1571553) { // 23.98 fps
qcdx->kVideoTimeScale = 2398;
qcdx->duration = 100;
G.scene->r.frs_sec = 24;
} else if (qcdx->gTemporalSettings.frameRate == 1964113) { // 29.97 fps
qcdx->kVideoTimeScale = 2997;
qcdx->duration = 100;
G.scene->r.frs_sec = 30;
} else if (qcdx->gTemporalSettings.frameRate == 3928227) { // 59.94 fps
qcdx->kVideoTimeScale = 5994;
qcdx->duration = 100;
G.scene->r.frs_sec = 60;
} else {
qcdx->kVideoTimeScale = 600;
qcdx->duration = qcdx->kVideoTimeScale / (qcdx->gTemporalSettings.frameRate / 65536);
G.scene->r.frs_sec = (qcdx->gTemporalSettings.frameRate / 65536);
}
return 1;
}
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
#if 0
/************************************************************
* *
* References for future codec handling *
* *
*************************************************************/
these are from mplayer sourcecode:
struct ComponentRecord {
long data[1];
};
typedef struct ComponentRecord ComponentRecord;
typedef ComponentRecord * Component;
typedef long OSErr;
typedef int OSType;
typedef long ComponentResult;
typedef long Fixed;
these are from quicktime:
typedef Component CodecComponent;
typedef OSType CodecType;
typedef unsigned short CodecFlags;
typedef unsigned long CodecQ;
typedef struct {
CodecType codecType; /* compressor type */
CodecComponent codec; /* compressor */
short depth; /* pixel depth */
CodecQ spatialQuality; /* desired quality */
} SCSpatialSettings;
/* temporal options structure with the temporal settings request */
typedef struct {
CodecQ temporalQuality; /* desired quality */
Fixed frameRate; /* frame rate */
long keyFrameRate; /* key frame rate */
} SCTemporalSettings;
/* data rate options with the data rate settings request */
typedef struct {
long dataRate; /* desired data rate */
long frameDuration; /* frame duration */
CodecQ minSpatialQuality; /* minimum value */
CodecQ minTemporalQuality; /* minimum value */
} SCDataRateSettings;
would look like this ???
typedef struct {
int codecType; /* compressor type */
//here is the prob
long *codec; /* compressor */
short depth; /* pixel depth */
unsigned long spatialQuality; /* desired quality */
} SCSpatialSettings;
/* temporal options structure with the temporal settings request */
typedef struct {
unsigned long temporalQuality; /* desired quality */
long frameRate; /* frame rate */
long keyFrameRate; /* key frame rate */
} SCTemporalSettings;
/* data rate options with the data rate settings request */
typedef struct {
long dataRate; /* desired data rate */
long frameDuration; /* frame duration */
unsigned long minSpatialQuality; /* minimum value */
unsigned long minTemporalQuality; /* minimum value */
} SCDataRateSettings;
stuff to use quicktime Atoms (doesnt work) heh
long size;
Ptr thePtr;
QTAtomContainer myContainer = NULL;
QTAtom myAtom;
QTAtomContainer SettingsAtom;
atom -> component
SCSetSettingsFromAtomContainer(qcdx->theComponent, SettingsAtom);
component -> atom
SCGetSettingsAsAtomContainer(qcdx->theComponent, SettingsAtom);
QTCopyAtomDataToPtr(container, atom, 0, size, &targetPtr, &actualsize);
QTGetAtomDataPtr(container, atom, &size, &ptr);
kParentAtomIsContainer
#endif /* 0 */

View File

@ -0,0 +1,652 @@
/**
* $Id$
*
* quicktime_import.c
*
* Code to use Quicktime to load images/movies as texture.
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* The Original Code is written by Rob Haarsma (phase)
*
* Contributor(s): Stefan Gartner (sgefant)
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined(__APPLE__)
#include "IMB_anim.h"
#include "BLO_sys_types.h"
#include <Movies.h>
#ifdef _WIN32
#include <QTML.h>
#include <TextUtils.h>
#endif /* _WIN32 */
//#ifdef __APPLE__
#include <QuickTimeComponents.h>
//#endif /* __APPLE__ */
#include "quicktime_import.h"
#define RECT_WIDTH(r) (r.right-r.left)
#define RECT_HEIGHT(r) (r.bottom-r.top)
#define QTIME_DEBUG 0
int anim_is_quicktime (char *name)
{
FSSpec theFSSpec;
Str255 dst;
char theFullPath[255];
Boolean isMovieFile = false;
AliasHandle myAlias = NULL;
Component myImporter = NULL;
#ifdef __APPLE__
FInfo myFinderInfo;
FSRef myRef;
#endif
OSErr err = noErr;
// dont let quicktime movie import handle these
if( BLI_testextensie(name, ".swf") ||
BLI_testextensie(name, ".txt") ||
BLI_testextensie(name, ".mpg") ||
BLI_testextensie(name, ".avi") || // wouldnt be appropriate ;)
BLI_testextensie(name, ".wav") ||
BLI_testextensie(name, ".zip") ||
BLI_testextensie(name, ".mp3")) return 0;
if(QTIME_DEBUG) printf("qt: checking as movie %s\n");
sprintf(theFullPath, "%s", name);
#ifdef __APPLE__
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
#else
CopyCStringToPascal(theFullPath, dst);
err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
#endif
#ifdef __APPLE__
// see whether the file type is MovieFileType; to do this, get the Finder information
err = FSpGetFInfo(&theFSSpec, &myFinderInfo);
if (err == noErr) {
if (myFinderInfo.fdType == kQTFileTypeMovie) {
return(true);
}
}
#endif
/* on mac os x this results in using quicktime for other formats as well
* not sure whether this is intended
*/
// if it isn't a movie file, see whether the file can be imported as a movie
err = QTNewAlias(&theFSSpec, &myAlias, true);
if (err == noErr) {
if (myAlias != NULL) {
err = GetMovieImporterForDataRef(rAliasType, (Handle)myAlias, kGetMovieImporterDontConsiderGraphicsImporters, &myImporter);
DisposeHandle((Handle)myAlias);
}
}
if ((err == noErr) && (myImporter != NULL)) { // this file is a movie file
isMovieFile = true;
}
return(isMovieFile);
}
void free_anim_quicktime (struct anim *anim) {
if (anim == NULL) return;
if (anim->qtime == NULL) return;
UnlockPixels(anim->qtime->offscreenPixMap);
if(anim->qtime->have_gw)
DisposeGWorld( anim->qtime->offscreenGWorld );
if(anim->qtime->ibuf)
IMB_freeImBuf(anim->qtime->ibuf);
DisposeMovie( anim->qtime->movie );
CloseMovieFile( anim->qtime->movieRefNum );
if(anim->qtime->frameIndex) MEM_freeN (anim->qtime->frameIndex);
if(anim->qtime) MEM_freeN (anim->qtime);
anim->qtime = NULL;
anim->duration = 0;
}
OSErr QT_get_frameIndexes(struct anim *anim)
{
int i;
OSErr anErr = noErr;
OSType media = VideoMediaType;
TimeValue nextTime = 0;
TimeValue startPoint;
TimeValue tmpstartPoint;
startPoint = -1;
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample+nextTimeEdgeOK, (TimeValue)1, &media, 0,
1, &startPoint, NULL);
tmpstartPoint = startPoint;
anim->qtime->framecount = 0;
while(tmpstartPoint != -1) {
nextTime = 0;
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, tmpstartPoint, 0, &nextTime, NULL);
tmpstartPoint = nextTime;
anim->qtime->framecount ++;
}
anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex");
//rewind
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, (TimeValue)1, 0, &tmpstartPoint, NULL);
anim->qtime->frameIndex[0] = startPoint;
for(i = 1; i < anim->qtime->framecount; i++) {
nextTime = 0;
GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, startPoint, 0, &nextTime, NULL);
startPoint = nextTime;
anim->qtime->frameIndex[i] = nextTime;
}
anErr = GetMoviesError();
return anErr;
}
ImBuf * qtime_fetchibuf (struct anim *anim, int position)
{
PixMapHandle myPixMap = NULL;
Ptr myPtr;
register int index;
register int boxsize;
register uint32_t *readPos;
register uint32_t *changePos;
ImBuf *ibuf = NULL;
unsigned int *rect;
unsigned char *crect;
if (anim == NULL) {
return (NULL);
}
ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect, 0);
rect = ibuf->rect;
SetMovieTimeValue(anim->qtime->movie, anim->qtime->frameIndex[position]);
UpdateMovie(anim->qtime->movie);
MoviesTask(anim->qtime->movie, 0);
myPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
myPtr = GetPixBaseAddr(myPixMap);
if (myPtr == NULL) {
printf ("Error reading frame from Quicktime");
IMB_freeImBuf (ibuf);
return NULL;
}
boxsize = anim->x * anim->y;
readPos = (uint32_t *) myPtr;
changePos = (uint32_t *) rect; //textureIMBuf *THE* data pointerrr
#ifdef __APPLE__
// Swap alpha byte to the end, so ARGB become RGBA; note this is
// big endian-centric.
for( index = 0; index < boxsize; index++, changePos++, readPos++ )
*( changePos ) = ( ( *readPos & 0xFFFFFF ) << 8 ) |
( ( *readPos >> 24 ) & 0xFF );
#endif
#ifdef _WIN32
for( index = 0; index < boxsize; index++, changePos++, readPos++ )
*( changePos ) = *(readPos );
if(anim->qtime->depth < 32) {
//add alpha to ibuf
boxsize = anim->x * anim->y * 4;
crect = (unsigned char *) rect;
for( index = 0; index < boxsize; index+=4, crect+=4 )
crect[3] = 0xFF;
}
#endif
IMB_flipy(ibuf);
return ibuf;
}
// following two functions only here to get movie pixeldepth
int GetFirstVideoMedia(struct anim *anim)
{
long numTracks;
OSType mediaType;
numTracks = GetMovieTrackCount(anim->qtime->movie);
for (anim->qtime->trackIndex=1; anim->qtime->trackIndex<=numTracks; (anim->qtime->trackIndex)++) {
anim->qtime->theTrack = GetMovieIndTrack(anim->qtime->movie, anim->qtime->trackIndex);
if (anim->qtime->theTrack)
anim->qtime->theMedia = GetTrackMedia(anim->qtime->theTrack);
if (anim->qtime->theMedia)
GetMediaHandlerDescription(anim->qtime->theMedia,&mediaType, nil, nil);
if (mediaType = VideoMediaType) return 1;
}
anim->qtime->trackIndex = 0; // trackIndex can't be 0
return 0; // went through all tracks and no video
}
short GetFirstVideoTrackPixelDepth(struct anim *anim)
{
SampleDescriptionHandle imageDescH = (SampleDescriptionHandle)NewHandle(sizeof(Handle));
long trackIndex = 0;
if(!GetFirstVideoMedia(anim))
return -1;
if (!anim->qtime->trackIndex || !anim->qtime->theMedia) return -1; // we need both
GetMediaSampleDescription(anim->qtime->theMedia, anim->qtime->trackIndex, imageDescH);
return (*(ImageDescriptionHandle)imageDescH)->depth;
}
int startquicktime (struct anim *anim)
{
FSSpec theFSSpec;
OSErr err = noErr;
Str255 dst;
char theFullPath[255];
#ifdef __APPLE__
FSRef myRef;
#endif
anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
anim->qtime->have_gw = FALSE;
if (anim->qtime == NULL) {
if(QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
return -1;
}
if(QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name);
sprintf(theFullPath, "%s", anim->name);
#ifdef __APPLE__
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
#else
CopyCStringToPascal(theFullPath, dst);
FSMakeFSSpec(0, 0L, dst, &theFSSpec);
#endif
err = OpenMovieFile(&theFSSpec, &anim->qtime->movieRefNum, fsRdPerm);
if (err == noErr) {
if(QTIME_DEBUG) printf("qt: movie opened\n");
err = NewMovieFromFile(&anim->qtime->movie,
anim->qtime->movieRefNum,
&anim->qtime->movieResId, NULL, newMovieActive, NULL);
}
if (err) {
if(QTIME_DEBUG) printf("qt: bad movie\n", anim->name);
if (anim->qtime->movie) {
DisposeMovie(anim->qtime->movie);
MEM_freeN(anim->qtime);
if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
return -1;
}
}
GetMovieBox(anim->qtime->movie, &anim->qtime->movieBounds);
anim->x = anim->qtime->movWidth = RECT_WIDTH(anim->qtime->movieBounds);
anim->y = anim->qtime->movHeight = RECT_HEIGHT(anim->qtime->movieBounds);
if(QTIME_DEBUG) printf("qt: got bounds\n", anim->name);
if(anim->x == 0 && anim->y == 0) {
if(QTIME_DEBUG) printf("qt: error, no dimensions\n");
free_anim_quicktime(anim);
return -1;
}
anim->qtime->ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect, 0);
#ifdef _WIN32
err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
k32RGBAPixelFormat,
&anim->qtime->movieBounds,
NULL, NULL, 0,
(unsigned char *)anim->qtime->ibuf->rect,
anim->x * 4);
#else
err = NewGWorldFromPtr(&anim->qtime->offscreenGWorld,
k32ARGBPixelFormat,
&anim->qtime->movieBounds,
NULL, NULL, 0,
(unsigned char *)anim->qtime->ibuf->rect,
anim->x * 4);
#endif /* _WIN32 */
if(err == noErr) {
anim->qtime->have_gw = TRUE;
SetMovieGWorld(anim->qtime->movie,
anim->qtime->offscreenGWorld,
GetGWorldDevice(anim->qtime->offscreenGWorld));
QT_get_frameIndexes(anim);
}
anim->qtime->offscreenPixMap = GetGWorldPixMap(anim->qtime->offscreenGWorld);
LockPixels(anim->qtime->offscreenPixMap);
//fill blender's anim struct
anim->qtime->depth = GetFirstVideoTrackPixelDepth(anim);
anim->duration = anim->qtime->framecount;
anim->params = 0;
anim->interlacing = 0;
anim->orientation = 0;
anim->framesize = anim->x * anim->y * 4;
anim->curposition = 0;
if(QTIME_DEBUG) printf("qt: load %s %dx%dx%d frames %d\n", anim->name, anim->qtime->movWidth,
anim->qtime->movHeight, anim->qtime->depth, anim->qtime->framecount);
return 0;
}
int imb_is_a_quicktime (char *name)
{
GraphicsImportComponent theImporter = NULL;
FSSpec theFSSpec;
Str255 dst;
char theFullPath[255];
Boolean isMovieFile = false;
AliasHandle myAlias = NULL;
Component myImporter = NULL;
#ifdef __APPLE__
FInfo myFinderInfo;
FSRef myRef;
#endif
OSErr err = noErr;
if(QTIME_DEBUG) printf("qt: checking as image %s\n", name);
// dont let quicktime image import handle these
if( BLI_testextensie(name, ".swf") ||
BLI_testextensie(name, ".txt") ||
BLI_testextensie(name, ".mpg") ||
BLI_testextensie(name, ".wav") ||
BLI_testextensie(name, ".mov") || // not as image, doesn't work
BLI_testextensie(name, ".avi") ||
BLI_testextensie(name, ".mp3")) return 0;
sprintf(theFullPath, "%s", name);
#ifdef __APPLE__
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
#else
CopyCStringToPascal(theFullPath, dst);
err = FSMakeFSSpec(0, 0L, dst, &theFSSpec);
#endif
GetGraphicsImporterForFile(&theFSSpec, &theImporter);
if (theImporter != NULL) {
if(QTIME_DEBUG) printf("qt: %s valid\n", name);
CloseComponent(theImporter);
return 1;
}
return 0;
}
ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags)
{
Rect myRect;
OSErr err = noErr;
GraphicsImportComponent gImporter = NULL;
ImageDescriptionHandle desc;
ComponentInstance dataHandler;
PointerDataRef dataref = (PointerDataRef)NewHandle(sizeof(PointerDataRefRecord));
int x, y, depth;
int have_gw = FALSE;
ImBuf *ibuf = NULL;
ImBuf *imbuf = NULL;
GWorldPtr offGWorld;
PixMapHandle myPixMap = NULL;
#ifdef __APPLE__
Ptr myPtr;
register int index;
register int boxsize;
register uint32_t *readPos;
register uint32_t *changePos;
ImBuf *wbuf = NULL;
unsigned int *rect;
#endif
if (mem == NULL)
goto bail;
if(QTIME_DEBUG) printf("qt: attempt to load mem as image\n");
(**dataref).data = mem;
(**dataref).dataLength = size;
err = OpenADataHandler(dataref,
PointerDataHandlerSubType,
nil,
(OSType)0,
nil,
kDataHCanRead,
&dataHandler);
if (err != noErr) {
if(QTIME_DEBUG) printf("no datahandler\n");
goto bail;
}
err = GetGraphicsImporterForDataRef(dataref, PointerDataHandlerSubType, &gImporter);
if (err != noErr) {
if(QTIME_DEBUG) printf("no graphimport\n");
goto bail;
}
err = GraphicsImportGetNaturalBounds(gImporter, &myRect);
if (err != noErr) {
if(QTIME_DEBUG) printf("no bounds\n");
goto bail;
}
err = GraphicsImportGetImageDescription (gImporter, &desc );
if (err != noErr) {
if(QTIME_DEBUG) printf("no imagedescription\n");
goto bail;
}
x = RECT_WIDTH(myRect);
y = RECT_HEIGHT(myRect);
depth = (**desc).depth;
if (flags & IB_test) {
ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
ibuf->ftype = QUICKTIME;
DisposeHandle((Handle)dataref);
if (gImporter != NULL) CloseComponent(gImporter);
return ibuf;
}
#ifdef __APPLE__
ibuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);
wbuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);
err = NewGWorldFromPtr(&offGWorld,
k32ARGBPixelFormat,
&myRect, NULL, NULL, 0,
(unsigned char *)wbuf->rect, x * 4);
#else
ibuf = IMB_allocImBuf (x, y, 32, IB_rect, 0);
err = NewGWorldFromPtr(&offGWorld,
k32RGBAPixelFormat,
&myRect, NULL, NULL, 0,
(unsigned char *)ibuf->rect, x * 4);
#endif
if (err != noErr) {
if(QTIME_DEBUG) printf("no newgworld\n");
goto bail;
} else {
have_gw = TRUE;
}
GraphicsImportSetGWorld(gImporter, offGWorld, NULL);
GraphicsImportDraw(gImporter);
#ifdef __APPLE__
rect = ibuf->rect;
myPixMap = GetGWorldPixMap(offGWorld);
LockPixels(myPixMap);
myPtr = GetPixBaseAddr(myPixMap);
if (myPtr == NULL) {
printf ("Error reading frame from Quicktime");
IMB_freeImBuf (ibuf);
return NULL;
}
boxsize = x * y;
readPos = (uint32_t *) myPtr;
changePos = (uint32_t *) rect;
for( index = 0; index < boxsize; index++, changePos++, readPos++ )
*( changePos ) = ( ( *readPos & 0xFFFFFF ) << 8 ) |
( ( *readPos >> 24 ) & 0xFF );
#endif
bail:
DisposeHandle((Handle)dataref);
UnlockPixels(myPixMap);
if(have_gw) DisposeGWorld(offGWorld);
#ifdef __APPLE__
if (wbuf) {
IMB_freeImBuf (wbuf);
wbuf = NULL;
}
#endif
if (gImporter != NULL) CloseComponent(gImporter);
if (err != noErr) {
if(QTIME_DEBUG) printf("quicktime import unsuccesfull\n");
if (ibuf) {
IMB_freeImBuf (ibuf);
ibuf = NULL;
}
}
if(ibuf) {
#ifdef _WIN32
// add alpha layer, might also be nescessary for OSX
int i;
int box = x * y;
unsigned char *arect = (unsigned char *) ibuf->rect;
if(depth < 32)
for(i = 0; i < box; i++, arect+=4)
arect[3] = 0xFF;
#endif
IMB_flipy(ibuf);
ibuf->ftype = QUICKTIME;
}
return ibuf;
}
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
#if 0
struct ImageDescription {
long idSize;
CodecType cType;
long resvd1;
short resvd2;
short dataRefIndex;
short version;
short revisionLevel;
long vendor;
CodecQ temporalQuality;
CodecQ spatialQuality;
short width;
short height;
Fixed hRes;
Fixed vRes;
long dataSize;
short frameCount;
Str31 name;
short depth;
short clutID;
};
#endif // 0

View File

@ -0,0 +1,54 @@
/* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef __QUICKTIME_EXPORT_H__
#define __QUICKTIME_EXPORT_H__
#if defined (_WIN32) || (__APPLE__)
// quicktime movie output functions
void start_qt(void); //for initrender.c
void append_qt(int frame);
void end_qt(void);
int get_qtcodec_settings(void); //for buttons.c
void free_qtcodecdataExt(void); //usiblender.c
void makeqtstring (char *string); //for playanim.c
int G_have_quicktime; //unused, is located in blenlib/BKE_global.h
int have_qtcodec;
#endif //(_WIN32) || (__APPLE__)
#endif // __QUICKTIME_IMP_H__

View File

@ -0,0 +1,95 @@
/**
* Quicktime_import.h
*
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2002-2003 by TNCCI Inc.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef __QUICKTIME_IMP_H__
#define __QUICKTIME_IMP_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "../imbuf/IMB_imbuf.h"
#include "../imbuf/IMB_imbuf_types.h"
#ifndef __MOVIES__
#include <Movies.h>
#endif
#ifdef _WIN32
#ifndef __FIXMATH__
#include <FixMath.h>
#endif /* __FIXMATH__ */
#endif /* _WIN32 _ */
// quicktime structure definition
// this structure is part of the anim struct
typedef struct _QuicktimeMovie {
GWorldPtr offscreenGWorld;
PixMapHandle offscreenPixMap;
Movie movie;
short movieRefNum;
short movieResId;
int movWidth, movHeight;
Rect movieBounds;
int framecount;
TimeValue *frameIndex;
ImBuf *ibuf;
Media theMedia;
Track theTrack;
long trackIndex;
short depth;
int have_gw; //ugly
} QuicktimeMovie;
// quicktime movie import functions
int anim_is_quicktime (char *name);
int startquicktime (struct anim *anim);
void free_anim_quicktime (struct anim *anim);
ImBuf *qtime_fetchibuf (struct anim *anim, int position);
// quicktime image import functions
int imb_is_a_quicktime (char *name);
ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags);
#endif // __QUICKTIME_IMP_H__

View File

@ -81,6 +81,8 @@
#include "BSE_drawview.h"
#include "BSE_sequence.h"
#include "quicktime_export.h"
/* this module */
#include "render.h"
#include "render_intern.h"
@ -1258,6 +1260,10 @@ void RE_animrender(struct View3D *ogl_render_view3d)
#ifdef _WIN32
} else if (R.r.imtype == R_AVICODEC) {
start_avi_codec();
#endif
#if WITH_QUICKTIME
} else if (R.r.imtype == R_QUICKTIME) {
start_qt();
#endif
} else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) {
@ -1284,6 +1290,10 @@ void RE_animrender(struct View3D *ogl_render_view3d)
#ifdef _WIN32
} else if (R.r.imtype == R_AVICODEC) {
append_avi_codec((G.scene->r.cfra));
#endif
#ifdef WITH_QUICKTIME
} else if (R.r.imtype == R_QUICKTIME) {
append_qt((G.scene->r.cfra));
#endif
} else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
append_avi((G.scene->r.cfra));
@ -1320,6 +1330,10 @@ void RE_animrender(struct View3D *ogl_render_view3d)
#ifdef _WIN32
} else if (R.r.imtype == R_AVICODEC) {
end_avi_codec();
#endif
#ifdef WITH_QUICKTIME
} else if (R.r.imtype == R_QUICKTIME) {
end_qt();
#endif
} else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) {
end_avi();

View File

@ -149,6 +149,9 @@
#include "BIF_previewrender.h"
#include "BIF_writeimage.h"
#include "BIF_writeavicodec.h"
#ifdef WITH_QUICKTIME
#include "quicktime_export.h"
#endif
/* 'old' stuff": defines and types ------------------------------------- */
#include "blendef.h"
@ -265,6 +268,7 @@ char texstr[15][8]= {"None" , "Clouds" , "Wood",
#define B_ENV_OB 1354
#define B_PACKIMA 1355
#define B_TEXSETFRAMES 1356
/* *********************** */
#define B_ANIMBUTS 1500
@ -3267,7 +3271,16 @@ void do_texbuts(unsigned short event)
sa= closest_bigger_area();
areawinset(sa->win);
if(tex->ima) name= tex->ima->name;
else name= U.textudir;
#ifdef _WIN32
else {
if (strcmp (U.textudir, "/") == 0)
name= G.sce;
else
name= U.textudir;
}
#else
else name = U.textudir;
#endif
if(event==B_LOADTEXIMA)
activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_tex_image);
@ -3359,6 +3372,11 @@ void do_texbuts(unsigned short event)
}
break;
case B_TEXSETFRAMES:
if(tex->ima->anim) tex->frames = IMB_anim_get_duration(tex->ima->anim);
allqueue(REDRAWBUTSTEX, 0);
break;
case B_PACKIMA:
if(tex && tex->ima) {
if (tex->ima->packedfile) {
@ -3832,6 +3850,7 @@ void texbuts(void)
/* printen aantal frames anim */
if(tex->ima && tex->ima->anim) {
uiDefBut(block, BUT, B_TEXSETFRAMES, "<", 802, 110, 20, 18, 0, 0, 0, 0, 0, "Paste number of frames in Frames: button");
sprintf(str, "%d frs ", IMB_anim_get_duration(tex->ima->anim));
uiDefBut(block, LABEL, 0, str, 834, 110, 90, 18, 0, 0, 0, 0, 0, "");
sprintf(str, "%d cur ", tex->ima->lastframe);
@ -5930,7 +5949,12 @@ void do_renderbuts(unsigned short event)
allqueue(REDRAWALL, 0);
break;
case B_PLAYANIM:
makeavistring(file);
#ifdef WITH_QUICKTIME
if(G.scene->r.imtype == R_QUICKTIME)
makeqtstring(file);
else
#endif
makeavistring(file);
if(BLI_exist(file)) {
run_playanim(file);
}
@ -5987,18 +6011,78 @@ void do_renderbuts(unsigned short event)
allqueue(REDRAWBUTSRENDER, 0);
allqueue(REDRAWVIEWCAM, 0);
break;
#ifdef _WIN32
#ifdef WITH_QUICKTIME
case B_FILETYPEMENU:
allqueue(REDRAWBUTSRENDER, 0);
#if defined (_WIN32) || defined (__APPLE__)
// fall through to codec settings if this is the first
// time R_AVICODEC is selected for this scene.
if ((G.scene->r.imtype != R_AVICODEC) || (G.scene->r.avicodecdata)) {
break;
if (((G.scene->r.imtype == R_AVICODEC)
&& (G.scene->r.avicodecdata == NULL)) ||
((G.scene->r.imtype == R_QUICKTIME)
&& (have_qtcodec == FALSE))) {
} else {
break;
}
#else /* libquicktime */
if(G.scene->r.imtype == R_QUICKTIME) {
/* i'm not sure if this should be here... */
/* set default quicktime codec */
if (!G.scene->r.qtcodecdata) {
G.scene->r.qtcodecdata = MEM_callocN(sizeof(QtCodecData),
"QtCodecData");
qtcodec_idx = 1;
}
qt_init_codecs();
if (qtcodec_idx < 1) qtcodec_idx = 1;
G.scene->r.qtcodecdata->fourcc =
qtcodecidx_to_fcc(qtcodec_idx-1);
qt_init_codecdata(G.scene->r.qtcodecdata);
/* I'm not sure if this is really needed, so don't remove it yet */
#if 0
/* get index of codec that can handle a given fourcc */
if (qtcodec_idx < 1)
qtcodec_idx = get_qtcodec_idx(G.scene->r.qtcodecdata->fourcc)+1;
/* no suitable codec found, alert user */
if (qtcodec_idx < -1) {
error("no suitable codec found!");
qtcodec_idx = 1;
}
#endif /* 0 */
}
#endif /*_WIN32 || __APPLE__ */
case B_SELECTCODEC:
get_codec_settings();
#if defined (_WIN32) || defined (__APPLE__)
if ((G.scene->r.imtype == R_QUICKTIME)) /* || (G.scene->r.qtcodecdata)) */
get_qtcodec_settings();
#ifdef _WIN32
else
get_avicodec_settings();
#endif /* _WIN32 */
#else /* libquicktime */
if (!G.scene->r.qtcodecdata) {
G.scene->r.qtcodecdata = MEM_callocN(sizeof(QtCodecData),
"QtCodecData");
qtcodec_idx = 1;
}
if (qtcodec_idx < 1) {
qtcodec_idx = 1;
qt_init_codecs();
}
G.scene->r.qtcodecdata->fourcc = qtcodecidx_to_fcc(qtcodec_idx-1);
/* if the selected codec differs from the previous one, reinit it */
qt_init_codecdata(G.scene->r.qtcodecdata);
allqueue(REDRAWBUTSRENDER, 0);
#endif /* _WIN32 || __APPLE__ */
break;
#endif
#endif /* WITH_QUICKTIME */
case B_PR_FULL:
G.scene->r.xsch= 1280;
G.scene->r.ysch= 1024;
@ -6202,7 +6286,7 @@ uiBlock *edge_render_menu(void *arg_unused)
&G.scene->r.edgeB, 0.0, 1.0, B_EDGECOLSLI, 0,
"For unified renderer: Colour for edges in toon shading mode.");
uiDefButI(block, NUM, 0,"AntiShift",
uiDefButS(block, NUM, 0,"AntiShift",
365,70,140,19,
&(G.scene->r.same_mat_redux), 0, 255.0, 0, 0,
"For unified renderer: reduce intensity on boundaries "
@ -6285,22 +6369,49 @@ static char *imagetype_pup(void)
strcat(formatstring, "|%s %%x%d"); // add space for AVI Codec
#endif
sprintf(string, formatstring,
"AVI Raw", R_AVIRAW,
"AVI Jpeg", R_AVIJPEG,
#ifdef _WIN32
"AVI Codec", R_AVICODEC,
#ifdef WITH_QUICKTIME
if(G.have_quicktime)
strcat(formatstring, "|%s %%x%d"); // add space for Quicktime
#endif
"Targa", R_TARGA,
"Targa Raw", R_RAWTGA,
"PNG", R_PNG,
"Jpeg", R_JPEG90,
"HamX", R_HAMX,
"Iris", R_IRIS,
"Iris + Zbuffer", R_IRIZ,
"Ftype", R_FTYPE,
"Movie", R_MOVIE
);
if(G.have_quicktime) {
sprintf(string, formatstring,
"AVI Raw", R_AVIRAW,
"AVI Jpeg", R_AVIJPEG,
#ifdef _WIN32
"AVI Codec", R_AVICODEC,
#endif
#ifdef WITH_QUICKTIME
"QuickTime", R_QUICKTIME,
#endif
"Targa", R_TARGA,
"Targa Raw", R_RAWTGA,
"PNG", R_PNG,
"Jpeg", R_JPEG90,
"HamX", R_HAMX,
"Iris", R_IRIS,
"Iris + Zbuffer", R_IRIZ,
"Ftype", R_FTYPE,
"Movie", R_MOVIE
);
} else {
sprintf(string, formatstring,
"AVI Raw", R_AVIRAW,
"AVI Jpeg", R_AVIJPEG,
#ifdef _WIN32
"AVI Codec", R_AVICODEC,
#endif
"Targa", R_TARGA,
"Targa Raw", R_RAWTGA,
"PNG", R_PNG,
"Jpeg", R_JPEG90,
"HamX", R_HAMX,
"Iris", R_IRIS,
"Iris + Zbuffer", R_IRIZ,
"Ftype", R_FTYPE,
"Movie", R_MOVIE
);
}
return (string);
}
@ -6452,16 +6563,38 @@ void renderbuts(void)
if(G.scene->r.quality==0) G.scene->r.quality= 90;
#ifdef _WIN32
if (G.scene->r.imtype == R_AVICODEC) {
#else
#ifdef WITH_QUICKTIME
if (G.scene->r.imtype == R_AVICODEC || G.scene->r.imtype == R_QUICKTIME) {
#else /* WITH_QUICKTIME */
if (0) {
#endif
uiDefBut(block, BUT,B_SELECTCODEC, "Select Codec", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for AVI Codec");
if(G.scene->r.imtype == R_QUICKTIME) {
#ifdef WITH_QUICKTIME
#if defined (_WIN32) || defined (__APPLE__)
uiDefBut(block, BUT,B_SELECTCODEC, "Codec settings", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for Quicktime Codec");
#else /* libquicktime */
if (!G.scene->r.qtcodecdata) G.scene->r.qtcodecdata = MEM_callocN(sizeof(QtCodecData), "QtCodecData");
uiDefButI(block, MENU, B_SELECTCODEC, qtcodecs_pup(), 892,yofs, 112, 20, &qtcodec_idx, 0, 0, 0, 0, "Codec");
/* make sure the codec stored in G.scene->r.qtcodecdata matches the selected
* one, especially if it's not set.. */
if (!G.scene->r.qtcodecdata->fourcc) {
G.scene->r.qtcodecdata->fourcc = qtcodecidx_to_fcc(qtcodec_idx-1);
qt_init_codecdata(G.scene->r.qtcodecdata);
}
yofs -= 22;
uiDefBlockBut(block, qtcodec_menu, NULL, "Codec Settings |>> ", 892,yofs, 227, 20, "Edit Codec settings for QuickTime");
yofs +=22;
#endif /* libquicktime */
#endif /* WITH_QUICKTIME */
} else {
uiDefBut(block, BUT,B_SELECTCODEC, "Codec settings", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for AVI Codec");
}
} else {
uiDefButS(block, NUM,0, "Quality:", 892,yofs,112,20, &G.scene->r.quality, 10.0, 100.0, 0, 0, "Quality setting for JPEG images, AVI Jpeg and SGI movies");
}
uiDefButS(block, NUM,REDRAWSEQ,"Frs/sec:", 1007,yofs,112,20, &G.scene->r.frs_sec, 1.0, 120.0, 0, 0, "Frames per second, for AVI and Sequence window grid");
uiDefButS(block, NUM,REDRAWSEQ,"Frs/sec:", 1006,yofs,113,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second, for AVI and Sequence window grid");
uiDefButS(block, NUM,REDRAWSEQ,"Sta:", 692,10,94,24, &G.scene->r.sfra,1.0,18000.0, 0, 0, "The start frame of the animation");
uiDefButS(block, NUM,REDRAWSEQ,"End:", 790,10,95,24, &G.scene->r.efra,1.0,18000.0, 0, 0, "The end frame of the animation");

View File

@ -418,6 +418,12 @@ static void str_image_type(int ftype, char *name)
if( ftype & PNG ) { strcat(name, "png "); }
if( ftype & BMP ) { strcat(name, "bmp "); }
if( ftype & AMI ) { strcat(name, "iff "); }
#ifdef WITH_QUICKTIME
if( ftype & QUICKTIME ) { strcat(name, "quicktime "); }
#endif
#ifdef WITH_FREEIMAGE
if( ftype & FREEIMAGE ) { strcat(name, "freeimage "); }
#endif
}
void draw_sima_area(SpaceImaSel *simasel)
@ -572,7 +578,7 @@ void draw_sima_area(SpaceImaSel *simasel)
glRecti(sx, sy, ex, ey); uiEmboss(sx,sy, ex,ey, 1);
}
if (ima->disksize/1000 > 1000){ sprintf(infostr, "%s %.2fMb x%i y%i %i bits ",ima->file_name,(ima->disksize/1024)/1024.0, ima->orgx, ima->orgy, ima->orgd);
}else{ sprintf(infostr, "%s %dKb x%i y%i %i bits ", ima->file_name,ima->disksize/1024, ima->orgx, ima->orgy, ima->orgd);
}else{ sprintf(infostr, "%s %dKb %ix%i %i bits ", ima->file_name,ima->disksize/1024, ima->orgx, ima->orgy, ima->orgd);
}
if (ima->anim == 1){ strcat (infostr, "movie"); }else{
str_image_type(ima->ibuf_type, naam);

View File

@ -513,22 +513,86 @@ void test_flags_file(SpaceFile *sfile)
file->flags |= PSXFILE;
}
} else if (sfile->type==FILE_SPECIAL){
if( BLI_testextensie(file->relname, ".jpg") ||
BLI_testextensie(file->relname, ".tga") ||
BLI_testextensie(file->relname, ".rgb") ||
BLI_testextensie(file->relname, ".png") ||
/* BLI_testextensie(file->relname, ".bmp") || */
BLI_testextensie(file->relname, ".iff") ||
BLI_testextensie(file->relname, ".lbm") ||
BLI_testextensie(file->relname, ".sgi")) {
file->flags |= IMAGEFILE;
}
else if(BLI_testextensie(file->relname, ".avi") ||
BLI_testextensie(file->relname, ".mv")) {
file->flags |= MOVIEFILE;
}
else if(BLI_testextensie(file->relname, ".py")) {
if(BLI_testextensie(file->relname, ".py")) {
file->flags |= PYSCRIPTFILE;
} else if( BLI_testextensie(file->relname, ".ttf")
|| BLI_testextensie(file->relname, ".pfb")
|| BLI_testextensie(file->relname, ".otc")) {
file->flags |= FTFONTFILE;
} else if (G.have_quicktime){
if( BLI_testextensie(file->relname, ".jpg")
|| BLI_testextensie(file->relname, ".jpeg")
|| BLI_testextensie(file->relname, ".tga")
|| BLI_testextensie(file->relname, ".rgb")
|| BLI_testextensie(file->relname, ".bmp")
|| BLI_testextensie(file->relname, ".png")
|| BLI_testextensie(file->relname, ".iff")
|| BLI_testextensie(file->relname, ".lbm")
|| BLI_testextensie(file->relname, ".gif")
|| BLI_testextensie(file->relname, ".psd")
|| BLI_testextensie(file->relname, ".tif")
|| BLI_testextensie(file->relname, ".tiff")
|| BLI_testextensie(file->relname, ".pct")
|| BLI_testextensie(file->relname, ".pict")
|| BLI_testextensie(file->relname, ".pntg") //macpaint
|| BLI_testextensie(file->relname, ".qtif")
#ifdef WITH_FREEIMAGE
|| BLI_testextensie(file->relname, ".jng")
|| BLI_testextensie(file->relname, ".mng")
|| BLI_testextensie(file->relname, ".pbm")
|| BLI_testextensie(file->relname, ".pgm")
|| BLI_testextensie(file->relname, ".ppm")
|| BLI_testextensie(file->relname, ".wbmp")
|| BLI_testextensie(file->relname, ".cut")
|| BLI_testextensie(file->relname, ".ico")
|| BLI_testextensie(file->relname, ".koala")
|| BLI_testextensie(file->relname, ".pcd")
|| BLI_testextensie(file->relname, ".pcx")
|| BLI_testextensie(file->relname, ".ras")
#endif
|| BLI_testextensie(file->relname, ".sgi")) {
file->flags |= IMAGEFILE;
}
else if(BLI_testextensie(file->relname, ".avi")
|| BLI_testextensie(file->relname, ".flc")
|| BLI_testextensie(file->relname, ".mov")
|| BLI_testextensie(file->relname, ".movie")
|| BLI_testextensie(file->relname, ".mv")) {
file->flags |= MOVIEFILE;
}
} else { // no quicktime
if(BLI_testextensie(file->relname, ".jpg")
|| BLI_testextensie(file->relname, ".tga")
|| BLI_testextensie(file->relname, ".rgb")
|| BLI_testextensie(file->relname, ".bmp")
|| BLI_testextensie(file->relname, ".png")
|| BLI_testextensie(file->relname, ".iff")
|| BLI_testextensie(file->relname, ".lbm")
#ifdef WITH_FREEIMAGE
|| BLI_testextensie(file->relname, ".jng")
|| BLI_testextensie(file->relname, ".mng")
|| BLI_testextensie(file->relname, ".pbm")
|| BLI_testextensie(file->relname, ".pgm")
|| BLI_testextensie(file->relname, ".ppm")
|| BLI_testextensie(file->relname, ".wbmp")
|| BLI_testextensie(file->relname, ".cut")
|| BLI_testextensie(file->relname, ".ico")
|| BLI_testextensie(file->relname, ".koala")
|| BLI_testextensie(file->relname, ".pcd")
|| BLI_testextensie(file->relname, ".pcx")
|| BLI_testextensie(file->relname, ".ras")
|| BLI_testextensie(file->relname, ".gif")
|| BLI_testextensie(file->relname, ".psd")
|| BLI_testextensie(file->relname, ".tif")
|| BLI_testextensie(file->relname, ".tiff")
#endif
|| BLI_testextensie(file->relname, ".sgi")) {
file->flags |= IMAGEFILE;
}
else if(BLI_testextensie(file->relname, ".avi")
|| BLI_testextensie(file->relname, ".mv")) {
file->flags |= MOVIEFILE;
}
}
}
}
@ -877,6 +941,10 @@ static void printregel(SpaceFile *sfile, struct direntry *files, int x, int y)
cpack(0x4477dd);
glRects(x-14, y, x-8, y+7);
}
else if(files->flags & FTFONTFILE) {
cpack(0xff2371);
glRects(x-14, y, x-8, y+7);
}
if(S_ISDIR(files->type)) cpack(0xFFFFFF);
else cpack(0x0);

View File

@ -48,6 +48,15 @@
#endif
#include "MEM_guardedalloc.h"
#ifdef WITH_QUICKTIME
#ifdef _WIN32
#include <QTML.h>
#endif /* _WIN32 */
#if defined (_WIN32) || defined (__APPLE__)
#include <Movies.h>
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
#include "PIL_time.h"
#include <math.h>
@ -348,6 +357,22 @@ void playanim(int argc, char **argv)
} else break;
}
#ifdef WITH_QUICKTIME
#if defined (_WIN32) || defined (__APPLE__)
/* Initialize QuickTime */
#ifdef _WIN32
if (InitializeQTML(0) != noErr)
G.have_quicktime = FALSE;
else
G.have_quicktime = TRUE;
#endif /* _WIN32 */
if (EnterMovies() != noErr)
G.have_quicktime = FALSE;
else
#endif /* _WIN32 || __APPLE__ */
G.have_quicktime = TRUE;
#endif /* WITH_QUICKTIME */
if (argc > 1) strcpy(name,argv[1]);
else {
BLI_getwdN(name);
@ -713,4 +738,14 @@ void playanim(int argc, char **argv)
}
picture = picture->next;
}
#ifdef WITH_QUICKTIME
#if defined (_WIN32) || defined (__APPLE__)
if(G.have_quicktime) {
ExitMovies();
#ifdef _WIN32
TerminateQTML();
#endif /* _WIN32 */
}
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
}

View File

@ -116,6 +116,16 @@
#include "PIL_time.h"
#ifdef WITH_QUICKTIME
#include "quicktime_export.h"
#ifdef _WIN32
#include <QTML.h>
#endif /* _WIN32 */
#if defined (_WIN32) || defined (__APPLE__)
#include <Movies.h>
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
/***/
void BIF_read_file(char *name)
@ -501,6 +511,18 @@ void exit_usiblender(void)
sound_exit_audio();
#if defined(_WIN32) || defined(__APPLE__)
#ifdef WITH_QUICKTIME
if(G.have_quicktime) {
free_qtcodecdataExt();
ExitMovies();
#ifdef _WIN32
TerminateQTML();
#endif /* _WIN32 */
}
#endif /* WITH_QUICKTIME */
#endif /* _WIN32 || __APPLE__ */
BPY_end_python();
if (!G.background) {

View File

@ -761,7 +761,7 @@ void append_avi_codec(int frame)
}
int get_codec_settings(void)
int get_avicodec_settings(void)
{
int ret_val = 0;
AVICOMPRESSOPTIONS *aopts[1] = {&opts};

View File

@ -94,6 +94,17 @@
#endif
#endif
#ifdef WITH_QUICKTIME
# ifdef _WIN32
# include <QTML.h>
# endif /* _WIN32 */
# if defined (_WIN32) || defined (__APPLE__)
# include <Movies.h>
# elif defined (__linux__)
# include <quicktime/lqt.h>
# endif /* __linux__ */
#endif /* WITH_QUICKTIME */
// from buildinfo.c
extern char * build_date;
extern char * build_time;
@ -161,6 +172,8 @@ static void print_help(void)
printf (" -R\t\tRegister .blend extension\n");
#endif
}
double PIL_check_seconds_timer(void);
extern void winlay_get_screensize(int *width_r, int *height_r);
int main(int argc, char **argv)
@ -375,7 +388,28 @@ int main(int argc, char **argv)
RE_init_filt_mask();
/* OK we zijn er klaar voor */
#ifdef WITH_QUICKTIME
#ifdef _WIN32
if (InitializeQTML(0) != noErr)
G.have_quicktime = FALSE;
else
G.have_quicktime = TRUE;
#endif /* _WIN32 */
/* Initialize QuickTime */
#if defined(_WIN32) || defined (__APPLE__)
if (EnterMovies() != noErr)
G.have_quicktime = FALSE;
else
#endif /* _WIN32 || __APPLE__ */
#ifdef __linux__
/* inititalize quicktime codec registry */
lqt_registry_init();
#endif
G.have_quicktime = TRUE;
#endif /* WITH_QUICKTIME */
/* OK we zijn er klaar voor */
for(a=1; a<argc; a++) {
if (G.afbreek==1) break;