Alchemy - asynchronous jpeg encoding

over 2 years ago malczak alchemy comments

Just a quick note, motivated by bytearray.org post about fast jpeg encoding. I am preparing a short talk about Alchemy project and, as an example I have developed an asynchronous JPEG encoder. Encouraged by bytearray.org post I have decided to publish (proof-of-concept) solution.

Encoding JPEG with Alchemy is not only fast, but it also produces smaller JPEG images. Just take a look at the example below. I have used an jpeg encoder taken from bytearray.org.
Optimized JPEGEncoder code and post about it can be found at bytearray.org - http://www.bytearray.org/?p=775.

In demo below we encode 2880x2880 BitmapData, showing the difference in time and size between Alchemy libjpeg port and optimized JPEGEncoder. Right click for flex source code. FlashPlayer 10 required.

Flash player (ver. 10.0.0) is required to see this content. Please update to newest possible version.

Get newest Adobe Flash player

When using non asynchronous Alchemy implementation, compression time is much shorter.

But asynchronous implementation is fast enough and can be used particularly in AIR runtime.

Alchemy C code (non optimized, hard coded BitmapData dimensions) is available for download. To compile it You need to recompile libjpeg (http://www.ijg.org/) with Alchemy.

Download Alchemy source file here
Download Alchemy compiled swc library here

For flex source code - right click on application ;)

** update **

This is updated version of libjpeg port. You can now compare JPEG encoding times for alchemy asynchronous, alchemy synchronous, bytearray.org, Kyle Lu and buildin mx.* encoders. The difference in the size of a file can also be noted. Right click for code view.

Flash player (ver. 10.0.0) is required to see this content. Please update to newest possible version.

Get newest Adobe Flash player

Download jpeg swc library source code, libjpeg ported code with compiled library and swc build script here

** update **

Read also post about decoding JPEG images with Alchemy. Used to load bitmap larger than 16MB
http://segfaultlabs.com/devlogs/alchemy-loading-large-jpeg-images

** update 2 **

I have uploaded a new c source file, where I have added as3 objects release lines (thanks David R for a clue). I hope this will prevent memory leaks.
Download source - here

** update 3 !! **
if You're interested in using this library, read latest post about new improved swc library
http://segfaultlabs.com/devlogs/alchemy-asynchronous-jpeg-encoding-2

Comments

about 2 years ago Robert #0

Hi. The link to the sources doesn't seem to be working.

about 2 years ago Keyston #1

Anyway to have the sources reposted???

Thanks

about 2 years ago mxx #2

I've tried in my project to swap the bytearray.org encoder with the alchemy encoder. I've just added a few lines of as3 and imported your swc. It works great but there's an annoying issue: the release build file size of my flex project (Flex 3.4) jumped from 2.4MB to 4MB. Your sample on this page seems to be much lighter.
I browsed several alchemy ports and all of them have a reasonnable swf file size.

did I miss something ?
thanks

almost 2 years ago Klas Lundberg http://last.instinct.se/ #3

The alchemy JPEG is really great! I'm using it in Flash so it's took me a while to get it working, but when you finally get there, it works like a charm.

A little tip:
I found that it was very easy to get the progress of the encoding when using the asynchronous encoder. Just set up a function that monitors ba.position/ba.length via setInterval or similar while encoding.

almost 2 years ago malczak #4

@mxx: I still dont know what is the reason for this ;(

@klas: thanks for that tip :)

almost 2 years ago jerri #5

can you send the image to your email once it is created?

almost 2 years ago Thomas #6

Doesn't work unter Mac OSX?

almost 2 years ago Klas Lundberg http://last.instinct.se/ #7

I have just put up a tutorial/guide on how to use the Alchemy JPEG encoder in Flash. Check out http://last.instinct.se/graphics-and-effects/using-the-fast-asynchronous-alchemy-jpeg-encoder-in-flash/640

almost 2 years ago Ryan Andrews #8

Hello,

I was wondering about encoding JPEG's in 300 DPI. How can I do this? For the other encoders out there I could change a few lines in the “writeAPP0″ function of the encoder and have the jpeg be in 300dpi vs the default of 72.

Thanks for any help you can provide.

over 1 year ago David R http://blog.davr.org #9

Seems like there might be a memory leak in this problem, but I may not be doing something right.

It seems like the library holds a reference to the input ByteArray, preventing it from being garbage collected. When I use the memory profiler, it shows the reference coming from:

flash.utils:ByteARray
flash.utils:Dictionary [key0]
cmodule.jpegencoder:ValueTracker val2rcv
cmodule.jpegencoder:CAS3ValTypemap values
cmodule.jpegencoder:CProcTypemap retTypemap [GC Root]

Is there any way to get the library to release these references? Otherwise, memory usages grows very very quickly when encoding a lot of JPEGs (I'm using the library in conjunction with AlivePDF, it's much quicker than using the JPEG library included with AlivePDF).

