Quicktime for Cocoa : import part
authorDamien Plisson <damien.plisson@yahoo.fr>
Wed, 18 Nov 2009 09:49:42 +0000 (09:49 +0000)
committerDamien Plisson <damien.plisson@yahoo.fr>
Wed, 18 Nov 2009 09:49:42 +0000 (09:49 +0000)
This makes quicktime import (.mov & quicktime handled image files such as .gif) available also for 64bit OSX

Unfortunately, Apple currently incomplete implementation of QTKit has much lower performance than old Carbon Quicktime.
FYI, it spawns a 32bit process "QTKitserver" to place calls to Quicktime 7.

So this is mostly meant as a "backup" for 64bit OSX builds, until Apple releases full Quicktime X.

Export part will come just after.

CMake scripts updated: set WITH_QUICKTIME and USE_QTKIT to ON

CMakeLists.txt
source/blender/imbuf/intern/util.c
source/blender/quicktime/CMakeLists.txt
source/blender/quicktime/apple/qtkit_export.m [new file with mode: 0644]
source/blender/quicktime/apple/qtkit_import.m [new file with mode: 0644]
source/blender/quicktime/apple/quicktime_import.c
source/blender/quicktime/quicktime_import.h

index 0706d3a9b52f2a5790b7827be59e983ceb27fd9d..0dd331469a08880d22549d7d2a23875641776a7b 100644 (file)
@@ -84,6 +84,7 @@ OPTION(WITH_OPENCOLLADA               "Enable OpenCollada Support (http://www.opencollada.org
 
 IF (APPLE)
 OPTION(WITH_COCOA        "Use Cocoa framework instead of deprecated Carbon" ON)
+OPTION(USE_QTKIT         "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF)
 OPTION(WITH_LIBS10.5     "Use 10.5 libs (needed for 64bit builds)" OFF)
 ENDIF (APPLE)
 
@@ -525,7 +526,15 @@ IF(APPLE)
 
        IF (WITH_COCOA)
        SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DGHOST_COCOA")
-       SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
+       SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio")
+       IF(USE_QTKIT)
+       SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DUSE_QTKIT")
+       SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QTKit")
+       ELSE(USE_QTKIT)
+       IF(WITH_QUICKTIME)
+       SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
+       ENDIF(WITH_QUICKTIME)
+       ENDIF(USE_QTKIT)
        ELSE (WITH_COCOA)
        SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
        SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
index 26434583118c991f310bfc141d3b4299b67b9da8..5bcdd6c96706b9cd0351f76b8b636412ce8f6d3f 100644 (file)
@@ -384,6 +384,9 @@ int imb_get_anim_type(char * name) {
        if(UTIL_DEBUG) printf("in getanimtype: %s\n", name);
 
 #ifndef _WIN32
+#      ifdef WITH_QUICKTIME
+       if (isqtime(name)) return (ANIM_QTIME);
+#      endif
 #      ifdef WITH_FFMPEG
        /* stat test below fails on large files > 4GB */
        if (isffmpeg(name)) return (ANIM_FFMPEG);
@@ -394,9 +397,6 @@ int imb_get_anim_type(char * name) {
        if (isavi(name)) return (ANIM_AVI);
 
        if (ismovie(name)) return (ANIM_MOVIE);
-#      ifdef WITH_QUICKTIME
-       if (isqtime(name)) return (ANIM_QTIME);
-#      endif
 #else
        if (ib_stat(name,&st) == -1) return(0);
        if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
index ac503bb62cbe8cfa270221efa767ec511599392f..14589ca4c5b5effc5a77f3a5025262fb1704e055 100644 (file)
 #
 # ***** END GPL LICENSE BLOCK *****
 
-SET(SRC apple/quicktime_import.c apple/quicktime_export.c)
+IF(USE_QTKIT)
+       SET(SRC apple/qtkit_import.m apple/qtkit_export.m)
+ELSE(USE_QTKIT)
+       SET(SRC apple/quicktime_import.c apple/quicktime_export.c)
+ENDIF(USE_QTKIT)
 
 SET(INC 
        .
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
new file mode 100644 (file)
index 0000000..c5e878c
--- /dev/null
@@ -0,0 +1,665 @@
+/**
+ * $Id: qtkit_export.m 24424 2009-11-09 17:06:48Z damien78 $
+ *
+ * qtkit_export.m
+ *
+ * Code to create QuickTime Movies with Blender
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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)
+ *                                Damien Plisson 11/2009
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifdef WITH_QUICKTIME
+#if defined(_WIN32) || defined(__APPLE__)
+
+#include "DNA_scene_types.h"
+
+#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 "quicktime_import.h"
+#include "quicktime_export.h"
+
+
+#ifdef __APPLE__
+/* evil */
+#ifndef __AIFF__
+#define __AIFF__
+#endif
+#endif /* __APPLE__ */
+
+#define        kMyCreatorType  FOUR_CHAR_CODE('TVOD')
+#define        kTrackStart             0
+#define        kMediaStart             0
+
+//static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame, int rectx, int recty);
+static void QT_DoAddVideoSamplesToMedia (int frame, int *pixels, int rectx, int recty);
+static void QT_EndAddVideoSamplesToMedia (void);
+static void QT_CreateMyVideoTrack (int rectx, int recty);
+static void QT_EndCreateMyVideoTrack (void);
+static void check_renderbutton_framerate(struct RenderData *rd);
+
+typedef struct QuicktimeExport {
+
+       /*FSSpec                theSpec;
+       short           resRefNum;
+       Str255          qtfilename;
+
+       Media           theMedia;
+       Movie           theMovie;
+       Track           theTrack;
+
+       GWorldPtr                       theGWorld;
+       PixMapHandle            thePixMap;
+       ImageDescription        **anImageDescription;*/
+
+       ImBuf           *ibuf;  //imagedata for Quicktime's Gworld
+       ImBuf           *ibuf2; //copy of renderdata, to be Y-flipped
+
+} QuicktimeExport;
+
+typedef struct QuicktimeComponentData {
+
+       /*ComponentInstance     theComponent;
+       SCTemporalSettings  gTemporalSettings;
+       SCSpatialSettings   gSpatialSettings;
+       SCDataRateSettings  aDataRateSetting;
+       TimeValue                       duration;
+       long                            kVideoTimeScale;*/
+
+} QuicktimeComponentData;
+
+static struct QuicktimeExport *qtexport;
+static struct QuicktimeComponentData *qtdata;
+
+static int     sframe;
+
+#if 0
+
+static OSErr QT_SaveCodecSettingsToScene(RenderData *rd)
+{      
+       QTAtomContainer         myContainer = NULL;
+       ComponentResult         myErr = noErr;
+       Ptr                                     myPtr;
+       long                            mySize = 0;
+
+       CodecInfo                       ci;
+       char str[255];
+
+       QuicktimeCodecData *qcd = rd->qtcodecdata;
+
+       // check if current scene already has qtcodec settings, and clear them
+       if (qcd) {
+               free_qtcodecdata(qcd);
+       } else {
+               qcd = rd->qtcodecdata = MEM_callocN(sizeof(QuicktimeCodecData), "QuicktimeCodecData");
+       }
+
+       // obtain all current codec settings
+       SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
+       SCSetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
+       SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
+
+       // retreive codecdata from quicktime in a atomcontainer
+       myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent,  &myContainer);
+       if (myErr != noErr) {
+               printf("Quicktime: SCGetSettingsAsAtomContainer failed\n"); 
+               goto bail;
+       }
+
+       // get the size of the atomcontainer
+       mySize = GetHandleSize((Handle)myContainer);
+
+       // lock and convert the atomcontainer to a *valid* pointer
+       QTLockContainer(myContainer);
+       myPtr = *(Handle)myContainer;
+
+       // copy the Quicktime data into the blender qtcodecdata struct
+       if (myPtr) {
+               qcd->cdParms = MEM_mallocN(mySize, "qt.cdParms");
+               memcpy(qcd->cdParms, myPtr, mySize);
+               qcd->cdSize = mySize;
+
+               GetCodecInfo (&ci, qtdata->gSpatialSettings.codecType, 0);
+               CopyPascalStringToC(ci.typeName, str);
+               sprintf(qcd->qtcodecname, "Codec: %s", str);
+       } else {
+               printf("Quicktime: QT_SaveCodecSettingsToScene failed\n"); 
+       }
+
+       QTUnlockContainer(myContainer);
+
+bail:
+       if (myContainer != NULL)
+               QTDisposeAtomContainer(myContainer);
+               
+       return((OSErr)myErr);
+}
+
+
+static OSErr QT_GetCodecSettingsFromScene(RenderData *rd)
+{      
+       Handle                          myHandle = NULL;
+       ComponentResult         myErr = noErr;
+//     CodecInfo ci;
+//     char str[255];
+
+       QuicktimeCodecData *qcd = rd->qtcodecdata;
+
+       // if there is codecdata in the blendfile, convert it to a Quicktime handle 
+       if (qcd) {
+               myHandle = NewHandle(qcd->cdSize);
+               PtrToHand( qcd->cdParms, &myHandle, qcd->cdSize);
+       }
+               
+       // restore codecsettings to the quicktime component
+       if(qcd->cdParms && qcd->cdSize) {
+               myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qtdata->theComponent, (QTAtomContainer)myHandle);
+               if (myErr != noErr) {
+                       printf("Quicktime: SCSetSettingsFromAtomContainer failed\n"); 
+                       goto bail;
+               }
+
+               // update runtime codecsettings for use with the codec dialog
+               SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
+               SCGetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
+               SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
+
+//             GetCodecInfo (&ci, qtdata->gSpatialSettings.codecType, 0);
+//             CopyPascalStringToC(ci.typeName, str);
+//             printf("restored Codec: %s\n", str);
+       } else {
+               printf("Quicktime: QT_GetCodecSettingsFromScene failed\n"); 
+       }
+bail:
+       if (myHandle != NULL)
+               DisposeHandle(myHandle);
+               
+       return((OSErr)myErr);
+}
+
+
+static OSErr QT_AddUserDataTextToMovie (Movie theMovie, char *theText, OSType theType)
+{
+       UserData                                        myUserData = NULL;
+       Handle                                          myHandle = NULL;
+       long                                            myLength = strlen(theText);
+       OSErr                                           myErr = noErr;
+
+       // get the movie's user data list
+       myUserData = GetMovieUserData(theMovie);
+       if (myUserData == NULL)
+               return(paramErr);
+       
+       // copy the specified text into a new handle
+       myHandle = NewHandleClear(myLength);
+       if (myHandle == NULL)
+               return(MemError());
+
+       BlockMoveData(theText, *myHandle, myLength);
+
+       // add the data to the movie's user data
+       myErr = AddUserDataText(myUserData, myHandle, theType, 1, (short)GetScriptManagerVariable(smRegionCode));
+
+       // clean up
+       DisposeHandle(myHandle);
+       return(myErr);
+}
+
+
+static void QT_CreateMyVideoTrack(int rectx, int recty)
+{
+       OSErr err = noErr;
+       Rect trackFrame;
+//     MatrixRecord myMatrix;
+
+       trackFrame.top = 0;
+       trackFrame.left = 0;
+       trackFrame.bottom = recty;
+       trackFrame.right = rectx;
+       
+       qtexport->theTrack = NewMovieTrack (qtexport->theMovie, 
+                                                       FixRatio(trackFrame.right,1),
+                                                       FixRatio(trackFrame.bottom,1), 
+                                                       0);
+       CheckError( GetMoviesError(), "NewMovieTrack error" );
+
+//     SetIdentityMatrix(&myMatrix);
+//     ScaleMatrix(&myMatrix, fixed1, Long2Fix(-1), 0, 0);
+//     TranslateMatrix(&myMatrix, 0, Long2Fix(trackFrame.bottom));
+//     SetMovieMatrix(qtexport->theMovie, &myMatrix);
+
+       qtexport->theMedia = NewTrackMedia (qtexport->theTrack,
+                                                       VideoMediaType,
+                                                       qtdata->kVideoTimeScale,
+                                                       nil,
+                                                       0);
+       CheckError( GetMoviesError(), "NewTrackMedia error" );
+
+       err = BeginMediaEdits (qtexport->theMedia);
+       CheckError( err, "BeginMediaEdits error" );
+
+       QT_StartAddVideoSamplesToMedia (&trackFrame, rectx, recty);
+} 
+
+
+static void QT_EndCreateMyVideoTrack(void)
+{
+       OSErr err = noErr;
+
+       QT_EndAddVideoSamplesToMedia ();
+
+       err = EndMediaEdits (qtexport->theMedia);
+       CheckError( err, "EndMediaEdits error" );
+
+       err = InsertMediaIntoTrack (qtexport->theTrack,
+                                                               kTrackStart,/* track start time */
+                                                               kMediaStart,/* media start time */
+                                                               GetMediaDuration (qtexport->theMedia),
+                                                               fixed1);
+       CheckError( err, "InsertMediaIntoTrack error" );
+} 
+
+
+static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame, int rectx, int recty)
+{
+       SCTemporalSettings gTemporalSettings;
+       OSErr err = noErr;
+
+       qtexport->ibuf = IMB_allocImBuf (rectx, recty, 32, IB_rect, 0);
+       qtexport->ibuf2 = IMB_allocImBuf (rectx, recty, 32, IB_rect, 0);
+
+       err = NewGWorldFromPtr( &qtexport->theGWorld,
+                                                       k32ARGBPixelFormat,
+                                                       trackFrame,
+                                                       NULL, NULL, 0,
+                                                       (Ptr)qtexport->ibuf->rect,
+                                                       rectx * 4 );
+       CheckError (err, "NewGWorldFromPtr error");
+
+       qtexport->thePixMap = GetGWorldPixMap(qtexport->theGWorld);
+       LockPixels(qtexport->thePixMap);
+
+       SCDefaultPixMapSettings (qtdata->theComponent, qtexport->thePixMap, true);
+
+       // workaround for crash with H.264, which requires an upgrade to
+       // the new callback based api for proper encoding, but that's not
+       // really compatible with rendering out frames sequentially
+       gTemporalSettings = qtdata->gTemporalSettings;
+       if(qtdata->gSpatialSettings.codecType == kH264CodecType) {
+               if(gTemporalSettings.temporalQuality != codecMinQuality) {
+                       fprintf(stderr, "Only minimum quality compression supported for QuickTime H.264.\n");
+                       gTemporalSettings.temporalQuality = codecMinQuality;
+               }
+       }
+
+       SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &gTemporalSettings);
+       SCSetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
+       SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
+
+       err = SCCompressSequenceBegin(qtdata->theComponent, qtexport->thePixMap, NULL, &qtexport->anImageDescription); 
+       CheckError (err, "SCCompressSequenceBegin error" );
+}
+
+
+static void QT_DoAddVideoSamplesToMedia (int frame, int *pixels, int rectx, int recty)
+{
+       OSErr   err = noErr;
+       Rect    imageRect;
+
+       int             index;
+       int             boxsize;
+       unsigned char *from, *to;
+
+       short   syncFlag;
+       long    dataSize;
+       Handle  compressedData;
+       Ptr             myPtr;
+
+
+       //copy and flip renderdata
+       memcpy(qtexport->ibuf2->rect, pixels, 4*rectx*recty);
+       IMB_flipy(qtexport->ibuf2);
+
+       //get pointers to parse bitmapdata
+       myPtr = GetPixBaseAddr(qtexport->thePixMap);
+       imageRect = (**qtexport->thePixMap).bounds;
+
+       from = (unsigned char *) qtexport->ibuf2->rect;
+       to = (unsigned char *) myPtr;
+
+       //parse RGBA bitmap into Quicktime's ARGB GWorld
+       boxsize = rectx * recty;
+       for( index = 0; index < boxsize; index++) {
+               to[0] = from[3];
+               to[1] = from[0];
+               to[2] = from[1];
+               to[3] = from[2];
+               to +=4, from += 4;
+       }
+
+       err = SCCompressSequenceFrame(qtdata->theComponent,
+               qtexport->thePixMap,
+               &imageRect,
+               &compressedData,
+               &dataSize,
+               &syncFlag);
+       CheckError(err, "SCCompressSequenceFrame error");
+
+       err = AddMediaSample(qtexport->theMedia,
+               compressedData,
+               0,
+               dataSize,
+               qtdata->duration,
+               (SampleDescriptionHandle)qtexport->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(qtdata->theComponent);
+
+       UnlockPixels(qtexport->thePixMap);
+       if (qtexport->theGWorld)
+               DisposeGWorld (qtexport->theGWorld);
+
+       if (qtexport->ibuf)
+               IMB_freeImBuf(qtexport->ibuf);
+
+       if (qtexport->ibuf2)
+               IMB_freeImBuf(qtexport->ibuf2);
+} 
+#endif //0
+
+void makeqtstring (RenderData *rd, char *string) {
+       char txt[64];
+
+       if (string==0) return;
+
+       strcpy(string, rd->pic);
+       BLI_convertstringcode(string, G.sce);
+
+       BLI_make_existing_file(string);
+
+       if (BLI_strcasecmp(string + strlen(string) - 4, ".mov")) {
+               sprintf(txt, "%04d_%04d.mov", (rd->sfra) , (rd->efra) );
+               strcat(string, txt);
+       }
+}
+
+
+void start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty) {
+#if 0
+       OSErr err = noErr;
+
+       char name[2048];
+       char theFullPath[255];
+
+
+       if(qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
+
+       if(qtdata) {
+               if(qtdata->theComponent) CloseComponent(qtdata->theComponent);
+               free_qtcomponentdata();
+       }
+
+       qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeCodecDataExt");
+
+       if(rd->qtcodecdata == NULL || rd->qtcodecdata->cdParms == NULL) {
+               get_qtcodec_settings(rd);
+       } else {
+               qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
+
+               QT_GetCodecSettingsFromScene(rd);
+               check_renderbutton_framerate(rd);
+       }
+       
+       if (G.afbreek != 1) {
+               sframe = (rd->sfra);
+
+               makeqtstring(rd, name);
+
+               sprintf(theFullPath, "%s", name);
+
+               /* 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((const UInt8 *)theFullPath, &myRef, 0);
+               CheckError(err, "FsPathMakeRef error");
+               err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qtexport->theSpec, NULL);
+               CheckError(err, "FsGetCatalogInfoRef error");
+
+               err = CreateMovieFile (&qtexport->theSpec, 
+                                                       kMyCreatorType,
+                                                       smCurrentScript, 
+                                                       createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
+                                                       &qtexport->resRefNum, 
+                                                       &qtexport->theMovie );
+               CheckError(err, "CreateMovieFile error");
+
+               if(err != noErr) {
+                       G.afbreek = 1;
+// XXX                 error("Unable to create Quicktime movie: %s", name);
+               } else {
+                       printf("Created QuickTime movie: %s\n", name);
+
+                       QT_CreateMyVideoTrack(rectx, recty);
+               }
+       }
+#endif
+}
+
+
+void append_qt(struct RenderData *rd, int frame, int *pixels, int rectx, int recty) {
+       //QT_DoAddVideoSamplesToMedia(frame, pixels, rectx, recty);
+}
+
+
+void end_qt(void) {
+/*     OSErr err = noErr;
+       short resId = movieInDataForkResID;
+
+       if(qtexport->theMovie) {
+               QT_EndCreateMyVideoTrack();
+
+               err = AddMovieResource (qtexport->theMovie, qtexport->resRefNum, &resId, qtexport->qtfilename);
+               CheckError(err, "AddMovieResource error");
+
+               err = QT_AddUserDataTextToMovie(qtexport->theMovie, "Made with Blender", kUserDataTextInformation);
+               CheckError(err, "AddUserDataTextToMovie error");
+
+               err = UpdateMovieResource(qtexport->theMovie, qtexport->resRefNum, resId, qtexport->qtfilename);
+               CheckError(err, "UpdateMovieResource error");
+
+               if(qtexport->resRefNum) CloseMovieFile(qtexport->resRefNum);
+
+               DisposeMovie(qtexport->theMovie);
+
+               printf("Finished QuickTime movie.\n");
+       }
+
+       if(qtexport) {
+               MEM_freeN(qtexport);
+               qtexport = NULL;
+       }*/
+}
+
+
+void free_qtcomponentdata(void) {
+       /*if(qtdata) {
+               if(qtdata->theComponent) CloseComponent(qtdata->theComponent);
+               MEM_freeN(qtdata);
+               qtdata = NULL;
+       }*/
+}
+
+
+static void check_renderbutton_framerate(RenderData *rd) 
+{
+       // to keep float framerates consistent between the codec dialog and frs/sec button.
+/*     OSErr   err;    
+
+       //err = SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
+       CheckError(err, "SCGetInfo fr error");
+
+       if( (rd->frs_sec == 24 || rd->frs_sec == 30 || rd->frs_sec == 60) &&
+               (qtdata->gTemporalSettings.frameRate == 1571553 ||
+                qtdata->gTemporalSettings.frameRate == 1964113 ||
+                qtdata->gTemporalSettings.frameRate == 3928227)) {;} 
+       else {
+               if (rd->frs_sec_base > 0)
+                       qtdata->gTemporalSettings.frameRate = 
+                       (rd->frs_sec << 16) / rd->frs_sec_base ;
+       }
+       
+       //err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
+       CheckError( err, "SCSetInfo error" );
+
+       if(qtdata->gTemporalSettings.frameRate == 1571553) {                    // 23.98 fps
+               qtdata->kVideoTimeScale = 24000;
+               qtdata->duration = 1001;
+       } else if (qtdata->gTemporalSettings.frameRate == 1964113) {    // 29.97 fps
+               qtdata->kVideoTimeScale = 30000;
+               qtdata->duration = 1001;
+       } else if (qtdata->gTemporalSettings.frameRate == 3928227) {    // 59.94 fps
+               qtdata->kVideoTimeScale = 60000;
+               qtdata->duration = 1001;
+       } else {
+               qtdata->kVideoTimeScale = (qtdata->gTemporalSettings.frameRate >> 16) * 100;
+               qtdata->duration = 100;
+       }*/
+}
+
+
+int get_qtcodec_settings(RenderData *rd) 
+{
+/*     OSErr   err = noErr;
+
+       // erase any existing codecsetting
+       if(qtdata) {
+               if(qtdata->theComponent) CloseComponent(qtdata->theComponent);
+               free_qtcomponentdata();
+       }
+
+       // allocate new
+       qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData");
+       qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
+
+       // get previous selected codecsetting, if any 
+       if(rd->qtcodecdata && rd->qtcodecdata->cdParms) {
+               QT_GetCodecSettingsFromScene(rd);
+               check_renderbutton_framerate(rd);
+       } else {
+               // configure the standard image compression dialog box
+               // set some default settings
+               qtdata->gSpatialSettings.codec = anyCodec;         
+               qtdata->gSpatialSettings.spatialQuality = codecMaxQuality;
+               qtdata->gTemporalSettings.temporalQuality = codecMaxQuality;
+               qtdata->gTemporalSettings.keyFrameRate = 25;   
+               qtdata->aDataRateSetting.dataRate = 90 * 1024;          
+
+               err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType,   &qtdata->gTemporalSettings);
+               CheckError(err, "SCSetInfo1 error");
+               err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType,    &qtdata->gSpatialSettings);
+               CheckError(err, "SCSetInfo2 error");
+               err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType,   &qtdata->aDataRateSetting);
+               CheckError(err, "SCSetInfo3 error");
+       }
+
+       check_renderbutton_framerate(rd);
+
+       // put up the dialog box - it needs to be called from the main thread
+       err = SCRequestSequenceSettings(qtdata->theComponent);
+       if (err == scUserCancelled) {
+               G.afbreek = 1;
+               return 0;
+       }
+
+       // get user selected data
+       SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
+       SCGetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
+       SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
+
+       QT_SaveCodecSettingsToScene(rd);
+
+       // framerate jugglin'
+       if(qtdata->gTemporalSettings.frameRate == 1571553) {                    // 23.98 fps
+               qtdata->kVideoTimeScale = 24000;
+               qtdata->duration = 1001;
+
+               rd->frs_sec = 24;
+               rd->frs_sec_base = 1.001;
+       } else if (qtdata->gTemporalSettings.frameRate == 1964113) {    // 29.97 fps
+               qtdata->kVideoTimeScale = 30000;
+               qtdata->duration = 1001;
+
+               rd->frs_sec = 30;
+               rd->frs_sec_base = 1.001;
+       } else if (qtdata->gTemporalSettings.frameRate == 3928227) {    // 59.94 fps
+               qtdata->kVideoTimeScale = 60000;
+               qtdata->duration = 1001;
+
+               rd->frs_sec = 60;
+               rd->frs_sec_base = 1.001;
+       } else {
+               double fps = qtdata->gTemporalSettings.frameRate;
+
+               qtdata->kVideoTimeScale = 60000;
+               qtdata->duration = qtdata->kVideoTimeScale / (qtdata->gTemporalSettings.frameRate / 65536);
+
+               if ((qtdata->gTemporalSettings.frameRate & 0xffff) == 0) {
+                       rd->frs_sec = fps / 65536;
+                       rd->frs_sec_base = 1;
+               } else {
+                       // we do our very best... 
+                       rd->frs_sec = (fps * 10000 / 65536);
+                       rd->frs_sec_base = 10000;
+               }
+       }
+*/
+       return 0;
+}
+
+#endif /* _WIN32 || __APPLE__ */
+#endif /* WITH_QUICKTIME */
+
diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m
new file mode 100644 (file)
index 0000000..2da66e6
--- /dev/null
@@ -0,0 +1,526 @@
+/**
+ * $Id: qtkit_import.m 19323 2009-03-17 21:44:58Z blendix $
+ *
+ * qtkit_import.m
+ *
+ * Code to use Quicktime to load images/movies as texture.
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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)
+ *                                Damien Plisson 11/2009
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifdef WITH_QUICKTIME
+
+#include "IMB_anim.h"
+#include "BLO_sys_types.h"
+#include "BKE_global.h"
+#include "BLI_dynstr.h"
+
+#import <Cocoa/Cocoa.h>
+#import <QTKit/QTKit.h>
+
+#include "quicktime_import.h"
+#include "quicktime_export.h"
+
+// quicktime structure definition
+// this structure is part of the anim struct
+
+typedef struct _QuicktimeMovie {
+       QTMovie *movie;
+       QTMedia *media;
+       
+       long durationTime;
+       long durationScale;
+       long framecount;
+       
+
+       ImBuf *ibuf;
+       
+       long previousPosition;
+       
+} QuicktimeMovie;
+
+
+#define QTIME_DEBUG 0
+
+
+void quicktime_init(void)
+{
+               G.have_quicktime = TRUE;
+}
+
+
+void quicktime_exit(void)
+{
+       if(G.have_quicktime) {
+               free_qtcomponentdata();
+       }
+}
+
+
+int anim_is_quicktime (char *name)
+{
+       NSAutoreleasePool *pool;
+       
+       // 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, ".tga") ||
+               BLI_testextensie(name, ".png") ||
+               BLI_testextensie(name, ".bmp") ||
+               BLI_testextensie(name, ".jpg") ||
+               BLI_testextensie(name, ".wav") ||
+               BLI_testextensie(name, ".zip") ||
+               BLI_testextensie(name, ".mp3")) return 0;
+
+       if(QTIME_DEBUG) printf("qt: checking as movie: %s\n", name);
+
+       pool = [[NSAutoreleasePool alloc] init];
+       
+       if([QTMovie canInitWithFile:[NSString stringWithUTF8String:name]])
+       {
+               [pool drain];
+               return true;
+       }
+       else
+       {
+               [pool drain];
+               return false;
+       }
+}
+
+
+void free_anim_quicktime (struct anim *anim) {
+       if (anim == NULL) return;
+       if (anim->qtime == NULL) return;
+
+       if(anim->qtime->ibuf)
+               IMB_freeImBuf(anim->qtime->ibuf);
+
+       [anim->qtime->media release];
+       [anim->qtime->movie release];
+
+       if(anim->qtime) MEM_freeN (anim->qtime);
+
+       anim->qtime = NULL;
+
+       anim->duration = 0;
+}
+
+static ImBuf * nsImageToiBuf(NSImage *sourceImage, int width, int height)
+{
+       ImBuf *ibuf = NULL;
+       uchar *rasterRGB = NULL;
+       uchar *rasterRGBA = NULL;
+       uchar *toIBuf = NULL;
+       int x, y, to_i, from_i;
+       NSSize bitmapSize;
+       NSBitmapImageRep *blBitmapFormatImageRGB,*blBitmapFormatImageRGBA,*bitmapImage;
+       NSEnumerator *enumerator;
+       NSImageRep *representation;
+       
+       ibuf = IMB_allocImBuf (width, height, 32, IB_rect, 0);
+       if (!ibuf) {
+               if(QTIME_DEBUG) printf("quicktime_import: could not allocate memory for the " \
+                               "image.\n");
+               return NULL;
+       }
+       
+       /*Get the bitmap of the image*/
+       enumerator = [[sourceImage representations] objectEnumerator];
+       while (representation = [enumerator nextObject]) {
+        if ([representation isKindOfClass:[NSBitmapImageRep class]]) {
+            bitmapImage = (NSBitmapImageRep *)representation;
+                       break;
+        }
+    }
+
+       if (([bitmapImage bitmapFormat] & 0x5) == 0) {
+               /* Try a fast copy if the image is a planar RGBA 32bit bitmap*/
+               toIBuf = (uchar*)ibuf->rect;
+               rasterRGB = (uchar*)[bitmapImage bitmapData];
+               for (y = 0; y < height; y++) {
+                       to_i = (height-y-1)*width;
+                       from_i = y*width;
+                               memcpy(toIBuf+4*to_i, rasterRGB+4*from_i, 4*width);
+               }
+       }
+       else {
+
+               bitmapSize.width = width;
+               bitmapSize.height = height;
+               
+               /* Tell cocoa image resolution is same as current system one */
+               [bitmapImage setSize:bitmapSize];
+               
+               /* Convert the image in a RGBA 32bit format */
+               /* As Core Graphics does not support contextes with non premutliplied alpha,
+                we need to get alpha key values in a separate batch */
+               
+               /* First get RGB values w/o Alpha to avoid pre-multiplication, 32bit but last byte is unused */
+               blBitmapFormatImageRGB = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+                                                                                                                                                pixelsWide:width 
+                                                                                                                                                pixelsHigh:height
+                                                                                                                                         bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO
+                                                                                                                                        colorSpaceName:NSCalibratedRGBColorSpace 
+                                                                                                                                          bitmapFormat:0
+                                                                                                                                               bytesPerRow:4*width
+                                                                                                                                          bitsPerPixel:32/*RGB format padded to 32bits*/];
+               
+               [NSGraphicsContext saveGraphicsState];
+               [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGB]];
+               [bitmapImage draw];
+               [NSGraphicsContext restoreGraphicsState];
+               
+               rasterRGB = (uchar*)[blBitmapFormatImageRGB bitmapData];
+               if (rasterRGB == NULL) {
+                       [bitmapImage release];
+                       [blBitmapFormatImageRGB release];
+                       return NULL;
+               }
+               
+               /* Then get Alpha values by getting the RGBA image (that is premultiplied btw) */
+               blBitmapFormatImageRGBA = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+                                                                                                                                                 pixelsWide:width
+                                                                                                                                                 pixelsHigh:height
+                                                                                                                                          bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO
+                                                                                                                                         colorSpaceName:NSCalibratedRGBColorSpace
+                                                                                                                                               bitmapFormat:0
+                                                                                                                                                bytesPerRow:4*width
+                                                                                                                                               bitsPerPixel:32/* RGBA */];
+               
+               [NSGraphicsContext saveGraphicsState];
+               [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGBA]];
+               [bitmapImage draw];
+               [NSGraphicsContext restoreGraphicsState];
+               
+               rasterRGBA = (uchar*)[blBitmapFormatImageRGBA bitmapData];
+               if (rasterRGBA == NULL) {
+                       [bitmapImage release];
+                       [blBitmapFormatImageRGB release];
+                       [blBitmapFormatImageRGBA release];
+                       return NULL;
+               }
+
+               /*Copy the image to ibuf, flipping it vertically*/
+               toIBuf = (uchar*)ibuf->rect;
+               for (x = 0; x < width; x++) {
+                       for (y = 0; y < height; y++) {
+                               to_i = (height-y-1)*width + x;
+                               from_i = y*width + x;
+                               
+                               toIBuf[4*to_i] = rasterRGB[4*from_i]; /* R */
+                               toIBuf[4*to_i+1] = rasterRGB[4*from_i+1]; /* G */
+                               toIBuf[4*to_i+2] = rasterRGB[4*from_i+2]; /* B */
+                               toIBuf[4*to_i+3] = rasterRGBA[4*from_i+3]; /* A */
+                       }
+               }
+
+               [blBitmapFormatImageRGB release];
+               [blBitmapFormatImageRGBA release];
+       }
+       
+       return ibuf;
+}
+
+ImBuf * qtime_fetchibuf (struct anim *anim, int position)
+{
+       NSImage *frameImage;
+       QTTime time;
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       ImBuf *ibuf;
+       
+       if (anim == NULL) {
+               return (NULL);
+       }
+
+       if (position == anim->qtime->previousPosition+1) { //Optimize sequential read
+               [anim->qtime->movie stepForward];
+               frameImage = [anim->qtime->movie currentFrameImage];
+               anim->qtime->previousPosition++;
+       }
+       else {
+               time.timeScale = anim->qtime->durationScale;
+               time.timeValue = (anim->qtime->durationTime * position) / anim->qtime->framecount;
+       
+               [anim->qtime->movie setCurrentTime:time];
+               frameImage = [anim->qtime->movie currentFrameImage]; 
+               
+               anim->qtime->previousPosition = position;
+       }
+               
+       if (frameImage == nil) {
+               if(QTIME_DEBUG) printf ("Error reading frame from Quicktime");
+               [pool drain];
+               return NULL;
+       }
+
+       ibuf = nsImageToiBuf(frameImage,anim->x, anim->y);
+       [pool drain];
+       return ibuf;
+}
+
+
+int startquicktime (struct anim *anim)
+{
+       NSAutoreleasePool *pool;
+       NSArray* videoTracks;
+       NSSize frameSize;
+       QTTime qtTimeDuration;
+       NSDictionary *attributes;
+       
+       anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
+
+       if (anim->qtime == NULL) {
+               if(QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
+               return -1;
+       }
+
+       pool = [[NSAutoreleasePool alloc] init];
+       
+       attributes = [NSDictionary dictionaryWithObjectsAndKeys:
+                                [NSString stringWithUTF8String:anim->name], QTMovieFileNameAttribute,
+                                [NSNumber numberWithBool:NO], QTMovieEditableAttribute,
+                                nil];
+       
+       anim->qtime->movie = [QTMovie movieWithAttributes:attributes error:NULL];
+       
+       if (!anim->qtime->movie) {
+               if(QTIME_DEBUG) printf("qt: bad movie %s\n", anim->name);
+               MEM_freeN(anim->qtime);
+               if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
+               [pool drain];
+               return -1;
+       }
+       [anim->qtime->movie retain];
+
+       // sets Media and Track!
+       
+       videoTracks = [anim->qtime->movie tracksOfMediaType:QTMediaTypeVideo];
+       
+       if([videoTracks count] == 0) {
+               if(QTIME_DEBUG) printf("qt: no video tracks for movie %s\n", anim->name);
+               [anim->qtime->movie release];
+               MEM_freeN(anim->qtime);
+               if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
+               [pool drain];
+               return -1;
+       }
+       
+       anim->qtime->media = [[videoTracks objectAtIndex:0] media];
+       [anim->qtime->media retain];
+       
+       
+       frameSize = [[anim->qtime->movie attributeForKey:QTMovieCurrentSizeAttribute] sizeValue];
+       anim->x = frameSize.width;
+       anim->y = frameSize.height;
+
+       if(anim->x == 0 && anim->y == 0) {
+               if(QTIME_DEBUG) printf("qt: error, no dimensions\n");
+               free_anim_quicktime(anim);
+               [pool drain];
+               return -1;
+       }
+
+       anim->qtime->ibuf = IMB_allocImBuf (anim->x, anim->y, 32, IB_rect, 0);
+       
+       qtTimeDuration = [[anim->qtime->media attributeForKey:QTMediaDurationAttribute] QTTimeValue];
+       anim->qtime->durationTime = qtTimeDuration.timeValue;
+       anim->qtime->durationScale = qtTimeDuration.timeScale;
+       
+       anim->qtime->framecount = [[anim->qtime->media attributeForKey:QTMediaSampleCountAttribute] longValue];
+       anim->qtime->previousPosition = -2; //Force seeking for first read
+       
+       //fill blender's anim struct
+
+       anim->duration = anim->qtime->framecount;
+       anim->params = 0;
+
+       anim->interlacing = 0;
+       anim->orientation = 0;
+       anim->framesize = anim->x * anim->y * 4;
+
+       anim->curposition = 0;
+
+       [pool drain];
+                                                                                                
+       return 0;
+}
+
+int imb_is_a_quicktime (char *name)
+{
+       NSImage *image;
+       int result;
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       
+       // 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;
+
+       
+       image = [NSImage alloc];
+       if ([image initWithContentsOfFile:[NSString stringWithUTF8String:name]]) 
+               result = true;
+       else 
+               result = false;
+
+       [image release];
+       [pool drain];
+       return result;
+}
+
+ImBuf  *imb_quicktime_decode(unsigned char *mem, int size, int flags)
+{
+       struct ImBuf *ibuf = NULL;
+       NSSize bitmapSize;
+       uchar *rasterRGB = NULL;
+       uchar *rasterRGBA = NULL;
+       uchar *toIBuf = NULL;
+       int x, y, to_i, from_i;
+       NSData *data;
+       NSBitmapImageRep *bitmapImage;
+       NSBitmapImageRep *blBitmapFormatImageRGB,*blBitmapFormatImageRGBA;
+       NSAutoreleasePool *pool;
+       
+       pool = [[NSAutoreleasePool alloc] init];
+       
+       data = [NSData dataWithBytes:mem length:size];
+       bitmapImage = [[NSBitmapImageRep alloc] initWithData:data];
+       
+       if (!bitmapImage) {
+               fprintf(stderr, "imb_cocoaLoadImage: error loading image\n");
+               [pool drain];
+               return NULL;
+       }
+       
+       bitmapSize.width = [bitmapImage pixelsWide];
+       bitmapSize.height = [bitmapImage pixelsHigh];
+       
+       /* Tell cocoa image resolution is same as current system one */
+       [bitmapImage setSize:bitmapSize];
+       
+       /* allocate the image buffer */
+       ibuf = IMB_allocImBuf(bitmapSize.width, bitmapSize.height, 32/*RGBA*/, 0, 0);
+       if (!ibuf) {
+               fprintf(stderr, 
+                               "imb_cocoaLoadImage: could not allocate memory for the " \
+                               "image.\n");
+               [bitmapImage release];
+               [pool drain];
+               return NULL;
+       }
+       
+       /* read in the image data */
+       if (!(flags & IB_test)) {
+               
+               /* allocate memory for the ibuf->rect */
+               imb_addrectImBuf(ibuf);
+               
+               /* Convert the image in a RGBA 32bit format */
+               /* As Core Graphics does not support contextes with non premutliplied alpha,
+                we need to get alpha key values in a separate batch */
+               
+               /* First get RGB values w/o Alpha to avoid pre-multiplication, 32bit but last byte is unused */
+               blBitmapFormatImageRGB = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+                                                                                                                                                pixelsWide:bitmapSize.width 
+                                                                                                                                                pixelsHigh:bitmapSize.height
+                                                                                                                                         bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO
+                                                                                                                                        colorSpaceName:NSCalibratedRGBColorSpace 
+                                                                                                                                          bitmapFormat:0
+                                                                                                                                               bytesPerRow:4*bitmapSize.width
+                                                                                                                                          bitsPerPixel:32/*RGB format padded to 32bits*/];
+               
+               [NSGraphicsContext saveGraphicsState];
+               [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGB]];
+               [bitmapImage draw];
+               [NSGraphicsContext restoreGraphicsState];
+               
+               rasterRGB = (uchar*)[blBitmapFormatImageRGB bitmapData];
+               if (rasterRGB == NULL) {
+                       [bitmapImage release];
+                       [blBitmapFormatImageRGB release];
+                       [pool drain];
+                       return NULL;
+               }
+               
+               /* Then get Alpha values by getting the RGBA image (that is premultiplied btw) */
+               blBitmapFormatImageRGBA = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+                                                                                                                                                 pixelsWide:bitmapSize.width
+                                                                                                                                                 pixelsHigh:bitmapSize.height
+                                                                                                                                          bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO
+                                                                                                                                         colorSpaceName:NSCalibratedRGBColorSpace
+                                                                                                                                               bitmapFormat:0
+                                                                                                                                                bytesPerRow:4*bitmapSize.width
+                                                                                                                                               bitsPerPixel:32/* RGBA */];
+               
+               [NSGraphicsContext saveGraphicsState];
+               [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGBA]];
+               [bitmapImage draw];
+               [NSGraphicsContext restoreGraphicsState];
+               
+               rasterRGBA = (uchar*)[blBitmapFormatImageRGBA bitmapData];
+               if (rasterRGBA == NULL) {
+                       [bitmapImage release];
+                       [blBitmapFormatImageRGB release];
+                       [blBitmapFormatImageRGBA release];
+                       [pool drain];
+                       return NULL;
+               }
+               
+               /*Copy the image to ibuf, flipping it vertically*/
+               toIBuf = (uchar*)ibuf->rect;
+               for (x = 0; x < bitmapSize.width; x++) {
+                       for (y = 0; y < bitmapSize.height; y++) {
+                               to_i = (bitmapSize.height-y-1)*bitmapSize.width + x;
+                               from_i = y*bitmapSize.width + x;
+                               
+                               toIBuf[4*to_i] = rasterRGB[4*from_i]; /* R */
+                               toIBuf[4*to_i+1] = rasterRGB[4*from_i+1]; /* G */
+                               toIBuf[4*to_i+2] = rasterRGB[4*from_i+2]; /* B */
+                               toIBuf[4*to_i+3] = rasterRGBA[4*from_i+3]; /* A */
+                       }
+               }
+               
+               [blBitmapFormatImageRGB release];
+               [blBitmapFormatImageRGBA release];
+       }
+       
+       /* release the cocoa objects */
+       [bitmapImage release];
+       [pool drain];
+       
+       if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+       
+       /* return successfully */
+       return (ibuf);  
+}
+
+
+#endif /* WITH_QUICKTIME */
+
index 1f3071f114c0077c39808f3cacfd6a0f440e98bb..571da92a29257b3ba97c155282d48aeb49a9d899 100644 (file)
 #include "quicktime_import.h"
 #include "quicktime_export.h"
 
