Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-03

Copy buffer of PWord to TMemoryStream

18 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Leonardo M. Ramé

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);
end;

As you can see, on each iteration, one PWord is copied. What I would like to do, is to copy bigger blocks, for example:

lStream.WriteBuffer(lTmpBuff^, lBufSize);

But, if I do this, I get different results than using the former method.

Do you see what I'm doing wrong?.

BTW, the buffer is an Uint16 array generated by a C++ library, the array contains images with 65535 levels of gray.

Regards,

Mattias Gaertner
to Leonardo M. Ramé
Show quoted text 15 lines
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); end; As you can see, on each iteration, one PWord is copied. What I would like to do, is to copy bigger blocks, for example: lStream.WriteBuffer(lTmpBuff^, lBufSize);
lStream.WriteBuffer(lTmpBuff^, lBufSize*SizeOf(Word));
[...]

Mattias

Leonardo M. Ramé
to Mattias Gaertner
Mattias Gaertner wrote 5 lines
On Sun, 24 Mar 2013 14:51:26 -0300 Leonardo M. Ram? wrote: lStream.WriteBuffer(lTmpBuff^, lBufSize*SizeOf(Word));

I've already tried that, but it doesn't work as expected.

Maybe the problem is caused because lBufSize is a longint, instead of Word or LongWord?.

Leonardo M. Ramé
to Joao Morais
Joao Morais wrote 16 lines
2013/3/24 Leonardo M. Ram? : > 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));

I've already tried that, but the only way it works is incrementing by just 1.

Sven Barth
to Joao Morais: 2013/3/24 Leonardo M. Ram? : What about: inc(lTmpBuff, SizeOf(PWord)); inc(I,…
Joao Morais wrote 15 lines
2013/3/24 Leonardo M. Ram? : > 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.

Regards,
Sven

Mattias Gaertner
to Sven Barth
Show quoted text 12 lines
[...] >> Hi, I'm copying a buffer of PWord to a TMemoryStream using this code: >> 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)".

I guess, you mean multiples of SizeOf(Word).

Regarding lBufSize it will be important to know whether the C code returns the size in elements or in byte.

Mattias

Sven Barth
to Mattias Gaertner
Mattias Gaertner wrote 17 lines
On Sun, 24 Mar 2013 19:21:49 +0100 Sven Barth wrote: > [...] >>> Hi, I'm copying a buffer of PWord to a TMemoryStream using this code: >>> 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)". I guess, you mean multiples of SizeOf(Word).

Of course :)

Regards,
Sven

Leonardo M. Ramé
to Sven Barth: If lTmpBuff is declared as PWord then "Inc" already increases in multiplies of…
Sven Barth wrote 22 lines
On 24.03.2013 19:19, Joao Morais wrote: >2013/3/24 Leonardo M. Ram? : >>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:

myfunction(void * &buffer, unsigned long& bufSize)
{
    bufsize = interdata->getcount() * sizeof(uint16);
    buffer = new uint16[bufSize];
    // interdata is an object containing image data
    memcpy((void *)buffer, interdata->getData(), interdata->getCount());
}

So, I'm using this variables:

