public interface Gdi {
    public static final int OPAQUE = 2;
    public static final int TRANSPARENT = 1;

    public static final int TA_BASELINE = 24;
    public static final int TA_BOTTOM = 8;
    public static final int TA_TOP = 0;
    public static final int TA_CENTER = 6;
    public static final int TA_LEFT = 0;
    public static final int TA_RIGHT = 2;
    public static final int TA_NOUPDATECP = 0;
    public static final int TA_RTLREADING = 256;
    public static final int TA_UPDATECP = 1;
    public static final int VTA_BASELINE = 24;
    public static final int VTA_CENTER = 6;

    public static final int ETO_CLIPPED = 4;
    public static final int ETO_NUMERICSLOCAL = 1024;
    public static final int ETO_NUMERICSLATIN = 2048;
    public static final int ETO_GLYPH_INDEX = 16;
    public static final int ETO_OPAQUE = 2;
    public static final int ETO_PDY = 8192;
    public static final int ETO_RTLREADING = 128;
    public static final int ETO_IGNORELANGUAGE = 4096;

    public static final int MM_ANISOTROPIC = 8;
    public static final int MM_HIENGLISH = 5;
    public static final int MM_HIMETRIC = 3;
    public static final int MM_ISOTROPIC = 7;
    public static final int MM_LOENGLISH = 4;
    public static final int MM_LOMETRIC = 2;
    public static final int MM_TEXT = 1;
    public static final int MM_TWIPS = 6;

    public static final int STRETCH_ANDSCANS = 2;
    public static final int STRETCH_DELETESCANS = 3;
    public static final int STRETCH_HALFTONE = 4;
    public static final int STRETCH_ORSCANS = 2;
    public static final int BLACKONWHITE = 2;
    public static final int COLORONCOLOR = 3;
    public static final int HALFTONE = 4;
    public static final int WHITEONBLACK = 2;

    public static final int ALTERNATE = 1;
    public static final int WINDING = 2;

    public static final int R2_BLACK = 1;
    public static final int R2_COPYPEN = 13;
    public static final int R2_MASKNOTPEN = 3;
    public static final int R2_MASKPEN = 9;
    public static final int R2_MASKPENNOT = 5;
    public static final int R2_MERGENOTPEN = 12;
    public static final int R2_MERGEPEN = 15;
    public static final int R2_MERGEPENNOT = 14;
    public static final int R2_NOP = 11;
    public static final int R2_NOT = 6;
    public static final int R2_NOTCOPYPEN = 4;
    public static final int R2_NOTMASKPEN = 8;
    public static final int R2_NOTMERGEPEN = 2;
    public static final int R2_NOTXORPEN = 10;
    public static final int R2_WHITE = 16;
    public static final int R2_XORPEN = 7;
    
	public static final long BLACKNESS = 66;
	public static final long DSTINVERT = 5570569;
	public static final long MERGECOPY = 12583114;
	public static final long MERGEPAINT = 12255782;
	public static final long NOTSRCCOPY = 3342344;
	public static final long NOTSRCERASE = 1114278;
	public static final long PATCOPY = 15728673;
	public static final long PATINVERT = 5898313;
	public static final long PATPAINT = 16452105;
	public static final long SRCAND = 8913094;
	public static final long SRCCOPY = 13369376;
	public static final long SRCERASE = 4457256;
	public static final long SRCINVERT = 6684742;
	public static final long SRCPAINT = 15597702;
	public static final long WHITENESS = 16711778;
	
	public static final int DIB_RGB_COLORS = 0;
	public static final int DIB_PAL_COLORS = 1;
	
	public static final int LAYOUT_BITMAPORIENTATIONPRESERVED = 8;
	public static final int LAYOUT_RTL = 1;
	
	public static final int ABSOLUTE = 1;
	public static final int RELATIVE = 2;
	
	public static final int ASPECT_FILTERING = 1;
	
