1b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* contrib/arm-neon/linux.c 2b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 3b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Copyright (c) 2014 Glenn Randers-Pehrson 4b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Written by John Bowler, 2014. 5b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Last changed in libpng 1.6.10 [March 6, 2014] 6b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 7b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * This code is released under the libpng license. 8b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * For conditions of distribution and use, see the disclaimer 9b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * and license in png.h 10b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 11b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * SEE contrib/arm-neon/README before reporting bugs 12b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 13b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * STATUS: SUPPORTED 14b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * BUG REPORTS: png-mng-implement@sourceforge.net 15b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 16b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * png_have_neon implemented for Linux by reading the widely available 17b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * pseudo-file /proc/cpuinfo. 18b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 19b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * This code is strict ANSI-C and is probably moderately portable, it does 20b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * however use <stdio.h> and assumes that /proc/cpuinfo is never localized. 21b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 22b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#include <stdio.h> 23b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 24b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic int 25b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraripng_have_neon(png_structp png_ptr) 26b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari{ 27b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari FILE *f = fopen("/proc/cpuinfo", "rb"); 28b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 29b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (f != NULL) 30b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 31b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* This is a simple state machine which reads the input byte-by-byte until 32b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * it gets a match on the 'neon' feature or reaches the end of the stream. 33b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 34b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 }; 35b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari static const char ch_neon[] = { 78, 69, 79, 78 }; 36b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 37b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari enum 38b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 39b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine 40b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } state; 41b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int counter; 42b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 43b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari for (state=StartLine, counter=0;;) 44b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 45b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari int ch = fgetc(f); 46b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 47b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch == EOF) 48b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 49b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* EOF means error or end-of-file, return false; neon at EOF is 50b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * assumed to be a mistake. 51b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 52b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari fclose(f); 53b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari return 0; 54b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 55b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 56b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari switch (state) 57b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 58b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case StartLine: 59b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Match spaces at the start of line */ 60b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch <= 32) /* skip control characters and space */ 61b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 62b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 63b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari counter=0; 64b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = Feature; 65b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* FALL THROUGH */ 66b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 67b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case Feature: 68b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Match 'FEATURE', ASCII case insensitive. */ 69b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((ch & ~0x20) == ch_feature[counter]) 70b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 71b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (++counter == (sizeof ch_feature)) 72b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = Colon; 73b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 74b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 75b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 76b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* did not match 'feature' */ 77b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = SkipLine; 78b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* FALL THROUGH */ 79b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 80b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case SkipLine: 81b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari skipLine: 82b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Skip everything until we see linefeed or carriage return */ 83b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch != 10 && ch != 13) 84b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 85b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 86b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = StartLine; 87b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 88b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 89b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case Colon: 90b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Match any number of space or tab followed by ':' */ 91b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch == 32 || ch == 9) 92b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 93b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 94b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch == 58) /* i.e. ':' */ 95b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 96b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = StartTag; 97b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 98b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 99b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 100b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Either a bad line format or a 'feature' prefix followed by 101b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * other characters. 102b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 103b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = SkipLine; 104b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari goto skipLine; 105b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 106b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case StartTag: 107b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Skip space characters before a tag */ 108b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch == 32 || ch == 9) 109b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 110b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 111b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = Neon; 112b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari counter = 0; 113b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* FALL THROUGH */ 114b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 115b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case Neon: 116b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Look for 'neon' tag */ 117b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if ((ch & ~0x20) == ch_neon[counter]) 118b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 119b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (++counter == (sizeof ch_neon)) 120b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = HaveNeon; 121b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 122b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 123b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 124b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = SkipTag; 125b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* FALL THROUGH */ 126b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 127b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case SkipTag: 128b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Skip non-space characters */ 129b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch == 10 || ch == 13) 130b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = StartLine; 131b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 132b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else if (ch == 32 || ch == 9) 133b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = StartTag; 134b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 135b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 136b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari case HaveNeon: 137b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* Have seen a 'neon' prefix, but there must be a space or new 138b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * line character to terminate it. 139b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 140b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari if (ch == 10 || ch == 13 || ch == 32 || ch == 9) 141b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari { 142b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari fclose(f); 143b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari return 1; 144b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 145b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 146b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari state = SkipTag; 147b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari break; 148b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 149b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari default: 150b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_error(png_ptr, "png_have_neon: internal error (bug)"); 151b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 152b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 153b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari } 154b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 155b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari else 156b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_warning(png_ptr, "/proc/cpuinfo open failed"); 157b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 158b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari return 0; 159b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari} 160