-
Content Count
2561 -
Joined
-
Last visited
-
Days Won
133
Everything posted by Anders Melander
-
FireDAC, New OLE DB Driver, and SQL Server
Anders Melander replied to BruceTTTT's topic in Databases
Um... you aren't using ODBC data sources via FireDAC, are you? ODBC is just the API FireDAC uses to talk to the driver. From your perspective there's nothing ODBC about it - the API could be anything. Maybe they did 🙂 We've just completed replacing MSSQL via ADO with FireDAC and for us it works fine. We had to update the client library to a newer version on a couple of clients but apart from that it's faster, better. I think the oldest SQL server version we connect to is 2014/v12. -
What you're dealing with is an unavavoidable rounding problem and a misunderstanding of what's going on mathematically. The two versions are equally bad. They just distribute the rounding error differently. You want the first palette entry to have a grey-level value of 0 and the last one to have a value of 255 - not 256. Level = 255 * (Index / (Levels-1)) or Grey := i * 255 div (_NumColors-1)
-
https://letmegooglethat.com/?q=delphi+webp Seems Bing has hijacked that service so here's a link without the sarcasm: https://www.google.com/search?q=delphi+webp
-
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
I had to reread the source 3 times before I spotted the place it occurs. "with" strikes again: ClusterWeight := ClusterX[X].Weight; with HorzBuffer[ClusterX[X].Pos - MapXLoPos] do begin Inc(Cb, B * ClusterWeight); // Note: Fixed precision multiplication done here Inc(Cg, G * ClusterWeight); Inc(Cr, R * ClusterWeight); Inc(Ca, A * ClusterWeight); end; As you can see I have now added a comment to make it obvious 🙂 Anyway, your changes has now been committed. Please verify that the comments I've added in the source are correct. I will continue working on correcting the alpha handling (i.e. do premultiplication). -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
Yes, you're right. I understand the midpoint rule but I just can't make your code fit it. Let me have a look again... Ah, now I get it. It was your comments that confused me. For example: // old weight: Filter(x0*Oldscale)*Oldscale If I just read the code and ignore the comments it makes much more sense. That's a new one 🙂 I mean that when you operate on 32-bit integer values which has been multiplied by $800 (= 1 shl 11) it means that the upper 21 bits will contain the integer part and the lower 11 bits the fractional part. In other words [21:11] fixed precision. When applying the weight values you do a shr 22 (= $800*$800) to convert from [10:22] fixed precision back to integer. The [10:22] must mean that you have multiplied two [21:11] values at some point but I can't really spot where that happens. FWIW much of Graphics32 supports the TFixed [16:16] fixed precision type. For example many methods allow you to specify coordinates in either integer, TFixed or floating point format. I don't understand what this refers to. -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
Duh! Yes of course. I've just checked and the value was correct in my original resampler source so it appears to be a copy/paste bug introduced when the code was integrated in GR32. As far as I can tell the bug has been there from the start 😕 Regarding this: x0 := J - Center; // old weight: Filter(x0*Oldscale)*Oldscale x1 := max(x0 - 0.5, -FilterWidth); x2 := min(x0 + 0.5, FilterWidth); // intersect symmetric interval of length 1 about x0 with support of scaled filter x3 := 0.5 * (x2 + x1); // new center Weight := Round(Prec * Filter(x3 * OldScale) * OldScale * (x2 - x1)); // intersection with support entered into the weight You say that you're "computing the integral for the convolution with the filter using the midpoint-rule" so I would have expected to see the averaging of two filter values in order to find the midpoint but I can't really match that with the above. Can you explain what's going on, please? Once I understand it I'll comment the code so it's maintainable. Also, am I correct in assuming that you're doing calculation in [21:11] fixed precision and storing the weights in [10:22] instead of the old [24:8] and [16:16]? -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
Very, very nice. The performance has suffered a bit but the result is much better. It actually seems that the quality of the Graphics32 resampler now surpasses your original algorithm for most kernels (there's still artifacts with the GR32 box filter). I've integrated your changes locally and will commit once I've done a bit more testing. One thing that almost gave me brain cancer was the abysmal ASM generated by this code (not your fault): C.B := min((max(Cb, 0) + $1FFFFF) shr 22, 255) It goes something like this cmp dword ptr [Cb],$00 jle A mov eax,[Cb] jmp B A: xor eax,eax B: lea edx,[eax+$001fffff] shr edx,$16 cmp edx,$000000ff jnl C add eax,$001fffff shr eax,$16 jmp D C: mov eax,$000000ff D: mov [C.B],al Luckily the path with that code isn't taken in your example. -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
Take a bath. Always works for me 🙂 -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
I was surprised that this was necessary at all as I really thought that the compiler already made this optimization. Anyway, basically a "for" loop like this (the loop value isn't used inside the loop): for i := LowValue to HighValue do begin ..stuff here end; is compiled to this pseudo code: var i := LowValue; var test := HighValue - i; if (test = 0) then goto end_loop; :start_loop ..stuff here Inc(i); var test := HighValue - i; if (test <> 0) then goto start_loop; :end_loop while this equivalent while loop: i := HighValue - LowValue; while (i >= 0) do begin ..stuff here Dec(i); end; is compiled to: var i := HighValue - LowValue; if (test = 0) then goto end_loop; :start_loop ..stuff here Dec(i); if (test <> 0) then goto start_loop; :end_loop Exact same code if iterating from zero in case you wondered. Similarly a for loop where the loop variable is used inside the loop is also slightly faster when implemented as a while loop. -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
I've now merged your changes into the main Graphics32 branch. In addition I also included the following (very minor) optimizations of the Resample() function: Replaced for loops with while loops where possible. The channels are processed in their physical order: B, G, R, A instead of R, G, B, A. I've replaced the RGB bit-twiddling with regular record field access (32-bit compiler only). For example instead of: with BufferEntry^ do begin B := Integer(SourceColor.ARGB and $000000FF) * ClusterWeight; G := Integer(SourceColor.ARGB and $0000FF00) shr 8 * ClusterWeight; R := Integer(SourceColor.ARGB and $00FF0000) shr 16 * ClusterWeight; A := Integer(SourceColor.ARGB shr 24) * ClusterWeight; end; I now do this: BufferEntry.B := SourceColor.B * ClusterWeight; BufferEntry.G := SourceColor.G * ClusterWeight; BufferEntry.R := SourceColor.R * ClusterWeight; BufferEntry.A := SourceColor.A * ClusterWeight; I'm pretty sure the old method used to be faster but apparently not anymore. Maybe the compiler has gotten better or maybe it's the hardware (I have a pretty old CPU so I doubt it's that). I have only profiled the changes with optimization enabled so it's possible that I've made the unoptimized code slower. With optimization enabled, the performance of Resample() now matches, and in some cases even exceed, your algorithm. However since yours is also alpha-aware I still consider yours faster. There are a few additional things that could be done to make the code faster but I'm not really inclined to go there as it would also make it pretty unreadable. The performance of Resample() with the 64-bit compiler is horrible. For some reason your code is much faster there. I've not done anything to improve that. -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
That's excellent. I'm a bit surprised about the presence of the XY iteration order problem as that's a bit of a rookie mistake. It probably wasn't caught because the outer loop does iterate Y (and then iterates XY in the inner). Anyway, good catch. Would you mind either creating a pull request or posting a patched version of GR32_Resamplers.pas (without the reformat as that makes it hard to spot the actual changes - not that I disagree about the need to reformat). Your algorithm seems to be consistently 5-15% faster than GR32 on my system (tested with your latest changes). The quality is almost identical. For some kernels yours is marginally better, for some GR32 is marginally better. For the box filter GR32 wins in quality of details, but loses on fidelity (artifacts). WIC wins on both quality and speed. I think these results are as expected; GR32 is paying the price of the overhead a generalized framework. The quality could probably be improved to match WIC but the question is if it's worth the trouble or if the current quality is "good enough"...? I haven't had time to investigate why the Resample function doesn't use the alpha-aware methods. I'm knee deep in a quantization/dithering extension for GR32. P.S. "const StopWatch: TStopWatch" really should be "var StopWatch: TStopWatch". The only reason it works with const is Delphi doesn't know/care that the methods are modifying the TStopWatch record. -
Can undefined function result point to valid/used data in memory?
Anders Melander replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
No. It's empty. I don't know who "we" are but there's nothing unsafe about the code you posted. It's just fundamental string handling. -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
Apparently the GetSampleX methods are only used when sampling via a rasterizer or a transformation (e.g. rotate/skev/etc). -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
That's correct. A fully transparent pixel has no color. I'm not sure what it is you're showing here. I contributed code to handle that in 2011. See TKernelResampler.GetSampleFloat. That said there does seem to be a problem because when I resample in my own bitmap editor the alpha isn't handled correctly. I'll look into it. -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
Of course it's wanted. Improvements are always welcome and you seem to have a really good understanding of the subject. You might opt to have two versions instead: One for 32-bit opaque RGB and one for 32-bit RGBA. The premultiply/unpremultiply really messes with the quality since you're operating on 8-bit values. One way to avoid this is to premultiply to floating or fixed point, resample the floating/fixed point values and then unpremultiply back to 8-bit. As you can imagine this doesn't exactly improve the performance or memory usage. The memory usage can be lessened by processing one channel at a time. -
Parallel Resampling of (VCL-) Bitmaps
Anders Melander replied to Renate Schaaf's topic in I made this
Very nice. As a Graphics32 contributor I would have preferred though that you'd spent the (probably considerable) effort improving Graphics32 🙂 A few suggestions: Use TStopWatch to measure elapsed time and add the stopwatch as a parameters to TScaleProcedure. This way the procedure can pause the stopwatch when it's doing something which shouldn't be included in the benchmarking. For example assigning back and forth between TBitmap/TBitmap32. Use TTask instead of TThread. This solves your problem of how to manage the threads and avoids the overhead of creating the threads. I understood that you had problems with TTask, but IMO the solution to that is to locate and fix those problems rather than avoiding TTask. For Graphics32, using the memory backend instead of the GDI backend is better when you don't need to use GDI features. See below. In this case it doesn't make much of a difference though. Your code seems to handle RGBA but as far as I can tell you're doing it wrong. You cannot process each RGBA channel independently. Instead you need to operate on premultiplied RGBA values. For example you wouldn't want an RGBA value of $00FFFFFF to have any influence on neighboring pixels. So: 1) Premultiply, 2) Resample, 3) Unpremultiply. Unfortunately this will probably have a very negative impact on both performance and quality. Have cake/Eat cake - Choose one. FWIW, Graphics32 does have a multi-threaded rasterizer but since it uses TThread it doesn't make sense to use it in your benchmark since the overhead of thread setup/teardown for just a single call would kill performance. procedure LanczosGR32(const Source, Target: TBitmap; parallel: boolean); var Source32, Target32: TBitmap32; Resampler: TKernelResampler; begin Source32 := TBitmap32.Create(TMemoryBackend); Target32 := TBitmap32.Create(TMemoryBackend); try Source32.Assign(Source); Target32.SetSize(Target.Width, Target.Height); Resampler := TKernelResampler.Create; try Resampler.KernelClassName := 'TLanczosKernel'; Resampler.Resample(Target32, Target32.BoundsRect, Target32.BoundsRect, Source32, Source32.BoundsRect, dmOpaque, nil); finally Resampler.Free; end; Target.Assign(Target32); finally Source32.Free; Target32.Free; end; end; -
EULA declined installing 11.1 with Network Named license
Anders Melander replied to Lachlan Gemmell's topic in General Help
Hey, that's cheating 🙂 -
Digital Persona UAreU 4500 Fingerprint Reader ActiveX
Anders Melander replied to jon eskandi's topic in VCL
Google "OposBiometric activex", 3rd result: http://carol.havocshack.com/carol-winslow-tech-writer/files/one-touch-for-windows-sdk-com-activex-developer-guide.pdf -
FYI: Old security BUG fixed from ZLib
Anders Melander replied to Tommi Prami's topic in Tips / Blogs / Tutorials / Videos
From: https://www.openwall.com/lists/oss-security/2022/03/28/1 via https://github.com/madler/zlib/issues/605#issuecomment-1084218467 The following are the only (two) calls to DeflateInit2 in the Delphi source (System.ZLib.pas): procedure ZCompress2(const inBuffer: TBytes; out outBuffer: TBytes); ... begin ... ZCompressCheck(DeflateInit2(zstream, 1, 8, -15, 9, 0)); ... constructor TZCompressionStream.Create(dest: TStream; compressionLevel: TZCompressionLevel; windowBits: Integer); begin ... ZCompressCheck(DeflateInit2(FZStream, ZLevels[compressionLevel], Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY)); end; Note that one uses MemLevel=9 and the other MemLevel=8. None uses the Z_FIXED method the original bug was about. -
FYI: Old security BUG fixed from ZLib
Anders Melander replied to Tommi Prami's topic in Tips / Blogs / Tutorials / Videos
As far as I've been able to evaluate this bug isn't much of a problem for Delphi desktop applications. Server applications could have a problem if they do compression of user supplied data (the bug only exists in the zlib compressor) but since it's only a buffer overrun (as far as I can tell) it's not that bad. -
EULA declined installing 11.1 with Network Named license
Anders Melander replied to Lachlan Gemmell's topic in General Help
Okay then. I thought that maybe you were just voicing an uninformed opinion. My bad. -
EULA declined installing 11.1 with Network Named license
Anders Melander replied to Lachlan Gemmell's topic in General Help
That would mean Windows 8.x isn't supported either: https://sockettools.com/kb/windows-and-supported-tls-versions/ -
EULA declined installing 11.1 with Network Named license
Anders Melander replied to Lachlan Gemmell's topic in General Help
Are there any particular security update, unavailable for Windows 7, that you can't do without? -
Delphi 11.1 Provisioning Access Violation
Anders Melander replied to Michael Collier's topic in Delphi IDE and APIs
Looks like a corrupt installation to me, but it's hard to conclude anything from the info available. -
KILLER PROJECT - RESUSCITATE MWA DB JPEG COMPONENT LIBRARY
Anders Melander replied to Blavatsky's topic in Databases
Calm down, dude.