All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgrasstools.gears.io.dxfdwg.libs.dwg.DwgUtil Maven / Gradle / Ivy

The newest version!
/*
 * JGrass - Free Open Source Java GIS http://www.jgrass.org 
 * (C) HydroloGIS - www.hydrologis.com 
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Library General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 * 
 * This library 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 Library General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Library General Public License
 * along with this library; if not, write to the Free Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.jgrasstools.gears.io.dxfdwg.libs.dwg;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Vector;

import org.jgrasstools.gears.io.dxfdwg.libs.dwg.utils.ByteUtils;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.utils.HexUtil;


/**
 * The DwgUtil class contains the essential set of functions for reading bitstreams
 * in DWG files
 * 
 * @author jmorell
 */
public final class DwgUtil {
    
	/**
	 * Read the extended data for a DWG object
	 * Don't use in this version. Serious bugs detected
	 * 
	 * @param data Array of unsigned bytes obtained from the DWG binary file
	 * @param offset The current bit offset where the value begins
	 * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
	 * 		   when we are looking for LwPolylines.
	 * @return Vector This vector has two parts. First is an int value that represents
	 * 		   the new offset, and second is the extended data of a DWG object 
	 */
	public static Vector readExtendedData(int[] data, int offset) throws Exception {
		int bitPos = offset;
		Vector extData = new Vector();
		while (true) {
			int newBitPos = ((Integer)getBitShort(data, bitPos).get(0)).intValue();
			int size = ((Integer)getBitShort(data, bitPos).get(1)).intValue();
			bitPos = newBitPos;
			if (size==0) {
				break;
			}
			newBitPos = ((Integer)((Vector)getHandle(data, bitPos)).get(0)).intValue();
			// TODO: Esto no es correcto. Repasar ...
			int handle = ((Integer)((Vector)getHandle(data, bitPos)).get(1)).intValue();
			bitPos = newBitPos;
			Vector eedata = new Vector();
			while (size>0) {
				newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
				int cb = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
				bitPos = newBitPos;
				size = size-1;
				if (cb==0x0) {
					newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
					int len = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
					bitPos = newBitPos;
					newBitPos = ((Integer)getRawShort(data, bitPos).get(0)).intValue();
					int cp = ((Integer)getRawShort(data, bitPos).get(1)).intValue();
					bitPos = newBitPos;
					Vector chars = new Vector();
					for (int i=0; i0) {
					fac = -1;
					bytee = bytee & 0xbf;
				}
			}
			bytes.add(new Integer(bytee & 0x7f));
		}
		if (bytes.size()==1) val = ((Integer)bytes.get(0)).intValue();
		else if (bytes.size()==2) val = ((Integer)bytes.get(0)).intValue() | (((Integer)bytes.get(1)).intValue() << 7);
		else if (bytes.size()==3) val = ((Integer)bytes.get(0)).intValue() | (((Integer)bytes.get(1)).intValue() << 7) | (((Integer)bytes.get(2)).intValue() << 14);
		else if (bytes.size()==4) val = ((Integer)bytes.get(0)).intValue() | (((Integer)bytes.get(1)).intValue() << 7) | (((Integer)bytes.get(2)).intValue() << 14) | (((Integer)bytes.get(3)).intValue() << 21);
		else System.out.println("Unexpected byte array length: " + bytes.size());
		Vector v = new Vector();
		v.add(new Integer(offsett));
		v.add(new Integer(fac*val));
		return v;
	}
	/**
	 * Read a String from a group of unsigned bytes
	 * 
	 * @param data Array of unsigned bytes obtained from the DWG binary file
	 * @param offset The current bit offset where the value begins
	 * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
	 * 		   when we are looking for LwPolylines.
	 * @return Vector This vector has two parts. First is an int value that represents
	 * 		   the new offset, and second is the String
	 */
	public static Vector getTextString(int[] data, int offset) throws Exception {
		int bitPos = offset;
	    int newBitPos = ((Integer)DwgUtil.getBitShort(data, bitPos).get(0)).intValue();
	    int len = ((Integer)DwgUtil.getBitShort(data, bitPos).get(1)).intValue();
	    bitPos = newBitPos;
	    int bitLen = len * 8;
	    Object cosa = DwgUtil.getBits(data, bitLen, bitPos);
	    String string;
	    if (cosa instanceof byte[]) {
		    string = new String((byte[])cosa);
	    } else {
	    	//string = ((Integer)cosa).toString();
	    	byte[] bytes = new byte[]{((Integer)cosa).byteValue()};
	    	string = new String((byte[])bytes);
	    }
	    bitPos = bitPos + bitLen;
	    Vector v = new Vector();
	    v.add(new Integer(bitPos));
	    v.add(string);
	    return v;
	}
	/**
	 * Read a int value (the handle of a DWG object) from a group of unsigned bytes
	 * 
	 * @param data Array of unsigned bytes obtained from the DWG binary file
	 * @param offset The current bit offset where the value begins
	 * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
	 * 		   when we are looking for LwPolylines.
	 * @return Vector This vector has two parts. First is an int value that represents
	 * 		   the new offset, and second is the int value (handle of a DWG object)
	 */
	public static Vector getHandle(int[] data, int offset) throws Exception {
		Vector v = new Vector();
		int code = ((Integer)DwgUtil.getBits(data, 4, offset)).intValue();
	    int counter = ((Integer)DwgUtil.getBits(data, 4, (offset + 4))).intValue();
	    int read = 8;
	    Vector hlist = new Vector();
	    if (counter>0) {
	        int hlen = counter * 8;
	        Object handle = DwgUtil.getBits(data, hlen, (offset + 8));
	        read = read + hlen;
	        if (hlen > 8) {
	        	byte[] handleBytes = (byte[])handle;
	        	int[] handleInts = new int[handleBytes.length];
	    		// Hacerlos unsigned ...
	    		for (int i=0; i0) {
			shorts.add(new Short(shortt));
			shortt = bb.getShort();
		}
		shorts.add(new Short(shortt));
		for (int i=0; i> 8) | ((shortt & 0xff) << 8)));
		}
		int slen = shorts.size();
		if (slen==1) {
			size = (((Integer)shorts.get(0)).intValue()) & 0x7fff;//(new Integer(((Integer)shorts.get(0)).shortValue() & 0x7fff)).byteValue();
		} else if (slen==2) {
			int tmp = ((Integer)shorts.get(0)).intValue();
			shorts.set(0, shorts.get(1));
			shorts.set(1, new Integer(tmp));
			size = (((((Integer)shorts.get(0)).intValue()) & 0x7fff) << 15) | (((((Integer)shorts.get(1)).intValue()) & 0x7fff));//(new Integer(((Integer)shorts.get(0)).shortValue() & 0x7fff)).byteValue();
		} else {
			System.out.println("Unexpected array length: " + slen);
		}
		return size;
	}
	/**
	 * Returns a set of bits from a group of unsigned bytes
	 * 
	 * @param data Array of unsigned bytes obtained from the DWG binary file
	 * @param count Bit counter
	 * @param offset The current bit offset where the value begins
	 * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
	 * 		   when we are looking for LwPolylines.
	 * @return This method returns an array of bytes or an int value
	 */
	public static Object getBits(int[] data, int count, int offset) throws Exception {
		int idx = offset/8;
		int bitidx = offset%8;
		/**
		 * mask1: bit mask to apply to the current byte
		 * lshift: left shift amount of mask results
		 * mask2: bit mask to apply to the next byte
		 * rshift: right shift amount of the mask results
		 */
		int[][] maskTable = new int[][]{
		    {0xff, 0, 0x00, 0}, // bit offset == 0
		    {0x7f, 1, 0x80, 7}, // bit offset == 1
		    {0x3f, 2, 0xc0, 6}, // bit offset == 2
		    {0x1f, 3, 0xe0, 5}, // bit offset == 3
		    {0x0f, 4, 0xf0, 4}, // bit offset == 4
		    {0x07, 5, 0xf8, 3}, // bit offset == 5
		    {0x03, 6, 0xfc, 2}, // bit offset == 6
		    {0x01, 7, 0xfe, 1}, // bit offset == 7
		};
		int mask1 = maskTable[bitidx][0];
		int lsh = maskTable[bitidx][1];
		int mask2 = maskTable[bitidx][2];
		int rsh = maskTable[bitidx][3];
		int binc = 8 - bitidx;
		int read = 0;
		int rem = count;
		int bytee = 0x0;
		Vector bytes = new Vector();
		while (read < count) {
			int b1 = 0;
			if (rem > binc) {
				b1 = (data[idx] & mask1);
				read = read + binc;
				rem = rem - binc;
			} else {
	            b1 = ((data[idx] & mask1) >> (8 - bitidx - rem));
	            bytee = b1;
				read = read + rem;
				rem = 0;
			}
			if (read < count) {
				idx = idx + 1;
				if (rem > bitidx) {
	                int b2 = (data[idx] & mask2);
	                bytee = (b1 << lsh) | (b2 >> rsh);
	                read = read + bitidx;
	                rem = rem - bitidx;
				} else {
	                int mask = maskTable[rem][2];
	                int b2 = data[idx] & mask;
	                bytee = (b1 << rem) | (b2 >> (8 - rem));
	                read = read + rem;
	                rem = 0;
				}
			}
			if (count > 8) {
				bytes.add(new Integer(bytee));
			}
		}
		if (bytes.size()>0) {
			byte[] newBytes = new byte[bytes.size()];
			for (int i=0; i 0) val = true;
		Vector v = new Vector();
		v.add(new Integer(offset+1));
		v.add(new Boolean(val));
		return v;
	}
	/**
	 * Convert bytes to machine value bytes
	 * 
	 * @param data Input of array of bytes
	 * @return int[] Output of array of machine bytes
	 */
	public static int[] bytesToMachineBytes(byte[] data) {
		String[] dataString = new String[data.length];
		int[] dataOut = new int[data.length];
		for (int i=0; i2) layerBytes[3] = (byte)((Integer)layerHandle.get(2)).intValue();
		if (layerHandle.size()>3) {
			layerBytes[3] = (byte)((Integer)layerHandle.get(3)).intValue();
			layerBytes[2] = (byte)((Integer)layerHandle.get(2)).intValue();
		}
		if (layerHandle.size()>4) {
			layerBytes[3] = (byte)((Integer)layerHandle.get(4)).intValue();
			layerBytes[2] = (byte)((Integer)layerHandle.get(3)).intValue();
			layerBytes[1] = (byte)((Integer)layerHandle.get(2)).intValue();
		}
		if (layerHandle.size()>5) {
			layerBytes[3] = (byte)((Integer)layerHandle.get(5)).intValue();
			layerBytes[2] = (byte)((Integer)layerHandle.get(4)).intValue();
			layerBytes[1] = (byte)((Integer)layerHandle.get(3)).intValue();
			layerBytes[0] = (byte)((Integer)layerHandle.get(2)).intValue();
		}
		int layer = ByteUtils.bytesToInt(layerBytes, new int[]{0});
		return layer;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy