Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.60 KB | None | 0 0
  1. /*
  2. * \file imageProcessor.c
  3. * \author Megyesi, Balazs Karoly
  4. * \date 19.06.2015.
  5. *
  6. * \brief Different image processor functions.
  7. */
  8.  
  9.  
  10. /* ------------------------------------------------------------ */
  11. /* Include File Definitions */
  12. /* ------------------------------------------------------------ */
  13.  
  14. #include <limits.h>
  15.  
  16. #include "arm_neon.h"
  17.  
  18. #include "xil_types.h"
  19. #include "xil_cache.h"
  20.  
  21. #include "imageProcessor.h"
  22. #include "vga_modes.h"
  23.  
  24. /* ------------------------------------------------------------ */
  25. /* Global constants */
  26. /* ------------------------------------------------------------ */
  27.  
  28. static const s8 filterEdge[3][3] =
  29. {
  30. {-1, -1, -1},
  31. {-1, 8, -1},
  32. {-1, -1, -1}
  33. };
  34.  
  35. static const s8 filterEmboss[3][3] =
  36. {
  37. {-2, -1, 0},
  38. {-1, 1, 1},
  39. { 0, 1, 2}
  40. };
  41.  
  42. /* ------------------------------------------------------------ */
  43. /* Local function declarations */
  44. /* ------------------------------------------------------------ */
  45.  
  46. // Unused attribute suppresses warning if function is not used
  47. static void BypassImage(rgbType* frameInput, rgbType* frameOutput, int brightness) __attribute__((unused));
  48. static void BypassImageNeon(rgbType* frameInput, rgbType* frameOutput, int brightness) __attribute__((unused));
  49.  
  50. static void SampleImageProcessing(rgbType* frameInput, rgbType* frameOutput, int contrast) __attribute__((unused));
  51. static void SampleImageProcessingNeon(rgbType* frameInput, rgbType* frameOutput) __attribute__((unused));
  52.  
  53. /* ------------------------------------------------------------ */
  54. /* Function implementations */
  55. /* ------------------------------------------------------------ */
  56.  
  57.  
  58.  
  59. // 1. feladat - vilagositas beallitasa
  60.  
  61.  
  62. int saturation(int value, int add)
  63. {
  64.  
  65. if((value +add) < 0) return 0;
  66. else if((value + add) > 255) return 255;
  67. else{return (value+ add);}
  68.  
  69. }
  70.  
  71.  
  72. /*
  73. * Wrapper function for different image processing algorithms
  74. */
  75. void RunImageProcessing(rgbType* frameInput, rgbType* frameOutput)
  76. {
  77. //BypassImage(frameInput, frameOutput, 1);
  78. //BypassImageNeon(frameInput, frameOutput, -150);
  79. //SampleImageProcessing(frameInput, frameOutput, 8);
  80. SampleImageProcessingNeon(frameInput, frameOutput );
  81. }
  82.  
  83.  
  84. /*
  85. * Bypasses incoming images.
  86. *
  87. * Runtime (-O3, -fno-tree-vectorize, -fno-prefetch-loop-arrays): 3.87ms
  88. */
  89. static void BypassImage(rgbType* frameInput, rgbType* frameOutput, int brightness)
  90. {
  91. u32 i;
  92.  
  93. for (i = 0; i < VMODE_640x480.size; i++)
  94. { // Plain pixel copy
  95.  
  96. frameOutput[i].red = saturation(frameInput[i].red, brightness);
  97. frameOutput[i].green = saturation(frameInput[i].green, brightness);
  98. frameOutput[i].blue = saturation(frameInput[i].blue, brightness);
  99. }
  100. }
  101.  
  102.  
  103. /*
  104. * Bypasses incoming images with NEON instructions.
  105. *
  106. * Runtime (-O3): 2.85ms
  107. */
  108. static void BypassImageNeon(rgbType* frameInput, rgbType* frameOutput, int brightness)
  109. {
  110. // Vector variable
  111. uint8x16x4_t pixelVectorArray;
  112.  
  113. u32 i;
  114.  
  115. for (i = 0; i < VMODE_640x480.size; i += 16)
  116. {
  117. // Load pixel vector
  118. pixelVectorArray = vld4q_u8((u8*)&frameInput[i]);
  119.  
  120.  
  121. if(brightness > 0)
  122. {
  123. pixelVectorArray.val[0] = vqaddq_u8( pixelVectorArray.val[0], vdupq_n_u8(brightness));
  124. pixelVectorArray.val[1] = vqaddq_u8( pixelVectorArray.val[1], vdupq_n_u8(brightness));
  125. pixelVectorArray.val[2] = vqaddq_u8( pixelVectorArray.val[2], vdupq_n_u8(brightness));
  126.  
  127. }
  128. else
  129. {
  130. pixelVectorArray.val[0] = vqsubq_u8( pixelVectorArray.val[0], vdupq_n_u8(-brightness));
  131. pixelVectorArray.val[1] = vqsubq_u8( pixelVectorArray.val[1], vdupq_n_u8(-brightness));
  132. pixelVectorArray.val[2] = vqsubq_u8( pixelVectorArray.val[2], vdupq_n_u8(-brightness));
  133.  
  134.  
  135. }
  136.  
  137. // Copy the result back to DDRAM
  138. vst4q_u8((u8*)&frameOutput[i], pixelVectorArray);
  139. }
  140. }
  141.  
  142.  
  143. /*
  144. * Sample image processing code. It eliminates green channel.
  145. *
  146. * Runtime (-O3, -fno-tree-vectorize, -fno-prefetch-loop-arrays): 4.80ms
  147. */
  148. static void SampleImageProcessing(rgbType* frameInput, rgbType* frameOutput, int contrast)
  149. {
  150. u32 i;
  151.  
  152. for (i = 0; i < VMODE_640x480.size; i++)
  153. {
  154.  
  155.  
  156. s16 red = (((frameInput[i].red - 128) * contrast) >> 4) + 128;
  157. s16 green = (((frameInput[i].green - 128) * contrast) >> 4) + 128;
  158. s16 blue = (((frameInput[i].blue - 128) * contrast) >> 4) + 128;
  159.  
  160. frameOutput[i].red = saturation(red, 0);
  161. frameOutput[i].green = saturation(green, 0);
  162. frameOutput[i].blue = saturation(blue, 0);
  163.  
  164. }
  165. }
  166.  
  167.  
  168. /*
  169. * Sample image processing code with NEON instructions. It eliminates green channel.
  170. *
  171. * Runtime (-O3): 2.91ms
  172. */
  173.  
  174.  
  175.  
  176.  
  177.  
  178. static void SampleImageProcessingNeon(rgbType* frameInput, rgbType* frameOutput)
  179. {
  180.  
  181.  
  182.  
  183.  
  184. // Vector variable
  185. uint8x8x4_t pixelVectorArray;
  186. int16x8x4_t pixelVectorArray_new;
  187.  
  188. u32 i;
  189.  
  190. for (i = 0; i < VMODE_640x480.size; i += 8)
  191. {
  192. // Load pixel vector
  193. pixelVectorArray = vld4_u8((u8*)&frameInput[i]);
  194.  
  195. // Vector containing green channels is set to zero
  196. s16 shift = 128;
  197. s8 contrast = 7;
  198.  
  199. for(int i = 0; i < 3; i++)
  200. {
  201. pixelVectorArray_new.val[i] = (int16x8_t)vmovl_u8(pixelVectorArray.val[i]);
  202. pixelVectorArray_new.val[i] = vqsubq_s16(pixelVectorArray_new.val[i], vdupq_n_s16(shift));
  203. pixelVectorArray_new.val[i] = vmulq_n_s16(pixelVectorArray_new.val[i], contrast);
  204. pixelVectorArray_new.val[i] = vshrq_n_s16(pixelVectorArray_new.val[i], 4);
  205. pixelVectorArray_new.val[i] = vqaddq_s16(pixelVectorArray_new.val[i], vdupq_n_s16(shift));
  206. pixelVectorArray.val[i] = vqmovun_s16(pixelVectorArray_new.val[i]);
  207.  
  208.  
  209. }
  210.  
  211. // Copy the result back to DDRAM
  212. vst4_u8((u8*)&frameOutput[i], pixelVectorArray);
  213. }
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement