package readers ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.nio.file.Path ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.List ;
import java.util.regex.Pattern ;
import java.awt.Color ;
public abstract class Reader {
final static int REGION_PADDING = 32 ;
int score ;
int rank ;
int [ ] notes = new int [ 7 ] ;
int difficulty ;
String title = "" ;
double pct ;
int maxcombo ;
String other = "" ;
List < Box > readRegions = new ArrayList < > ( ) ;
final int TRANSPARENT = new Color ( 0 , 0 , 0 , 0 ) . getRGB ( ) ;
String readAllBoxes ( Path img ) {
try {
Process p = Runtime . getRuntime ( ) . exec ( new String [ ] { "python3" , "runocr.py" , "ja" , img . toAbsolutePath ( ) . toString ( ) } ) ;
while ( p . isAlive ( ) ) ;
InputStreamReader result = new InputStreamReader ( p . getInputStream ( ) ) ;
StringBuilder sb = new StringBuilder ( ) ;
while ( result . ready ( ) ) {
sb . append ( ( char ) result . read ( ) ) ;
}
result . close ( ) ;
sb . append ( "\n" ) ;
p = Runtime . getRuntime ( ) . exec ( new String [ ] { "python3" , "runocr.py" , "en" , img . toAbsolutePath ( ) . toString ( ) } ) ;
while ( p . isAlive ( ) ) ;
result = new InputStreamReader ( p . getInputStream ( ) ) ;
while ( result . ready ( ) ) {
sb . append ( ( char ) result . read ( ) ) ;
}
return sb . toString ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
return "" ;
}
String interpretOutput ( String [ ] jp_data , String [ ] en_data ) {
//[6, 0, 218, 0, 218, 48, 6, 48, 32 5 4 1 5, 0.9670235803680689]
//For each data point we want to first see if it's within the correct rectangular bounds and from there parse it as such.
double [ ] accuracy = new double [ readRegions . size ( ) ] ;
String [ ] finalData = new String [ readRegions . size ( ) ] ;
for ( int i = 0 ; i < finalData . length ; i + + ) {
finalData [ i ] = "" ;
}
for ( int i = 0 ; i < en_data . length ; i + = 10 ) {
int spacing = 0 ;
for ( int j = 0 ; j < readRegions . size ( ) ; j + + ) {
int midpoint = ( Integer . parseInt ( en_data [ i + 1 ] ) + Integer . parseInt ( en_data [ i + 5 ] ) ) / 2 ;
if ( midpoint > = spacing & & midpoint < = spacing + readRegions . get ( j ) . h + REGION_PADDING
/*&&accuracy[j]<Double.parseDouble(en_data[i+9]) Only for jp string testing.*/ ) {
System . out . print ( "[" ) ;
for ( int k = 0 ; k < 10 ; k + + ) {
if ( k ! = 0 ) {
System . out . print ( "," ) ;
}
System . out . print ( en_data [ i + k ] ) ;
}
System . out . print ( "]" ) ;
System . out . println ( " belongs to region " + j + "." ) ;
finalData [ j ] = finalData [ j ] + "\n" + en_data [ i + 8 ]
. substring ( 1 , en_data [ i + 8 ] . length ( ) - 1 ) ; //The beginning and endings have a ', so we remove it.
accuracy [ j ] = Double . parseDouble ( en_data [ i + 9 ] ) ;
break ;
}
spacing + = readRegions . get ( j ) . h + REGION_PADDING ;
}
}
for ( int i = 0 ; i < jp_data . length ; i + = 10 ) {
int spacing = 0 ;
for ( int j = 0 ; j < readRegions . size ( ) ; j + + ) {
int midpoint = ( Integer . parseInt ( jp_data [ i + 1 ] ) + Integer . parseInt ( jp_data [ i + 5 ] ) ) / 2 ;
if ( midpoint > = spacing & & midpoint < = spacing + readRegions . get ( j ) . h + REGION_PADDING
& & accuracy [ j ] < Double . parseDouble ( jp_data [ i + 9 ] ) ) {
System . out . print ( "JP[" ) ;
for ( int k = 0 ; k < 10 ; k + + ) {
if ( k ! = 0 ) {
System . out . print ( "," ) ;
}
System . out . print ( jp_data [ i + k ] ) ;
}
System . out . print ( "]" ) ;
System . out . println ( " belongs to region " + j + "." ) ;
if ( accuracy [ j ] ! = 0 ) {
finalData [ j ] = "" ;
}
finalData [ j ] = finalData [ j ] + "\n" + jp_data [ i + 8 ]
. substring ( 1 , jp_data [ i + 8 ] . length ( ) - 1 ) ; //The beginning and endings have a ', so we remove it.
accuracy [ j ] = 0 ;
break ;
}
spacing + = readRegions . get ( j ) . h + REGION_PADDING ;
}
}
System . out . println ( Arrays . toString ( finalData ) ) ;
interpretResults ( finalData ) ;
return null ;
} ;
abstract void interpretResults ( String [ ] finalData ) ;
void trimAllData ( String [ ] data ) {
StringBuilder sb = new StringBuilder ( ) ;
for ( int i = 0 ; i < data . length ; i + + ) {
sb . delete ( 0 , sb . length ( ) ) ;
for ( int j = 0 ; j < data [ i ] . length ( ) ; j + + ) {
if ( data [ i ] . charAt ( j ) ! = '[' & & data [ i ] . charAt ( j ) ! = '(' & & data [ i ] . charAt ( j ) ! = ')' & & data [ i ] . charAt ( j ) ! = ']' ) {
sb . append ( data [ i ] . charAt ( j ) ) ;
}
}
data [ i ] = sb . toString ( ) . trim ( ) ;
}
}
void seek ( int [ ] arr , int i , ColorRange SEEKCOLOR , Color FINALCOLOR , int width ) {
seek ( arr , i , SEEKCOLOR , FINALCOLOR , width , 0 ) ;
}
int seek ( int [ ] arr , int i , ColorRange SEEKCOLOR , Color FINALCOLOR , int width , int farthestRight ) {
arr [ i ] = FINALCOLOR . getRGB ( ) ;
int X = i % width ;
for ( int x = - 1 ; x < = 1 ; x + + ) {
for ( int y = - 1 ; y < = 1 ; y + + ) {
int newX = ( i + x + y * width ) % width ;
int newY = ( i + x + y * width ) / width ;
if ( newX > = 0 & & newY > = 0 & & newX < = width & & newY < = arr . length / width ) {
Color col = new Color ( arr [ i + x + y * width ] ) ;
if ( ! col . equals ( Color . MAGENTA ) & & SEEKCOLOR . colorInRange ( col ) ) {
farthestRight = seek ( arr , i + x + y * width , SEEKCOLOR , FINALCOLOR , width , farthestRight ) ;
}
}
}
}
return X > farthestRight ? X : farthestRight ;
}
void seekThreshold ( int [ ] arr , int i , int threshold , Color FINALCOLOR , int width ) {
seekThreshold ( arr , i , threshold , FINALCOLOR , width , 0 ) ;
}
int seekThreshold ( int [ ] arr , int i , int threshold , Color FINALCOLOR , int width , int farthestRight ) {
arr [ i ] = FINALCOLOR . getRGB ( ) ;
int X = i % width ;
for ( int x = - 1 ; x < = 1 ; x + + ) {
for ( int y = - 1 ; y < = 1 ; y + + ) {
int newX = ( i + x + y * width ) % width ;
int newY = ( i + x + y * width ) / width ;
if ( newX > = 0 & & newY > = 0 & & newX < = width & & newY < = arr . length / width ) {
Color col = new Color ( arr [ i + x + y * width ] ) ;
if ( ! col . equals ( Color . MAGENTA ) & & colorIsBright ( col , threshold ) ) {
farthestRight = seekThreshold ( arr , i + x + y * width , threshold , FINALCOLOR , width , farthestRight ) ;
}
}
}
}
return X > farthestRight ? X : farthestRight ;
}
void process ( int [ ] arr , int width , int a , int b , int c , int d , int e , int f , int g , int h , int ii , int j , int k , int l ) {
final ColorRange TARGETCOLOR = new ColorRange ( a , b , c , d , e , f ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( g , h , ii , j , k , l ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
}
boolean colorIsBright ( Color col , int brightnessThreshold ) {
return col . getRed ( ) + col . getBlue ( ) + col . getGreen ( ) > brightnessThreshold ;
}
void processBrightness ( int [ ] arr , int width , int threshold1 , int threshold2 ) {
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( colorIsBright ( col , threshold1 ) ) {
seekThreshold ( arr , i , threshold2 , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
}
char [ ] [ ] number_alternatives = {
/*0*/ { '0' , 'o' , 'O' , 'e' } ,
/*1*/ { '1' , '\\' , '/' , 'I' , 'i' } ,
/*2*/ { '2' , '己' } ,
/*3*/ { '3' } ,
/*4*/ { '4' } ,
/*5*/ { '5' } ,
/*6*/ { '6' , 'b' , 'G' } ,
/*7*/ { '7' , 'z' , 'Z' } ,
/*8*/ { '8' , 'B' } ,
/*9*/ { '9' , 'g' , 'y' , } ,
} ;
String convertToString ( String [ ] data ) {
return String . join ( "\n" , data ) . replaceFirst ( Pattern . quote ( "\n" ) , "" ) ;
}
double convertToDouble ( String [ ] data ) { return convertToDouble ( "" , data ) ; }
double convertToDouble ( String prefix , String [ ] data ) {
int numb = 0 ;
int decimal = 0 ;
boolean decimalFound = false ;
for ( int i = 0 ; i < data . length ; i + + ) {
String s = data [ i ] ;
int j = 0 ;
if ( i = = 1 ) {
j = prefix . length ( ) ;
} else {
j = 0 ;
}
//System.out.println("["+s+"]"+" starts at "+j);
for ( ; j < s . length ( ) ; j + + ) {
if ( s . charAt ( j ) = = '.' | | s . charAt ( j ) = = ',' ) {
decimalFound = true ;
}
letter_iterator :
for ( int k = 0 ; k < number_alternatives . length ; k + + ) {
for ( int l = 0 ; l < number_alternatives [ k ] . length ; l + + ) {
if ( s . charAt ( j ) = = number_alternatives [ k ] [ l ] ) {
if ( ! decimalFound ) {
numb * = 10 ;
numb + = k ;
} else {
decimal * = 10 ;
decimal + = k ;
}
//System.out.println(" "+s.charAt(j)+" found for "+k+".");
break letter_iterator ;
}
}
}
}
}
return Double . parseDouble ( Integer . toString ( numb ) + "." + Integer . toString ( decimal ) ) ;
}
int convertToInt ( String [ ] data ) { return convertToInt ( "" , data ) ; }
int convertToInt ( String prefix , String [ ] data ) {
int numb = 0 ;
for ( int i = 0 ; i < data . length ; i + + ) {
String s = data [ i ] ;
int j = 0 ;
if ( i = = 1 ) {
j = prefix . length ( ) ;
} else {
j = 0 ;
}
//System.out.println("["+s+"]"+" starts at "+j);
for ( ; j < s . length ( ) ; j + + ) {
letter_iterator :
for ( int k = 0 ; k < number_alternatives . length ; k + + ) {
for ( int l = 0 ; l < number_alternatives [ k ] . length ; l + + ) {
if ( s . charAt ( j ) = = number_alternatives [ k ] [ l ] ) {
numb * = 10 ;
numb + = k ;
//System.out.println(" "+s.charAt(j)+" found for "+k+".");
break letter_iterator ;
}
}
}
}
}
return numb ;
}
@Override
public String toString ( ) {
return "Reader [difficulty=" + difficulty + ", maxcombo=" + maxcombo + ", notes=" + Arrays . toString ( notes )
+ ", other=" + other + ", pct=" + pct + ", rank=" + rank + ", score=" + score + ", title=" + title
+ "]" ;
}
}