Decode speed

For discussion of LizardTech's free Decode SDK for MrSID and JPEG 2000.

Moderator: jskiffington

Decode speed

Postby BrianP » Mon Jan 18, 2010 12:38 pm

I was under the impression that the reason to use MrSid images were 2 fold. 1) Reduce file size on disk and 2) decode speed.

So, does it make sense that decoding a MrSid image is slower than decoding a TIFF image? I am basically reading an image file and converting to and RGB array. (I know, someone mentioned BIP and XCreateImage, but my speed problems are not in the array copy). So, here is my MrSid decode:
[code]
adt::RGB** rgb = NULL;
LT_STATUS sts = LT_STS_Uninit;
unsigned red, green, blue;

const LTFileSpec fileSpec(_fname.c_str());
MrSIDImageReader *reader = MrSIDImageReader::create();

sts = reader->initialize(fileSpec, false);

const LTIScene scene(x, y, w, h, 1.0);
LTISceneBuffer bufData(reader->getPixelProps(), w, h, NULL);
sts = reader->read(scene, bufData);

rgb = static_cast<adt::RGB**>(malloc(sizeof(adt::RGB*) * w));
for (unsigned int i = 0; i < w; i++)
rgb[i] = static_cast<adt::RGB*>(malloc(sizeof(adt::RGB) * h));
int count = 0;
for (unsigned int pixelY = 0; pixelY < h; pixelY++)
{
for (unsigned int pixelX = 0; pixelX < w; pixelX++)
{
red = static_cast<lt_uint8*>(bufData.getWindowBandData(0))[count];
green = static_cast<lt_uint8*>(bufData.getWindowBandData(1))[count];
blue = static_cast<lt_uint8*>(bufData.getWindowBandData(2))[count];
count++;
rgb[pixelX][pixelY] = adt::RGB((unsigned char)red, (unsigned char)green, (unsigned char)blue);
}
}

reader->release();
reader = NULL;
[/code]

and here is my TIFF decode:

[code]
adt::RGB** rgb = NULL;
TIFF* image;

if ((image = TIFFOpen(_fname.c_str(), "r")) != NULL)
{
size_t npixels;
uint32* raster;

npixels = imageWidth * imageHeight;
raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
if (raster != NULL)
{
unsigned red, green, blue, rasterLocation;

if (TIFFReadRGBAImage(image, imageWidth, imageHeight, raster, 0))
{
// Allocate memory for image
rgb = static_cast<adt::RGB**>(malloc(sizeof(adt::RGB*) * w));
for (unsigned int i = 0; i < w; i++)
rgb[i] = static_cast<adt::RGB*>(malloc(sizeof(adt::RGB) * h));

// Loop through height
for (unsigned int pixelY = 0; pixelY < h; pixelY++)
{
// Loop through width
for (unsigned int pixelX = 0; pixelX < w; pixelX++)
{
// the raster is - to be organized such that the pixel at location (x,y) is raster[y*width+x];
// with the raster origin in the lower-left hand corner.
// The values provided for the smaller image - the origin in the upper right.
// so we need to convert the y values to the proper locations
rasterLocation = (pixelY + (imageHeight - h - y)) * imageWidth + (pixelX + x);
red = TIFFGetR(raster[rasterLocation]);
green = TIFFGetG(raster[rasterLocation]);
blue = TIFFGetB(raster[rasterLocation]);
rgb[pixelX][h - pixelY - 1] = adt::RGB((unsigned char)red, (unsigned char)green, (unsigned char)blue);
}
}
}
_TIFFfree(raster);
}
[/code]

So, I have a MrSid image:
basic image info:
format: MrSID/MG3
width: 5000
height: 5000
nband: 3
color space: RGB
datatype: uint8
precision: 8
dyn range min: (natural)
dyn range max: (natural)
background color: (0, 0, 0)
nodata color: (0, 0, 0)
nominal size: 75000000 (72 MB)
physical size: 4999998 (5 MB)
compression ratio: 15.0 : 1

and the TIFF equivalent (I have the TIFF that mrsidecode made which is uncompressed and a jpg compressed version of hte image).

The MrSid decode is consistently about twice the time as the TIFF decode. And the time is all in the reader->read() call.

For an LTIScene scene(0, 3806, 1833,1194, 1.0) MrSid did it in 1130 ms (972 ms for just the read() call) and the TIFF did it in 395 ms (257 for the TIFFReadRGBAImage() call).

Any thoughts? Is there another to get access to the RGB than what I am doing? While I can do stuff to optimize the code post the read() call, if I can't speed up the call it doesn't matter too much. I tried using Jpeg2000 images and had the same result (Jpeg200 faster then MrSid but not by much). I am willing to scarifice some quality, but I can't quite figure out how to change (x,y) and (w,h) for a magnification of 0.5 as I need the resulting image to still be the same size.

Thanks!
- Brian
BrianP
 
Posts: 10
Joined: Thu Jan 14, 2010 8:27 am

Postby gat » Mon Jan 18, 2010 1:18 pm

decode speed for mrsid images is not quite as fast as raw when decoding at full resolution. It will be VERY close but there is some extra overhead in the decompression of a mrsid image. There are many benefits however in that the data is stored in a pyramid to allow for very fast non full resolution decode speeds.

Use the mrsiddecode application as a baseline for your application to compare performance. You should be able to decode as quickly as the mrsiddecode application does.
gat
 
Posts: 28
Joined: Mon Jan 12, 2009 12:41 pm

Postby BrianP » Mon Jan 18, 2010 1:33 pm

[quote="gat"]Use the mrsiddecode application as a baseline for your application to compare performance. You should be able to decode as quickly as the mrsiddecode application does.[/quote]

The problem with mrsiddecode is I can't tell when the read is complete compared to the write.

I guess I was more asking if there was a better way to read in the MrSid file to make it faster.

LTFileSpec or LTIOStreamInf?
MrSIDImageReader->read() then bufData.getWindowBandData() to get RGB or something using LTIViewerImageFilter?

I don't understand much about images and there aren't really examples showing anything too complicated.

Maybe I will tweak the examples to us my images and do some speed testing....

- Brian
BrianP
 
Posts: 10
Joined: Thu Jan 14, 2010 8:27 am

Postby gat » Mon Jan 18, 2010 2:10 pm

Yes, I think experimentation is needed. stream/filespec will not make any difference.
gat
 
Posts: 28
Joined: Mon Jan 12, 2009 12:41 pm

Postby jdstark » Tue Mar 09, 2010 6:27 pm

Decoding images is much faster when you do it in full resolution.
jdstark
 
Posts: 3
Joined: Fri Mar 12, 2010 2:21 pm
Location: Ft. Collins, CO


Return to SDKs

Who is online

Users browsing this forum: No registered users and 2 guests

cron