/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */

/*
 * Disclaimer of Warranty
 *
 * These software programs are available to the user without any license fee or
 * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
 * any and all warranties, whether express, implied, or statuary, including any
 * implied warranties or merchantability or of fitness for a particular
 * purpose.  In no event shall the copyright-holder be liable for any
 * incidental, punitive, or consequential damages of any kind whatsoever
 * arising from the use of these programs.
 *
 * This disclaimer of warranty extends to the user of these programs and user's
 * customers, employees, agents, transferees, successors, and assigns.
 *
 * The MPEG Software Simulation Group does not represent or warrant that the
 * programs furnished hereunder are free of infringement of any third-party
 * patents.
 *
 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
 * are subject to royalty fees to patent holders.  Many of these patents are
 * general enough such that they are unavoidable regardless of implementation
 * design.
 *
 */


/*
 * @(#)MpvDecoder.java - still Picture Decoder
 * 
 * Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved. 
 *
 * This file is part of ProjectX, a free Java based demux utility.
 * By the authors, ProjectX is intended for educational purposes only, 
 * as a non-commercial test project.
 * 
 * necessary codes are derived from the MSSG mpeg2dec
 *
 * display modifications: shows I-Frames only
 * 
 *
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

package net.sourceforge.dvb.projectx.video;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.sourceforge.dvb.projectx.common.Resource;
import net.sourceforge.dvb.projectx.common.Common;

import net.sourceforge.dvb.projectx.parser.CommonParsing;


public class MpvDecoder extends Object {

	private IDCTRefNative idct;
	private IDCTSseNative idctsse;

	private int[] pixels2 = new int[512 * 288];
	private int[] pixels = new int[250]; //full pixel data

	private int Fault_Flag = 0;
	private int BitPos = 0;
	private int BufferPos = 0;
	private int SequenceHeader = 0; 

	private long StartPos = 0;

	private boolean acceleration = false;
	private boolean FAST = false;
	private boolean PLAY = true;
	private boolean DIRECTION = false;
	private boolean ERROR1 = false;
	private boolean ERROR2 = false;
	private boolean viewGOP = true;

	private String info_4 = "";
	private String info_3 = "";
	private String info_2 = "";
	private String info_1 = "";

	private byte[] buf = new byte[0];

	/**
	 *
	 */
	public MpvDecoder()
	{
		Arrays.fill(pixels2, 0xFF505050);

		idct = new IDCTRefNative();
		idctsse = new IDCTSseNative();

		if (IDCTRefNative.isLibraryLoaded())
			idct.init();

		if (IDCTRefNative.isLibraryLoaded() || IDCTSseNative.isLibraryLoaded())
			acceleration = true;
	}

	/**
	 *
	 */
	public boolean isAccelerated()
	{
		return acceleration;
	}


final int PICTURE_START_CODE=0x100;
final int SLICE_START_CODE_MIN=0x101;
final int SLICE_START_CODE_MAX=0x1AF;
final int USER_DATA_START_CODE=0x1B2;
final int SEQUENCE_HEADER_CODE=0x1B3;
final int EXTENSION_START_CODE=0x1B5;
final int SEQUENCE_END_CODE=0x1B7;
final int GROUP_START_CODE=0x1B8;
final int SYSTEM_END_CODE=0x1B9;
final int PACK_START_CODE=0x1BA;
final int SYSTEM_START_CODE=0x1BB;

private int File_Flag;
private int File_Limit;
private int FO_Flag;
private int IDCT_Flag;
private int Luminance_Flag;
private int Scale_Flag;
private int SystemStream_Flag;
private int ERROR_CODE=0;
private int ERROR_CODE1=0;

/* extension start code IDs */
final int SEQUENCE_EXTENSION_ID=1;
final int SEQUENCE_DISPLAY_EXTENSION_ID=2;
final int QUANT_MATRIX_EXTENSION_ID=3;
final int COPYRIGHT_EXTENSION_ID=4;
final int PICTURE_DISPLAY_EXTENSION_ID=7;
final int PICTURE_CODING_EXTENSION_ID=8;
final int ZIG_ZAG=0;
final int MB_WEIGHT=32;
final int MB_CLASS4=64;
final int MC_FIELD=1;
final int MC_FRAME=2;
final int MC_16X8=2;
final int MC_DMV=3;
final int MV_FIELD=0;
final int MV_FRAME=1;
final int I_TYPE=1;
final int P_TYPE=2;
final int B_TYPE=3;
final int TOP_FIELD=1;
final int BOTTOM_FIELD=2;
final int FRAME_PICTURE=3;
final int MACROBLOCK_INTRA=1;
final int MACROBLOCK_PATTERN=2;
final int MACROBLOCK_MOTION_BACKWARD=4;
final int MACROBLOCK_MOTION_FORWARD=8;
final int MACROBLOCK_QUANT=16;
final int CHROMA420=1;
final int CHROMA422=2;
final int CHROMA444=3;
final int IDCT_CLIP_TABLE_OFFSET=512;

private int q_scale_type=0;  //1
private int quantizer_scale=0, alternate_scan=0;//1
private int Coded_Picture_Width=0, Coded_Picture_Height=0, Chroma_Width=0, Chroma_Height=0;
private int block_count=0, Second_Field=0;
private int horizontal_size=0, vertical_size=0, mb_width=0, mb_height=0;

/* ISO/IEC 13818-2 section 6.2.2.1:  sequence_header() */
private int frame_rate_code=0;
private int aspect_ratio_information=0;

/* ISO/IEC 13818-2 section 6.2.2.3:  sequence_extension() */
private int progressive_sequence=1;  //prog.s std 
private int chroma_format=1;  //4:2:0std 
private int profile_and_level_indication;
private int video_format;
private String video_format_S[] = { "comp","PAL","NTSC","SECAM","MAC","unspec","res","res" };
private String prof[] = { "res","HP","SS","SNR","MP","SP","res","res" };
private String lev[] = { "res","res","res","res","HL","res","HL1440","res","ML","res","LL","res","res","res","res" };

/* ISO/IEC 13818-2 section 6.2.3: picture_header() */
private int picture_coding_type=0;
private int temporal_reference=0;

/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() header */
private int f_code[][] = new int[2][2];
private int picture_structure=3;  //0
private int frame_pred_frame_dct=1; //0
private int progressive_frame=1;  //0
private int concealment_motion_vectors=0;
private int intra_dc_precision=0; //8bit
private int top_field_first=0;
private int repeat_first_field=0;
private int intra_vlc_format=0; //

private int intra_quantizer_matrix[] = new int[64];
private int non_intra_quantizer_matrix[] = new int[64];
private int chroma_intra_quantizer_matrix[] = new int[64];
private int chroma_non_intra_quantizer_matrix[] = new int[64];
  
private int load_intra_quantizer_matrix=0;
private int load_non_intra_quantizer_matrix=0;
private int load_chroma_intra_quantizer_matrix=0;
private int load_chroma_non_intra_quantizer_matrix=0;

private short block[][]=new short[12][64]; //macroblocks

final String picture_coding_type_string[] = {
	"bad","I","P","B","D"
};

final String progressive_string[] = {
	"i","p"
};

final String aspect_ratio_string[] = {
	"bad","(1:1)","(4:3)","(16:9)","(2.21:1)","(0.8055)","(0.8437)","(0.9375)","(0.9815)","(1.0255)","(1.0695)","(1.1250)","(1.1575)","(1.2015)"
};

/* cosine transform matrix for 8x1 IDCT */
final float ref_dct_matrix[][] = {
	{    // [0][0-7]
		 3.5355339059327379e-001f,  3.5355339059327379e-001f,
		 3.5355339059327379e-001f,  3.5355339059327379e-001f,
		 3.5355339059327379e-001f,  3.5355339059327379e-001f,
		 3.5355339059327379e-001f,  3.5355339059327379e-001f,
	}, { // [1][0-7]
		 4.9039264020161522e-001f,  4.1573480615127262e-001f,
		 2.7778511650980114e-001f,  9.7545161008064166e-002f,
		-9.7545161008064096e-002f, -2.7778511650980098e-001f,
		-4.1573480615127267e-001f, -4.9039264020161522e-001f,
	}, { // [2][0-7]
		 4.6193976625564337e-001f,  1.9134171618254492e-001f,
		-1.9134171618254486e-001f, -4.6193976625564337e-001f,
		-4.6193976625564342e-001f, -1.9134171618254517e-001f,
		 1.9134171618254500e-001f,  4.6193976625564326e-001f,
	}, { // [3][0-7]
		 4.1573480615127262e-001f, -9.7545161008064096e-002f,
		-4.9039264020161522e-001f, -2.7778511650980109e-001f,
		 2.7778511650980092e-001f,  4.9039264020161522e-001f,
		 9.7545161008064388e-002f, -4.1573480615127256e-001f,
	}, { // [4][0-7]
		 3.5355339059327379e-001f, -3.5355339059327373e-001f,
		-3.5355339059327384e-001f,  3.5355339059327368e-001f,
		 3.5355339059327384e-001f, -3.5355339059327334e-001f,
		-3.5355339059327356e-001f,  3.5355339059327329e-001f,
	}, { // [5][0-7]
		 2.7778511650980114e-001f, -4.9039264020161522e-001f,
		 9.7545161008064152e-002f,  4.1573480615127273e-001f,
		-4.1573480615127256e-001f, -9.7545161008064013e-002f,
		 4.9039264020161533e-001f, -2.7778511650980076e-001f,
	}, { // [6][0-7]
		 1.9134171618254492e-001f, -4.6193976625564342e-001f,
		 4.6193976625564326e-001f, -1.9134171618254495e-001f,
		-1.9134171618254528e-001f,  4.6193976625564337e-001f,
		-4.6193976625564320e-001f,  1.9134171618254478e-001f,
	}, { // [7][0-7]
		 9.7545161008064166e-002f, -2.7778511650980109e-001f,
		 4.1573480615127273e-001f, -4.9039264020161533e-001f,
		 4.9039264020161522e-001f, -4.1573480615127251e-001f,
		 2.7778511650980076e-001f, -9.7545161008064291e-002f,
	},
};


