Module brewcompressedimage
[hide private]
[frames] | no frames]

Source Code for Module brewcompressedimage

  1  #!/usr/bin/env python 
  2   
  3  ### BITPIM 
  4  ### 
  5  ### Copyright (C) 2003-2004 Roger Binns <rogerb@rogerbinns.com> 
  6  ### 
  7  ### This program is free software; you can redistribute it and/or modify 
  8  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  9  ### 
 10  ### $Id: brewcompressedimage.py 2781 2006-01-30 23:18:32Z djpham $ 
 11   
 12  """Support for the BCI (Brew Compressed Image) format 
 13   
 14  Currently this code can read a BCI file.  You should call the 
 15  L{getimage} function. 
 16   
 17  """ 
 18   
 19  """ 
 20  integers are lsb 
 21   
 22  0000 - 0003 BCI\0 
 23  0004 - 0007 ?  (x0844 = 2116) [length of file] 
 24  0008 - 000b ?  (x0434 = 1076) [offset to first image 
 25  000c - 000d ?  (1) 
 26  000e - 000f width 
 27  0010 - 0011 height 
 28  0012 - 0013 ?  (1) 2 
 29  0014 - 0015 ?  (1) 2 
 30  0016 - 0017 ?  (1) 2 
 31  0018 - 0019 ?  (0) 
 32  001a - 001b ?  (8) [bits per pixel?] 
 33  001c - 001d ?  (1) 
 34  001e - 001f ?  [0x100 = 256 ] # number of entries in palette 
 35   
 36  palette 
 37  b,g,r,0  (32 bit entry) 
 38   
 39  next palette 
 40  0000 - 0001 ? (2) palette number/id 
 41  0002 - 0003 number of entries in palette 
 42   
 43  image 
 44  0000 - 0001 data length 
 45  0002 - 0003 ? (0) 
 46  0004 - 0005 width 
 47  0006 - 0007 height 
 48  0008 - 0009 ? (1) 
 49  000a - 000b ? (1) 
 50   
 51  """ 
 52   
 53  import common 
 54  import zlib 
 55  import cStringIO 
 56   
 57  import wx 
 58   
