/*
* 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.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.util.Vector;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgArc;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgAttdef;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgAttrib;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgBlock;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgBlockControl;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgBlockHeader;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgCircle;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgEllipse;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgEndblk;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgInsert;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgLayer;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgLayerControl;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgLine;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgLinearDimension;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgLwPolyline;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgMText;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgPoint;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgPolyline2D;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgPolyline3D;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgSeqend;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgSolid;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgSpline;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgText;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgVertex2D;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.objects.DwgVertex3D;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.utils.ByteUtils;
import org.jgrasstools.gears.io.dxfdwg.libs.dwg.utils.HexUtil;
/**
* The DwgFileV15Reader reads the DWG version 15 format
*
* @author jmorell
*/
public class DwgFileV15Reader extends DwgFileReader {
private DwgFile dwgFile;
/**
* Reads the DWG version 15 format
*
* @param dwgFile Represents the DWG file that we want to read
* @throws IOException When DWG file path is wrong
*/
public void read(DwgFile dwgFile) throws IOException {
System.out.println("DwgFileV15Reader.read() executed ...");
this.dwgFile = dwgFile;
File f = new File(dwgFile.getFileName());
FileInputStream fis = new FileInputStream(f);
FileChannel fc = fis.getChannel();
long s = fc.size();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, s);
readDwgSectionOffsets(bb);
try {
readDwgObjectOffsets(bb);
//readDwgClasses(bb);
} catch (Exception e) {
System.out.println("Error leyendo offsets y classes. Posible corrupci�n en" +
"el DWG file ...");
}
long t1 = System.currentTimeMillis();
readDwgObjects(bb);
long t2 = System.currentTimeMillis();
System.out.println("Tiempo empleado por readDwgObjects() = " + (t2-t1));
}
private void readDwgSectionOffsets(ByteBuffer bb) {
bb.position(19);
bb.order(ByteOrder.LITTLE_ENDIAN);
short codePage = bb.getShort();
int count = bb.getInt();
for (int i=0; i<count; i++) {
byte rec = bb.get();
int seek = bb.getInt();
int size = bb.getInt();
if (rec==0) {
dwgFile.addDwgSectionOffset("HEADERS", seek, size);
} else if (rec==1) {
dwgFile.addDwgSectionOffset("CLASSES", seek, size);
} else if (rec==2) {
dwgFile.addDwgSectionOffset("OBJECTS", seek, size);
} else if (rec==3) {
dwgFile.addDwgSectionOffset("UNKNOWN", seek, size);
} else if (rec==4) {
dwgFile.addDwgSectionOffset("R14DATA", seek, size);
} else if (rec==5) {
dwgFile.addDwgSectionOffset("R14REC5", seek, size);
} else {
System.out.println("ERROR: C�digo de n�mero de registro no soportado: " + rec);
}
}
}
private void readDwgObjectOffsets(ByteBuffer bb) throws Exception {
int offset = dwgFile.getDwgSectionOffset("OBJECTS");
bb.position(offset);
while (true) {
bb.order(ByteOrder.BIG_ENDIAN);
short size = bb.getShort();
if (size==2) break;
bb.order(ByteOrder.LITTLE_ENDIAN);
byte[] dataBytes = new byte[size];
for (int i=0; i<dataBytes.length; i++) {
dataBytes[i] = bb.get();
}
int[] data = DwgUtil.bytesToMachineBytes(dataBytes);
int lastHandle=0;
int lastLoc=0;
int bitPos=0;
int bitMax=(size-2)*8;
while (bitPos<bitMax) {
Vector v = DwgUtil.getModularChar(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
lastHandle = lastHandle + ((Integer)v.get(1)).intValue();
v = DwgUtil.getModularChar(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
lastLoc = lastLoc + ((Integer)v.get(1)).intValue();
dwgFile.addDwgObjectOffset(lastHandle, lastLoc);
}
}
}
private void readDwgClasses(ByteBuffer bb) throws Exception {
int offset = dwgFile.getDwgSectionOffset("CLASSES");
// Por ahora nos saltamos los 16 bytes de control
bb.position(offset+16);
bb.order(ByteOrder.LITTLE_ENDIAN);
int size = bb.getInt();
byte[] dataBytes = new byte[size];
for (int i=0; i<dataBytes.length; i++) {
dataBytes[i] = bb.get();
}
int[] data = DwgUtil.bytesToMachineBytes(dataBytes);
for (int i=0; i<data.length; i++) {
data[i] = (byte)ByteUtils.getUnsigned((byte)data[i]);
}
bb.position(bb.position()+2+16);
int maxbit = size * 8;
int bitPos = 0;
while ((bitPos+8) < maxbit) {
Vector v = DwgUtil.getBitShort(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
v = DwgUtil.getBitShort(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
v = DwgUtil.getTextString(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
v = DwgUtil.getTextString(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
v = DwgUtil.getTextString(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
v = DwgUtil.testBit(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
v = DwgUtil.getBitShort(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
}
}
private void readDwgObjects(ByteBuffer bb) {
//System.out.println("DwgFileV15Reader.readDwgObjects() executed ...");
for (int i=0; i<dwgFile.getDwgObjectOffsets().size(); i++) {
DwgObjectOffset doo = (DwgObjectOffset)dwgFile.getDwgObjectOffsets().get(i);
DwgObject obj = readDwgObject(bb, doo.getOffset());
if (obj!=null) {
dwgFile.addDwgObject(obj);
}
}
}
private DwgObject readDwgObject(ByteBuffer bb, int offset) {
try {
bb.position(offset);
int size = DwgUtil.getModularShort(bb);
bb.order(ByteOrder.LITTLE_ENDIAN);
byte[] dataBytes = new byte[size];
String[] dataMachValString = new String[size];
int[] data = new int[size];
// fromfile de python devuelve los bytes en valores nativos de la m�quina ...
for (int i=0; i<size; i++) {
dataBytes[i] = bb.get();
dataMachValString[i] = HexUtil.bytesToHex(new byte[]{dataBytes[i]});
Integer dataMachValShort = Integer.decode("0x" + dataMachValString[i]);
data[i] = dataMachValShort.byteValue();
// Hacerlos unsigned ...
data[i] = ByteUtils.getUnsigned((byte)data[i]);
}
int bitPos = 0;
Vector v = DwgUtil.getBitShort(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
int type = ((Integer)v.get(1)).intValue();
//System.out.println("type = " + type);
DwgObject obj = new DwgObject();
if (type==0x11) {
obj = new DwgArc();
obj.setGraphicsFlag(true);
} else if (type==0x12) {
obj = new DwgCircle();
obj.setGraphicsFlag(true);
} else if (type==0x13) {
obj = new DwgLine();
obj.setGraphicsFlag(true);
} else if (type==0x1B) {
obj = new DwgPoint();
obj.setGraphicsFlag(true);
} else if (type==0x0F) {
obj = new DwgPolyline2D();
obj.setGraphicsFlag(true);
} else if (type==0x10) {
obj = new DwgPolyline3D();
obj.setGraphicsFlag(true);
} else if (type==0x0A) {
obj = new DwgVertex2D();
obj.setGraphicsFlag(true);
} else if (type==0x0B) {
obj = new DwgVertex3D();
obj.setGraphicsFlag(true);
} else if (type==0x6) {
obj = new DwgSeqend();
obj.setGraphicsFlag(true);
} else if (type==0x1) {
obj = new DwgText();
obj.setGraphicsFlag(true);
} else if (type==0x2) {
obj = new DwgAttrib();
obj.setGraphicsFlag(true);
} else if (type==0x3) {
obj = new DwgAttdef();
obj.setGraphicsFlag(true);
} else if (type==0x4) {
obj = new DwgBlock();
//System.out.println("Creando objeto tipo DwgBlock");
obj.setGraphicsFlag(true);
} else if (type==0x5) {
obj = new DwgEndblk();
obj.setGraphicsFlag(true);
} else if (type==0x30) {
obj = new DwgBlockControl();
obj.setGraphicsFlag(false);
} else if (type==0x31) {
obj = new DwgBlockHeader();
//System.out.println("Creando objeto tipo DwgBlockHeader");
obj.setGraphicsFlag(false);
} else if (type==0x32) {
obj = new DwgLayerControl();
obj.setGraphicsFlag(false);
} else if (type==0x33) {
obj = new DwgLayer();
obj.setGraphicsFlag(false);
} else if (type==0x7) {
obj = new DwgInsert();
//System.out.println("Creando objeto tipo DwgInsert");
obj.setGraphicsFlag(true);
} else if (type==0x2C) {
obj = new DwgMText();
obj.setGraphicsFlag(true);
} else if (type==0x1F) {
obj = new DwgSolid();
obj.setGraphicsFlag(true);
} else if (type==0x23) {
obj = new DwgEllipse();
obj.setGraphicsFlag(true);
} else if (type==0x24) {
obj = new DwgSpline();
obj.setGraphicsFlag(true);
} else if (type==0x15) {
obj = new DwgLinearDimension();
obj.setGraphicsFlag(true);
} else if (type==0x4D) {
obj = new DwgLwPolyline();
//System.out.println("Creando objeto tipo DwgLwPolyline");
obj.setGraphicsFlag(true);
} else if (type==0x4E) {
obj = new DwgLwPolyline();
obj.setGraphicsFlag(true);
} else if (type==0x4F) {
obj = new DwgLwPolyline();
obj.setGraphicsFlag(true);
} else if (type==0x50) {
obj = new DwgLwPolyline();
obj.setGraphicsFlag(true);
} else if (type==0x51) {
obj = new DwgLwPolyline();
obj.setGraphicsFlag(true);
} else if (type==0x52) {
obj = new DwgLwPolyline();
obj.setGraphicsFlag(true);
} else if (type==0x53) {
obj = new DwgLwPolyline();
obj.setGraphicsFlag(true);
} else {
}
obj.setType(type);
v = DwgUtil.getRawLong(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
int objBSize = ((Integer)v.get(1)).intValue();
obj.setSizeInBits(objBSize);
Vector entityHandle = new Vector();
v = DwgUtil.getHandle(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
for (int i=1;i<v.size();i++) {
entityHandle.add(v.get(i));
}
obj.setHandle(DwgUtil.handleBinToHandleInt(entityHandle));
v = DwgUtil.readExtendedData(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
Vector extData = (Vector)v.get(1);
obj.setExtendedData(extData);
boolean gflag = false;
gflag = obj.isGraphicsFlag();
if (gflag) {
v = DwgUtil.testBit(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
boolean val = ((Boolean)v.get(1)).booleanValue();
if (val) {
v = DwgUtil.getRawLong(data, bitPos);
bitPos = ((Integer)v.get(0)).intValue();
size = ((Integer)v.get(1)).intValue();
int bgSize = size*8;
Integer giData = (Integer)DwgUtil.getBits(data, bgSize, bitPos);
obj.setGraphicData(giData.intValue());
bitPos = bitPos + bgSize;
}
}
readSpecificObject(obj, data, bitPos);
return obj;
} catch (Exception e) {
System.out.println("Exception capturada. Probablemente se ha encontrado un" +
"objeto con type non fixed");
//e.printStackTrace();
return null;
}
}
private void readSpecificObject(DwgObject obj, int[] data, int bitPos) throws Exception {
if (obj.getType()==0x11) {
((DwgArc)obj).readDwgArcV15(data, bitPos);
} else if (obj.getType()==0x12) {
((DwgCircle)obj).readDwgCircleV15(data, bitPos);
} else if (obj.getType()==0x13) {
((DwgLine)obj).readDwgLineV15(data, bitPos);
} else if (obj.getType()==0x1B) {
((DwgPoint)obj).readDwgPointV15(data, bitPos);
} else if (obj.getType()==0x0F) {
((DwgPolyline2D)obj).readDwgPolyline2DV15(data, bitPos);
} else if (obj.getType()==0x10) {
((DwgPolyline3D)obj).readDwgPolyline3DV15(data, bitPos);
} else if (obj.getType()==0x0A) {
((DwgVertex2D)obj).readDwgVertex2DV15(data, bitPos);
} else if (obj.getType()==0x0B) {
((DwgVertex3D)obj).readDwgVertex3DV15(data, bitPos);
} else if (obj.getType()==0x6) {
((DwgSeqend)obj).readDwgSeqendV15(data, bitPos);
} else if (obj.getType()==0x1) {
((DwgText)obj).readDwgTextV15(data, bitPos);
} else if (obj.getType()==0x2) {
((DwgAttrib)obj).readDwgAttribV15(data, bitPos);
} else if (obj.getType()==0x3) {
((DwgAttdef)obj).readDwgAttdefV15(data, bitPos);
} else if (obj.getType()==0x4) {
((DwgBlock)obj).readDwgBlockV15(data, bitPos);
} else if (obj.getType()==0x5) {
((DwgEndblk)obj).readDwgEndblkV15(data, bitPos);
} else if (obj.getType()==0x30) {
((DwgBlockControl)obj).readDwgBlockControlV15(data, bitPos);
} else if (obj.getType()==0x31) {
((DwgBlockHeader)obj).readDwgBlockHeaderV15(data, bitPos);
} else if (obj.getType()==0x32) {
((DwgLayerControl)obj).readDwgLayerControlV15(data, bitPos);
} else if (obj.getType()==0x33) {
((DwgLayer)obj).readDwgLayerV15(data, bitPos);
} else if (obj.getType()==0x7) {
((DwgInsert)obj).readDwgInsertV15(data, bitPos);
} else if (obj.getType()==0x2C) {
((DwgMText)obj).readDwgMTextV15(data, bitPos);
} else if (obj.getType()==0x1F) {
((DwgSolid)obj).readDwgSolidV15(data, bitPos);
} else if (obj.getType()==0x23) {
((DwgEllipse)obj).readDwgEllipseV15(data, bitPos);
} else if (obj.getType()==0x24) {
((DwgSpline)obj).readDwgSplineV15(data, bitPos);
} else if (obj.getType()==0x14) {
//System.out.println("... detectado un dim del tipo 0x14 ...");
} else if (obj.getType()==0x15) {
//System.out.println("... detectado un dim del tipo 0x15 ...");
//((DwgLinearDimension)obj).readDwgLinearDimensionV15(data, bitPos);
} else if (obj.getType()==0x16) {
//System.out.println("... detectado un dim del tipo 0x16 ...");
} else if (obj.getType()==0x17) {
//System.out.println("... detectado un dim del tipo 0x17 ...");
} else if (obj.getType()==0x18) {
//System.out.println("... detectado un dim del tipo 0x18 ...");
} else if (obj.getType()==0x19) {
//System.out.println("... detectado un dim del tipo 0x19 ...");
} else if (obj.getType()==0x1A) {
//System.out.println("... detectado un dim del tipo 0x1A ...");
} else if (obj.getType()==0x4D) {
((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
} else if (obj.getType()==0x4E) {
((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
} else if (obj.getType()==0x4F) {
((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
} else if (obj.getType()==0x50) {
((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
} else if (obj.getType()==0x51) {
((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
} else if (obj.getType()==0x52) {
((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
} else if (obj.getType()==0x53) {
((DwgLwPolyline)obj).readDwgLwPolylineV15(data, bitPos);
} else {
//System.out.println("Tipo de objeto pendiente de implementaci�n");
}
}
}