final short idct_clip_table[] = {
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-256,-256,-256,-256,-256,-256,-256,
	-256,-255,-254,-253,-252,-251,-250,-249,
	-248,-247,-246,-245,-244,-243,-242,-241,
	-240,-239,-238,-237,-236,-235,-234,-233,
	-232,-231,-230,-229,-228,-227,-226,-225,
	-224,-223,-222,-221,-220,-219,-218,-217,
	-216,-215,-214,-213,-212,-211,-210,-209,
	-208,-207,-206,-205,-204,-203,-202,-201,
	-200,-199,-198,-197,-196,-195,-194,-193,
	-192,-191,-190,-189,-188,-187,-186,-185,
	-184,-183,-182,-181,-180,-179,-178,-177,
	-176,-175,-174,-173,-172,-171,-170,-169,
	-168,-167,-166,-165,-164,-163,-162,-161,
	-160,-159,-158,-157,-156,-155,-154,-153,
	-152,-151,-150,-149,-148,-147,-146,-145,
	-144,-143,-142,-141,-140,-139,-138,-137,
	-136,-135,-134,-133,-132,-131,-130,-129,
	-128,-127,-126,-125,-124,-123,-122,-121,
	-120,-119,-118,-117,-116,-115,-114,-113,
	-112,-111,-110,-109,-108,-107,-106,-105,
	-104,-103,-102,-101,-100, -99, -98, -97,
	 -96, -95, -94, -93, -92, -91, -90, -89,
	 -88, -87, -86, -85, -84, -83, -82, -81,
	 -80, -79, -78, -77, -76, -75, -74, -73,
	 -72, -71, -70, -69, -68, -67, -66, -65,
	 -64, -63, -62, -61, -60, -59, -58, -57,
	 -56, -55, -54, -53, -52, -51, -50, -49,
	 -48, -47, -46, -45, -44, -43, -42, -41,
	 -40, -39, -38, -37, -36, -35, -34, -33,
	 -32, -31, -30, -29, -28, -27, -26, -25,
	 -24, -23, -22, -21, -20, -19, -18, -17,
	 -16, -15, -14, -13, -12, -11, -10,  -9,
	  -8,  -7,  -6,  -5,  -4,  -3,  -2,  -1,
	   0,   1,   2,   3,   4,   5,   6,   7,
	   8,   9,  10,  11,  12,  13,  14,  15,
	  16,  17,  18,  19,  20,  21,  22,  23,
	  24,  25,  26,  27,  28,  29,  30,  31,
	  32,  33,  34,  35,  36,  37,  38,  39,
	  40,  41,  42,  43,  44,  45,  46,  47,
	  48,  49,  50,  51,  52,  53,  54,  55,
	  56,  57,  58,  59,  60,  61,  62,  63,
	  64,  65,  66,  67,  68,  69,  70,  71,
	  72,  73,  74,  75,  76,  77,  78,  79,
	  80,  81,  82,  83,  84,  85,  86,  87,
	  88,  89,  90,  91,  92,  93,  94,  95,
	  96,  97,  98,  99, 100, 101, 102, 103,
	 104, 105, 106, 107, 108, 109, 110, 111,
	 112, 113, 114, 115, 116, 117, 118, 119,
	 120, 121, 122, 123, 124, 125, 126, 127,
	 128, 129, 130, 131, 132, 133, 134, 135,
	 136, 137, 138, 139, 140, 141, 142, 143,
	 144, 145, 146, 147, 148, 149, 150, 151,
	 152, 153, 154, 155, 156, 157, 158, 159,
	 160, 161, 162, 163, 164, 165, 166, 167,
	 168, 169, 170, 171, 172, 173, 174, 175,
	 176, 177, 178, 179, 180, 181, 182, 183,
	 184, 185, 186, 187, 188, 189, 190, 191,
	 192, 193, 194, 195, 196, 197, 198, 199,
	 200, 201, 202, 203, 204, 205, 206, 207,
	 208, 209, 210, 211, 212, 213, 214, 215,
	 216, 217, 218, 219, 220, 221, 222, 223,
	 224, 225, 226, 227, 228, 229, 230, 231,
	 232, 233, 234, 235, 236, 237, 238, 239,
	 240, 241, 242, 243, 244, 245, 246, 247,
	 248, 249, 250, 251, 252, 253, 254, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
	 255, 255, 255, 255, 255, 255, 255, 255,
};

final byte cc_table[] = {
	0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2
};

final int ChromaFormat[] = {
	0, 6, 8, 12
};

/* non-linear quantization coefficient table */
final byte Non_Linear_quantizer_scale[] = {
	0, 1, 2, 3, 4, 5, 6, 7,
	8, 10, 12, 14, 16, 18, 20, 22,
	24, 28, 32, 36, 40, 44, 48, 52,
	56, 64, 72, 80, 88, 96, 104, 112
};

final byte MBAtab1[][] = {  //VLCtab val,len
	{-1,0}, {-1,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4},
	{4,4}, {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3}
};

/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
final byte MBAtab2[][] = {  //VLCtab val,len
	{33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11},
	{25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10},
	{19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10},
	{15,8},  {15,8},  {15,8},  {15,8},  {15,8},  {15,8},  {15,8},  {15,8},
	{14,8},  {14,8},  {14,8},  {14,8},  {14,8},  {14,8},  {14,8},  {14,8},
	{13,8},  {13,8},  {13,8},  {13,8},  {13,8},  {13,8},  {13,8},  {13,8},
	{12,8},  {12,8},  {12,8},  {12,8},  {12,8},  {12,8},  {12,8},  {12,8},
	{11,8},  {11,8},  {11,8},  {11,8},  {11,8},  {11,8},  {11,8},  {11,8},
	{10,8},  {10,8},  {10,8},  {10,8},  {10,8},  {10,8},  {10,8},  {10,8},
	{9,7},   {9,7},   {9,7},   {9,7},   {9,7},   {9,7},   {9,7},   {9,7},
	{9,7},   {9,7},   {9,7},   {9,7},   {9,7},   {9,7},   {9,7},   {9,7},
	{8,7},   {8,7},   {8,7},   {8,7},   {8,7},   {8,7},   {8,7},   {8,7},
	{8,7},   {8,7},   {8,7},   {8,7},   {8,7},   {8,7},   {8,7},   {8,7}
};


/* default intra quantization matrix */
final int default_intra_quantizer_matrix[] = {
	8, 16, 19, 22, 26, 27, 29, 34,
	16, 16, 22, 24, 27, 29, 34, 37,
	19, 22, 26, 27, 29, 34, 34, 38,
	22, 22, 26, 27, 29, 34, 37, 40,
	22, 26, 27, 29, 32, 35, 40, 48,
	26, 27, 29, 32, 35, 40, 48, 58,
	26, 27, 29, 34, 38, 46, 56, 69,
	27, 29, 35, 38, 46, 56, 69, 83
};

/* zig-zag and alternate scan patterns */
final byte scan[][] = {
	{ /* Zig-Zag scan pattern  */
		0,  1,  8, 16,  9,  2,  3, 10,
	   17, 24, 32, 25, 18, 11,  4,  5,
	   12, 19, 26, 33, 40, 48, 41, 34,
	   27, 20, 13,  6,  7, 14, 21, 28,
	   35, 42, 49, 56, 57, 50, 43, 36,
	   29, 22, 15, 23, 30, 37, 44, 51,
	   58, 59, 52, 45, 38, 31, 39, 46,
	   53, 60, 61, 54, 47, 55, 62, 63
	}
	,
	{ /* Alternate scan pattern */
		0,  8, 16, 24,  1,  9,  2, 10,
	   17, 25, 32, 40, 48, 56, 57, 49,
	   41, 33, 26, 18,  3, 11, 4,  12,
	   19, 27, 34, 42, 50, 58, 35, 43,
	   51, 59, 20, 28,  5, 13,  6, 14,
	   21, 29, 36, 44, 52, 60, 37, 45,
	   53, 61, 22, 30,  7, 15, 23, 31,
	   38, 46, 54, 62, 39, 47, 55, 63
	}
};

/***
typedef struct {
	char run, level, len;
} DCTtab;

typedef struct {
	char val, len;
} VLCtab;
***/

/* Table B-14, DCT coefficients table zero,
 * codes 000001xx ... 00111xxx  */