    public void placeableHeader(int vsx, int vsy, int vex, int vey, int dpi);
    public void header();
    public void animatePalette(GdiPalette palette, int startIndex, int[] entries);
    public void arc(int sxr, int syr, int exr, int eyr,
		    int sxa, int sya, int exa, int eya);
    public void bitBlt(byte[] image, int dx, int dy, int dw, int dh, int sx, int sy, long rop);
    public void chord(int sxr, int syr, int exr, int eyr,
		      int sxa, int sya, int exa, int eya);
    public GdiBrush createBrushIndirect(int style, int color, int hatch);
    public GdiFont createFontIndirect(int height, int width, int escapement,
				      int orientation, int weight,
				      boolean italic, boolean underline, boolean strikeout,
				      int charset, int outPrecision, int clipPrecision,
				      int quality, int pitchAndFamily, byte[] faceName);
    public GdiPalette createPalette(int version, int[] palEntry);
    public GdiPatternBrush createPatternBrush(byte[] image);
    public GdiPen createPenIndirect(int style, int width, int color);
    public GdiRegion createRectRgn(int left, int top, int right, int bottom);
    public void deleteObject(GdiObject obj);
    public void dibBitBlt(byte[] image, int dx, int dy, int dw, int dh,
			int sx, int sy, long rop);
    public GdiPatternBrush dibCreatePatternBrush(byte[] image, int usage);
    public void dibStretchBlt(byte[] image, int dx, int dy, int dw, int dh,
			int sx, int sy, int sw, int sh, long rop);
    public void ellipse(int sx, int sy, int ex, int ey);
    public void escape(byte[] data);
    public int excludeClipRect(int left, int top, int right, int bottom);
    public void extFloodFill(int x, int y, int color, int type);
    public void extTextOut(int x, int y, int options, int[] rect, byte[] text, int[] lpdx);
    public void fillRgn(GdiRegion rgn, GdiBrush brush);
    public void floodFill(int x, int y, int color);
    public void frameRgn(GdiRegion rgn, GdiBrush brush, int w, int h);
    public void intersectClipRect(int left, int top, int right, int bottom);
    public void invertRgn(GdiRegion rgn);
    public void lineTo(int ex, int ey);
    public void moveToEx(int x, int y, Point old);
    public void offsetClipRgn(int x, int y);
    public void offsetViewportOrgEx(int x, int y, Point point);
    public void offsetWindowOrgEx(int x, int y, Point point);
    public void paintRgn(GdiRegion rgn);
    public void patBlt(int x, int y, int width, int height, long rop);
    public void pie(int sx, int sy, int ex, int ey, int sxr, int syr, int exr, int eyr);
    public void polygon(Point[] points);
    public void polyline(Point[] points);
    public void polyPolygon(Point[][] points);
    public void realizePalette();
    public void restoreDC(int savedDC);
    public void rectangle(int sx, int sy, int ex, int ey);
    public void resizePalette(GdiPalette palette);
    public void roundRect(int sx, int sy, int ex, int ey, int rw, int rh);
    public void seveDC();
    public void scaleViewportExtEx(int x, int xd, int y, int yd, Size old);
    public void scaleWindowExtEx(int x, int xd, int y, int yd, Size old);
    public void selectClipRgn(GdiRegion rgn);
    public void selectObject(GdiObject obj);
    public void selectPalette(GdiPalette palette, boolean mode);
    public void setBkColor(int color);
    public void setBkMode(int mode);
    public void setDIBitsToDevice(int dx, int dy, int dw, int dh, int sx, int sy,
        			int startscan, int scanlines, byte[] image, int colorUse);
    public void setLayout(long layout);
    public void setMapMode(int mode);
    public void setMapperFlags(long flags);
    public void setPaletteEntries(GdiPalette palette, int startIndex, int[] entries);
    public void setPixel(int x, int y, int color);
    public void setPolyFillMode(int mode);
    public void setRelAbs(int mode);
    public void setROP2(int mode);
    public void setStretchBltMode(int mode);
    public void setTextAlign(int align);
    public void setTextCharacterExtra(int extra);
    public void setTextColor(int color);
    public void setTextJustification(int breakExtra, int breakCount);
    public void setViewportExtEx(int x, int y, Size old);
    public void setViewportOrgEx(int x, int y, Point old);
    public void setWindowExtEx(int width, int height, Size old);
    public void setWindowOrgEx(int x, int y, Point old);
    public void stretchBlt(byte[] image, int dx, int dy, int dw, int dh,
			int sx, int sy, int sw, int sh, long rop);
    public void stretchDIBits(int dx, int dy, int dw, int dh,
					int sx, int sy, int sw, int sh,
					byte[] image, int usage, long rop);
    public void textOut(int x, int y, byte[] text);
    public void footer();
}
 public interface GdiBrush extends GdiObject {
	public static final int BS_DIBPATTERN = 5;
	public static final int BS_DIBPATTERN8X8 = 8;
	public static final int BS_DIBPATTERNPT = 6;
	public static final int BS_HATCHED = 2;
	public static final int BS_HOLLOW = 1;
	public static final int BS_NULL = 1;
	public static final int BS_PATTERN = 3;
	public static final int BS_PATTERN8X8 = 7;
	public static final int BS_SOLID = 0;

	public static final int DIB_PAL_COLORS = 1;
	public static final int DIB_RGB_COLORS = 0;

	public static final int HS_HORIZONTAL = 0;
	public static final int HS_VERTICAL = 1;
	public static final int HS_FDIAGONAL = 2;
	public static final int HS_BDIAGONAL = 3;
	public static final int HS_CROSS = 4;
	public static final int HS_DIAGCROSS = 5;
	
	public int getStyle();
	public int getColor();
	public int getHatch();
}
 public interface GdiFont extends GdiObject {
    public static final int FW_DONTCARE = 0;
    public static final int FW_THIN = 100;
    public static final int FW_EXTRALIGHT = 200;
    public static final int FW_ULTRALIGHT = 200;
    public static final int FW_LIGHT = 300;
    public static final int FW_NORMAL = 400;
    public static final int FW_REGULAR = 400;
    public static final int FW_MEDIUM = 500;
    public static final int FW_SEMIBOLD = 600;
    public static final int FW_DEMIBOLD = 600;
    public static final int FW_BOLD = 700;
    public static final int FW_EXTRABOLD = 800;
    public static final int FW_ULTRABOLD = 800;
    public static final int FW_HEAVY = 900;
    public static final int FW_BLACK = 900;

    public static final int ANSI_CHARSET = 0;
    public static final int DEFAULT_CHARSET = 1;
    public static final int SYMBOL_CHARSET = 2;
    public static final int MAC_CHARSET = 77;
    public static final int SHIFTJIS_CHARSET = 128;
    public static final int HANGUL_CHARSET = 129;
    public static final int JOHAB_CHARSET = 130;
    public static final int GB2312_CHARSET = 134;
    public static final int CHINESEBIG5_CHARSET = 136;
    public static final int GREEK_CHARSET = 161;
    public static final int TURKISH_CHARSET = 162;
    public static final int VIETNAMESE_CHARSET = 163;
    public static final int ARABIC_CHARSET = 178;
    public static final int HEBREW_CHARSET = 177;
    public static final int BALTIC_CHARSET = 186;
    public static final int RUSSIAN_CHARSET = 204;
    public static final int THAI_CHARSET = 222;
    public static final int EASTEUROPE_CHARSET = 238;
    public static final int OEM_CHARSET = 255;

    public static final int OUT_DEFAULT_PRECIS = 0;
    public static final int OUT_STRING_PRECIS = 1;
    public static final int OUT_CHARACTER_PRECIS = 2;
    public static final int OUT_STROKE_PRECIS = 3;
    public static final int OUT_TT_PRECIS = 4;
    public static final int OUT_DEVICE_PRECIS = 5;
    public static final int OUT_RASTER_PRECIS = 6;
    public static final int OUT_TT_ONLY_PRECIS = 7;
    public static final int OUT_OUTLINE_PRECIS = 8;
    public static final int OUT_SCREEN_OUTLINE_PRECIS = 9; 

    public static final int CLIP_DEFAULT_PRECIS = 0;
    public static final int CLIP_CHARACTER_PRECIS = 1;
    public static final int CLIP_STROKE_PRECIS = 2;
    public static final int CLIP_MASK = 15;
    public static final int CLIP_LH_ANGLES = 16;
    public static final int CLIP_TT_ALWAYS = 32;
    public static final int CLIP_EMBEDDED = 128;

    public static final int DEFAULT_QUALITY = 0;
    public static final int DRAFT_QUALITY = 1;
    public static final int PROOF_QUALITY = 2;
    public static final int NONANTIALIASED_QUALITY = 3;
    public static final int ANTIALIASED_QUALITY = 4;
    public static final int CLEARTYPE_QUALITY = 5; // Windows XP only

    public static final int DEFAULT_PITCH = 0;
    public static final int FIXED_PITCH = 1;
    public static final int VARIABLE_PITCH = 2;

    public static final int FF_DONTCARE = 0;
    public static final int FF_ROMAN = 16;
    public static final int FF_SWISS = 32;
    public static final int FF_MODERN = 48;
    public static final int FF_SCRIPT = 64;
    public static final int FF_DECORATIVE = 80;
    
	public int getHeight();
	
	public int getWidth();
	
	public int getEscapement();
	
	public int getOrientation();
	
	public int getWeight();
	
	public boolean isItalic();
	
	public boolean isUnderlined();
	
	public boolean isStrikedOut();
	
	public int getCharset();
	
	public int getOutPrecision();
	
	public int getClipPrecision();
	
	public int getQuality();
	
	public int getPitchAndFamily();
	
	public String getFaceName();
}
 public interface GdiObject {
}
 public interface GdiPalette extends GdiObject {
	public int getVersion();
	public int[] getEntries();
}
 public interface GdiPatternBrush extends GdiObject {
	public byte[] getPattern();
}
 public interface GdiPen extends GdiObject {
    public static final int PS_SOLID = 0;
    public static final int PS_DASH = 1;
    public static final int PS_DOT = 2;
    public static final int PS_DASHDOT = 3;
    public static final int PS_DASHDOTDOT = 4;
    public static final int PS_NULL = 5;
    public static final int PS_INSIDEFRAME = 6;
    
    public int getStyle();
    public int getWidth();
    public int getColor();
}
 public interface GdiRegion extends GdiObject {	
	public static final int NULLREGION = 1;
	public static final int SIMPLEREGION	 = 2;
	public static final int COMPLEXREGION = 3;
	public static final int ERROR = 0;
}
 public final class GdiUtils {
	public static String convertString(byte[] chars, int charset) {
		String str = null;

		int length = 0;
		while (length < chars.length && chars[length] != 0) {
			length++;
		}
		
		try {
			str = new String(chars, 0, length, getCharset(charset));
		} catch (UnsupportedEncodingException e) {
			try {
				str = new String(chars, 0, length, "US-ASCII");
			} catch (UnsupportedEncodingException e2) {
				throw new IllegalStateException(e2);
			}
		}
		return str;
	}
	
	public static String getCharset(int charset) {
		switch (charset) {
		case GdiFont.ANSI_CHARSET:
			return "Cp1252";
		case GdiFont.SYMBOL_CHARSET:
			return "ISO-8859-1";
		case GdiFont.MAC_CHARSET:
			return "MacRoman";
		case GdiFont.SHIFTJIS_CHARSET:
			return "MS932";
		case GdiFont.HANGUL_CHARSET:
			return "MS949";
		case GdiFont.JOHAB_CHARSET:
			return "Johab";
		case GdiFont.GB2312_CHARSET:
			return "MS936";
		case GdiFont.CHINESEBIG5_CHARSET:
			return "MS950";
		case GdiFont.GREEK_CHARSET:
			return "Cp1253";
		case GdiFont.TURKISH_CHARSET:
			return "Cp1254";
		case GdiFont.VIETNAMESE_CHARSET:
			return "Cp1258";
		case GdiFont.HEBREW_CHARSET:
			return "Cp1255";
		case GdiFont.ARABIC_CHARSET:
			return "Cp1256";
		case GdiFont.BALTIC_CHARSET:
			return "Cp1257";
		case GdiFont.RUSSIAN_CHARSET:
			return "Cp1251";
		case GdiFont.THAI_CHARSET:
			return "MS874";
		case GdiFont.EASTEUROPE_CHARSET:
			return "Cp1250";
		case GdiFont.OEM_CHARSET:
			return "Cp1252";
		default:
			return "Cp1252";
		}
	}
	
	public static String getLanguage(int charset) {
		switch (charset) {
		case GdiFont.ANSI_CHARSET:
			return "en";
		case GdiFont.SYMBOL_CHARSET:
			return "en";
		case GdiFont.MAC_CHARSET:
			return "en";
		case GdiFont.SHIFTJIS_CHARSET:
			return "ja";
		case GdiFont.HANGUL_CHARSET:
			return "ko";
		case GdiFont.JOHAB_CHARSET:
			return "ko";
		case GdiFont.GB2312_CHARSET:
			return "zh-CN";
		case GdiFont.CHINESEBIG5_CHARSET:
			return "zh-TW";
		case GdiFont.GREEK_CHARSET:
			return "el";
		case GdiFont.TURKISH_CHARSET:
			return "tr";
		case GdiFont.VIETNAMESE_CHARSET:
			return "vi";
		case GdiFont.HEBREW_CHARSET:
			return "iw";
		case GdiFont.ARABIC_CHARSET:
			return "ar";
		case GdiFont.BALTIC_CHARSET:
			return "bat";
		case GdiFont.RUSSIAN_CHARSET:
			return "ru";
		case GdiFont.THAI_CHARSET:
			return "th";
		case GdiFont.EASTEUROPE_CHARSET:
			return null;
		case GdiFont.OEM_CHARSET:
			return null;
		default:
			return null;
		}		
	}
	
	private static int[][] FBA_SHIFT_JIS = {{0x81, 0x9F}, {0xE0, 0xFC}};
	private static int[][] FBA_HANGUL_CHARSET = {{0x80, 0xFF}};
	private static int[][] FBA_JOHAB_CHARSET = {{0x80, 0xFF}};
	private static int[][] FBA_GB2312_CHARSET = {{0x80, 0xFF}};
	private static int[][] FBA_CHINESEBIG5_CHARSET = {{0xA1, 0xFE}};
	
	public static int[][] getFirstByteArea(int charset) {
		switch (charset) {
		case GdiFont.SHIFTJIS_CHARSET:
			return FBA_SHIFT_JIS;
		case GdiFont.HANGUL_CHARSET:
			return FBA_HANGUL_CHARSET;
		case GdiFont.JOHAB_CHARSET:
			return FBA_JOHAB_CHARSET;
		case GdiFont.GB2312_CHARSET:
			return FBA_GB2312_CHARSET;
		case GdiFont.CHINESEBIG5_CHARSET:
			return FBA_CHINESEBIG5_CHARSET;
		default:
			return null;
		}
	}

	public static int[] fixTextDx(int charset, byte[] chars, int[] dx) {
		if (dx == null || dx.length == 0) {
			return null;
		}

		int[][] area = GdiUtils.getFirstByteArea(charset);
		if (area == null) {
			return dx;
		}

		int n = 0;
		boolean skip = false;

		for (int i = 0; i < chars.length && i < dx.length; i++) {
			int c = (0xFF & chars[i]);

			if (skip) {
				dx[n - 1] += dx[i];
				skip = false;
				continue;
			}

			for (int j = 0; j < area.length; j++) {
				if (area[j][0] <= c && c <= area[j][1]) {
					skip = true;
					break;
				}
			}

			dx[n++] = dx[i];
		}

		int[] ndx = new int[n];
		System.arraycopy(dx, 0, ndx, 0, n);

		return ndx;
	}
}
 public class Point {
	public int x;
	public int y;
	
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}

	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Point other = (Point) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}

	public String toString() {
		return "Point [x=" + x + ", y=" + y + "]";
	}
}
 public class Size {
	public int width;
	public int height;
	
	public Size(int width, int height) {
		this.width = width;
		this.height = height;
	}

	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + height;
		result = prime * result + width;
		return result;
	}

	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Size other = (Size) obj;
		if (height != other.height)
			return false;
		if (width != other.width)
			return false;
		return true;
	}

	public String toString() {
		return "Size [width=" + width + ", height=" + height + "]";
	}
}
 public class Base64 {
	private static final char[] ENCODE_DATA = {
		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
		'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
		'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
		'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
		'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
		'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
		'w', 'x', 'y', 'z', '0', '1', '2', '3',
		'4', '5', '6', '7', '8', '9', '+', '/' 
	};

	public static String encode(byte[] data) {
		char[] buffer = null;

		if (data.length % 3 == 0) {
			buffer = new char[data.length / 3 * 4];
		} else {
			buffer = new char[(data.length / 3 + 1) * 4];
		}

		int buf = 0;
		for (int i = 0; i < data.length; i++) {
			switch (i % 3) {
				case 0 :
					buffer[i / 3 * 4] = ENCODE_DATA[(data[i] & 0xFC) >> 2];
					buf = (data[i] & 0x03) << 4;
					if (i + 1 == data.length) {
						buffer[i / 3 * 4 + 1] = ENCODE_DATA[buf];
						buffer[i / 3 * 4 + 2] = '=';
						buffer[i / 3 * 4 + 3] = '=';
					}
					break;
				case 1 :
					buf += (data[i] & 0xF0) >> 4;
					buffer[i / 3 * 4 + 1] = ENCODE_DATA[buf];
					buf = (data[i] & 0x0F) << 2;
					if (i + 1 == data.length) {
						buffer[i / 3 * 4 + 2] = ENCODE_DATA[buf];
						buffer[i / 3 * 4 + 3] = '=';
					}
					break;
				case 2 :
					buf += (data[i] & 0xC0) >> 6;
					buffer[i / 3 * 4 + 2] = ENCODE_DATA[buf];
					buffer[i / 3 * 4 + 3] = ENCODE_DATA[data[i] & 0x3F];
					break;
			}
		}

		return new String(buffer);
	}
}
 public class ImageUtil {
	private static Converter converter;

	static {
		if ("Production".equals(System.getProperty("com.google.appengine.runtime.environment"))) {
			converter = new GAEConverter();
		} else if ("The Android Project".equals(System.getProperty("java.specification.vendor"))) {
			converter = new AndroidConverter();
		} else {
			try {
				Class.forName("javax.imageio.ImageIO");
				converter = new ImageIOConverter();
			} catch (ClassNotFoundException e2) {
				// no handle
			}
		}
	}

	public static byte[] convert(byte[] image, String destType, boolean reverse) {
		if (converter == null) {
			throw new UnsupportedOperationException("Image Conversion API(Image IO or GAE Image API) is missing.");
		}
		return converter.convert(image, destType, reverse);
	}

	private static interface Converter {
		public byte[] convert(byte[] image, String destType, boolean reverse);
	}

	private static class ImageIOConverter implements Converter {
		public byte[] convert(byte[] image, String destType, boolean reverse) {
			if (destType == null) {
				throw new IllegalArgumentException("dest type is null.");
			} else {
				destType = destType.toLowerCase();
			}

			byte[] outimage = null;
			try {
				// convert to 24bit color
				BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(image));
				BufferedImage dst = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
				ColorConvertOp colorConvert = new ColorConvertOp(dst.getColorModel().getColorSpace(), null);
				colorConvert.filter(bufferedImage, dst);
				bufferedImage = dst;

				if (reverse) {
					DataBuffer srcData = bufferedImage.getRaster().getDataBuffer();
					BufferedImage dstImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), bufferedImage.getType());
					DataBuffer dstData = dstImage.getRaster().getDataBuffer();
					int lineSize = bufferedImage.getWidth() * bufferedImage.getColorModel().getPixelSize() / 8;
					for (int h = 0, k = bufferedImage.getHeight() - 1; h < bufferedImage.getHeight(); h++, k--) {
						for (int j = 0; j < lineSize; j++) {
							dstData.setElem(h * lineSize + j, srcData.getElem(k * lineSize + j));
						}
					}
					bufferedImage = dstImage;
				}

				ByteArrayOutputStream out = new ByteArrayOutputStream();
				ImageIO.write(bufferedImage, destType, out);
				outimage = out.toByteArray();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return outimage;
		}
	}

	private static class GAEConverter implements Converter {
		public byte[] convert(byte[] image, String destType, boolean reverse) {
			if (destType == null) {
				throw new IllegalArgumentException("dest type is null.");
			} else {
				destType = destType.toLowerCase();
			}

			ImagesService.OutputEncoding encoding = null;
			if ("png".equals(destType)) {
				encoding = OutputEncoding.PNG;
			} else if ("jpeg".equals(destType)) {
				encoding = OutputEncoding.JPEG;
			} else {
				throw new UnsupportedOperationException("unsupported image encoding: " + destType);
			}

			ImagesService imagesService = ImagesServiceFactory.getImagesService();
			Image bmp = ImagesServiceFactory.makeImage(image);

			Transform t = (reverse) ? ImagesServiceFactory.makeVerticalFlip() : ImagesServiceFactory.makeCompositeTransform();
			return imagesService.applyTransform(t, bmp, encoding).getImageData();
		}
	}
	
	private static class AndroidConverter implements Converter {
		public byte[] convert(byte[] image, String destType, boolean reverse) {
			Bitmap bmp = BitmapFactory.decodeByteArray(image, 0, image.length);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			if ("png".equals(destType)) {
				bmp.compress(CompressFormat.PNG, 100, out);
			} else if ("jpeg".equals(destType)) {
				bmp.compress(CompressFormat.JPEG, 100, out);
			} else {
				throw new UnsupportedOperationException("unsupported image encoding: " + destType);
			}
			bmp.recycle();
			return out.toByteArray();
		}
	}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import net.arnx.wmf2svg.gdi.Gdi;
