Codebase list hachoir / fa1769e
Run autopep8 Victor Stinner 7 years ago
39 changed file(s) with 224 addition(s) and 105 deletion(s). Raw diff Collapse all Expand all
6868
6969
7070 class Grep:
71
7172 def __init__(self):
7273 self.pattern = None
7374 self.case_sensitive = True
9596
9697
9798 class ConsoleGrep(Grep):
99
98100 def __init__(self):
99101 Grep.__init__(self)
100102 self.term_charset = getTerminalCharset()
1919 Compute compression rate, sizes have to be in byte.
2020 """
2121 if (not meta.has("file_size")
22 or not meta.get("compr_size", 0)):
22 or not meta.get("compr_size", 0)):
2323 return
2424 file_size = meta.get("file_size")
2525 if not file_size:
44
55
66 class ISO9660_Metadata(RootMetadata):
7
78 def extract(self, iso):
89 desc = iso['volume[0]/content']
910 self.title = desc['volume_id'].value
7070 for entry in ifd.array("entry"):
7171 self.processIfdEntry(ifd, entry, attr)
7272 if 'BitsPerSample' in attr and 'SamplesPerPixel' in attr:
73 self.bits_per_pixel = attr['BitsPerSample'] * attr['SamplesPerPixel']
73 self.bits_per_pixel = attr[
74 'BitsPerSample'] * attr['SamplesPerPixel']
7475
7576 @fault_tolerant
7677 def processIfdEntry(self, ifd, entry, attr):
3838 """
3939 # Invalid key?
4040 if key not in self.__data:
41 raise KeyError("%s has no metadata '%s'" % (self.__class__.__name__, key))
41 raise KeyError("%s has no metadata '%s'" %
42 (self.__class__.__name__, key))
4243
4344 # Skip duplicates
4445 self.__data[key].add(value)
7677 item = self.getItem(key, index)
7778 if item is None:
7879 if default is None:
79 raise ValueError("Metadata has no value '%s' (index %s)" % (key, index))
80 raise ValueError(
81 "Metadata has no value '%s' (index %s)" % (key, index))
8082 else:
8183 return default
8284 return item.value
181183
182184
183185 class RootMetadata(Metadata):
186
184187 def __init__(self, quality=QUALITY_NORMAL):
185188 Metadata.__init__(self, None, quality)
186189
239242 title = key
240243 else:
241244 title = None
242 value = metadata.exportPlaintext(priority, human, line_prefix, title=title)
245 value = metadata.exportPlaintext(
246 priority, human, line_prefix, title=title)
243247 if value:
244248 text.extend(value)
245249 if len(text):
6161
6262 self.compression = format["codec"].display
6363 if ("nb_sample/nb_sample" in wav
64 and 0 < format["sample_per_sec"].value):
65 self.duration = timedelta(seconds=float(wav["nb_sample/nb_sample"].value) / format["sample_per_sec"].value)
64 and 0 < format["sample_per_sec"].value):
65 self.duration = timedelta(seconds=float(
66 wav["nb_sample/nb_sample"].value) / format["sample_per_sec"].value)
6667 if format["codec"].value in UNCOMPRESSED_AUDIO:
6768 # Codec with fixed bit rate
68 self.bit_rate = format["nb_channel"].value * format["bit_per_sample"].value * format["sample_per_sec"].value
69 self.bit_rate = format[
70 "nb_channel"].value * format["bit_per_sample"].value * format["sample_per_sec"].value
6971 if (not self.has("duration")
70 and "audio_data/size" in wav
71 and self.has("bit_rate")):
72 duration = float(wav["audio_data/size"].value) * 8 / self.get('bit_rate')
72 and "audio_data/size" in wav
73 and self.has("bit_rate")):
74 duration = float(wav["audio_data/size"].value) * \
75 8 / self.get('bit_rate')
7376 self.duration = timedelta(seconds=duration)
7477
7578 def extractInfo(self, fieldset):
9093 fps = float(header["rate"].value) / header["scale"].value
9194 meta.frame_rate = fps
9295 if 0 < fps:
93 self.duration = meta.duration = timedelta(seconds=float(header["length"].value) / fps)
96 self.duration = meta.duration = timedelta(
97 seconds=float(header["length"].value) / fps)
9498
9599 if "../stream_fmt/width" in header:
96100 format = header["../stream_fmt"]
111115 if "../stream_hdr" in format:
112116 header = format["../stream_hdr"]
113117 if header["rate"].value and header["scale"].value:
114 frame_rate = float(header["rate"].value) / header["scale"].value
115 meta.duration = timedelta(seconds=float(header["length"].value) / frame_rate)
118 frame_rate = float(
119 header["rate"].value) / header["scale"].value
120 meta.duration = timedelta(seconds=float(
121 header["length"].value) / frame_rate)
116122 if header["fourcc"].value != "":
117123 meta.compression = "%s (fourcc:\"%s\")" \
118124 % (format["codec"].display, header["fourcc"].value)
126132 uncompr = meta.get('bit_rate', 0)
127133 if not uncompr:
128134 return
129 compr = meta.get('nb_channel') * meta.get('sample_rate') * meta.get('bits_per_sample', default=16)
135 compr = meta.get('nb_channel') * meta.get('sample_rate') * \
136 meta.get('bits_per_sample', default=16)
130137 if not compr:
131138 return
132139 meta.compr_rate = float(compr) / uncompr
165172
166173 # Compute global bit rate
167174 if self.has("duration") and "/movie/size" in headers:
168 self.bit_rate = float(headers["/movie/size"].value) * 8 / timedelta2seconds(self.get('duration'))
175 self.bit_rate = float(
176 headers["/movie/size"].value) * 8 / timedelta2seconds(self.get('duration'))
169177
170178 # Video has index?
171179 if "/index" in headers:
44 http://standards.ieee.org/regauth/oui/oui.txt
55 """
66
7 REGISTERED_OUID = { # noqa
7 REGISTERED_OUID = { # noqa
88 0x000000: u'XEROX CORPORATION',
99 0x000001: u'XEROX CORPORATION',
1010 0x000002: u'XEROX CORPORATION',
88 Store self.size data rates to compute good average speed.
99 Don't compute average before self.min_size values are computed.
1010 """
11
1112 def __init__(self, offset, size=20, min_size=3):
1213 self.last_offset = offset
1314 self.last_time = time()
22
33 if __name__ == "__main__":
44 main()
5
00 #!/usr/bin/env python3
1 import sys, os
1 import sys
2 import os
23
34 from gi.repository import Gtk
45
67 from hachoir.metadata import extractMetadata
78 from hachoir.metadata.metadata import MultipleMetadata
89
10
911 class Gui:
12
1013 def __init__(self):
1114 self.main_window = Gtk.Window()
1215 self.main_window.set_border_width(5)
2427 self.main_vbox.pack_start(self.select_hbox, False, True, 0)
2528
2629 self.metadata_table = Gtk.Table(1, 1)
27 self.metadata_table.attach(Gtk.Label("Select a file to view metadata information..."), 0, 1, 0, 1)
30 self.metadata_table.attach(
31 Gtk.Label("Select a file to view metadata information..."), 0, 1, 0, 1)
2832 self.main_vbox.pack_start(self.metadata_table, True, True, 0)
2933
3034 self.main_window.add(self.main_vbox)
3539
3640 def _select_clicked(self, widget):
3741 file_chooser = Gtk.FileChooserDialog("Ouvrir..", None,
38 Gtk.FILE_CHOOSER_ACTION_OPEN,
39 (Gtk.STOCK_CANCEL, Gtk.RESPONSE_CANCEL,
40 Gtk.STOCK_OPEN, Gtk.RESPONSE_OK))
42 Gtk.FILE_CHOOSER_ACTION_OPEN,
43 (Gtk.STOCK_CANCEL, Gtk.RESPONSE_CANCEL,
44 Gtk.STOCK_OPEN, Gtk.RESPONSE_OK))
4145 file_chooser.set_default_response(Gtk.RESPONSE_OK)
4246 file_chooser.show()
4347
5862 self.main_vbox.pack_start(self.metadata_table, True, True, 0)
5963
6064 if metadata is None:
61 self.metadata_table.attach(Gtk.Label("Unknown file format"), 0, 1, 0, 1)
65 self.metadata_table.attach(
66 Gtk.Label("Unknown file format"), 0, 1, 0, 1)
6267 else:
6368 total = 1
6469 for data in sorted(metadata):
6873 for item in data.values:
6974 self.metadata_table.resize(total, 2)
7075 value = item.text
71 self.metadata_table.attach(Gtk.Label(title + ":"), 0, 1, total-1, total)
72 self.metadata_table.attach(Gtk.Label(value), 1, 2, total-1, total)
76 self.metadata_table.attach(
77 Gtk.Label(title + ":"), 0, 1, total - 1, total)
78 self.metadata_table.attach(
79 Gtk.Label(value), 1, 2, total - 1, total)
7380 total += 1
7481 self.metadata_table.show_all()
7582
94101
95102 if __name__ == "__main__":
96103 Gui().main()
97
0 import wx, os
0 import wx
1 import os
12 from hachoir.core.i18n import _
3
24
35 def file_open_dialog():
46 dialog_style = wx.OPEN | wx.FILE_MUST_EXIST
57
68 dialog = wx.FileDialog(
7 None, message = _('Open'),
8 defaultDir = os.getcwd(),
9 defaultFile = '', style = dialog_style)
9 None, message=_('Open'),
10 defaultDir=os.getcwd(),
11 defaultFile='', style=dialog_style)
1012
1113 return dialog
14
1215
1316 def file_save_dialog(title):
1417 dialog_style = wx.SAVE
1518
1619 dialog = wx.FileDialog(
17 None, message = title,
18 defaultDir = os.getcwd(),
19 defaultFile = '', style = dialog_style)
20 None, message=title,
21 defaultDir=os.getcwd(),
22 defaultFile='', style=dialog_style)
2023
2124 return dialog
00 class dispatcher_t:
1
12 def __init__(self):
23 self.receivers = []
34
22
33 from .field_menu_setup import setup_field_menu
44 from .field_menu import field_menu_t
5
11 from hachoir_wx.field_view.mutator import convert_field
22 from hachoir_wx.field_view.stubs import can_convert
33
4
45 class core_type_menu_imp_t:
6
57 def __init__(self):
68 self.cur_field = None
79
00 from hachoir_wx.field_view.stubs import save_substream_to_disk
11 from hachoir.core.i18n import _
22
3
34 class field_menu_imp_t:
5
46 def on_field_set_ready(self, dispatcher, fields):
57 assert fields is not None
68 self.fields = fields
4446 self.dispatcher.trigger('field_open_window_here', self.selected)
4547
4648 def on_dump_to_disk(self, event):
47 dump_path = self.view.ask_for_dump_file(_('Dump "' + self.selected._getPath() + '" To Disk...'))
49 dump_path = self.view.ask_for_dump_file(
50 _('Dump "' + self.selected._getPath() + '" To Disk...'))
4851 if dump_path is not None:
4952 save_substream_to_disk(self.selected, dump_path)
50
00 from wx import GetNumberFromUser
11 from hachoir.core.i18n import _
22
3
34 class field_split_menu_t:
5
46 def __init__(self, parent, menu):
57 self.parent = parent
68 self.menu = menu
7 self.Bind = self.menu.Bind # see note in field_menu.py
9 self.Bind = self.menu.Bind # see note in field_menu.py
810
911 def ask_split(self, caption, min, max):
1012 num = GetNumberFromUser(_('Enter split offset:'), '',
11 from hachoir.field import RawBytes, RawBits
22 from hachoir.core.i18n import _
33
4
45 class field_split_menu_imp_t:
6
57 def on_field_split_menu_ready(self, dispatcher, view):
68 assert view is not None
79 self.view = view
2022 def split_field(self, caption, field, split_type, size_func):
2123 offset = self.view.ask_split(caption, 1, size_func(field) - 1)
2224 if offset is not None:
23 new_fields = split_field(field, offset, field._getName(), split_type, size_func)
25 new_fields = split_field(
26 field, offset, field._getName(), split_type, size_func)
2427
2528 return offset
22 from sys import maxsize
33 from hachoir.core.i18n import _
44
5
56 class field_view_t(ListCtrl, ListCtrlAutoWidthMixin):
7
68 def __init__(self):
79 self.cols = {}
810
1315 def post_init(self):
1416 ListCtrlAutoWidthMixin.__init__(self)
1517
16 columns = [_('address'), _('name'), _('type'), _('size'), _('data'), _('description')]
18 columns = [_('address'), _('name'), _('type'),
19 _('size'), _('data'), _('description')]
1720 for name in columns:
1821 self.append_column(name)
1922 self.col_min_width = [len(s) for s in columns]
2932 def append_column(self, name):
3033 index = self.GetColumnCount()
3134 self.cols[name] = index
32 self.InsertColumn(col = index, heading = name)
35 self.InsertColumn(col=index, heading=name)
3336
3437 def get_selected(self, name):
3538 return self.GetItem(self.GetFocusedItem(), self.cols[_('name')]).GetText()
4447 return self.OnGetItemText_imp(item, col)
4548
4649 def get_col_index(self, name):
47 return self.cols[name]
50 return self.cols[name]
4851
4952 def get_col_count(self):
50 return len(self.cols)
53 return len(self.cols)
5154
5255 def resize_column(self, col_index, width):
5356 width = max(self.col_min_width[col_index], width) + 1
22
33 MAXITEMS = 1000
44
5
56 class field_view_imp_t:
7
68 def __init__(self):
79 self.addr_func = lambda field: field._getAbsoluteAddress()
810 self.format_addr = lambda field: format_addr_hex(self.addr_func(field))
2426 assert view is not None
2527
2628 # register callbacks before activating the field view
27 view.register_callback(cbGetItemText = self.OnGetItemTextImp)
29 view.register_callback(cbGetItemText=self.OnGetItemTextImp)
2830
2931 self.view = view
3032 self.fill_view()
9193 width = 0
9294 func = self.col_str_table[col]
9395 # when fields has more than 20 rows, they are probably similar.
94 # Therefore this routine only checks the first 10 rows and last 10 rows.
96 # Therefore this routine only checks the first 10 rows and last 10
97 # rows.
9598
9699 if field_count <= 20:
97100 field_range = [(0, field_count)]
117120 else:
118121 parent_count = 0
119122 try:
120 self.fields[item+MAXITEMS]
121 if item+MAXITEMS+parent_count > self.view.GetItemCount():
122 self.view.SetItemCount(item+MAXITEMS+parent_count)
123 self.fields[item + MAXITEMS]
124 if item + MAXITEMS + parent_count > self.view.GetItemCount():
125 self.view.SetItemCount(item + MAXITEMS + parent_count)
123126 except:
124127 if len(self.fields) + parent_count != self.view.GetItemCount():
125 self.view.SetItemCount(len(self.fields)+parent_count)
128 self.view.SetItemCount(len(self.fields) + parent_count)
126129 field = self.fields[item]
127130 return self.col_str_table[col](field)
128131
00 def format_addr_dec(addr):
11 return "%08d.%01d" % divmod(addr, 8)
2
23
34 def format_addr_hex(addr):
45 return "%08x.%01d" % divmod(addr, 8)
56
7
68 def format_size(size):
79 return "%08u.%01d" % divmod(size, 8)
10
811
912 def format_data(field):
1013 data = ''
1417
1518 return data
1619
20
1721 def format_name(field):
1822 name = field._getName()
1923 if field.is_field_set:
2125
2226 return name
2327
28
2429 def format_desc(field):
2530 if field.description:
2631 return str(field.description)
2732 return ''
28
44 from hachoir.core.tools import alignValue
55 from hachoir.stream.input import FileFromInputStream
66
7
78 def field_index(field_set, field):
89 return field_set._fields.index(field._getName())
10
911
1012 def field_from_index(field_set, index):
1113 return field_set._fields.values[index]
1214
15
1316 def has_static_size(type):
1417 return isinstance(type.static_size, int)
18
1519
1620 def can_convert(from_field, to_type):
1721 if has_static_size(from_field) and has_static_size(to_type):
2125 else:
2226 return False
2327
28
2429 def field_type_name(field):
2530 return field.__class__.__name__
31
2632
2733 def convert_size(from_field, to_type):
2834 if not(('Byte' in field_type_name(from_field)) ^ ('Byte' in to_type.__name__)):
3238 else:
3339 return from_field._getSize() // 8
3440
41
3542 def save_substream_to_disk(field, dest_path):
3643 dest_stream = open(dest_path, 'wb')
3744 f = FileFromInputStream(field.getSubIStream())
3845 dest_stream.write(f.read())
3946 dest_stream.close()
40
00 from wx import Frame, PreFrame
11
2
23 class frame_view_t(Frame):
4
35 def __init__(self):
46 pre = PreFrame()
57 self.PostCreate(pre)
68
79 def ready(self):
810 self.dispatcher.trigger('frame_view_ready', self)
9
00 import wx
11
2
23 class frame_view_fwd_t:
4
35 def __init__(self, imp):
46 self.imp = imp
57
00 class frame_view_imp_t:
1
12 def on_frame_view_ready(self, dispatcher, frame_view):
23 assert frame_view is not None
34 self.view = frame_view
1112
1213 def format_title(self, field):
1314 field_path = field._getPath()
14 return self.filename+'/'+field_path[1:]
15 return self.filename + '/' + field_path[1:]
1516
1617 def on_field_activated(self, dispatcher, field):
1718 self.view.SetTitle(self.format_title(field))
11 from .frame_view_fwd import frame_view_fwd_t
22
33 from hachoir_wx.resource import get_frame
4
45
56 def setup_frame_view(dispatcher):
67 print('[+] Setup frame view')
00 # Windows wx compatibility
11
2
23 def get_width_chars(view):
3 return ((view.GetClientSize()[0]-3) // (view.GetCharWidth()-1) - 1) // 3
4 return ((view.GetClientSize()[0] - 3) // (view.GetCharWidth() - 1) - 1) // 3
5
46
57 def get_height_chars(view):
68 return view.GetClientSize()[1] // view.GetCharHeight()
00 from wx import TextCtrl, TextAttr, PreTextCtrl
11 from .stubs import to_ascii, to_hex, calc_char_range, calc_ascii_range, clamp_range
22 from hachoir_wx.hex_view import get_width_chars, get_height_chars
3
34
45 class hex_view_t(TextCtrl):
56 default_style = TextAttr()
2627 self.Refresh()
2728
2829 def mark_range(self, start, size):
29 mark_start, mark_end = calc_char_range(start, start + size, self.get_width_chars())
30 mark_start, mark_end = calc_char_range(
31 start, start + size, self.get_width_chars())
3032
3133 mark_start = clamp_range(mark_start, 0, self.get_size())
3234 mark_end = clamp_range(mark_end, 0, self.get_size())
3436 self.SetStyle(mark_start, mark_end, self.highlight_style)
3537 self.Refresh()
3638
37 mark_start, mark_end = calc_ascii_range(start, start + size, self.get_width_chars())
39 mark_start, mark_end = calc_ascii_range(
40 start, start + size, self.get_width_chars())
3841
3942 mark_start = clamp_range(mark_start, 0, self.get_ascii_size())
4043 mark_end = clamp_range(mark_end, 0, self.get_ascii_size())
5255 def get_size(self):
5356 return len(self.GetValue())
5457
58
5559 def get_page_size(view):
5660 return view.get_width_chars() * view.get_height_chars()
00 from wx import ScrollBar, PreScrollBar
11
2
23 class hex_view_scroll_t(ScrollBar):
4
35 def __init__(self):
46 pre = PreScrollBar()
57 self.PostCreate(pre)
68
79 def ready(self):
810 self.dispatcher.trigger('hex_view_scroll_ready', self)
9
00 from math import ceil
11 from .stubs import byte_addr, get_file_size, get_page_num
22
3
34 class hex_view_scroll_imp_t:
5
46 def on_file_ready(self, dispatcher, file):
57 assert file is not None
68 self.file = file
2123 cur_height = self.offset_to_thumb(pos)
2224 total_height = int(ceil(get_file_size(self.file) / float(page_width)))
2325
24 self.view.SetScrollbar(cur_height, page_height, total_height, page_height)
26 self.view.SetScrollbar(cur_height, page_height,
27 total_height, page_height)
2528
2629 def on_field_selected(self, dispatcher, field):
2730 offset = byte_addr(field._getAbsoluteAddress())
3437
3538 def set_mappers(self, page_width):
3639 self.thumb_to_offset = lambda thumb_pos: thumb_pos * page_width
37 self.offset_to_thumb = lambda offset: get_page_num(offset = offset,
38 page_width = page_width)
40 self.offset_to_thumb = lambda offset: get_page_num(offset=offset,
41 page_width=page_width)
3942
4043 def on_scrolled(self):
4144 offset = self.thumb_to_offset(self.view.GetThumbPosition())
00 from hachoir.core.tools import alignValue
11 from hachoir.core.error import warning
2
23
34 def byte_addr(bit):
45 return bit // 8
56
7
68 def bit_addr(byte):
79 return byte * 8
10
811
912 def get_file_size(file):
1013 pos = file.tell()
1417
1518 return size
1619
20
1721 def to_hex(data, width=None):
1822 hex_data = ''
1923 for i in range(len(data)):
2024 hex_data += "%02x" % ord(data[i])
21 if width and (i+1)%width==0:
25 if width and (i + 1) % width == 0:
2226 hex_data += '\n'
2327 else:
2428 hex_data += ' '
2529
2630 return hex_data.rstrip(' ')
31
2732
2833 def to_ascii(data, width=None):
2934 ascii_data = ''
3237 ascii_data += data[i]
3338 else:
3439 ascii_data += '.'
35 if width and (i+1)%width==0:
40 if width and (i + 1) % width == 0:
3641 ascii_data += '\n'
3742
3843 return ascii_data
3944
45
4046 def calc_byte_range(start, end):
4147 return byte_addr(start), byte_addr(alignValue(end, 8))
48
4249
4350 def calc_ascii_range(start, end, width=None):
4451 aligned_start, aligned_end = calc_byte_range(start, end)
4855
4956 return char_start, char_end
5057
58
5159 def calc_ascii_pos(byte_pos, width=None):
5260 if width:
53 line_offset = (byte_pos // width) * (width+1)
61 line_offset = (byte_pos // width) * (width + 1)
5462 return line_offset + (byte_pos % width)
5563 return byte_pos
64
5665
5766 def calc_char_range(start, end, width=None):
5867 aligned_start, aligned_end = calc_byte_range(start, end)
5968
6069 char_start = calc_char_pos(aligned_start)
61 char_end = calc_char_pos(aligned_end)-1
70 char_end = calc_char_pos(aligned_end) - 1
6271
6372 return char_start, char_end
6473
74
6575 def calc_char_pos(byte_pos):
6676 return byte_pos * 3
77
6778
6879 def clamp_range(what, begin, end):
6980 what = max(what, begin)
7081 what = min(what, end)
7182 return what
83
7284
7385 def safe_seek(file, where):
7486 try:
8092
8193 return True
8294
95
8396 def get_page_num(offset, page_width):
8497 return offset // page_width
8598
99
86100 def get_page_offset(offset, page_width):
87101 return get_page_num(offset, page_width) * page_width
102
88103
89104 def calc_field_mark(offset, field):
90105 start = field._getAbsoluteAddress() - bit_addr(offset)
00 import os
11 from wx.xrc import XmlResource, XRCCTRL
22
3
34 def get_resource():
4 filename = os.path.join(os.getcwd(), os.path.dirname(__file__), 'hachoir_wx.xrc')
5 filename = os.path.join(
6 os.getcwd(), os.path.dirname(__file__), 'hachoir_wx.xrc')
57 return XmlResource(filename)
8
69
710 def get_frame(name):
811 return get_resource().LoadFrame(None, name)
912
13
1014 def get_child_control(parent, child):
1115 return XRCCTRL(parent, child)
16
1217
1318 def get_menu_bar(name):
1419 return get_resource().LoadMenuBar(name)
1520
21
1622 def get_menu_from_bar(menu_bar, menu_name):
1723 menu_index = menu_bar.FindMenu(menu_name)
18 assert -1 != menu_index, 'cannot find menu ' + menu_name + ' in menu bar ' + menu_bar.GetTitle()
24 assert -1 != menu_index, 'cannot find menu ' + \
25 menu_name + ' in menu bar ' + menu_bar.GetTitle()
1926 return menu_bar.GetMenu(menu_index)
20
11 VERSION = "0.3.1"
22 WEBSITE = 'http://bitbucket.org/haypo/hachoir/wiki/hachoir-wx'
33 LICENSE = 'GNU GPL v2'
4
1111 'Operating System :: OS Independent',
1212 'Natural Language :: English',
1313 'Programming Language :: Python']
14
1415
1516 def main():
1617 if "--setuptools" in sys.argv:
3536 exitcode = 1
3637 if exitcode:
3738 if path.exists(dialog_python):
38 print("Warning: unable to recompile dialog.ui to dialog_ui.py using pyuic4", file=sys.stderr)
39 print('(use command "%s --disable-qt" to disable this warning)' % ' '.join(sys.argv), file=sys.stderr)
39 print(
40 "Warning: unable to recompile dialog.ui to dialog_ui.py using pyuic4", file=sys.stderr)
41 print('(use command "%s --disable-qt" to disable this warning)' %
42 ' '.join(sys.argv), file=sys.stderr)
4043 print(file=sys.stderr)
4144 else:
42 print("ERROR: Unable to compile dialog.ui to dialog_ui.py using pyuic4", file=sys.stderr)
43 print('Use command "%s --disable-qt" to skip hachoir-metadata-qt' % ' '.join(sys.argv), file=sys.stderr)
44 print('pyuic4 is included in the PyQt4 development package', file=sys.stderr)
45 print(
46 "ERROR: Unable to compile dialog.ui to dialog_ui.py using pyuic4", file=sys.stderr)
47 print('Use command "%s --disable-qt" to skip hachoir-metadata-qt' %
48 ' '.join(sys.argv), file=sys.stderr)
49 print('pyuic4 is included in the PyQt4 development package',
50 file=sys.stderr)
4551 sys.exit(1)
4652 PACKAGES.append("hachoir.metadata.qt")
4753
48 hachoir.metadata = load_source("version", path.join("hachoir.metadata", "version.py"))
54 hachoir.metadata = load_source(
55 "version", path.join("hachoir.metadata", "version.py"))
4956 long_description = open('README').read() + open('ChangeLog').read()
5057 install_options = {
5158 "name": hachoir.metadata.PACKAGE,
6168 "packages": PACKAGES,
6269 }
6370 if use_setuptools:
64 install_options["install_requires"] = ["hachoir-core>=1.3", "hachoir-parser>=1.3"]
71 install_options["install_requires"] = [
72 "hachoir-core>=1.3", "hachoir-parser>=1.3"]
6573 install_options["zip_safe"] = True
6674 setup(**install_options)
6775
6876 if __name__ == "__main__":
6977 main()
70
2929 print("Stopping image pool (please wait).")
3030 pool.shutdown()
3131 pool.join()
32
33
2828 # 1 times on 20 tries
2929 TRUNCATE_RATE = 20
3030
31
3132 class UndoMangle:
33
3234 def __init__(self, fuzz):
3335 self.data = fuzz.data.tostring()
3436 self.orig = fuzz.is_original
3739 fuzz.data = array('B', self.data)
3840 fuzz.is_original = self.orig
3941
42
4043 class UndoTruncate:
44
4145 def __init__(self, fuzz):
4246 self.data = fuzz.data
4347 self.orig = fuzz.is_original
4650 fuzz.data = self.data
4751 fuzz.is_original = self.orig
4852
53
4954 class FileFuzzer:
55
5056 def __init__(self, fuzzer, filename):
5157 self.fuzzer = fuzzer
5258 self.verbose = fuzzer.verbose
8591 self.nb_truncate, percent, self.size))
8692
8793 def warning(self, message):
88 print(" %s (%s): %s" % (basename(self.filename), self.nb_extract, message))
94 print(" %s (%s): %s" %
95 (basename(self.filename), self.nb_extract, message))
8996
9097 def info(self, message):
9198 if self.verbose:
111118
112119 # Truncate
113120 self.nb_truncate += 1
114 new_size = randint(MIN_SIZE, len(self.data)-1)
121 new_size = randint(MIN_SIZE, len(self.data) - 1)
115122 self.warning("Truncate #%s (%s bytes)" % (self.nb_truncate, new_size))
116123 self.data = self.data[:new_size]
117124 self.is_original = False
129136 self.undo = None
130137
131138 # Update mangle percent
132 percent = max(self.mangle_percent - MANGLE_PERCENT_INCR, MIN_MANGLE_PERCENT)
139 percent = max(self.mangle_percent -
140 MANGLE_PERCENT_INCR, MIN_MANGLE_PERCENT)
133141 if self.mangle_percent != percent:
134142 self.mangle_percent = percent
135 self.info("Set mangle percent to: %u%%" % int(self.mangle_percent*100))
143 self.info("Set mangle percent to: %u%%" %
144 int(self.mangle_percent * 100))
136145 return True
137146
138147 def extract(self):
177186 def keepFile(self, prefix):
178187 data = self.data.tostring()
179188 uniq_id = generateUniqueID(data)
180 filename="%s-%s" % (uniq_id, basename(self.filename))
189 filename = "%s-%s" % (uniq_id, basename(self.filename))
181190 if prefix:
182191 filename = "%s-%s" % (prefix, filename)
183192 filename = path.join(self.fuzzer.error_dir, filename)
184193 open(filename, "wb").write(data)
185194 print("=> Store file %s" % filename)
186
11
22 if platform == 'win32':
33 from win32process import (GetCurrentProcess, SetPriorityClass,
4 BELOW_NORMAL_PRIORITY_CLASS)
4 BELOW_NORMAL_PRIORITY_CLASS)
55
66 def beNice():
77 process = GetCurrentProcess()
2020
2121 try:
2222 import sha
23
2324 def generateUniqueID(data):
2425 return sha.new(data).hexdigest()
2526 except ImportError:
2829 return generateUniqueID.sequence
2930 generateUniqueID.sequence = 0
3031
32
3133 def getFilesize(file):
3234 file.seek(0, 2)
3335 size = file.tell()
3436 file.seek(0, 0)
3537 return size
36
2727 raise
2828
2929 if not hasattr(fuse, '__version__'):
30 raise RuntimeError("your fuse-py doesn't know of fuse.__version__, probably it's too old.")
30 raise RuntimeError(
31 "your fuse-py doesn't know of fuse.__version__, probably it's too old.")
3132
3233 # This setting is optional, but it ensures that this class will keep
3334 # working after a future API revision
3435 fuse.fuse_python_api = (0, 2)
3536
37
3638 class MyStat(fuse.Stat):
39
3740 def __init__(self):
3841 self.st_mode = 0
3942 self.st_ino = 0
4649 self.st_mtime = 0
4750 self.st_ctime = 0
4851
52
4953 class HelloFS(Fuse):
54
5055 def __init__(self, input_filename, **kw):
5156 Fuse.__init__(self, **kw)
5257 log.setFilename("/home/haypo/fuse_log")
7782 raise
7883
7984 def fieldValue(self, field):
80 return makePrintable(field.display, "ISO-8859-1")+"\n"
85 return makePrintable(field.display, "ISO-8859-1") + "\n"
8186
8287 def getattr(self, path):
8388 st = MyStat()
153158 count = len(fieldset)
154159 if count % 10:
155160 count += 10 - (count % 10)
156 format = "%%0%ud-%%s" % (count//10)
161 format = "%%0%ud-%%s" % (count // 10)
157162
158163 # Create entries
159164 for index, field in enumerate(fieldset):
160 name = format % (1+index, field.name)
165 name = format % (1 + index, field.name)
161166 entry = fuse.Direntry(name)
162167 if field.is_field_set:
163168 entry.type = stat.S_IFDIR
207212 return ''
208213 if offset + size > slen:
209214 size = slen - offset
210 data = data[offset:offset+size]
215 data = data[offset:offset + size]
211216 log.info("=> %s" % repr(data))
212217 return data
213218
217222 def truncate(self, *args):
218223 log.info("truncate(): TODO!")
219224
225
220226 def main():
221 usage="""
227 usage = """
222228 Userspace hello example
223229
224230 """ + Fuse.fusage
00 #!/usr/bin/env python3
11
22 from hachoir.editor import (createEditor as hachoirCreateEditor,
3 NewFieldSet, EditableInteger, EditableString, EditableBytes)
3 NewFieldSet, EditableInteger, EditableString, EditableBytes)
44 from hachoir.stream import FileOutputStream
55 from hachoir.parser import createParser
66 from hachoir.parser.image import PngFile
88 from sys import argv, stdin, stdout, stderr, exit
99 import zlib
1010
11
1112 class InjecterError(Exception):
1213 pass
1314
15
1416 class Injecter:
17
1518 def __init__(self, editor):
1619 self.editor = editor
1720
1821 def getMaxSize(self):
1922 "None: no limit"
2023 raise NotImplementedError()
24
2125 def read(self):
2226 raise NotImplementedError()
27
2328 def write(self, data):
2429 raise NotImplementedError()
30
2531 def saveInto(self, filename):
2632 output = FileOutputStream(filename)
2733 self.editor.writeInto(output)
34
2835
2936 def computeCRC32(data):
3037 "Compute CRC-32 of data string. Result is a positive integer."
3441 else:
3542 return 1 << 32
3643
44
3745 class PngInjecter(Injecter):
3846 MAGIC = "HACHOIR"
3947
4048 def getMaxSize(self):
4149 return None
50
4251 def read(self):
4352 for field in self.editor:
4453 if field.name.startswith("text[") \
45 and field["keyword"].value == self.MAGIC:
54 and field["keyword"].value == self.MAGIC:
4655 return field["text"].value
4756 return None
4857
5261 size = len(data)
5362 crc = computeCRC32(tag + data)
5463 chunk = NewFieldSet(self.editor, "inject[]")
55 chunk.insert( EditableInteger(chunk, "size", False, 32, size) )
56 chunk.insert( EditableBytes(chunk, "tag", tag) )
57 chunk.insert( EditableBytes(chunk, "content", data) )
58 chunk.insert( EditableInteger(chunk, "crc32", False, 32, crc) )
64 chunk.insert(EditableInteger(chunk, "size", False, 32, size))
65 chunk.insert(EditableBytes(chunk, "tag", tag))
66 chunk.insert(EditableBytes(chunk, "content", data))
67 chunk.insert(EditableInteger(chunk, "crc32", False, 32, crc))
5968 self.editor.insertBefore("end", chunk)
69
6070
6171 class MpegAudioInjecter(Injecter):
6272 MAX_PACKET_SIZE = 2048 # bytes between each frame
90100 print("Packet size: %s" % self.packet_size)
91101 print("Check input message")
92102 if "\xff" in data:
93 raise InjecterError("Sorry, MPEG audio injecter disallows 0xFF byte")
103 raise InjecterError(
104 "Sorry, MPEG audio injecter disallows 0xFF byte")
94105
95106 # print "Check message size"
96107 # maxbytes = self.getMaxSize()
106117 padding = data[index:index + self.packet_size]
107118 name = "frame[%u]" % field_index
108119 print("Insert %s before %s" % (len(padding), name))
109 output.insertAfter(name, EditableString(output, "padding[]", "fixed", padding) )
120 output.insertAfter(name, EditableString(
121 output, "padding[]", "fixed", padding))
110122 index += self.packet_size
111123 field_index += 2
112124
119131 PngFile: PngInjecter,
120132 MpegAudioFile: MpegAudioInjecter,
121133 }
134
122135
123136 def main():
124137 if len(argv) != 2:
152165
153166 if __name__ == "__main__":
154167 main()
155
22 from hachoir.parser.container.swf import SOUND_CODEC_MP3
33 from sys import stderr, exit, argv
44
5
56 class JpegExtractor:
7
68 def __init__(self):
79 self.jpg_index = 1
810 self.snd_index = 1
2729 if 32 < header.size:
2830 if self.verbose:
2931 print("Use JPEG table: %s" % header.path)
30 header = field.root.stream.readBytes(header.absolute_address, (header.size-16)//8)
32 header = field.root.stream.readBytes(
33 header.absolute_address, (header.size - 16) // 8)
3134 else:
3235 header = ""
3336 else:
5053 assert data[:1] == b'\xFF'
5154 output.write(data)
5255 elif field.name.startswith("sound_blk") \
53 and "music_data" in field:
56 and "music_data" in field:
5457 data = field["music_data"].value
5558 if data:
5659 assert data[0] == '\xFF'
8487 self.extractFormat2(field)
8588
8689 # Extract sound
87 #self.extractSound(parser)
90 # self.extractSound(parser)
8891 self.extractSound2(parser)
8992
9093 # Does it extract anything?
9497 print("No sound found.")
9598
9699 JpegExtractor().main()
97