advertisement
javaboutique
Search Tips
Articles  |   Tutorials  |   Reviews  |   Tools  |   by Category  |   by Date  |   by Name  |   Submit  |   Source  |   Forums  |  
javaboutique
Browse DevX


Partners & Affiliates











advertisement

Polymap


/********************************************************************************
* ImageMap.java: Java Polymap Applet source code                                *
*                                                                               *
* Copyright (C) 1996 Cheong S Ang                                               *
*                                                                               *
* Java Polymap Applet, both binary and source (hereafter, Software) is          *
* copyrighted by Cheong S Ang (hereafter, Author), and ownership remains        *
* with the the Author.                                                          *
*                                                                               *
* The Author grants you (hereafter, Licensee) a license to use the Software     *
* for academic, research and non-commercial purposes only, without a            *
* fee.  Licensee may distribute the binary and source code (if released)        *
* to third parties provided that the copyright notice and this statement        *
* appears on all copies and that no charge is associated with such              *
* copies.                                                                       *
*                                                                               *
* Licensee may make derivative works.  However, if Licensee distributes         *
* any derivative work based on or derived from the Software, then               *
* Licensee will (1) notify the Author regarding its distributing of the         *
* derivative work, and (2) clearly notify users that such derivative            *
* work is derived from the Software.                                            *
*                                                                               *
* Any Licensee wishing to make commercial use of the Software should            *
* contact the Author, to negotiate an appropriate license for such              *
* commercial use.  Commercial use included (1) integration of all or            *
* part of the source code into a product for sale or license by or on           *
* behalf of Licensee to third parties, or (2) distribution of the binary        *
* code or source code to third parties that need it to utilize a                *
* commercial product sold or licensed by or on behalf of Licensee.              *
*                                                                               *
* THE AUTHOR MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE    *
* FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED           *
* WARRANTY.  THE AUTHOR SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE     *
* USERS OF THIS SOFTWARE.                                                       *
*                                                                               *
* By using or copying this Software, Licensee agrees to abide by the            *
* copyright law and all other applicable laws of the U.S. including, but        *
* not limited to, export control laws, and the terms of this license.           *
* The Author shall have the right to terminate this license immediately by      *
* written notice upon Licensee's breach of, or non-compliance with, any         *
* of its terms.  Licensee may be held legally responsible for any               *
* copyright infringement that is caused or encouraged by Licensee's             *
* failure to abide by the terms of this license.                                *
*                                                                               *
********************************************************************************/

/*
 * @version 1.0 15 March 1996
 * @author Cheong S Ang
 */

import java.applet.Applet;
import java.lang.Thread;
import java.lang.Integer;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.*;
import java.awt.Rectangle;
import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;

class Point {
        int x, y;
}
class Poly {
        Polygon pol; // cache it
        Point[] pt;
        int npts;
}
class PolyObj {
        Poly[] p;
        String url;
        int nps;
}
class Polymap {
        PolyObj[] pobj;
        int npobjs;
}


public class ImageMap extends Applet {
        static final int NONE = -1;

        Polygon current_polygon;
        int current_obj=NONE;
        int current_poly=NONE;
        Polymap pm;
        Color highlight_color;
    Image baseImage;

