diff options
Diffstat (limited to 'Lib/plat-mac/PixMapWrapper.py')
-rw-r--r-- | Lib/plat-mac/PixMapWrapper.py | 362 |
1 files changed, 181 insertions, 181 deletions
diff --git a/Lib/plat-mac/PixMapWrapper.py b/Lib/plat-mac/PixMapWrapper.py index 01973e8..a2d13fe 100644 --- a/Lib/plat-mac/PixMapWrapper.py +++ b/Lib/plat-mac/PixMapWrapper.py @@ -14,202 +14,202 @@ 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 + '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 + '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.""" + """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 __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 __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 __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 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 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 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 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 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 EasyDialogs - import Image - path = EasyDialogs.AskFileForOpen("Image File:") - if not path: return - pm = PixMapWrapper() - pm.fromImage( Image.open(path) ) - pm.blit(20,20) - return pm + import MacOS + import EasyDialogs + import Image + path = EasyDialogs.AskFileForOpen("Image File:") + if not path: return + pm = PixMapWrapper() + pm.fromImage( Image.open(path) ) + pm.blit(20,20) + return pm |