Кодирование-декодирование изображений
11.01.2014, 06:45. Показов 6362. Ответов 1
Нужна программа с++, которая кодирует изображение в изображение(и обратно), используя при этом 2 младших бита.
Есть программа, которая (по идеи) использует 3 младших бита, но при проверке кодированного изображения получилось, что меняет она 4 бита.
Кодирование
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
| #define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <io.h>
using namespace std;
void Integration(int counter,unsigned char *MessageBits) //функция встраивания сообщения в в картинку
{
FILE *ENCODE;
ENCODE=fopen("ENCODE.bmp", "r+b"); //открываем бинарный файл в режиме чтение+запись
int ImagePosition; //переменная для смещения, с которого начинается само изображение
int counter2=0;//переменная счётчик
fseek(ENCODE,10,SEEK_SET);//сдвигаем указатель на 10 байт
fread (&ImagePosition,4,1,ENCODE); //читаем смещение, с которого начинается само изображение
unsigned char byte;//переменная в которой будет помещаться 1 байт считываемой картинки
//Алгоритм шифрования
for (int i=0;;i++)
{
fseek(ENCODE,ImagePosition+i,SEEK_SET);//двигаем указатель на позицию изображения+i
fread(&byte,1,1,ENCODE);//читаем байт изображения
byte=byte&248;//побитово складываем байт изображения с числом 11111000
for (int j=2;j>=0;j--)//алгоритм встраивания трёх младших битов
{
if (counter2==counter) break; //если счётчик больше длины сообщения выходим
byte=byte|(MessageBits[counter2]<<j);//встраиваем 3 младших бита сообщения в 1 байт изображения
counter2++;
}
if (counter2==counter) break;//если счётчик больше длины сообщения выходим
fseek(ENCODE,ImagePosition+i,SEEK_SET);//смещаем указатель после чтения байта назад
fwrite(&byte,1,1,ENCODE);//записываем изменённый байт
}
fclose(ENCODE);//закрываем файл
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char MesByte;//байт сообщения
FILE *Message;
Message=fopen("Message.bmp", "rb");//открываем бинарный файл в режиме для чтения
union//объединение ,элементы которого разделяют одну область памяти(нужно чтобы записать размер сообщения в первые четыре байта изображения)
{
unsigned int size; //само число
unsigned char SizeChar[4]; //байты числа
};
size = _filelength(_fileno(Message));//получаем размер сообщения
unsigned char *MessageBits=new unsigned char[(size+6)*8];//создаём динамический массив, где будут храниться "биты"(0 или 1) сообщения
for(int i=0;i<(size+6)*8;i++)//инициализируем массив
MessageBits[i]=0;
int counter=0;//переменная счётчик
for (int i=0;i<6;i++ )//записываем размер сообщения в массив,для размера используется 4 байта,2 пустые(для кратности 24)
{
for (int j=0;j<=7;j++)
{
if (i<4) MessageBits[counter]=((SizeChar[i]<<j)>>7)&1;//записываем в массив из "битов" размер
counter++;
}
}
fseek(Message,0,SEEK_SET);//сдвигаем указатель на начало файла
for (int i=0;i<size;i++ )//читаем байты сообщения до конца файла
{
fread (&MesByte,1,1,Message);//читаем байт сообщения
for (int j=0;j<=7;j++)
{
MessageBits[counter]=((MesByte<<j)>>7)&1;//заносим в массив из "битов" всё наше сообщение
counter++;
}
}
fclose(Message);//закрываем файл
Integration( counter, MessageBits);//вызов функции встраивания сообщения в изображение
delete []MessageBits;//освобождаем память отведённую под динамический массив
return 0;
} |
|
Декодирование
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
| #define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
int GetSize()//функция для получения размера сообщения из первых четырёх байт картинки
{
FILE *ENCODE;
ENCODE=fopen("ENCODE.bmp", "r+b");//открываем бинарный файл в режиме чтение+запись
int counter=0;//переменная счётчик
int ImagePosition; //переменная для смещения,с которого начинается само изображение
unsigned char SizeBits[36];//массив из "битов" котором будет содержаться размер картинки
fseek(ENCODE,10,SEEK_SET);//сдвигаем указатель на 10 байт
fread (&ImagePosition,4,1,ENCODE); //читаем смещение,с которого начинается само изображение
unsigned char byte;//переменная,в которой будет содержаться байт сообщения
union//объединение,элементы которого разделяют одну область памяти(чтобы получить int размер из 4 байт char)
{
unsigned int size; //само число
unsigned char SizeChar[4]; //байты числа
};
size=0;
for (int i=0;i<12;i++)
{
fseek(ENCODE,ImagePosition+i,SEEK_SET);//смещаем указатель на позицию изображения+i
fread(&byte,1,1,ENCODE);//читаем байт изображения
byte=byte&7;//складываем байт сообщения с 00000111
for(int j=2;j>=0;j--)
{
SizeBits[counter]=(byte>>j)&1;//записываем 3 бита размера в "битовый" массив
counter++;
}
}
int counter2=0;//переменная счётчик
for (int i=0;i<4;i++)//получаем 4 байта размера сообщения
{
for(int j=7;j>=0;j--)
{
SizeChar[i]+=SizeBits[counter2]*pow(2,j);//переводим каждый байт из двоичной системы в десятичную
counter2++;
}
}
fclose(ENCODE);//закрываем файл
return size;//возвращаем размер сообщения
}
void GetBits(int size,unsigned char *message)//функция, которая получает "биты" сообщения и записывает их в массив(массив из 0 и 1)
{
FILE *ENCODE;
ENCODE=fopen("ENCODE.bmp", "r+b");//открываем бинарный файл в режиме чтение+запись
int counter=0;//переменная счётчик
int ImagePosition; //переменная для смещения
unsigned char byte;//переменная,в которой будет содержаться байт сообщения
fseek(ENCODE,10,SEEK_SET);//сдвигаем указатель на 10 байт
fread (&ImagePosition,4,1,ENCODE); //читаем смещение,с которого начинается само изображение
for (int i=0;i<size*8/3;i++)//считываем наше сообщение из изображения (до size*8/3 т.к 8б бит сообщения кодируется в 3 байта изображения)
{
fseek(ENCODE,ImagePosition+16+i,SEEK_SET);//смещаем указатель на позицию изображения +16(т.к первые 4 байта размер 2 пустые=6 байт=48бит кодируются в 3 байта изображения)+i
fread(&byte,1,1,ENCODE);//читаем 1 байт изображения
byte=byte&7;//складываем полученный байт с 00000111
for(int j=2;j>=0;j--)
{
message[counter]=(byte>>j)&1;//записываем младшие биты в "битовый" массив сообщения
counter++;
}
}
fclose(ENCODE);//закрываем файл
}
void Decoding(int size,unsigned char *message,unsigned char *DecodedMessage)//функция расшифровки сообщения
{
int counter2=0;//переменная-счётчик
for (int i=0;i<size;i++)//получение массива из байтов сообщения
{
for(int j=7;j>=0;j--)
{
DecodedMessage[i]+=message[counter2]*pow(2,j);//каждый байт сообщения переводим в десятичное число
counter2++;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int size = GetSize();//получаем размер сообщения
unsigned char *message = new unsigned char[size*8];//создаём динамический массив,в который будут записываться биты сообщения
for (int i=0;i<size*8;i++) message[i]=0;//инициализируем массив
GetBits(size,message);//вызываем функцию для заполнения нашего массива "битами" сообщения(0 или 1)
unsigned char *DecodedMessage = new unsigned char[size];//создаём динамический массив, в который будут записываться байты сообщения
for (int i=0;i<size;i++) DecodedMessage[i]=0;//инициализируем массив
Decoding(size,message,DecodedMessage);//вызываем функцию расшифровки сообщения
FILE *DecMes;
DecMes=fopen("DecMes.bmp", "wb");//открываем файл для записи расшифрованного сообщения
for (int i=0;i<size;i++)
{
fwrite(&DecodedMessage[i],1,1,DecMes);//вывод сообщения в файл
}
fclose(DecMes);//закрываем файл
delete []message;//освобождаем память отведённую под динамический массив
delete []DecodedMessage;//освобождаем память отведённую под динамический массив
return 0;
} |
|
0
|