Advertisement
here2share

# standard_all_png.py

May 6th, 2019
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.19 KB | None | 0 0
  1. class pngIDAT:
  2.     def __init__(self,width,height,IDATs):
  3.         if type(IDATs) in (list,tuple):IDAT=''.join(IDATs)
  4.         else:IDAT=IDATs
  5.         del IDATs
  6.         try:self.IDAT=IDAT.decode('zlib')
  7.         except:self.IDAT=IDAT
  8.         self.width,self.height=width,height
  9.         self.size=lambda:(self.width,self.height)
  10.         l=len(self.IDAT)
  11.         if l%self.height!=0 or (l/self.height-1)%self.width!=0 or (l/self.height-1)/self.width not in (1,2,3,4):raise TypeError('It not a valid  8 bit IDAT')
  12.         self.IDAT=[x[1:] for x in yields.yieldSliceLength(self.IDAT,len(self.IDAT)/self.height)]
  13.         #self.IDAT=string2D(self.width,self.height,list(''.join([x[1:] for x in yieldSliceLength(self.IDAT,len(self.IDAT)/self.height)])))
  14.         self.planes=(l/self.height-1)/self.width
  15.         self.modes=('L','LA','RGB','RGBA')
  16.         self.mode=self.modes[self.planes-1]
  17.         self.R=lambda:self.getChannel(0)
  18.         self.G=lambda:self.getChannel(1)
  19.         self.B=lambda:self.getChannel(2)
  20.         self.A=lambda:self.getChannel(3)
  21.     def getChannel(self,n):
  22.         if n==0:N=0
  23.         elif n==4:
  24.             if self.mode in ('L','RGB'):N=None
  25.             elif self.mode=='LA':N=2
  26.             elif self.mode=='RGBA':N=4
  27.         elif n==3:
  28.             if self.mode in ('L','RGB'):N=0
  29.             elif self.mode=='RGBA':N=3
  30.             elif self.mode=='LA':N=2
  31.         elif n==2:
  32.             if self.mode in ('L','LA'):N=0
  33.             elif self.mode in ('RGB','RGBA'):N=2
  34.         elif n==1:
  35.             if self.mode in ('L','LA'):N=0
  36.             elif self.mode in ('RGB','RGBA'):N=1
  37.         if N==None:return ('\0'*self.width for x in xrange(self.height))
  38.         elif self.planes==1:return (x for x in self.IDAT)
  39.         else:
  40.             return (x[N::self.planes] for x in self.IDAT)
  41.     def toFile(self,path=None):
  42.         if path==None:path=tempfile.mktemp('.png')
  43.         pngWriteAll(path,genIHDR(self.width,self.height,self.planes),('\0'+'\0'.join(self.IDAT)).encode('zlib'))
  44.         return path
  45.     def toImage(self,path=None):
  46.         path=self.toFile(path)
  47.         return Image.open(path)
  48.     def show(self,temp=None):
  49.         i=self.toImage(temp)
  50.         showImage(i)
  51.         del i
  52.     def IHDR(self):return genIHDR(self.width,self.height,self.planes)
  53.     def dictIHDR(self):return IHDR_decode(self.IHDR())
  54.     #
  55.     #
  56.    
  57.     #
  58.  
  59.  
  60. def pngAddAlpha(source,alpha_path,target=None):
  61.     if type(source) is not Image:
  62.         img=pngChunks(source,1,'IHDR').next()
  63.         iBitdepth=img[1]['bitdepth']
  64.         if iBitdepth!=8:source=Image.open(source)
  65.         del img
  66.     if type(alpha_path) is not Image:
  67.         mask=pngChunks(alpha_path,1,'IHDR').next()
  68.         mBitdepth=mask[1]['bitdepth']
  69.         if mBitdepth!=8:alpha_path=Image.open(alpha_path)
  70.         del mask
  71.     if type(source) is Image:
  72.         _source=tempfile.mktemp('.png')
  73.         source.save(_source,bpp=24)
  74.         del source
  75.         source=_source
  76.     if type(alpha_path) is Image:
  77.         _alpha_path=tempfile.mktemp('.png')
  78.         alpha_path.save(_alpha_path,bpp=8)
  79.         del alpha_path
  80.         alpha_path=_alpha_path  
  81.     img=pngChunksDict(source,1)
  82.     mask=pngChunksDict(alpha_path,1)
  83.     IHDR=img['IHDR'][0]
  84.     iBitdepth=IHDR['bitdepth']
  85.     mBitdepth=mask['IHDR'][0]['bitdepth']
  86.     IHDR['color_type']=6
  87.     IHDR['bitdepth']=8
  88.     width,height=IHDR['width'],IHDR['height']
  89.     IHDR['compression']=0
  90.     IHDR['interlace']=0
  91.     IHDR=IHDR_encode(IHDR)
  92.     RGB=yieldSliceLength(''.join(img['IDAT']).decode('zlib'),width*3+1)
  93.     A=iter(yieldSliceLength(''.join(mask['IDAT']).decode('zlib'),width+1))
  94.     RGBA=list()
  95.     for row in RGB:
  96.         RGBs=row[1:]
  97.         if len(RGBs)!=width*3:RGBs=rowToRGB(RGBs,width)
  98.         As=A.next()[1:]
  99.         if len(As)==width*3:As=As[::3]
  100.         elif len(As)==width*2:As=As[1::2]
  101.         elif len(As)==width*4:As=As[3::4]
  102.         temp=[' ']*(len(RGBs)*4/3)
  103.         temp[::4]=RGBs[::3]
  104.         temp[1::4]=RGBs[1::3]
  105.         temp[2::4]=RGBs[2::3]
  106.         temp[3::4]=As
  107.         RGBA.extend(['\0']+temp)
  108.     RGBA=''.join(RGBA)
  109.     RGBA=RGBA.encode('zlib')
  110.     if target==None:target='%smasked%s'%os.path.split(source)
  111.     pngWriteAll(target,IHDR,RGBA)
  112. def rowToRGB(row,width):
  113.     l=len(row)
  114.     if l==width:case='L'
  115.     elif l==width*3:return row
  116.     elif l==width*2:case='LA'
  117.     temp=[' ']*width*3
  118.     if case=='LA':row=row[::2]
  119.     temp[::3]=temp[1::3]=temp[2::3]=row
  120.     rt=''.join(temp)
  121.     del temp
  122.     return rt
  123. def genIHDR(width,height,planes):
  124.     if planes==3:ty=2
  125.     elif planes==4:ty=6
  126.     else:ty=2
  127.     return IHDR_encode({'width':width, 'height':height, 'bitdepth':8, 'color_type':ty,'compression':0, 'filter':0,'interlace':0})
  128.    
  129.    
  130.    
  131.  
  132. def IHDR_decode(data):
  133.     try:return dict(zip(
  134.         ('width', 'height', 'bitdepth', 'color_type','compression', 'filter','interlace') ,struct.unpack("!2I5B", data)) )
  135.     except:raise TypeError('It is not a valid IHDR data')
  136. def IHDR_encode(data):
  137.     d=[data[x] for x in ('width', 'height', 'bitdepth', 'color_type','compression', 'filter','interlace')]
  138.     return struct.pack('!2I5B',*d)
  139. def is_png(f):
  140.     signature='\x89PNG\r\n\x1a\n'
  141.     if type(f)  in (str,unicode):
  142.         try:return open('f','wb').read(8)==signature
  143.         except:raise TypeError
  144.     else:
  145.         try:
  146.             f.seek(0)
  147.             return f.read(8)==signature
  148.         except:raise TypeError
  149. def pngChunk(f,result=0,req=None):
  150.     head=f.read(8)
  151.     try:
  152.         length,ty=struct.unpack('!I4s', head)
  153.         if ty=='IHDR':
  154.             data=IHDR_decode(f.read(length+4)[:-4])
  155.         elif result==0:
  156.             pos=f.tell()
  157.             f.seek(pos+length+4)
  158.             data=(pos,length)
  159.         elif result in (1,2,3):
  160.             data=f.read(length+4)[:-4]
  161.             if ty=='IDAT' and result==2:
  162.                 pass
  163.             elif ty=='IDAT' and result==3:data=len(data)
  164.         if req==None or req==ty:return (ty,data)
  165.         else:return pngChunk(f,result,req)
  166.     except:raise ValueError('It is not a valid checksum')
  167.    
  168. def pngChunks(path,result=0,req=None):
  169.     f=open(path,'rb')
  170.     if not is_png(f):raise TypeError('It is not a png file')
  171.     while True:
  172.             try:yield pngChunk(f,result,req)
  173.             except ValueError:
  174.                 f.close()
  175.                 del f
  176.                 break
  177. def pngChunksDict(path,result=0):
  178.     rt=dict()
  179.     for x in iter(pngChunks(path,result)):
  180.         ty,data=x
  181.         if ty not in rt:rt[ty]=[]
  182.         rt[ty].append(data)
  183.     return rt
  184.  
  185. def pngWriteChunk(f, ty, data=''):
  186.     f.write(struct.pack("!I", len(data)))
  187.     f.write(ty)
  188.     f.write(data)
  189.     checksum=zlib.crc32(ty)
  190.     checksum=zlib.crc32(data, checksum)
  191.     checksum&=2**32-1
  192.     f.write(struct.pack("!I", checksum))
  193. def pngWriteAll(path,IHDR,IDAT):
  194.     signature='\x89PNG\r\n\x1a\n'
  195.     f=file(path,'wb')
  196.     f.write(signature)
  197.     pngWriteChunk(f,'IHDR',IHDR)
  198.     pngWriteChunk(f,'IDAT',IDAT)
  199.     pngWriteChunk(f,'IEND')
  200.     f.close()
  201.  
  202. def pngCeil(path,target,n):
  203.     img=pngChunksDict(path,1)
  204.     IHDR=IHDR_encode(img['IHDR'][0])
  205.     IDAT=''.join(img['IDAT']).decode('zlib').translate(ceilMask(n)).encode('zlib')
  206.     pngWriteAll(target,IHDR,IDAT)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement