- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
I've got a fair amount of experience with jpeg-2000using other APIs (OpenJPEG, j2k-codec, Luratech). I thought I'd take a look at Intel's solution to see how it compares.We needmaximum performance on decode, but only a really basic API- memory buffer j2k to memory buffer RGB (and ideally, optionally direct toDXTn, but texture compression is currently done as a second pass). We also need support for j2k's incorporating an alpha channel and also greyscale (with and without alpha). We don't care about encode performance (within reason), but do care about encode quality. The application is real-time decode of real-time 3D application assets.
Here's what I've managed to come up with so far using the Intel API. It works, but could be a lot faster.
The code was originally based on decode.cpp from the Intel jpeg-2000 sample.
I welcome input from anyone who has suggestions as to how the performance of this code can be improved.
Thanks in advance.
Best regards,
Steve Williams
Director
Advance Software
PS. We also need the ability to decode to a lower resolution from the encoded resolution for scaling on low spec equipment.
// Intel IPP includes ...
#include "djp2file.h"
#include "edib.h"
#include "mdjp2.h"
#include "medib.h"
#include "memoryinput.h"
#include "memoryoutput.h"
#include "consdiagnoutput.h"
#include "transcodingexception.h"
#ifdef IPP_JPEG2000_TIMING
#include "timer.h"
#endif
typedef ByteInputSigned
typedef ByteOutputSigned
class MemoryBoundedInputBE : public ByteInputBoundService
{
public:
MemoryBoundedInputBE() {}
virtual ~MemoryBoundedInputBE() {}
using MemoryInput::Attach;
using MemoryInput::Detach;
};
// -----------------------------------------------------------------------------------------------------------------------
//
// Function : Intel_IPP_J2K_Decode
//
// Converts a j2k codestream in memory to an RGB888 memory buffer.
//
// TODO: 1. Upgrade to enable specification of desired output pixel formats.
// Need to specifyfour output pixel formats : grey, grey with alpha, colour, colour with alpha.
//
// 2. Enable automatic jp2 decode when detected.
//
// -----------------------------------------------------------------------------------------------------------------------
void * __cdecl Intel_IPP_J2K_Decode(void *src_data, unsigned long src_len, unsigned long &dest_width, unsigned long &dest_height)
{
if (!src_data || src_len==0)
return NULL;
ConsDiagnOutput diagnOutput;
BDiagnOutputPtr diagnOutputPtr = diagnOutput;
MRstrImage metaImage;
MemoryBoundedInputBE jp2Stream;
jp2Stream.Attach((const Ipp8u *)src_data);
jp2Stream.PushSize(src_len);
#ifdef IPP_JPEG2000_TIMING
Timer timer;
timer.PriorityBoost();
timer.Start();
#endif
if (0) //jp2
{
DJP2File
jp2File.AttachDiagnOutput(diagnOutput);
jp2File.Attach(jp2Stream);
jp2File.ReadIntroBoxes();
if(!jp2File.ReadNextCSMainHeader())
throw DiagnDescrCT
ReAllocMetaImageComponents(jp2File.CSMainHeader(), metaImage);
SetMRstrImageResolution(jp2File.HeaderBox().Resolution(), metaImage.CaptureResolution(), metaImage.DisplayResolution());
SetMRstrImagePalette(jp2File.HeaderBox(), metaImage.Palette());
while(jp2File.ReadCSNextTilePartHeader())
{
while(jp2File.ReadCSPacket());
}
FixedBuffer
SelectOnlyImageCore(metaImage.ComponentImage(), interfaceImgRef, metaImage.NOfComponents());
jp2File.UpdateCSImageComponents((ImageCoreC
}
else // JPEG 2000 codestream
{
DJP2Codestream
j2kCodestream.AttachDiagnOutput(diagnOutput);
j2kCodestream.Attach(jp2Stream);
j2kCodestream.ReadMainHeader();
ReAllocMetaImageComponents(j2kCodestream.MainHeader(), metaImage);
while(j2kCodestream.ReadNextTilePartHeader())
{
while(j2kCodestream.ReadPacket());
}
FixedBuffer
SelectOnlyImageCore(metaImage.ComponentImage(), interfaceImgRef, metaImage.NOfComponents());
j2kCodestream.UpdateImageComponents((ImageCoreC
}
// Create output.
DIBEncoder
SetBestDIBSizeAndResolution(metaImage, dib.Info(), true, diagnOutputPtr);
SetBestDIBDepthAndPalette (metaImage, dib.Info(), diagnOutputPtr);
ImagePn
image_map.Alloc(dib.Info().Size().Width(), dib.Info().Size().Height(), NOfChannels(dib.Info().Depth()));
ConvertImageChannelsToDIB(metaImage, dib.Info(), image_map.Channels(), false, diagnOutputPtr);
// Intel codec returns 32 bits (signed) per channel. We want 8 bit unsigned, so convert ...
// TODO [OPTIMIZATION] : Decode j2k codestream directly into an 8 bits per channel format to remove unnecessary conversion step.
// Allocate an output buffer, and return image dimensions.
dest_width = dib.Info().Size().Width();
dest_height = dib.Info().Size().Height();
Ipp8u *dest_buffer = new Ipp8u[dest_width*dest_height*3];
MemoryOutputBE output;
output.Attach(dest_buffer);
// Convert ...
WriteDIBImageDataDepth_24(output, dib.Info().Origin(), dib.Info().Size(), image_map.Channels()[0], image_map.Channels()[1], image_map.Channels()[2]);
output.Detach();
#ifdef IPP_JPEG2000_TIMING
timer.Stop();
timer.PriorityRelease();
printf("decoding time = %f msec\n", timer.GetTime(Timer::msec));
#endif
return (void*) dest_buffer;
}
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried UIC, but have found it isnot yetready for use.
I had to figure out how to bypass the error and build the transcoder, as I don't need a full application,
just an API. I don't want or need to install QT. What should happen is Picnic build should fail with
a message that QT needs to be installed, ideally with a URL of where it can be downloaded from (for the interested), then the remaining projects in the directory should attempt to build.
in build32.bat
call %NMAKE% /I
3. I tested this with an RGB j2k codestream like this :
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
we will provide MSVC studio project files for UIC sample in the next IPP release, so you will be able to build in debug configuration. For the current version you have to create VC solution by yourself.
Yes, GUI part of picnic application is based on Qt library. This is why we additionally provide simple command line application which does not depend on any third party GUI libraries.
Thanks for reporting issue with wrong detection of image color format. I think the reason is that UIC JPEG2000 encoder expected JP2 file format where color information is specified explicitly. When it did not find color info in J2K stream (which is simple JPEG2000 bitstream) application use some default value which is wrong. Regardless of that the resulting decoded image was correct I believe. You can check it by specifying the name of output file (-o out.bmp for example).
It also would be nice if you can attach problem file here, so we may investigate the issue in more details.
Regards,
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Vladimir,
> we will provide MSVC studio project files for UIC sample in the next IPP release
Thanks, Is it possible to build with debug information usingyour current scripts/makefiles ?
> I think the reason is that UIC JPEG2000 encoder expected JP2 file format where color information is specified explicitly. When it did not find color info in J2K stream (which is simple JPEG2000 bitstream) application use some default value which is wrong. Regardless of that the resulting decoded image was correct I believe. You can check it by specifying the name of output file (-o out.bmp for example).
That sounds about right. The way other apps I've used/written process codestreams is as follows :
1 channel - greyscale
2 channels - greyscale with alpha
3 channels - rgb
4 channels -rgb + alpha
(though it's just a codestream, so the channels could in theory represent anything you like)
I exported to a bitmap as you suggested, and it looks fine, so apologies for overreacting. I'll take another look.
Example codestream uploaded, as requested.
Example output here :
exe -i c:test.j2k -o c:test.bmp
image: c:test.j2k, 128x128x3, 8-bits, color: Grayscale, sampling: 444
decode time: 22.40 msec
encode time: 0.31 msec
Your decode is far slower than your encode. Is that right ? I would have expected the opposite. Is it simply an error in the console output (displayed wrong way round) ?
Cheers,
Steve.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
encode time: 0.29 msec
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
encode time: 0.06 msec
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The fastest way to decode JPEG2000 image in reduced resolution is to use native wavelet downscaling (but it only supports power of two factors). If this is not what you want you can use just ippiResizeSqrPixel function.
I do not think there is big potential in possible performance gain by skipping YUV-RGB color conversion step in JPEG2000 codec. Color conversion is quite simple operation which effectively implemented with using SSE instruction set. But entropy coding part of JPEG2000 is complex and not SIMD friendly kind of operations. It takes significant part of the whole coding pipeline, so color conversion is only a few percent of the time required by whole codec.
It make sense in JPEG case where all operation are relatively simple and take more-less equal time of codec pipeline.
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Vladimir.
I've posted the link to the test images above.
There's some largerimages I'musingfor testing here :
http://advance-software.com/examples/slideshow/photos/1.j2k
thu .... 20.j2k
These larger images decode faster than they encode, as I would expect.
Best regards,
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Vladimir,
I've taken another look at your UIC sample, and have run into problems.
I've put together a minimal reproducible here : http://advance-software.com/misc/adv_sw_intel_test.zip
Build the app in MSVC 2003, debug mode. Step into the program. You will note an exception is hit on exit from the test function.
I think this is because memory was allocated in one module, and released in another.
Hope this helps.
Best regards,
Steve.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
I've got JPEG2000 test streams but was not able to download test case.
Note, you may submit your issue report to Intel Premier Support and provide test case in this ad-hoc channel. This will be routed to our team as well.
Regards,
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Vladimir.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page