AS3 JPEG Decoder by Thibault Imbert

basisWhen recently playing with Alchemy for AlivePDF I looked at the libjpeg library and thought it would be cool to expose the JPEG decoding capability to ActionScript 3 developers. As some of you may know, the libjpeg can also be used to encode JPEG files in a very optimized way.

So you may wonder, why the hell would I need a JPEG decoder in AS3 ? The Flash Player does it natively and supports it, its not like decoding animated GIFs, or BMP, etc. Well, for my part, I needed a JPEG decoding class for AlivePDF in order to make the addImageStream method work, which basically embed any JPEG file (any dpi) into any page of the PDF created.

When embedding such a file, you need to provide to the PDF reader some informations, like the image dimensions (width, height), its color space, etc in a synchronous way (Loader.loadBytes() is asynchronous). Hopefully the reader takes care of the pixels decoding, you just tell the reader to decode the pixels using the DCTDecode (Descrete Cosine Transform) algorithm and voilà.

But now, let's say you create an application which needs to fully decode a JPEG file, retrieve the image dimensions just by parsing the jpeg stream, do any processing on the pixels before sending them to a BitmapData or maybe just simply map them to a corresponding BitmapData object, then this library is for you. This could be done without Alchemy and libjpeg but I guess it would be much slower for big images and I was in an Alchemy mood :)

So here is what the API looks like :

import org.bytearray.jpeg.decoder.JPEGDecoder;

var myDecoder:JPEGDecoder = new JPEGDecoder();
myDecoder.parse(jpegStream);
var width:uint = myDecoder.width;
var height:uint = myDecoder.height;
var colorComponents:uint = myDecoder.colorComponents;
var numComponents:uint = myDecoder.numComponents;
var pixels:Vector.<uint> = myDecoder.pixels;

The pixels getter returns an ARGB Vector that you can pass to the fast BitmapData.setVector() method.

var width:uint = myDecoder.width;
var height:uint = myDecoder.height;
var pixels:Vector.<uint> = myDecoder.pixels;
var bitmap:BitmapData = new BitmapData ( width, height, false );
bitmap.setVector ( bitmap.rect, pixels );

I will post another version in the following days with more options. Click in the area below to browse for any JPEG file, the pixels are extracted and decompressed in AS3 and sent to a BitmapData object.

A Flash animation should have appeared here, but it seems that your browser has an older version of the Flash Player or it is not installed at all. Please, install the last release of the Flash Player now, then reload this page.

Download the sources here.