59 -class Display(wx.Frame):
60 """Used for the builtin tester""" 61
62 - def __init__(self, file, parent=None):
63 bmp=wx.BitmapFromImage(wx.Image(file)) 64 65 wx.Frame.__init__(self, parent, -1, "Image Display") 66 67 b=wx.StaticBitmap(self, -1, bmp) 68 69 b.SetSize((bmp.GetWidth(), bmp.GetHeight())) 70 self.Fit() 71 self.Show(True)
72 73
74 -class MyImage:
75 """An encapsulation of the image""" 76
77 - def __init__(self, width, height, bytes, palette):
78 self.width=width 79 self.height=height 80 offset=0 81 import cStringIO 82 data=cStringIO.StringIO() 83 for row in range(height): 84 # print "\r"+`row`, 85 # 32 bit alignment 86 while (offset%4)!=0: 87 offset+=1 88 for col in range(width): 89 v=ord(bytes[offset]) 90 offset+=1 91 data.write(palette[v]) 92 93 self.data=data.getvalue()
94 # print 95
96 - def toImage(self, img=None):
97 """Converts image to wxImage 98 99 @rtype: wxImage 100 """ 101 if img is None: 102 img=wx.EmptyImage(self.width, self.height) 103 else: 104 img.Destroy() 105 img.Create(self.width, self.height) 106 img.SetData(self.data) 107 return img
108
109 -class BCIPalette:
110 """An encapsulation of the palette"""
111 - def __init__(self, data=""):
112 pal=[] 113 for offset in range(0, len(data), 4): 114 assert data[3]=="\x00" 115 pal.append(data[offset+2]+data[offset+1]+data[offset]) 116 self.pal=pal
117
118 - def __getitem__(self,e):
119 return self.pal[e]
120
121 -class MemoryInputStream(wx.InputStream):
122 - def __init__(self, data):
123 import cStringIO 124 wx.InputStream.__init__(self,cStringIO.StringIO(data))
125
126 -class FileInputStream(wx.InputStream):
127 - def __init__(self, name):
128 self.f=open(name, "rb") 129 wx.InputStream.__init__(self, self.f)
130
131 - def __del__(self):
132 self.f.close()
133
134 -def getimage(stream, intoImage=None):
135 """Returns a wxImage of the stream specified""" 136 137 # try to read the entire thing in one gulp 138 data=stream.read() 139 # save hex version for debugging 140 # f=open(file+".hex", "w") 141 # f.write(common.datatohexstring(data)) 142 # f.close() 143 144 palettes={} 145 146 ### verify format 147 148 # header 149 assert data[0x00:0x04]=='BCI\x00' 150 # file length 151 assert readlsb(data[0x04:0x08])<=len(data) # this would be == but the bci tool doesn't truncate the file! 152 # image offset 153 imageoffset=readlsb(data[0x08:0x0b]) 154 assert imageoffset<len(data) 155 # ? (1) 156 assert readlsb(data[0x0c:0x0e])==1 157 # width, height 158 width=readlsb(data[0x0e:0x10]) 159 height=readlsb(data[0x10:0x12]) 160 assert width>0 and height>0 161 # number of objects/frames/palettes? no idea on order 162 numitem1=readlsb(data[0x12:0x14]) 163 numitem2=readlsb(data[0x14:0x16]) 164 numitem3=readlsb(data[0x16:0x18]) 165 # print "number of objects/frames/palettes? no idea on order: %d, %d, %d" % (numitem1, numitem2, numitem3) 166 numpalettes=numitem1 # just a guess 167 numotherthing=numitem2 # no idea what they are, possibly 'frames' as in the doc 168 numimages=numitem3 # images, probably 'object' as in the doc 169 # ? (0) 170 assert readlsb(data[0x18:0x1a])==0 171 # palette depth? 172 bpp=readlsb(data[0x1a:0x1c]) 173 # read the palettes 174 offset=0x1c 175 for _ in range(numpalettes): 176 id=readlsb(data[offset:offset+2]) 177 # print "palette id",id 178 offset+=2 179 numentries=readlsb(data[offset:offset+2]) 180 # print "contains",numentries,"entries" 181 offset+=2 182 # f=open(file+".palette."+`id`+".hex", "w") 183 # f.write(common.datatohexstring(data[offset:offset+numentries*4])) 184 # f.close() 185 pal=BCIPalette(data[offset:offset+numentries*4]) 186 offset+=numentries*4 187 palettes[id]=pal 188 189 190 # some other type of object, possibly frames as in the doc 191 for _ in range(numotherthing): 192 # we just ignore the contents for the moment 193 # print common.datatohexstring(data[offset:offset+0x14]) 194 offset+=0x14 195 196 # images 197 for _ in range(numimages): 198 szdata=readlsb(data[offset:offset+4]) 199 width=readlsb(data[offset+4:offset+6]) 200 height=readlsb(data[offset+6:offset+8]) 201 id1=readlsb(data[offset+8:offset+0xa]) # image id? 202 id2=readlsb(data[offset+0xa:offset+0xc]) # palette id? 203 offset+=0xc 204 buf=data[offset:offset+szdata] 205 res=zlib.decompress(buf) 206 # f=open(file+".image."+`id1`+".hex", "w") 207 # f.write(common.datatohexstring(res)) 208 # f.close() 209 210 img=MyImage(width, height, res, palettes[id2]) 211 212 return img.toImage(intoImage)
213
214 -def readlsb(data):
215 """Read binary data in lsb""" 216 res=0 217 shift=0 218 for i in data: 219 res|=ord(i)<<shift 220 shift+=8 221 return res
222 223 BITMAP_TYPE_BCI=wx.BITMAP_TYPE_ANY+1 224
225 -class BCIImageHandler(wx.PyImageHandler):
226
227 - def __init__(self):
228 super(BCIImageHandler, self).__init__() 229 self.SetName("BREW Compressed Image") 230 self.SetExtension("bci") 231 self.SetType(BITMAP_TYPE_BCI) 232 self.SetMimeType("image/x-brewcompressedimage")
233
234 - def GetImageCount(self, _):
235 # ::TODO:: return multiple images 236 return 1
237
238 - def LoadFile(self, image, stream, verbose, index):
239 try: 240 getimage(stream, image) 241 return True 242 except: 243 return False
244
245 - def SaveFile(self, image, stream, verbose):
246 raise NotImplementedError
247
248 - def DoCanRead(self, stream):
249 # Check to see if the stream is a valid BCI stream, 250 return stream.read(4)=='BCI\x00'
251 252 BITMAP_TYPE_LGBIT=BITMAP_TYPE_BCI+1
253 -class LGBITImageHandler(wx.PyImageHandler):
254 - def __init__(self):
255 super(LGBITImageHandler, self).__init__() 256 self.SetName('LG BIT Image') 257 self.SetExtension('bit') 258 self.SetType(BITMAP_TYPE_LGBIT)
259
260 - def GetImageCount(self, _):
261 return 1
262
263 - def LoadFile(self, image, stream, verbose, index):
264 return False
265 - def SaveFile(self, image, stream, verbose):
266 return False
267 - def DoCanRead(self, stream):
268 return False
269 270 wx.Image_AddHandler(BCIImageHandler()) 271 272 if __name__=='__main__': 273 import sys 274 275 app=wx.PySimpleApp() 276 if len(sys.argv)==2: 277 f=Display(sys.argv[1]) 278 elif len(sys.argv)==3: 279 bciconvert(sys.argv[1], sys.argv[2]) 280 f=Display(sys.argv[2]) 281 else: 282 assert Exception, "not enough params" 283 284 app.MainLoop() 285