-
 #define        RECT_WIDTH(r)   (r.right-r.left)
 #define        RECT_HEIGHT(r)  (r.bottom-r.top)
 
 #define QTIME_DEBUG 0
 
+typedef struct _QuicktimeMovie {
+
+       GWorldPtr       offscreenGWorld;
+       PixMapHandle    offscreenPixMap;
+       Movie           movie;
+       Rect            movieBounds;
+       short           movieRefNum;
+       short           movieResId;
+       int                     movWidth, movHeight;
+
+       
+       int                     framecount;
+       
+       
+       ImBuf           *ibuf;
+       
+
+       TimeValue       *frameIndex;
+       Media           theMedia;
+       Track           theTrack;
+       long            trackIndex;
+       short           depth;
+       
+       int                     have_gw;        //ugly
+} QuicktimeMovie;
+
+
 
 void quicktime_init(void)
 {
index 1444827e12e679140a124c6372c7b8a2c0ee1475..6dea59561953b7caebba913765d126cbb482147b 100644 (file)
@@ -42,6 +42,7 @@
 #include "../imbuf/IMB_imbuf.h"
 #include "../imbuf/IMB_imbuf_types.h"
 
+#ifndef USE_QTKIT
 #ifndef __MOVIES__
 #ifdef _WIN32
 #include <Movies.h>
@@ -50,7 +51,8 @@
 #import <Carbon/Carbon.h>
 #include <QuickTime/Movies.h>
 #endif
-#endif
+#endif //__MOVIES__
+#endif //USE_QTKIT
 
 #ifdef _WIN32
 #ifndef __FIXMATH__
 #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;
 
 char *get_valid_qtname(char *name);