[Pythonmac-SIG] Building Mac extensions for Apple Python

Bob Ippolito bob@redivi.com
Mon, 10 Feb 2003 03:33:19 -0500


--Apple-Mail-10--13193347
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed


On Sunday, Feb 9, 2003, at 19:42 America/New_York, Bob Ippolito wrote:

>
> On Sunday, Feb 9, 2003, at 18:09 America/New_York, Bob Ippolito wrote:
>
>> On Friday, Jan 3, 2003, at 16:52 America/New_York, Kevin Ollivier 
>> wrote:
>>
>>> Hi Jack,
>>>
>>> Thanks for your help! I am also clueless as to why PyObject_Del 
>>> would be causing that error message. Do those extensions get built 
>>> with a framework build as well? I did some playing around (removing 
>>> the extensions that were not building and changing 
>>> $(scripts)/Lib/Mac to its new home), but I'm getting import errors 
>>> for the mac modules during the import_BuildApplet phase. It cannot 
>>> find import macfsn and EasyDialogs, which are of course in the CVS 
>>> but the path is probably not set properly. Are these supposed to be 
>>> copied over to /Applications/MacPython-OSX-2.3 before this portion 
>>> of setup is run?
>>
>> I took a look at this yesterday, as I was trying to do some stuff 
>> with quicktime and I thought it'd be nice to be able to backport it 
>> to jaguar python.  I had some problems with this, because 
>> Makefile.jaguar is broken, so I tried doing what I wanted in ctypes, 
>> but that gave me bus errors left and right just defining Structures 
>> and whatnot, so I had to stop there.. and then I started writing my 
>> own python extension, but that started taking too long.. so I think 
>> I'm going to try and fix Makefile.jaguar again.
>>
>> Anyways, here's the definition of PyObject_Del:
>> #define PyObject_Del(op) _PyObject_Del((PyObject *)(op))
>>
>> See the problem is that in the implementation of _AE, and the other 
>> modules that cause problems, we're attempting to put this macro 
>> inside of a type definition.  You can't get a pointer to PyObject_Del 
>> because it's not an actual function, it's a macro function.  My lazy 
>> fix was just to load each file that had this issue and do this (in 
>> vim)  :%s/(#define.*)\<PyObject_Del/\1_PyObject_Del -- which solved 
>> it.  Right now, the problem seems to be that a large number of the 
>> Mac modules are not built at all by Makefile.jaguar, so I'm going to 
>> have to start getting into setup.jaguar.py.
>>
>
> This is my preliminary fix, please be sure to read the updated 
> README.JAGUAR, as two additional steps are necessary (modification to 
> Python.h to get around the lack of bool and add some missing macros, 
> and the and modification to site.py to get around the lack of bool).
>
> I don't know how to use any of these modules yet, so I haven't done 
> testing.. but they all compile except Nav, which I had to comment out. 
>  It's got some reference to AEDesc_NewBorrowed or something of the 
> like, which is defined as a C function in the module _AE -- but is 
> used as a python function argument in Nav.. so something seems fishy 
> there.  Again, I don't know enough about Carbon / Toolbox to figure 
> out what it's trying to do and how to fix it.
>
> -bob
>
> this is the output of: cvs diff dist/src/Mac > jagfixes.diff

I've made more changes, it's now possible to create quicktime movies 
with jaguar Python 2.2 with these fixes (same command line).  I 
basically changed a little bit of the argument parsing, and added a 
Qt.CompressImage function.  Note that it's probably bad form that I'm 
not doing this in the templates that these files get autogenerated 
from, but I don't understand that module yet so I went ahead and hacked 
at the output files by hand.

Also attached is a sample python program using Numeric and PIL to 
create a quicktime (just a video track) from a list of image files 
(must be same dimensions, and PIL must spit out RGB or RGBA strings 
from them).  I'm a little bit late on the solution, since the question 
was asked in 2001 ( 
http://mail.python.org/pipermail/pythonmac-sig/2001-October/004246.html 
), but better late than never :)

