Le programme crée un programme de stéganographie qui cache un message secret dans une image .ppm en changeant les valeurs de pixels rouges aléatoires en caractères ascii. Le programme est basé sur le code qui est sur stackoverflow pour lire et écrire des images en ppm (read PPM file and store it in an array; coded with C), tout autre code est mon propre travail. J'ai accompli toutes les fonctions nécessaires pour écrire, lire, encoder et décoder les fichiers, mais j'ai du mal à saisir la fonction fwrite.C: Écrire des structures de valeurs RVB dans un fichier pour créer une image ppm - fin prématurée du fichier
Actuellement, lorsque le programme code une image qu'il prend en .ppm le convertit en valeurs rgb dans une structure. Puis il cache le message secret en éditant les valeurs rouges en caractères ASCII. Le problème se pose lorsqu'il s'agit «d'imprimer» l'image dans un fichier. Lorsque le programme a terminé l'image produite est d'environ 90% de ce qu'il devrait être imprimé. Exemple d'affichage ci-dessous: Example of the unfinished image
J'ai vérifié qu'il stocke toutes les valeurs sont stockées correctement en imprimant toutes les valeurs RGB et il est. (utilisé la méthode showPPM). N'y a-t-il pas assez de mémoire pour écrire l'image? l'image est-elle trop grande pour la fonction d'écriture? Ce sont mes suppositions.
Toute information sur la façon dont je devrais changer la fonction writePPM afin que j'imprime correctement 100% de l'image dans le fichier serait géniale.
Voici le code ci-dessous:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<time.h>
typedef struct {
unsigned char red,green,blue;
} PPMPixel;
typedef struct {
int x, y;
PPMPixel *data;
} PPMImage;
void writePPM(PPMImage *img);
static PPMImage *getPPM(const char *filename)
{
char buff[16];
PPMImage *img;
FILE *fp;
int c, rgb_comp_color;
//open PPM file for reading
fp = fopen(filename, "rb");
if (!fp) {
fprintf(stderr, "Unable to open file '%s'\n", filename);
exit(1);
}
//read image format
if (!fgets(buff, sizeof(buff), fp)) {
perror(filename);
exit(1);
}
//check the image format
if (buff[0] != 'P' || buff[1] != '3') {
fprintf(stderr, "Invalid image format (must be 'P3')\n");
exit(1);
}else{
printf("P3\n");
}
//alloc memory form image
img = (PPMImage *)malloc(sizeof(PPMImage));
if (!img) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
c = getc(fp);
while (c == '#') {
while (getc(fp) != '\n') ;
c = getc(fp);
}
ungetc(c, fp);
//read image size information
if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
exit(1);
}else{
printf("Height: %d\n",img->x);
printf("Width: %d\n",img->y);
}
//read rgb component
if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
exit(1);
}else{
printf("%d\n",rgb_comp_color);
}
//check rgb component depth
if (rgb_comp_color!= 255) {
fprintf(stderr, "'%s' does not have 8-bits components\n", filename);
exit(1);
}
while (fgetc(fp) != '\n') ;
//memory allocation for pixel data
img->data = (PPMPixel*)malloc(24*img->x * img->y * sizeof(PPMPixel));
if (!img) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
//read pixel data from file
if (fread(img->data, 10*img->x, img->y, fp) != img->y) {
fprintf(stderr, "Error loading image '%s'\n", filename);
exit(1);
}
fclose(fp);
return img;
}
struct PPMImage * encode(char * text, PPMImage * img)
{
//convert secret message to ascii code
int i,ascii,height,width;
int total = 0;
int rolling = 0;
int original = 0;
time_t t;
srand((unsigned) time(&t));
height=img->y;
width=img->x;
for(i = 0; text[i]; i++){
ascii = text[i];
//create random number between 0 and max the width
total = total + rand() % width;
original = total;
//printf("Random Number: %d\n",total);
if(total >= width){
rolling = rolling + 1;
total = total - width;
}
//printf("Before R: %d \n",img->data[0].red);
img->x=rolling;
img->y=total;
printf("X: %d ",rolling);
printf("Y: %d ",total);
//set img position
//at position random we set the red bit equal to ascii number
printf("Old R: %d ",img->data[i].red);
img->data[i].red=ascii;
printf("New R: %d\n ",img->data[i].red);
}
//take img then print it out
//setting the img values again for printing
img->x=width;
img->y=height;
writePPM(img);
}
void writePPM(PPMImage *img)
{
FILE *fp;
//open file to be written
fp = fopen("encoded.ppm", "wb");
if (!fp) {
fprintf(stderr, "Unable to open file \n");
exit(1);
}
//image format
fprintf(fp, "P3\n");
//comments
//need to store comments to be outputted
fprintf(fp, "# Created by Sean \n");
//image size
fprintf(fp,"%d %d\n",img->x,img->y);
// rgb component depth
fprintf(fp, "%d\n",255);
//write pixels currently not fully working
fwrite(img->data, sizeof(img->data), 3*img->y*img->x, fp);
//close file stream
fclose(fp);
}
void showPPM(PPMImage *img)
{
int i;
if(img){
for(i=-1;i<img->x*img->y;i++){
printf("Number: %d\n",i);
printf("R: %d ",img->data[i].red);
printf("G: %d ",img->data[i].green);
printf("B: %d\n ",img->data[i].blue);
}
}
}
char * decode(PPMImage * i1,PPMImage * i2){
//compare difference in number of bits in red pixels
//if there is a different then take the red pixel value from the encrypted image
//then translate it from ascii to chars then print.
printf("Decoding......\n");
int i;
for(i=-1;i<i1->x*i1->y;i++){
if(i1->data[i].red != i2->data[i].red){
printf("%c",i1->data[i].red);
}
}
//to be able to test and finish this need to write code for encoding
}
int main(int argc, char *argv[]){
//input statements
if(argc == 3){
PPMImage *image;
image = getPPM(argv[2]);
//uncomment the showPPM to display all rgb values in the encoded files
//showPPM(image);
if(argv[1] = "e"){
printf("Please enter your secret message to be encoded estimated max characters: %d\n",image->y);
//need to add user input
encode("test output!",image);
}
}else if(argc == 4){
PPMImage *i1;
PPMImage *i2;
i1 = getPPM(argv[2]);
i2 = getPPM(argv[3]);
if(argv[1] = "d"){
decode(i1,i2);
}
}else{
printf("Wrong arguments");
}
}
'sizeof (img-> données)' est pas ce que vous voulez. Cela vous donne la taille du * pointeur * et non la taille de la mémoire allouée. Vous avez des nombres magiques dans votre code tels que '24' et' 3' qui rendent non évident ce que les différentes tailles représentent. Donc je ne sais pas exactement de quelle taille vous avez besoin dans 'fwrite'. Mais ce n'est définitivement pas 'sizeof (img-> data)'. – kaylum
Vous devriez éditer ceci pour enlever la conversation de marin d'anti-calum, nous essayons d'exécuter un joint respectable ici. – samgak
Merci pour le conseil oublié que c'était là :) –