|
fukasawa |
e60969 |
/* contrib/arm-neon/linux.c
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* Copyright (c) 2014 Glenn Randers-Pehrson
|
|
fukasawa |
e60969 |
* Written by John Bowler, 2014.
|
|
fukasawa |
e60969 |
* Last changed in libpng 1.6.16 [December 22, 2014]
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* This code is released under the libpng license.
|
|
fukasawa |
e60969 |
* For conditions of distribution and use, see the disclaimer
|
|
fukasawa |
e60969 |
* and license in png.h
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* SEE contrib/arm-neon/README before reporting bugs
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* STATUS: SUPPORTED
|
|
fukasawa |
e60969 |
* BUG REPORTS: png-mng-implement@sourceforge.net
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* png_have_neon implemented for Linux by reading the widely available
|
|
fukasawa |
e60969 |
* pseudo-file /proc/cpuinfo.
|
|
fukasawa |
e60969 |
*
|
|
fukasawa |
e60969 |
* This code is strict ANSI-C and is probably moderately portable; it does
|
|
fukasawa |
e60969 |
* however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.</stdio.h>
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
#include <stdio.h></stdio.h>
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
static int
|
|
fukasawa |
e60969 |
png_have_neon(png_structp png_ptr)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
FILE *f = fopen("/proc/cpuinfo", "rb");
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (f != NULL)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
/* This is a simple state machine which reads the input byte-by-byte until
|
|
fukasawa |
e60969 |
* it gets a match on the 'neon' feature or reaches the end of the stream.
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 };
|
|
fukasawa |
e60969 |
static const char ch_neon[] = { 78, 69, 79, 78 };
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
enum
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine
|
|
fukasawa |
e60969 |
} state;
|
|
fukasawa |
e60969 |
int counter;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
for (state=StartLine, counter=0;;)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
int ch = fgetc(f);
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (ch == EOF)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
/* EOF means error or end-of-file, return false; neon at EOF is
|
|
fukasawa |
e60969 |
* assumed to be a mistake.
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
fclose(f);
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
switch (state)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
case StartLine:
|
|
fukasawa |
e60969 |
/* Match spaces at the start of line */
|
|
fukasawa |
e60969 |
if (ch <= 32) /* skip control characters and space */
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
counter=0;
|
|
fukasawa |
e60969 |
state = Feature;
|
|
fukasawa |
e60969 |
/* FALL THROUGH */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case Feature:
|
|
fukasawa |
e60969 |
/* Match 'FEATURE', ASCII case insensitive. */
|
|
fukasawa |
e60969 |
if ((ch & ~0x20) == ch_feature[counter])
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (++counter == (sizeof ch_feature))
|
|
fukasawa |
e60969 |
state = Colon;
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* did not match 'feature' */
|
|
fukasawa |
e60969 |
state = SkipLine;
|
|
fukasawa |
e60969 |
/* FALL THROUGH */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case SkipLine:
|
|
fukasawa |
e60969 |
skipLine:
|
|
fukasawa |
e60969 |
/* Skip everything until we see linefeed or carriage return */
|
|
fukasawa |
e60969 |
if (ch != 10 && ch != 13)
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
state = StartLine;
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case Colon:
|
|
fukasawa |
e60969 |
/* Match any number of space or tab followed by ':' */
|
|
fukasawa |
e60969 |
if (ch == 32 || ch == 9)
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
if (ch == 58) /* i.e. ':' */
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
state = StartTag;
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
/* Either a bad line format or a 'feature' prefix followed by
|
|
fukasawa |
e60969 |
* other characters.
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
state = SkipLine;
|
|
fukasawa |
e60969 |
goto skipLine;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case StartTag:
|
|
fukasawa |
e60969 |
/* Skip space characters before a tag */
|
|
fukasawa |
e60969 |
if (ch == 32 || ch == 9)
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
state = Neon;
|
|
fukasawa |
e60969 |
counter = 0;
|
|
fukasawa |
e60969 |
/* FALL THROUGH */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case Neon:
|
|
fukasawa |
e60969 |
/* Look for 'neon' tag */
|
|
fukasawa |
e60969 |
if ((ch & ~0x20) == ch_neon[counter])
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
if (++counter == (sizeof ch_neon))
|
|
fukasawa |
e60969 |
state = HaveNeon;
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
state = SkipTag;
|
|
fukasawa |
e60969 |
/* FALL THROUGH */
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case SkipTag:
|
|
fukasawa |
e60969 |
/* Skip non-space characters */
|
|
fukasawa |
e60969 |
if (ch == 10 || ch == 13)
|
|
fukasawa |
e60969 |
state = StartLine;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
else if (ch == 32 || ch == 9)
|
|
fukasawa |
e60969 |
state = StartTag;
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
case HaveNeon:
|
|
fukasawa |
e60969 |
/* Have seen a 'neon' prefix, but there must be a space or new
|
|
fukasawa |
e60969 |
* line character to terminate it.
|
|
fukasawa |
e60969 |
*/
|
|
fukasawa |
e60969 |
if (ch == 10 || ch == 13 || ch == 32 || ch == 9)
|
|
fukasawa |
e60969 |
{
|
|
fukasawa |
e60969 |
fclose(f);
|
|
fukasawa |
e60969 |
return 1;
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
state = SkipTag;
|
|
fukasawa |
e60969 |
break;
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
default:
|
|
fukasawa |
e60969 |
png_error(png_ptr, "png_have_neon: internal error (bug)");
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
}
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
#ifdef PNG_WARNINGS_SUPPORTED
|
|
fukasawa |
e60969 |
else
|
|
fukasawa |
e60969 |
png_warning(png_ptr, "/proc/cpuinfo open failed");
|
|
fukasawa |
e60969 |
#endif
|
|
fukasawa |
e60969 |
|
|
fukasawa |
e60969 |
return 0;
|
|
fukasawa |
e60969 |
}
|