/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.internal.image;


import org.eclipse.swt.*;

final class JPEGFrameHeader extends JPEGVariableSizeSegment {
	int maxVFactor;
	int maxHFactor;
	public int[] componentIdentifiers;
	public int[][] componentParameters;

	public JPEGFrameHeader(byte[] reference) {
		super(reference);
	}
	
	public JPEGFrameHeader(LEDataInputStream byteStream) {
		super(byteStream);
		initializeComponentParameters();
	}
	
	public int getSamplePrecision() {
		return reference[4] & 0xFF;
	}
	
	public int getNumberOfLines() {
		return (reference[5] & 0xFF) << 8 | (reference[6] & 0xFF);
	}
	
	public int getSamplesPerLine() {
		return (reference[7] & 0xFF) << 8 | (reference[8] & 0xFF);
	}
	
	public int getNumberOfImageComponents() {
		return reference[9] & 0xFF;
	}
	
	public void setSamplePrecision(int precision) {
		reference[4] = (byte)(precision & 0xFF);
	}
	
	public void setNumberOfLines(int anInteger) {
		reference[5] = (byte)((anInteger & 0xFF00) >> 8);
		reference[6] = (byte)(anInteger & 0xFF);
	}
	
	public void setSamplesPerLine(int samples) {
		reference[7] = (byte)((samples & 0xFF00) >> 8);
		reference[8] = (byte)(samples & 0xFF);
	}
	
	public void setNumberOfImageComponents(int anInteger) {
		reference[9] = (byte)(anInteger & 0xFF);
	}
	
	public int getMaxHFactor() {
		return maxHFactor;
	}
	
	public int getMaxVFactor() {
		return maxVFactor;
	}
	
	public void setMaxHFactor(int anInteger) {
		maxHFactor = anInteger;
	}
	
	public void setMaxVFactor(int anInteger) {
		maxVFactor = anInteger;
	}
	
	/* Used when decoding. */
	void initializeComponentParameters() {
		int nf = getNumberOfImageComponents();
		componentIdentifiers = new int[nf];
		int[][] compSpecParams = new int[0][];
		int hmax = 1;
		int vmax = 1;
		for (int i = 0; i < nf; i++) {
			int ofs = i * 3 + 10;
			int ci = reference[ofs] & 0xFF;
			componentIdentifiers[i] = ci;
			int hi = (reference[ofs + 1] & 0xFF) >> 4;
			int vi = reference[ofs + 1] & 0xF;
			int tqi = reference[ofs + 2] & 0xFF;
			if (hi > hmax) {
				hmax = hi;
			}
			if (vi > vmax) {
				vmax = vi;
			}
			int[] compParam = new int[5];
			compParam[0] = tqi;
			compParam[1] = hi;
			compParam[2] = vi;
			if (compSpecParams.length <= ci) {
				int[][] newParams = new int[ci + 1][];
				System.arraycopy(compSpecParams, 0, newParams, 0, compSpecParams.length);
				compSpecParams = newParams;
			}
			compSpecParams[ci] = compParam;
		}
		int x = getSamplesPerLine();
		int y = getNumberOfLines();
		int[] multiples = new int[] { 8, 16, 24, 32 };
		for (int i = 0; i < nf; i++) {
			int[] compParam = compSpecParams[componentIdentifiers[i]];
			int hi = compParam[1];
			int vi = compParam[2];
			int compWidth = (x * hi + hmax - 1) / hmax;
			int compHeight = (y * vi + vmax - 1) / vmax;
			int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]);
			int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]);
			compParam[3] = dsWidth;
			compParam[4] = dsHeight;
		}
		setMaxHFactor(hmax);
		setMaxVFactor(vmax);
		componentParameters = compSpecParams;
	}
	
	/* Used when encoding. */
	public void initializeContents() {
		int nf = getNumberOfImageComponents();
		if (nf == 0 || nf != componentParameters.length) {
			SWT.error(SWT.ERROR_INVALID_IMAGE);
		}
		int hmax = 0;
		int vmax = 0;
		int[][] compSpecParams = componentParameters;
		for (int i = 0; i < nf; i++) {
			int ofs = i * 3 + 10;
			int[] compParam = compSpecParams[componentIdentifiers[i]];
			int hi = compParam[1];
			int vi = compParam[2];
			if (hi * vi > 4) {
				SWT.error(SWT.ERROR_INVALID_IMAGE);
			}
			reference[ofs] = (byte)(i + 1);
			reference[ofs + 1] = (byte)(hi * 16 + vi);
			reference[ofs + 2] = (byte)(compParam[0]);
			if (hi > hmax) hmax = hi;
			if (vi > vmax) vmax = vi;
		}
		int x = getSamplesPerLine();
		int y = getNumberOfLines();
		int[] multiples = new int[] {8, 16, 24, 32};
		for (int i = 0; i < nf; i++) {
			int[] compParam = compSpecParams[componentIdentifiers[i]];
			int hi = compParam[1];
			int vi = compParam[2];
			int compWidth = (x * hi + hmax - 1) / hmax;
			int compHeight = (y * vi + vmax - 1) / vmax;
			int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]);
			int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]);
			compParam[3] = dsWidth;
			compParam[4] = dsHeight;
		}
		setMaxHFactor(hmax);
		setMaxVFactor(vmax);
	}
	
	int roundUpToMultiple(int anInteger, int mInteger) {
		int a = anInteger + mInteger - 1;
		return a - (a % mInteger);
	}
	
	/*
	 * Verify the information contained in the receiver is correct.
	 * Answer true if the header contains a valid marker. Otherwise,
	 * answer false. Valid Start Of Frame markers are:
	 *	SOF_0  - Baseline DCT, Huffman coding
	 *	SOF_1  - Extended sequential DCT, Huffman coding
	 *	SOF_2  - Progressive DCT, Huffman coding
	 *	SOF_3  - Lossless (sequential), Huffman coding
	 *	SOF_5  - Differential sequential, Huffman coding
	 *	SOF_6  - Differential progressive, Huffman coding
	 *	SOF_7  - Differential lossless, Huffman coding
	 *	SOF_9  - Extended sequential DCT, arithmetic coding
	 *	SOF_10 - Progressive DCT, arithmetic coding
	 *	SOF_11 - Lossless (sequential), arithmetic coding
	 *	SOF_13 - Differential sequential, arithmetic coding
	 *	SOF_14 - Differential progressive, arithmetic coding
	 *	SOF_15 - Differential lossless, arithmetic coding
	 */
	public boolean verify() {
		int marker = getSegmentMarker();
		return (marker >= JPEGFileFormat.SOF0 && marker <= JPEGFileFormat.SOF3) ||
			(marker >= JPEGFileFormat.SOF5 && marker <= JPEGFileFormat.SOF7) ||
			(marker >= JPEGFileFormat.SOF9 && marker <= JPEGFileFormat.SOF11) ||
			(marker >= JPEGFileFormat.SOF13 && marker <= JPEGFileFormat.SOF15);
	}

	public boolean isProgressive() {
		int marker = getSegmentMarker();
		return marker == JPEGFileFormat.SOF2
			|| marker == JPEGFileFormat.SOF6
			|| marker == JPEGFileFormat.SOF10
			|| marker == JPEGFileFormat.SOF14;
	}
	
	public boolean isArithmeticCoding() {
		return getSegmentMarker() >= JPEGFileFormat.SOF9;
	}
}