    public void init() {
                baseImage = getImage(getDocumentBase(), getParameter("img"));

                byte[] im;
                URL url;
                InputStream us;
                ByteArrayOutputStream bos;
                int nread = 0;
                int st;
                try {
                        String base = getDocumentBase().toString();
                        int s=0, e;
                        while((e=base.indexOf('/', s))!=-1) {
                                s = e+1;
                        }
                        //System.out.println("base: " + base);
                        char[] nurl = base.toCharArray();
                        base = new String(nurl, 0, s);
                        String surl = base + getParameter("img");
                        //System.out.println("base: " + base + " img: " + getParameter("img"));
                        System.out.println("full img url: " + surl);

                        showStatus("Polymap Applet. Copyright © 1996 Cheong S Ang.");
                        url = new URL(surl);
                        us = url.openStream();

                        byte[] buf = new byte[1024];
                        int nbytes = 0;
                        bos = new ByteArrayOutputStream();
                        nread = us.read(buf, 0, 1024);
                        bos.write(buf, 0, nread);
                        while (nread > 0) {
                                nread = us.read(buf, 0, 1024);
                                if (nread<=0) break;
                                bos.write(buf, 0, nread);
                                nbytes += nread;
                                //System.out.println(nbytes + " bytes read");
                        }

                        String str = bos.toString();
                        st = str.indexOf("PMAP1.0");
                        //if (st > 0)   System.out.println("Location of PMAP: " + st);
                }
                catch (Exception e) {
                        e.printStackTrace();
                        return;
                }
                if (st > 0) { // found PMAP1.0
                        im = bos.toByteArray();
                        String sim = new String(im, 0, st, 20);
                        DoPolymap(im, st); // create pm

                        // create all the polygons ahead of time
                        int max_j, max_k;
                        for (int i=pm.npobjs-1; i>=0; i--) {
                                max_j = pm.pobj[i].nps;
                                for (int j=0; j<max_j; j++) {
                                        max_k = pm.pobj[i].p[j].npts;
                                        int[] xpts=new int[max_k];
                                        int[] ypts=new int[max_k];
                                        for (int k=0; k<max_k; k++) {
                                                xpts[k] = pm.pobj[i].p[j].pt[k].x;
                                                ypts[k] = pm.pobj[i].p[j].pt[k].y;
                                        }
                                        pm.pobj[i].p[j].pol = new Polygon(xpts, ypts, max_k);
                                }
                        }

                        String scolor = getParameter("color");
                        Integer icolor;
                        try {
                                icolor = Integer.valueOf(scolor, 16);
                                highlight_color = new Color(icolor.intValue());
                        } catch (NumberFormatException e) {
                                highlight_color = Color.blue;
                        }
                }
    }

        int nim; // im pointer
        boolean ReadOK(byte[] src, byte[] buffer, int b, int len) {
                for (int i=0; i<len; i++)
                        buffer[b+i] = src[nim+i];
                nim += len;
                return true;
        }

        boolean    ZeroDataBlock = false;
        int     GetDataBlock(byte[] im, byte[] buf, int b) {
                byte[]   count = new byte[1];

                count[0]=0;
                if (! ReadOK(im, count, 0, 1)) {
                        System.out.println( "error in getting DataBlock size");
                        return -1;
                }

                ZeroDataBlock = ((count[0]&0xff) == 0);
                if (((count[0]&0xff) != 0) && (! ReadOK(im, buf, b, (count[0]&0xff)))) {
                        System.out.println( "error in reading DataBlock\r\n");
                        return -1;
                }

                return (count[0]&0xff);
        }
        /*
        **  Used in nextCode
        */
        int      curbit, lastbit;
        int      last_byte;
        boolean  return_clear, get_done;
        int[] maskTbl = {
                0x0000, 0x0001, 0x0003, 0x0007,
                0x000f, 0x001f, 0x003f, 0x007f,
                0x00ff, 0x01ff, 0x03ff, 0x07ff,
                0x0fff, 0x1fff, 0x3fff, 0x7fff,
        };
        byte[]   buf = new byte[280];
        /*
        **  Used in nextLWZ
        */
        static final int        MAX_LWZ_BITS = 12;
        int[]   stack;
        int             sp; // stack pointer
        int     code_size, set_code_size;
        int     max_code, max_code_size;
        int     clear_code, end_code;

