diff options
Diffstat (limited to 'Mac/Lib/PixMapWrapper.py')
-rw-r--r-- | Mac/Lib/PixMapWrapper.py | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/Mac/Lib/PixMapWrapper.py b/Mac/Lib/PixMapWrapper.py deleted file mode 100644 index bcd3e07..0000000 --- a/Mac/Lib/PixMapWrapper.py +++ /dev/null @@ -1,216 +0,0 @@ -"""PixMapWrapper - defines the PixMapWrapper class, which wraps an opaque -QuickDraw PixMap data structure in a handy Python class. Also provides -methods to convert to/from pixel data (from, e.g., the img module) or a -Python Imaging Library Image object. - -J. Strout <joe@strout.net> February 1999""" - -from Carbon import Qd -from Carbon import QuickDraw -import struct -import MacOS -import img -import imgformat - -# PixMap data structure element format (as used with struct) -_pmElemFormat = { - 'baseAddr':'l', # address of pixel data - 'rowBytes':'H', # bytes per row, plus 0x8000 - 'bounds':'hhhh', # coordinates imposed over pixel data - 'top':'h', - 'left':'h', - 'bottom':'h', - 'right':'h', - 'pmVersion':'h', # flags for Color QuickDraw - 'packType':'h', # format of compression algorithm - 'packSize':'l', # size after compression - 'hRes':'l', # horizontal pixels per inch - 'vRes':'l', # vertical pixels per inch - 'pixelType':'h', # pixel format - 'pixelSize':'h', # bits per pixel - 'cmpCount':'h', # color components per pixel - 'cmpSize':'h', # bits per component - 'planeBytes':'l', # offset in bytes to next plane - 'pmTable':'l', # handle to color table - 'pmReserved':'l' # reserved for future use -} - -# PixMap data structure element offset -_pmElemOffset = { - 'baseAddr':0, - 'rowBytes':4, - 'bounds':6, - 'top':6, - 'left':8, - 'bottom':10, - 'right':12, - 'pmVersion':14, - 'packType':16, - 'packSize':18, - 'hRes':22, - 'vRes':26, - 'pixelType':30, - 'pixelSize':32, - 'cmpCount':34, - 'cmpSize':36, - 'planeBytes':38, - 'pmTable':42, - 'pmReserved':46 -} - -class PixMapWrapper: - """PixMapWrapper -- wraps the QD PixMap object in a Python class, - with methods to easily get/set various pixmap fields. Note: Use the - PixMap() method when passing to QD calls.""" - - def __init__(self): - self.__dict__['data'] = '' - self._header = struct.pack("lhhhhhhhlllhhhhlll", - id(self.data)+MacOS.string_id_to_buffer, - 0, # rowBytes - 0, 0, 0, 0, # bounds - 0, # pmVersion - 0, 0, # packType, packSize - 72<<16, 72<<16, # hRes, vRes - QuickDraw.RGBDirect, # pixelType - 16, # pixelSize - 2, 5, # cmpCount, cmpSize, - 0, 0, 0) # planeBytes, pmTable, pmReserved - self.__dict__['_pm'] = Qd.RawBitMap(self._header) - - def _stuff(self, element, bytes): - offset = _pmElemOffset[element] - fmt = _pmElemFormat[element] - self._header = self._header[:offset] \ - + struct.pack(fmt, bytes) \ - + self._header[offset + struct.calcsize(fmt):] - self.__dict__['_pm'] = None - - def _unstuff(self, element): - offset = _pmElemOffset[element] - fmt = _pmElemFormat[element] - return struct.unpack(fmt, self._header[offset:offset+struct.calcsize(fmt)])[0] - - def __setattr__(self, attr, val): - if attr == 'baseAddr': - raise 'UseErr', "don't assign to .baseAddr -- assign to .data instead" - elif attr == 'data': - self.__dict__['data'] = val - self._stuff('baseAddr', id(self.data) + MacOS.string_id_to_buffer) - elif attr == 'rowBytes': - # high bit is always set for some odd reason - self._stuff('rowBytes', val | 0x8000) - elif attr == 'bounds': - # assume val is in official Left, Top, Right, Bottom order! - self._stuff('left',val[0]) - self._stuff('top',val[1]) - self._stuff('right',val[2]) - self._stuff('bottom',val[3]) - elif attr == 'hRes' or attr == 'vRes': - # 16.16 fixed format, so just shift 16 bits - self._stuff(attr, int(val) << 16) - elif attr in _pmElemFormat.keys(): - # any other pm attribute -- just stuff - self._stuff(attr, val) - else: - self.__dict__[attr] = val - - def __getattr__(self, attr): - if attr == 'rowBytes': - # high bit is always set for some odd reason - return self._unstuff('rowBytes') & 0x7FFF - elif attr == 'bounds': - # return bounds in official Left, Top, Right, Bottom order! - return ( \ - self._unstuff('left'), - self._unstuff('top'), - self._unstuff('right'), - self._unstuff('bottom') ) - elif attr == 'hRes' or attr == 'vRes': - # 16.16 fixed format, so just shift 16 bits - return self._unstuff(attr) >> 16 - elif attr in _pmElemFormat.keys(): - # any other pm attribute -- just unstuff - return self._unstuff(attr) - else: - return self.__dict__[attr] - - - def PixMap(self): - "Return a QuickDraw PixMap corresponding to this data." - if not self.__dict__['_pm']: - self.__dict__['_pm'] = Qd.RawBitMap(self._header) - return self.__dict__['_pm'] - - def blit(self, x1=0,y1=0,x2=None,y2=None, port=None): - """Draw this pixmap into the given (default current) grafport.""" - src = self.bounds - dest = [x1,y1,x2,y2] - if x2 == None: - dest[2] = x1 + src[2]-src[0] - if y2 == None: - dest[3] = y1 + src[3]-src[1] - if not port: port = Qd.GetPort() - Qd.CopyBits(self.PixMap(), port.GetPortBitMapForCopyBits(), src, tuple(dest), - QuickDraw.srcCopy, None) - - def fromstring(self,s,width,height,format=imgformat.macrgb): - """Stuff this pixmap with raw pixel data from a string. - Supply width, height, and one of the imgformat specifiers.""" - # we only support 16- and 32-bit mac rgb... - # so convert if necessary - if format != imgformat.macrgb and format != imgformat.macrgb16: - # (LATER!) - raise "NotImplementedError", "conversion to macrgb or macrgb16" - self.data = s - self.bounds = (0,0,width,height) - self.cmpCount = 3 - self.pixelType = QuickDraw.RGBDirect - if format == imgformat.macrgb: - self.pixelSize = 32 - self.cmpSize = 8 - else: - self.pixelSize = 16 - self.cmpSize = 5 - self.rowBytes = width*self.pixelSize/8 - - def tostring(self, format=imgformat.macrgb): - """Return raw data as a string in the specified format.""" - # is the native format requested? if so, just return data - if (format == imgformat.macrgb and self.pixelSize == 32) or \ - (format == imgformat.macrgb16 and self.pixelsize == 16): - return self.data - # otherwise, convert to the requested format - # (LATER!) - raise "NotImplementedError", "data format conversion" - - def fromImage(self,im): - """Initialize this PixMap from a PIL Image object.""" - # We need data in ARGB format; PIL can't currently do that, - # but it can do RGBA, which we can use by inserting one null - # up frontpm = - if im.mode != 'RGBA': im = im.convert('RGBA') - data = chr(0) + im.tostring() - self.fromstring(data, im.size[0], im.size[1]) - - def toImage(self): - """Return the contents of this PixMap as a PIL Image object.""" - import Image - # our tostring() method returns data in ARGB format, - # whereas Image uses RGBA; a bit of slicing fixes this... - data = self.tostring()[1:] + chr(0) - bounds = self.bounds - return Image.fromstring('RGBA',(bounds[2]-bounds[0],bounds[3]-bounds[1]),data) - -def test(): - import MacOS - import macfs - import Image - fsspec, ok = macfs.PromptGetFile("Image File:") - if not ok: return - path = fsspec.as_pathname() - pm = PixMapWrapper() - pm.fromImage( Image.open(path) ) - pm.blit(20,20) - return pm - |