Strange problem. Maybe someone can give some insight.
Scenario 1. I have a TBitmap in memory that is written to while complex calculations take place to calculate the color of each pixel. Every so often (usually after every horizontal line that the bitmap is filled) the TBitmap is drawn to an image on a form (image1.Canvas.Draw(0, 0, TBitmap). Most of the time this works fine, but I noticed that if there are many slow complex calcs for each bitmap line (say taking more than 30 secs or a minute to calculate) then the main form has a momentary "flicker" that somehow erases the bitmap, so then the image.draw call only draws the latest calculated line and the first y lines are blanked out in the bitmap. I got around this by locking the bitmap prior to calculations.
Scenario 2. This is the main hassle. I am writing to a TMemoryStream rather than a bitmap. Same deal. Calculations take place to calculate each pixel value and then each pixel value is written to the TMemoryStream with memstream.Write(bytevalue, 1) during the process. At the end of all the calculations I save the stream to a bitmap with memstream.SaveToFile('whatever.bmp') and then free the stream with memstream.Free. If the calculation is quick then the stream saves no matter what size (i am doing tests with 10000x10000 dimensions).
I can even tell the resulting file will be corrupt as the main application window/form does have a slight flicker like it is being repainted. When that happens it is as if every handle to bitmaps and TMemoryStream is killed/refreshed so the existing data is corrupted.
Any ideas? This really sucks. Especially when each single image can take an hour to create only to find that when it finishes something in the background happened and corrupted the bitmap or TMemoryStream.
Is there any way I can lock a TMemoryStream handle like I can with a bitmap? That may help. Or some declaration to tell Delphi "Don't mess with my objects, even if it looks like the app is taking too long"
Or does anyone know the back end reason inside Delphi that causes this to happen.
The TMemoryStream is created inside the procedure that does all the calculations so is a local object. With the bitmap issue the bitmap was a global variable outside the procedure and it happened, so I don't think that is the cause.
This is also under Windows 7, but I noticed the original bitmap issue under Vista.
Update 1:
Sorry for not using the comments, but there is the restirction on text size...
In reply to Remy (and anyone else reading this)...
Single threaded. For the memorystream it works fine for 5000x5000 resolution if the calculations are quick, but fails if the cals are slow.
As a basic framework the code is along the lines of
SetupMemorystream;
for y:=0 to height do
for x:=0 to width do
DoCalcs;
SetByteValue;
end;
end;
SaveStream;
If the DoCalcs is relatively speedy then all goes to plan. If it is slow then I get the TMemoryStream corruption and the resulting bitmap the stream is saved to is corrupt.
This was identical with using an in memory TBitmap until I discovered I could lock the bitmap which stops Delphi and/or Windows reallocating a new handle to it "when it wants to" which corrupts the data inside the bitmap.
This is too much of a coincidence to not think the same issue is not happening with the TMemoryStream and its handle.
Update 2:
One more maybe helpful bit of info.
When the TMemoryStream saves OK the resulting file (for a 5000x5000 bitmap) is 75,000,054 bytes in size.
When the saved stream is corrupt it seems to be a random value (of the size from when the handle was corrupted until the stream is saved). Example sizes have been 22 MB and 9 MB.
When I look at the resulting files is a hex editor it shows that the start of the files are correct with the header chunks, but the tail ends get truncated somehow.
This is so bizarre. Anyway I can absolutely for sure flush a TMemoryStream after a SaveToFile call and before freeing it?