1 5 package org.riotfamily.common.util; 6 7 import java.io.*; 8 import java.util.zip.*; 9 10 import org.apache.commons.logging.Log; 11 import org.apache.commons.logging.LogFactory; 12 13 16 public class FlashInfo { 17 18 protected Log log = LogFactory.getLog(getClass()); 19 20 public static String COMPRESSED = "compressed"; 21 22 public static String UNCOMPRESSED = "uncompressed"; 23 24 private String signature; 25 26 private String compressionType; 27 28 private int version; 29 30 private long size; 31 32 private int nbits; 33 34 private int xmax; 35 36 private int ymax; 37 38 private int width; 39 40 private int height; 41 42 private int frameRate; 43 44 private int frameCount; 45 46 private boolean valid = false; 47 48 public FlashInfo(File file) throws IOException { 49 valid = parseHeader(file); 50 } 51 52 public boolean parseHeader(File file) throws IOException { 53 log.debug("Parsing file '" + file + "'..."); 54 55 FileInputStream fis = null; 56 byte[] temp = new byte[(int) file.length()]; 57 byte[] swf = null; 58 59 fis = new FileInputStream(file); 60 fis.read(temp); 61 fis.close(); 62 63 if (!isSWF(temp)) { 64 log.debug("The file does not appear to be a swf - incorrect file signature"); 65 return false; 66 } 67 else { 68 signature = "" + (char) temp[0] + (char) temp[1] + (char) temp[2]; 69 } 70 71 if (isCompressed(temp[0])) { 72 try { 73 swf = decompress(temp); 74 } 75 catch (DataFormatException dfe) { 76 log.warn("The file appears to be compressed, but decompression failed: " 77 + dfe.getMessage()); 78 79 return false; 80 } 81 compressionType = FlashInfo.COMPRESSED; 82 } 83 else { 84 swf = temp; 85 compressionType = FlashInfo.UNCOMPRESSED; 86 } 87 88 version = swf[3]; 90 91 size = readSize(swf); 93 94 96 nbits = ((swf[8] & 0xff) >> 3); 97 98 PackedBitObj pbo = readPackedBits(swf, 8, 5, nbits); 99 100 PackedBitObj pbo2 = readPackedBits(swf, pbo.nextByteIndex, pbo.nextBitIndex, nbits); 101 102 PackedBitObj pbo3 = readPackedBits(swf, pbo2.nextByteIndex, pbo2.nextBitIndex, nbits); 103 104 PackedBitObj pbo4 = readPackedBits(swf, pbo3.nextByteIndex, pbo3.nextBitIndex, nbits); 105 106 xmax = pbo2.value; 107 ymax = pbo4.value; 108 109 width = convertTwipsToPixels(xmax); 110 height = convertTwipsToPixels(ymax); 111 112 int bytePointer = pbo4.nextByteIndex + 2; 113 114 frameRate = swf[bytePointer]; 115 bytePointer++; 116 117 int fc1 = swf[bytePointer] & 0xFF; 118 bytePointer++; 119 120 int fc2 = swf[bytePointer] & 0xFF; 121 bytePointer++; 122 123 frameCount = (fc2 << 8) + fc1; 124 125 log.debug("signature: " + getSignature()); 126 log.debug("version: " + getVersion()); 127 log.debug("compression: " + getCompressionType()); 128 log.debug("size: " + getSize()); 129 log.debug("nbits: " + getNbits()); 130 log.debug("xmax: " + getXmax()); 131 log.debug("ymax: " + getYmax()); 132 log.debug("width: " + getWidth()); 133 log.debug("height: " + getHeight()); 134 log.debug("frameRate: " + getFrameRate()); 135 log.debug("frameCount: " + getFrameCount()); 136 137 return true; 138 } 139 140 public void read(byte[] output, byte[] input, int offset) { 141 System.arraycopy(input, offset, output, 0, output.length - offset); 142 } 143 144 public int readSize(byte[] bytes) { 145 int size = 0; 146 for (int i = 0; i < 4; i++) { 147 size = (size << 8) + bytes[i + 4]; 148 } 149 150 size = Integer.reverseBytes(size); 151 152 return size; 153 } 154 155 public PackedBitObj readPackedBits(byte[] bytes, int byteMarker, int bitMarker, int length) { 156 int total = 0; 157 int shift = 7 - bitMarker; 158 int counter = 0; 159 int bitIndex = bitMarker; 160 int byteIndex = byteMarker; 161 162 while (counter < length) { 163 164 for (int i = bitMarker; i < 8; i++) { 165 int bit = ((bytes[byteMarker] & 0xff) >> shift) & 1; 166 total = (total << 1) + bit; 167 bitIndex = i; 168 shift--; 169 counter++; 170 if (counter == length) { 171 break; 172 } 173 } 174 byteIndex = byteMarker; 175 byteMarker++; 176 bitMarker = 0; 177 shift = 7; 178 } 179 return new PackedBitObj(bitIndex, byteIndex, total); 180 } 181 182 public int convertTwipsToPixels(int twips) { 183 return twips / 20; 184 } 185 186 public int convertPixelsToTwips(int pixels) { 187 return pixels * 20; 188 } 189 190 public boolean isSWF(byte[] signature) { 191 String sig = "" + (char) signature[0] + (char) signature[1] + (char) signature[2]; 192 193 if (sig.equals("FWS") || sig.equals("CWS")) { 194 return true; 195 } 196 else { 197 return false; 198 } 199 } 200 201 public boolean isCompressed(int firstByte) { 202 if (firstByte == 67) { 203 return true; 204 } 205 else { 206 return false; 207 } 208 } 209 210 public byte[] compress(byte[] bytes, int length) { 211 212 byte[] compressed = null; 213 byte[] temp = new byte[length]; 214 215 Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION); 216 deflater.setInput(bytes, 8, length - 8); 217 deflater.finish(); 218 219 int compressedLength = deflater.deflate(temp); 220 221 compressed = new byte[compressedLength + 8]; 222 223 System.arraycopy(bytes, 0, compressed, 0, 8); 225 226 System.arraycopy(temp, 0, compressed, 8, compressedLength); 229 230 temp[0] = 67; 232 233 int bl = bytes.length; 236 temp[4] = (byte) (bl & 0x000000FF); 237 temp[5] = (byte) ((bl & 0x0000FF00) >> 8); 238 temp[6] = (byte) ((bl & 0x00FF0000) >> 16); 239 temp[7] = (byte) ((bl & 0xFF000000) >> 24); 240 241 return compressed; 242 } 243 244 public byte[] decompress(byte[] bytes) throws DataFormatException { 245 int size = readSize(bytes); 246 247 byte[] uncompressed = new byte[size]; 248 System.arraycopy(bytes, 0, uncompressed, 0, 8); 249 250 Inflater inflater = new Inflater(); 251 inflater.setInput(bytes, 8, bytes.length - 8); 252 inflater.inflate(uncompressed, 8, size - 8); 253 inflater.finished(); 254 255 uncompressed[0] = 70; 257 258 return uncompressed; 259 } 260 261 262 265 public int getFrameCount() { 266 return frameCount; 267 } 268 269 272 public int getFrameRate() { 273 return frameRate; 274 } 275 276 279 public int getNbits() { 280 return nbits; 281 } 282 283 286 public String getSignature() { 287 return signature; 288 } 289 290 293 public long getSize() { 294 return size; 295 } 296 297 300 public int getVersion() { 301 return version; 302 } 303 304 307 public int getXmax() { 308 return xmax; 309 } 310 311 314 public int getYmax() { 315 return ymax; 316 } 317 318 321 public String getCompressionType() { 322 return compressionType; 323 } 324 325 328 public int getHeight() { 329 return height; 330 } 331 332 335 public int getWidth() { 336 return width; 337 } 338 339 342 public boolean isValid() { 343 return valid; 344 } 345 346 347 350 public class PackedBitObj { 351 352 public int bitIndex = 0; 353 354 public int byteIndex = 0; 355 356 public int value = 0; 357 358 public int nextBitIndex = 0; 359 360 public int nextByteIndex = 0; 361 362 public int nextByteBoundary = 0; 363 364 370 public PackedBitObj(int bitMarker, int byteMarker, int decimalValue) { 371 bitIndex = bitMarker; 372 byteIndex = byteMarker; 373 value = decimalValue; 374 nextBitIndex = bitMarker; 375 376 if (bitMarker < 7) { 377 nextBitIndex++; 378 nextByteIndex = byteMarker; 379 nextByteBoundary = byteMarker++; 380 } 381 else { 382 nextBitIndex = 0; 383 nextByteIndex++; 384 nextByteBoundary = nextByteIndex; 385 } 386 } 387 388 } 389 390 } | Popular Tags |