/* 
  Test_run.java
  A demo program that illustrates the concepts of quantization, zigzag 
  reordering and run-level encoding.  It reads DCT coefficients from the 
  file specified by args[0] which has saved 8x8 blocks of DCT 
  coefficients in short ( 16-bit ) form.
  Compile:  javac Test_run.java
  Execute:  e.g. java Test_run ../6/t.dct 
*/

import java.io.*;

public class Test_run {
   
  //DCT file header 
  private static byte []  header = { 'D', 'C', 'T', '4', ':', '2', ':', '0' };

  static int read_dct_header ( DataInputStream in )
  {
    byte [] bytes = new byte[header.length];
    try {
      in.read ( bytes );
      int width = in.readInt();    //not used here
      int height = in.readInt();   //not used here
    } catch (IOException e) {
       e.printStackTrace();
       System.exit(0);
    }
    for ( int i = 0; i < header.length; ++i )
      if ( bytes[i] != header[i] )
        return -1;      //wrong header

    return 1;
  }
  
  public static void main(String[] args) throws InterruptedException
  {
    if (args.length < 1) {
      System.out.println("Usage: java " + "Test_run" +
        " input_dct_filename \n" +
        "e.g. java Test_run ../6/t.dct");
      System.exit(-1);
    }
    
    Run3D [] runs = new Run3D[64];
    short [][] Y = new short[8][8];
    short [][] Yr = new short[8][8];
    for ( int i = 0; i < 64; ++i )
      runs[i] = new Run3D();
    //read the DCT data back from args[0]
    DataInputStream in;
    Quantizer quantizer = new Quantizer();
    Reorder reorder = new Reorder();
    Run run = new Run();
    try {
      File f = new File ( args[0] );
      InputStream ins = new FileInputStream( f );
      in = new DataInputStream ( ins );
      if ( read_dct_header ( in ) == -1 ){
        System.out.println("Not dct File");
        return;
      }
      String key;
      InputStreamReader converter = new InputStreamReader(System.in);
      BufferedReader keyin = new BufferedReader(converter);
      while ( run.get64 ( Y, in ) > 0 ) {       //read a block of 64 samples
        System.out.printf("\nA block of DCT coefficients:");
        run.print_block ( Y );
        quantizer.quantize_block ( Y );

        System.out.printf("\nDCT block after quantization ( Qstep = %d ):", quantizer.Qstep );
        run.print_block ( Y );
        reorder.reorder ( Y, Yr );

        System.out.printf("\nDCT block After zigzag reorder:");
        run.print_block ( Yr );
        run.run_block ( Yr, runs );

        System.out.printf("\n3D run-level codewords of the reordered quantized DCT coeficients:");
        run.print_run ( runs );
        System.out.printf("\nHit any key to reverse the processes:");
        keyin.readLine();
     
        //reversing the process
        short [][] new_Y = new short[8][8];
        run.run_decode ( runs, new_Y );
        System.out.printf("\nDCT block after decode run:");
        run.print_block ( new_Y );
 
        reorder.reverse_reorder ( new_Y, Y );
        System.out.printf("\nDCT block after reversing reorder:");
        run.print_block ( Y );

        quantizer.inverse_quantize_block ( Y );
        System.out.printf("\nDCT block after inverse quantization:");
        run.print_block ( Y );

        System.out.printf("\nDo you want another block? ( y/n) ");
        key = keyin.readLine();
        if ( key.equals( "n" ) ) break;
      }
      in.close();
    } catch (IOException e) {
       e.printStackTrace();
       System.exit(0);
    }
  }
}
