Advertisement
Guest User

Untitled

a guest
Jan 26th, 2020
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.55 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. typedef struct {
  6. unsigned char red,green,blue;
  7. } PPMPixel;
  8.  
  9. typedef struct {
  10. int x, y;
  11. PPMPixel *data;
  12. } PPMImage;
  13.  
  14. typedef struct {
  15. int Y,Cb,Cr;
  16. } YCbCrPixel;
  17.  
  18. typedef struct {
  19. int x, y;
  20. YCbCrPixel *data;
  21. } YCbCrImage;
  22.  
  23. //pravljenje tablica za kvantizaciju
  24.  
  25. int K1[8][8] = {
  26. {16, 11, 10, 16, 24, 40, 51, 61},
  27. {12, 12, 14, 19, 26, 58, 60, 55},
  28. {14, 13, 16, 24, 40, 57, 69, 56},
  29. {14, 17, 22, 29, 51, 87, 80, 62},
  30. {18, 22, 37, 56, 68, 109, 103, 77},
  31. {24, 35, 55, 64, 81, 104, 113, 92},
  32. {49, 64, 78, 87, 103, 121, 120, 101},
  33. {72, 92, 95, 98, 112, 100, 103, 99}
  34. };
  35.  
  36. int K2[8][8] = {
  37. {17, 18, 24, 47 ,99, 99, 99, 99},
  38. {18, 21, 26, 66, 99, 99, 99, 99},
  39. {24, 26, 56, 99, 99, 99, 99, 99},
  40. {47, 66, 99, 99, 99, 99, 99, 99},
  41. {99, 99, 99, 99, 99, 99, 99, 99},
  42. {99, 99, 99, 99, 99, 99, 99, 99},
  43. {99, 99, 99, 99, 99, 99, 99, 99},
  44. {99, 99, 99, 99, 99, 99, 99, 99}
  45. };
  46.  
  47. int T[8][8] = {
  48. {0 ,1 ,8 ,16, 9, 2, 3, 10},
  49. {17 ,24 ,32 ,25 ,18 ,11 ,4 ,5},
  50. {12 ,19 ,26 ,33 ,40 ,48, 41, 34},
  51. {27 ,20 ,13, 6, 7 ,14 ,21 ,28},
  52. {35 ,42 ,49 ,56 ,57, 50, 43, 36},
  53. {29 ,22, 15 ,23 ,30 ,37 ,44 ,51},
  54. {58 ,59 ,52 ,45, 38, 31, 39, 46},
  55. {53 ,60 ,61 ,54 ,47, 55 ,62 ,63}
  56. };
  57.  
  58. int brojI;
  59. int brojJ;
  60.  
  61. #define RGB_COMPONENT_COLOR 255
  62. #define PI 3.142857
  63. #define MAX_HIGHT 8
  64. #define MAX_WIDTH 8
  65.  
  66. static PPMImage *readFile(char *filename){
  67. char buff[16];
  68. PPMImage *img;
  69. FILE *fp;
  70. int c, rgb_comp_color;
  71. //dohvaca file
  72. fp = fopen(filename, "rb");
  73. //puni buffer sa podatcima
  74. fgets(buff, sizeof(buff), fp);
  75.  
  76. //1. "magical number" mora bit P6
  77. if (buff[0] != 'P' || buff[1] != '6') {
  78. fprintf(stderr, "Ovo nije ispravna PPM datoteka (nema P6)\n");
  79. exit(1);
  80. }
  81.  
  82. //alociranje memorije za sliku
  83. img = (PPMImage *)malloc(sizeof(PPMImage));
  84.  
  85. //rucitavanje dimenzija slike
  86. fscanf(fp, "%d %d", &img->x, &img->y);
  87.  
  88. //provjera rgb komponente (moglo bi se izbaciti)
  89.  
  90. //ucitavanje rgb komponente
  91. fscanf(fp, "%d", &rgb_comp_color);
  92.  
  93. //provjera rgb
  94. if (rgb_comp_color!= RGB_COMPONENT_COLOR){
  95. fprintf(stderr, "RGB nije 255\n");
  96. exit(1);
  97. }
  98.  
  99. //procita se prazan redak (ili vise njih)
  100. while (fgetc(fp) != '\n') ;
  101. //alociranje memorije za pixel data
  102. img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel));
  103.  
  104. //ucitava podatke o pikselima iz datoteke
  105. fread(img->data, 3 * img->x, img->y, fp);
  106.  
  107. fclose(fp);
  108. return img;
  109. }
  110.  
  111. static YCbCrImage *RGBToYCbCr(PPMImage *img){
  112. YCbCrImage *imgYCbCr;
  113. imgYCbCr = (YCbCrImage *)malloc(sizeof(YCbCrImage));
  114. //istih su dimenzija
  115. imgYCbCr->x=img->x;
  116. imgYCbCr->y=img->y;
  117. imgYCbCr->data = (YCbCrPixel*)malloc(imgYCbCr->x * imgYCbCr->y * sizeof(YCbCrPixel));
  118.  
  119. int i;
  120. //ode bi odma mogli sve smanjit za 128 samo treba paziti na pretvaranje tipova u c-u
  121.  
  122. for(i=0;i<imgYCbCr->x*imgYCbCr->y;++i){
  123. //printf("%d \n", i);
  124. int red =(int)img->data[i].red;
  125. int green =(int)img->data[i].green;
  126. int blue =(int)img->data[i].blue;
  127.  
  128. imgYCbCr->data[i].Y= (0.299*red) + (0.587*green) + (0.114*blue)-128;
  129. imgYCbCr->data[i].Cb=(-0.1687*red) - (0.3313*green) + (0.5*blue);
  130. imgYCbCr->data[i].Cr=(0.5*red) - (0.4187*green) - (0.0813*blue);
  131. }
  132. return imgYCbCr;
  133. }
  134.  
  135.  
  136. void writeFile(const char *filename, YCbCrImage *img, int sizeX, int sizeY){
  137. FILE *fp;
  138. fp = fopen(filename, "wb");
  139.  
  140. fprintf(fp, "%d %d\n",sizeX, sizeY);
  141.  
  142. int i;
  143. int j;
  144. for(i=0;i<img->x;++i){
  145. for(j=0;j<img->y;++j){
  146. fprintf(fp, "%d ",img->data[i*MAX_WIDTH+j].Y);
  147. }
  148. fprintf(fp,"\n");
  149. }
  150. fprintf(fp,"\n");
  151.  
  152. for(i=0;i<img->x;++i){
  153. for(j=0;j<img->y;++j){
  154. fprintf(fp, "%d ",img->data[i*MAX_WIDTH+j].Cb);
  155. }
  156. fprintf(fp,"\n");
  157. }
  158. fprintf(fp,"\n");
  159.  
  160. for(i=0;i<img->x;++i){
  161. for(j=0;j<img->y;++j){
  162. fprintf(fp, "%d ",img->data[i*MAX_WIDTH+j].Cr);
  163. }
  164. fprintf(fp,"\n");
  165. }
  166. fprintf(fp,"\n");
  167.  
  168. fclose(fp);
  169. }
  170.  
  171. static YCbCrImage *zmijica(YCbCrImage *image3){
  172. YCbCrImage *imgYCbCr;
  173. imgYCbCr = (YCbCrImage *)malloc(sizeof(YCbCrImage));
  174. //istih su dimenzija
  175. imgYCbCr->x=image3->x;
  176. imgYCbCr->y=image3->y;
  177. imgYCbCr->data = (YCbCrPixel*)malloc(imgYCbCr->x * imgYCbCr->y * sizeof(YCbCrPixel));
  178.  
  179.  
  180. //writeFile("prijeZmije.txt", image3, hight, width);
  181. int brojacI;
  182. int brojacJ;
  183. int index;
  184. for(brojacI=0;brojacI<MAX_HIGHT;++brojacI){
  185. for(brojacJ=0;brojacJ<MAX_WIDTH;++brojacJ){
  186. index=T[brojacI][brojacJ];
  187. imgYCbCr->data[index]=image3->data[brojacI*MAX_WIDTH+brojacJ];
  188. }
  189. }
  190.  
  191.  
  192. return imgYCbCr;
  193. }
  194.  
  195. static YCbCrPixel kvantizacija(float dctY,float dctCb,float dctCr, int m, int n){
  196.  
  197. int dctYKvantizirano=0;
  198. int dctCbKvantizirano=0;
  199. int dctCrKvantizirano=0;
  200.  
  201. dctYKvantizirano=round(dctY/(K1[m][n]*1.0));
  202. dctCbKvantizirano=round(dctCb/(K2[m][n]*1.0));
  203. dctCrKvantizirano=round(dctCr/(K2[m][n]*1.0));
  204.  
  205. YCbCrPixel pomPixel = { .Y = dctYKvantizirano, .Cb = dctCbKvantizirano, .Cr = dctCrKvantizirano };
  206.  
  207. return pomPixel;
  208. }
  209.  
  210.  
  211.  
  212.  
  213. int main(int argc, char *argv[]){
  214. //int a, b, c;
  215.  
  216. if (argc < 4 || argc > 5){
  217. printf("Potrebno je unjeti 3 argumenta");
  218. return 0;
  219. }
  220.  
  221. char *inputFileName = argv[1];
  222. int brojBloka = atoi(argv[2]);
  223. char *outputFileName = argv[3];
  224.  
  225. //printf("Broj bloka : %d\n", brojBloka);
  226.  
  227. brojJ=brojBloka%MAX_WIDTH;
  228. brojI=(brojBloka-brojJ)/MAX_WIDTH;
  229.  
  230. //printf("i : %d\n", brojI);
  231.  
  232. //printf("j : %d\n", brojJ);
  233.  
  234. PPMImage *image;
  235. image = readFile(inputFileName);
  236.  
  237. int hight = image->y;
  238. int width = image->x;
  239.  
  240. YCbCrImage *image2;
  241. image2 = RGBToYCbCr(image);
  242. //dealociranje
  243. free(image->data);
  244. free(image);
  245.  
  246. int i;
  247. int j;
  248.  
  249. for(i=0;i<hight/MAX_HIGHT;++i){
  250. for(j=0;j<width/MAX_WIDTH;++j){
  251.  
  252. //odma nakon transformacije se vrsi kvantizacija
  253.  
  254.  
  255. //alociranje nove male slike koja je veclini 8X8 - tj blok je (tu se pohranjuju podatci nakon kosinusne transformacije)
  256. YCbCrImage *image3;
  257. image3 = (YCbCrImage *)malloc(sizeof(YCbCrImage));
  258. image3->x=MAX_WIDTH;
  259. image3->y=MAX_HIGHT;
  260. image3->data = (YCbCrPixel*)malloc(image3->x * image3->y * sizeof(YCbCrPixel));
  261.  
  262. //alociranje nove male slike koja je veclini 8X8 - tj blok je u koju cemo zapisat podatke nakon zmijice
  263. YCbCrImage *image4;
  264. image4 = (YCbCrImage *)malloc(sizeof(YCbCrImage));
  265. image4->x=MAX_WIDTH;
  266. image4->y=MAX_HIGHT;
  267. image4->data = (YCbCrPixel*)malloc(image4->x * image4->y * sizeof(YCbCrPixel));
  268.  
  269. float cv;
  270. float cu;
  271.  
  272. int m;
  273. int n;
  274.  
  275. for(m=0;m<MAX_HIGHT;++m){
  276. for(n=0;n<MAX_WIDTH;++n){
  277.  
  278. //kosinusna transformacija
  279.  
  280. cv = 1.0;
  281. cu = 1.0;
  282.  
  283. if(m==0){
  284. cv=0.7071068; //korijen iz 2 korz 2
  285. }
  286. if(n==0){
  287. cu=0.7071068; //korijen iz 2 korz 2
  288. }
  289.  
  290. float sumY = 0;
  291. float dct1Y = 0;
  292. float sumCb = 0;
  293. float dct1Cb = 0;
  294. float sumCr = 0;
  295. float dct1Cr= 0;
  296. float tempConst;
  297. YCbCrPixel pomPixel;
  298. int k;
  299. int l;
  300. for (k = 0; k < MAX_HIGHT; ++k) {
  301. for (l = 0; l < MAX_WIDTH; ++l) {
  302. pomPixel = image2->data[i*MAX_WIDTH*width+j*MAX_WIDTH+k*width+l];
  303.  
  304. tempConst = cos((2 * k + 1) * m * PI / 16) * cos((2 * l + 1) * n * PI / 16);
  305.  
  306. //if(m==1&&n==1&&k==0&&l==0){
  307. // printf("TEMP KONST: %f \n", tempConst);
  308. // printf("pomPixel.Y: %d \n", pomPixel.Y);
  309. //}
  310.  
  311. dct1Y = pomPixel.Y * tempConst;
  312. sumY = sumY + dct1Y;
  313.  
  314. dct1Cb = pomPixel.Cb * tempConst;
  315. sumCb = sumCb + dct1Cb;
  316.  
  317. dct1Cr = pomPixel.Cr * tempConst;
  318. sumCr = sumCr + dct1Cr;
  319.  
  320. }
  321. }
  322. float dctY=0;
  323. float dctCb=0;
  324. float dctCr=0;
  325.  
  326. dctY = 0.25*cv*cu*sumY;
  327. dctCb = 0.25*cv*cu*sumCb;
  328. dctCr = 0.25*cv*cu*sumCr;
  329.  
  330. YCbCrPixel pomPixe2;
  331. pomPixe2 = kvantizacija(dctY, dctCb, dctCr, m, n);
  332.  
  333. image3->data[m*MAX_WIDTH+n]=pomPixe2;
  334.  
  335. }
  336.  
  337. }
  338.  
  339. image4 = zmijica(image3);
  340.  
  341. //kraj zmijice
  342. //nakon zmicijie mozemo zapisat podatke u datoteku, ako se radi o tom bloku
  343. if(i==brojI && j==brojJ){
  344. writeFile(outputFileName, image4, hight, width);
  345. }
  346.  
  347.  
  348. //zatvaranje dvaju for ptelji od i i j
  349. }
  350. }
  351.  
  352. return 0;
  353. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement