As someone already said, you can grab that data from the swf header.

I've done this in C# / .NET and I've just wrote a quick and dirty "port" of
the header parsing part to AS 3.0. Probably there's room for optimization
but as a proof of concept I think it's ok. Also, the code could use some
clean-up and the SwfRect part is based on an API different from ByteArray,
so basically I was not using readByte() and such but calculating offsets "by
hand", which could be avoided.

So, the flow would be:

1) Load the swf as binary
2) Parse the headers to get the info you're looking for
3) Use the loadBytes method from the Loader class to load the swf from the
bytearray you already have loaded.

I'm pasting the sample code in this email, but you could see it more nicely
formatted here:

http://pastebin.be/14115   (SwfHeader class)
http://pastebin.be/14116   (Mainclass)

Cheers
Juan Pablo Califano

package {
 import flash.display.Sprite;
 import flash.net.URLLoader;
 import flash.net.URLLoaderDataFormat;
 import flash.events.*;
 import flash.net.URLRequest;

 public class Main extends Sprite {

  private var urlLoader:URLLoader;
  private var swfHeader:SwfHeader;

  public function Main() {
   init();
   loadSwf("test_data.swf");
  // loadSwf("test_data_comp.swf");
  }

  private function init() {
   urlLoader = new URLLoader();
   urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
            urlLoader.addEventListener(Event.COMPLETE, handleComplete);
            urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
handleSecurityError);
            urlLoader.addEventListener(IOErrorEvent.IO_ERROR,
handleIoError);
  }

        private function handleComplete(event:Event):void {
            var loader:URLLoader = URLLoader(event.target);
            trace("completeHandler: " + loader.data);
   swfHeader = new SwfHeader();
   swfHeader.parse(loader.data);

        }

        private function handleSecurityError(event:SecurityErrorEvent):void
{
            trace("securityErrorHandler: " + event);
        }

        private function handleIoError(event:IOErrorEvent):void {
            trace("ioErrorHandler: " + event);
        }

  public function loadSwf(file:String):void {
   var req:URLRequest = new URLRequest(file);
   urlLoader.load(req);
  }
 }
}
///////////////////////////////////////////////////////
//////////////////////////////////////////////////////


package {
 import flash.utils.ByteArray;
 import flash.utils.Endian;

 public class SwfHeader {


  public function SwfHeader() {

  }

  public function parse(rawData:ByteArray):void {
   var signature:String = rawData.readUTFBytes(3);
   var isCompressed:Boolean;

   // this is used to uncompress swf (if necesary). It can't be uncompressed
in place
   // since the first 8 bytes are not compressed...
   var buffer:ByteArray = new ByteArray();

   if (signature == "FWS") {
    isCompressed  = false;
    rawData.position = 8;
    rawData.readBytes(buffer, 0, rawData.length - 8);
   } else if (signature == "CWS") {
    isCompressed = true;
    rawData.position = 8;
    rawData.readBytes(buffer, 0, rawData.length - 8);
    buffer.uncompress();
   } else {
    trace("not a valid SWF");
   }

   rawData.position = 4;
   rawData.endian  = Endian.LITTLE_ENDIAN;
   var fileSize:uint  = rawData.readUnsignedInt();

   buffer.position  = 0;
   var rect:SwfRect = new SwfRect();
   rect.parse(buffer);

   trace("width:"+rect.xMax);
   trace("height:"+rect.yMax);

  }
 }
}


import flash.utils.ByteArray;


internal class SwfRect {

 public var xMin:uint;
 public var xMax:uint;
 public var yMin:uint;
 public var yMax:uint;

 public function SwfRect() {

 }

 /*
 RECT:

 5 parts:
 Nbits  UB[5]  (the number of bits for storing each field)
 Xmin SB[Nbits] x
 Xmax SB[Nbits] width
 Ymin SB[Nbits] y
 Ymax SB[Nbits] height
 */
 public function parse(buffer:ByteArray):void {
  // get the first 5 bits to know the size of each field
  var fieldBitSize:int = buffer[0] >> 3;
  // total "data" bits (w/o padding): the 5 bits read plus the fieldBitSize
of each field
  var rectBitSize:int  = 5 + (fieldBitSize * 4);
  // the rect struct is padded with 0'z for byte aligning...
  rectBitSize    = rectBitSize + (8 - rectBitSize % 8);
  // divide by 8 to get the size of the rect in bytes
  var size:int   = rectBitSize / 8;

  var curOffset:uint = 0;

  var i:int  = 0;
  var bitPos:int = 5;  // the first bit to read:  0123 4xxx xxx xxx, etc
  var mask:int = 0;

 // int[] tmp = new int[4];
  var tmp:Array = new Array();

  while(i<4) {


   var curField:int = 0;

   var bitsRead:int = 0;
   var bit:int   = 0;

   while(bitsRead<fieldBitSize) {

    // if we've hit the byte boundary, add 1 to the current offset in the
stream
    if(bitPos % 8 == 0) {
     curOffset++;
    }
    // set the mask according to the position of the bit in its byte
    mask = 1 << (7 - (bitPos % 8));
    // get the bit value applying the mask
    bit = (buffer[curOffset] & mask);
    // if the bit is on, shift it to its position in curField and set that
bit to on in curField
    // otherwise "add" 0 to curField
    curField |= (bit > 0) ? 1 << (fieldBitSize - 1 - bitsRead) : 0;

    bitsRead++;
    bitPos++;
   }
   // save the value of the current field and go to the next field
   tmp[i] = curField;
   i++;
  }

  xMin  = tmp[0] / 20;
  xMax  = tmp[1] / 20;
  yMin  = tmp[2] / 20;
  yMax  = tmp[3] / 20;
 }

}



2008/10/2, Andrew Sinning <[EMAIL PROTECTED]>:
>
> I'm using AS3.  After loading in an arbitrary swf using the Loader class,
> getRect and getBounds don't necessarily reveal the internally defined
> boundaries of the loaded swf, rather they seem to return the boundaries of
> the stuff inside the loaded swf which can be either smaller or larger than
> the internally defined boundaries.  Am I missing something?
>
> I want to load in a swf, create a mask around it so that only the stuff
> that is supposed to show is shown, and then scale it to fit a target area.
>  This should be easy, right?
>
> Thanks!
> _______________________________________________
> Flashcoders mailing list
> Flashcoders@chattyfig.figleaf.com
> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
>
_______________________________________________
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Reply via email to