|
|
|
@ -45,5 +45,66 @@ void extract(string picture_path, string output_path) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EXIT_ON_TRUE(fclose(fp), SYSTEM_CALL_FAIL); |
|
|
|
|
free(image); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void clean(string picture_path, string output_path) { |
|
|
|
|
|
|
|
|
|
picture image = 0; |
|
|
|
|
u32 width, height; |
|
|
|
|
|
|
|
|
|
EXIT_ON_TRUE(lodepng_decode32_file(&image, &width, &height, picture_path), LODEPNG_ERROR); |
|
|
|
|
|
|
|
|
|
u32 pixels_nb = width * height; // nombre de pixels
|
|
|
|
|
u32 lsb = image[0] & 7u; // nombre de bits occupes par channnel
|
|
|
|
|
byte mask = ((byte) (0xffu << lsb)) & 0xff; |
|
|
|
|
|
|
|
|
|
image[0] &= ~7u; |
|
|
|
|
|
|
|
|
|
for (u32 i = 1; (i < pixels_nb * 4); i++) { |
|
|
|
|
if (i % 4 == 3) continue; // on skip le canal alpha
|
|
|
|
|
image[i] &= mask; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EXIT_ON_TRUE(lodepng_encode32_file(output_path, image, width, height), LODEPNG_ERROR); |
|
|
|
|
free(image); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void get_info(byte *lsb, u32 *length, string picture_path) { |
|
|
|
|
picture image = 0; |
|
|
|
|
u32 width, height; |
|
|
|
|
|
|
|
|
|
EXIT_ON_TRUE(lodepng_decode32_file(&image, &width, &height, picture_path), LODEPNG_ERROR); |
|
|
|
|
|
|
|
|
|
u32 pixels_nb = width * height; // nombre de pixels
|
|
|
|
|
*lsb = image[0] & 7u; // nombre de bits occupes par channnel
|
|
|
|
|
u32 real_length = 0; // reelle longueur des donnees a lire
|
|
|
|
|
u32 read_bytes = 0; // nombre d'octets lus
|
|
|
|
|
|
|
|
|
|
byte data = 0; // buffer de lecture d'un octet
|
|
|
|
|
byte mask = (byte) (1 << (*lsb - 1)); // masque permettant de lire le plus haut bit dissimule
|
|
|
|
|
byte current_mask; // contient les decalages a droite du masque
|
|
|
|
|
byte buffer_fill = 0; // remplissage du buffer
|
|
|
|
|
|
|
|
|
|
for (u32 i = 1; (i < pixels_nb * 4) && read_bytes < EMBEDDED_HEADER_SIZE; i++) { |
|
|
|
|
if (i % 4 == 3) continue; // on skip le canal alpha
|
|
|
|
|
u32 j; |
|
|
|
|
for (j = 0, current_mask = mask; j < *lsb; ++j, current_mask >>= 1) { |
|
|
|
|
data = (data << 1) | (image[i] & current_mask) >> (*lsb - (j + 1)); // on ajoute le bit courant au buffer
|
|
|
|
|
if (++buffer_fill == 8) { // si on a recupere un octet complet
|
|
|
|
|
if (read_bytes < LEN_HEADER_SIZE) { // si on est en train de lire le header
|
|
|
|
|
real_length = (real_length << 8) | data; |
|
|
|
|
if (read_bytes == 3) { |
|
|
|
|
*length = real_length + EMBEDDED_HEADER_SIZE; |
|
|
|
|
free(image); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
buffer_fill = 0; |
|
|
|
|
read_bytes++; // dans tous les cas un octet de plus a ete lu
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(image); |
|
|
|
|
} |