- Home /
Know a run-time JPEG decoder?
Hi,
Does anyone know of a decent run-time JPEG decoder that would work out of the box in Unity? On mobile devices. Doesn't have to be super fast; I'd use it when loading a scene.
What I need essentially is something that would make a byte[] -> Color32[] conversion without extra memory allocations, as I need to merge the Color32 array into another array again. I know about
Texture2D.LoadImage()
and its sister
WWW.LoadImageIntoTexture()
but I'd really like to avoid copying the buffer twice. (As I imagine the Texture2D.GetPixels32() only returns copied data.) The image is relatively large.
Surely there must be a library or a bunch of scripts somewhere. Although I can't find anything...
GetPixels allows you to select a portion of the texture to read, so if the image is larger you just split into sections, you can then use SetPixels to put them back.
http://docs.unity3d.com/ScriptReference/Texture2D.GetPixels.html
@$$anonymous$$pjComp Yeah, I know about it. It's similar to GetPixels32() only less efficient. One problem is it works with floats, so: 4x bigger buffers, probably a conversion needed between my code and internal Texture2D buffers (I can't imagine Unity would store raster colour data in floats).
Another problem is it can only read uncompressed RGB(A) data (and DXT I think). *32 version can also manage PVR (tried) and probably other formats. The reason I'm talking about this is I need to store the source images somewhere on disc in some form and having it as uncompressed RGB data is unacceptable. Hence run-time loaded JPEGs or PNGs look like the best way to go. Hence I don't need a Texture2D at all until I finally write into one; I need a decoder.
Oh, right I see yes,.. That now makes sense. With you saying PNG (lossless), I wonder if you could get about the same compression on DXT files by just using a LZF Decompresser like this one -> http://forum.unity3d.com/threads/lzf-compression-and-decompression-for-unity.152579/ as I think that's what PNG's are using anyway.
@$$anonymous$$pjComp I think I could, yes. It's certainly an option. I zipped a Targa (raw RGB data) and it came out only moderately worse than PNG (for 3 $$anonymous$$B RGB the PNG was 1.7 $$anonymous$$B and ZIP 2.15 $$anonymous$$B). Still, JPEG comes out better for my data with mere 1 $$anonymous$$B. Thank you for the link. I'll have a look at it if the JPEG decoder doesn't work out.
@$$anonymous$$pjComp Unfortunately, the LZF compressor does almost nothing for my data. Savings in size are negligible, so not worth a bother. (Still a great script though.) Looks like I'll have to roll with JPEGs and Texture2D.LoadImage() after all.
Answer by Bunny83 · Oct 16, 2014 at 11:47 PM
I've just found this decoder on google code. It looks like it'a a whole JPEG framework. It also has an encoder. Haven't tested it yet if it runs in Unity, but it looks like it's pure managed code, but i might be wrong.
Hah, FJCore. I've seen a post somewhere on forums or answers where a guy gave it a try. It barfed on iOS. Generated IL as I recall. But maybe it's old news and they changed it...
Hmm, still true. Quantization is emitted. But it's a short section of code; I'll see if I can rewrite it. Otherwise looks very promising. Got to do it proper decoding on PC.
I've been able to get it to work on iOS in Unity. But I also run memory profiling and results aren't pretty. The decoder allocated extra ~25 $$anonymous$$B on mono heap for a 1 $$anonymous$$B JPG picture (decoded data excluded) that didn't even get reclaimed after GC.Collect(). (Even if it were, the damage is done.)
This way it's just better to use a custom Texture2D. I just don't see the point to allocate the decoded data twice -- once on Unity heap and then on mono heap -- if I'm going to process and discard it.