]>
vgcfreebox.myrthtech.pt Git - ue-ccd-compressaodeimagensbinarias.git/blob - lz78/lz_78.py
4 ########################################################################################
5 # python lz_78.py <d/c> <caminho_para_o_ficheiro_original>
10 # Os ficheiros gerados ficarão na mesma pasta que o script
11 ########################################################################################
13 def lz78_compression(image
):
23 if (symbol
+ i
) in dictionary
.values():
28 dictionary
[len(dictionary
)] = i
30 output
.append([list(dictionary
.keys())[list(dictionary
.values()).index(symbol
)], i
])
31 dictionary
[len(dictionary
)] = symbol
+ i
35 idx
= list(dictionary
.keys())[list(dictionary
.values()).index(symbol
)]
36 output
.append([idx
, ""])
38 return output
, dictionary
40 def lz78_decompression(compressed_image
):
47 for i
in compressed_image
:
48 output
+= dictionary
.get(i
[0]) + i
[1]
49 dictionary
[len(dictionary
)] = dictionary
.get(i
[0]) + i
[1]
53 def clean_image_data(image_data
):
57 for line
in image_data
:
59 line
= line
.replace(" ", "")
60 if not line
or line
.startswith('#'):
66 def chunkstring(string
, length
):
67 return [string
[i
: length
+i
] for i
in range(0, len(string
), length
)]
70 if sys
.argv
[1] == "c":
72 with open(sys
.argv
[2], "r") as image
:
73 lines
= image
.readlines()
76 if lines
[0].strip() != 'P1':
77 raise ValueError("This is not a pbm file")
79 clean_text
= clean_image_data(lines
[2:]) #Limpa os espaços em branco para comprimir melhor
81 output
, dic
= lz78_compression(clean_text
)
83 print(f
"Output: {output}\n")
84 print(f
"Dictionary: {dic}")
86 #Compressão em texto (human-readable)
87 with open(sys
.argv
[2] + "_compressed", "w") as save_file
:
88 save_file
.write(f
"{output} \n{image_size}")
90 #Compressão em binário (compressão "a sério")
91 with open(sys
.argv
[2] + ".bin", "wb") as save_file
:
92 largura
= int(image_size
.split()[0])
93 altura
= int(image_size
.split()[1])
94 save_file
.write(struct
.pack('II', largura
, altura
))
96 for indice
, simbolo
in output
:
97 simbolo_byte
= ord(simbolo
) if simbolo
!= "" else 0
98 save_file
.write(struct
.pack('HB', indice
, simbolo_byte
))
100 elif sys
.argv
[1] == "d":
102 #Descomprimir do ficheiro de texto
103 with open(sys
.argv
[2] + "_compressed", "r") as image
:
104 lines
= image
.readlines()
106 compressed_image
= eval(lines
[0])
107 image_size
= lines
[1]
108 length
= int(lines
[1].split(" ")[0])
110 output
= lz78_decompression(compressed_image
)
112 chuncked_output
= chunkstring(output
, length
)
114 with open(sys
.argv
[2] + "_decompressed", "w") as save_file
:
115 save_file
.write(f
"P1\n{image_size}")
116 for line
in chuncked_output
:
117 save_file
.write(f
"{line}\n")
119 #Descomprimir do binário
120 with open(sys
.argv
[2] + ".bin", "rb") as image
:
121 header
= image
.read(8)
122 largura
, altura
= struct
.unpack('II', header
)
124 compressed_image_bin
= []
126 chunk
= image
.read(3)
129 indice
, simbolo_byte
= struct
.unpack('HB', chunk
)
130 simbolo
= chr(simbolo_byte
) if simbolo_byte
!= 0 else ""
131 compressed_image_bin
.append([indice
, simbolo
])
133 output
= lz78_decompression(compressed_image_bin
)
135 chuncked_output
= chunkstring(output
, largura
)
137 with open(sys
.argv
[2]+ "_bin_decompressed", "w") as save_file
:
138 save_file
.write(f
"P1\n{largura} {altura}\n")
139 for line
in chuncked_output
:
140 save_file
.write(f
"{line}\n")