package uk.co.mmscomputing.device.twain;
import java.util.*;
public class TwainCapability implements TwainConstants{
// DAT_CAPABILITY. Used by application to get/set capability from/in a data source.
/*
typedef struct {
TW_UINT16 Cap; // id of capability to set or get, e.g. CAP_BRIGHTNESS
TW_UINT16 ConType; // TWON_ONEVALUE, _RANGE, _ENUMERATION or _ARRAY
TW_HANDLE hContainer; // Handle to container of type Dat
} TW_CAPABILITY, FAR * pTW_CAPABILITY;
*/
protected TwainSource source;
protected int cap;
protected byte[] buf=new byte[(jtwain.getPtrSize()==4)?8:12]; // TW_CAPABILITY 32 bit OS: 8 Bytes; 64 bit OS: 12 Bytes
protected TwainContainer container;
TwainCapability(TwainSource source,int cap)throws TwainIOException{
this.source=source;
this.cap=cap;
this.container=null;
container=get();
}
TwainCapability(TwainSource source,int cap,int mode)throws TwainIOException{
this.source=source;
this.cap=cap;
this.container=null;
switch(mode){
case MSG_GET: container=get(); break;
case MSG_GETCURRENT: container=getCurrent(); break;
case MSG_GETDEFAULT: container=getDefault(); break;
default: container=get(); break;
}
}
private TwainContainer get(int msg,int contype)throws TwainIOException{
jtwain.setINT16(buf,0,cap); // Cap : set capability we are looking for
jtwain.setINT16(buf,2,contype); // ConType : what container do we accept
// jtwain.setPtr(buf,4,0); // hContainer : source will set handle to container
source.call(DG_CONTROL,DAT_CAPABILITY,msg,buf); // [1] 7-145 pp state 4 - 7; get capability container
int containerType =jtwain.getINT16(buf,2); // get container type
// 10/01/09
// long containerPtr =jtwain.getPTR(buf,4); // ptr to native capability container
// byte[] container =jtwain.ngetContainer(containerType,containerPtr); // get java capability container, free native container
byte[] container =jtwain.ngetContainer(buf); // get java capability container, free native container
switch(containerType){ // As of TWAIN 1.9 spec these are the only container types possible
case TWON_ARRAY: return new TwainArray(cap,container);
case TWON_ENUMERATION: return new TwainEnumeration(cap,container);
case TWON_ONEVALUE: return new TwainOneValue(cap,container);
case TWON_RANGE: return new TwainRange(cap,container);
default: throw new TwainIOException(getClass().getName()+".get:\n\tUnknown container type.");
}
}
private TwainContainer get(int msg)throws TwainIOException{
return get(msg,-1); // ConType: accept any container type
}
public TwainContainer get()throws TwainIOException{
container= get(MSG_GET); // [1] 7-145 state 4 - 7; get capability container
return container;
}
public TwainContainer getCurrent()throws TwainIOException{
return get(MSG_GETCURRENT); // [1] 7-147 state 4 - 7; get current capability container
}
public TwainContainer getDefault()throws TwainIOException{
return get(MSG_GETDEFAULT); // [1] 7-149 state 4 - 7; get default capability container
}
public int querySupport()throws TwainIOException{ // what actions are allowed on this capability
return get(MSG_QUERYSUPPORT,TWON_ONEVALUE).intValue(); // [1] 7-151 state 4 - 7; TWTY_INT32 flags TWQC_GET, TWQC_SET ...
}
public boolean querySupport(int flagMask){
try{
int flags=get(MSG_QUERYSUPPORT,TWON_ONEVALUE).intValue();
return ((flags&flagMask)!=0);
}catch(TwainIOException tioe){ // if some error assume not supported
System.out.println("3\b"+getClass().getName()+".querySupport:\n\t"+tioe.getMessage());
return false;
}
}
public TwainContainer reset()throws TwainIOException{
container = get(MSG_RESET); // [1] 7-153 state 4; reset to twain or source default
return container;
}
public TwainContainer set()throws TwainIOException{
container = set(container);
return container;
}
private TwainContainer set(TwainContainer container)throws TwainIOException{ // use only in state 4
int containerType =container.getType();
byte[] containerBytes =container.getBytes();
// 10/01/09
// long containerHandle =jtwain.nsetContainer(containerType,containerBytes); // allocate native memory and copy container data into it.
try{
jtwain.setINT16(buf,0,cap); // set capability
jtwain.setINT16(buf,2,containerType); // set container type
// jtwain.setPTR(buf,4,containerHandle); // set native container
jtwain.nsetContainer(buf,containerBytes); // allocate native memory and copy container data into it.
/*
System.err.println("buf.length = "+buf.length);
System.err.println(TwainContainer.toString(buf));
System.err.println(container.toString());
System.err.println(TwainContainer.toString(containerBytes));
*/
source.call(DG_CONTROL,DAT_CAPABILITY,MSG_SET,buf);
}catch(TwainResultException.CheckStatus trecs){
container=get();
}finally{
jtwain.nfreeContainer(buf); // release native container memory again
}
return container;
}
public Object[] getItems(){ return container.getItems();}
public boolean booleanValue()throws TwainIOException{ return getCurrent().booleanValue();}
public int intValue() throws TwainIOException{ return getCurrent().intValue();}
public double doubleValue() throws TwainIOException{ return getCurrent().doubleValue();}
public void setCurrentValue(boolean v)throws TwainIOException{setCurrentValue(new Boolean(v));}
public void setCurrentValue(int v) throws TwainIOException{setCurrentValue(new Integer(v));}
public void setCurrentValue(double v) throws TwainIOException{setCurrentValue(new Double(v));}
public void setCurrentValue(Object val)throws TwainIOException{
container.setCurrentValue(val);set();
}
public boolean booleanDefaultValue()throws TwainIOException{ return getDefault().booleanDefaultValue();}
public int intDefaultValue() throws TwainIOException{ return getDefault().intDefaultValue();}
public double doubleDefaultValue() throws TwainIOException{ return getDefault().doubleDefaultValue();}
public void setDefaultValue(boolean v)throws TwainIOException{setDefaultValue(new Boolean(v));}
public void setDefaultValue(int v) throws TwainIOException{setDefaultValue(new Integer(v));}
public void setDefaultValue(double v) throws TwainIOException{setDefaultValue(new Double(v));}
public void setDefaultValue(Object val)throws TwainIOException{
container.setDefaultValue(val);set();
}
protected String toString(String[] strs){
String s=getClass().getName()+"\n";
Object[] items =container.getItems();
for(int i=0;i<items.length;i++){
int n=((Number)items[i]).intValue();
s+=strs[n]+"\n";
}
s+="\n"+container.toString();
return s;
}
public String getName(){
String name=getCapName(cap);
if(name==null){
return "Cap_0x"+Integer.toHexString(cap);
}
return name;
}
public String toString(){
String s=getClass().getName()+"\n";
s+="name = "+getName()+"\n";
s+=container.toString();
return s;
}
static public TwainCapability[] getCapabilities(TwainSource source)throws TwainIOException{
TwainCapability tc = source.getCapability(CAP_SUPPORTEDCAPS);
Object[] items = tc.getItems();
Vector<Object> caps = new Vector<Object>();
for(int i=0;i<items.length;i++){
int capid=((Number)items[i]).intValue();
try{
switch(capid){
case ICAP_COMPRESSION: caps.add(new Compression(source)); break; // 0x0100
case ICAP_XFERMECH: caps.add(new XferMech(source)); break; // 0x0103
case ICAP_IMAGEFILEFORMAT: caps.add(new ImageFileFormat(source)); break; // 0x110C
default: caps.add(new TwainCapability(source,capid)); break;
}
}catch(TwainFailureException.BadCap tfebc){ // Unknown capability
}catch(TwainFailureException.CapUnsupported tfecu){ // Capability not supported by source
}catch(TwainIOException tioe){
String name=getCapName(capid);
if(name==null){name="Cap_0x"+Integer.toHexString(capid)+"["+Integer.toString(capid)+"]";}
System.out.println("3\b\n"+name+"\n\t"+tioe.toString());
}
}
return (TwainCapability[])caps.toArray(new TwainCapability[0]);
}
//----- ICAP_COMPRESSION 0x0100 -----
static public class Compression extends TwainCapability{
Compression(TwainSource source) throws TwainIOException{
super(source,ICAP_COMPRESSION);
}
public String toString(){return toString(CompressionStrings);}
}
//----- ICAP_XFERMECH 0x0103 -----
static public class XferMech extends TwainCapability{
XferMech(TwainSource source) throws TwainIOException{
super(source,ICAP_XFERMECH);
}
public String toString(){return toString(XferMechStrings);}
public int intValue(){
try{
return super.intValue();
}catch(Exception e){ // Shouldn't happen must be supported by all sources.
System.err.println(getClass().getName()+".intValue:\n\t"+e);
return TWSX_NATIVE; // if some error assume source does native transfer
}
}
}
//----- ICAP_IMAGEFILEFORMAT 0x110C -----
static public class ImageFileFormat extends TwainCapability{
ImageFileFormat(TwainSource source) throws TwainIOException{
super(source,ICAP_IMAGEFILEFORMAT);
}
public String toString(){return toString(ImageFileFormatStrings);}
}
//----- -----
static private Hashtable<Integer,String> caps;
static public String getCapName(int i){
return (String)caps.get(new Integer(i));
}
static{
caps = new Hashtable<Integer,String>();
caps.put(new Integer(0x0001), "CAP_XFERCOUNT");
caps.put(new Integer(0x0100), "ICAP_COMPRESSION");
caps.put(new Integer(0x0101), "ICAP_PIXELTYPE");
caps.put(new Integer(0x0102), "ICAP_UNITS");
caps.put(new Integer(0x0103), "ICAP_XFERMECH");
caps.put(new Integer(0x1000), "CAP_AUTHOR");
caps.put(new Integer(0x1001), "CAP_CAPTION");
caps.put(new Integer(0x1002), "CAP_FEEDERENABLED");
caps.put(new Integer(0x1003), "CAP_FEEDERLOADED");
caps.put(new Integer(0x1004), "CAP_TIMEDATE");
caps.put(new Integer(0x1005), "CAP_SUPPORTEDCAPS");
caps.put(new Integer(0x1006), "CAP_EXTENDEDCAPS");
caps.put(new Integer(0x1007), "CAP_AUTOFEED");
caps.put(new Integer(0x1008), "CAP_CLEARPAGE");
caps.put(new Integer(0x1009), "CAP_FEEDPAGE");
caps.put(new Integer(0x100a), "CAP_REWINDPAGE");
caps.put(new Integer(0x100b), "CAP_INDICATORS");
caps.put(new Integer(0x100c), "CAP_SUPPORTEDCAPSEXT");
caps.put(new Integer(0x100d), "CAP_PAPERDETECTABLE");
caps.put(new Integer(0x100e), "CAP_UICONTROLLABLE");
caps.put(new Integer(0x100f), "CAP_DEVICEONLINE");
caps.put(new Integer(0x1010), "CAP_AUTOSCAN");
caps.put(new Integer(0x1011), "CAP_THUMBNAILSENABLED");
caps.put(new Integer(0x1012), "CAP_DUPLEX");
caps.put(new Integer(0x1013), "CAP_DUPLEXENABLED");
caps.put(new Integer(0x1014), "CAP_ENABLEDSUIONLY");
caps.put(new Integer(0x1015), "CAP_CUSTOMDSDATA");
caps.put(new Integer(0x1016), "CAP_ENDORSER");
caps.put(new Integer(0x1017), "CAP_JOBCONTROL");
caps.put(new Integer(0x1018), "CAP_ALARMS");
caps.put(new Integer(0x1019), "CAP_ALARMVOLUME");
caps.put(new Integer(0x101a), "CAP_AUTOMATICCAPTURE");
caps.put(new Integer(0x101b), "CAP_TIMEBEFOREFIRSTCAPTURE");
caps.put(new Integer(0x101c), "CAP_TIMEBETWEENCAPTURES");
caps.put(new Integer(0x101d), "CAP_CLEARBUFFERS");
caps.put(new Integer(0x101e), "CAP_MAXBATCHBUFFERS");
caps.put(new Integer(0x101f), "CAP_DEVICETIMEDATE");
caps.put(new Integer(0x1020), "CAP_POWERSUPPLY");
caps.put(new Integer(0x1021), "CAP_CAMERAPREVIEWUI");
caps.put(new Integer(0x1022), "CAP_DEVICEEVENT");
caps.put(new Integer(0x1023), "CAP_PAGEMULTIPLEACQUIRE");
caps.put(new Integer(0x1024), "CAP_SERIALNUMBER");
caps.put(new Integer(0x1025), "CAP_FILESYSTEM");
caps.put(new Integer(0x1026), "CAP_PRINTER");
caps.put(new Integer(0x1027), "CAP_PRINTERENABLED");
caps.put(new Integer(0x1028), "CAP_PRINTERINDEX");
caps.put(new Integer(0x1029), "CAP_PRINTERMODE");
caps.put(new Integer(0x102a), "CAP_PRINTERSTRING");
caps.put(new Integer(0x102b), "CAP_PRINTERSUFFIX");
caps.put(new Integer(0x102c), "CAP_LANGUAGE");
caps.put(new Integer(0x102d), "CAP_FEEDERALIGNMENT");
caps.put(new Integer(0x102e), "CAP_FEEDERORDER");
caps.put(new Integer(0x102f), "CAP_PAPERBINDING");
caps.put(new Integer(0x1030), "CAP_REACQUIREALLOWED");
caps.put(new Integer(0x1031), "CAP_PASSTHRU");
caps.put(new Integer(0x1032), "CAP_BATTERYMINUTES");
caps.put(new Integer(0x1033), "CAP_BATTERYPERCENTAGE");
caps.put(new Integer(0x1034), "CAP_POWERDOWNTIME");
caps.put(new Integer(0x1100), "ICAP_AUTOBRIGHT");
caps.put(new Integer(0x1101), "ICAP_BRIGHTNESS");
caps.put(new Integer(0x1103), "ICAP_CONTRAST");
caps.put(new Integer(0x1104), "ICAP_CUSTHALFTONE");
caps.put(new Integer(0x1105), "ICAP_EXPOSURETIME");
caps.put(new Integer(0x1106), "ICAP_FILTER");
caps.put(new Integer(0x1107), "ICAP_FLASHUSED");
caps.put(new Integer(0x1108), "ICAP_GAMMA");
caps.put(new Integer(0x1109), "ICAP_HALFTONES");
caps.put(new Integer(0x110a), "ICAP_HIGHLIGHT");
caps.put(new Integer(0x110c), "ICAP_IMAGEFILEFORMAT");
caps.put(new Integer(0x110d), "ICAP_LAMPSTATE");
caps.put(new Integer(0x110e), "ICAP_LIGHTSOURCE");
caps.put(new Integer(0x1110), "ICAP_ORIENTATION");
caps.put(new Integer(0x1111), "ICAP_PHYSICALWIDTH");
caps.put(new Integer(0x1112), "ICAP_PHYSICALHEIGHT");
caps.put(new Integer(0x1113), "ICAP_SHADOW");
caps.put(new Integer(0x1114), "ICAP_FRAMES");
caps.put(new Integer(0x1116), "ICAP_XNATIVERESOLUTION");
caps.put(new Integer(0x1117), "ICAP_YNATIVERESOLUTION");
caps.put(new Integer(0x1118), "ICAP_XRESOLUTION");
caps.put(new Integer(0x1119), "ICAP_YRESOLUTION");
caps.put(new Integer(0x111a), "ICAP_MAXFRAMES");
caps.put(new Integer(0x111b), "ICAP_TILES");
caps.put(new Integer(0x111c), "ICAP_BITORDER");
caps.put(new Integer(0x111d), "ICAP_CCITTKFACTOR");
caps.put(new Integer(0x111e), "ICAP_LIGHTPATH");
caps.put(new Integer(0x111f), "ICAP_PIXELFLAVOR");
caps.put(new Integer(0x1120), "ICAP_PLANARCHUNKY");
caps.put(new Integer(0x1121), "ICAP_ROTATION");
caps.put(new Integer(0x1122), "ICAP_SUPPORTEDSIZES");
caps.put(new Integer(0x1123), "ICAP_THRESHOLD");
caps.put(new Integer(0x1124), "ICAP_XSCALING");
caps.put(new Integer(0x1125), "ICAP_YSCALING");
caps.put(new Integer(0x1126), "ICAP_BITORDERCODES");
caps.put(new Integer(0x1127), "ICAP_PIXELFLAVORCODES");
caps.put(new Integer(0x1128), "ICAP_JPEGPIXELTYPE");
caps.put(new Integer(0x112a), "ICAP_TIMEFILL");
caps.put(new Integer(0x112b), "ICAP_BITDEPTH");
caps.put(new Integer(0x112c), "ICAP_BITDEPTHREDUCTION");
caps.put(new Integer(0x112d), "ICAP_UNDEFINEDIMAGESIZE");
caps.put(new Integer(0x112e), "ICAP_IMAGEDATASET");
caps.put(new Integer(0x112f), "ICAP_EXTIMAGEINFO");
caps.put(new Integer(0x1130), "ICAP_MINIMUMHEIGHT");
caps.put(new Integer(0x1131), "ICAP_MINIMUMWIDTH");
caps.put(new Integer(0x1134), "ICAP_AUTODISCARDBLANKPAGES");
caps.put(new Integer(0x1136), "ICAP_FLIPROTATION");
caps.put(new Integer(0x1137), "ICAP_BARCODEDETECTIONENABLED");
caps.put(new Integer(0x1138), "ICAP_SUPPORTEDBARCODETYPES");
caps.put(new Integer(0x1139), "ICAP_BARCODEMAXSEARCHPRIORITIES");
caps.put(new Integer(0x113a), "ICAP_BARCODESEARCHPRIORITIES");
caps.put(new Integer(0x113b), "ICAP_BARCODESEARCHMODE");
caps.put(new Integer(0x113c), "ICAP_BARCODEMAXRETRIES");
caps.put(new Integer(0x113d), "ICAP_BARCODETIMEOUT");
caps.put(new Integer(0x113e), "ICAP_ZOOMFACTOR");
caps.put(new Integer(0x113f), "ICAP_PATCHCODEDETECTIONENABLED");
caps.put(new Integer(0x1140), "ICAP_SUPPORTEDPATCHCODETYPES");
caps.put(new Integer(0x1141), "ICAP_PATCHCODEMAXSEARCHPRIORITIES");
caps.put(new Integer(0x1142), "ICAP_PATCHCODESEARCHPRIORITIES");
caps.put(new Integer(0x1143), "ICAP_PATCHCODESEARCHMODE");
caps.put(new Integer(0x1144), "ICAP_PATCHCODEMAXRETRIES");
caps.put(new Integer(0x1145), "ICAP_PATCHCODETIMEOUT");
caps.put(new Integer(0x1146), "ICAP_FLASHUSED2");
caps.put(new Integer(0x1147), "ICAP_IMAGEFILTER");
caps.put(new Integer(0x1148), "ICAP_NOISEFILTER");
caps.put(new Integer(0x1149), "ICAP_OVERSCAN");
caps.put(new Integer(0x1150), "ICAP_AUTOMATICBORDERDETECTION");
caps.put(new Integer(0x1151), "ICAP_AUTOMATICDESKEW");
caps.put(new Integer(0x1152), "ICAP_AUTOMATICROTATE");
}
}