PPM 이미지에서 기본 스테 가노 그래피를 시도합니다.스테 가노 그라피 C
기본 알고리즘을 완료했습니다. 파일을 읽고 헤더가 P6으로 시작하는지 확인하고 이미지 너비와 높이 및 픽셀 데이터를 가져옵니다.
총 4 가지 방법 (ReadPPM, WritePPM, WriteMsg 및 ReadMsg)이 필요합니다.
필자는 ReadImg 및 WriteImg 메서드를 사용하지 않지만 내 기능이 멈추는 곳은 WriteMsg 메서드입니다. 이것은 각 바이트의 마지막 비트에 문자열의 각 비트를 쓰는 기본 스테 가노 그래피입니다. 처음 8 바이트는 숨겨진 문자열의 크기를 포함한다고 가정하고 그 이후의 각 바이트는 숨겨진 메시지를 시작합니다.
제 아이디어는 문자열의 크기와 이진 코드의 바이너리 코드를 저장하는 방대한 배열을 만드는 것이 었습니다. 나는 그 배열을 어떻게 가져 와서 이미지의 각 바이트에 추가할지 알아 내려고하고있다.
도움을 주시면 감사하겠습니다. 여기에 내 현재 코드 :
#include<stdio.h>
#include<stdlib.h>
typedef struct {
unsigned char red,green,blue;
} PPMPixel;
typedef struct {
int x, y;
PPMPixel *data;
} PPMImage;
#define CREATOR "RPFELGUEIRAS"
#define RGB_COMPONENT_COLOR 255
static PPMImage *readPPM(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] != '6') {
fprintf(stderr, "Invalid image format (must be 'P6')\n");
exit(1);
}
//alloc memory form image
img = (PPMImage *)malloc(sizeof(PPMImage));
if (!img) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
//check for comments
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);
}
//read rgb component
if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
exit(1);
}
//check rgb component depth
if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
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(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, 3 * img->x, img->y, fp) != img->y) {
fprintf(stderr, "Error loading image '%s'\n", filename);
exit(1);
}
fclose(fp);
return img;
}
void writePPM(const char *filename, PPMImage *img)
{
FILE *fp;
//open file for output
fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Unable to open file '%s'\n", filename);
exit(1);
}
//write the header file
//image format
fprintf(fp, "P6\n");
//comments
fprintf(fp, "# Created by %s\n",CREATOR);
//image size
fprintf(fp, "%d %d\n",img->x,img->y);
// rgb component depth
fprintf(fp, "%d\n",RGB_COMPONENT_COLOR);
// pixel data
fwrite(img->data, 3 * img->x, img->y, fp);
fclose(fp);
}
void writeMsg(PPMImage *img, char *s)
{
int i;
int len;
len = sizeof(s);
if (img)
{
j = 0;
for (i=0; i < img->x * img->y; i++)
{
while(j < 8)
{
if(len & 0x80)
{
img->data[i].red= img->data[i].red | 0x01;
}
else
{
img->data[i].red= img->data[i].red & 0xFE;
}
len=len << 1;
j++;
if (len & 0x80)
{
img->data[i].green= img->data[i].green | 0x01;
}
else
{
img->data[i].green= img->data[i].green & 0xFE;
}
len = len << 1;
j++;
if (len & 0x80)
{
img->data[i].blue= img->data[i].blue | 0x01;
}
else
{
img->data[i].blue= img->data[i].blue & 0xFE;
}
j++;
}
}
}
}
코드 형식이 대부분 괜찮습니다 ... 실제로 도움이 필요한 기능은 제외! 고쳐주세요. 그것은 완전히 읽을 수없는 것입니다. – MatthewD
당신은 두 사이클을 필요로합니다 : 하나는 len이고 다른 하나는 모든 char의 비트들입니다. @Patashu가 말한 것과 같은 두 번째 사이클 내에서만 데이터를 쓰거나 역순으로 ('byte << i & 0x80') 쓰십시오. 길이 변수를 굴리지 마라! –
'len = sizeof (s)'는 포인터의 크기를 반환합니다. 문자열의 길이를 원하면'strlen()'을 사용하십시오. – MatthewD