Bug 691307 - fix computation of fz_mul255
Summary: fix computation of fz_mul255
Status: RESOLVED FIXED
Alias: None
Product: MuPDF
Classification: Unclassified
Component: fitz (show other bugs)
Version: unspecified
Hardware: PC Linux
: P4 enhancement
Assignee: Tor Andersson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-14 17:13 UTC by riccardo
Modified: 2010-05-20 22:04 UTC (History)
1 user (show)

See Also:
Customer:
Word Size: ---


Attachments
proof of correctness for the patched version (1.31 KB, text/x-python)
2010-05-14 17:13 UTC, riccardo
Details
perf test (redirect output if you want to do any measures) (1.27 KB, text/x-csrc)
2010-05-14 17:14 UTC, riccardo
Details
the actual patch (579 bytes, application/octet-stream)
2010-05-14 17:14 UTC, riccardo
Details

Note You need to log in before you can comment on or make changes to this bug.
Description riccardo 2010-05-14 17:13:41 UTC
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.
Comment 1 riccardo 2010-05-14 17:14:22 UTC
Created attachment 6289 [details]
perf test (redirect output if you want to do any measures)
Comment 2 riccardo 2010-05-14 17:14:47 UTC
Created attachment 6290 [details]
the actual patch
Comment 3 Lev Bishop 2010-05-17 06:42:50 UTC
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.
Comment 4 riccardo 2010-05-17 12:11:14 UTC
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.
Comment 5 Tor Andersson 2010-05-20 22:04:38 UTC
I have applied Lev Bishop's earlier patches for this same problem.