Comments (22)

  1. Mike Almond wrote::

    This is nice :) I looked at JPEG decoding in Flash ages ago when I wanted to load/use CMYK (4 channel) JPEGs in flash.

    A custom decoder should also allow more JPEG glitching possibilities…
    http://blog.madebypi.co.uk/2009/11/19/jpeglitch/

    Monday, December 7, 2009 at 3:21 pm #
  2. Thibault Imbert wrote::

    Hi Mike,

    Happy you like it :)

    Talking about CMYK, yes that’s a good idea, I think I will surface also the API to retrieve the JPEG color space, that could be useful.

    I will take a look at thise glitching features :)

    Thibault

    Monday, December 7, 2009 at 3:37 pm #
  3. Ben wrote::

    Nice … maybe the decoder could be used to resize and/or rotate a JPEG without re-compressing it? … do you know how to achieve that?

    Monday, December 7, 2009 at 6:41 pm #
  4. Erik Pettersson wrote::

    Hey,

    Could this be spread out over multiple frames to not lock the UI?

    Flash built in image loading locks when loading and/or decoding.
    I guess you can ‘get around’ this by using smaller image sizes, 255×255 should be small enough to not lock too much at 30 FPS for example.
    Around 400×400 you take up the entire frame with decoding.

    Looked quickly at the JPEG lib but it’s over my head :)

    Assumed the jpeg_finish_decompress() is heavier than jpeg_read_scanlines()..?

    Cheers!

    Monday, December 7, 2009 at 9:53 pm #
  5. Macaca wrote::

    Took me a while to realize this is a unique capability (‘what? flash does that’), good for the toolbox.

    Next up: synchronous PNG decoding :p

    Tuesday, December 8, 2009 at 10:39 pm #
  6. malczak wrote::

    Hi there,
    I have been experimenting with loading large jpeg images (larger than 16Mb) into flash using Alchemy code. Image decoding is performed asynchronously, it takes some time for large images. But once again, asynchronous functions can be tuned to be ‘less asynchronous, but faster’. Experiment is available on my page :
    http://segfaultlabs.com/blog/post/alchemy-loading-large-jpeg-images/

    Wednesday, December 9, 2009 at 8:41 pm #
  7. Thibault Imbert wrote::

    Hi malczak,

    Good one! :)

    I decided to go synchronous for me, cause I needed such a behavior for AlivePDF or other recent projects.

    Thibault

    Thursday, December 10, 2009 at 5:32 am #
  8. Jloa wrote::

    Way to go, Thibault!
    I’ve always wondered why there are only “JPGEncoder” and “PNGEncoder” in the adobe’s coreas3lib – why no decode classes are included.
    Thx to you, know there’s only one more “PNGDecoder” to go :)

    Thursday, December 10, 2009 at 5:07 pm #
  9. Thibault Imbert wrote::

    Hey Jloa,

    Yep, PNGDecoder would be sweet too. Good idea :)

    Thibault

    Thursday, December 10, 2009 at 10:34 pm #
  10. Vitero wrote::

    Hmm, the library doesn’t install. Too bad they probably spent a lot of time making it

    Thursday, December 17, 2009 at 12:53 am #
  11. Chuck Genco wrote::

    I’ve constructed a simple test using your swc and Flash Builder 3. All I did was load a 30k jpeg with URLLoader and hold on to the data. On click of the stage, I decompress the loaded data, create a new Bitmap with it and add it to the stage. On ctrl-click, I clear the stage. Memory just keeps climbing, even after clearing the stage. Using the profiler, there’s thousands of instances of cmodule.jpegdecoder.AlchemyYeild, and thye keep changing, even with no user activity.
    I only have one instance of your JPEGDecoder and keep reusing it. Eventually the browser crashes. Any notion as to what’s happening?

    Wednesday, February 3, 2010 at 12:59 am #
  12. Thibault Imbert wrote::

    Hi Chuck,

    I think I know where it comes from. I should have included a dispose() method to free up the buffer used by the image in memory.

    I will recompile the SWC and update it and let you know here.

    Thanks for noticing this bug ;)

    Thibault

    Wednesday, February 3, 2010 at 1:37 am #
  13. Chuck Genco wrote::

    Thanks! This is all very interesting. I’m looking into caching the images compressed and reusing them as need be to keep client memory down. I may have some questions going forward.

    Wednesday, February 3, 2010 at 5:26 pm #
  14. Rakuten wrote::

    when i process photo in a row of over 50…i got a error info of “system
    is out of memory” in the flex.

    help me pls…

    Tuesday, May 18, 2010 at 8:33 am #
  15. Urs Martini wrote::

    Hi there!

    This is really great work. I experimented with the alchemy-decoder from segfaultlabs and now I’m juggling with an alchemy-encoder for jpegs.
    What I realize is the following: Using the c-commandline-tools decoding some test-JPGs is blazing fast. But using alchemy-crosscompiled libjpeg (mine or yours, Thibault) is considerable slower than the build-in Flash-Loader-stuff. Do you know why?

    Monday, June 21, 2010 at 9:09 pm #
  16. Thibault Imbert wrote::

    Hi Thibault,

    Did u released the new library with dispose() method. where I can find it.
    Please send me the library link

    Tuesday, December 21, 2010 at 1:16 pm #
  17. Krishna Chaitanya wrote::

    Hi Thibault,

    Did u released the new library with dispose() method. where I can find it.

    Please send me the library link to use it

    Tuesday, December 21, 2010 at 1:17 pm #
  18. krishna chaitanya wrote::

    Hi There,

    I am using the jpegdecoder.swc, but there is a memory leak.

    Where I can get the new Library with memory leak fix or can i get the dependencies to build new one.

    Wednesday, December 22, 2010 at 7:46 am #
  19. Alex wrote::

    Hi Thibault!
    It look like the thing I’m looking for. I need a decoder to get a data from big jpg file and then process this data. The only thing is that I need to process big files and asynchronous behavior would be cool too.
    I’m trying to find a person who can do it for me (of course it’s will be paid).
    Please contact me to discuss this project. Or maybe you can suggest someone.
    Thanks,
    Alex

    Tuesday, May 3, 2011 at 6:19 am #
  20. Enrica wrote::

    What procedure did you use to compile jpeglib? Do you need static libs?

    # alc-on
    # ./configure
    # make
    # alc-off

    Tuesday, August 23, 2011 at 4:11 pm #
  21. CL Boyce wrote::

    Can anyone explain to me how to get this to work in Flash Builder 4.5 – I’ve imported the SWC but can’t seem to import/use it – do I have to go down the whole alchemy route or is that just for the SWC compilation?

    Any help is much appreciated!

    Wednesday, March 21, 2012 at 6:19 pm #
  22. jobigoud wrote::

    @CL Boyce:
    - Add jpegdecoder.swc to your Referenced libraries.
    - Add the JPEGDecoder.as file somewhere in your code or in its own package.
    - This should be enough to use the code snippet above.

    However, I also experienced the memory leak, I’ll try to understand if it’s fixable from within the AS3 code alone…

    Thursday, June 7, 2012 at 6:28 pm #

Trackbacks/Pingbacks (6)

  1. [...] AS3 JPEG Decoder [ by Thibault Imbert ] http://www.bytearray.org/?p=1089 [...]

     
  2. AS3 JPEG Decoder [ by Thibault Imbert ] — Some Random Dude on Monday, December 7, 2009 at 10:08 pm

    [...] AS3 JPEG Decoder [ by Thibault Imbert ] [...]

     
  3. decoder - StartTags.com on Tuesday, January 26, 2010 at 1:43 am

    [...] transformation of the movie business, television, print, advertising, marketing and new media. …AS3 JPEG Decoder [ by Thibault Imbert ]AS3 JPEG Decoder [ When recently playing with Alchemy for AlivePDF I looked at the libjpeg library [...]

     
  4. Flash Fur Generator « Zachernuk.com on Sunday, April 10, 2011 at 6:44 am

    [...] one thing that was extremely frustrating and somewhat silly: I had to use Thibault Imbert’s custom JPG decoder because of the security sandbox that the latest Flash player throws up around images loaded from [...]

     
  5. Anonymous on Monday, August 15, 2011 at 10:10 am

    [...] [...]

     
  6. Brauche Hilfe bei Fotogenerierung - Flashforum on Thursday, December 15, 2011 at 11:10 am

    [...] [...]