· 7 years ago · Dec 21, 2018, 03:24 PM
1#define _CRT_SECURE_NO_WARNINGS
2#include <stdio.h>
3#include <string.h>
4
5struct pixel {
6 unsigned char R, G, B;
7};
8
9struct detectie {
10 unsigned int x, y, latime, inaltime, sablon;
11};
12
13unsigned int grayscaleImage(char* nume_fisier_sursa, char* nume_fisier_destinatie)
14{
15 FILE *fin, *fout;
16 unsigned int dim_img, latime_img, inaltime_img;
17 unsigned char aux, *pRGB = (unsigned char*)malloc(3);
18 int i, j;
19
20 fin = fopen(nume_fisier_sursa, "rb");
21 if (fin == NULL)
22 {
23 printf("Nu am gasit imaginea sursa din care citesc.\n");
24 return 0;
25 }
26
27 fout = fopen(nume_fisier_destinatie, "wb+");
28
29 fseek(fin, 2, SEEK_SET);
30 fread(&dim_img, sizeof(unsigned int), 1, fin);
31
32 fseek(fin, 18, SEEK_SET);
33 fread(&latime_img, sizeof(unsigned int), 1, fin);
34 fread(&inaltime_img, sizeof(unsigned int), 1, fin);
35
36 printf("\nTransformare grayscale..");
37 fseek(fin, 0, SEEK_SET);
38 unsigned char c; // copiem headerul
39 for (i = 0; i < 54; i++)
40 {
41 fread(&c, 1, 1, fin);
42 fwrite(&c, 1, 1, fout);
43 fflush(fout);
44 }
45
46 int padding;
47 if (latime_img % 4 != 0)
48 padding = 4 - (3 * latime_img) % 4;
49 else
50 padding = 0;
51
52 printf(".");
53 for (i = 0; i < inaltime_img; i++)
54 {
55 for (j = 0; j < latime_img; j++)
56 {
57 fread(pRGB, 1, 3, fin);
58 aux = 0.299*pRGB[2] + 0.587*pRGB[1] + 0.114*pRGB[0];
59 pRGB[0] = pRGB[1] = pRGB[2] = aux;
60 fwrite(pRGB, 1, 3, fout);
61 fflush(fout);
62 }
63 if (padding)
64 {
65 fread (pRGB, 1, padding, fin);
66 fwrite(pRGB, 1, padding, fout);
67 }
68 if (i % 128 == 0) //vizualizare progres
69 printf(".");
70 }
71 printf("\n");
72 fclose(fin);
73 fclose(fout);
74 return dim_img;
75}
76
77void xorshift32_C1(unsigned int **R, unsigned int n, unsigned int seed)
78{
79 unsigned int r = seed;
80
81 *R = (unsigned int*)malloc(n * sizeof(unsigned int));
82
83 (*R)[0] = r;
84 for (int k = 1; k < n; k++)
85 {
86 r = r ^ r << 13;
87 r = r ^ r >> 17;
88 r = r ^ r << 5;
89 (*R)[k] = r;
90 }
91}
92
93void pDurstenfeld(unsigned int **P, unsigned int n, unsigned int *R)
94{
95 unsigned int r, k, rk, aux;
96
97 *P = (unsigned int*)malloc(n * sizeof(unsigned int));
98
99 for (k = 0; k < n; k++)
100 (*P)[k] = k;
101
102 rk = 1;
103 for (k = n - 1; k > 0; k--)
104 {
105 r = R[rk] % (k + 1);
106 aux = (*P)[r];
107 (*P)[r] = (*P)[k];
108 (*P)[k] = aux;
109 rk++;
110 }
111}
112
113void inversaPerm(unsigned int **P, unsigned int n)
114{
115 unsigned int *invP = (unsigned int*)malloc(n * sizeof(unsigned int));
116 int i;
117 for (i = 0; i < n; i++)
118 invP[(*P)[i]] = i;
119
120 for (i = 0; i < n; i++)
121 (*P)[i] = invP[i];
122 free(invP);
123}
124
125int getSecretKeys(char *nume_fisier_secret_key, unsigned int *R0, unsigned int *SV)
126{
127 FILE *s;
128 s = fopen(nume_fisier_secret_key, "r");
129 if (s == NULL)
130 {
131 printf("Nu am gasit fisierul ce contine cheile secrete.\n");
132 return 0;
133 }
134 fscanf(s, "%u", &(*R0));
135 fscanf(s, "%u", &(*SV));
136 fclose(s);
137 return 1;
138}
139
140unsigned int loadImageLin_C2(char *nume_fisier_sursa, unsigned char **header, struct pixel **L, unsigned int *latime_img, unsigned int *inaltime_img, unsigned int *padding, int okType)
141{
142 unsigned int dim_img;
143 unsigned char *tmp = (unsigned char*)malloc(3);
144 int i;
145
146 if (okType)
147 printf("\nNume_fisier_sursa = %s \n", nume_fisier_sursa);
148
149 //Deschidere fisier imagine
150 FILE *fin;
151 fin = fopen(nume_fisier_sursa, "rb");
152 if (fin == NULL)
153 {
154 printf("Nu am gasit imaginea sursa din care citesc.\n");
155 return 0;
156 }
157
158 //Dimensiune imagine
159 fseek(fin, 2, SEEK_SET);
160 fread(&dim_img, sizeof(unsigned int), 1, fin);
161 if (okType)
162 printf("Dimensiunea imaginii in octeti: %u\n", dim_img);
163
164 //Latime si inaltime imagine
165 fseek(fin, 18, SEEK_SET);
166 fread(latime_img, sizeof(unsigned int), 1, fin);
167 fread(inaltime_img, sizeof(unsigned int), 1, fin);
168 if (okType)
169 printf("Dimensiunea imaginii in pixeli (latime x inaltime): %u x %u\n", *latime_img, *inaltime_img);
170
171 //Calculare padding
172 if ((*latime_img) % 4 != 0)
173 *padding = 4 - (3 * (*latime_img)) % 4;
174 else
175 *padding = 0;
176 if (okType)
177 printf("padding = %d \n", *padding);
178
179 //Copierea header-ului
180 *header = (unsigned char*)malloc(54);
181 fseek(fin, 0, SEEK_SET);
182 for (i = 0; i < 54; i++)
183 fread(&(*header)[i], 1, 1, fin);
184
185 //Alocare spatiu pt imaginea liniarizata
186 *L = (struct pixel *) malloc((*latime_img) * (*inaltime_img) * sizeof(struct pixel));
187
188 //Citirea imaginii in forma liniarizata
189 if (okType)
190 printf("\nCitire...");
191 for (i = 0; i < (*inaltime_img); i++)
192 {
193 for (int j = 0; j < (*latime_img); j++)
194 {
195 fread(&(*L)[i*(*latime_img) + j].B, 1, 1, fin);
196 fread(&(*L)[i*(*latime_img) + j].G, 1, 1, fin);
197 fread(&(*L)[i*(*latime_img) + j].R, 1, 1, fin);
198 }
199 if (*padding)
200 fread(&tmp, 1, (*padding), fin);
201 if (i % 128 == 0 && okType) //vizualizare progres
202 printf(".");
203 }
204 printf("\n");
205 fclose(fin);
206 free(tmp);
207 return dim_img;
208}
209
210void saveImageLin_C3(char *nume_fisier_destinatie, unsigned char *header, struct pixel *L, unsigned int latime_img, unsigned int inaltime_img, unsigned int padding)
211{
212 FILE *fout;
213 fout = fopen(nume_fisier_destinatie, "wb");
214 int i;
215
216 //Salvarea header ului imaginii
217 for (i = 0; i < 54; i++)
218 fwrite(&header[i], 1, 1, fout);
219
220 //Salvarea imaginii din forma liniarizata
221 unsigned char *tmp = (unsigned char*)malloc(3); tmp[0] = 0; tmp[1] = 0; tmp[2] = 0;
222 printf("\nSalvare...");
223 for (i = 0; i < inaltime_img; i++)
224 {
225 for (int j = 0; j < latime_img; j++)
226 {
227 //printf("%c", L[i*latime_img + j].B);
228 fwrite(&L[i*latime_img + j].B, 1, 1, fout);
229 fwrite(&L[i*latime_img + j].G, 1, 1, fout);
230 fwrite(&L[i*latime_img + j].R, 1, 1, fout);
231 }
232 if (padding)
233 fwrite(tmp, 1, padding, fout);
234 if (i % 128 == 0) //vizualizare progres
235 printf(".");
236 }
237 printf("\n");
238 fclose(fout);
239 free(tmp);
240}
241
242void chiSquaredTest_C6(char *nume_fisier_testat)
243{
244 struct frecventa {
245 unsigned int R, G, B;
246 };
247
248 unsigned int dim_img, latime_img, inaltime_img, padding;
249 unsigned char *header;
250 struct pixel *L;
251 int i;
252
253 dim_img = loadImageLin_C2(nume_fisier_testat, &header, &L, &latime_img, &inaltime_img, &padding, 0);
254 if (!dim_img)
255 return;
256
257 FILE *fout = fopen("chi-squared-test-values.txt", "ab");
258
259 struct frecventa *frecv = (struct frecventa*)malloc(256 * sizeof(struct frecventa));
260 for (i = 0; i < 256; i++)
261 {
262 frecv[i].R = 0;
263 frecv[i].G = 0;
264 frecv[i].B = 0;
265 }
266 for (i = 0; i < latime_img * inaltime_img; i++)
267 {
268 frecv[L[i].R].R++;
269 frecv[L[i].G].G++;
270 frecv[L[i].B].B++;
271 }
272
273 float chiR = 0, chiG = 0, chiB = 0, frecvEstT;
274 frecvEstT = (latime_img * inaltime_img) / 256;
275
276 for (i = 0; i < 256; i++)
277 {
278 chiR = chiR + ((frecv[i].R - frecvEstT) * (frecv[i].R - frecvEstT)) / frecvEstT;
279 chiG = chiG + ((frecv[i].G - frecvEstT) * (frecv[i].G - frecvEstT)) / frecvEstT;
280 chiB = chiB + ((frecv[i].B - frecvEstT) * (frecv[i].B - frecvEstT)) / frecvEstT;
281 }
282 printf("Chi-squared test on RGB channels for %s:\nR: %.2f\nG: %.2f\nB: %.2f\n", nume_fisier_testat, chiR, chiG, chiB);
283 fprintf(fout, "Chi-squared test on RGB channels for %s:\r\nR: %.2f\r\nG: %.2f\r\nB: %.2f\r\n\r\n", nume_fisier_testat, chiR, chiG, chiB);
284 fclose(fout);
285 free(frecv);
286}
287
288void encryptImage_C4(char *nume_fisier_sursa, char *nume_fisier_destinatie, char *secret_key)
289{
290 unsigned int dim_img, latime_img, inaltime_img, padding, *R, *Perm, R0, SV;
291 unsigned char *header;
292 struct pixel *L, *LP, *C;
293 int i;
294
295 //Citire chei secrete
296 if (!getSecretKeys(secret_key, &R0, &SV))
297 return;
298
299 //Citire imagine initiala
300 dim_img = loadImageLin_C2(nume_fisier_sursa, &header, &L, &latime_img, &inaltime_img, &padding, 1);
301 if (!dim_img)
302 return;
303
304 //Generare secventa de nr aleatoare
305 xorshift32_C1(&R, 2 * latime_img * inaltime_img, R0);
306
307 //Generare permutare aleatorie
308 pDurstenfeld(&Perm, latime_img*inaltime_img, R);
309
310 //Permutarea pixelilor imaginii
311 LP = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
312 for (i = 0; i < latime_img * inaltime_img; i++)
313 LP[Perm[i]] = L[i];
314
315 //Schimbarea valorilor pixelilor
316 printf("\nCriptare...");
317 C = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
318 C[0].R = SV ^ (LP[0].R) ^ R[latime_img * inaltime_img];
319 C[0].G = SV ^ (LP[0].G) ^ R[latime_img * inaltime_img];
320 C[0].B = SV ^ (LP[0].B) ^ R[latime_img * inaltime_img];
321 for (int k = 1; k < latime_img * inaltime_img; k++)
322 {
323 C[k].R = (C[k - 1].R) ^ (LP[k].R) ^ R[latime_img * inaltime_img + k];
324 C[k].G = (C[k - 1].G) ^ (LP[k].G) ^ R[latime_img * inaltime_img + k];
325 C[k].B = (C[k - 1].B) ^ (LP[k].B) ^ R[latime_img * inaltime_img + k];
326 if (k % (128 * latime_img) == 0) //vizualizare progres
327 printf(".");
328 }
329 printf("\n");
330
331 //Salvare imagine criptata
332 saveImageLin_C3(nume_fisier_destinatie, header, C, latime_img, inaltime_img, padding);
333
334 free(L);
335 free(LP);
336 free(C);
337 free(R);
338 free(Perm);
339 free(header);
340 printf("\nImaginea a fost criptata.\n");
341 chiSquaredTest_C6(nume_fisier_sursa);
342 chiSquaredTest_C6(nume_fisier_destinatie);
343}
344
345void decryptImage_C5(char *nume_fisier_decriptat, char *nume_fisier_criptat, char *secret_key)
346{
347 unsigned int dim_img, latime_img, inaltime_img, padding, *R, *Perm, R0, SV;
348 unsigned char *header;
349 struct pixel *C, *CP, *L;
350 int i;
351
352 //Citire chei secrete
353 if (!getSecretKeys(secret_key, &R0, &SV))
354 return;
355
356 //Citire imagine initiala
357 dim_img = loadImageLin_C2(nume_fisier_criptat, &header, &C, &latime_img, &inaltime_img, &padding, 1);
358 if (!dim_img)
359 return;
360
361 //Generare secventa de nr aleatoare
362 xorshift32_C1(&R, 2 * latime_img * inaltime_img, R0);
363
364 //Generare permutare aleatorie
365 pDurstenfeld(&Perm, latime_img * inaltime_img, R);
366
367 //Calculare inversa permutarii
368 inversaPerm(&Perm, latime_img * inaltime_img);
369
370 //Restaurarea valorilor pixelilor
371 printf("\nDecriptare...");
372 CP = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
373 CP[0].R = SV ^ (C[0].R) ^ R[latime_img * inaltime_img];
374 CP[0].G = SV ^ (C[0].G) ^ R[latime_img * inaltime_img];
375 CP[0].B = SV ^ (C[0].B) ^ R[latime_img * inaltime_img];
376 for (int k = 1; k < latime_img * inaltime_img; k++)
377 {
378 CP[k].R = (C[k - 1].R) ^ (C[k].R) ^ R[latime_img * inaltime_img + k];
379 CP[k].G = (C[k - 1].G) ^ (C[k].G) ^ R[latime_img * inaltime_img + k];
380 CP[k].B = (C[k - 1].B) ^ (C[k].B) ^ R[latime_img * inaltime_img + k];
381 if (k % (128 * latime_img) == 0) //vizualizare progres
382 printf(".");
383 }
384 printf("\n");
385
386 //Permutarea pixelilor imaginii
387 L = (struct pixel*) malloc(latime_img * inaltime_img * sizeof(struct pixel));
388 for (i = 0; i < latime_img * inaltime_img; i++)
389 L[Perm[i]] = CP[i];
390
391 //Salvare imagine decriptata
392 saveImageLin_C3(nume_fisier_decriptat, header, L, latime_img, inaltime_img, padding);
393
394 free(L);
395 free(CP);
396 free(C);
397 free(R);
398 free(Perm);
399 free(header);
400 printf("\nImaginea a fost decriptata.\n");
401}
402
403struct detectie *templateMatching(char *nume_fisier_sursa, char *nume_sablon, float prag, unsigned int *cnt)
404{
405
406}
407
408void patternMatching(char *nume_fisier_sursa)
409{
410 char *nume_fisier_grayscale, *nume_fisier_sabloane, *nume_fisier_rec, **sabloane;
411 struct detectie *arrFiSab, *arrDetected;
412 unsigned int dimImg, cntDetFi, cntDet;
413 int i, j;
414 float ps = 0.5;
415
416 nume_fisier_sabloane = (char*)malloc(50);
417 printf("\nNumele fisierului ce contine adresele sabloanelor: ");
418 scanf("%s", nume_fisier_sabloane);
419
420 FILE *fSab = fopen(nume_fisier_sabloane, "r");
421 if (fSab == NULL)
422 {
423 printf("Fisierul nu a fost gasit.\n");
424 return;
425 }
426 sabloane = (char**)malloc(10 * sizeof(char*));
427 for (i = 0; i < 10; i++)
428 {
429 sabloane[i] = (char*)malloc(50);
430 fscanf(fSab, "%s", sabloane[i]);
431 }
432 fclose(fSab);
433 free(nume_fisier_sabloane);
434
435 nume_fisier_grayscale = (char*)malloc(100);
436 strcpy(nume_fisier_grayscale, nume_fisier_sursa);
437 strcat(nume_fisier_sursa, ".bmp");
438 strcat(nume_fisier_grayscale, "_grayscale.bmp");
439
440 dimImg = grayscaleImage(nume_fisier_sursa, nume_fisier_grayscale);
441 if (!dimImg)
442 {
443 free(nume_fisier_grayscale);
444 return;
445 }
446
447 arrDetected = (struct detectie*)malloc(dimImg * 10 * sizeof(struct detectie));
448 arrFiSab = (struct detectie*)malloc(dimImg * sizeof(struct detectie));
449 cntDet = 0;
450 for (i = 0; i < 10; i++)
451 {
452 //cntDetFi = 0;
453 arrFiSab = templateMatching(nume_fisier_grayscale, sabloane[i], ps, &cntDetFi);
454 for (j = 0; j < cntDetFi; j++)
455 {
456 arrDetected[cntDet] = arrFiSab[j];
457 cntDet++;
458 }
459 }
460 for (i = 0; i < 10; i++)
461 free(sabloane[i]);
462 free(sabloane);
463 free(arrFiSab);
464 free(nume_fisier_grayscale);
465
466
467 //dwasadadwswa
468
469
470 FILE *fin, *fout;
471 nume_fisier_rec = (char*)malloc(100);
472 fin = fopen(nume_fisier_sursa, "rb");
473 fout = fopen(nume_fisier_rec, "wb");
474 unsigned char c;
475 while (fread(&c, 1, 1, fin) == 1)
476 {
477 fwrite(&c, 1, 1, fout);
478 fflush(fout);
479 }
480 fclose(fin);
481 fclose(fout);
482
483 printf("\nRecunoasterea de pattern-uri a fost efectuata.\n");
484 free(arrDetected);
485}
486
487void menu_C11()
488{
489 int t;
490 char *nume_img_sursa = (char*)malloc(90);
491 printf("*** Numele imaginii sursa se va scrie fara extensie (.bmp)! ***\n\n");
492 while (1)
493 {
494 printf("1. Criptare imagine\n");
495 printf("2. Decriptare imagine\n");
496 printf("3. Recunoastere pattern-uri\n");
497 printf("0. Exit\n");
498 scanf("%d", &t);
499 if (!t)
500 return;
501 printf("Nume fisier imagine: ");
502 scanf("%s", nume_img_sursa);
503 switch (t)
504 {
505 case 1:
506 {
507 char *nume_img_encrypted = (char*)malloc(100);
508 strcpy(nume_img_encrypted, nume_img_sursa);
509 strcat(nume_img_sursa, ".bmp");
510 strcat(nume_img_encrypted, "_encrypted.bmp");
511 printf("Nume fisier cheie secreta: ");
512 char *nume_cheie_secreta = (char*)malloc(50);
513 scanf("%s", nume_cheie_secreta);
514 encryptImage_C4(nume_img_sursa, nume_img_encrypted, nume_cheie_secreta);
515 free(nume_img_encrypted);
516 free(nume_cheie_secreta);
517 }
518 break;
519 case 2:
520 {
521 char *nume_img_decrypted = (char*)malloc(100);
522 strcpy(nume_img_decrypted, nume_img_sursa);
523 strcat(nume_img_sursa, ".bmp");
524 strcat(nume_img_decrypted, "_decrypted.bmp");
525 printf("Nume fisier cheie secreta: ");
526 char *nume_cheie_secreta = (char*)malloc(50);
527 scanf("%s", nume_cheie_secreta);
528 decryptImage_C5(nume_img_decrypted, nume_img_sursa, nume_cheie_secreta);
529 free(nume_img_decrypted);
530 free(nume_cheie_secreta);
531 }
532 break;
533 case 3:
534 {
535 patternMatching(nume_img_sursa);
536 }
537 break;
538 case 0:
539 break;
540 default: printf("Optiune invalida.\n");
541 break;
542 }
543 printf("\n");
544 }
545 free(nume_img_sursa);
546}
547
548int main()
549{
550 menu_C11();
551 return 0;
552}