1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
| public enum ImageType { TGA, BMP, JPG, GIF, PNG; }
public class ImageMetaData { public final ImageType type; public final int width; public final int height;
public ImageMetaData(ImageType type, int width, int height) { this.type = type; this.width = width; this.height = height; }
public Dimension getDimension() { return new Dimension(this.width, this.height); }
public String toString() { return type.name() + ":" + this.width + "x" + this.height; } }
public static Dimension getImageSize(InputStream in) throws IOException { ImageMetaData meta = getImageTypeAndSize(in); if(meta == null) return null; return new Dimension(meta.width, meta.height); }
public static ImageMetaData getImageTypeAndSize(InputStream in) throws IOException { DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
try { int header = dis.readUnsignedShort();
if (header == 0x8950) { dis.readFully(new byte[(8 - 2) + 4 + 4]); return new ImageMetaData(ImageType.PNG, dis.readInt(), dis.readInt()); }
if (header == 0xffd8) { while (true) { int marker = dis.readUnsignedShort();
switch (marker) { case 0xffd8: case 0xffd0: case 0xffd1: case 0xffd2: case 0xffd3: case 0xffd4: case 0xffd5: case 0xffd6: case 0xffd7: case 0xffd9: break;
case 0xffdd: dis.readUnsignedShort(); break;
case 0xffe0: case 0xffe1: case 0xffe2: case 0xffe3: case 0xffe4: case 0xffe5: case 0xffe6: case 0xffe7: case 0xffe8: case 0xffe9: case 0xffea: case 0xffeb: case 0xffec: case 0xffed: case 0xffee: case 0xffef: case 0xfffe: case 0xffdb: case 0xffc4: case 0xffda: dis.readFully(new byte[dis.readUnsignedShort() - 2]); break;
case 0xffc0: case 0xffc2: dis.readUnsignedShort(); dis.readByte(); int height = dis.readUnsignedShort(); int width = dis.readUnsignedShort(); return new ImageMetaData(ImageType.JPG, width, height);
default: throw new IllegalStateException("invalid jpg marker: " + Integer.toHexString(marker)); } } } else if (header == 0x424D) { dis.readFully(new byte[16]);
int w = PrimIO.swap32(dis.readInt()); int h = PrimIO.swap32(dis.readInt()); return new ImageMetaData(ImageType.BMP, w, h); } else if (header == (('G' << 8) | ('I' << 0))) { dis.readFully(new byte[4]); int w = PrimIO.swap16(dis.readUnsignedShort()); int h = PrimIO.swap16(dis.readUnsignedShort()); return new ImageMetaData(ImageType.GIF, w, h); } else { byte[] tgaRemainingHeader = new byte[18 - 2]; try { dis.readFully(tgaRemainingHeader); } catch (EOFException exc) { return null; }
try { if (tgaRemainingHeader[2 - 2] != 2) throw new IllegalStateException(); int w = 0, h = 0; w |= (tgaRemainingHeader[12 - 2] & 0xFF) << 0; w |= (tgaRemainingHeader[13 - 2] & 0xFF) << 8; h |= (tgaRemainingHeader[14 - 2] & 0xFF) << 0; h |= (tgaRemainingHeader[15 - 2] & 0xFF) << 8; if ((w | h) < 0) throw new IllegalStateException();
boolean alpha; if (tgaRemainingHeader[16 - 2] == 24) alpha = false; else if (tgaRemainingHeader[16 - 2] == 32) alpha = true; else throw new IllegalStateException(); if (tgaRemainingHeader[17 - 2] != ((alpha ? 8 : 0) & 15)) throw new IllegalStateException();
return new ImageMetaData(ImageType.TGA, w, h); } catch (IllegalStateException exc) { return null; } } } finally { dis.close(); } } |