srcanamdw/codescanner/pyinstaller/icon.py
changeset 1 22878952f6e2
equal deleted inserted replaced
0:509e4801c378 1:22878952f6e2
       
     1 #! /usr/bin/env python
       
     2 # Copyright (C) 2005, Giovanni Bajo
       
     3 # Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
       
     4 #
       
     5 # This program is free software; you can redistribute it and/or
       
     6 # modify it under the terms of the GNU General Public License
       
     7 # as published by the Free Software Foundation; either version 2
       
     8 # of the License, or (at your option) any later version.
       
     9 #
       
    10 # This program is distributed in the hope that it will be useful,
       
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13 # GNU General Public License for more details.
       
    14 #
       
    15 # You should have received a copy of the GNU General Public License
       
    16 # along with this program; if not, write to the Free Software
       
    17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
       
    18 
       
    19 # This code is courtesy of Thomas Heller, who
       
    20 # has kindly donated it to this project.
       
    21 RT_ICON = 3
       
    22 RT_GROUP_ICON = 14
       
    23 LOAD_LIBRARY_AS_DATAFILE = 2
       
    24 
       
    25 import struct
       
    26 
       
    27 class Structure:
       
    28     def __init__ (self):
       
    29         size = self._sizeInBytes = struct.calcsize (self._format_)
       
    30         self._fields_ = list (struct.unpack (self._format_, '\000' * size))
       
    31         indexes = self._indexes_ = {}
       
    32         for i in range (len (self._names_)):
       
    33             indexes[self._names_[i]] = i
       
    34     def dump (self):
       
    35         print "I: DUMP of", self
       
    36         for name in self._names_:
       
    37             if name[0] != '_':
       
    38                 print "I: %20s = %s" % (name, getattr (self, name))
       
    39         print
       
    40     def __getattr__ (self, name):
       
    41         if name in self._names_:
       
    42             index = self._indexes_[name]
       
    43             return self._fields_[index]
       
    44         try:
       
    45             return self.__dict__[name]
       
    46         except KeyError:
       
    47             raise AttributeError, name
       
    48     def __setattr__ (self, name, value):
       
    49         if name in self._names_:
       
    50             index = self._indexes_[name]
       
    51             self._fields_[index] = value
       
    52         else:
       
    53             self.__dict__[name] = value
       
    54     def tostring (self):
       
    55         return apply (struct.pack, [self._format_,] + self._fields_)
       
    56     def fromfile (self, file):
       
    57         data = file.read (self._sizeInBytes)
       
    58         self._fields_ = list (struct.unpack (self._format_, data))
       
    59 
       
    60 class ICONDIRHEADER (Structure):
       
    61     _names_ = "idReserved", "idType", "idCount"
       
    62     _format_ = "hhh"
       
    63 
       
    64 class ICONDIRENTRY (Structure):
       
    65     _names_ = "bWidth", "bHeight", "bColorCount", "bReserved", "wPlanes", "wBitCount", "dwBytesInRes", "dwImageOffset"
       
    66     _format_ = "bbbbhhii"
       
    67 
       
    68 class GRPICONDIR (Structure):
       
    69     _names_ = "idReserved", "idType", "idCount"
       
    70     _format_ = "hhh"
       
    71 
       
    72 class GRPICONDIRENTRY (Structure):
       
    73     _names_ = "bWidth", "bHeight", "bColorCount", "bReserved", "wPlanes", "wBitCount", "dwBytesInRes", "nID"
       
    74     _format_ = "bbbbhhih"
       
    75 
       
    76 class IconFile:
       
    77     def __init__ (self, path):
       
    78         self.path = path
       
    79         file = open (path, "rb")
       
    80         self.entries = []
       
    81         self.images = []
       
    82         header = self.header = ICONDIRHEADER()
       
    83         header.fromfile (file)
       
    84         for i in range (header.idCount):
       
    85             entry = ICONDIRENTRY()
       
    86             entry.fromfile (file)
       
    87             self.entries.append (entry)
       
    88         for e in self.entries:
       
    89             file.seek (e.dwImageOffset, 0)
       
    90             self.images.append (file.read (e.dwBytesInRes))
       
    91 
       
    92     def grp_icon_dir (self):
       
    93         return self.header.tostring()
       
    94 
       
    95     def grp_icondir_entries (self):
       
    96         data = ""
       
    97         i = 1
       
    98         for entry in self.entries:
       
    99             e = GRPICONDIRENTRY()
       
   100             for n in e._names_[:-1]:
       
   101                 setattr(e, n, getattr (entry, n))
       
   102             e.nID = i
       
   103             i = i + 1
       
   104             data = data + e.tostring()
       
   105         return data
       
   106 
       
   107 
       
   108 def CopyIcons_FromIco (dstpath, srcpath):
       
   109     f = IconFile (srcpath)
       
   110     print "I: Updating icons from", srcpath, "to", dstpath
       
   111     import win32api #, win32con
       
   112     hdst = win32api.BeginUpdateResource (dstpath, 0)
       
   113     data = f.grp_icon_dir()
       
   114     data = data + f.grp_icondir_entries()
       
   115     win32api.UpdateResource (hdst, RT_GROUP_ICON, 1, data)
       
   116     print "I: Writing RT_GROUP_ICON resource with %d bytes" % len (data)
       
   117     i = 1
       
   118     for data in f.images:
       
   119         win32api.UpdateResource (hdst, RT_ICON, i, data)
       
   120         print "I: Writing RT_ICON resource with %d bytes" % len (data)
       
   121         i = i + 1
       
   122     win32api.EndUpdateResource (hdst, 0)
       
   123 
       
   124 def CopyIcons (dstpath, srcpath):
       
   125     import os.path, string
       
   126     index = None
       
   127     try:
       
   128         srcpath, index = map (string.strip, string.split (srcpath, ','))
       
   129         index = int (index)
       
   130     except:
       
   131         pass
       
   132     print "I: PATH, INDEX", srcpath, index
       
   133     srcext = os.path.splitext (srcpath)[1]
       
   134     if string.lower (srcext) == '.ico':
       
   135         return CopyIcons_FromIco (dstpath, srcpath)
       
   136     if index is not None:
       
   137         print "I: Updating icons from", srcpath, ", %d to" % index, dstpath
       
   138     else:
       
   139         print "I: Updating icons from", srcpath, "to", dstpath
       
   140     import win32api #, win32con
       
   141     hdst = win32api.BeginUpdateResource (dstpath, 0)
       
   142     hsrc = win32api.LoadLibraryEx (srcpath, 0, LOAD_LIBRARY_AS_DATAFILE)
       
   143     if index is None:
       
   144         grpname = win32api.EnumResourceNames (hsrc, RT_GROUP_ICON)[0]
       
   145     elif index >= 0:
       
   146         grpname = win32api.EnumResourceNames (hsrc, RT_GROUP_ICON)[index]
       
   147     else:
       
   148         grpname = -index
       
   149     data = win32api.LoadResource (hsrc, RT_GROUP_ICON, grpname)
       
   150     win32api.UpdateResource (hdst, RT_GROUP_ICON, grpname, data)
       
   151     for iconname in win32api.EnumResourceNames (hsrc, RT_ICON):
       
   152         data = win32api.LoadResource (hsrc, RT_ICON, iconname)
       
   153         win32api.UpdateResource (hdst, RT_ICON, iconname, data)
       
   154     win32api.FreeLibrary (hsrc)
       
   155     win32api.EndUpdateResource (hdst, 0)
       
   156