summaryrefslogtreecommitdiff
path: root/mybinview.py
blob: 5064013299990c97f3a99f0f3805a80779a44193 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python

# RaidGuessFS, a FUSE pseudo-filesystem to guess RAID parameters of a damaged device
# Copyright (C) 2015 Ludovic Pouzenc <ludovic@pouzenc.fr>
#
# This file is part of RaidGuessFS.
#
# RaidGuessFS is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RaidGuessFS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with RaidGuessFS. If not, see <http://www.gnu.org/licenses/>

import struct

class MyBinView():
    """"Auxiliary class, dumping binary data as image files"""

    def __init__(self, *args, **kwargs):
        self.bmp_start_offset=0
        self.bmp_height=4096
        self.bmp_width=1024

        self.bmp_pixeldata_start=0
        self.bmp_size=0
        self.bmp_header=bytearray()

    def get_bmp_start_offset(self):
        return self.bmp_start_offset

    def get_bmp_height(self):
        return self.bmp_height

    def get_bmp_width(self):
        return self.bmp_width

    def set_bmp_start_offset(self, new_bmp_start_offset):
        """Offset to choose which fiel part you want to render as image"""
        self.bmp_start_offset = new_bmp_start_offset

    def set_bmp_width(self, new_bmp_width):
        """Update the BMP (yes bitmap images) width in pixels"""
        self.bmp_width = new_bmp_width / 4 * 4
        self.refresh_bmp()
        self.refresh_disks_dentries()

    def set_bmp_height(self, new_bmp_height):
        """Update the BMP (yes bitmap images) height in pixels"""
        self.bmp_height = new_bmp_height
        self.refresh_bmp()
        self.refresh_disks_dentries()

    def refresh_bmp(self):
        """Update the BMP headers accroding to bitmap settings"""
        bmp_header_fmt = struct.Struct('< 2s I x x x x I I i i H H I I i i I I')

        bitmap_pixel_count = self.bmp_width * self.bmp_height
        # From https://en.wikipedia.org/wiki/BMP_file_format
        bitmap_magic='BM'
        dib_size=40 # BITMAPINFOHEADER (Windows NT, 3.1x or later)
        bitmap_bpp=8
        bitmap_compress=0
        imagehres=2835 # pixels per meter
        imagevres=2835
        palette_size=256
        palette_start = bmp_header_fmt.size

        self.bmp_pixeldata_start = palette_start + palette_size*4
        self.bmp_size = self.bmp_pixeldata_start + bitmap_pixel_count
        self.bmp_header = bytearray(self.bmp_pixeldata_start)
        bmp_header_fmt.pack_into(self.bmp_header,0,
                'BM', self.bmp_size, self.bmp_pixeldata_start, dib_size,
                self.bmp_width, self.bmp_height, 1, bitmap_bpp, bitmap_compress, 
                bitmap_pixel_count, imagehres, imagevres, palette_size, palette_size
                )

        for i in range(palette_size):
            struct.pack_into('< B B B B', self.bmp_header, bmp_header_fmt.size + i*4, i,i,i,0) # All shades of gray in RGBA

    def read(self, fd, offset, size):
        if offset < self.bmp_pixeldata_start:
            data = str(self.bmp_header[offset:offset+size-1])
            if offset + size > self.bmp_pixeldata_start:
                data += self.read(fd, self.bmp_pixeldata_start, size - self.bmp_pixeldata_start)
            return data
        else:
            fd.seek(self.bmp_start_offset + offset - self.bmp_pixeldata_start)
            return fd.read(size)