final byte DCTtab0[][] = {
	{65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
	{2,2,7}, {2,2,7}, {9,1,7}, {9,1,7},
	{0,4,7}, {0,4,7}, {8,1,7}, {8,1,7},
	{7,1,6}, {7,1,6}, {7,1,6}, {7,1,6},
	{6,1,6}, {6,1,6}, {6,1,6}, {6,1,6},
	{1,2,6}, {1,2,6}, {1,2,6}, {1,2,6},
	{5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
	{13,1,8}, {0,6,8}, {12,1,8}, {11,1,8},
	{3,2,8}, {1,3,8}, {0,5,8}, {10,1,8},
	{0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
	{0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
	{4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
	{4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
	{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
	{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}
};

/* Table B-15, DCT coefficients table one,
 * codes 000001xx ... 11111111 */
final byte DCTtab0a[][] = {
	{65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
	{7,1,7}, {7,1,7}, {8,1,7}, {8,1,7},
	{6,1,7}, {6,1,7}, {2,2,7}, {2,2,7},
	{0,7,6}, {0,7,6}, {0,7,6}, {0,7,6},
	{0,6,6}, {0,6,6}, {0,6,6}, {0,6,6},
	{4,1,6}, {4,1,6}, {4,1,6}, {4,1,6},
	{5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
	{1,5,8}, {11,1,8}, {0,11,8}, {0,10,8},
	{13,1,8}, {12,1,8}, {3,2,8}, {1,4,8},
	{2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
	{2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
	{1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
	{1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
	{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
	{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
	{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */
	{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
	{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
	{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
	{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
	{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
	{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
	{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
	{0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
	{0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
	{0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
	{0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
	{9,1,7}, {9,1,7}, {1,3,7}, {1,3,7},
	{10,1,7}, {10,1,7}, {0,8,7}, {0,8,7},
	{0,9,7}, {0,9,7}, {0,12,8}, {0,13,8},
	{2,3,8}, {4,2,8}, {0,14,8}, {0,15,8}
};

/* Table B-14, DCT coefficients table zero,
 * codes 0000001000 ... 0000001111 */
final byte DCTtab1[][] = {
	{16,1,10}, {5,2,10}, {0,7,10}, {2,3,10},
	{1,4,10}, {15,1,10}, {14,1,10}, {4,2,10}
};

/* Table B-15, DCT coefficients table one,
 * codes 000000100x ... 000000111x */
final byte DCTtab1a[][] = {
	{5,2,9}, {5,2,9}, {14,1,9}, {14,1,9},
	{2,4,10}, {16,1,10}, {15,1,9}, {15,1,9}
};

/* Table B-14/15, DCT coefficients table zero / one,
 * codes 000000010000 ... 000000011111 */
final byte DCTtab2[][] = {
	{0,11,12}, {8,2,12}, {4,3,12}, {0,10,12},
	{2,4,12}, {7,2,12}, {21,1,12}, {20,1,12},
	{0,9,12}, {19,1,12}, {18,1,12}, {1,5,12},
	{3,3,12}, {0,8,12}, {6,2,12}, {17,1,12}
};

/* Table B-14/15, DCT coefficients table zero / one,
 * codes 0000000010000 ... 0000000011111 */
final byte DCTtab3[][] = {
	{10,2,13}, {9,2,13}, {5,3,13}, {3,4,13},
	{2,5,13}, {1,7,13}, {1,6,13}, {0,15,13},
	{0,14,13}, {0,13,13}, {0,12,13}, {26,1,13},
	{25,1,13}, {24,1,13}, {23,1,13}, {22,1,13}
};

/* Table B-14/15, DCT coefficients table zero / one,
 * codes 00000000010000 ... 00000000011111 */
final byte DCTtab4[][] = {
	{0,31,14}, {0,30,14}, {0,29,14}, {0,28,14},
	{0,27,14}, {0,26,14}, {0,25,14}, {0,24,14},
	{0,23,14}, {0,22,14}, {0,21,14}, {0,20,14},
	{0,19,14}, {0,18,14}, {0,17,14}, {0,16,14}
};

/* Table B-14/15, DCT coefficients table zero / one,
 * codes 000000000010000 ... 000000000011111 */
final byte DCTtab5[][] = {
	{0,40,15}, {0,39,15}, {0,38,15}, {0,37,15},
	{0,36,15}, {0,35,15}, {0,34,15}, {0,33,15},
	{0,32,15}, {1,14,15}, {1,13,15}, {1,12,15},
	{1,11,15}, {1,10,15}, {1,9,15}, {1,8,15}
};

/* Table B-14/15, DCT coefficients table zero / one,
 * codes 0000000000010000 ... 0000000000011111 */
final byte DCTtab6[][] = {  //DCTtab run,level,len
	{1,18,16}, {1,17,16}, {1,16,16}, {1,15,16},
	{6,3,16}, {16,2,16}, {15,2,16}, {14,2,16},
	{13,2,16}, {12,2,16}, {11,2,16}, {31,1,16},
	{30,1,16}, {29,1,16}, {28,1,16}, {27,1,16}
};

/* Table B-14, DCT coefficients table zero,
 * codes 0100 ... 1xxx (used for first (DC) coefficient)  */
final byte DCTtabfirst[][] = {
	{0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
	{0,1,1}, {0,1,1}, {0,1,1}, {0,1,1},
	{0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}
};

/* Table B-14, DCT coefficients table zero,
 * codes 0100 ... 1xxx (used for all other coefficients) */
final byte DCTtabnext[][] = {
	{0,2,4},  {2,1,4},  {1,1,3},  {1,1,3},
	{64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */
	{0,1,2},  {0,1,2},  {0,1,2},  {0,1,2}
};

/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
final byte CBPtab0[][] = {
	{-1,0}, {-1,0}, {-1,0}, {-1,0},	{-1,0}, {-1,0}, {-1,0}, {-1,0},
	{62,5}, {2,5},  {61,5}, {1,5},  {56,5}, {52,5}, {44,5}, {28,5},
	{40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4},
	{8,4},  {8,4},  {4,4},  {4,4},  {60,3}, {60,3}, {60,3}, {60,3}
};

/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
final byte CBPtab1[][] = {
	{-1,0}, {-1,0}, {-1,0}, {-1,0},	{58,8}, {54,8}, {46,8}, {30,8},
	{57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8},
	{43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8},
	{41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8},
	{34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7},  {6,7},
	{33,7}, {33,7}, {17,7}, {17,7}, {9,7},  {9,7},  {5,7},  {5,7},
	{63,6}, {63,6}, {63,6}, {63,6}, {3,6},  {3,6},  {3,6},  {3,6},
	{36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6}
};

/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
final byte CBPtab2[][] = {
	{-1,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9}
};

/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
final byte DClumtab0[][] = {
	{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
	{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
	{0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
	{4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {-1, 0}
};

/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
final byte DClumtab1[][] = {
	{7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6},
	{8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9}
};

/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
final byte DCchromtab0[][] = {
	{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
	{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
	{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
	{3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {-1, 0}
};

/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
final byte DCchromtab1[][] = {
	{6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
	{6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
	{7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7},
	{8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10}
};

/* Table B-10, motion_code, codes 0001 ... 01xx */
final byte MVtab0[][] = {
	{-1,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1}
};

/* Table B-10, motion_code, codes 0000011 ... 000011x */
final byte MVtab1[][] = {
	{-1,0}, {-1,0}, {-1,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5}
};

/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
final byte MVtab2[][] = {
	{16,9}, {15,9}, {14,9}, {13,9},
	{12,9}, {11,9}, {10,8}, {10,8},
	{9,8},  {9,8},  {8,8},  {8,8}
};


/* Table B-3, macroblock_type in P-pictures, codes 001..1xx */
final byte PMBtab0[][] = {
	{-1,0},
	{MACROBLOCK_MOTION_FORWARD,3},
	{MACROBLOCK_PATTERN,2}, {MACROBLOCK_PATTERN,2},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, 
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, 
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}
};

/* Table B-3, macroblock_type in P-pictures, codes 000001..00011x */
final byte PMBtab1[][] = {
	{-1,0},
	{MACROBLOCK_QUANT|MACROBLOCK_INTRA,6},
	{MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5},
	{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5},
	{MACROBLOCK_INTRA,5}, {MACROBLOCK_INTRA,5}
};

/* Table B-4, macroblock_type in B-pictures, codes 0010..11xx */
final byte BMBtab0[][] = {
	{-1,0}, 
	{-1,0},
	{MACROBLOCK_MOTION_FORWARD,4},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,4},
	{MACROBLOCK_MOTION_BACKWARD,3}, 
	{MACROBLOCK_MOTION_BACKWARD,3},
	{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3}, 
	{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, 
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, 
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2},
	{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}
};

/* Table B-4, macroblock_type in B-pictures, codes 000001..00011x */
final byte BMBtab1[][] = {
	{-1,0},
	{MACROBLOCK_QUANT|MACROBLOCK_INTRA,6},
	{MACROBLOCK_QUANT|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,6},
	{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,6},
	{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5},
	{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5},
	{MACROBLOCK_INTRA,5}, 
	{MACROBLOCK_INTRA,5}
};

final double frame_rate_Table[] = {
	0.0,
	((24.0*1000.0)/1001.0),
	24.0,
	25.0,
	((30.0*1000.0)/1001.0),
	30.0,
	50.0,
	((60.0*1000.0)/1001.0),
	60.0,

	-1,		// reserved
	-1,
	-1,
	-1,
	-1,
	-1,
	-1
};

/* global value */
private byte backward_reference_frame[] = new byte[3], forward_reference_frame[] = new byte[3];
private byte auxframe[] = new byte[3], current_frame[] = new byte[3];
private byte u422, v422, u444, v444, rgb24, lum;
private int pf_backward, pf_forward, pf_current;
private float frame_rate,Frame_Rate;
//from gopheader
private int gop_hour;
private int gop_minute;
private int gop_sec;
private int gop_frame;
private int drop_flag;
private int closed_gop;
private int broken_link;



public void Clear_Block(int comp) { // assembler?
	java.util.Arrays.fill(block[comp],(short)0);	//clear macroblaock
}

/***/
public void loadbits(int size) {
	BitPos = BufferPos<<3;
	BufferPos += size;
}

public int Get_Bits(int N) {
	int Pos, Val;
	Pos = BitPos>>>3;
	Val =   (0xFF&buf[Pos])<<24 |
		(0xFF&buf[Pos+1])<<16 |
		(0xFF&buf[Pos+2])<<8 |
		(0xFF&buf[Pos+3]);
	Val <<= BitPos & 7;
	Val >>>= 32-N;
	BitPos += N;
	BufferPos = BitPos>>>3;
	return Val;
}

public int Show_Bits(int N) {
	int Pos, Val;
	Pos = BitPos>>>3;
	Val =   (0xFF&buf[Pos])<<24 |
		(0xFF&buf[Pos+1])<<16 |
		(0xFF&buf[Pos+2])<<8 |
		(0xFF&buf[Pos+3]);
	Val <<= BitPos & 7;
	Val >>>= 32-N;
	return Val;
}
/***/

public void Flush_Bits(int N) {
	BitPos += N;
	BufferPos = BitPos>>>3;
}

/* decode headers from one input stream */
public int extern_Get_Hdr() {
	int start_code;

	for (;;){
		/* look for next_start_code */
		if (DIRECTION) 
			previous_start_code();
		else 
			next_start_code();

		if ((start_code=Get_Bits(32))==SEQUENCE_HEADER_CODE){
			resetDecoder(); //DM26112003 081.5++
			StartPos=BufferPos-4;
			sequence_header();
			next_start_code();

			if ((start_code=Get_Bits(32))==GROUP_START_CODE)
			{
				group_of_pictures_header();
				next_start_code();

				if ((start_code=Get_Bits(32))==PICTURE_START_CODE)
				{
					picture_header();
					return 1;
				}
			}
		} else if (viewGOP && start_code==GROUP_START_CODE){
			StartPos=BufferPos-4;
			group_of_pictures_header();
			next_start_code();
			if ((start_code=Get_Bits(32))==PICTURE_START_CODE){
				picture_header();
				return 1;
			}
		}
		//else if (start_code==SEQUENCE_END_CODE)
		//	return 2;
		else if (DIRECTION) 
			Flush_Bits(-40);
	}
}

/* decode headers from one input stream */
public int Get_Hdr() {
	video_format=5;

	for (;;){
		/* look for next_start_code */



		next_start_code();

		switch (Get_Bits(32)){
			case SEQUENCE_HEADER_CODE:
				resetDecoder(); //DM26112003 081.5++
				StartPos=BufferPos-4;
				sequence_header();
				break;

			case GROUP_START_CODE:
				group_of_pictures_header();
				break;

			case PICTURE_START_CODE:
				picture_header();
				return 1;

			case SEQUENCE_END_CODE:
				return 2;
		}
	}
}

/* align to start of next next_start_code */
public void next_start_code(){
	Flush_Bits( (8-(BitPos & 7))&7 );
	while (Show_Bits(24) != 1)
		Flush_Bits(8);
}

/* align to start of next next_start_code */
public void previous_start_code(){
	Flush_Bits( (8-(BitPos & 7))&7 );
	while (Show_Bits(24) != 1) 
		Flush_Bits(-8);
}

/* decode sequence header */
private void sequence_header(){
	int constrained_parameters_flag;
	int bit_rate_value;
	int vbv_buffer_size;
	int i;

	horizontal_size             = Get_Bits(12);
	vertical_size               = Get_Bits(12);
	aspect_ratio_information    = Get_Bits(4);
	frame_rate_code             = Get_Bits(4);
	bit_rate_value              = Get_Bits(18);
	Flush_Bits(1);	// marker bit
	vbv_buffer_size             = Get_Bits(10);
	constrained_parameters_flag = Get_Bits(1);

	//DM05072004 081.7 int06 changed
	info_4 = " ";

	if ((load_intra_quantizer_matrix = Get_Bits(1))>0)
	{
		for (i=0; i<64; i++)
			intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);

		//DM05072004 081.7 int06 add
		info_4 += ",iqm";
	}
	else
	{
		System.arraycopy(default_intra_quantizer_matrix,0,intra_quantizer_matrix,0,64);
	}

	if ((load_non_intra_quantizer_matrix = Get_Bits(1))>0)
	{
		for (i=0; i<64; i++)
			non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);

		//DM05072004 081.7 int06 add
		info_4 += ",niqm";
	}
	else
	{
		java.util.Arrays.fill(non_intra_quantizer_matrix,16);
	}

	/* copy luminance to chrominance matrices */
	System.arraycopy(intra_quantizer_matrix,0,chroma_intra_quantizer_matrix,0,64);
	System.arraycopy(non_intra_quantizer_matrix,0,chroma_non_intra_quantizer_matrix,0,64);

	frame_rate = (float)frame_rate_Table[frame_rate_code]; //DM06022004 081.6 int15 add


	extension_and_user_data();

	//DM06052004 081.7 int02 add
	//DM29082004 081.7 int10 changed
	info_3 = ", " + (bit_rate_value * 400) + "bps, vbv " + vbv_buffer_size + (constrained_parameters_flag > 0 ? ", cpf" : "");
}

/* decode group of pictures header */
/* ISO/IEC 13818-2 section 6.2.2.6 */
private void group_of_pictures_header(){
	drop_flag   = Get_Bits(1);
	gop_hour    = Get_Bits(5);
	gop_minute  = Get_Bits(6);
	Flush_Bits(1);	// marker bit
	gop_sec     = Get_Bits(6);
	gop_frame	= Get_Bits(6);
	closed_gop  = Get_Bits(1);
	broken_link = Get_Bits(1);

	extension_and_user_data();
}

/* decode extension and user data */
/* ISO/IEC 13818-2 section 6.2.2.2 */
private void extension_and_user_data(){
	int code, ext_ID;

	next_start_code();

	while ((code = Show_Bits(32))==EXTENSION_START_CODE || code==USER_DATA_START_CODE){
		if (code==EXTENSION_START_CODE)	{
			Flush_Bits(32);
			ext_ID = Get_Bits(4);

			switch (ext_ID)	{
				case SEQUENCE_EXTENSION_ID:
					sequence_extension();
					break;
				case SEQUENCE_DISPLAY_EXTENSION_ID:
					sequence_display_extension();
					break;
				case QUANT_MATRIX_EXTENSION_ID:
					quant_matrix_extension();
					break;
				case PICTURE_DISPLAY_EXTENSION_ID:
					picture_display_extension();
					break;
				case PICTURE_CODING_EXTENSION_ID:
					picture_coding_extension();
					break;
				case COPYRIGHT_EXTENSION_ID:
					copyright_extension();
					break;
			}
			next_start_code();
		}else{
			info_4 += ", user_data"; //DM06052004 081.7 int02 add
			Flush_Bits(32);	// ISO/IEC 13818-2  sections 6.3.4.1 and 6.2.2.2.2
			next_start_code();	// skip user data
		}
	}
}

/* decode picture header */
/* ISO/IEC 13818-2 section 6.2.3 */
private void picture_header(){
	int vbv_delay;
	int full_pel_forward_vector;
	int forward_f_code;
	int full_pel_backward_vector;
	int backward_f_code;
	int Extra_Information_Byte_Count;

	temporal_reference  = Get_Bits(10);
	picture_coding_type = Get_Bits(3);

	vbv_delay = Get_Bits(16);

	if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE)	{
		full_pel_forward_vector = Get_Bits(1);
		forward_f_code = Get_Bits(3);
	}

	if (picture_coding_type==B_TYPE){
		full_pel_backward_vector = Get_Bits(1);
		backward_f_code = Get_Bits(3);
	}

	Extra_Information_Byte_Count = extra_bit_information();
	extension_and_user_data();
}

/* decode sequence extension */
/* ISO/IEC 13818-2 section 6.2.2.3 */
private void sequence_extension(){
	int low_delay;
	int frame_rate_extension_n;
	int frame_rate_extension_d;

	int horizontal_size_extension;
	int vertical_size_extension;
	int bit_rate_extension;
	int vbv_buffer_size_extension;

	profile_and_level_indication = Get_Bits(8);
	progressive_sequence         = Get_Bits(1);
	chroma_format                = Get_Bits(2);
	horizontal_size_extension    = Get_Bits(2);
	vertical_size_extension      = Get_Bits(2);
	bit_rate_extension           = Get_Bits(12);
	Flush_Bits(1);	// marker bit
	vbv_buffer_size_extension    = Get_Bits(8);
	low_delay                    = Get_Bits(1);
 
	frame_rate_extension_n       = Get_Bits(2);
	frame_rate_extension_d       = Get_Bits(5);
	frame_rate = frame_rate * (frame_rate_extension_n+1) / (frame_rate_extension_d+1); //DM06022004 081.6 int15 changed

	horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0xfff);
	vertical_size = (vertical_size_extension<<12) | (vertical_size&0xfff);

	info_4 += ", ld=" + low_delay; //DM26052004 081.7 int03 add
}

/* decode sequence display extension */
private void sequence_display_extension(){
	int color_description;
	int color_primaries;
	int transfer_characteristics;
	int matrix_coefficients;
	int display_horizontal_size;
	int display_vertical_size;

	video_format      = Get_Bits(3);
	color_description = Get_Bits(1);

	if (color_description>0){
		color_primaries          = Get_Bits(8);
		transfer_characteristics = Get_Bits(8);
		matrix_coefficients      = Get_Bits(8);
	}

	display_horizontal_size = Get_Bits(14);
	Flush_Bits(1);	// marker bit
	display_vertical_size   = Get_Bits(14);

	//DM06052004 081.7 int02 add
	//DM26052004 081.7 int03 changed
	info_4 += ", SDE: " + display_horizontal_size + "*" + display_vertical_size;
}

/* decode quant matrix entension */
/* ISO/IEC 13818-2 section 6.2.3.2 */
private void quant_matrix_extension(){
	int i;

	if ((load_intra_quantizer_matrix = Get_Bits(1))>0)
		for (i=0; i<64; i++)
			chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]]
			= intra_quantizer_matrix[scan[ZIG_ZAG][i]] 
			= Get_Bits(8);

	if ((load_non_intra_quantizer_matrix = Get_Bits(1))>0)
		for (i=0; i<64; i++)
			chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]]
			= non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] 
			= Get_Bits(8);

	if ((load_chroma_intra_quantizer_matrix = Get_Bits(1))>0)
		for (i=0; i<64; i++)
			chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);

	if ((load_chroma_non_intra_quantizer_matrix = Get_Bits(1))>0)
		for (i=0; i<64; i++)
			chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8);
}

/* decode picture display extension */
/* ISO/IEC 13818-2 section 6.2.3.3. */
private void picture_display_extension(){
	int frame_center_horizontal_offset[] = new int[3];
	int frame_center_vertical_offset[] = new int[3];

	int i;
	int number_of_frame_center_offsets;

	/* based on ISO/IEC 13818-2 section 6.3.12 
	   (November 1994) Picture display extensions */

	/* derive number_of_frame_center_offsets */
	if (progressive_sequence>0){
		if (repeat_first_field>0)	{
			if (top_field_first>0)
				number_of_frame_center_offsets = 3;
			else
				number_of_frame_center_offsets = 2;
		}else
			number_of_frame_center_offsets = 1;
	}else{
		if (picture_structure!=FRAME_PICTURE)
			number_of_frame_center_offsets = 1;
		else{
			if (repeat_first_field>0)
				number_of_frame_center_offsets = 3;
			else
				number_of_frame_center_offsets = 2;
		}
	}

	/* now parse */
	for (i=0; i<number_of_frame_center_offsets; i++){
		frame_center_horizontal_offset[i] = Get_Bits(16);
		Flush_Bits(1);	// marker bit

		frame_center_vertical_offset[i] = Get_Bits(16);
		Flush_Bits(1);	// marker bit

		//DM24062004 081.7 int05 add
		info_3 += ", (" + frame_center_horizontal_offset[i] + "," + frame_center_vertical_offset[i] + ")";
	}
}

/* decode picture coding extension */
private void picture_coding_extension(){
	int chroma_420_type;
	int composite_display_flag;
	int v_axis;
	int field_sequence;
	int sub_carrier;
	int burst_amplitude;
	int sub_carrier_phase;

	f_code[0][0] = Get_Bits(4);
	f_code[0][1] = Get_Bits(4);
	f_code[1][0] = Get_Bits(4);
	f_code[1][1] = Get_Bits(4);

	intra_dc_precision		= Get_Bits(2);
	picture_structure		= Get_Bits(2);
	top_field_first			= Get_Bits(1);
	frame_pred_frame_dct		= Get_Bits(1);
	concealment_motion_vectors	= Get_Bits(1);
	q_scale_type			= Get_Bits(1);
	intra_vlc_format		= Get_Bits(1);
	alternate_scan			= Get_Bits(1);
	repeat_first_field		= Get_Bits(1);
	chroma_420_type			= Get_Bits(1);
	progressive_frame		= Get_Bits(1);
	composite_display_flag		= Get_Bits(1);

	if (composite_display_flag>0){
		v_axis            = Get_Bits(1);
		field_sequence    = Get_Bits(3);
		sub_carrier       = Get_Bits(1);
		burst_amplitude   = Get_Bits(7);
		sub_carrier_phase = Get_Bits(8);

		//DM29082004 081.7 int10 add
		info_3 += ", cdf";
	}
}

/* Copyright extension */
/* ISO/IEC 13818-2 section 6.2.3.6. */
/* (header added in November, 1994 to the IS document) */
public void copyright_extension(){
	int copyright_flag;
	int copyright_identifier;
	int original_or_copy;
	int copyright_number_1;
	int copyright_number_2;
	int copyright_number_3;

	int reserved_data;

	copyright_flag =       Get_Bits(1); 
	copyright_identifier = Get_Bits(8);
	original_or_copy =     Get_Bits(1);
  
	/* reserved */
	reserved_data = Get_Bits(7);

	Flush_Bits(1); // marker bit
	copyright_number_1 =   Get_Bits(20);
	Flush_Bits(1); // marker bit
	copyright_number_2 =   Get_Bits(22);
	Flush_Bits(1); // marker bit
	copyright_number_3 =   Get_Bits(22);
}

/* set std for lower profiles as mpeg1 */
public void resetDecoder(){
	Fault_Flag=0; //DM14052004 081.7 int02 add,fix
	picture_coding_type=0; //DM14052004 081.7 int02 add,fix
	SequenceHeader=1;
	video_format=5;
	progressive_sequence=1;
	chroma_format=1;
	profile_and_level_indication=0;
	Second_Field=0;
	intra_dc_precision=0;
	picture_structure=FRAME_PICTURE;
	top_field_first=0;
	frame_pred_frame_dct=1;
	concealment_motion_vectors=0;
	intra_vlc_format=0;
	repeat_first_field=0;
	progressive_frame=1;
	q_scale_type=0;
	quantizer_scale=0;
	alternate_scan=0;
}

public void InitialDecoder(){

	mb_width = (horizontal_size+15)/16;
	mb_height = (progressive_sequence>0) ? (vertical_size+15)/16 : 2*((vertical_size+31)/32);

	Coded_Picture_Width = 16 * mb_width;
	Coded_Picture_Height = 16 * mb_height;

	Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width : Coded_Picture_Width>>1;
	Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height : Coded_Picture_Height>>1;

	block_count = ChromaFormat[chroma_format];

	if (picture_coding_type==I_TYPE) 
		pixels = new int[Coded_Picture_Width*Coded_Picture_Height]; //DM30112003 081.5++ fix
}


//public void Decode_Picture(int ref, byte dst, int pitch){
public void Decode_Picture(){
	if (picture_structure==FRAME_PICTURE && Second_Field>0)
		Second_Field = 0;

	if (picture_coding_type!=B_TYPE){
		pf_forward = pf_backward;
		pf_backward = pf_current;
	}

	//moved
	String SH[] = { "G","S" };
	String cf[] = { "res.","4:2:0","4:2:2","4:4:4" };
	String fieldorder[] = {"bff","tff"}; //<==TheHorse 221003
	String picture_struc[] = {"-","T","B","F"}; //DM08022004 081.6 int16 add

	//DM26022004 081.6 int18 changed
	//DM06052004 081.7 int02 changed
	info_2 = "" + gop_hour + ":" + gop_minute + ":" + gop_sec + ":" + gop_frame + " ";
	info_2 += ", " + drop_flag + "/" + closed_gop + "/" + broken_link + " ";
	info_2 += ", " + (Math.round(frame_rate * 1000) / 1000.0f) + "fps ";  //DM06022004 081.6 int15 change
	info_2 += ", " + SH[SequenceHeader] + " ";
	info_2 += ", " + picture_struc[picture_structure];  //DM08022004 081.6 int16 add
	info_2 += ", " + ((progressive_sequence==0) ? fieldorder[top_field_first] : "-") + " "; //<==TheHorse 221003 
	info_2 += ", " + cf[chroma_format];
	info_2 += info_3;

	SequenceHeader=0;
	Update_Picture_Buffers();
	picture_data();
	scale_Picture();

/**
	if (ref>0 && (picture_structure==FRAME_PICTURE || Second_Field>0)){
		if (picture_coding_type==B_TYPE)
			FrametoRGB(auxframe, pf_current, dst, pitch);
		else
			FrametoRGB(forward_reference_frame, pf_forward, dst, pitch);
	}
**/
	if (picture_structure!=FRAME_PICTURE)
		Second_Field ^= Second_Field;
}

/* reuse old picture buffers as soon as they are no longer needed */
public void Update_Picture_Buffers(){                           

	int cc;              /* color component index */
	byte tmp;  /* temporary swap pointer */

	for (cc=0; cc<3; cc++)	{
		/* B pictures  do not need to be save for future reference */
		if (picture_coding_type==B_TYPE)
			current_frame[cc] = auxframe[cc];
		else{
			if (Second_Field<1){
				/* only update at the beginning of the coded frame */
				tmp = forward_reference_frame[cc];

				/* the previously decoded reference frame is stored coincident with the 
				   location where the backward reference frame is stored (backwards 
				   prediction is not needed in P pictures) */
				forward_reference_frame[cc] = backward_reference_frame[cc];

				/* update pointer for potential future B pictures */
				backward_reference_frame[cc] = tmp;
			}

			/* can erase over old backward reference frame since it is not used
			   in a P picture, and since any subsequent B pictures will use the 
			   previously decoded I or P frame as the backward_reference_frame */
			current_frame[cc] = backward_reference_frame[cc];
		}

	    if (picture_structure==BOTTOM_FIELD)
			current_frame[cc] += (cc==0) ? Coded_Picture_Width : Chroma_Width;
	}
}

/* decode all macroblocks of the current picture */
/* stages described in ISO/IEC 13818-2 section 7 */
public void picture_data(){
	int MBAmax;
	int err=0;

	/* number of macroblocks per picture */
	MBAmax = mb_width*mb_height;

	if (picture_structure!=FRAME_PICTURE)
		MBAmax>>=1;

	for (;;)
		if (slice(MBAmax)<0)
			return;
}

/* decode slice header */
/* ISO/IEC 13818-2 section 6.2.4 */
public int slice_header(){
	int slice_picture_id_enable = 0;
	int slice_picture_id = 0;
	int extra_information_slice = 0;

	int slice_vertical_position_extension = vertical_size>2800 ? Get_Bits(3) : 0;

	int quantizer_scale_code = Get_Bits(5);
	quantizer_scale = (q_scale_type>0) ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1;

	/* slice_id introduced in March 1995 as part of the video corridendum
	   (after the IS was drafted in November 1994) */
	if (Get_Bits(1)>0){
		Get_Bits(1);	// intra slice

		slice_picture_id_enable = Get_Bits(1);
		slice_picture_id = Get_Bits(6);

		extra_information_slice = extra_bit_information();
	}

	return slice_vertical_position_extension;
}

/* decode extra bit information */
/* ISO/IEC 13818-2 section 6.2.3.4. */
public int extra_bit_information(){
	int Byte_Count = 0;

	while (Get_Bits(1)>0){
		Flush_Bits(8);
		Byte_Count ++;
	}

	return Byte_Count;
}



/* decode all macroblocks of the current picture */
/* ISO/IEC 13818-2 section 6.3.16 */
/* return 0 : go to next slice */
/* return -1: go to next picture */
public int slice(int MBAmax){

	int MBA[] = {0}, MBAinc[] ={0}, macroblock_type[]={0}, motion_type[]={0}, dct_type[]={0}, ret=0;
	int dc_dct_pred[] = new int[3], PMV[][][] = new int[2][2][2], 
		motion_vertical_field_select[][] = new int[2][2], dmvector[] = new int[2];

	if ((ret=start_of_slice(MBA, MBAinc, dc_dct_pred, PMV))!=1) return ret;

	for (;;){
		/* this is how we properly exit out of picture */
		if (MBA[0]>=MBAmax) return -1;		// all macroblocks decoded

		if (MBAinc[0]==0)	{
			if (Show_Bits(23)<1 || Fault_Flag>0){	// next_start_code or fault
				Fault_Flag = 0;
				return 0;	// trigger: go to next slice
			}else{	/* neither next_start_code nor Fault_Flag */
				/* decode macroblock address increment */
				MBAinc[0] = Get_macroblock_address_increment();
				if (Fault_Flag>0) {
					Fault_Flag = 0;
					return 0;	// trigger: go to next slice
				}
			}
		}

//test
//System.out.println("mba " + MBA[0]);

		if (MBAinc[0]==1) { /* not skipped */
			if (decode_macroblock(macroblock_type, motion_type, dct_type, PMV,
				dc_dct_pred, motion_vertical_field_select, dmvector)<1) {
					Fault_Flag = 0;
					//DM14052004 081.7 int02 changed
					return 0; //return -1; // return 0;	// trigger: go to next slice
			}
		}else{ /* MBAinc[0]!=1: skipped macroblock */	/* ISO/IEC 13818-2 section 7.6.6 */
			skipped_macroblock(dc_dct_pred, PMV, motion_type, 
					motion_vertical_field_select, macroblock_type);
		}

		/* ISO/IEC 13818-2 section 7.6 */
		motion_compensation(MBA, macroblock_type, motion_type, PMV,
					motion_vertical_field_select, dmvector, dct_type);

		/* advance to next macroblock */
		MBA[0]++; MBAinc[0]--;

		if (MBA[0]>=MBAmax) return -1;		// all macroblocks decoded
	}
}


/* ISO/IEC 13818-2 section 7.6.6 */
public void skipped_macroblock(int dc_dct_pred[], int PMV[][][], int motion_type[], 
		 int motion_vertical_field_select[][], int macroblock_type[]){

	int comp;

	for (comp=0; comp<block_count; comp++) Clear_Block(comp);

	/* reset intra_dc predictors */
	/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */
	dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;

	/* reset motion vector predictors */
	/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
	if (picture_coding_type==P_TYPE) PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;

	/* derive motion_type */
	if (picture_structure==FRAME_PICTURE) motion_type[0] = MC_FRAME;
	else{
		motion_type[0] = MC_FIELD;
		motion_vertical_field_select[0][0] = motion_vertical_field_select[0][1] = 
			((picture_structure==BOTTOM_FIELD)?1:0);
	}

	/* clear MACROBLOCK_INTRA */
	macroblock_type[0] &= ~MACROBLOCK_INTRA;
}

/* ISO/IEC 13818-2 sections 7.2 through 7.5 */
public int decode_macroblock(int macroblock_type[], int motion_type[], int dct_type[],
			 int PMV[][][], int dc_dct_pred[], 
			 int motion_vertical_field_select[][], int dmvector[]){

	int quantizer_scale_code, comp, motion_vector_count[]={0}, mv_format[]={0}; 
	int dmv[]={0}, mvscale[]={0}, coded_block_pattern;

	/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */
	macroblock_modes(macroblock_type, motion_type, motion_vector_count, mv_format,
					 dmv, mvscale, dct_type);

	if (Fault_Flag>0) return 0;	// trigger: go to next slice

	if ( (macroblock_type[0] & MACROBLOCK_QUANT)>0 ){

		quantizer_scale_code = Get_Bits(5);

		/* ISO/IEC 13818-2 section 7.4.2.2: Quantizer scale factor */
		quantizer_scale = (q_scale_type>0) ?
		Non_Linear_quantizer_scale[quantizer_scale_code] : (quantizer_scale_code << 1);
	}

	/* ISO/IEC 13818-2 section 6.3.17.2: Motion vectors */
	/* decode forward motion vectors */
	if ( ((macroblock_type[0] & MACROBLOCK_MOTION_FORWARD)>0) 
		|| (((macroblock_type[0] & MACROBLOCK_INTRA)>0) && (concealment_motion_vectors>0)))
		motion_vectors(PMV, dmvector, motion_vertical_field_select, 0,
		motion_vector_count, mv_format, f_code[0][0]-1, f_code[0][1]-1, dmv, mvscale);

	if (Fault_Flag>0) return 0;	// trigger: go to next slice

	/* decode backward motion vectors */
	if ((macroblock_type[0] & MACROBLOCK_MOTION_BACKWARD)>0)
		motion_vectors(PMV, dmvector, motion_vertical_field_select, 1,
		motion_vector_count,mv_format, f_code[1][0]-1, f_code[1][1]-1, new int[1], mvscale);

	if (Fault_Flag>0) return 0;  // trigger: go to next slice

	if (((macroblock_type[0] & MACROBLOCK_INTRA)>0) && (concealment_motion_vectors>0))
		Flush_Bits(1);	// marker bit

	/* macroblock_pattern */
	/* ISO/IEC 13818-2 section 6.3.17.4: Coded block pattern */
	if ((macroblock_type[0] & MACROBLOCK_PATTERN)>0)	{
		coded_block_pattern = Get_coded_block_pattern();

		if (chroma_format==CHROMA422)
			coded_block_pattern = (coded_block_pattern<<2) | Get_Bits(2);
		else if (chroma_format==CHROMA444)
			coded_block_pattern = (coded_block_pattern<<6) | Get_Bits(6);
	}else
	    coded_block_pattern = ((macroblock_type[0] & MACROBLOCK_INTRA)>0) ? (1<<block_count)-1 : 0;

	if (Fault_Flag>0) return 0;	// trigger: go to next slice

//test
/**
System.out.println(
	"ma " + macroblock_type[0] + 
	" /mt " + motion_type[0] + 
	" /mv " + motion_vector_count[0] + 
	" /mf " + mv_format[0] +
	" /ms " + mvscale[0] + 
	" /dm " + dmv[0] + 
	" /dc " + dct_type[0] +
	" /qs " + quantizer_scale + 
	" /qt " + q_scale_type +
	" /cm " + concealment_motion_vectors
);
**/

	/* decode blocks */
	for (comp=0; comp<block_count; comp++)	{
		Clear_Block(comp);

		if ((coded_block_pattern & (1<<(block_count-1-comp)))>0){
			if ((macroblock_type[0] & MACROBLOCK_INTRA)>0)
				Decode_MPEG2_Intra_Block(comp, dc_dct_pred);
			else
				Decode_MPEG2_Non_Intra_Block(comp);
			
			if (Fault_Flag>0) return 0;	// trigger: go to next slice
		}
	}

	/* reset intra_dc predictors */
	/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */
	if ((macroblock_type[0] & MACROBLOCK_INTRA)<1)
		dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;

	/* reset motion vector predictors */
	if ((macroblock_type[0] & MACROBLOCK_INTRA)>0 && concealment_motion_vectors<1 ) {
		/* intra mb without concealment motion vectors */
		/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
		PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
		PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
	}

	/* special "No_MC" macroblock_type case */
	/* ISO/IEC 13818-2 section 7.6.3.5: Prediction in P pictures */
	if ((picture_coding_type==P_TYPE) 
		&& (macroblock_type[0] & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_INTRA))<1)	{

		/* non-intra mb without forward mv in a P picture */
		/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
		PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;

		/* derive motion_type */
		/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes, frame_motion_type */
		if (picture_structure==FRAME_PICTURE)	motion_type[0] = MC_FRAME;
		else{
			motion_type[0] = MC_FIELD;
			motion_vertical_field_select[0][0] = (picture_structure==BOTTOM_FIELD)?1:0;
		}
	}
	/* successfully decoded macroblock */
	return 1 ;
}


/* decode one intra coded MPEG-2 block */
public void Decode_MPEG2_Intra_Block(int comp, int dc_dct_pred[]) {

	int val=0, i, j, sign, qmat[]; //qmat woanders??
	int code;
	byte tab[];
	short bp[];  //bp woanders array?

	bp = block[comp];  //macroblock
	qmat = (comp<4 || chroma_format==CHROMA420) 
		? intra_quantizer_matrix : chroma_intra_quantizer_matrix;

	/* ISO/IEC 13818-2 section 7.2.1: decode DC coefficients */
	switch (cc_table[comp])	{
		case 0:
			val = (dc_dct_pred[0]+= Get_Luma_DC_dct_diff());
			break;

		case 1:
			val = (dc_dct_pred[1]+= Get_Chroma_DC_dct_diff());
			break;

		case 2:
			val = (dc_dct_pred[2]+= Get_Chroma_DC_dct_diff());
			break;
	}

//test
/**
System.out.println("comp " + comp + " /dc " + val);
if (quantizer_scale > 4)
	val -= 128;
**/
	bp[0] = (short)(val << (3-intra_dc_precision));  //the top-left pixel value of block

	/* decode AC coefficients */
	for (i=1; ; i++){
		code = Show_Bits(16);

		if (code>=16384 && intra_vlc_format<1)
			tab = DCTtabnext[(code>>12)-4];
		else if (code>=1024){
			if (intra_vlc_format>0)
				tab = DCTtab0a[(code>>8)-4];
			else
				tab = DCTtab0[(code>>8)-4];
		}
		else if (code>=512){
			if (intra_vlc_format>0)
				tab = DCTtab1a[(code>>6)-8];
			else
				tab = DCTtab1[(code>>6)-8];
		}
		else if (code>=256)
			tab = DCTtab2[(code>>4)-16];
		else if (code>=128)
			tab = DCTtab3[(code>>3)-16];
		else if (code>=64)
			tab = DCTtab4[(code>>2)-16];
		else if (code>=32)
			tab = DCTtab5[(code>>1)-16];
		else if (code>=16)
			tab = DCTtab6[code-16];
		else{
			Fault_Flag = 1;
			return;
		}

		Flush_Bits(tab[2]);

		if (tab[0]<64){
			i+= tab[0];
			val = tab[1];
			sign = Get_Bits(1);
		}
		else if (tab[0]==64) /* end_of_block */
			return;

		else{ /* escape */
			if (profile_and_level_indication==0){
				//mpeg1 //DM28112003 081.5++
				i+= Get_Bits(6);
				val = Get_Bits(8);
				if (val==0)
					val = Get_Bits(8);
				else if(val==128)
					val = Get_Bits(8)-128;
				else if(val>128)
					val-=256;
				sign = 0;
			}else{
				//mpeg2
				i+= Get_Bits(6);
				val = Get_Bits(12);
				if ( (sign = (val>=2048)?1:0) >0)
					val = 4096 - val;
			}
		}

		j = scan[alternate_scan][i];

		val = (val * quantizer_scale * qmat[j]) >> 4;
		bp[j] = (short)((sign>0) ? -val : val);
	}
}


/* decode one non-intra coded MPEG-2 block */
public void Decode_MPEG2_Non_Intra_Block(int comp){
	int val, i, j, sign, qmat[];
	int code;
	byte tab[];
	short bp[];

	bp = block[comp];
	qmat = (comp<4 || chroma_format==CHROMA420) 
		? non_intra_quantizer_matrix : chroma_non_intra_quantizer_matrix;

	/* decode AC coefficients */
	for (i=0; ; i++){
		code = Show_Bits(16);

		if (code>=16384){
			if (i==0)
				tab = DCTtabfirst[(code>>12)-4];
			else
				tab = DCTtabnext[(code>>12)-4];
		}
		else if (code>=1024)
			tab = DCTtab0[(code>>8)-4];
		else if (code>=512)
			tab = DCTtab1[(code>>6)-8];
		else if (code>=256)
			tab = DCTtab2[(code>>4)-16];
		else if (code>=128)
			tab = DCTtab3[(code>>3)-16];
		else if (code>=64)
			tab = DCTtab4[(code>>2)-16];
		else if (code>=32)
			tab = DCTtab5[(code>>1)-16];
		else if (code>=16)
			tab = DCTtab6[code-16];
		else{
			Fault_Flag = 1;
			return;
		}

		Flush_Bits(tab[2]);

		if (tab[0]<64){
			i+= tab[0];
			val = tab[1];
			sign = Get_Bits(1);
		}
		else if (tab[0]==64) /* end_of_block */
			return;
		else { /* escape */
			i+= Get_Bits(6);
			val = Get_Bits(12);

			if ( (sign = (val>=2048)?1:0)>0 )
				val = 4096 - val;
		}

		j = scan[alternate_scan][i];

		val = (((val<<1)+1) * quantizer_scale * qmat[j]) >> 5;
		bp[j] = (short)((sign>0) ? -val : val);
	}
}


/*
   parse VLC and perform dct_diff arithmetic.
   MPEG-2:  ISO/IEC 13818-2 section 7.2.1 

   Note: the arithmetic here is presented more elegantly than
   the spec, yet the results, dct_diff, are the same.
*/
public int Get_Luma_DC_dct_diff(){
	int code, size, dct_diff;

	/* decode length */
	code = Show_Bits(5);

	if (code<31){
		size = DClumtab0[code][0];
		Flush_Bits(DClumtab0[code][1]);
	}else{
		code = Show_Bits(9) - 0x1f0;
		size = DClumtab1[code][0];
		Flush_Bits(DClumtab1[code][1]);
	}

	if (size==0)
		dct_diff = 0;
	else{
		dct_diff = Get_Bits(size);

		if ((dct_diff & (1<<(size-1)))==0)
			dct_diff-= (1<<size) - 1;
	}

	return dct_diff;
}

public int Get_Chroma_DC_dct_diff(){
	int code, size, dct_diff;

	/* decode length */
	code = Show_Bits(5);

	if (code<31){
		size = DCchromtab0[code][0];
		Flush_Bits(DCchromtab0[code][1]);
	}else{
		code = Show_Bits(10) - 0x3e0;
		size = DCchromtab1[code][0];
		Flush_Bits(DCchromtab1[code][1]);
	}

	if (size==0)
		dct_diff = 0;
	else{
		dct_diff = Get_Bits(size);

		if ((dct_diff & (1<<(size-1)))==0)
			dct_diff-= (1<<size) - 1;
	}

	return dct_diff;
}


public int Get_coded_block_pattern(){
	int code;

	if ((code = Show_Bits(9))>=128)	{
		code >>= 4;
		Flush_Bits(CBPtab0[code][1]);

		return CBPtab0[code][0];
	}

	if (code>=8)	{
		code >>= 1;
		Flush_Bits(CBPtab1[code][1]);

		return CBPtab1[code][0];
	}

	if (code<1)	{
		Fault_Flag = 3;
		return 0;
	}

	Flush_Bits(CBPtab2[code][1]);

	return CBPtab2[code][0];
}


/* return==-1 means go to next picture */
/* the expression "start of slice" is used throughout the normative
   body of the MPEG specification */
public int start_of_slice(int MBA[], int MBAinc[],  int dc_dct_pred[], int PMV[][][]){

	next_start_code();
	int code = Get_Bits(32);

	if (code<SLICE_START_CODE_MIN || code>SLICE_START_CODE_MAX){
		// only slice headers are allowed in picture_data
		Fault_Flag = 10;
		return -1;
	}

	/* decode slice header (may change quantizer_scale) */
	int slice_vert_pos_ext = slice_header();

	/* decode macroblock address increment */
	MBAinc[0] = Get_macroblock_address_increment();

	if (Fault_Flag>0) return -1;

	/* set current location */
	/* NOTE: the arithmetic used to derive macroblock_address below is
	   equivalent to ISO/IEC 13818-2 section 6.3.17: Macroblock */
	MBA[0] = ((slice_vert_pos_ext<<7) + (code&255) - 1) * mb_width + MBAinc[0] - 1;
	MBAinc[0] = 1;	// first macroblock in slice: not skipped

	/* reset all DC coefficient and motion vector predictors */
	/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */
	dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
  
	/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */
	PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
	PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;

	/* successfull: trigger decode macroblocks in slice */
	return 1;
}


public int Get_macroblock_address_increment(){
	int code=0, val=0;

	while ((code = Show_Bits(11))<24){
		if (code!=15){ /* if not macroblock_stuffing */
			if (code==8) /* if macroblock_escape */
				val+= 33;
			else{
				Fault_Flag = 4;
				return 1;
			}
		}
		Flush_Bits(11);
	}

	/* macroblock_address_increment == 1 */
	/* ('1' is in the MSB position of the lookahead) */
	if (code>=1024)	{
		Flush_Bits(1);
		return (val + 1);
	}

	/* codes 00010 ... 011xx */
	if (code>=128)	{
		/* remove leading zeros */
		code >>= 6;
		Flush_Bits(MBAtab1[code][1]);
    
		return (val + MBAtab1[code][0]);
	}
  
	/* codes 00000011000 ... 0000111xxxx */
	code-= 24; /* remove common base */
	Flush_Bits(MBAtab2[code][1]);

	return (val + MBAtab2[code][0]);
}

/* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */
public void motion_vectors(int PMV[][][],int dmvector[],
		int motion_vertical_field_select[][], int s,
		int motion_vector_count[], int mv_format[], int h_r_size,
		int v_r_size, int dmv[], int mvscale[]){

	if (motion_vector_count[0]==1)	{
		if (mv_format[0]==MV_FIELD && dmv[0]<1)
			motion_vertical_field_select[1][s] =
			motion_vertical_field_select[0][s] = Get_Bits(1);

		motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);

		/* update other motion vector predictors */
		PMV[1][s][0] = PMV[0][s][0];
		PMV[1][s][1] = PMV[0][s][1];
	}else{
		motion_vertical_field_select[0][s] = Get_Bits(1);
		motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
		motion_vertical_field_select[1][s] = Get_Bits(1);
		motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
	}
}

/* get and decode motion vector and differential motion vector for one prediction */
public void motion_vector(int PMV[], int dmvector[], int h_r_size, int v_r_size,
				   int dmv[], int mvscale[], int full_pel_vector){

	int motion_code, motion_residual;

	/* horizontal component */
	/* ISO/IEC 13818-2 Table B-10 */
	motion_code = Get_motion_code();

	motion_residual = (h_r_size!=0 && motion_code!=0) ? Get_Bits(h_r_size) : 0;



	decode_motion_vector(PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector);

	if (dmv[0]>0)
		dmvector[0] = Get_dmvector();

	/* vertical component */
	motion_code     = Get_motion_code();
	motion_residual = (v_r_size!=0 && motion_code!=0) ? Get_Bits(v_r_size) : 0;

	if (mvscale[0]>0)
		PMV[1] >>= 1; /* DIV 2 */

	decode_motion_vector(PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector);

	if (mvscale[0]>0)
		PMV[1] <<= 1;

	if (dmv[0]>0)
		dmvector[1] = Get_dmvector();
}

/* calculate motion vector component */
/* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */
/* Note: the arithmetic here is more elegant than that which is shown 
   in 7.6.3.1.  The end results (PMV[][][]) should, however, be the same.  */
public void decode_motion_vector(int pred, int r_size, int motion_code,
			 int motion_residual, int full_pel_vector){

	int lim, vec;

	lim = 16<<r_size;
	vec = (full_pel_vector>0) ? (pred >> 1) : (pred);

	if (motion_code>0){
		vec+= ((motion_code-1)<<r_size) + motion_residual + 1;
		if (vec>=lim)
			vec-= lim + lim;
	}else if (motion_code<0){
		vec-= ((-motion_code-1)<<r_size) + motion_residual + 1;
		if (vec<-lim)
			vec+= lim + lim;
	}

	pred = (full_pel_vector>0) ? (vec<<1) : vec;
}

/* ISO/IEC 13818-2 section 7.6.3.6: Dual prime additional arithmetic */
public void Dual_Prime_Arithmetic(int DMV[][],int dmvector[], int mvx,int mvy){
	if (picture_structure==FRAME_PICTURE){
		if (top_field_first>0){
			/* vector for prediction of top field from bottom field */
			DMV[0][0] = ((mvx  +((mvx>0)?1:0))>>1) + dmvector[0];
			DMV[0][1] = ((mvy  +((mvy>0)?1:0))>>1) + dmvector[1] - 1;

			/* vector for prediction of bottom field from top field */
			DMV[1][0] = ((3*mvx+((mvx>0)?1:0))>>1) + dmvector[0];
			DMV[1][1] = ((3*mvy+((mvy>0)?1:0))>>1) + dmvector[1] + 1;
		}else{
			/* vector for prediction of top field from bottom field */
			DMV[0][0] = ((3*mvx+((mvx>0)?1:0))>>1) + dmvector[0];
			DMV[0][1] = ((3*mvy+((mvy>0)?1:0))>>1) + dmvector[1] - 1;

			/* vector for prediction of bottom field from top field */
			DMV[1][0] = ((mvx  +((mvx>0)?1:0))>>1) + dmvector[0];
			DMV[1][1] = ((mvy  +((mvy>0)?1:0))>>1) + dmvector[1] + 1;
		}
	}else{
		/* vector for prediction from field of opposite 'parity' */
		DMV[0][0] = ((mvx+((mvx>0)?1:0))>>1) + dmvector[0];
		DMV[0][1] = ((mvy+((mvy>0)?1:0))>>1) + dmvector[1];

		/* correct for vertical field shift */
		if (picture_structure==TOP_FIELD)
			DMV[0][1]--;


		else
			DMV[0][1]++;
	}
}


/* ISO/IEC 13818-2 section 7.6 */
public void motion_compensation(int MBA[], int macroblock_type[], int motion_type[], 
		int PMV[][][], int motion_vertical_field_select[][],
		int dmvector[], int dct_type[]){

	int bx, by;
	int comp;

	/* derive current macroblock position within picture */
	/* ISO/IEC 13818-2 section 6.3.1.6 and 6.3.1.7 */
	bx = 16*(MBA[0]%mb_width);
	by = 16*(MBA[0]/mb_width);

	/* motion compensation */
	//if ((macroblock_type[0] & MACROBLOCK_INTRA)<1)
		//form_predictions(bx, by, macroblock_type, motion_type, PMV, motion_vertical_field_select, dmvector);

	//DM08022004 081.6 int16 changed
	/* copy or add block data into picture */
	for (comp=0; comp<block_count; comp++)	{
		/* ISO/IEC 13818-2 section Annex A: inverse DCT */

//
		if (IDCTSseNative.isLibraryLoaded())
			idctsse.referenceIDCT(block[comp]);

		else if (IDCTRefNative.isLibraryLoaded())
			idct.referenceIDCT(block[comp]);

		else
			IDCT_reference(block[comp], FAST ? 1 : 8);
//


		/* ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data */
		Add_Block(comp, bx, by, dct_type, (macroblock_type[0] & MACROBLOCK_INTRA)==0);
	}

}

/*  Perform IEEE 1180 reference (64-bit floating point, separable 8x1
 *  direct matrix multiply) Inverse Discrete Cosine Transform
 */
//DM08022004 081.6 int16 changed to float and first pixel only
public void IDCT_reference(short block[], int len){
	int i, j, k, v;
	float partial_product;
	float tmp[] = new float[64];

	for (i=0; i<len; i++)
		for (j=0; j<len; j++){
			partial_product = 0.0f;

			for (k=0; k<8; k++)
				partial_product += ref_dct_matrix[k][j] * block[8*i+k];

			tmp[8*i+j] = partial_product;
		}

	// Transpose operation is integrated into address mapping by switching loop order of i and j
	for (j=0; j<len; j++){
		for (i=0; i<len; i++){
			partial_product = 0.0f;

			for (k=0; k<8; k++)
				partial_product += ref_dct_matrix[k][i] * tmp[8*k+j];

			v = (int) Math.floor(partial_product+0.5);
			block[8*i+j] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET+v];
		}
	}

	if (len==1)
		Arrays.fill(block,block[0]);
}

	/**
	 * integer matrix by dukios
	 *
	static int ref_dct_matrix_i[] = new int[64];
	static {
		for(int i = 0; i < 8; i++)
		{
			for(int j = 0; j < 8; j++)
			{
				ref_dct_matrix_i[i * 8 + j] = Math.round(ref_dct_matrix[i][j] * 65536.0f);
			}
		}
	}

	public void IDCT_referenceFAST(short block[]){
		int i, j, k, v;

		long tmp0  = ref_dct_matrix_i[0] * block[0];	
		long partial_product = ref_dct_matrix_i[0] * tmp0;

		v = (int) (partial_product >> 32);
		block[0] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET + v];

		Arrays.fill(block,block[0]);
	}


	
	public void IDCT_reference(short block[]){
		int i, j, k, v;

		long tmp[] = new long[64];

		int i8 = 0;
		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				tmp[i8 + j] = (
						ref_dct_matrix_i[0 + j] * block[i8] +
						ref_dct_matrix_i[8 + j] * block[i8 + 1] +
						ref_dct_matrix_i[16 + j] * block[i8 + 2] +
						ref_dct_matrix_i[24 + j] * block[i8 + 3] +
						ref_dct_matrix_i[32 + j] * block[i8 + 4] +
						ref_dct_matrix_i[40 + j] * block[i8 + 5] +
						ref_dct_matrix_i[48 + j] * block[i8 + 6] +
						ref_dct_matrix_i[56 + j] * block[i8 + 7]);

			}
			i8 += 8;
		}

		// Transpose operation is integrated into address mapping by switching loop order of i and j
		for (j = 0; j < 8; j++)
		{
			for (i = 0; i < 8; i++)
			{
				long partial_product = (
					ref_dct_matrix_i[i] * tmp[j] +
					ref_dct_matrix_i[8 + i] * tmp[8 + j] +
					ref_dct_matrix_i[16 + i] * tmp[16 + j] +
					ref_dct_matrix_i[24 + i] * tmp[24 + j] +
					ref_dct_matrix_i[32 + i] * tmp[32 + j] +
					ref_dct_matrix_i[40 + i] * tmp[40 + j] +
					ref_dct_matrix_i[48 + i] * tmp[48 + j] +
					ref_dct_matrix_i[56 + i] * tmp[56 + j]);
					
				v = (int) (partial_product >> 32);
				block[8 * i + j] = idct_clip_table[IDCT_CLIP_TABLE_OFFSET + v];
			}
		}
	}
	**/

/* move/add 8x8-Block from block[comp] to backward_reference_frame */
/* copy reconstructed 8x8 block from block[comp] to current_frame[]
   ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data
   This stage also embodies some of the operations implied by:
   - ISO/IEC 13818-2 section 7.6.7: Combining predictions
   - ISO/IEC 13818-2 section 6.1.3: Macroblock
*/
//DM02092003+ changed
//DM08022004 081.6 int16 changed to float
public void Add_Block(int comp, int bx, int by, int dct_type[], boolean addflag){

	int cc, iincr;
	int rfp;
	short Block_Ptr[] = block[comp];

	/* derive color component index */
	/* equivalent to ISO/IEC 13818-2 Table 7-1 */
	cc = cc_table[comp];


	if (cc==0){
		if (picture_structure==FRAME_PICTURE){   //progressive
			if (dct_type[0]>0){
				rfp = current_frame[0] + Coded_Picture_Width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3);
				iincr = (Coded_Picture_Width<<1) - 8;
			}else{
				rfp = current_frame[0] + Coded_Picture_Width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3);
				iincr = Coded_Picture_Width - 8;
			}
		}else{
			rfp = current_frame[0] + (Coded_Picture_Width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3);
			iincr = (Coded_Picture_Width<<1) - 8;
		}
	}else{
		// chrominance
		// scale coordinates
		if (chroma_format!=CHROMA444) bx >>= 1;
		//if (chroma_format==CHROMA420) by >>= 1; // disabled

		if (picture_structure==FRAME_PICTURE){  //two fields in one pic=std
			if (dct_type[0]>0 && chroma_format!=CHROMA420){
				// field DCT coding
				rfp = current_frame[cc] + Chroma_Width*(by+((comp&2)>>1)) + bx + (comp&8);
				iincr = (Chroma_Width<<1) - 8;
			}else{
				// frame DCT coding
				rfp = current_frame[cc] + Chroma_Width*(by+((comp&2)<<2)) + bx + (comp&8);
				iincr = Chroma_Width - 8;
			}
		}else{
			// field picture, one field in one pic
			rfp = current_frame[cc] + (Chroma_Width<<1)*(by+((comp&2)<<2)) + bx + (comp&8);
			iincr = (Chroma_Width<<1) - 8;
		}
	}
	iincr += 8;

	//DM02092003+
	int val, luma, pPos, r, g, b;

	//DM20082004 081.7 int10 changed
	if (cc == 0) //lumi
	{   
		for (int y = 0; y < 8; y++)
		{
			for (int x = 0; x < 8; x++)
			{
				pPos = rfp + x + (y * iincr);
				val = Block_Ptr[x + (y * 8)] + ((picture_coding_type == I_TYPE) ? 128 : 0);
				val = val < 0 ? 0 : (val > 255 ? 255 : val);

				pixels[pPos] |= val<<16; //Y
			}
		}
	}
	else
	{    //chroma cc1 = Cb, cc2=Cr
		if (chroma_format != CHROMA444)
		{
			rfp <<= 1;
			iincr <<= 1;
		}

		for (int y = 0; y < 16; y++)
		{
			for (int x = 0; x < 16; x++)
			{
				pPos = rfp + (x >>(chroma_format == CHROMA444 ? 1 : 0)) + ((y >>(chroma_format != CHROMA420 ? 1 : 0)) * iincr);
				val = 128 + Block_Ptr[(x >>1) + (8 * (chroma_format != CHROMA420 ? (y >>1) : ((y & 1) == 0 ? ((y >>1) & ~dct_type[0]) : ((y >>1) | dct_type[0]))))];
				val = val < 0 ? 0 : (val > 255 ? 255 : val);

				if (cc == 1) //U
					pixels[pPos] |= val<<8;

				else  //V
					pixels[pPos] |= val;

				if (chroma_format == CHROMA444)
					x++;
			}

			if (chroma_format != CHROMA420)
				y++;
		}
	}
}
//DM02092003-


/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */
public void macroblock_modes(int pmacroblock_type[], int pmotion_type[],
		 int pmotion_vector_count[], int pmv_format[],
		 int pdmv[], int pmvscale[], int pdct_type[]){

	int macroblock_type, motion_type=0, motion_vector_count;
	int mv_format, dmv, mvscale, dct_type;

	/* get macroblock_type */
	macroblock_type = Get_macroblock_type();

	if (Fault_Flag>0) return;

	/* get frame/field motion type */
	if ((macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD))>0) {
		if (picture_structure==FRAME_PICTURE)
			motion_type = (frame_pred_frame_dct>0) ? MC_FRAME : Get_Bits(2);
		else
			motion_type = Get_Bits(2);
	}else if ((macroblock_type & MACROBLOCK_INTRA)>0 && concealment_motion_vectors>0)
		motion_type = (picture_structure==FRAME_PICTURE) ? MC_FRAME : MC_FIELD;

	/* derive motion_vector_count, mv_format and dmv, (table 6-17, 6-18) */
	if (picture_structure==FRAME_PICTURE){
		motion_vector_count = (motion_type==MC_FIELD) ? 2 : 1;
		mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD;
	}else{
		motion_vector_count = (motion_type==MC_16X8) ? 2 : 1;
		mv_format = MV_FIELD;
	}
	
	dmv = (motion_type==MC_DMV)?1:0; /* dual prime */

	/*
	   field mv predictions in frame pictures have to be scaled
	   ISO/IEC 13818-2 section 7.6.3.1 Decoding the motion vectors
	*/
	mvscale = ((mv_format==MV_FIELD) && (picture_structure==FRAME_PICTURE)) ?1:0;

	/* get dct_type (frame DCT / field DCT) */
	dct_type = (picture_structure==FRAME_PICTURE) && (frame_pred_frame_dct<1)
		&& ((macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA))>0 ) 
			? Get_Bits(1) : 0;

	/* return values */
	pmacroblock_type[0] = macroblock_type;
	pmotion_type[0] = motion_type;
	pmotion_vector_count[0] = motion_vector_count;
	pmv_format[0] = mv_format;
	pdmv[0] = dmv;
	pmvscale[0] = mvscale;
	pdct_type[0] = dct_type;
}


	private int Get_macroblock_type()
	{
		int macroblock_type=0;

		switch (picture_coding_type)
		{
		case I_TYPE:
			macroblock_type = Get_I_macroblock_type();
			break;

		case P_TYPE:
			macroblock_type = Get_P_macroblock_type();
			break;

		case B_TYPE:
			macroblock_type = Get_B_macroblock_type();
			break;
		}

		return macroblock_type;
	}


	private int Get_I_macroblock_type()
	{
		if (Get_Bits(1) > 0)
			return 1;

		if (Get_Bits(1) < 1)
			Fault_Flag = 2;

		return 17;
	}


	private int Get_P_macroblock_type()
	{
		int code;

		if ((code = Show_Bits(6)) >= 8)
		{
			code >>= 3;
			Flush_Bits(PMBtab0[code][1]);

			return PMBtab0[code][0];
		}

		if (code == 0)
		{
			Fault_Flag = 2;

			return 0;
		}

		Flush_Bits(PMBtab1[code][1]);

		return PMBtab1[code][0];
	}


	private int Get_B_macroblock_type()
	{
		int code;

		if ((code = Show_Bits(6)) >= 8)
		{
			code >>= 2;
			Flush_Bits(BMBtab0[code][1]);

			return BMBtab0[code][0];
		}

		if (code == 0)
		{
			Fault_Flag = 2;

			return 0;
		}

		Flush_Bits(BMBtab1[code][1]);

		return BMBtab1[code][0];
	}


	private int Get_motion_code()
	{
		int code;

		if (Get_Bits(1) > 0)
			return 0;

		if ((code = Show_Bits(9)) >= 64)
		{
			code >>= 6;
			Flush_Bits(MVtab0[code][1]);

			return ((Get_Bits(1) > 0) ? -MVtab0[code][0] : MVtab0[code][0]);
		}

		if (code >= 24)
		{
			code >>= 3;
			Flush_Bits(MVtab1[code][1]);

			return ((Get_Bits(1) > 0) ? -MVtab1[code][0] : MVtab1[code][0]);
		}

		if ((code -= 12) < 0)
		{
			Fault_Flag = 10;

			return 0;
		}

		Flush_Bits(MVtab2[code][1]);

		return ((Get_Bits(1)>0) ? -MVtab2[code][0] : MVtab2[code][0]);
	}


	/**
	 * get differential motion vector (for dual prime prediction) 
	 */
	private int Get_dmvector()
	{
		if (Get_Bits(1) > 0)
			return ((Get_Bits(1) > 0) ? -1 : 1);

		else
			return 0;
	}


	/**
	 * performs YUV to RGB conversion
	 */
	private int YUVtoRGB(int YUV)
	{
		int T  = 0xFF;
		int Y  = 0xFF & YUV>>>16;
		int Cb = 0xFF & YUV>>>8;
		int Cr = 0xFF & YUV;

		if (Y == 0)
			return 0;

		int R = (int)((float)Y +1.402f * (Cr-128));
		int G = (int)((float)Y -0.34414 * (Cb-128) -0.71414 * (Cr-128));
		int B = (int)((float)Y +1.722 * (Cb-128));

		R = R < 0 ? 0 : (R > 0xFF ? 0xFF : R);
		G = G < 0 ? 0 : (G > 0xFF ? 0xFF : G);
		B = B < 0 ? 0 : (B > 0xFF ? 0xFF : B);

		return (T<<24 | R<<16 | G<<8 | B);
	}


	/**
	 * scales source picture to 2nd picture of memoryimagesource
	 * includes YUV to RGB conversion
	 */
	private void scale_Picture()
	{
		Arrays.fill(pixels2, 0xFF505050);

		int x_offset = ((aspect_ratio_information == 3 || aspect_ratio_information == 4) && profile_and_level_indication != 0) ? 0 : 64;
		int scanline = 512;
		int ny = 288;
		int nx = x_offset == 0 ? scanline : scanline - x_offset;
		float Y = 0, X = 0;
		float Ydecimate = vertical_size / (float)ny;
		float Xdecimate = horizontal_size / (float)(nx - x_offset);

		for (int y = 0; Y < vertical_size && y < ny; Y += Ydecimate, y++, X=0)
			for (int x = x_offset; X < horizontal_size && x < nx; X += Xdecimate, x++)
				pixels2[x + (y * scanline)] = YUVtoRGB(pixels[(int)X + ((int)Y * horizontal_size)]);


		//Arrays.fill(pixels2, 0xFF507090);

		//source.newPixels();
		Common.getGuiInterface().updatePreviewPixel();

		messageStreamInfo();

		/**
		 * expects pixels in YUV format for WSS recognition
		 */
		WSS.init(pixels, horizontal_size);
	}


	/**
	 * updates info field 1
	 */
	private void messageStreamInfo()
	{
		String prog[] = { "i", "p" };

		info_1 = horizontal_size + "*" + vertical_size;
		info_1 += prog[progressive_sequence] + " ";
		info_1 += aspect_ratio_string[aspect_ratio_information] + " ";
		info_1 += picture_coding_type_string[picture_coding_type];
		info_1 += "(" + temporal_reference + ")";
		info_1 += progressive_string[progressive_frame] + " ";
		info_1 += ", " + video_format_S[video_format] + " ";
		info_1 += ", " + (profile_and_level_indication==0 ? "MPEG1" : (1 & profile_and_level_indication>>>7) + "|" +
			prof[7 & profile_and_level_indication>>>4] + "@" + lev[15 & profile_and_level_indication]);
		info_1 += "(" + Coded_Picture_Width + "*" + Coded_Picture_Height + ") ";
		info_1 += info_4;
	}

	/**
	 * 
	 */
	public int[] getPixels()
	{
		return pixels;
	}

	/**
	 * 
	 */
	public int[] getPreviewPixel()
	{
		return pixels2;
	}

	/**
	 * 
	 */
	public void clearPreviewPixel()
	{
		info_1 = "";
		info_2 = "";

		Arrays.fill(pixels2, 0xFF505050);

		WSS.init(new int[0], 0);

		Common.getGuiInterface().updatePreviewPixel();
	}

	/**
	 * 
	 */
	public int getWidth()
	{
		return horizontal_size;
	}

	/**
	 * 
	 */
	public int getHeight()
	{
		return vertical_size;
	}

	/**
	 * 
	 */
	public int getAspectRatio()
	{
		return aspect_ratio_information;
	}

	/**
	 * 
	 */
	public String getInfo_1()
	{
		return info_1;
	}

	/**
	 * 
	 */
	public String getInfo_2()
	{
		return info_2;
	}

	/**
	 * 
	 */
	public String getWSSInfo()
	{
		return WSS.getWSS();
	}

	/**
	 * 
	 */
	public boolean getPalPlusInfo()
	{
		return WSS.isPalPlus();
	}

	/**
	 * 
	 */
	public String getWSSFormatInfo()
	{
		return WSS.getFormatInfo();
	}

	/**
	 * 
	 */
	public int getErrors()
	{
		return 0 | (ERROR1 ? 1 : 0) | (ERROR2 ? 2 : 0);
	}

	/**
	 * 
	 */
	private void repaint()
	{
		Common.getGuiInterface().repaintPicturePanel();
	}

	/**
	 * create new smaller cutimage pixel data
	 */
	public int[] getCutImage()
	{
		int new_height = 126;
		int new_width = 224;
		int source_height = 288;
		int source_width = 512;

		float Y = 0;
		float X = 0;
		float decimate_height = (float)source_height / new_height;
		float decimate_width = (float)source_width / new_width;

		int[] cut_image = new int[new_width * new_height];

		for (int y = 0; Y < source_height && y < new_height; Y += decimate_height, y++, X = 0)
			for (int x = 0; X < source_width && x < new_width; X += decimate_width, x++)
				cut_image[x + (y * new_width)] = pixels2[(int)X + ((int)Y * source_width)];

		return cut_image;
	}

	/**
	 * returns arrays byteposition offset of 1st successful decoded GOP
	 * interface, entry point to decode picture for preview
	 *
	 * @param1 - ES byte array
	 * @param2 - search direction
	 * @param3 - enable GOPheader alignment
	 * @param4 - simple_fast decode
	 * @return
	 */
	public long decodeArray(byte array[], boolean direction, boolean _viewGOP, boolean fast)
	{
		return decodeArray(array, 0, direction, _viewGOP, fast);
	}

	/**
	 * returns arrays byteposition offset of 1st successful decoded GOP
	 * interface, entry point to decode picture for preview
	 *
	 * @param1 - ES byte array
	 * @param2 - start index position
	 * @param3 - search direction
	 * @param4 - enable GOPheader alignment
	 * @param5 - simple_fast decode
	 * @return
	 */
	public long decodeArray(byte array[], int start_position, boolean direction, boolean _viewGOP, boolean fast)
	{
		FAST = fast;
		DIRECTION = direction;
		ERROR1 = false;
		ERROR2 = false;
		buf = array;
		BufferPos = start_position;
		BitPos = BufferPos<<3;
		StartPos = BufferPos;
		viewGOP = _viewGOP;

		if (DIRECTION)
		{
			StartPos = BufferPos = buf.length - 4;
			BitPos = BufferPos<<3;
		}

		try {

			while (BufferPos < buf.length && BufferPos >= 0)
			{
				ERROR_CODE1 = extern_Get_Hdr();

				if ( ERROR_CODE1 == 1 )
				{
					if (picture_coding_type != I_TYPE)
					{
						BufferPos += 2048;
						continue;
					}

					InitialDecoder();
					Decode_Picture();
					repaint();

					return StartPos;
				}

				else if (ERROR_CODE1 == 2 )
				{
					repaint();
					return 0;
				}

				else
					BufferPos++;
			}

			ERROR2 = true;

		} catch (ArrayIndexOutOfBoundsException ae) { 
			ERROR1 = true;

		} catch (Error ee) { 
			ERROR1 = true;
		}

		repaint();

		return 0;
	}

}