import net.arnx.wmf2svg.gdi.GdiBrush;
import net.arnx.wmf2svg.gdi.GdiFont;
import net.arnx.wmf2svg.gdi.GdiObject;
import net.arnx.wmf2svg.gdi.GdiPalette;
import net.arnx.wmf2svg.gdi.GdiPatternBrush;
import net.arnx.wmf2svg.gdi.GdiPen;
import net.arnx.wmf2svg.gdi.GdiRegion;
import net.arnx.wmf2svg.gdi.GdiUtils;
import net.arnx.wmf2svg.gdi.Point;
import net.arnx.wmf2svg.gdi.Size;
import net.arnx.wmf2svg.util.Base64;
import net.arnx.wmf2svg.util.ImageUtil;
			double ey = ry * Math.sin(ea);

			double a = Math.atan2((ex-sx) * (-sy) - (ey-sy) * (-sx), (ex-sx) * (-sx) + (ey-sy) * (-sy));

			elem = doc.createElement("path");
			elem.setAttribute("d", "M " + dc.toAbsoluteX(sx + cx) + "," + dc.toAbsoluteY(sy + cy)
					+ " A " + dc.toRelativeX(rx)  + "," + dc.toRelativeY(ry)
					+ " 0 " + (a > 0 ? "1" : "0") + " 0"
					+ " " + dc.toAbsoluteX(ex + cx) + "," + dc.toAbsoluteY(ey + cy));
		}

		if (dc.getPen() != null) {
			elem.setAttribute("class", getClassString(dc.getPen()));
		}
		elem.setAttribute("fill", "none");
		parentNode.appendChild(elem);
	}

	public void bitBlt(byte[] image, int dx, int dy, int dw, int dh,
			int sx, int sy, long rop) {
		bmpToSvg(image, dx, dy, dw, dh, sx, sy, dw, dh, Gdi.DIB_RGB_COLORS, rop);
	}

	public void chord(int sxr, int syr, int exr, int eyr, int sxa, int sya,
			int exa, int eya) {
		double rx = Math.abs(exr - sxr) / 2.0;
		double ry = Math.abs(eyr - syr) / 2.0;
		if (rx <= 0 || ry <= 0) return;

		double cx = Math.min(sxr, exr) + rx;
		double cy = Math.min(syr, eyr) + ry;

		Element elem = null;
		if (sxa == exa && sya == eya) {
			if (rx == ry) {
				elem = doc.createElement("circle");
				elem.setAttribute("cx", "" + dc.toAbsoluteX(cx));
				elem.setAttribute("cy", "" + dc.toAbsoluteY(cy));
				elem.setAttribute("r", "" + dc.toRelativeX(rx));
			} else {
				elem = doc.createElement("ellipse");
				elem.setAttribute("cx", "" + dc.toAbsoluteX(cx));
				elem.setAttribute("cy", "" + dc.toAbsoluteY(cy));
				elem.setAttribute("rx", "" + dc.toRelativeX(rx));
				elem.setAttribute("ry", "" + dc.toRelativeY(ry));
			}
		} else {
			double sa = Math.atan2((sya - cy) * rx, (sxa - cx) * ry);
			double sx = rx * Math.cos(sa);
			double sy = ry * Math.sin(sa);

			double ea = Math.atan2((eya - cy) * rx, (exa - cx) * ry);
			double ex = rx * Math.cos(ea);
			double ey = ry * Math.sin(ea);

			double a = Math.atan2((ex-sx) * (-sy) - (ey-sy) * (-sx), (ex-sx) * (-sx) + (ey-sy) * (-sy));

			elem = doc.createElement("path");
			elem.setAttribute("d", "M " + dc.toAbsoluteX(sx + cx) + "," + dc.toAbsoluteY(sy + cy)
					+ " A " + dc.toRelativeX(rx)  + "," + dc.toRelativeY(ry)
					+ " 0 " + (a > 0 ? "1" : "0") + " 0"
					+ " " + dc.toAbsoluteX(ex + cx) + "," + dc.toAbsoluteY(ey + cy) + " Z");
		}

		if (dc.getPen() != null || dc.getBrush() != null) {
			elem.setAttribute("class", getClassString(dc.getPen(), dc.getBrush()));
			if (dc.getBrush() != null
					&& dc.getBrush().getStyle() == GdiBrush.BS_HATCHED) {
				String id = "pattern" + (patternNo++);
				elem.setAttribute("fill", "url(#" + id + ")");
				defsNode.appendChild(dc.getBrush().createFillPattern(id));
			}
		}

		parentNode.appendChild(elem);
	}

	public GdiBrush createBrushIndirect(int style, int color, int hatch) {
		SvgBrush brush = new SvgBrush(this, style, color, hatch);
		if (!nameMap.containsKey(brush)) {
			String name = "brush" + (brushNo++);
			nameMap.put(brush, name);
			styleNode.appendChild(brush.createTextNode(name));
		}
		return brush;
	}

	public GdiFont createFontIndirect(int height, int width, int escapement,
			int orientation, int weight, boolean italic, boolean underline,
			boolean strikeout, int charset, int outPrecision,
			int clipPrecision, int quality, int pitchAndFamily, byte[] faceName) {
		SvgFont font = new SvgFont(this, height, width, escapement,
				orientation, weight, italic, underline, strikeout, charset,
				outPrecision, clipPrecision, quality, pitchAndFamily, faceName);
		if (!nameMap.containsKey(font)) {
			String name = "font" + (fontNo++);
			nameMap.put(font, name);
			styleNode.appendChild(font.createTextNode(name));
		}
		return font;
	}

	public GdiPalette createPalette(int version, int[] entries) {
		return new SvgPalette(this, version, entries);
	}

	public GdiPatternBrush createPatternBrush(byte[] image) {
		return new SvgPatternBrush(this, image);
	}

	public GdiPen createPenIndirect(int style, int width, int color) {
		SvgPen pen = new SvgPen(this, style, width, color);
		if (!nameMap.containsKey(pen)) {
			String name = "pen" + (penNo++);
			nameMap.put(pen, name);
			styleNode.appendChild(pen.createTextNode(name));
		}
		return pen;
	}

	public GdiRegion createRectRgn(int left, int top, int right, int bottom) {