over 1 year ago malczak http://segfaultlabs.com #10

@David R
I have uploaded a bit modified c source code. You can try it, now all references should be cleaned. Seems like there were missing two lines


AS3_Release( source );
AS3_Release( dest )

over 1 year ago Beau N. Brewer #11

I was getting a compile error (error: parse error before ‘return’). The AS3_Release( dest ) is missing the semicolon.

over 1 year ago Urs Martini #12

Great work! I really appreciate your libjpeg-port!

The AS3_Release()-lines where not the only changes you made in the ** update 2 **, you modified the class more than that and I don't get behind it.
You even removed the as3-function-export of "export" and "exportAsync" in main() - why?

The next question is: will you share the code for your libjpeg-decoder-example?

Best regards from Berlin, Germany
Urs

over 1 year ago Aaron Hardy http://aaronhardy.com #13

I had the same issue as Beau and wondered the same thing as Urs. And, after compiling your original and running it, I get:

JPEG parameter struct mismatch: library thinks size is 372, caller expects 376

Looking into it. I suppose it might have something to do with compiling it using cygwin.

I'd very much appreciate a swc with asynchronous supported without the memory leaks.

Thanks for what you've done so far though!

over 1 year ago Urs Martini #14

> JPEG parameter struct mismatch: library thinks size is 372, caller expects 376

You have to compile the libjpeg-library on your own. I hat the same issue, recompiled libjpeg and then it worked.

try something like "make -f makefile.alchemy libjpeg.a" after deleting the file libjpeg.a.

Hope that helps!

over 1 year ago Aaron Hardy http://aaronhardy.com #15

Make ran fine, I rebuilt the swc, copied it to the project, rebuilt the app, and still get the same error. Do you have a swc you can send lest I don't get this figured out? If so, I'd love it if you sent it to aaronius9er at that one email service that ends with gmail.com. I'll keep digging in the meantime.

over 1 year ago Aaron Hardy http://aaronhardy.com #16

I had to clear the .o files, remake, and that worked. The problem is, it didn't fix all the memory leaks. AlchemyYield continues to increase in memory about 2 bytes per second and LEByteArray and CRunner stick around as well. Apparently it also shows up in Adobe's Hello World example as well:

http://forums.adobe.com/message/2015395?tstart=-2

over 1 year ago Nirmod http://www.myheritage.com #17

Hi,
Can you out a link to the latest swc, I have trubbles with compile the source code to swc.

Thanks,
Nimrod.

over 1 year ago BFK #18

Does the swc included in the zip file above have the memory leak fix compiled?

Great work,
thanks.

over 1 year ago malczak #19

@BFK
no it does not, you will have to recompile it. I will add re-compiled if only I found some time.

over 1 year ago BFK #20

Okay, thanks malczak.

I recompiled the new file but I'm still getting the following error after multiple uses of the same CLibInit instance:

RangeError: Error #1506: The specified range is invalid.
at cmodule.jpegencoder::FSM_imalloc$/start()
at cmodule.jpegencoder::FSM_pubrealloc/work()
at cmodule.jpegencoder::CRunner/work()
at Function/<anonymous>()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()

Any ideas?

BTW, this is a great tutorial for getting alchemy running on OSX if anyone's interested - http://thesven.com/?p=140

over 1 year ago BFK #21

Well the only way I've been able to get around this RangeError problem (I think it has something to do with memory) is to load in an external swf which encodes just one image using the alchemy library. Once the encoding is finished the swf is then unloaded using the Loader.unloadAndStop() method. If more images need to be encoded after that, just repeat the same process.

Hope this helps someone in the future.

over 1 year ago zwierz #22

Hi,
I really need this library working asap and I'm determined to compile it by myself. I was struggling with all that alchemy, cygwin and c stuff for a couple of days and when I finally got it working it appeard to produce whole black images.

I tried to compile both source codes available on this page but the result is the same... any ideas why it happens?

over 1 year ago felix #23

Thanks for your jpgencoder.swc. Very useful!

Is it possible to get a copy of the new SWC with the memory issues fixed?

thanks!

about 1 year ago Edw.M #24

You can use libjpeg-turbo, it'll be faster:

http://libjpeg-turbo.virtualgl.org/Main/HomePage

10 months ago streaming sport http://emo-tokex.blogspot.com #25

Thanks for your jpgencoder.swc. Very useful!

3 months ago loans http://goodfinance-blog.com #26

People in all countries receive the business loans from different banks, just because that's comfortable.

4 days ago Jay Terence http://www.findacellphoneuser.com/ #27

This post proved to be most useful to me. I have looked quite extensively for information such as this. Thanks for maintaining such a highly informative website.

New comment

  1. (with http or https prefix)

  2. (use [code][/code] tags to post a code snippet)

  3. (javascript is required)

Website content premeditately commited by malczak & sobstel.
Layout by mlando. Icons by dryicons.com. All rights reserved.