Summary: | fix computation of fz_mul255 | ||
---|---|---|---|
Product: | MuPDF | Reporter: | riccardo <riccardo.lucchese> |
Component: | fitz | Assignee: | Tor Andersson <tor.andersson> |
Status: | RESOLVED FIXED | ||
Severity: | enhancement | CC: | lev.bishop |
Priority: | P4 | ||
Version: | unspecified | ||
Hardware: | PC | ||
OS: | Linux | ||
Customer: | Word Size: | --- | |
Attachments: |
proof of correctness for the patched version
perf test (redirect output if you want to do any measures) the actual patch |
Created attachment 6289 [details]
perf test (redirect output if you want to do any measures)
Created attachment 6290 [details]
the actual patch
Note that the suggested patch does not round correctly for negative input. See bug 690631 for problems caused by fz_mul255 not treating negative numbers correctly. If I understand correctly that the best thing to do is fixing the callers passing negative arguments to fz_mull255 one could deal whith interpolations by introducing something like: #define fz_convex255(a,b,lambda) \ ({ unsigned int tmp; \ unsigned char _a = a; \ unsigned char _b = b; \ unsigned char _lambda = lambda; \ tmp = _a*_lambda + _b*(255 ^ _lambda) + 0x80; \ tmp += tmp >> 8; \ tmp >> 8; }) [which has zero error-energy against round((float(a*lambda) + float(b*(255-lambda)))/255.) over the set [0,255]^3] and switching those call-sites to the new helper. I have applied Lev Bishop's earlier patches for this same problem. |
Created attachment 6288 [details] proof of correctness for the patched version Ideally fz_mul255(a,b) in mupdf/fitz/fitz_base.h should return round(float(a)*float(b)/255.) for all the couples (a,b) in the discrete set [0,255]x[0,255] (ie. the approximation with the lowest error energy over the set [0,255]x[0,255]). This is not the case for the current implementation which is returning a less then optimal value for half of the possible couples (a,b). The attached patch fixes this. It also makes the multiplication around 20% faster on my machine.