diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 27546a7b9a2..43db9f08914 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -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; diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 100da22019f..8c97e9b2120 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -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 - diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 80da8ed8258..a8a509f92b3 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -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) diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h new file mode 100644 index 00000000000..6156026b313 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -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 +#include +#include +#include +#include + +#ifndef FREE_WINDOWS +#include +#endif + +#ifdef HAVE_CONFIG_H +#include +#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 +#include +#include +#include +#ifndef _WIN32 +#include +#else +#include +#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 + diff --git a/source/blender/imbuf/intern/IMB_anim5.h b/source/blender/imbuf/intern/IMB_anim5.h new file mode 100644 index 00000000000..245b3b9a9be --- /dev/null +++ b/source/blender/imbuf/intern/IMB_anim5.h @@ -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 + + diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 7fcf094e5e7..190267b2d41 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -39,10 +39,9 @@ #include #include #include -#include -#ifdef HAVE_CONFIG_H -#include +#ifndef FREE_WINDOWS +#include #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); diff --git a/source/blender/imbuf/intern/anim5.c b/source/blender/imbuf/intern/anim5.c new file mode 100644 index 00000000000..39d0cdd7f6f --- /dev/null +++ b/source/blender/imbuf/intern/anim5.c @@ -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); +} \ No newline at end of file diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 3b56aa0b295..fb574bf7da8 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -46,9 +46,16 @@ #include "IMB_hamx.h" #include "IMB_jpeg.h" #include "IMB_bmp.h" - -#ifdef HAVE_CONFIG_H -#include +#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)); diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 8f9c35532f8..4fda7882dcd 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -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 +#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); +} diff --git a/source/blender/include/BIF_writeavicodec.h b/source/blender/include/BIF_writeavicodec.h index e096cbd27f3..ff347fe494c 100644 --- a/source/blender/include/BIF_writeavicodec.h +++ b/source/blender/include/BIF_writeavicodec.h @@ -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 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index bd5f1d80f4c..c0e4c06295c 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -290,6 +290,7 @@ typedef struct Scene { #define R_AVIJPEG 16 #define R_PNG 17 #define R_AVICODEC 18 +#define R_QUICKTIME 19 /* **************** RENDER ********************* */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index f34979486b2..65a1de9198e 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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 */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 6f087f0f330..04d65d2b39b 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -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 diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c new file mode 100644 index 00000000000..e7b58e8021f --- /dev/null +++ b/source/blender/quicktime/apple/quicktime_export.c @@ -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 +#include + +#ifdef _WIN32 +#include +#include +#include +#endif /* _WIN32 */ + +#ifdef __APPLE__ +#include /* open() */ +#include /* close() */ +#include /* 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 */ diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c new file mode 100644 index 00000000000..61c4fcec215 --- /dev/null +++ b/source/blender/quicktime/apple/quicktime_import.c @@ -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 + +#ifdef _WIN32 +#include +#include +#endif /* _WIN32 */ + +//#ifdef __APPLE__ +#include +//#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 diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h new file mode 100644 index 00000000000..0ef3a2341a6 --- /dev/null +++ b/source/blender/quicktime/quicktime_export.h @@ -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__ diff --git a/source/blender/quicktime/quicktime_import.h b/source/blender/quicktime/quicktime_import.h new file mode 100644 index 00000000000..2a2e35fd671 --- /dev/null +++ b/source/blender/quicktime/quicktime_import.h @@ -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 +#endif + +#include "../imbuf/IMB_imbuf.h" +#include "../imbuf/IMB_imbuf_types.h" + +#ifndef __MOVIES__ +#include +#endif + +#ifdef _WIN32 +#ifndef __FIXMATH__ +#include +#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__ diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 8cef9bf1744..1d7d7e89d60 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -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(); diff --git a/source/blender/src/buttons.c b/source/blender/src/buttons.c index 5d782eb4c59..e1c235d1898 100644 --- a/source/blender/src/buttons.c +++ b/source/blender/src/buttons.c @@ -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"); diff --git a/source/blender/src/drawimasel.c b/source/blender/src/drawimasel.c index a4e439fc246..5db5bc6d51b 100644 --- a/source/blender/src/drawimasel.c +++ b/source/blender/src/drawimasel.c @@ -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); diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 73b58046883..3c3b3c5d468 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -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); diff --git a/source/blender/src/playanim.c b/source/blender/src/playanim.c index ca3cef32eb1..d42cca55e90 100644 --- a/source/blender/src/playanim.c +++ b/source/blender/src/playanim.c @@ -48,6 +48,15 @@ #endif #include "MEM_guardedalloc.h" +#ifdef WITH_QUICKTIME +#ifdef _WIN32 +#include +#endif /* _WIN32 */ +#if defined (_WIN32) || defined (__APPLE__) +#include +#endif /* _WIN32 || __APPLE__ */ +#endif /* WITH_QUICKTIME */ + #include "PIL_time.h" #include @@ -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 */ } diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 4d8dfc46b61..c892628e9c1 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -116,6 +116,16 @@ #include "PIL_time.h" +#ifdef WITH_QUICKTIME +#include "quicktime_export.h" +#ifdef _WIN32 +#include +#endif /* _WIN32 */ +#if defined (_WIN32) || defined (__APPLE__) +#include +#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) { diff --git a/source/blender/src/writeavicodec.c b/source/blender/src/writeavicodec.c index 0cca17ac676..cb3e98746be 100644 --- a/source/blender/src/writeavicodec.c +++ b/source/blender/src/writeavicodec.c @@ -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}; diff --git a/source/creator/creator.c b/source/creator/creator.c index c59b37f33b4..839a9d9d89a 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -94,6 +94,17 @@ #endif #endif +#ifdef WITH_QUICKTIME +# ifdef _WIN32 +# include +# endif /* _WIN32 */ +# if defined (_WIN32) || defined (__APPLE__) +# include +# elif defined (__linux__) +# include +# 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