1 package structures;
2 
3 import shared.KillSwitch;
4 import shared.Parse;
5 import shared.Tools;
6 import stream.Read;
7 
8 public class Quantizer {
9 
parse(String arg, String a, String b)10 	public static boolean parse(String arg, String a, String b){
11 		if(a.equals("quantize")){
12 			if(b!=null && b.equalsIgnoreCase("sticky")){
13 				STICKY=true;
14 				return true;
15 			}
16 		}else if(a.equals("quantizesticky")){
17 			STICKY=Parse.parseBoolean(b);
18 			return true;
19 		}
20 
21 		if(b==null || b.length()<1 || Character.isLetter(b.charAt(0))){
22 			return Parse.parseBoolean(b);
23 		}
24 		return setArray(b);
25 	}
26 
setArray(String s)27 	private static boolean setArray(String s){
28 		final byte[] array;
29 		if(s.charAt(0)=='/'){
30 			int quant=Integer.parseInt(s.substring(1));
31 			assert(quant>0 && quant<128);
32 			if(quant==1){return false;}
33 			ByteBuilder bb=new ByteBuilder();
34 			for(int i=0, max=Read.MAX_CALLED_QUALITY(); i<=max; i+=quant){
35 				bb.append((byte)i);
36 			}
37 			array=bb.toBytes();
38 		}else{
39 			array=Parse.parseByteArray(s, ",");
40 		}
41 		setArray(array);
42 		return true;
43 	}
44 
setArray(byte[] a)45 	private static void setArray(byte[] a){
46 		quantizeArray=a;
47 		qualityRemapArray=makeQualityRemapArray(quantizeArray);
48 	}
49 
quantize(Read r1, Read r2)50 	public static void quantize(Read r1, Read r2){
51 		quantize(r1.quality);
52 		if(r2!=null){quantize(r2.quality);}
53 	}
54 
quantize(byte[] quals)55 	public static void quantize(byte[] quals){
56 		if(quals==null){return;}
57 		byte prev=0;
58 		for(int i=0; i<quals.length; i++){
59 			final byte qOld=quals[i];
60 			byte q=qualityRemapArray[qOld];
61 			if(STICKY && q!=prev && prev>0 && q>0 && Tools.absdif(qOld, prev)<=Tools.absdif(qOld, q)){q=prev;}
62 			quals[i]=q;
63 			prev=q;
64 		}
65 	}
66 
makeQualityRemapArray(byte[] quantizeArray)67 	private static final byte[] makeQualityRemapArray(byte[] quantizeArray) {
68 		byte[] array=KillSwitch.allocByte1D(128);
69 		for(int i=0; i<array.length; i++){
70 			byte q=0;
71 			for(byte x : quantizeArray){
72 				if((i>0 && q==0 && x>0) || Tools.absdif(x, i)<=Tools.absdif(q, i)){q=x;}
73 			}
74 			array[i]=q;
75 		}
76 		return array;
77 	}
78 
79 //	private static byte[] quantizeArray={0, 8, 13, 22, 27, 32, 37}; //Old
80 	private static byte[] quantizeArray={0, 14, 21, 27, 32, 36};
81 	private static byte[] qualityRemapArray=makeQualityRemapArray(quantizeArray);
82 	private static boolean STICKY=true;
83 
84 }
85