/*******************************************************************************
 * DISCLAIMER: The sample code or utility or tool described herein
 *    is provided on an "as is" basis, without warranty of any kind.
 *    UIDAI does not warrant or guarantee the individual success
 *    developers may have in implementing the sample code on their
 *    environment. 
 *    
 *    UIDAI does not warrant, guarantee or make any representations
 *    of any kind with respect to the sample code and does not make
 *    any representations or warranties regarding the use, results
 *    of use, accuracy, timeliness or completeness of any data or
 *    information relating to the sample code. UIDAI disclaims all
 *    warranties, express or implied, and in particular, disclaims
 *    all warranties of merchantability, fitness for a particular
 *    purpose, and warranties related to the code, or any service
 *    or software related thereto. 
 *    
 *    UIDAI is not responsible for and shall not be liable directly
 *    or indirectly for any direct, indirect damages or costs of any
 *    type arising out of use or any action taken by you or others
 *    related to the sample code.
 *    
 *    THIS IS NOT A SUPPORTED SOFTWARE.
 ******************************************************************************/

package in.gov.uidai.tools;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentSampleModel;
import java.awt.image.DataBuffer;
import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import com.sun.media.imageio.stream.RawImageInputStream;

/**
 * 
 * @author Anujit
 * 
 */

public class ISORawToBMPImageConverter {

	private int STRIP_LEN = 46;

	public void showImage(byte[] bytes, JLabel lbl) throws IOException {
		int width = 0;
		int height = 0;
		byte[] dest = null;

		try {
			dest = new byte[bytes.length - STRIP_LEN];
			System.arraycopy(bytes, STRIP_LEN, dest, 0, (bytes.length - STRIP_LEN));

			if (checkISO(bytes)) {
				width = getWidth(bytes);
				height = getHeigth(bytes);
			}

			if (width > 0 && height > 0) {
				ByteArrayInputStream bin = new ByteArrayInputStream(dest);
				ImageInputStream imIs = ImageIO.createImageInputStream(bin);
				int[] bandOffets = { 0 };
				ComponentSampleModel imgSampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, 1, width, bandOffets);
				Dimension[] imageDimensions = { new Dimension(width, height) };
				long[] ofs = { 0L };
				RawImageInputStream ris = new RawImageInputStream(imIs, imgSampleModel, ofs, imageDimensions);
				BufferedImage image = ImageIO.read(ris);
				lbl.setIcon(new ImageIcon(image.getScaledInstance(lbl.getWidth(), lbl.getHeight(), java.awt.Image.SCALE_DEFAULT)));
			}
		} catch (Exception e) {
		}
	}

	private boolean checkISO(byte[] bytes) {
		boolean isISO = true;
		try {
			StringBuffer str = new StringBuffer();
			str.append(bytesToHex(new byte[] { bytes[0] }));
			str.append(" ");
			str.append(bytesToHex(new byte[] { bytes[1] }));
			str.append(" ");
			str.append(bytesToHex(new byte[] { bytes[2] }));
			str.append(" ");
			str.append(bytesToHex(new byte[] { bytes[3] }));
			if (!str.toString().trim().equalsIgnoreCase("46 49 52 00")) {
				isISO = false;
			}
			str = null;

			if (!bytesToHex(new byte[] { bytes[29] }).toString().trim().equalsIgnoreCase("00")) {
				isISO = false;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return isISO;
	}

	private int getWidth(byte[] bytes) {
		int width = 0;
		try {
			width = Integer.parseInt(String.valueOf(bytesToHex(new byte[] { bytes[41] })) + String.valueOf(bytesToHex(new byte[] { bytes[42] })), 16);
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return width;
	}

	private int getHeigth(byte[] bytes) {
		int heigth = 0;
		try {
			heigth = Integer.parseInt(String.valueOf(bytesToHex(new byte[] { bytes[43] })) + String.valueOf(bytesToHex(new byte[] { bytes[44] })), 16);
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return heigth;
	}

	private String bytesToHex(byte[] b) {
		return bytesToHex(b, 0, b.length);
	}

	private String bytesToHex(byte[] b, int index, int length) {
		StringBuffer buf = new StringBuffer();
		byte leading, trailing;
		for (int pos = index; pos >= 0 && pos < index + length && pos < b.length; ++pos) {
			leading = (byte) ((b[pos] >>> 4) & 0x0f);
			trailing = (byte) (b[pos] & 0x0f);
			buf.append((0 <= leading) && (leading <= 9) ? (char) ('0' + leading) : (char) ('A' + (leading - 10)));
			buf.append((0 <= trailing) && (trailing <= 9) ? (char) ('0' + trailing) : (char) ('A' + (trailing - 10)));
		}
		return buf.toString();
	}
}
