tags:

views:

168

answers:

2

Hi, I'm trying to manipulate an image that I receive to a function as TStream. I want to load it from memory and avoid writing to files.

input variable declared as:

inImage: TStream;

"lump" variable declared as:

imgLump: Array of TILubyte;

in the function I do as follows:

// setting input image into a "lump" 
SetLength(imgLump, inImage.Size); 
// rewind stream to beginning 
inImage.Seek(0, soBeginning); 
// read stream and write into array 
inImage.Read(imgLump[0], inImage.Size); 
loaded := ilLoadL(IL_JPG, imgLump, Length(imgLump));


at this stage, loaded gets the value 0 (IL_FALSE) and the call to ilGetError() returns 1298 (IL_FILE_READ_ERROR).

why?! what did I miss?

Thanks, Ilan

A: 

First try this:

loaded := ilLoadL(IL_JPG, @imgLump[0], Length(imgLump));

If that doesn't work, try this:

Step 1: Write the stream into a file and try to open it using your favourite image viewer.

It it doesn't work, the stream itself is corrupted.

Step 2: Write the array into a file and check it.

It it doesn't work, the stream-to-array is wrong.

Step 3: If all files are valid, then the problem must be at the call to ilLoadL. Double-check the documentation and/or ask the original developers.

DR
Definitely not that. Maybe @imgLump[0], though.
Rob Kennedy
There's no difference between those two, because the array is a continuous block. Because of that this assertion is valid: @array = @array[Low(array)], i.e. both pointers point to the very same address in memory.
DR
Ok, I was in doubt myself, but I checked the disassembly. It's definitly the same :)
DR
What I need is a pointer to an array of bytes (TILuBytes == Byte).See here for the authors example: http://openil.sourceforge.net/tuts/tut_5/index.htmI think what you all offered gives the same pointer...btw, stream is OK, stream to array seems OK (yet to be checked).I tend to agree with the 3rd step, so I already posted a question on their forum.Thanks anyway
Ilan Simon
If they're the same, DR, then you didn't declare that variable as a dynamic array like Ilan did. The address of a dynamic-array variable is not the same as the address of the array's first element.
Rob Kennedy
Yes, you are right. That might be also the reason why the ilLoadL call isn't working.
DR
I updated my answer. @Ilan: Please retry it using my updated code.
DR
+1  A: 

I wouldn't seek in the stream. Most APIs are written to assume that when they've been given a stream, the correct place to read from is the current position. They're supposed to read as much data as they want, and then leave the stream at that position, ready for the next function to continue reading what it needs from the stream. You mustn't assume that the entire stream is yours. The caller might have other stuff beforehand. Or the stream might not support seeking backward, or seeking at all.

Are you sure the stream contains JPEG data? What do the first few bytes look like? Have you tried opening the image with TJpegImage instead?

Is a TILubyte the same as a normal Byte? Is what DevIL calls a "lump" the same as what everyone else would call an ordinary array or memory buffer?

Rob Kennedy
I'll take that into consideration. Anyway, this time I control both the function and the caller, so I know exactly what it is within the stream. The file based solution (other loading function) works smoothly.I didn't invent the non-standard terms... I took it from here: http://openil.sourceforge.net/tuts/tut_5/index.htmTo my understanding, he uses a standard array.TILuByte is defined as Byte.
Ilan Simon