[Lazarus] Copy buffer of PWord to TMemoryStream

Sven Barth pascaldragon at googlemail.com
Sun Mar 24 20:29:44 CET 2013


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.

Regards,
Sven

Regards,
Sven




More information about the Lazarus mailing list