exifdata.java

来自「很棒的web服务器源代码」· Java 代码 · 共 247 行

JAVA
247
字号
// Exif.java// $Id: ExifData.java,v 1.1 2003/07/23 12:08:02 ylafon Exp $// Copyright (c) 2003 Norman Walsh// Please first read the full copyright statement in file COPYRIGHTpackage org.w3c.tools.jpeg;import java.util.Hashtable;/** * An internal API for decoding EXIF data. * * <p>This class identifies a byte array as valid EXIF and provides methods * for converting the internal representation of types to equivalent Java  * types. * </p> * * <p>This is a separate class in order to facilitate writing decoders for * unknown fields.</p> * * <p>Special note: string values are %-encoded to protect the caller from  * values that might not be legitimate UTF-8 strings.</p> * * <p><b>Bugs:</b></p> * <p>The EXIF format includes unsigned integers which aren't directly * available in Java. Unless I'm mistaken, they'd have to be turned into * longs. But that would * be inconvenient in other APIs. For the moment, I'm just treating them all as * signed. I've never seen an EXIF unsigned value too large to represent * in a Java int.</p> * * @version $Revision: 1.1 $ * @author  Norman Walsh * @see Exif */public class ExifData {    public static final int bytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};    public static final int NUM_FORMATS   = 12;    public static final int FMT_BYTE      =  1;    public static final int FMT_STRING    =  2;    public static final int FMT_USHORT    =  3;    public static final int FMT_ULONG     =  4;    public static final int FMT_URATIONAL =  5;    public static final int FMT_SBYTE     =  6;    public static final int FMT_UNDEFINED =  7;    public static final int FMT_SSHORT    =  8;    public static final int FMT_SLONG     =  9;    public static final int FMT_SRATIONAL = 10;    public static final int FMT_SINGLE    = 11;    public static final int FMT_DOUBLE    = 12;    private byte[] data = null;    private boolean intelOrder = false;    public ExifData(byte[] exifData) {	String dataStr = new String(exifData);	if (exifData.length <= 4 || !"Exif".equals(dataStr.substring(0, 4))) {	    // Not really EXIF data	    return;	}	String byteOrderMarker = dataStr.substring(6, 8);	if ("II".equals(byteOrderMarker)) {	    intelOrder = true;	} else if ("MM".equals(byteOrderMarker)) {	    intelOrder = false;	} else {	    // bogus!	    System.err.println("Bogus byte order in EXIF data.");	    return;	}	data = exifData;	int checkValue = get16u(8);	if (checkValue != 0x2a) {	    data = null;	    System.err.println("Check value fails: 0x" + 			       Integer.toHexString(checkValue));	    return;	}    }    public boolean isExifData() {	return (data != null);    }    public int get16s(int offset) {	if (data == null) {	    return 0;	}	int hi, lo;	if (intelOrder) {	    hi = data[offset+1];	    lo = data[offset];	} else {	    hi = data[offset];	    lo = data[offset+1];	}	lo = lo & 0xFF;	hi = hi & 0xFF;	return (hi << 8) + lo;    }    public int get16u(int offset) {	if (data == null) {	    return 0;	}	int value = get16s(offset);	value = value & 0xFFFF;	return value;    }    public int get32s(int offset) {	if (data == null) {	    return 0;	}	int n1, n2, n3, n4;	if (intelOrder) {	    n1 = data[offset+3] & 0xFF;	    n2 = data[offset+2] & 0xFF;	    n3 = data[offset+1] & 0xFF;	    n4 = data[offset] & 0xFF;	} else {	    n1 = data[offset] & 0xFF;	    n2 = data[offset+1] & 0xFF;	    n3 = data[offset+2] & 0xFF;	    n4 = data[offset+3] & 0xFF;	}	int value = (n1 << 24) + (n2 << 16) + (n3 << 8) + n4;	return value;    }    public int get32u(int offset) {	if (data == null) {	    return 0;	}	// I don't know how to represent an unsigned in Java!	return get32s(offset);    }    public byte[] getBytes(int offset, int length) {	if (data == null || length == 0) {	    return null;	}	byte[] raw = new byte[length];	for (int count = offset; length > 0; count++, length--) {	    raw[count-offset] = data[count];	}	return raw;    }    public String getString(int offset, int length) {	return getString(offset, length, true);    }    public String getUndefined(int offset, int length) {	return getString(offset, length, false);    }    protected String getString(int offset, int length, 			       boolean nullTerminated) {	if (data == null) {	    return "";	}	String result = "";	for (int count = offset;	     (length > 0) && (!nullTerminated || data[count] != 0);	     count++, length--) {	    short ub = data[count];	    ub = (short) (ub & 0xFF);	    String ch = "" + (char) ub;	    if ((ub == '%') || (ub < ' ') || (ub > '~')) {		ch = Integer.toHexString((char) ub);		if (ch.length() < 2) {		    ch = "0" + ch;		}		ch = "%" + ch;	    }	    result += ch;	}	return result;    }    public double convertAnyValue(int format, int offset) {	if (data == null) {	    return 0.0;	}	double value = 0.0;	switch(format){	case FMT_SBYTE:	    value = data[offset];	    break;	case FMT_BYTE:	    int iValue = data[offset];	    iValue = iValue & 0xFF;	    value = iValue;	    break;	case FMT_USHORT:	    value = get16u(offset);	    break;	case FMT_ULONG:	    value = get32u(offset);	    break;	case FMT_URATIONAL:	case FMT_SRATIONAL:	    int num = get32s(offset);	    int den = get32s(offset+4);	    if (den == 0) {		value = 0;	    } else {		value = (double) num / (double) den;	    }	    break;	case FMT_SSHORT:	    value = get16s(offset);	    break;	case FMT_SLONG:	    value = get32s(offset);	    break;	default:	    System.err.println("Unexpected number format: " + format);	}	return value;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?