import os.path import math def tryparse_int(value): try: return int(value) except ValueError: return None def do_dich(name): pi = load(name) b = "0110" x = 14 d = 25 n = 3 while n < len(pi): if x > d: x -= d b += "1" else: b += "0" x = 10 * x + int(str(pi[n])) d *= 5 n += 1 return b def load(name): d = "" with open(name) as f: for line in f: d = line.strip() break return d def save(name, bi): with open(name, mode='w') as f: f.write(bi) def verify_dich(b): x = 4.0 n = float(0) i = 0 while i < len(b) and x > 0: if b[i] == '1': n += x x /= 2.0 i += 1 print(n) return n == 3.141592653589793 def save_byte(name, data): with open(name, mode='wb') as f: f.write(bytearray(data)) def n2b(num, nbyte=4): b = [] for i in range(nbyte): b += [num % 256] num //= 256 return b def print_bytes(data): for i in range(len(data) // 16 + 1): for j in range(16): if i * 16 + j >= len(data): print(" . ", end='') else: print("{:02x} ".format(data[i * 16 + j]), end='') print() def save_bmp(name, data, width): # fix data size height = len(data) // (width * 3) if len(data) > height * width * 3: data = data[0:height * width * 3] # fix line width not %4 line_width = (width * 3) % 4 if line_width != 0: tail = (3 - line_width) * [0] + [255] data2 = [] for i in range(height): data2 += data[i * width * 3:(i + 1) * width * 3] + tail data = data2 header = [0] * 54 header[0:2] = [66, 77] # BM header[2:6] = n2b(len(data) + 54) # file size # 4 bytes application reserved header[10:14] = n2b(54) # offset of data header[14:18] = n2b(40) # size of header header[18:22] = n2b(width) # width header[22:26] = n2b(height) # height header[26:28] = n2b(1, 2) # color panes header[28:30] = n2b(24, 2) # color depth # 4 bytes compression method # 4 bytes optional image size header[38:42] = n2b(3780) # horizontal resolution header[42:46] = n2b(3780) # vertical resolution # 4 bytes number of colors # 4 bytes number of important colors print_bytes(header) with open(name, mode='wb') as f: f.write(bytearray(header + data)) def save_wav(name, data, channels, freq, sampling): header_size = 44 header = [0] * header_size bytesPerBloc = int(channels * sampling / 8) dataSize = len(data) mod = dataSize % bytesPerBloc if mod > 0: dataSize -= mod # file info header[0:4] = [0x52, 0x49, 0x46, 0x46] # "RIFF" header[4:8] = n2b(header_size + dataSize - 8) # file size - 8bytes header[8:12] = [0x57, 0x41, 0x56, 0x45] # "WAVE" # audio format header[12:16] = [0x66, 0x6D, 0x74, 0x20] header[16:20] = n2b(16) header[20:22] = n2b(1) # PCM format header[22:24] = n2b(channels) # nb of channels header[24:28] = n2b(freq) # frequency 11025, 22050, 44100, 48000, 96000 header[28:32] = n2b(freq * bytesPerBloc) # BytePerSec header[32:34] = n2b(bytesPerBloc) # BytePerBloc header[34:36] = n2b(sampling) # BitsPerSample 8, 16, 24 # data header[36:40] = [0x64, 0x61, 0x74, 0x61] # "data" header[40:44] = n2b(dataSize) print_bytes(header) with open(name, mode='wb') as f: f.write(bytearray(header + data[:dataSize])) def get_data(b): return [int(b[n * 8:(n + 1) * 8], 2) for n in range(int(len(b) / 8))] def get_bw_bmp_data(b, width): data = [] for n in range(width * width): c = 0 if b[n] == '1': c = 255 data += [c, c, c] # grey return data def get_grey_bmp_data(b, width): data = [] for n in range(width * width): c = b[n * 8:(n + 1) * 8] data += [int(c, 2), int(c, 2), int(c, 2)] # grey return data DIGIT_FILE = "pi1000000.txt" BIN_FILE = "pi1000000bin.txt" bpi = "" if os.path.isfile(BIN_FILE): print("loading dichotomy...") bpi = load(BIN_FILE) elif os.path.isfile(DIGIT_FILE): print("computing dichotomy (this might take a while)...") bpi = do_dich(DIGIT_FILE) print("saving dichotomy...") save(BIN_FILE, bpi) else: print(DIGIT_FILE, "was not found") exit(1) print(len(bpi), "bits of dichotomy in memory") print() print("verifying dichotomy...") if not (verify_dich(bpi)): print("could not verify dichotomy you may delete the file ", BIN_FILE) exit(1) print() print("modes :") print("1:binary file") print("2:black & white bitmap file") print("3:grey scale bitmap file") print("4:wave file") mode = tryparse_int(input("select a mode : ")) print() if mode == 1: defname = "pi_bin" name = input("enter file name : [{}] ".format(defname)).strip() if len(name) == 0: name = defname print("getting data...") data = get_data(bpi) print("saving to file '" + name + "' ...") save_byte(name, data) print("saved to file '" + name + "'") elif mode == 2: maxw = int(math.sqrt(len(bpi))) width = tryparse_int(input("enter image width (max:{0}): [{0}] ".format(maxw))) if width is None or width > maxw or width < 1: width = maxw defname = "pi_bw_{}.bmp".format(width) name = input("enter file name : [{}] ".format(defname)).strip() if len(name) == 0: name = defname if not (name.endswith(".bmp")): name += ".bmp" print("getting data...") data = get_bw_bmp_data(bpi, width) print("saving to file '" + name + "' ...") save_bmp(name, data, width) print("saved to file '" + name + "'") elif mode == 3: maxw = int(math.sqrt(len(bpi)) / 8) width = tryparse_int(input("enter image width (max:{0}): [{0}] ".format(maxw))) if width is None or width > maxw or width < 1: width = maxw defname = "pi_grey_{}.bmp".format(width) name = input("enter file name : [{}] ".format(defname)).strip() if len(name) == 0: name = defname if not (name.endswith(".bmp")): name += ".bmp" print("getting data...") data = get_grey_bmp_data(bpi, width) print("saving to file '" + name + "' ...") save_bmp(name, data, width) print("saved to file '" + name + "'") elif mode == 4: channels = tryparse_int(input("number of channels (max:6) : [1] ")) if channels is None or channels <= 0: channels = 1 if channels > 6: channels = 6 freq = tryparse_int(input("frequency (1->11k, 2->22k, 3->44.1k, 4->48k 5->96k) : [3] ")) if freq is None: freq = 3 if freq <= 0: freq = 1 if freq > 5: freq = 5 freq = int(11025 * math.pow(2, freq - 1)) bps = tryparse_int(input("bits per sample (1->8, 2->16, 3->24) : [1] ")) if bps is None or bps <= 0: bps = 1 if bps > 3: bps = 6 bps *= 8 defname = "pi_{}_{}_{}.wav".format(channels, bps, int(freq / 1000)) name = input("enter file name : [{}] ".format(defname)).strip() if len(name) == 0: name = defname if not (name.endswith(".wav")): name += ".wav" print("getting data...") data = get_data(bpi) print("saving to file '" + name + "' ...") save_wav(name, data, channels, freq, bps) print("saved to file '" + name + "'") print() print("goodbye")