Since it's mostly Python, and it copies a lot of memory around, it's 
not fast.  If we start using this tool regularly in the office I'll 
probably have to write some Numeric + PIL hacks to swizzle the bits and 
junk them into the GWorld pixMap with Altivec.

-bob


--Apple-Mail-10--13193347
Content-Disposition: attachment;
	filename=jagfixes.diff
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="jagfixes.diff"

? dist/src/Mac/Demo/PICTbrowse/PICTbrowse.rsrc.df.rsrc
? dist/src/Mac/Tools/IDE/PythonIDE.rsrc.df.rsrc
? dist/src/Mac/scripts/BuildApplet.rsrc.df.rsrc
Index: dist/src/Mac/Modules/ae/_AEmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/_AEmodule.c,v
retrieving revision 1.19
diff -r1.19 _AEmodule.c
7d6
< 
897c896
< #define AEDesc_tp_free PyObject_Del
---
> #define AEDesc_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/app/_Appmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/app/_Appmodule.c,v
retrieving revision 1.17
diff -r1.17 _Appmodule.c
140c140
< #define ThemeDrawingStateObj_tp_free PyObject_Del
---
> #define ThemeDrawingStateObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/carbonevt/_CarbonEvtmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/carbonevt/_CarbonEvtmodule.c,v
retrieving revision 1.14
diff -r1.14 _CarbonEvtmodule.c
435c435
< #define EventRef_tp_free PyObject_Del
---
> #define EventRef_tp_free _PyObject_Del
655c655
< #define EventQueueRef_tp_free PyObject_Del
---
> #define EventQueueRef_tp_free _PyObject_Del
784c784
< #define EventLoopRef_tp_free PyObject_Del
---
> #define EventLoopRef_tp_free _PyObject_Del
931c931
< #define EventLoopTimerRef_tp_free PyObject_Del
---
> #define EventLoopTimerRef_tp_free _PyObject_Del
1123c1123
< #define EventHandlerRef_tp_free PyObject_Del
---
> #define EventHandlerRef_tp_free _PyObject_Del
1255c1255
< #define EventHandlerCallRef_tp_free PyObject_Del
---
> #define EventHandlerCallRef_tp_free _PyObject_Del
1409c1409
< #define EventTargetRef_tp_free PyObject_Del
---
> #define EventTargetRef_tp_free _PyObject_Del
1538c1538
< #define EventHotKeyRef_tp_free PyObject_Del
---
> #define EventHotKeyRef_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/cg/_CGmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cg/_CGmodule.c,v
retrieving revision 1.11
diff -r1.11 _CGmodule.c
1293c1293
< #define CGContextRefObj_tp_free PyObject_Del
---
> #define CGContextRefObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/cm/_Cmmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cm/_Cmmodule.c,v
retrieving revision 1.15
diff -r1.15 _Cmmodule.c
284c284
< #define CmpInstObj_tp_free PyObject_Del
---
> #define CmpInstObj_tp_free _PyObject_Del
717c717
< #define CmpObj_tp_free PyObject_Del
---
> #define CmpObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/ctl/_Ctlmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ctl/_Ctlmodule.c,v
retrieving revision 1.24
diff -r1.24 _Ctlmodule.c
3897c3897
< #define CtlObj_tp_free PyObject_Del
---
> #define CtlObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/dlg/_Dlgmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/dlg/_Dlgmodule.c,v
retrieving revision 1.17
diff -r1.17 _Dlgmodule.c
980c980
< #define DlgObj_tp_free PyObject_Del
---
> #define DlgObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/drag/_Dragmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/drag/_Dragmodule.c,v
retrieving revision 1.14
diff -r1.14 _Dragmodule.c
767c767
< #define DragObj_tp_free PyObject_Del
---
> #define DragObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/file/_Filemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v
retrieving revision 1.17
diff -r1.17 _Filemodule.c
415c415
< #define FSCatalogInfo_tp_free PyObject_Del
---
> #define FSCatalogInfo_tp_free _PyObject_Del
600c600
< #define FInfo_tp_free PyObject_Del
---
> #define FInfo_tp_free _PyObject_Del
946c946
< #define Alias_tp_free PyObject_Del
---
> #define Alias_tp_free _PyObject_Del
1405c1405
< #define FSSpec_tp_free PyObject_Del
---
> #define FSSpec_tp_free _PyObject_Del
1972c1972
< #define FSRef_tp_free PyObject_Del
---
> #define FSRef_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/ibcarbon/_IBCarbon.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ibcarbon/_IBCarbon.c,v
retrieving revision 1.7
diff -r1.7 _IBCarbon.c
167c167
< #define IBNibRefObj_tp_free PyObject_Del
---
> #define IBNibRefObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/list/_Listmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/list/_Listmodule.c,v
retrieving revision 1.16
diff -r1.16 _Listmodule.c
787c787
< #define ListObj_tp_free PyObject_Del
---
> #define ListObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/menu/_Menumodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/menu/_Menumodule.c,v
retrieving revision 1.17
diff -r1.17 _Menumodule.c
2571c2571
< #define MenuObj_tp_free PyObject_Del
---
> #define MenuObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/mlte/_Mltemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/_Mltemodule.c,v
retrieving revision 1.17
diff -r1.17 _Mltemodule.c
1296c1296
< #define TXNObj_tp_free PyObject_Del
---
> #define TXNObj_tp_free _PyObject_Del
1449c1449
< #define TXNFontMenuObj_tp_free PyObject_Del
---
> #define TXNFontMenuObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/qd/_Qdmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/_Qdmodule.c,v
retrieving revision 1.16
diff -r1.16 _Qdmodule.c
1086c1086
< #define GrafObj_tp_free PyObject_Del
---
> #define GrafObj_tp_free _PyObject_Del
1284c1284
< #define BMObj_tp_free PyObject_Del
---
> #define BMObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/qdoffs/_Qdoffsmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qdoffs/_Qdoffsmodule.c,v
retrieving revision 1.13
diff -r1.13 _Qdoffsmodule.c
158c158
< #define GWorldObj_tp_free PyObject_Del
---
> #define GWorldObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/qt/_Qtmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qt/_Qtmodule.c,v
retrieving revision 1.15
diff -r1.15 _Qtmodule.c
1117c1117
< #define MovieCtlObj_tp_free PyObject_Del
---
> #define MovieCtlObj_tp_free _PyObject_Del
1605c1605
< #define TimeBaseObj_tp_free PyObject_Del
---
> #define TimeBaseObj_tp_free _PyObject_Del
1946c1946
< #define UserDataObj_tp_free PyObject_Del
---
> #define UserDataObj_tp_free _PyObject_Del
3158c3158
< #define MediaObj_tp_free PyObject_Del
---
> #define MediaObj_tp_free _PyObject_Del
3764,3765c3764,3765
< 	Handle dataRef;
< 	OSType dataRefType;
---
> 	Handle dataRef = NULL;
> 	OSType dataRefType = 0;
3769c3769
< 	if (!PyArg_ParseTuple(_args, "O&lO&O&",
---
> 	if (!PyArg_ParseTuple(_args, "O&l|O&O&",
4476c4476
< #define TrackObj_tp_free PyObject_Del
---
> #define TrackObj_tp_free _PyObject_Del
6163c6163
< 	short resId;
---
> 	short resId = nil;
6168c6168
< 	if (!PyArg_ParseTuple(_args, "hO&",
---
> 	if (!PyArg_ParseTuple(_args, "hO&|h",
6170c6170,6171
< 	                      PyMac_GetStr255, resName))
---
> 	                      PyMac_GetStr255, resName,
>                           &resId))
6781c6782
< 	 PyDoc_STR("(short resRefNum, Str255 resName) -> (short resId)")},
---
> 	 PyDoc_STR("(short resRefNum, Str255 resName, [short resId]) -> (short resId)")},
6849c6850
< #define MovieObj_tp_free PyObject_Del
---
> #define MovieObj_tp_free _PyObject_Del
9495a9497,9585
> /* !!! MODIFIED !!! */
> static PyObject *Qt_GetMaxCompressionSize(PyObject *_self, PyObject *_args)
> {
>     Rect trackFrame;
>     GWorldPtr gw;
>     OSErr _err = noErr;
>     CodecQ codecQuality = codecNormalQuality;
>     CodecType codecType = kRawCodecType;
>     CompressorComponent codec = anyCodec;
>     long size;
> #ifndef GetMaxCompressionSize
>     PyMac_PRECHECK(GetMaxCompressionSize);
> #endif
>     if (!PyArg_ParseTuple(_args, "O&O&|lO&l",
>                           GWorldObj_Convert, &gw,
>                           PyMac_GetRect, &trackFrame,
>                           (long*)&codecQuality,
>                           PyMac_GetOSType, (OSType*)&codecType,
>                           (long*)&codec))
>         return NULL;
>     _err = GetMaxCompressionSize(GetGWorldPixMap(gw),   /* Handle to the source image */
>                         &trackFrame,                    /* bounds */
>                         32,                             /* let ICM choose depth */
>                         codecQuality,                   /* desired image quality */ 
>                         codecType,                      /* compressor type */ 
>                         codec,                          /* compressor identifier */
>                         &size);                         /* returned size */
>     if (_err != noErr) return PyMac_Error(_err);
>     return PyInt_FromLong(size);
> }        
> 
> /* !!! MODIFIED !!! */
> static PyObject *Qt_CompressImage(PyObject *_self, PyObject *_args)
> {
>     GWorldPtr gw;
>     OSErr _err = noErr;
>     Rect trackFrame;
>     CodecQ codecQuality = codecNormalQuality;
>     CodecType codecType = kRawCodecType;
>     CompressorComponent codec = anyCodec;
>     long size;
>     Handle compressedData = nil;
>     Ptr compressedDataPtr;
>     ImageDescriptionHandle imageDesc = nil;
>     PyObject *_res;
> #ifndef CompressImage
>     PyMac_PRECHECK(CompressImage);
> #endif
>     if (!PyArg_ParseTuple(_args, "O&O&|lO&l",
>                           GWorldObj_Convert, &gw,
>                           PyMac_GetRect, &trackFrame,
>                           (long*)&codecQuality,
>                           PyMac_GetOSType, (OSType*)&codecType,
>                           (long*)&codec))
>         return NULL;
>     _err = GetMaxCompressionSize(GetGWorldPixMap(gw),   /* Handle to the source image */
>                         &trackFrame,                    /* bounds */
>                         32,                             /* let ICM choose depth */
>                         codecQuality,                   /* desired image quality */ 
>                         codecType,                      /* compressor type */ 
>                         codec,                          /* compressor identifier */
>                         &size);                         /* returned size */
>     if (_err != noErr) return PyMac_Error(_err);
> 
>     compressedData = NewHandle(size);
>     _err = MemError();
>     if (_err != noErr) return PyMac_Error(_err);
>     MoveHHi( compressedData );
>     HLock( compressedData );
>     compressedDataPtr = *compressedData;
> 
>     imageDesc = (ImageDescriptionHandle)NewHandle(4);
>     _err = MemError();
>     if (_err != noErr) return PyMac_Error(_err);
> 
>     _err = CompressImage(GetGWorldPixMap(gw),           /* source image to compress */
>                         &trackFrame,                    /* bounds */
>                         codecQuality,                   /* desired image quality */
>                         codecType,                      /* compressor identifier */
>                         imageDesc,                      /* handle to Image Description Structure; will be resized by call */
>                         compressedDataPtr);             /* pointer to a location to recieve the compressed image data */
>     if (_err != noErr) return PyMac_Error(_err);
>     _res = Py_BuildValue("O&O&l",
>                              ResObj_New, (Handle)imageDesc,
>                              ResObj_New, (Handle)compressedData,
>                              (**imageDesc).dataSize);
>     return _res;
> }
> 
9710a9801,9805
>     /* !!! MODIFIED !!! */
>     {"GetMaxCompressionSize", (PyCFunction)Qt_GetMaxCompressionSize, 1,
>      PyDoc_STR("(GWorldPtr gw, Rect trackFrame, CodecQ codecQuality, OSType codecType, CodecFlags codecFlags) -> int")},
>     {"CompressImage", (PyCFunction)Qt_CompressImage, 1,
>      PyDoc_STR("(GWorldPtr gw, Rect trackFrame, CodecQ codecQuality, OSType codecType, CodecFlags codecFlags) -> (Handle imgDesc, Handle compressedData, int dataSize)")},
9713,9714d9807
< 
< 
Index: dist/src/Mac/Modules/res/_Resmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/res/_Resmodule.c,v
retrieving revision 1.19
diff -r1.19 _Resmodule.c
628c628
< #define ResObj_tp_free PyObject_Del
---
> #define ResObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/te/_TEmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/te/_TEmodule.c,v
retrieving revision 1.15
diff -r1.15 _TEmodule.c
1007c1007
< #define TEObj_tp_free PyObject_Del
---
> #define TEObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/waste/wastemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/waste/wastemodule.c,v
retrieving revision 1.31
diff -r1.31 wastemodule.c
423c423
< #define WEOObj_tp_free PyObject_Del
---
> #define WEOObj_tp_free _PyObject_Del
2172c2172
< #define wasteObj_tp_free PyObject_Del
---
> #define wasteObj_tp_free _PyObject_Del
Index: dist/src/Mac/Modules/win/_Winmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/win/_Winmodule.c,v
retrieving revision 1.17
diff -r1.17 _Winmodule.c
2583c2583
< #define WinObj_tp_free PyObject_Del
---
> #define WinObj_tp_free _PyObject_Del
Index: dist/src/Mac/OSX/Makefile.jaguar
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/OSX/Makefile.jaguar,v
retrieving revision 1.4
diff -r1.4 Makefile.jaguar
70c70
< 	$(PYTHON) $(srcdir)/Mac/Lib/bundlebuilder.py -q --link-exec \
---
> 	$(PYTHON) $(srcdir)/Lib/plat-mac/bundlebuilder.py -q --link-exec \
Index: dist/src/Mac/OSX/README.JAGUAR
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/OSX/README.JAGUAR,v
retrieving revision 1.1
diff -r1.1 README.JAGUAR
28a29,41
> 3. Add the following to /usr/include/python2.2/Python.h
> #define PyDoc_VAR(name) static char name[]
> #define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
> #ifdef WITH_DOC_STRINGS
> #define PyDoc_STR(str) str
> #else
> #define PyDoc_STR(str) ""
> #endif
> #define PyBool_Check PyObject_IsTrue
> #define PyBool_FromLong PyInt_FromLong
> 4. Add the following to /usr/lib/python2.2/site.py
> __builtin__.True = not 0
> __builtin__.False = not not 0
Index: dist/src/Mac/OSX/setup.jaguar.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/OSX/setup.jaguar.py,v
retrieving revision 1.3
diff -r1.3 setup.jaguar.py
41c41,92
<     
---
> 
> def detect_tkinter_darwin():
>     # The _tkinter module, using frameworks. Since frameworks are quite
>     # different the UNIX search logic is not sharable.
>     from os.path import join, exists
>     framework_dirs = [
>         '/System/Library/Frameworks/',
>         '/Library/Frameworks',
>         join(os.getenv('HOME'), '/Library/Frameworks')
>     ]
> 
>     # Find the directory that contains the Tcl.framwork and Tk.framework
>     # bundles.
>     # XXX distutils should support -F!
>     for F in framework_dirs:
>         # both Tcl.framework and Tk.framework should be present
>         for fw in 'Tcl', 'Tk':
>             if not exists(join(F, fw + '.framework')):
>                 break
>         else:
>             # ok, F is now directory with both frameworks. Continure
>             # building
>             break
>     else:
>         # Tk and Tcl frameworks not found. Normal "unix" tkinter search
>         # will now resume.
>         return []
> 
>     # For 8.4a2, we must add -I options that point inside the Tcl and Tk
>     # frameworks. In later release we should hopefully be able to pass
>     # the -F option to gcc, which specifies a framework lookup path.
>     #
>     include_dirs = [
>         join(F, fw + '.framework', H)
>         for fw in 'Tcl', 'Tk'
>         for H in 'Headers', 'Versions/Current/PrivateHeaders'
>     ]
> 
>     # For 8.4a2, the X11 headers are not included. Rather than include a
>     # complicated search, this is a hard-coded path. It could bail out
>     # if X11 libs are not found...
>     include_dirs.append('/usr/X11R6/include')
>     frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
> 
>     return [Extension('_tkinter', [SRCDIR+'/Modules/_tkinter.c', SRCDIR+'/Modules/tkappinit.c'],
>                     define_macros=[('WITH_APPINIT', 1)],
>                     include_dirs = include_dirs,
>                     libraries = [],
>                     extra_compile_args = frameworks,
>                     extra_link_args = frameworks,
>                     )]    
> 
64a116,118
> def find_module(x):
>     return '%s/Mac/Modules/%s' % (SRCDIR, x)
> 
66a121,218
>         Extension('_CF', [find_module(x) for x in 'cf/_CFmodule.c', 'cf/pycfbridge.c'],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'CoreFoundation']),
>         Extension('gestalt', [find_module(x) for x in ['gestaltmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('MacOS', [find_module(x) for x in ['macosmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('icglue', [find_module(x) for x in ['icgluemodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Res', [find_module(x) for x in ['res/_Resmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Snd', [find_module(x) for x in ['snd/_Sndmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         #Extension('Nav', [find_module(x) for x in ['Nav.c']],
>         #        include_dirs=[SRCDIR+"/Mac/Include"],
>         #        extra_link_args=['-framework', 'Carbon']),
>         Extension('_AE', [find_module(x) for x in ['ae/_AEmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_AH', [find_module(x) for x in ['ah/_AHmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_App', [find_module(x) for x in ['app/_Appmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_CarbonEvt', [find_module(x) for x in ['carbonevt/_CarbonEvtmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_CG', [find_module(x) for x in ['cg/_CGmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'ApplicationServices',
>                                  '-framework', 'Carbon']),
>         Extension('_Cm', [find_module(x) for x in ['cm/_Cmmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Ctl', [find_module(x) for x in ['ctl/_Ctlmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Dlg', [find_module(x) for x in ['dlg/_Dlgmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Drag', [find_module(x) for x in ['drag/_Dragmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Evt', [find_module(x) for x in ['evt/_Evtmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_File', [find_module(x) for x in ['file/_Filemodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Folder', [find_module(x) for x in ['folder/_Foldermodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Fm', [find_module(x) for x in ['fm/_Fmmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Help', [find_module(x) for x in ['help/_Helpmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Icn', [find_module(x) for x in ['icn/_Icnmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_IBCarbon', [find_module(x) for x in ['ibcarbon/_IBCarbon.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_List', [find_module(x) for x in ['list/_Listmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Menu', [find_module(x) for x in ['menu/_Menumodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Mlte', [find_module(x) for x in ['mlte/_Mltemodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Qd', [find_module(x) for x in ['qd/_Qdmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Qdoffs', [find_module(x) for x in ['qdoffs/_Qdoffsmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Qt', [find_module(x) for x in ['qt/_Qtmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'QuickTime',
>                                  '-framework', 'Carbon']),
>         Extension('_Scrap', [find_module(x) for x in ['scrap/_Scrapmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_TE', [find_module(x) for x in ['te/_TEmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
>         Extension('_Win', [find_module(x) for x in ['win/_Winmodule.c']],
>                 include_dirs=[SRCDIR+"/Mac/Include"],
>                 extra_link_args=['-framework', 'Carbon']),
84,85c236,241
<         waste_Extension()
<     )
\ No newline at end of file
---
>         waste_Extension() +
>         detect_tkinter_darwin()
>     )
> 
> 
> 

--Apple-Mail-10--13193347
Content-Disposition: attachment;
	filename=makeQt.py
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="makeQt.py"

from __future__ import generators
import sys
# make sure ours get loaded, not 2.2 stock junk
sys.path.insert(0, 'lib-dynload')
import _Qt
from Carbon import Qt, QuickTime, Qd, Qdoffs, QuickDraw, QDOffscreen, Res
import Image
import Numeric
try:
    import SoftimageImage
except:
    # this is just a PIL codec I wrote to load SoftImage PICT files.. the reason I looked into this junk
    pass

def argDict(**kwargs):
    return kwargs

# compression constants
CODECS = argDict(
  kRawCodecType                 = 'raw ',
  kCinepakCodecType             = 'cvid',
  kGraphicsCodecType            = 'smc ',
  kAnimationCodecType           = 'rle ',
  kVideoCodecType               = 'rpza',
  kComponentVideoCodecType      = 'yuv2',
  kJPEGCodecType                = 'jpeg',
  kMotionJPEGACodecType         = 'mjpa',
  kMotionJPEGBCodecType         = 'mjpb',
  kSGICodecType                 = '.SGI',
  kPlanarRGBCodecType           = '8BPS',
  kMacPaintCodecType            = 'PNTG',
  kGIFCodecType                 = 'gif ',
  kPhotoCDCodecType             = 'kpcd',
  kQuickDrawGXCodecType         = 'qdgx',
  kAVRJPEGCodecType             = 'avr ',
  kOpenDMLJPEGCodecType         = 'dmb1',
  kBMPCodecType                 = 'WRLE',
  kWindowsRawCodecType          = 'WRAW',
  kVectorCodecType              = 'path',
  kQuickDrawCodecType           = 'qdrw',
  kWaterRippleCodecType         = 'ripl',
  kFireCodecType                = 'fire',
  kCloudCodecType               = 'clou',
  kH261CodecType                = 'h261',
  kH263CodecType                = 'h263',
  kDVCNTSCCodecType             = 'dvc ',
  kDVCPALCodecType              = 'dvcp',
  kDVCProPALCodecType           = 'dvpp',
  kBaseCodecType                = 'base',
  kFLCCodecType                 = 'flic',
  kTargaCodecType               = 'tga ',
  kPNGCodecType                 = 'png ',
  kTIFFCodecType                = 'tiff',
  kComponentVideoSigned         = 'yuvu',
  kComponentVideoUnsigned       = 'yuvs',
  kCMYKCodecType                = 'cmyk',
  kMicrosoftVideo1CodecType     = 'msvc',
  kSorensonCodecType            = 'SVQ1',
  kSorenson3CodecType           = 'SVQ3',
  kIndeo4CodecType              = 'IV41',
  kMPEG4VisualCodecType         = 'mp4v',
  k64ARGBCodecType              = 'b64a',
  k48RGBCodecType               = 'b48r',
  k32AlphaGrayCodecType         = 'b32a',
  k16GrayCodecType              = 'b16g',
  kMpegYUV420CodecType          = 'myuv',
  kYUV420CodecType              = 'y420',
  kSorensonYUV9CodecType        = 'syv9',
  k422YpCbCr8CodecType          = '2vuy',
  k444YpCbCr8CodecType          = 'v308',
  k4444YpCbCrA8CodecType        = 'v408',
  k422YpCbCr16CodecType         = 'v216',
  k422YpCbCr10CodecType         = 'v210',
  k444YpCbCr10CodecType         = 'v410',
  k4444YpCbCrA8RCodecType       = 'r408')

# quality constants
CODECQUALITY = argDict(
  codecLosslessQuality          = 0x00000400,
  codecMaxQuality               = 0x000003FF,
  codecMinQuality               = 0x00000000,
  codecLowQuality               = 0x00000100,
  codecNormalQuality            = 0x00000200,
  codecHighQuality              = 0x00000300
)

def to_fps(n):
    # 1 fps = 600
    # 10 fps = 60
    return int(600.0 / float(n))

def makeQuicktimeFromFiles(qtFilename, images, codec = CODECS['kRawCodecType'], codecq = CODECQUALITY['codecLosslessQuality'], fps = 30.0):
    """Returns an iterator that yields for each frame rendered"""
    size = Image.open(images[0]).size
    fps = to_fps(fps)
    left, top, right, bottom = RECT = (0, 0) + size
    Qt.EnterMovies()
    open(qtFilename, 'w').close()
    res, mov = Qt.CreateMovieFile(qtFilename, 'TVOD', -2, 0x80000000 | 0x10000000)
    track = mov.NewMovieTrack(right, bottom, 0x100)
    media = track.NewTrackMedia('vide', 600)
    media.BeginMediaEdits()
    gworld = Qdoffs.NewGWorld(32, RECT, None, None, 0)
    Qdoffs.LockPixels(gworld.GetGWorldPixMap())
    oldGWorld = Qdoffs.GetGWorld()
    Qdoffs.SetGWorld(gworld.as_GrafPtr(), None)
    pixMap = gworld.GetGWorldPixMap()
    pixRowBytes = Qdoffs.GetPixRowBytes(pixMap)
    widthBytes = right * 4
    output = Numeric.zeros((widthBytes,), 'b')
    for file in images:
        inputImg = Image.open(file)
        assert inputImg.size == size
        inputStr = inputImg.tostring()
        inputDepth = len(inputStr) / (right * bottom)
        del inputImg
        if inputDepth == 3:
            input = Numeric.reshape(Numeric.fromstring(inputStr, 'b'), (bottom, right * 3))
            output[0::4] = 0xff
            for scanline in range(bottom):
                iscan = input[scanline]
                output[1::4] = iscan[0::3]
                output[2::4] = iscan[1::3]
                output[3::4] = iscan[2::3]
                Qdoffs.PutPixMapBytes(pixMap, scanline * pixRowBytes, output.tostring())
        elif inputDepth == 4:
            input = Numeric.reshape(Numeric.fromstring(inputStr, 'b'), (bottom, widthBytes))
            for scanline in range(bottom):
                iscan = input[scanline]
                output[0::4] = iscan[3::4]
                output[1::4] = iscan[0::4]
                output[2::4] = iscan[1::4]
                output[3::4] = iscan[2::4]
                Qdoffs.PutPixMapBytes(pixMap, scanline * pixRowBytes, output.tostring())
        else:
            raise ValueError, 'Must be RGB or RGBA!'
        imgDescHandle, dataHandle, dataLen = Qt.CompressImage(gworld, RECT, codecq, codec)
        sampleTime = media.AddMediaSample(dataHandle, 0, dataLen, fps, imgDescHandle, 1, 0)
        del dataHandle
        del imgDescHandle
        yield file
    Qdoffs.UnlockPixels(gworld.GetGWorldPixMap())
    Qdoffs.SetGWorld(*oldGWorld)
    del gworld
    del oldGWorld
    media.EndMediaEdits()
    track.InsertMediaIntoTrack(0, 0, media.GetMediaDuration(), 1.0)
    resId = mov.AddMovieResource(res, 'Video', -1)
    if res:
        Qt.CloseMovieFile(res)
    del media
    del track
    del mov

if __name__ == '__main__':
    import sys
    quicktime = sys.argv[1]
    files = sys.argv[2:]
    for filename in makeQuicktimeFromFiles(quicktime, files):
        print filename

--Apple-Mail-10--13193347--