]>
vgcfreebox.myrthtech.pt Git - ue-ccd-compressaodeimagensbinarias.git/blob - lz78/lz_78_xor.py
4 ########################################################################################
5 # python lz_78_xor.py <d/c> <caminho_para_o_ficheiro_original>
10 # Os ficheiros gerados ficarão na mesma pasta que o script
11 ########################################################################################
13 def xor(bitstream
, largura
, altura
):
15 for i
in range(altura
):
16 linha
= [int(b
) for b
in bitstream
[i
* largura
: (i
+ 1) * largura
]]
20 # A primeira linha mantém-se igual (não tem linha anterior)
21 nova_imagem
+= "".join(map(str, matriz
[0]))
23 for i
in range(1, altura
):
25 for j
in range(largura
):
26 res
= matriz
[i
][j
] ^ matriz
[i
-1][j
]
27 nova_linha
.append(str(res
))
28 nova_imagem
+= "".join(nova_linha
)
32 def descodificar_xor(bitstream_transformado
, largura
, altura
):
34 for i
in range(altura
):
35 linha
= [int(b
) for b
in bitstream_transformado
[i
* largura
: (i
+ 1) * largura
]]
36 matriz_temp
.append(linha
)
40 matriz_original
.append(matriz_temp
[0])
42 for i
in range(1, altura
):
44 for j
in range(largura
):
45 pixel_original
= matriz_temp
[i
][j
] ^ matriz_original
[i
-1][j
]
46 linha_recuperada
.append(pixel_original
)
47 matriz_original
.append(linha_recuperada
)
50 for linha
in matriz_original
:
51 bitstream_final
+= "".join(map(str, linha
))
53 return bitstream_final
55 def lz78_compression(image
):
65 if (symbol
+ i
) in dictionary
.values():
70 dictionary
[len(dictionary
)] = i
72 output
.append([list(dictionary
.keys())[list(dictionary
.values()).index(symbol
)], i
])
73 dictionary
[len(dictionary
)] = symbol
+ i
77 idx
= list(dictionary
.keys())[list(dictionary
.values()).index(symbol
)]
78 output
.append([idx
, ""])
80 return output
, dictionary
82 def lz78_decompression(compressed_image
):
89 for i
in compressed_image
:
90 output
+= dictionary
.get(i
[0]) + i
[1]
91 dictionary
[len(dictionary
)] = dictionary
.get(i
[0]) + i
[1]
95 def clean_image_data(image_data
):
99 for line
in image_data
:
101 line
= line
.replace(" ", "")
102 if not line
or line
.startswith('#'):
108 def chunkstring(string
, length
):
109 return [string
[i
: length
+i
] for i
in range(0, len(string
), length
)]
112 if sys
.argv
[1] == "c":
114 with open(sys
.argv
[2], "r") as image
:
115 lines
= image
.readlines()
116 image_size
= lines
[1].split()
118 if lines
[0].strip() != 'P1':
119 raise ValueError("This is not a pbm file")
121 clean_text
= clean_image_data(lines
[2:]) #Limpa os espaços em branco para comprimir melhor
123 clean_text
= xor(clean_text
, int(image_size
[0]), int(image_size
[1]))
125 output
, dic
= lz78_compression(clean_text
)
127 print(f
"Output: {output}\n")
128 print(f
"Dictionary: {dic}")
130 #Compressão em texto (human-readable)
131 with open(sys
.argv
[2] + "_compressed", "w") as save_file
:
132 save_file
.write(f
"{output} \n{image_size[0]} {image_size[1]}")
134 #Compressão em binário (compressão "a sério")
135 with open(sys
.argv
[2] + ".bin", "wb") as save_file
:
136 largura
= int(image_size
[0])
137 altura
= int(image_size
[1])
138 save_file
.write(struct
.pack('II', largura
, altura
))
140 for indice
, simbolo
in output
:
141 simbolo_byte
= ord(simbolo
) if simbolo
!= "" else 0
142 save_file
.write(struct
.pack('HB', indice
, simbolo_byte
))
144 elif sys
.argv
[1] == "d":
146 #Descomprimir do ficheiro de texto
147 with open(sys
.argv
[2] + "_compressed", "r") as image
:
148 lines
= image
.readlines()
150 compressed_image
= eval(lines
[0])
151 image_size
= lines
[1]
152 largura
= int(lines
[1].split(" ")[0])
153 altura
= int(lines
[1].split(" ")[1])
155 output
= lz78_decompression(compressed_image
)
157 output
= descodificar_xor(output
, largura
, altura
)
159 chuncked_output
= chunkstring(output
, largura
)
161 with open(sys
.argv
[2] + "_decompressed", "w") as save_file
:
162 save_file
.write(f
"P1\n{image_size}\n")
163 for line
in chuncked_output
:
164 save_file
.write(f
"{line}\n")
166 #Descomprimir do binário
167 with open(sys
.argv
[2] + ".bin", "rb") as image
:
168 header
= image
.read(8)
169 largura
, altura
= struct
.unpack('II', header
)
171 compressed_image_bin
= []
173 chunk
= image
.read(3)
176 indice
, simbolo_byte
= struct
.unpack('HB', chunk
)
177 simbolo
= chr(simbolo_byte
) if simbolo_byte
!= 0 else ""
178 compressed_image_bin
.append([indice
, simbolo
])
180 output
= lz78_decompression(compressed_image_bin
)
182 output
= descodificar_xor(output
, largura
, altura
)
184 chuncked_output
= chunkstring(output
, largura
)
186 with open(sys
.argv
[2]+ "_bin_decompressed", "w") as save_file
:
187 save_file
.write(f
"P1\n{largura} {altura}\n")
188 for line
in chuncked_output
:
189 save_file
.write(f
"{line}\n")