mips_init.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* mips_init.c - MSA optimised filter functions
  2. *
  3. * Copyright (c) 2018-2024 Cosmin Truta
  4. * Copyright (c) 2016 Glenn Randers-Pehrson
  5. * Written by Mandar Sahastrabuddhe, 2016
  6. * Updated by guxiwei, 2023
  7. *
  8. * This code is released under the libpng license.
  9. * For conditions of distribution and use, see the disclaimer
  10. * and license in png.h
  11. */
  12. /* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
  13. * called.
  14. */
  15. #define _POSIX_SOURCE 1
  16. #include <stdio.h>
  17. #include "../pngpriv.h"
  18. #ifdef PNG_READ_SUPPORTED
  19. #if PNG_MIPS_MSA_IMPLEMENTATION == 1 || PNG_MIPS_MMI_IMPLEMENTATION > 0
  20. #ifdef PNG_MIPS_MSA_CHECK_SUPPORTED /* Do MIPS MSA run-time checks */
  21. /* WARNING: it is strongly recommended that you do not build libpng with
  22. * run-time checks for CPU features if at all possible. In the case of the MIPS
  23. * MSA instructions there is no processor-specific way of detecting the
  24. * presence of the required support, therefore run-time detection is extremely
  25. * OS specific.
  26. *
  27. * You may set the macro PNG_MIPS_MSA_FILE to the file name of file containing
  28. * a fragment of C source code which defines the png_have_msa function. There
  29. * are a number of implementations in contrib/mips-msa, but the only one that
  30. * has partial support is contrib/mips-msa/linux.c - a generic Linux
  31. * implementation which reads /proc/cpufino.
  32. */
  33. #ifndef PNG_MIPS_MSA_FILE
  34. # ifdef __linux__
  35. # define PNG_MIPS_MSA_FILE "contrib/mips-msa/linux.c"
  36. # endif
  37. #endif
  38. #ifdef PNG_MIPS_MSA_FILE
  39. #include <signal.h> /* for sig_atomic_t */
  40. static int png_have_msa(png_structp png_ptr);
  41. #error #include PNG_MIPS_MSA_FILE
  42. #else /* PNG_MIPS_MSA_FILE */
  43. # error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks"
  44. #endif /* PNG_MIPS_MSA_FILE */
  45. #endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
  46. #ifdef PNG_MIPS_MMI_CHECK_SUPPORTED /* Do MIPS MMI run-times checks */
  47. #ifndef PNG_MIPS_MMI_FILE
  48. # ifdef __linux__
  49. # define PNG_MIPS_MMI_FILE "contrib/mips-mmi/linux.c"
  50. # endif
  51. #endif
  52. #ifdef PNG_MIPS_MMI_FILE
  53. #include <signal.h> /* for sig_atomic_t */
  54. static int png_have_mmi();
  55. #error #include PNG_MIPS_MMI_FILE
  56. #else /* PNG_MIPS_MMI_FILE */
  57. # error "PNG_MIPS_MMI_FILE undefined: no support for run-time MIPS MMI checks"
  58. #endif /* PNG_MIPS_MMI_FILE */
  59. #endif /* PNG_MIPS_MMI_CHECK_SUPPORTED*/
  60. #ifndef PNG_ALIGNED_MEMORY_SUPPORTED
  61. # error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
  62. #endif
  63. /* MIPS supports two optimizations: MMI and MSA. The appropriate
  64. * optimization is chosen at runtime
  65. */
  66. void
  67. png_init_filter_functions_mips(png_structp pp, unsigned int bpp)
  68. {
  69. #if PNG_MIPS_MMI_IMPLEMENTATION > 0
  70. #ifdef PNG_MIPS_MMI_API_SUPPORTED
  71. switch ((pp->options >> PNG_MIPS_MMI) & 3)
  72. {
  73. case PNG_OPTION_UNSET:
  74. #endif /* PNG_MIPS_MMI_API_SUPPORTED */
  75. #ifdef PNG_MIPS_MMI_CHECK_SUPPORTED
  76. {
  77. static volatile sig_atomic_t no_mmi = -1; /* not checked */
  78. if (no_mmi < 0)
  79. no_mmi = !png_have_mmi();
  80. if (no_mmi)
  81. goto MIPS_MSA_INIT;
  82. }
  83. #ifdef PNG_MIPS_MMI_API_SUPPORTED
  84. break;
  85. #endif
  86. #endif /* PNG_MIPS_MMI_CHECK_SUPPORTED */
  87. #ifdef PNG_MIPS_MMI_API_SUPPORTED
  88. default: /* OFF or INVALID */
  89. goto MIPS_MSA_INIT;
  90. case PNG_OPTION_ON:
  91. /* Option turned on */
  92. break;
  93. }
  94. #endif
  95. pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_mmi;
  96. if (bpp == 3)
  97. {
  98. pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_mmi;
  99. pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_mmi;
  100. pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
  101. png_read_filter_row_paeth3_mmi;
  102. }
  103. else if (bpp == 4)
  104. {
  105. pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_mmi;
  106. pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_mmi;
  107. pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
  108. png_read_filter_row_paeth4_mmi;
  109. }
  110. #endif /* PNG_MIPS_MMI_IMPLEMENTATION > 0 */
  111. MIPS_MSA_INIT:
  112. #if PNG_MIPS_MSA_IMPLEMENTATION == 1
  113. /* The switch statement is compiled in for MIPS_MSA_API, the call to
  114. * png_have_msa is compiled in for MIPS_MSA_CHECK. If both are defined
  115. * the check is only performed if the API has not set the MSA option on
  116. * or off explicitly. In this case the check controls what happens.
  117. */
  118. #ifdef PNG_MIPS_MSA_API_SUPPORTED
  119. switch ((pp->options >> PNG_MIPS_MSA) & 3)
  120. {
  121. case PNG_OPTION_UNSET:
  122. /* Allow the run-time check to execute if it has been enabled -
  123. * thus both API and CHECK can be turned on. If it isn't supported
  124. * this case will fall through to the 'default' below, which just
  125. * returns.
  126. */
  127. #endif /* PNG_MIPS_MSA_API_SUPPORTED */
  128. #ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
  129. {
  130. static volatile sig_atomic_t no_msa = -1; /* not checked */
  131. if (no_msa < 0)
  132. no_msa = !png_have_msa(pp);
  133. if (no_msa)
  134. return;
  135. }
  136. #ifdef PNG_MIPS_MSA_API_SUPPORTED
  137. break;
  138. #endif
  139. #endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
  140. #ifdef PNG_MIPS_MSA_API_SUPPORTED
  141. default: /* OFF or INVALID */
  142. return;
  143. case PNG_OPTION_ON:
  144. /* Option turned on */
  145. break;
  146. }
  147. #endif
  148. /* IMPORTANT: any new external functions used here must be declared using
  149. * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
  150. * 'prefix' option to configure works:
  151. *
  152. * ./configure --with-libpng-prefix=foobar_
  153. *
  154. * Verify you have got this right by running the above command, doing a build
  155. * and examining pngprefix.h; it must contain a #define for every external
  156. * function you add. (Notice that this happens automatically for the
  157. * initialization function.)
  158. */
  159. pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_msa;
  160. if (bpp == 3)
  161. {
  162. pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_msa;
  163. pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_msa;
  164. pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_msa;
  165. }
  166. else if (bpp == 4)
  167. {
  168. pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_msa;
  169. pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_msa;
  170. pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_msa;
  171. }
  172. #endif /* PNG_MIPS_MSA_IMPLEMENTATION == 1 */
  173. return;
  174. }
  175. #endif /* PNG_MIPS_MSA_IMPLEMENTATION == 1 || PNG_MIPS_MMI_IMPLEMENTATION > 0 */
  176. #endif /* READ */