        int nextCode(byte[] im, int code_size) {
                int i, j, ret, end;

                if (return_clear) {
                        return_clear = false;
                        return clear_code;
                }

                end = curbit + code_size;

                if (end >= lastbit) {
                        int count;

                        if (get_done) {
                                if (curbit >= lastbit)
                                        System.out.println("ran off the end of my bits \r\n" );
                                return -1;
                        }
                        buf[0] = buf[last_byte-2];
                        buf[1] = buf[last_byte-1];

                        if ((count = GetDataBlock(im, buf, 2)) == 0)
                                get_done = true;

                        last_byte = 2 + count;
                        curbit = (curbit - lastbit) + 16;
                        lastbit = (2+count)*8 ;

                        end = curbit + code_size;
                }

                j = end / 8;
                i = curbit / 8;

                if (i == j)
                        ret = (buf[i]&0xff);
                else if (i + 1 == j)
                        ret = (buf[i]&0xff) | (((buf[i+1]&0xff)) << 8);
                else
                        ret = (buf[i]&0xff) | (((buf[i+1]&0xff)) << 8) | (((buf[i+2]&0xff)) << 16);

                ret = (ret >> (curbit % 8)) & maskTbl[code_size];

                curbit += code_size;

                return ret;
        }
        int readLWZ(byte[] im) {
                if (sp > 0)
                        return stack[--sp];
                else
                        return nextLWZ(im);
        }
        int[][]   table = new int[2][(1<< MAX_LWZ_BITS)];
        int firstcode=0;
        int oldcode=0;
        int nextLWZ(byte[] im) {
                int       code, incode;
                int             i;

                while ((code = nextCode(im, code_size)) >= 0) {
                         if (code == clear_code) {

                                /* corrupt GIFs can make this happen */
                                if (clear_code >= (1<<MAX_LWZ_BITS)) {
                                        System.out.println("Gif Error: probable corrupt gif.");
                                        return -2;
                                }
                        for (i = 0; i < clear_code; ++i) {
                                table[0][i] = 0;
                                table[1][i] = i;
                        }
                        for (; i < (1<<MAX_LWZ_BITS); ++i)
                                table[0][i] = table[1][i] = 0;
                        code_size = set_code_size+1;
                        max_code_size = 2*clear_code;
                        max_code = clear_code+2;
                        sp = 0;
                                do {
                                           firstcode = oldcode = nextCode(im, code_size);
                                } while (firstcode == clear_code);

                                return firstcode;
                        }
                        if (code == end_code) {
                                        int     count;
                                byte[]   buf = new byte[260];

                                if (ZeroDataBlock) {
                                        System.out.println("Gif Error?  ZeroDataBlock");
                                        return -2;
                                        }

                                while ((count = GetDataBlock(im, buf, 0)) > 0);

                                if (count != 0)
                                       System.out.println("missing EOD in data stream (common occurence)");
                                        System.out.println("GIF:  code==end_code");
                                        return -2;
                        }

                        incode = code;

                    if (code >= max_code) {
                               stack[sp++] = firstcode;
                               code = oldcode;
                        }

                        while (code >= clear_code) {
                                stack[sp++] = table[1][code];
                                if (code == table[0][code]) {
                                System.out.println("circular table entry BIG ERROR");
                                return(code);
                                }
                                code = table[0][code];
                        }

                        stack[sp++] = firstcode = table[1][code];

                        if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
                                table[0][code] = oldcode;
                                table[1][code] = firstcode;
                                ++max_code;
                                if ((max_code >= max_code_size) && (max_code_size < (1<<MAX_LWZ_BITS))) {
                                        max_code_size *= 2;
                                        ++code_size;
                                }
                        }

                        oldcode = incode;

                        if (sp > 0)
                                return stack[--sp];
                }
                return code;
        }
        boolean      inited = false;
        void initLWZ(int input_code_size) {

                set_code_size = input_code_size;
                code_size     = set_code_size + 1;
                clear_code    = 1 << set_code_size ;
                end_code      = clear_code + 1;
                max_code_size = 2 * clear_code;
                max_code      = clear_code + 2;

                curbit = lastbit = 0;
                last_byte = 2;
                get_done = false;

                return_clear = true;

                stack = new int[(1<<MAX_LWZ_BITS)*2];
                sp = 0;
        }
        void ReadPolymapData ( byte[] im, byte[] mdata, int nbytes, int bit_size )
        {
                int i, v, m=0;

                initLWZ(bit_size);
                for (i = 0; i < nbytes; i++) {
                        if ((v = readLWZ(im)) < 0) {
                                System.out.println("Skipping extra LWZ data");
                                break;
                        }
                mdata[m++] = (byte)v;
                }
        }
        boolean DoPolymap(byte[] im, int st) { // read polymap from byte array
                int nbytes, bit_size;
                int n = st+7;
                byte[] b = new byte[4];

                b[0] = im[n++];
                b[1] = im[n++];
                b[2] = im[n++];
                b[3] = im[n++];
                nbytes = (b[0]&0xff) | (b[1]&0xff)<<8 | (b[2]&0xff)<<16 | (b[3]&0xff)<<24;
                bit_size = im[n++]&0xff;

                byte[] mdata = new byte[nbytes];
                nim = n; // the global im pointer; current reading position
                ReadPolymapData( im, mdata, nbytes, bit_size );

                b[0] = mdata[0];
                b[1] = mdata[1];
                int NumObjs = (b[0]&0xff) | (b[1]&0xff)<<8;
                if (NumObjs <= 0) return false;
                pm = new Polymap();
        pm.pobj = new PolyObj[NumObjs];
                pm.npobjs = NumObjs;

                byte[] buf = new byte[100];
                int len, nb;
                nb = 2; // mdata[0] and mdata[1] used, see above
                for (int i=0; i<NumObjs; i++) {
                    len = 0;
                    while ((char)mdata[nb] != '\0') {
                                buf[len++] = mdata[nb++];
                        }
                        nb++;
                        pm.pobj[i] = new PolyObj();
                        pm.pobj[i].url = new String(buf, 0, 0, len);
                }

                if (true) {
                    int uc_left = nbytes;
                    int nuc, i, value;
                    i = n = NONE;
                    nuc = nb; // nb bytes of mdata read as url's, see above
                    while (nuc < uc_left) {
                                b[0] = mdata[nuc]; b[1] = mdata[nuc+1];
                                value = (b[0]&0xff) | (b[1]&0xff)<<8;
                                if (value == 65535) {
                                    nuc+=2;
                                    b[0] = mdata[nuc++]; b[1] = mdata[nuc++];
                                    i = b[0] | b[1]<<8;
                                    b[0] = mdata[nuc++]; b[1] = mdata[nuc++];
                                    n = (b[0]&0xff) | (b[1]&0xff)<<8;

                                        if (n>0) {
                                            Poly[] tmp = new Poly[pm.pobj[i].nps];
                                                for (int j=0; j<pm.pobj[i].nps; j++)
                                                        tmp[j] = pm.pobj[i].p[j];
                                            pm.pobj[i].p = new Poly[pm.pobj[i].nps+1];
                                                for (int j=0; j<pm.pobj[i].nps; j++)
                                                        pm.pobj[i].p[j] = tmp[j];
                                                pm.pobj[i].nps++;
                                        }
                                        else {
                                                pm.pobj[i].nps = 1;
                                            pm.pobj[i].p = new Poly[1];
                                        }
                                        pm.pobj[i].p[n] = new Poly();
                                        pm.pobj[i].p[n].npts = 0;
                                }
                                else if (i >= 0 && n >= 0) {
                                        if (nuc < uc_left) {
                                            b[0] = mdata[nuc]; b[1] = mdata[nuc+1];
                                            value = (b[0]&0xff) | (b[1]&0xff)<<8;
                                            while (nuc < uc_left && value != 65535) {
                                                    nuc+=2;
                                                        if (pm.pobj[i].p[n].npts > 0) {
                                                                Point[] tmp = new Point[pm.pobj[i].p[n].npts];
                                                                for (int j=0; j<pm.pobj[i].p[n].npts; j++){
                                                                        tmp[j] = pm.pobj[i].p[n].pt[j];
                                                                }
                                                            pm.pobj[i].p[n].pt = new Point[pm.pobj[i].p[n].npts+1];
                                                                for (int j=0; j<pm.pobj[i].p[n].npts; j++) {
                                                                        pm.pobj[i].p[n].pt[j] = tmp[j];
                                                                }
                                                                pm.pobj[i].p[n].npts++;
                                                        }
                                                        else {
                                                                pm.pobj[i].p[n].npts = 1;
                                                                pm.pobj[i].p[n].pt = new Point[1];
                                                        }
                                                        pm.pobj[i].p[n].pt[pm.pobj[i].p[n].npts-1] = new Point();
                                                    pm.pobj[i].p[n].pt[pm.pobj[i].p[n].npts-1].x = value;
                                                        b[0] = mdata[nuc++]; b[1] = mdata[nuc++];
                                                value = (b[0]&0xff) | (b[1]&0xff)<<8;
                                                    pm.pobj[i].p[n].pt[pm.pobj[i].p[n].npts-1].y = value;

                                                        if (nuc+1 >= uc_left) break; // about to access two more bytes
                                                b[0] = mdata[nuc]; b[1] = mdata[nuc+1];
                                                value = (b[0]&0xff) | (b[1]&0xff)<<8;
                                                }
                                        }
                                }
                                else {
                                        System.out.println("Corrupted Polymap data");
                                        return false;
                                }
                        }
                }
                return true;
        }

    public void paint(Graphics g) {
                if (baseImage == null) {
                        return;
                }
                g.drawImage(baseImage, 0, 0, this);
    }

    public void update(Graphics g) {
                if (current_poly!=NONE) {
                        Rectangle rect = current_polygon.getBoundingBox();
                        g.clipRect(rect.x, rect.y, rect.width+1, rect.height+1);
                }
                else {
                        int w = baseImage.getWidth(this);
                        int h = baseImage.getHeight(this);
                        g.clipRect(0, 0, w+1, h+1);
                }
                paint(g);
    }

        boolean just_entered = true;
        public boolean mouseEnter(java.awt.Event evt, int x, int y) {
                showStatus("Polymap Applet. Copyright © 1996 Cheong S Ang.");
                just_entered = true;
                return true;
        }

    /**
     * Make sure that no ImageAreas are highlighted.
     */
    public boolean mouseExit(java.awt.Event evt, int x, int y) {
                if (current_obj!=NONE && current_poly!=NONE) {
                        repaint();
                        showStatus("Polymap Applet. Copyright © 1996 Cheong S Ang.");
                }
                return true;
    }

    public boolean mouseMove(java.awt.Event evt, int x, int y) {
                try { // just to test for null pm
                        if (pm.npobjs <= 0) return true;
                }
                catch (Exception e) { // no polymap
                        showStatus("No Polymap data");
                        return true;
                }

                Graphics g = getGraphics();
                g.setColor(highlight_color);

                int max_j;
                for (int i=pm.npobjs-1; i>=0; i--) {
                        max_j = pm.pobj[i].nps;
                        for (int j=0; j<max_j; j++) {
                                Polygon pol = pm.pobj[i].p[j].pol; // created earlier
                                if (pol.inside(x,y)) {
                                        if (i==current_obj && j==current_poly) return true;
                                        if ((i!=current_obj || j!=current_poly) &&
                                                (current_obj!=NONE && current_poly!=NONE)) {
                                                update(g);
                                        }
                                        current_obj = i;
                                        current_poly = j;
                                        current_polygon = pol;
                                        Graphics g2 = getGraphics(); //get a new one. g has been clipRect in update(g)
                                        g2.setColor(highlight_color);
                                        g2.drawPolygon(pol);
                                        showStatus(pm.pobj[current_obj].url);
                                        return true;
                                }
                        }
                }
                if (current_obj!=NONE && current_poly!=NONE) {
                        repaint();
                        just_entered = false;
                }
                current_obj = NONE;
                current_poly = NONE;
                if (just_entered)
                        showStatus("Polymap Applet. Copyright © 1996 Cheong S Ang.");
                else
                        showStatus("Ready");
                return true;
    }

    public boolean mouseDown(java.awt.Event evt, int x, int y) {
                mouseMove(evt, x, y); // let mouse move handle it
                return true;
    }

    public boolean mouseUp(java.awt.Event evt, int x, int y) {
                if (current_obj!=NONE && current_poly!=NONE) {
                        URL url;
                        try {
                                url = new URL(pm.pobj[current_obj].url);
                        }
                        catch (Exception e) {
                                e.printStackTrace();
                                return true;
                        }
                        super.getAppletContext().showDocument(url);
                }
                return true;
    }
}


