I chose Cay's answer, but I'll also answer my own question to add some clarification and inform everyone else of what I went through, did wrong and eventually did right, just in case someone else stumbles upon my question.
If you want to progressively load a jpeg, you need two things: a URLStream and a Loader. Then you need to follow these steps:
1) You must use a URLStream to load the jpeg from a URLRequest into a ByteArray.
2) You need to add a PROGRESS event handler to the URLStream. In that handler, you need to use a Loader to loadBytes() the newly loaded bytes of the URLStream.
3) You need a Loader COMPLETE event handler to acces every pass of the loaded jpeg and do whatever you want on it, like display it or resize it, etc.
4) You need a URLStream COMPLETE event handler to make sure all bytes have been loaded and to clean after yourself and close the stream.
var urlStream:URLStream = new URLStream(); //We will use this to progressively stream the bytes of the jpeg
var byteArray:ByteArray = new ByteArray(); //Bytes from the URLStream will go here
var loader:Loader = new Loader(); //We will use this Loader to load the bytes from the ByteArray
var url:String = "http://myAddressToMyJpeg.jpg"; //The url to the jpeg
urlStream.load(new URLRequest(url));
urlStream.addEventListener(ProgressEvent.PROGRESS, onStreamProgress, false, 0, true);
urlStream.addEventListener(Event.COMPLETE, onStreamComplete, false, 0, true);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete, false, 0, true);
function onStreamProgress(evt:ProgressEvent):void
{
// You could put a condition here to restrain the number of calls to updateBytes().
// Use the evt.bytesTotal and evt.bytesLoaded to help accomplish this.
// You will find that by limiting it, it will increase responssivness of your
// program and give an overall better result.
// Have it call updateBytes() every 100 bytes or so.
updateBytes();
}
function onStreamComplete(evt:Event):void
{
updateBytes(); // Call updateBytes one more time to load in the last bytes.
urlStream.removeEventListener(ProgressEvent.PROGRESS, onStreamProgress); // Clean after yourself
urlStream.removeEventListener(Event.COMPLETE, onStreamComplete); // Clean after yourself
// Somehow, without this, it does not work. You will end up with a ~90% loaded image
setTimeout(confirmBytesLoaded,500); // Would be nice if someone could tell me why this makes it work!!
}
function confirmBytesLoaded():void
{
updateBytes(); // As said earlier, you need to check it one last time it seems.
if (urlStream.connected) urlStream.close(); // Close the stream once you're done with it.
}
function updateBytes():void
{
// Important step. We copy the bytes from the stream into our byteArray,
// but we only want to add the new bytes to our byteArray, so we use the lenght
// attribute as an offset so that the new bytes gets added after the bytes that we added before.
urlStream.readBytes(byteArray, byteArray.length);
if(byteArray.length > 0) // Make sure there are new bytes to load.
{
loader.loadBytes(byteArray); // Use the Loader to decode the loaded bytes.
}
}
// onLoaderComplete will be called many times.
// Every time there is enough new bytes to diplay more of the image
// onLoaderComplete will be called. So for every pass of the jpeg one
// this will be called.
function onLoaderComplete(evt:Event):void
{
// bm will now contain the bitmapData of the progressively loaded jpeg.
var bm:Bitmap = Bitmap(loader); // We make a bitmap object from the loader.
bm.width = 400; // Because my goal was to be able to resize the image as it is loaded and display it :).
bm.height = 400; // Because my goal was to be able to resize the image as it is loaded and display it :).
addChild(bm); // See the result for yourself...
}
Some notes on the whole process:
1) The confirmBytesLoaded is your queue to know when the image has been fully loaded.
2) The Loader will not dispatch a complete event if the bytes it was given does not allow to display more of the image. Therefore, the Loader progress event is not required unless you want to know the progress of the loading of every pass of the jpeg.
3) In onLoaderComplete you can do whatever you want. At that point, the event gives you a full image to work with . You can access the loader.content attribute. Remeber that if is not the last Loader complete event, it means it is CustomActions partially loaded image that you will have, so either in lower defenition or with some gray pixels in it.
4) When you use loadBytes, it loads the image in your application context. So make sure you only load trusted content this way. I'm not yet sure if there is a way around this, to make it secure. See: http://onflash.org/ted/2008/01/loaderload-vs-loaderloadbytes.php
P.S:
Here is the link to where most of my code comes from:
http://orangeflash.eu/?p=13
Here are some links that actually show you a way to read the width and height yourself by parsing every byte as their are loaded using the jped specification:
http://www.anttikupila.com/flash/getting-jpg-dimensions-with-as3-without-loading-the-entire-file/
http://www.emstris.com/2009/05/extracting-binary-info/
http://blog.onebyonedesign.com/?p=71