Advertisement
Guest User

Untitled

a guest
Jul 29th, 2016
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.75 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <arm_neon.h>
  5.  
  6. #define N 8
  7.  
  8. int read_bmp(FILE *f, unsigned char **image);
  9. void write_bmp(FILE *f, unsigned char *image);
  10. void rgb_to_yuv420(unsigned char rgb[16][48], unsigned char y[16][16], unsigned char u[8][8], unsigned char v[8][8]);
  11. void yuv420_to_rgb(unsigned char y[16][16], unsigned char u[8][8], unsigned char v[8][8], unsigned char rgb[16][48]);
  12.  
  13. void convert_rgb_to_yuv420();
  14. void convert_yuv420_to_rgb();
  15. void extend_borders();
  16. void perform_filtering();
  17.  
  18. int XSIZE, YSIZE;
  19. unsigned char *rgb_pic;
  20. unsigned char *y_pic;
  21. unsigned char *y_pic2;
  22. unsigned char *u_pic;
  23. unsigned char *v_pic;
  24. unsigned char rgb_buff[16][48];
  25. unsigned char y_buff[16][16];
  26. unsigned char y_buff11x11[11][11];
  27. unsigned char y_buff8x8[8][8];
  28. unsigned char u_buff[8][8];
  29. unsigned char v_buff[8][8];
  30. short dct_coefs[8][8];
  31. short dct_coefs2[8][8];
  32.  
  33.  
  34. int main(int argc, char **argv)
  35. {
  36. FILE *f;
  37.  
  38. if (argc != 3)
  39. {
  40. printf("You must specify input and output file\n");
  41. return -1;
  42. }
  43.  
  44. f = fopen(argv[1], "rb");
  45. if (read_bmp(f, &rgb_pic) == 0)
  46. {
  47. printf("Error loading input file\n");
  48. return -1;
  49. }
  50. fclose(f);
  51.  
  52. if ((XSIZE & 0xf) | (YSIZE & 0xf))
  53. {
  54. printf("Image size must be a multiple of 16x16\n");
  55. return -1;
  56. }
  57.  
  58. y_pic = (unsigned char *)malloc((XSIZE+16)*(YSIZE+16));
  59. y_pic2 = (unsigned char *)malloc((XSIZE+16)*(YSIZE+16));
  60. u_pic = (unsigned char *)malloc((XSIZE+16)*(YSIZE+16)/4);
  61. v_pic = (unsigned char *)malloc((XSIZE+16)*(YSIZE+16)/4);
  62.  
  63. convert_rgb_to_yuv420();
  64. extend_borders();
  65. perform_filtering();
  66. convert_yuv420_to_rgb();
  67.  
  68. f = fopen(argv[2], "wb");
  69. write_bmp(f, rgb_pic);
  70. fclose(f);
  71.  
  72. free(rgb_pic);
  73. free(y_pic);
  74. free(y_pic2);
  75. free(u_pic);
  76. free(v_pic);
  77.  
  78. return 0;
  79. }
  80.  
  81. void convert_rgb_to_yuv420()
  82. {
  83. int x, y, i, j;
  84.  
  85. for (y=0; y<YSIZE/16; y++)
  86. {
  87. for (x=0; x<XSIZE/16; x++)
  88. {
  89. for (j=0; j<16; j++)
  90. {
  91. for (i=0; i<48; i++)
  92. {
  93. rgb_buff[j][i] = rgb_pic[(16*y+j)*3*XSIZE+48*x+i];
  94. }
  95. }
  96.  
  97. rgb_to_yuv420(rgb_buff, y_buff, u_buff, v_buff);
  98.  
  99. for (j=0; j<8; j++)
  100. {
  101. for (i=0; i<8; i++)
  102. {
  103. y_pic[(16*y+2*j+8)*(XSIZE+16)+16*x+2*i+8] = y_buff[2*j][2*i];
  104. y_pic[(16*y+2*j+8)*(XSIZE+16)+16*x+2*i+9] = y_buff[2*j][2*i+1];
  105. y_pic[(16*y+2*j+9)*(XSIZE+16)+16*x+2*i+8] = y_buff[2*j+1][2*i];
  106. y_pic[(16*y+2*j+9)*(XSIZE+16)+16*x+2*i+9] = y_buff[2*j+1][2*i+1];
  107. u_pic[(8*y+j+4)*(XSIZE/2+8)+8*x+i+4] = u_buff[j][i];
  108. v_pic[(8*y+j+4)*(XSIZE/2+8)+8*x+i+4] = v_buff[j][i];
  109. }
  110. }
  111. }
  112. }
  113. }
  114.  
  115. void convert_yuv420_to_rgb()
  116. {
  117. int x, y, i, j;
  118.  
  119. for (y=0; y<YSIZE/16; y++)
  120. {
  121. for (x=0; x<XSIZE/16; x++)
  122. {
  123. for (j=0; j<8; j++)
  124. {
  125. for (i=0; i<8; i++)
  126. {
  127. y_buff[2*j ][2*i ] = y_pic2[(16*y+2*j+8)*(XSIZE+16)+16*x+2*i+8];
  128. y_buff[2*j ][2*i+1] = y_pic2[(16*y+2*j+8)*(XSIZE+16)+16*x+2*i+9];
  129. y_buff[2*j+1][2*i ] = y_pic2[(16*y+2*j+9)*(XSIZE+16)+16*x+2*i+8];
  130. y_buff[2*j+1][2*i+1] = y_pic2[(16*y+2*j+9)*(XSIZE+16)+16*x+2*i+9];
  131. u_buff[j][i] = u_pic[(8*y+j+4)*(XSIZE/2+8)+8*x+i+4];
  132. v_buff[j][i] = v_pic[(8*y+j+4)*(XSIZE/2+8)+8*x+i+4];
  133. }
  134. }
  135.  
  136. yuv420_to_rgb(y_buff, u_buff, v_buff, rgb_buff);
  137.  
  138. for (j=0; j<16; j++)
  139. {
  140. for (i=0; i<48; i++)
  141. {
  142. rgb_pic[(16*y+j)*3*XSIZE+48*x+i] = rgb_buff[j][i];
  143. }
  144. }
  145. }
  146. }
  147. }
  148.  
  149. void extend_borders()
  150. {
  151. int i;
  152.  
  153. for (i=0; i<8; i++)
  154. {
  155. memcpy(&y_pic[i*(XSIZE+16)+8], &y_pic[8*(XSIZE+16)+8], XSIZE);
  156. memcpy(&y_pic[(YSIZE+8+i)*(XSIZE+16)+8], &y_pic[(YSIZE+7)*(XSIZE+16)+8], XSIZE);
  157. }
  158.  
  159. for (i=0; i<YSIZE+16; i++)
  160. {
  161. memset(&y_pic[i*(XSIZE+16)], y_pic[i*(XSIZE+16)+8], 8);
  162. memset(&y_pic[i*(XSIZE+16)+XSIZE+8], y_pic[i*(XSIZE+16)+XSIZE+7], 8);
  163. }
  164.  
  165. for (i=0; i<4; i++)
  166. {
  167. memcpy(&u_pic[i*(XSIZE/2+8)+4], &u_pic[4*(XSIZE/2+8)+4], XSIZE/2);
  168. memcpy(&u_pic[(YSIZE/2+4+i)*(XSIZE/2+8)+4], &u_pic[(YSIZE/2+3)*(XSIZE/2+8)+4], XSIZE/2);
  169. memcpy(&v_pic[i*(XSIZE/2+8)+4], &v_pic[4*(XSIZE/2+8)+4], XSIZE/2);
  170. memcpy(&v_pic[(YSIZE/2+4+i)*(XSIZE/2+8)+4], &v_pic[(YSIZE/2+3)*(XSIZE/2+8)+4], XSIZE/2);
  171. }
  172.  
  173. for (i=0; i<YSIZE/2+8; i++)
  174. {
  175. memset(&u_pic[i*(XSIZE/2+8)], u_pic[i*(XSIZE/2+8)+4], 4);
  176. memset(&u_pic[i*(XSIZE/2+8)+XSIZE/2+4], u_pic[i*(XSIZE/2+8)+XSIZE/2+3], 4);
  177. memset(&v_pic[i*(XSIZE/2+8)], v_pic[i*(XSIZE/2+8)+4], 4);
  178. memset(&v_pic[i*(XSIZE/2+8)+XSIZE/2+4], v_pic[i*(XSIZE/2+8)+XSIZE/2+3], 4);
  179. }
  180. }
  181.  
  182. void perform_filtering()
  183. {
  184. int x, y, dy;
  185. int8_t avg;
  186. uint8x8_t pixels_row;
  187. uint16x8_t row_sum;
  188. uint16x4_t row_sum_16;
  189. uint32x2_t row_sum_32;
  190. uint64x1_t row_sum_64;
  191.  
  192. for (y=0; y<YSIZE; y+= N)
  193. {
  194. for (x=0; x<XSIZE; x+= N)
  195. {
  196. //Fill vector with zeroes
  197. row_sum = vdupq_n_u16(0);
  198.  
  199. for( dy=0; dy<N; dy++)
  200. {
  201. //Calculate sum of rows, and store in int16_8_t vector
  202. pixels_row = vld1_u8((uint8_t const *) (y_pic + (y+dy+8)*(XSIZE+16)+(x+8)));
  203. row_sum = vaddw_u8(row_sum, pixels_row);
  204. }
  205. //Do a pairwise sum of vector elements
  206. row_sum_16 = vpadd_u16(vget_high_u16(row_sum), vget_low_u16(row_sum));
  207. row_sum_32 = vpaddl_u16(row_sum_16);
  208. row_sum_64 = vpaddl_u32(row_sum_32);
  209. //Average value of pixel in block
  210. avg = (int8_t)(row_sum_64>>6);
  211.  
  212. //Fill a vector with a new pixel value
  213. pixels_row = vdup_n_u8(avg);
  214.  
  215. // Write new big pixel value
  216. for( dy=0; dy<N; dy++)
  217. {
  218. vst1_u8((uint8_t *) (y_pic2 + (y+dy+8)*(XSIZE+16)+(x+8)), pixels_row);
  219. }
  220. }
  221. }
  222. }
  223.  
  224.  
  225. #pragma pack(2)
  226. typedef struct
  227. {
  228. short bfType; /* always 'BM' */
  229. int bfSize; /* size of bitmap file in bytes */
  230. short bfReserved1; /* always 0 */
  231. short bfReserved2; /* always 0 */
  232. int bfOffBits; /* offset to data for bitmap */
  233. int biSize;
  234. int biWidth;
  235. int biHeight;
  236. short biPlanes;
  237. short biBitCount;
  238. int biCompression;
  239. int biSizeImage;
  240. int biXPelsPerMeter;
  241. int biYPelsPerMeter;
  242. int biClrUsed;
  243. int biClrImportant;
  244. } BITMAPFILEHEADER;
  245. #pragma pack(4)
  246.  
  247. int read_bmp(FILE *f, unsigned char **image)
  248. {
  249. BITMAPFILEHEADER bmhdr;
  250.  
  251. if (f == NULL)
  252. return 0;
  253.  
  254. fread(&bmhdr, sizeof(bmhdr), 1, f);
  255.  
  256. if (bmhdr.bfType != 0x4d42)
  257. return 0;
  258.  
  259. XSIZE = bmhdr.biWidth;
  260. YSIZE = bmhdr.biHeight;
  261. if (YSIZE < 0)
  262. YSIZE = -YSIZE;
  263.  
  264. *image = (unsigned char *)malloc(XSIZE*YSIZE*3);
  265. fread(*image, 1, XSIZE*YSIZE*3, f);
  266.  
  267. return 1;
  268. }
  269.  
  270. void write_bmp(FILE *f, unsigned char *image)
  271. {
  272. BITMAPFILEHEADER bmhdr = { 0x4d42, 3*XSIZE*YSIZE+54, 0, 0, 54, 40, XSIZE, YSIZE, 1, 24, 0, 0, 100, 100, 0, 0};
  273.  
  274. if (f)
  275. {
  276. fwrite(&bmhdr, 54, 1, f);
  277. fwrite(image, 1, 3*XSIZE*YSIZE, f);
  278. }
  279. }
  280.  
  281. void rgb_to_yuv420(unsigned char rgb[16][48], unsigned char y[16][16], unsigned char u[8][8], unsigned char v[8][8])
  282. {
  283. int i, j;
  284. int Y, U, V;
  285.  
  286. for (j=0; j<8; j++)
  287. {
  288. for (i=0; i<8; i++)
  289. {
  290. Y = 66 * rgb[2*j][6*i+2] + 129 * rgb[2*j][6*i+1] + 25 * rgb[2*j][6*i];
  291. U = - 38 * rgb[2*j][6*i+2] - 74 * rgb[2*j][6*i+1] + 112 * rgb[2*j][6*i];
  292. V = 112 * rgb[2*j][6*i+2] - 94 * rgb[2*j][6*i+1] - 18 * rgb[2*j][6*i];
  293.  
  294. Y = (Y + 128) >> 8;
  295. y[2*j][2*i] = Y + 16;
  296.  
  297. Y = 66 * rgb[2*j][6*i+5] + 129 * rgb[2*j][6*i+4] + 25 * rgb[2*j][6*i+3];
  298. U += - 38 * rgb[2*j][6*i+5] - 74 * rgb[2*j][6*i+4] + 112 * rgb[2*j][6*i+3];
  299. V += 112 * rgb[2*j][6*i+5] - 94 * rgb[2*j][6*i+4] - 18 * rgb[2*j][6*i+3];
  300.  
  301. Y = (Y + 128) >> 8;
  302. y[2*j][2*i+1] = Y + 16;
  303.  
  304. Y = 66 * rgb[2*j+1][6*i+2] + 129 * rgb[2*j+1][6*i+1] + 25 * rgb[2*j+1][6*i];
  305. U += - 38 * rgb[2*j+1][6*i+2] - 74 * rgb[2*j+1][6*i+1] + 112 * rgb[2*j+1][6*i];
  306. V += 112 * rgb[2*j+1][6*i+2] - 94 * rgb[2*j+1][6*i+1] - 18 * rgb[2*j+1][6*i];
  307.  
  308. Y = (Y + 128) >> 8;
  309. y[2*j+1][2*i] = Y + 16;
  310.  
  311. Y = 66 * rgb[2*j+1][6*i+5] + 129 * rgb[2*j+1][6*i+4] + 25 * rgb[2*j+1][6*i+3];
  312. U += - 38 * rgb[2*j+1][6*i+5] - 74 * rgb[2*j+1][6*i+4] + 112 * rgb[2*j+1][6*i+3];
  313. V += 112 * rgb[2*j+1][6*i+5] - 94 * rgb[2*j+1][6*i+4] - 18 * rgb[2*j+1][6*i+3];
  314.  
  315. Y = (Y + 128) >> 8;
  316. y[2*j+1][2*i+1] = Y + 16;
  317.  
  318. U = (U + 512) >> 10;
  319. u[j][i] = U + 128;
  320.  
  321. V = (V + 512) >> 10;
  322. v[j][i] = V + 128;
  323. }
  324. }
  325. }
  326.  
  327. void yuv420_to_rgb(unsigned char y[16][16], unsigned char u[8][8], unsigned char v[8][8], unsigned char rgb[16][48])
  328. {
  329. int i, j, Y, U, V, UV, r, g, b;
  330.  
  331. for (j=0; j<8; j++)
  332. {
  333. for (i=0; i<8; i++)
  334. {
  335. U = u[j][i] - 128;
  336. V = v[j][i] - 128;
  337.  
  338. UV = -6657 * U - 13424 * V;
  339. U = 33311 * U;
  340. V = 26355 * V;
  341.  
  342. Y = 19077 * (y[2*j][2*i] - 16);
  343.  
  344. r = (Y + V) >> 14;
  345. if (r < 0)
  346. r = 0;
  347. else if (r > 255)
  348. r = 255;
  349. g = (Y + UV) >> 14;
  350. if (g < 0)
  351. g = 0;
  352. else if (g > 255)
  353. g = 255;
  354. b = (Y + U) >> 14;
  355. if (b < 0)
  356. b = 0;
  357. else if (b > 255)
  358. b = 255;
  359.  
  360. rgb[2*j][6*i ] = b;
  361. rgb[2*j][6*i+1] = g;
  362. rgb[2*j][6*i+2] = r;
  363.  
  364. Y = 19077 * (y[2*j][2*i+1] - 16);
  365.  
  366. r = (Y + V) >> 14;
  367. if (r < 0)
  368. r = 0;
  369. else if (r > 255)
  370. r = 255;
  371. g = (Y + UV) >> 14;
  372. if (g < 0)
  373. g = 0;
  374. else if (g > 255)
  375. g = 255;
  376. b = (Y + U) >> 14;
  377. if (b < 0)
  378. b = 0;
  379. else if (b > 255)
  380. b = 255;
  381.  
  382. rgb[2*j][6*i+3] = b;
  383. rgb[2*j][6*i+4] = g;
  384. rgb[2*j][6*i+5] = r;
  385.  
  386. Y = 19077 * (y[2*j+1][2*i] - 16);
  387.  
  388. r = (Y + V) >> 14;
  389. if (r < 0)
  390. r = 0;
  391. else if (r > 255)
  392. r = 255;
  393. g = (Y + UV) >> 14;
  394. if (g < 0)
  395. g = 0;
  396. else if (g > 255)
  397. g = 255;
  398. b = (Y + U) >> 14;
  399. if (b < 0)
  400. b = 0;
  401. else if (b > 255)
  402. b = 255;
  403.  
  404. rgb[2*j+1][6*i ] = b;
  405. rgb[2*j+1][6*i+1] = g;
  406. rgb[2*j+1][6*i+2] = r;
  407.  
  408. Y = 19077 * (y[2*j+1][2*i+1] - 16);
  409.  
  410. r = (Y + V) >> 14;
  411. if (r < 0)
  412. r = 0;
  413. else if (r > 255)
  414. r = 255;
  415. g = (Y + UV) >> 14;
  416. if (g < 0)
  417. g = 0;
  418. else if (g > 255)
  419. g = 255;
  420. b = (Y + U) >> 14;
  421. if (b < 0)
  422. b = 0;
  423. else if (b > 255)
  424. b = 255;
  425.  
  426. rgb[2*j+1][6*i+3] = b;
  427. rgb[2*j+1][6*i+4] = g;
  428. rgb[2*j+1][6*i+5] = r;
  429. }
  430. }
  431. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement