salut,
je suis toujours sur mon travail de stegano et j'ai encor un problème. j'ai donc 2 fichiers, le source qui est l'image et le dest qui sera l'image avec le texte caché.
je trouve bien les bits de chaque lettre de la chaine a cacher grace à l afonction getBit puis je dois remplacer le bit de poids faible de chaque octet de l'image par ceux du texte et que j'ai modifié tous les octets nécessaires pour cacher le texte je suppose que je dois finir de lire l'image depuis l'octet du dernier bit inscrit et jusqu'à la fin du fichier et sauver ça dns mon fichier dest mais c'est là que je ne sais pas comment faire.si quelqu'un pourrait m'aider?
et comment faire pour qu'a la fin le fichier dest devienne source?
merci de vos réponses
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
int getBit(unsigned char *,int );
int hideMessage(char*,char*,char*);
int isBitmapHeaderCorrect(FILE *,struct BMP_HEADER *);
int loadBitmapHeader(FILE *,struct BMP_HEADER *);
int saveBitmapDatas(FILE * , BMP_HEADER *,unsigned char * );
unsigned char * loadBitmapDatas(FILE * , BMP_HEADER * header,int);
struct BMP_HEADER
{
char Identifier [2];
long FileSize;
long Reserved;
long DataOffset;
long HeaderSize;
long Width;
long Height;
short Planes;
short BitPerPixels;
long Compression;
long BitmapDataSize;
long HResolution;
long VResolution;
long Colors;
long ImportantColors;
};
void main()
{
struct BMP_HEADER binaire;
int retour, taille,nb_caract_max;
char menu;
char * message;
unsigned char *octet;
FILE * fichier;
char*dest = (char*)malloc(20 * sizeof(char));strcpy(dest,"c:\\img_modif.bmp");
gotoxy(12,26);printf("entrez la taille du nom et emplacement du fichier:");scanf("%d",&taille);fflush(stdin);
char * source = (char*)malloc(taille+5 * sizeof(char));gotoxy(15,27);printf("entrez le nom et emplacement du fichier:");gets(source);
strcat(source,".bmp");
fichier = fopen(source,"r+b");
clrscr();
do
{
nb_caract_max = ((binaire.BitmapDataSize - binaire.HeaderSize)/8)-8;
gotoxy(27,1);printf(" __________________________");
gotoxy(27,2);printf("| |");
gotoxy(27,3);printf("| fichier BMP |");
gotoxy(27,4);printf("| ====================== |");
gotoxy(27,5);puts ("|__________________________|");
printf("\n\n Quelle opération voulez-vous faire?\n\n");
puts(" <C>acher du texte");
puts(" <D>écouvrir du texte");
puts(" <Q>uitter");
do
menu = toupper(getch());
while(!strchr("CQ", menu));
switch(menu)
{
case 'C' : do
{
printf("entrez la taille de votre texte:");scanf("%i",&taille);
}
while(taille > nb_caract_max);
message = (char*)malloc(taille * sizeof(char));fflush(stdin);
printf("entrez le message que vous voulez cacher:");gets(message);
hideMessage(source, dest, message);break;
case 'Q' : puts("fin");exit(0); break;
}
}
while(menu != 'Q');
free(dest);
free(source);
free(message);
}
//cette fonction donne la bit cpt_bit du caractère cpt_carac
int getBit(char *message,int cpt_bit,int cpt_carac)
{
int binaire;
char valeur;
char tmp = message[cpt_carac];
binaire = pow(2,cpt_bit);
valeur = tmp & binaire;
valeur = valeur >> cpt_bit;
return(valeur);
}
//dans cette fonction on doit modifier le bit de poids faible de chaque octet par celui que renvoi la fonction getBIt
//il y a autant de bit que de (lettre +1)*8
int hideMessage(char*source,char*dest,char*message)
{
FILE * fichier_source = fopen(source,"r+b"); //fichier contenant l'image
FILE * fichier_dest = fopen(dest,"w+b"); //fichier qui contiendra l'image avec le texte dissimuler
BMP_HEADER entete;
unsigned char *octet;
int i = 0,cpt_carac,cpt_bit;
char bit;
loadBitmapHeader(fichier_source,&entete);
fwrite(&entete,sizeof(entete),1,fichier_dest);
for (cpt_carac = 0; cpt_carac < (1 + strlen (message)); cpt_carac++)
{
for(cpt_bit = 7;cpt_bit >= 0;cpt_bit--)
{
bit = getBit(message,cpt_bit,cpt_carac);
octet = loadBitmapDatas(fichier_source, &entete,i);
*octet = *octet & 254;
*octet = *octet + bit;
saveBitmapDatas(fichier_dest, &entete, octet);
i++;
}
}
return 1;
}
//fonction vérifiant si c'est bien une BMP 24bits non compressée
int isBitmapHeaderCorrect(FILE *fichier,struct BMP_HEADER *header)
{
long largeur, hauteur,taille;
if(header->Identifier[0] != 'B')
return 0;
if(header->Identifier[1] != 'M')
return 0;
if(header->Compression != 0)
{
printf("la compression est de:%i\n",header->Compression);
return 0;
}
if(header->BitPerPixels != 24)
{
printf("les bits par pixels sont de:%d",header->BitPerPixels);
return 0;
}
largeur = header->Width; hauteur = header->Height;
taille = largeur * hauteur * 3;
if(header->BitmapDataSize != taille)
return 0;
return 1;
}
//fonction chargeant les infos sur l'image dans la structure
int loadBitmapHeader(FILE *fichier ,struct BMP_HEADER * entete)
{
fread(entete,sizeof(struct BMP_HEADER),1,fichier);
if (fichier==NULL)
return(0) ;
else
return(1);
}
//cette fonction sauve le fichier BMP grace aux infos du header,et un pointeur sur une zone en mémoire contenant les pixels de l'image
int saveBitmapDatas(FILE * fichier, BMP_HEADER *header,unsigned char * octet)
{
// fwrite(header,sizeof(struct BMP_HEADER),1,fichier);
fwrite(octet, sizeof(char),1,fichier);
if (fichier==NULL)
return(0) ;
else
return(1);
}
//cette fonction doit lire les données du fichier BMP
//ça retourne un pointeur unsigned char* qui pointe une zone contenant la suite des pixels lus à partir du fichier
unsigned char * loadBitmapDatas(FILE * fichier, BMP_HEADER * header, int i)
{
int retour;
unsigned char * octet = (unsigned char *) malloc(sizeof(char));
// retour = loadBitmapHeader(fichier,header);
retour = isBitmapHeaderCorrect(fichier,header);
gotoxy(20,19);printf("valeur de retour de la validité d'en-tete:%d\n",retour);
fseek(fichier,sizeof(header + i) + i,SEEK_SET); //on se positionne après la taille de l'entete et on avance de 1 à chaque appel
fread(&octet, sizeof(char), 1, fichier);
return(octet);
}
Désoler, je t'ai deja aider beaucoup et ca sera une erreur de tout te montrer comment faire, alors je vais seulement te l'expliquer.
1-tu store ton texte dans une chaine de charactere(char LeTexte[4096];)
2-tu ouvre le bitmap
3-lire 8 char du bitmap
4-lire 1 char du texte
5-pour chaque char du bitmap lu, tu replace le bit faible par le le bit de l'octect lut ci dessu correspondand
6-enregistrer dans le fichier de sorti les 8 octecs du bitmap modifier
ensuite il faut retounrne a l'etape 3 et recommencer jusqua ce qu'il ny est plus de texte.
en fait le problème n'est pas là. dans mon fichier dest au final il me met 102octets(54 pour l'entete + 6*8 pour mon texte "\0 inclus")ce qui est bien juste.donc ce n'est pas un problème de cacher mon texte ça j'ai réussi.
mais j'aimerai savoir comment sauver le reste de l'image source dans dest(à partir d'apès le texte enregistrer)
merci de ton aide
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
int getBit(unsigned char *,int );
int hideMessage(char*,char*,char*);
int isBitmapHeaderCorrect(FILE *,struct BMP_HEADER *);
int loadBitmapHeader(FILE *,struct BMP_HEADER *);
int saveBitmapDatas(FILE * , BMP_HEADER *,unsigned char * );
unsigned char * loadBitmapDatas(FILE * , BMP_HEADER * header,int);
struct BMP_HEADER
{
char Identifier [2];
long FileSize;
long Reserved;
long DataOffset;
long HeaderSize;
long Width;
long Height;
short Planes;
short BitPerPixels;
long Compression;
long BitmapDataSize;
long HResolution;
long VResolution;
long Colors;
long ImportantColors;
};
void main()
{
struct BMP_HEADER binaire;
int retour, taille,nb_caract_max;
char menu;
char * message;
unsigned char *octet;
FILE * fichier;
char*dest = (char*)malloc(20 * sizeof(char));strcpy(dest,"c:\\img_modif.bmp");
gotoxy(12,26);printf("entrez la taille du nom et emplacement du fichier:");scanf("%d",&taille);fflush(stdin);
char * source = (char*)malloc(taille+5 * sizeof(char));gotoxy(15,27);printf("entrez le nom et emplacement du fichier:");gets(source);
strcat(source,".bmp");
fichier = fopen(source,"r+b");
clrscr();
do
{
nb_caract_max = ((binaire.BitmapDataSize - binaire.HeaderSize)/8)-8;
gotoxy(27,1);printf(" __________________________");
gotoxy(27,2);printf("| |");
gotoxy(27,3);printf("| fichier BMP |");
gotoxy(27,4);printf("| ====================== |");
gotoxy(27,5);puts ("|__________________________|");
printf("\n\n Quelle opération voulez-vous faire?\n\n");
puts(" <C>acher du texte");
puts(" <D>écouvrir du texte");
puts(" <Q>uitter");
do
menu = toupper(getch());
while(!strchr("CQ", menu));
switch(menu)
{
case 'C' : do
{
printf("entrez la taille de votre texte:");scanf("%i",&taille);
}
while(taille > nb_caract_max);
message = (char*)malloc(taille * sizeof(char));fflush(stdin);
printf("entrez le message que vous voulez cacher:");gets(message);
hideMessage(source, dest, message);break;
case 'Q' : puts("fin");exit(0); break;
}
}
while(menu != 'Q');
free(dest);
free(source);
free(message);
}
//cette fonction donne la bit cpt_bit du caractère cpt_carac
int getBit(char *message,int cpt_bit,int cpt_carac)
{
int binaire;
char valeur;
char tmp = message[cpt_carac];
binaire = pow(2,cpt_bit);
valeur = tmp & binaire;
valeur = valeur >> cpt_bit;
return(valeur);
}
//dans cette fonction on doit modifier le bit de poids faible de chaque octet par celui que renvoi la fonction getBIt
//il y a autant de bit que de (lettre +1)*8
int hideMessage(char*source,char*dest,char*message)
{
FILE * fichier_source = fopen(source,"r+b"); //fichier contenant l'image
FILE * fichier_dest = fopen(dest,"w+b"); //fichier qui contiendra l'image avec le texte dissimuler
BMP_HEADER entete;
unsigned char *octet;
int i = 0,cpt_carac,cpt_bit;
char bit;
loadBitmapHeader(fichier_source,&entete);
fwrite(&entete,sizeof(entete),1,fichier_dest);
for (cpt_carac = 0; cpt_carac < (1 + strlen (message)); cpt_carac++)
{
for(cpt_bit = 7;cpt_bit >= 0;cpt_bit--)
{
bit = getBit(message,cpt_bit,cpt_carac);
octet = loadBitmapDatas(fichier_source, &entete,i);
*octet = *octet & 254;
*octet = *octet + bit;
saveBitmapDatas(fichier_dest, &entete, octet);
i++;
}
}
return 1;
}
//fonction vérifiant si c'est bien une BMP 24bits non compressée
int isBitmapHeaderCorrect(FILE *fichier,struct BMP_HEADER *header)
{
long largeur, hauteur,taille;
if(header->Identifier[0] != 'B')
return 0;
if(header->Identifier[1] != 'M')
return 0;
if(header->Compression != 0)
{
printf("la compression est de:%i\n",header->Compression);
return 0;
}
if(header->BitPerPixels != 24)
{
printf("les bits par pixels sont de:%d",header->BitPerPixels);
return 0;
}
largeur = header->Width; hauteur = header->Height;
taille = largeur * hauteur * 3;
if(header->BitmapDataSize != taille)
return 0;
return 1;
}
//fonction chargeant les infos sur l'image dans la structure
int loadBitmapHeader(FILE *fichier ,struct BMP_HEADER * entete)
{
fread(entete,sizeof(struct BMP_HEADER),1,fichier);
if (fichier==NULL)
return(0) ;
else
return(1);
}
//cette fonction sauve le fichier BMP grace aux infos du header,et un pointeur sur une zone en mémoire contenant les pixels de l'image
int saveBitmapDatas(FILE * fichier, BMP_HEADER *header,unsigned char * octet)
{
// fwrite(header,sizeof(struct BMP_HEADER),1,fichier);
fwrite(octet, sizeof(char),1,fichier);
if (fichier==NULL)
return(0) ;
else
return(1);
}
//cette fonction doit lire les données du fichier BMP
//ça retourne un pointeur unsigned char* qui pointe une zone contenant la suite des pixels lus à partir du fichier
unsigned char * loadBitmapDatas(FILE * fichier, BMP_HEADER * header, int i)
{
int retour;
unsigned char * octet = (unsigned char *) malloc(sizeof(char));
// retour = loadBitmapHeader(fichier,header);
retour = isBitmapHeaderCorrect(fichier,header);
gotoxy(20,19);printf("valeur de retour de la validité d'en-tete:%d\n",retour);
fseek(fichier,sizeof(header + i) + i,SEEK_SET); //on se positionne après la taille de l'entete et on avance de 1 à chaque appel
fread(&octet, sizeof(char), 1, fichier);
return(octet);
}
Ok, voici ce que je te conseil de faire, tu te crée une array de char de 54 element pour l'entete, tu ouvre tou fichier source et tu copie l'emtete dans ton array. Apres tu crée une autre array de char de la grosseur de ton image, tu copie le reste du fichier dedans, tu ferme le fichier source. Donc la tu peut commencer a modifier ton image, (la 2eme array). Ensuite quand tout est fait,
tu ouvre le fichier source en mode "w+", comme ca il va ouvrir ET crée le fichier, effaccant tout dedans. Tu ecrit la 1ere array, ensuite la 2eme dans le fichier, et voila.