lTmpBuff: PWord;
lBufSize: longword;
I: Integer;
Sven Barth
to Leonardo M. Ramé
Leonardo M. Ram? wrote 29 lines
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? : >>> 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: myfunction(void * &buffer, unsigned long& bufSize) { bufsize = interdata->getcount() * sizeof(uint16);

So bufsize contains the amount of Bytes.

buffer = new uint16[bufSize];

Ehm... shouldn't this be "new uint16[interdata->getcount()]"? Because currently if your "getcount()" function returns e.g. 42 you will allocate an array containing 84 elements...

// interdata is an object containing image data memcpy((void *)buffer, interdata->getData(), interdata->getCount()); }

So assuming that lBuffer is passed as the buffer argument and lBufSize as the bufSize one then your old code is wrong.

It should look like this:

=== code begin ===

I := 0;
while I < lBufSize do begin
   lStream.Write(lTmpBuffer^, SizeOf(Word)); // do you really have
"SizeOf(PWord)" there?
   Inc(lTmpBuff); // move pointer by one element
   Inc(I, SizeOf(Word)); // we need to increase I by the element size
end;

=== code end ===

An alternative would be:

=== code begin ===

for I := 0 to lBufSize div SizeOf(Word) do
   lStream.Write(lBuffer[I], SizeOf(Word));

=== code end ===

And to finally write all data at once:

=== code begin ===

lStream.Write(lBuffer^, lBufSize); // as lBufSize is the byte size, this
is correct without further multiplication

=== code end ===

Now if your C function is written correctly, all three should give you the same result.

Regards,
Sven

Leonardo M. Ramé
to Sven Barth
Sven Barth wrote 81 lines
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? : >>>>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: > >myfunction(void * &buffer, unsigned long& bufSize) >{ > bufsize = interdata->getcount() * sizeof(uint16); So bufsize contains the amount of Bytes. > buffer = new uint16[bufSize]; Ehm... shouldn't this be "new uint16[interdata->getcount()]"? Because currently if your "getcount()" function returns e.g. 42 you will allocate an array containing 84 elements... > // interdata is an object containing image data > memcpy((void *)buffer, interdata->getData(), interdata->getCount()); >} So assuming that lBuffer is passed as the buffer argument and lBufSize as the bufSize one then your old code is wrong. It should look like this: === code begin === I := 0; while I < lBufSize do begin lStream.Write(lTmpBuffer^, SizeOf(Word)); // do you really have "SizeOf(PWord)" there? Inc(lTmpBuff); // move pointer by one element Inc(I, SizeOf(Word)); // we need to increase I by the element size end; === code end === An alternative would be: === code begin === for I := 0 to lBufSize div SizeOf(Word) do lStream.Write(lBuffer[I], SizeOf(Word)); === code end === And to finally write all data at once: === code begin === lStream.Write(lBuffer^, lBufSize); // as lBufSize is the byte size, this is correct without further multiplication === code end === 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));
Sven Barth
to Leonardo M. Ramé
Leonardo M. Ram? wrote 27 lines
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? : >>>>> 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]

Show quoted text 23 lines
> 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 ===

Regards,
Sven

Leonardo M. Ramé
to Sven Barth
Sven Barth wrote 67 lines
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? : >>>>>>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.

Leonardo M. Ram? http://leonardorame.blogspot.com -------------- next part -------------- A non-text attachment was scrubbed... Name: Captura de pantalla - 240313 - 16:10:16.png Type: image/png Size: 60031 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130324/dacc9abb/attachment-0001.png>
Sven Barth
to Leonardo M. Ramé
Leonardo M. Ram? wrote 78 lines
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? : >>>>>>> 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 ,
Sven

Regards,
Sven

Leonardo M. Ramé
to Sven Barth
Sven Barth wrote 86 lines
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? : >>>>>>>>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).

Sven Barth
to Leonardo M. Ramé
Leonardo M. Ram? wrote 49 lines
>>> 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).

Maybe your problem is indeed in your drawing function. Because the usage of SizeOf(PWord) is definitely wrong if your lBuffer basically contains Word sized pixels after each other. You should currently even get different results depending on whether the application is 32 or 64 bit.

Regards,
Sven

Leonardo M. Ramé
to Sven Barth
Sven Barth wrote 60 lines
On 24.03.2013 20:39, Leonardo M. Ram? wrote: >>>>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). > Maybe your problem is indeed in your drawing function. Because the usage of SizeOf(PWord) is definitely wrong if your lBuffer basically contains Word sized pixels after each other. You should currently even get different results depending on whether the application is 32 or 64 bit. Regards, Sven

Sven, I can confirm the image display function was wrong. Now I can write all data to the stream at once!.

Sven Barth
to Leonardo M. Ramé
Leonardo M. Ram? wrote 65 lines
On 2013-03-24 20:44:50 +0100, Sven Barth wrote: > On 24.03.2013 20:39, Leonardo M. Ram? wrote: >>>>> 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). >> > > Maybe your problem is indeed in your drawing function. Because the > usage of SizeOf(PWord) is definitely wrong if your lBuffer basically > contains Word sized pixels after each other. You should currently > even get different results depending on whether the application is > 32 or 64 bit. > > Regards, > Sven > Sven, I can confirm the image display function was wrong. Now I can write all data to the stream at once!.

Nice to hear that you found the final problem as well :)

Regards,
Sven