One of these JPEGs is not like the other
blog.benjojo.co.uk
blog.benjojo.co.uk
Frustrating to hear it called bizarre. Arithmetic encoding should've been the default if IBM hadn't sat on a patent for mathematics. A huge amount of bandwidth has been wasted sending images around the world because Huffman encoding avoided legal headaches.
https://en.wikipedia.org/wiki/Arithmetic_coding#History_and_...
This is also the reason for the 2 in bzip2.
On an Intel Mac running Big Sur, that image (title "444-fp-acode-prog.jpg") is only solid white in Chrome; in Safari, it's solid black and in Firefox it doesn't load at all, there's the broken image placeholder.
Could not complete your request because reading arithmetic coded JPEG files is not implemented.
I find it interesting that they wrote an error message this specific.
Also interesting that Photoshop, with dozens of developers, didn't deem this format interesting enough to add support for it.
My Mac has a I7-9750H (Coffee Lake) processor with an AMD Radeon Pro 5300M.
The image does render on my iPhone with an Apple A14 Bionic processor. The 2020 iPad Air (4th gen) also has this processor.
If "2020 iPad" means iPad 10.2" 8th Gen, that has an A12 Bionic processor.
If the image doesn't render on an Apple mobile device, maybe it's one with an older processor?
My guess is your JPEG rendering is being done by libjpeg, which has supported Arithmetic coding since 2009.
iPhone XS (iOS 15.1 / A12), displays a black box.
2020 iPad Air (iPadOS 15.1 / A14), displays image perfectly.
Interesting if it's hardware assisted.
If their "2020 iPad" was actually a 4th gen Air (A14 Bionic) or 2nd iPad Pro (A12Z Bionic), it could still be a hardware decoding difference.
If I had to guess, A14 devices aren't using the hardware decoder any more for some reason, and that's why it works.
Madness indeed.
H.264 decoding should be fully deterministic and consistent, I believe. That said, bugs exist, shortcuts are taken, and not all decoders are truly compliant. But "some decoders are non-compliant" is very different from "it's impossible to consistently decode H.264".
(A colleague of mine filed something like 30% of all the bugs on the H265 bug tracker, for instances where the reference implementation produced different results than the textual specification. Because we'd written a parser for the English text ..)
There is also the concept of a "profile", a set of features which an encoder/decoder may limit itself to on small hardware. http://blog.mediacoderhq.com/h264-profiles-and-levels/
I was playing with email parsers a couple of years ago and I still don’t know if my cobbled together email parser works correctly with all emails. 40 years after RFC822 it seems there’s still no standard, reference set of email message test cases to process to verify an email parser is correct & robust.
https://www.hhi.fraunhofer.de/en/departments/vca/technologie...
https://www.allegrodvt.com/video-ip-compliance-streams/compl...
A very legitimate question we asked ourselves was whether we could skip it altogether: the pass did smooth out edges between MacroBlocks, but on our test streams you really had to look closely at still frames to see the difference.
So I can imagine different codecs implementing different parts of standard, as long as you could produce a valid stream/image that was acceptable to the human eye.
(I don't remember what the final decision was for our deblocking. I would guess that certified compliance required it to be implemented)
Well, he could be including YUV -> RGB conversion, which while the conversion matrix is specified, the required precision and chroma upsampling method are outside the scope of the spec.
EDIT: Also, try converting JPEGs to uncompressed PNG using Python with Pillow or OpenCV, then try on C using libjpeg and the stb_image header library. All four create slightly different output. I discovered this evaluating the accuracy of a MobileNet implementation. The accuracy of the model changed based on what language/library converted the JPEGs.
Note that even between two versions of the same library, you can get different results.
What compiler settings? With -O3, GCC will flush-to-zero your denormals, because Intel CPUs have _SEVERE_ penalties on subnormal floats.
You don't even get the same results with -O vs -O3 on the same programming language on the same system... let alone different CPUs.
https://carlh.net/plugins/denormals.php
Denormals are part of IEEE 754, but in practice are more complicated for hardware to figure out. So as a common efficiency trick, you disable the processing of denormals entirely (IE: all denormals are seen as "0" to the hardware, speeding up processing severely).
On Intel processors, a configurable register can set up how your floating-point units act when they come across a denormal. So an inline-assembly statement can change your results, even if it was no where "close" to your code.
To enable that, you need to use -Ofast or -ffast-math, there's a reason they're not default enabled after all.
On the contrary. One of the most common multiplayer bugs is the multiplayer-desync due to different settings of floating-point arithmetic.
https://stackoverflow.com/questions/1948929/keeping-sync-in-...
This stuff happens in pretty much every video game. You "solve" it by...
1. In FPS games, most _clients_ serve as the source of truth. This means that in most FPS games, you allow the client to "hack" the location data for clipping, speed-hacks, and the like. (Server calculated you at point X. Client claims to be at point X+.05. Well, client wins the argument).
2. In games like Factorio, an extraordinary amount of effort is placed upon finding all sources of desync (https://wiki.factorio.com/Desynchronization) and squashing them. Protocols communicate with integers as much as possible, avoiding any floating point issues.
> but do they start becoming problems in weather forecasting or particle simulations? What kind of applications are impacted?
I'm no supercomputer expert. But for reliability, a lot of supercomputer simulations step through twice to "verify" the results. That means both simulations must be setup with the same settings, so that your floats all line up.
In my undergraduate studies, my professor for numeric computing stressed the importance of sorting numbers: not only to avoid floating-point cancellation error, but also to have a precisely defined ordering for supercomputer applications.
You want to do things like add / subtract numbers from smallest to biggest, and all the positive numbers add together, then all the negative numbers add together and only do one subtraction. Cancellation error is serious business!!
In such cases, the result of one simulation is not enough, and we do several ones with slightly different initial conditions, just to make sure that we don’t spend time analysing an outlier. Exact reproducibility is important to validate the codes running test suites, but for the purpose of using simulations to make predictions, it does not really matter as long as each simulation is physically accurate enough.
For a project relying on multiple runs on different computers for verification of correctness, this was a serious issue. IIRC before they solved it properly, they had to increase the number of validations per piece of work, as well as trying to segregate the work so a work unit was only issued to either Intel or AMD but not both. This only reduced the impact somewhat though.
From their[1] page:
Besides helping build the LHC, LHC@home has proved to be an invaluable, even essential, tool for investigating and solving fundamental problems with floating-point arithmetic. Different processors, even of the same brand, all conforming more or less to the IEE754 standard, produce different results, a problem further compounded by the different libraries provided for Linux and Windows. In particular, a major problem was the evaluation of the elementary functions, such as exponent and logarithm, which are not covered by the standard at all (apart from the square root function). This problem was solved by the use of the correctly rounded elementary function library (crlibm) developed by a group at the Ecole Nationale Supérieure in Lyon. Due to the often chaotic motion of the particles even a one unit of difference in the last digit of a binary number produces completely different results, as the difference grows exponentially as the particle circulates for up to one million turns round the LHC. Thus it is extremely difficult to find bugs or to verify new software and hardware platforms. This methodology has allowed us to detect failing hardware, otherwise unnoticed, and to find compiler bugs. With your help, it is being extended to ensure identical results on any IEE754 compliant processor with a standard compliant compiler (C++ or FORTRAN) which will allow us to work on any such system and even on Graphical Processing Units (GPUs).
[1]: https://lhcathome.web.cern.ch/projects/sixtrack/sixtrack-and... (
Different standard libraries for different processors could have different precision for transcendental functions though. There are those that are written to always produce reproducible results though; and in the case of CRlibm, proven correctly rounded.
Older compilers for x86 used the x87 FPU which used a 80-bit type internally but all modern compilers for x86 and x86-64 use SSE/AVX instead which supports IEEE types.
Optimizations in FMACs can lead to LSB differences. IEEE doesn't specify how an FMAC is to be implemented, only the format of the number.
(Also: I'm 99% sure I'm right... still 1% could be wrong as I understand it.)
Quoth the spec:
> Each of the computational operations that return a numeric result specified by this standard shall be performed as if it first produced an intermediate result correct to infinite precision and with unbounded range, and then rounded that intermediate result, if necessary, to fit in the destination’s format (see 4 and 7).
In the end the idea of a CMYK JPEG makes no sense to me, because if you're generating content specifically to print, especially if it contains vector-like content, why are you storing it in a lossy format? But, whatever, that is less annoying than people who ask for the ability to modify the DPI of an image to 72 for "web exports". I built it in instead of trying to explain to them that there's no need to turn a 300 dpi JPG into a 72 dpi JPG for use on social media.
I don't even want to get into the joy of CMYK SVGs with transparency, and trying to explain to customers that since JPG doesn't support transparency I have to use PNG for generated preview images, which necessitate a conversion to PNG, and SVG doesn't have any sort of color profile support, so converting them from CMYK to RGB is kind of just lucky dip.
But in general when you're dealing with user generated content you see a lot of weird stuff... we get a lot of JPG uploads that are actually MP4 video files, and sometimes the reverse, MP4 uploads that are actually still frame JPEGs.