|
|
|
@ -1,9 +1,9 @@
|
|
|
|
|
#include "hide.h" |
|
|
|
|
|
|
|
|
|
void hide(string picture_path, string file_path, string output_path) { |
|
|
|
|
void hide_lsb(string picture_path, string file_path, string output_path, byte forced_lsb) { |
|
|
|
|
|
|
|
|
|
u32 width, height, size; |
|
|
|
|
u32 lsb_size; // nombre de bits occupes par channnel
|
|
|
|
|
u32 lsb; // nombre de bits occupes par channnel
|
|
|
|
|
u32 w_index = 1; // nombre de groupes de bits écrits
|
|
|
|
|
|
|
|
|
|
picture image = 0; |
|
|
|
@ -25,14 +25,16 @@ void hide(string picture_path, string file_path, string output_path) {
|
|
|
|
|
|
|
|
|
|
if (fclose(fp)) exit(3); |
|
|
|
|
|
|
|
|
|
if ((lsb_size = (size * 8 + HEADER_SIZE_BITS) / (width * height * 3 - 1) + |
|
|
|
|
((size * 8 + HEADER_SIZE_BITS) % (width * height * 3 - 1) != 0)) > 7) |
|
|
|
|
if ((lsb = (size * 8 + HEADER_SIZE_BITS) / (width * height * 3 - 1) + |
|
|
|
|
((size * 8 + HEADER_SIZE_BITS) % (width * height * 3 - 1) != 0)) > 7) |
|
|
|
|
exit(DATA_DOESNT_FIT); |
|
|
|
|
//printf("%d\n", lsb_size);
|
|
|
|
|
//printf("%d\n", lsb);
|
|
|
|
|
|
|
|
|
|
lsb = (forced_lsb && forced_lsb >= lsb) ? forced_lsb : lsb; |
|
|
|
|
|
|
|
|
|
// premiere partie header (3 bits)
|
|
|
|
|
image[0] = (byte) ((image[0] & 0xf8) | lsb_size); |
|
|
|
|
u32 mask = gen_mask(lsb_size); |
|
|
|
|
image[0] = (byte) ((image[0] & 0xf8) | lsb); |
|
|
|
|
u32 mask = gen_mask(lsb); |
|
|
|
|
|
|
|
|
|
// deuxieme partie header (32 bits)
|
|
|
|
|
for (u32 i = 0, m = 0xff000000; i < LEN_HEADER_SIZE; ++i, m >>= 8) |
|
|
|
@ -49,9 +51,9 @@ void hide(string picture_path, string file_path, string output_path) {
|
|
|
|
|
for (u32 j = 0, mk = 0x80; j < 8; ++j, mk >>= 1) { |
|
|
|
|
// on decale le contenu du buffer pour liberer le dernier bit
|
|
|
|
|
// on ecrit le bit courant dans le buffer
|
|
|
|
|
write_buffer = (byte) (write_buffer << 1 | (to_hide[i] & mk) >> (8 - j - 1)); |
|
|
|
|
write_buffer = (byte) (write_buffer << 1u | (byte) (to_hide[i] & mk) >> (8u - j - 1u)); |
|
|
|
|
buffer_fill++; // on incremente le nombre d'elements dans le buffer
|
|
|
|
|
if (buffer_fill == lsb_size) { // si on a assez de donnees dans le buffer pour ecrire un canal de pixel
|
|
|
|
|
if (buffer_fill == lsb) { // si on a assez de donnees dans le buffer pour ecrire un canal de pixel
|
|
|
|
|
// formule pour retrouver le canal en evitant les alpha
|
|
|
|
|
// on insere les donnees du buffer dans l'image
|
|
|
|
|
image[w_index + w_index / 3] = (byte) ((image[w_index + w_index / 3] & mask) | |
|
|
|
@ -64,17 +66,17 @@ void hide(string picture_path, string file_path, string output_path) {
|
|
|
|
|
|
|
|
|
|
if (buffer_fill) { // si le buffer n'est pas vide en fin d'execution on l'ecrit dans l'image
|
|
|
|
|
image[w_index + w_index / 3] = |
|
|
|
|
(byte) (image[w_index + w_index / 3] & mask | write_buffer << (lsb_size - buffer_fill) & ~mask); |
|
|
|
|
(byte) ((image[w_index + w_index / 3] & mask) | (write_buffer << (lsb - buffer_fill) & ~mask)); |
|
|
|
|
w_index++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (u32 i = w_index + w_index / 3; i < width * height * 4; ++i) { // remplissage du reste de l'image avec du bruit
|
|
|
|
|
if (i % 4 == 3) continue; // on skip le canal alpha
|
|
|
|
|
image[i] = (byte) ((image[i] & mask) | (rand() & (~mask))); |
|
|
|
|
image[i] = (byte) ((image[i] & mask) | ((byte) rand() & (~mask))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EXIT_ON_TRUE(lodepng_encode32_file(output_path, image, width, height), LODEPNG_ERROR); |
|
|
|
|
|
|
|
|
|
free(to_hide); |
|
|
|
|
free(image); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|