/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
*/
package petascope.wcst.transaction.tools;
//~--- non-JDK imports --------------------------------------------------------
import org.odmg.DBag;
import org.odmg.Database;
import org.odmg.Implementation;
import org.odmg.ODMGException;
import org.odmg.OQLQuery;
import org.odmg.Transaction;
import rasj.RasGMArray;
import rasj.RasImplementation;
import rasj.RasMInterval;
import rasj.RasResultIsNoIntervalException;
import petascope.wcs.server.exceptions.WCSException;
//~--- JDK imports ------------------------------------------------------------
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.io.ByteArrayInputStream;
import java.util.Iterator;
import org.odmg.QueryException;
import petascope.wcs.server.exceptions.InternalComponentException;
/**
* Utility class for doing various tasks that involve the Rasdaman server.
*
* @author Andrei Aiordachioaie
*/
public class RasdamanUtils {
Implementation myApp = null;
Database myDb = null;
Transaction myTa = null;
private String base;
private String server;
/**
* Simple constructor
*
* @param s server string
* @param b database name
*/
public RasdamanUtils(String s, String b) {
this.server = s;
this.base = b;
}
public void log(String msg) {
System.err.flush();
System.out.println("Rasdaman Utils: " + msg);
System.out.flush();
}
/**
* Opens a new connection to the Rasdaman server, and starts a new transaction.
* @throws WCSException on connection error
*/
public void init() throws WCSException {
try {
if (myApp == null) {
myApp = new RasImplementation(server);
}
if (myDb == null) {
myDb = myApp.newDatabase();
log("Opening database...");
myDb.open(base, Database.OPEN_READ_WRITE);
}
if (myTa == null) {
log("Beginning new transaction ...");
myTa = myApp.newTransaction();
myTa.begin();
}
} catch (ODMGException e) {
throw new InternalComponentException("Could not connect to the Rasdaman server !", e);
}
}
public void commitAndClose() throws ODMGException {
if (myTa != null) {
log("Commiting transaction ...");
myTa.commit();
myTa = null;
}
if (myDb != null) {
log("Closing database...");
myDb.close();
myDb = null;
}
log("Finished !");
}
public void abortAndClose() throws ODMGException {
if (myTa != null) {
log("Aborting transaction...");
myTa.abort();
myTa = null;
}
if (myDb != null) {
log("Closing database...");
myDb.close();
myDb = null;
}
log("Finished !");
}
public BufferedImage loadCoverage(String name) throws Exception {
init();
log("Running Load Coverage " + name + " query!");
OQLQuery myQu = myApp.newOQLQuery();
myQu.create("select jpeg(" + name + ") from " + name);
DBag resultSet = (DBag) myQu.execute();
if (resultSet != null) {
log("Query successful !");
Iterator iter = resultSet.iterator();
if (iter.hasNext()) {
RasGMArray result = (RasGMArray) iter.next();
byte[] ba = result.getArray();
ByteArrayInputStream bas = new ByteArrayInputStream(ba);
com.sun.image.codec.jpeg.JPEGImageDecoder decoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGDecoder(bas);
BufferedImage bufImg = null;
try {
bufImg = decoder.decodeAsBufferedImage();
} catch (Exception e) {
System.err.println("Error decoding the image !!!");
}
commitAndClose();
return bufImg;
}
}
abortAndClose();
return null;
}
public RasGMArray createMDD() throws RasResultIsNoIntervalException {
// create 2-D MDD with cell length 1, i.e., type “byte”:
RasGMArray myMDD = new RasGMArray(new RasMInterval("[1:400,1:400]"), 1);
// byte container for array data, matching in size:
byte[] mydata = new byte[160000];
// initialize array as grid of gray and black stripes:
for (int y = 0; y < 400; y++) {
for (int x = 0; x < 400; x++) {
mydata[y * 399 + x] = (byte) ((y % 4) > 1
? 80
: 0);
}
}
// now insert byte array into MDD object
// (sets only the pointer, no copying takes place!):
myMDD.setArray(mydata);
return myMDD;
}
public void insertGrayImageAsArray(String name) throws ODMGException {
try {
init();
log("Creating grey image ...");
RasGMArray myMDD = createMDD();
// set up query object for collection creation:
OQLQuery myQu = myApp.newOQLQuery();
myQu.create("create collection " + name + " GreySet");
// set the object type name (used for server type checking):
myMDD.setObjectTypeName("GreyImage");
// finally, execute “create collection” statement:
log("Creating collection '" + name + "'");
myQu.execute();
// now create the insert statement:
myQu.create("insert into " + name + " values $1");
// let the server generate a new OID for the object to be
// inserted, and remember this OID locally:
String myNewOID = myApp.getObjectId(myMDD);
// bind the MDD value which substitutes formal parameter $1:
myQu.bind(myMDD);
// …and ship the complete statement to the server:
log("Inserting data into the collection");
myQu.execute();
log("Done !");
commitAndClose();
} catch (Exception e) {
e.printStackTrace();
abortAndClose();
}
}
public void updateGrayImageWithArray(String name, BufferedImage img, int x1, int y1, int x2,
int y2) {
try {
log("Building query for updating gray image ...");
RasGMArray myMDD = createMddFromImage(img);
myMDD.setObjectTypeName("GreyImage");
// set up query object for collection creation:
OQLQuery myQu = myApp.newOQLQuery();
// Where to insert new image
String interval = String.valueOf(x1) + ":" + String.valueOf(x2) + ","
+ String.valueOf(y1) + ":" + String.valueOf(y2);
// Size of new image
String interval2 = String.valueOf(0) + ":" + String.valueOf(x2 - x1) + ","
+ String.valueOf(0) + ":" + String.valueOf(y2 - y1);
myQu.create("update " + name + " AS c SET c[" + interval + "] "
+ "assign maaray x in [" + interval2 + "] values $1");
// let the server generate a new OID for the object to be
// inserted, and remember this OID locally:
String myNewOID = myApp.getObjectId(myMDD);
// bind the MDD value which substitutes formal parameter $1:
myQu.bind(myMDD);
// …and ship the complete statement to the server:
log("Updating image ...");
myQu.execute();
log("Done !");
} catch (Exception e) {
e.printStackTrace();
}
}
public void insertGrayImageAsArray(String name, BufferedImage img) throws ODMGException, InternalComponentException {
log("Creating grey image ...");
RasGMArray myMDD = createMddFromImage(img);
// set up query object for collection creation:
OQLQuery myQu = myApp.newOQLQuery();
myQu.create("create collection " + name + " GreySet");
// set the object type name (used for server type checking):
myMDD.setObjectTypeName("GreyImage");
// finally, execute “create collection” statement:
log("Creating collection '" + name + "'");
myQu.execute();
// now create the insert statement:
myQu.create("insert into " + name + " values $1");
// let the server generate a new OID for the object to be
// inserted, and remember this OID locally:
String myNewOID = myApp.getObjectId(myMDD);
// bind the MDD value which substitutes formal parameter $1:
myQu.bind(myMDD);
// …and ship the complete statement to the server:
log("Inserting data into the collection");
myQu.execute();
log("Done !");
}
public void insertColorImageAsArray(String name, BufferedImage img) throws ODMGException {
try {
log("Creating grey image ...");
RasGMArray myMDD = createMddFromImage(img);
// set up query object for collection creation:
OQLQuery myQu = myApp.newOQLQuery();
myQu.create("create collection " + name + " RGBSet");
// set the object type name (used for server type checking):
myMDD.setObjectTypeName("RGBImage");
// finally, execute “create collection” statement:
log("Creating collection '" + name + "'");
myQu.execute();
// now create the insert statement:
myQu.create("insert into " + name + " values $1");
// let the server generate a new OID for the object to be
// inserted, and remember this OID locally:
String myNewOID = myApp.getObjectId(myMDD);
// bind the MDD value which substitutes formal parameter $1:
myQu.bind(myMDD);
// …and ship the complete statement to the server:
log("Inserting data into the collection");
myQu.execute();
log("Done !");
} catch (Exception e) {
e.printStackTrace();
}
}
public void insertImageAsJpeg(String name, byte[] img, int maxX, int maxY) throws ODMGException {
try {
init();
log("Creating image from bytes ...");
RasGMArray myMDD = createRasArrayFromBytes(img, maxX, maxY);
// set up query object for collection creation:
OQLQuery myQu = myApp.newOQLQuery();
myQu.create("create collection " + name + " GreySet");
// set the object type name (used for server type checking):
myMDD.setObjectTypeName("GreyImage");
// finally, execute “create collection” statement:
log("Creating collection '" + name + "'");
myQu.execute();
// now create the insert statement:
myQu.create("insert into " + name + " values inv_jpeg($1)");
// let the server generate a new OID for the object to be
// inserted, and remember this OID locally:
String myNewOID = myApp.getObjectId(myMDD);
// bind the MDD value which substitutes formal parameter $1:
myQu.bind(myMDD);
// …and ship the complete statement to the server:
log("Inserting data into the collection");
myQu.execute();
log("Done !");
commitAndClose();
} catch (Exception e) {
System.out.flush();
e.printStackTrace();
System.err.flush();
abortAndClose();
}
}
private RasGMArray createRasArrayFromBytes(byte[] bytes, int maxX, int maxY)
throws RasResultIsNoIntervalException {
// create 2-D MDD with cell length 1, i.e., type “byte”:
String strX = String.valueOf(maxX), strY = String.valueOf(maxY);
String interval = "[1:" + strX + "],1:" + strY + "]";
// FIXME: maybe change cell type?
int cellType = 1;
// create the RasGMArray object
RasGMArray myMDD = new RasGMArray(new RasMInterval(interval), cellType);
myMDD.setArray(bytes);
return myMDD;
}
public void deleteCollection(String name)
throws ODMGException, ODMGException, ODMGException, Exception {
try {
// init();
log("Creating query...");
// set up query object for collection creation:
OQLQuery myQu = myApp.newOQLQuery();
myQu.create("drop collection " + name);
// finally, execute “create collection” statement:
log("Executing deletion query...");
myQu.execute();
// now create the insert statement:
log("Query finished !");
// commitAndClose();
} catch (Exception e) {
e.printStackTrace();
throw e;
// abortAndClose();
}
}
public void printAllCollections() throws ODMGException {
String query = "select r from RAS_COLLECTIONNAMES as r";
// init();
log("Querying for all available collections ...");
OQLQuery myQu = myApp.newOQLQuery();
myQu.create(query);
DBag resultSet = (DBag) myQu.execute();
if (resultSet != null) {
Iterator iter = resultSet.iterator();
while (iter.hasNext()) {
RasGMArray result = (RasGMArray) iter.next();
byte[] ba = result.getArray();
String name = new String(ba);
if (name.endsWith("\u0000")) {
name = name.substring(0, name.length() - (new String("\u0000")).length());
}
System.out.println("* " + name);
}
}
// commitAndClose();
}
public RasGMArray createMddFromImage(BufferedImage img) throws InternalComponentException {
String interval = null;
try {
int cols = img.getWidth();
int rows = img.getHeight();
// create 2-D MDD with cell length 1, i.e., type “byte”:
interval = "[1:" + cols + ",1:" + rows + "]";
int cellType = 1;
// create the RasGMArray object
RasGMArray myMDD = new RasGMArray(new RasMInterval(interval), cellType);
DataBuffer db = img.getData().getDataBuffer();
byte[] bytes = new byte[cols * rows];
System.out.println("Processing image with size: " + interval);
System.out.println("Created vector with size: " + cols * rows);
System.out.println("Processing data with size: " + db.getSize());
int i = 0;
/*
* Java image data-types store an image as a 1-D array, reading the
* image row-wise. Rasdaman stores the image column-wise. So we need to
* convert between the two representations.
*/
for (int c = 0; c < cols; c++) {
for (int r = 0; r < rows; r++) {
bytes[i++] = (byte) db.getElem(r * cols + c);
}
}
myMDD.setArray(bytes);
return myMDD;
} catch (RasResultIsNoIntervalException e) {
throw new InternalComponentException("Illegal Interval String: " + interval, e);
}
}
public BufferedImage convertImageToGray(BufferedImage img) {
BufferedImage image = new BufferedImage(img.getWidth(), img.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);
Graphics g = image.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
return image;
}
}