mips_init.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* mips_init.c - MSA optimised filter functions
  2. *
  3. * Copyright (c) 2018 Cosmin Truta
  4. * Copyright (c) 2016 Glenn Randers-Pehrson
  5. * Written by Mandar Sahastrabuddhe, 2016.
  6. *
  7. * This code is released under the libpng license.
  8. * For conditions of distribution and use, see the disclaimer
  9. * and license in png.h
  10. */
  11. /* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
  12. * called.
  13. */
  14. #define _POSIX_SOURCE 1
  15. #include <stdio.h>
  16. #include "../pngpriv.h"
  17. #ifdef PNG_READ_SUPPORTED
  18. #if PNG_MIPS_MSA_OPT > 0
  19. #ifdef PNG_MIPS_MSA_CHECK_SUPPORTED /* Do run-time checks */
  20. /* WARNING: it is strongly recommended that you do not build libpng with
  21. * run-time checks for CPU features if at all possible. In the case of the MIPS
  22. * MSA instructions there is no processor-specific way of detecting the
  23. * presence of the required support, therefore run-time detection is extremely
  24. * OS specific.
  25. *
  26. * You may set the macro PNG_MIPS_MSA_FILE to the file name of file containing
  27. * a fragment of C source code which defines the png_have_msa function. There
  28. * are a number of implementations in contrib/mips-msa, but the only one that
  29. * has partial support is contrib/mips-msa/linux.c - a generic Linux
  30. * implementation which reads /proc/cpufino.
  31. */
  32. #ifndef PNG_MIPS_MSA_FILE
  33. # ifdef __linux__
  34. # define PNG_MIPS_MSA_FILE "contrib/mips-msa/linux.c"
  35. # endif
  36. #endif
  37. #ifdef PNG_MIPS_MSA_FILE
  38. #include <signal.h> /* for sig_atomic_t */
  39. static int png_have_msa(png_structp png_ptr);
  40. #error #include PNG_MIPS_MSA_FILE
  41. #else /* PNG_MIPS_MSA_FILE */
  42. # error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks"
  43. #endif /* PNG_MIPS_MSA_FILE */
  44. #endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
  45. #ifndef PNG_ALIGNED_MEMORY_SUPPORTED
  46. # error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
  47. #endif
  48. void
  49. png_init_filter_functions_msa(png_structp pp, unsigned int bpp)
  50. {
  51. /* The switch statement is compiled in for MIPS_MSA_API, the call to
  52. * png_have_msa is compiled in for MIPS_MSA_CHECK. If both are defined
  53. * the check is only performed if the API has not set the MSA option on
  54. * or off explicitly. In this case the check controls what happens.
  55. */
  56. #ifdef PNG_MIPS_MSA_API_SUPPORTED
  57. switch ((pp->options >> PNG_MIPS_MSA) & 3)
  58. {
  59. case PNG_OPTION_UNSET:
  60. /* Allow the run-time check to execute if it has been enabled -
  61. * thus both API and CHECK can be turned on. If it isn't supported
  62. * this case will fall through to the 'default' below, which just
  63. * returns.
  64. */
  65. #endif /* PNG_MIPS_MSA_API_SUPPORTED */
  66. #ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
  67. {
  68. static volatile sig_atomic_t no_msa = -1; /* not checked */
  69. if (no_msa < 0)
  70. no_msa = !png_have_msa(pp);
  71. if (no_msa)
  72. return;
  73. }
  74. #ifdef PNG_MIPS_MSA_API_SUPPORTED
  75. break;
  76. #endif
  77. #endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
  78. #ifdef PNG_MIPS_MSA_API_SUPPORTED
  79. default: /* OFF or INVALID */
  80. return;
  81. case PNG_OPTION_ON:
  82. /* Option turned on */
  83. break;
  84. }
  85. #endif
  86. /* IMPORTANT: any new external functions used here must be declared using
  87. * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
  88. * 'prefix' option to configure works:
  89. *
  90. * ./configure --with-libpng-prefix=foobar_
  91. *
  92. * Verify you have got this right by running the above command, doing a build
  93. * and examining pngprefix.h; it must contain a #define for every external
  94. * function you add. (Notice that this happens automatically for the
  95. * initialization function.)
  96. */
  97. pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_msa;
  98. if (bpp == 3)
  99. {
  100. pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_msa;
  101. pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_msa;
  102. pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_msa;
  103. }
  104. else if (bpp == 4)
  105. {
  106. pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_msa;
  107. pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_msa;
  108. pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_msa;
  109. }
  110. }
  111. #endif /* PNG_MIPS_MSA_OPT > 0 */
  112. #endif /* READ */