Back to the Polymap applet page.

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.

 Avaya DevConnect Center
 Service Component Architecture/Service Data Objects Solution Center
 Intel Go Parallel Portal
 Internet.com eBook Library
 IBM Software Construction Toolbox
 Microsoft RIA Development Center
 Destination .NET
XML error: not well-formed (invalid token) at line 53
advertisement
Receive Articles via our XML/RSS feed
Receive Articles via our XML/RSS feed

JavaBytes
Internet Cyclone
This powerful, easy-to-use, internet optimizer is for Windows 95, 98, ME, NT, 2000 and XP. It's designed to automatically optimize your Windows settings, boosting your Internet connection up to 200%.

Red Hat Takes on HPC Market, Microsoft
Python's New Release Bridges the Gap
No Flash Seen on iPhone Horizon
Apple Yields to Complaints Over iPhone NDA
Microsoft Shows Some Ankle With Visual Studio
Gentoo Linux Cancels Distribution
It's Official: Windows 7 at PDC, WinHEC
Oracle Keeps Building on Spoils From BEA
Intel, Oracle Head For 'The Cloud'
Oracle Focuses on Grid, Developer Tools

eCryptfs: Single-File Encryption in Linux
CCXML in Action: A CCXML Auto Attendant
Ballmer: Current Woes Won't Halt Tech, Microsoft
Microsoft Uses VMworld to Hype Its Hypervisor
Microsoft Charges Ahead in Virtualization
Microsoft Shows Some Ankle With Visual Studio
Top 5 Reasons to Adopt SQL Server 2008
Make Application Development Easy With Software Plus Services
SharePoint Applied: 10 Things You Wish They Had Told You?Part 2
Introducing Zend_Search_Lucene

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map  |   Network Map  |   About



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
IBM Whitepaper: Innovative Collaboration to Advance Your Business
Internet.com eBook: Real Life Rails
Avaya Article: Call Control XML - Powerful, Standards-Based Call Control
Internet.com eBook: The Pros and Cons of Outsourcing
Go Parallel Article: Scalable Parallelism with Intel(R) Threading Building Blocks
Internet.com eBook: Best Practices for Developing a Web Site
IBM CXO Whitepaper: The 2008 Global CEO Study "The Enterprise of the Future"
Avaya Article: Call Control XML in Action - A CCXML Auto Attendant
Go Parallel Article: James Reinders on the Intel Parallel Studio Beta Program
IBM CXO Whitepaper: Unlocking the DNA of the Adaptable Workforce--The Global Human Capital Study 2008
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Go Parallel Article: Getting Started with TBB on Windows
HP eBook: Storage Networking , Part 1
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
Go Parallel Video: Intel(R) Threading Building Blocks: A New Method for Threading in C++
HP Video: Is Your Data Center Ready for a Real World Disaster?
Microsoft Partner Portal Video: Microsoft Gold Certified Partners Build Successful Practices
HP On Demand Webcast: Virtualization in Action
Go Parallel Video: Performance and Threading Tools for Game Developers
Rackspace Hosting Center: Customer Videos
Intel vPro Developer Virtual Bootcamp
HP Disaster-Proof Solutions eSeminar
HP On Demand Webcast: Discover the Benefits of Virtualization
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Microsoft Download: Silverlight 2 Software Development Kit Beta 2
30-Day Trial: SPAMfighter Exchange Module
Red Gate Download: SQL Toolbelt
Iron Speed Designer Application Generator
Microsoft Download: Silverlight 2 Beta 2 Runtime
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
IBM IT Innovation Article: Green Servers Provide a Competitive Advantage
Microsoft Article: Expression Web 2 for PHP Developers--Simplify Your PHP Applications
Featured Algorithm: Intel Threading Building Blocks - parallel_reduce
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES