[Lazarus] Copy buffer of PWord to TMemoryStream

Leonardo M. Ramé l.rame at griensu.com
Sun Mar 24 20:39:46 CET 2013


On 2013-03-24 20:29:44 +0100, Sven Barth wrote:
> On 24.03.2013 20:14, Leonardo M. Ramé wrote:
> >On 2013-03-24 20:02:38 +0100, Sven Barth wrote:
> >>On 24.03.2013 19:57, Leonardo M. Ramé wrote:
> >>>On 2013-03-24 19:46:09 +0100, Sven Barth wrote:
> >>>>On 24.03.2013 19:30, Leonardo M. Ramé wrote:
> >>>>>On 2013-03-24 19:21:49 +0100, Sven Barth wrote:
> >>>>>>On 24.03.2013 19:19, Joao Morais wrote:
> >>>>>>>2013/3/24 Leonardo M. Ramé <l.rame at griensu.com>:
> >>>>>>>>Hi, I'm copying a buffer of PWord to a TMemoryStream using this code:
> >>>>>>>>
> >>>>>>>>lTmpBuff := lBuffer;
> >>>>>>>>I := 0;
> >>>>>>>>while I < lBufSize do
> >>>>>>>>begin
> >>>>>>>>   lStream.Write(lTmpBuff^, SizeOf(PWord));
> >>>>>>>>   inc(lTmpBuff, 1);
> >>>>>>>>   inc(I, 1);
> >>>>>>>
> >>>>>>>What about:
> >>>>>>>
> >>>>>>>    inc(lTmpBuff, SizeOf(PWord));
> >>>>>>>    inc(I, SizeOf(PWord));
> >>>>>>
> >>>>>>If lTmpBuff is declared as PWord then "Inc" already increases in
> >>>>>>multiplies of "SizeOf(PWord)".
> >>>>>>Regarding lBufSize it will be important to know whether the C code
> >>>>>>returns the size in elements or in byte.
> >>>>>>
> >>>>>
> >>>>>Heres the interface of the library:
> >>[snip]
> >>>>Now if your C function is written correctly, all three should give
> >>>>you the same result.
> >>>>
> >>>
> >>>Thanks Sven, I modified the C function as this:
> >>>
> >>>bufSize = interdata->getCount(); // <- returns number of pixels
> >>>buffer = new Uint16[bufSize];
> >>>memcpy((void *)buffer, interdata->getData(), interdata->getCount());
> >>>
> >>>Here's the getCount() documentation:
> >>>http://support.dcmtk.org/docs/classDiPixel.html#15bbe5e57b15ea67bbc9541752ccccce
> >>>
> >>>Hence, my confusion is because I thought getCount was number of bytes,
> >>>but it is number of pixels :)
> >>>
> >>>After changing the C function, now I can do this:
> >>>
> >>>lStream.Write(lTmpBuff^, SizeOf(PWord));
> >>>inc(lTmpBuff);
> >>>inc(I, 2); // it also works with inc(I, 1) but not using inc(I,
> >>>sizeof(Word));
> >>>
> >>
> >>Now your lBufSize contains the number of pixels, so only Inc(I, 1)
> >>should be correct. And for copying all data at once you now need to
> >>use "lBufSize * SizeOf(Word)" instead. And the for-loop variant
> >>would look like this:
> >>
> >>=== code begin ===
> >>
> >>for i := 0 to lBufSize - 1 do
> >>   lStream.Write(lBuffer[i], SizeOf(Word));
> >>   // or
> >>   lStream.WriteWord(lBuffer[i]);
> >>
> >>=== code end ===
> >>
> >
> >Yes, the code looks correct, but it still creates the wrong resulting
> >image.
> >
> >If you look at the attachment, the upper image is the result of your
> >last suggestion, while the lower image was created using the while loop
> >I've shown.
> >
> >I'll re-check my drawing function, maybe your code is correct and the
> >problem is on that function.
> 
> I just noticed that you are still using "SizeOf(PWord)" in your
> lStream.Write. This is wrong. You want to copy one Word element
> (SizeOf(Word)=2) instead of two/four (depending on 32 vs 64 bit
> SizeOf(PWord) is either 4 or 8). Which is also why your Inc(..., 2)
> works as you are copying multiple entries at once.
> 

Well, this is funny, after re-checking the code, I noted it works if I
use this:

(1)   for I := 0 to lBufSize - 1 do
        lUnCompressed.Write(lTmpBuff[i], SizeOf(PWord));

But, using SizeOf(Word) doesn't:

(2)   for I := 0 to lBufSize - 1 do
        lUnCompressed.Write(lTmpBuff[i], SizeOf(Word));

What I would like to achieve is this:

(3)   lUnCompressed.WriteBuffer(lTmpBuff^, lBufSize * SizeOf(Word)); 
  
But using this, I get the same result of (2).

-- 
Leonardo M. Ramé
http://leonardorame.blogspot.com




More information about the Lazarus mailing list