17a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
27a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis/* mips_init.c - MSA optimised filter functions
37a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis *
47a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * Copyright (c) 2016 Glenn Randers-Pehrson
57a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * Written by Mandar Sahastrabuddhe, 2016.
6851c67770f9cebece9c79e914a54c348f539a512Matt Sarett * Last changed in libpng 1.6.25 [September 1, 2016]
77a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis *
87a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * This code is released under the libpng license.
97a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * For conditions of distribution and use, see the disclaimer
107a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * and license in png.h
117a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis */
127a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
137a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * called.
147a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis */
157a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#define _POSIX_SOURCE 1
167a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
177a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#include <stdio.h>
187a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#include "../pngpriv.h"
197a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
207a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifdef PNG_READ_SUPPORTED
217a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
227a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#if PNG_MIPS_MSA_OPT > 0
237a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED /* Do run-time checks */
247a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis/* WARNING: it is strongly recommended that you do not build libpng with
257a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * run-time checks for CPU features if at all possible.  In the case of the MIPS
267a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * MSA instructions there is no processor-specific way of detecting the
277a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * presence of the required support, therefore run-time detection is extremely
287a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * OS specific.
297a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis *
307a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * You may set the macro PNG_MIPS_MSA_FILE to the file name of file containing
317a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * a fragment of C source code which defines the png_have_msa function.  There
327a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * are a number of implementations in contrib/mips-msa, but the only one that
337a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * has partial support is contrib/mips-msa/linux.c - a generic Linux
347a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * implementation which reads /proc/cpufino.
357a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis */
367a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifndef PNG_MIPS_MSA_FILE
377a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#  ifdef __linux__
387a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#     define PNG_MIPS_MSA_FILE "contrib/mips-msa/linux.c"
397a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#  endif
407a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif
417a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
427a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifdef PNG_MIPS_MSA_FILE
437a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
447a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#include <signal.h> /* for sig_atomic_t */
457a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidisstatic int png_have_msa(png_structp png_ptr);
467a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#include PNG_MIPS_MSA_FILE
477a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
487a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#else  /* PNG_MIPS_MSA_FILE */
497a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#  error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks"
507a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif /* PNG_MIPS_MSA_FILE */
517a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
527a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
537a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
547a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#  error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
557a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif
567a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
577a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidisvoid
587a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidispng_init_filter_functions_msa(png_structp pp, unsigned int bpp)
597a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis{
607a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   /* The switch statement is compiled in for MIPS_MSA_API, the call to
617a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * png_have_msa is compiled in for MIPS_MSA_CHECK. If both are defined
627a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * the check is only performed if the API has not set the MSA option on
637a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * or off explicitly. In this case the check controls what happens.
647a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    */
657a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
667a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifdef PNG_MIPS_MSA_API_SUPPORTED
677a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   switch ((pp->options >> PNG_MIPS_MSA) & 3)
687a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   {
697a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      case PNG_OPTION_UNSET:
707a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis         /* Allow the run-time check to execute if it has been enabled -
717a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis          * thus both API and CHECK can be turned on.  If it isn't supported
727a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis          * this case will fall through to the 'default' below, which just
737a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis          * returns.
747a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis          */
757a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif /* PNG_MIPS_MSA_API_SUPPORTED */
767a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
777a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis         {
787a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis            static volatile sig_atomic_t no_msa = -1; /* not checked */
797a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
807a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis            if (no_msa < 0)
817a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis               no_msa = !png_have_msa(pp);
827a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
837a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis            if (no_msa)
847a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis               return;
857a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis         }
867a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifdef PNG_MIPS_MSA_API_SUPPORTED
877a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis         break;
887a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif
897a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
907a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
917a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#ifdef PNG_MIPS_MSA_API_SUPPORTED
927a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      default: /* OFF or INVALID */
937a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis         return;
947a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
957a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      case PNG_OPTION_ON:
967a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis         /* Option turned on */
977a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis         break;
987a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   }
997a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif
1007a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
1017a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   /* IMPORTANT: any new external functions used here must be declared using
1027a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * PNG_INTERNAL_FUNCTION in ../pngpriv.h.  This is required so that the
1037a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * 'prefix' option to configure works:
1047a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    *
1057a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    *    ./configure --with-libpng-prefix=foobar_
1067a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    *
1077a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * Verify you have got this right by running the above command, doing a build
1087a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * and examining pngprefix.h; it must contain a #define for every external
1097a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * function you add.  (Notice that this happens automatically for the
1107a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    * initialization function.)
1117a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis    */
1127a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_msa;
1137a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
1147a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   if (bpp == 3)
1157a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   {
1167a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_msa;
1177a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_msa;
1187a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_msa;
1197a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   }
1207a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis
1217a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   else if (bpp == 4)
1227a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   {
1237a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_msa;
1247a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_msa;
1257a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_msa;
1267a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis   }
1277a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis}
1287a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif /* PNG_MIPS_MSA_OPT > 0 */
1297a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis#endif /* READ */
130