package caida.image; import caida.list.MyList; import java.awt.*; import java.awt.image.*; import java.util.Hashtable; /*********************************************************************** * WorldProducer written 11/06/97 * by Bradley Huffaker * Cooperative Association for Internet Data Analysis (CAIDA) * version 1.0 * * This should take in a image of the world, lat/long * pairing, width, height, and create a image of width * and hieght that is that part of the world ************************************************************************ ************************************************************************ By accessing this software, WORLDPRODUCER, you are duly informed of and agree to be bound by the conditions described below in this notice: This software product, WORLDPRODUCER, is developed by Bradley Huffaker, and copyrighted(C) 1998 by the University of California, San Diego (UCSD), with all rights reserved. UCSD administers the NSF grant to CAIDA, number NCR-9711092, under which this code was developed. There is no charge for WORLDPRODUCER software. You can redistribute it and/or modify it under the terms of the GNU General Public License, v. 2 dated June 1991 which is incorporated by reference herein. WORLDPRODUCER is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use of it will not infringe on any third party's intellectual property rights. You should have received a copy of the GNU GPL along with the WORLDPRODUCER program. Copies can also be obtained from http://www.gnu.org/copyleft/gpl.html or by writing to University of California, San Diego SDSC/CAIDA 9500 Gilman Dr., MS-0505 La Jolla, CA 92093 - 0505 USA Or contact INFO@CAIDA.ORG ***********************************************************************/ public class WorldProducer extends Object implements ImageConsumer, ImageProducer { private boolean dimensions_given; private int newWidth, newHeight; private int oldWidth, oldHeight; private ColorModel oldCM = ColorModel.getRGBdefault(); private Hashtable oldProps; private int oldStatus; private int oldHints; private double old_top_lon, old_top_lat, old_bot_lon, old_bot_lat; private double top_lat, top_lon, bot_lat, bot_lon; private MyList consumers; private ImageConsumer consumer; private int source_pixels[]; private int y_shift; private int left_x, right_x, left_width, right_width, final_left_width, final_right_width; private int total_width, total_height; private int parts; private boolean loading; private boolean dimension_set = false; public WorldProducer (Image image, double t_lon, double t_lat, double b_lon, double b_lat) { top_lon = old_top_lon = t_lon; top_lat = old_top_lat = t_lat; bot_lon = old_bot_lon = b_lon; bot_lat = old_bot_lat = b_lat; dimensions_given = false; parts = 1; consumers = new MyList(); loading = true; image.getSource().startProduction(this); } public WorldProducer (Image image, double t_lon, double t_lat, double b_lon, double b_lat, int width_input, int height_input) { top_lon = old_top_lon = t_lon; top_lat = old_top_lat = t_lat; bot_lon = old_bot_lon = b_lon; bot_lat = old_bot_lat = b_lat; dimensions_given = true; newWidth = width_input; newHeight = height_input; parts = 1; consumers = new MyList(); loading = true; image.getSource().startProduction(this); } public synchronized void addConsumer(ImageConsumer cm) { if (loading) { consumers.push(cm); return; } do { consumer = (ImageConsumer) consumers.pop(); if (consumer == null) consumer = cm; // try { produce(); /* } catch (Exception e) { if (consumer != null) consumer.imageComplete(ImageConsumer.IMAGEERROR); System.err.println("Error " + e.toString()); } */ consumer = null; } while (!consumers.empty()); } public synchronized boolean isConsumer(ImageConsumer cm) { //System.err.println("isConsumer"); return (consumers.exists(cm) || (consumer == cm)); } public synchronized void removeConsumer(ImageConsumer cm) { //System.err.println("removeConsumer"); if (consumer == cm) { //System.err.println("I never did anything"); consumer = null; } else consumers.drop(cm); } public synchronized void abort() { if (consumer != null) consumer.imageComplete(IMAGEABORTED); consumer = null; } public void requestTopDownLeftRightResend(ImageConsumer cm) { //System.err.println("requestTopDownLeftRightResend"); addConsumer(cm); } public void startProduction(ImageConsumer cm) { //System.err.println("startProduction"); addConsumer(cm); } public void setBox(double t_lon, double t_lat, double b_lon, double b_lat, int new_width, int new_height) { dimensions_given = true; top_lon = t_lon; top_lat = t_lat; bot_lon = b_lon; bot_lat = b_lat; newWidth = new_width; newHeight = new_height; setSource(); } public void setBox(double t_lon, double t_lat, double b_lon, double b_lat) { top_lon = t_lon; top_lat = t_lat; bot_lon = b_lon; bot_lat = b_lat; setSource(); } private void setSource() { //System.err.println ("(long,lat) (" + top_lon + "," + top_lat +") (" + bot_lon + "," + bot_lat + ")" ); if ((old_bot_lon - old_top_lon != 360) || (old_bot_lon - old_top_lon > 360)) { System.err.println("World Zoom must have a map of the whole world"); top_lon = old_top_lon; top_lat = old_top_lat; bot_lon = old_bot_lon; bot_lat = old_bot_lat; } while (bot_lon - top_lon > 360) top_lon += 360; while ((bot_lon - top_lon)/360 <= 0.0000001) bot_lon += 360; if (bot_lon == top_lon) bot_lon = top_lon + 360; while (top_lon > old_bot_lon) { top_lon -= 360; bot_lon -= 360; } while (top_lon < old_top_lon) { top_lon += 360; bot_lon += 360; } if (top_lat > old_top_lat) top_lat = old_top_lat; if (bot_lat < old_bot_lat) bot_lat = old_bot_lat; setup(); } public int getWidth() { return newWidth; } public int getHeight() { return newHeight; } public void setWidthHeight(int width, int height) { newWidth = width; newHeight = height; } public void setDimensions(int width, int height) { //System.err.println("setDimensions:"+ width +","+ height); dimension_set = true; oldWidth = width; oldHeight = height; if (!dimensions_given) { newWidth = width; newHeight = height; } source_pixels = new int[oldWidth*oldHeight]; setup(); } private void setup() { if (!dimension_set) return; double t_lon[] = new double[2]; double t_lat[] = new double[2]; double b_lon[] = new double[2]; double b_lat[] = new double[2]; if (bot_lon <= old_bot_lon) { parts = 1; t_lon[0] = top_lon; t_lat[0] = top_lat; b_lon[0] = bot_lon; b_lat[0] = bot_lat; } else { parts = 2; t_lon[0] = top_lon; t_lat[0] = top_lat; b_lon[0] = old_bot_lon; b_lat[0] = bot_lat; t_lon[1] = old_top_lon; t_lat[1] = top_lat; b_lon[1] = bot_lon-360; b_lat[1] = bot_lat; } double lat_height = old_top_lat - old_bot_lat; double total_lon = bot_lon - top_lon; y_shift = (new Double(((old_top_lat - t_lat[0]) /lat_height)*oldHeight)).intValue(); total_height = (new Double(((t_lat[0] - b_lat[0]) /lat_height)*oldHeight)).intValue(); left_x = (new Double(((t_lon[0] - old_top_lon)/360) *oldWidth)).intValue(); left_width = (new Double(((b_lon[0] - t_lon[0])/360) *oldWidth)).intValue(); final_left_width = (new Double(((b_lon[0] - t_lon[0])/total_lon) *newWidth)).intValue(); total_width = left_width; if (parts == 2) { right_x = (new Double(((t_lon[1] - old_top_lon)/360) *oldWidth)).intValue(); right_width = (new Double(((b_lon[1] - t_lon[1])/360) *oldWidth)).intValue(); final_right_width = (new Double(((b_lon[1] - t_lon[1]) /total_lon)*newWidth)).intValue(); total_width += right_width; } /* System.err.println("left_x:" + left_x); System.err.println("left_width:" + left_width); System.err.println("final_left_width:" + final_left_width); System.err.println("right_x:" + right_x); System.err.println("right_width:" + right_width); System.err.println("final_right_width:" + final_right_width); */ } public void setColorModel(ColorModel model) { //System.err.println("setColorModel"); //oldCM = model; } public void setHints(int hintflags) { //System.err.println("setHints"); oldHints = (TOPDOWNLEFTRIGHT | COMPLETESCANLINES | SINGLEPASS | (hintflags & SINGLEFRAME)); } public void setProperties(Hashtable props) { //System.err.println("setProperties"); oldProps = props; } public void setThePixels(int x, int y, int width, int height, ColorModel cm, Object pixels, int offset, int scansize) { int sourceOffset = offset; int destinationOffset = y * oldWidth + x; boolean bytearray = (pixels instanceof byte[]); for (int yy=0; yy< height;yy++) { for (int xx=0;xx oldWidth) x_map = oldWidth; pixels[pixel_index] = source_pixels[y_map + x_map]; pixel_index++; } if (consumer == null) return; else consumer.setPixels(0,yy,newWidth,1,oldCM,pixels,0 ,newWidth); } if (consumer == null) return; else consumer.imageComplete(oldStatus); } }