These are chat archives for rust-lang/rust

7th
Mar 2019
mmynsted
@mmynsted
Mar 07 01:14
Thank you @Ichoran
kylegoetz
@kylegoetz
Mar 07 04:19
I've noticed when I fetch the pixel data of a JPEG in Rust vs Scala, most pixels' RGB values are exactly the same, but sometimes a pixel will be, say, (73,60,70) in Scala but (73,59,72) in Rust. The pixels are undoubtedly indistinguishable with the naked eye. But why aren't they the same? I get that JPEG is lossy, but that should only affect the product of a WRITE, but here I'm comparing the product of READs of two different libraries (one of which happens to be for a different programming language). Anyone know why this might be? Or should I take my talents to an image processing Gitter? :D
And, astonishingly, if I open the JPG in Photoshop, the pixel data for that pixel is (76,58,72)! So a third outcome!
Ichoran
@Ichoran
Mar 07 04:39
Maybe they each use different gamma correction? It's also possible that there are rounding errors in the calculations of some of them.
@kylegoetz - With a little snooping around, I'm also suspecting that differences between sRGB and RGB with 2.2 gamma correction are also to blame. They're almost the same, but not quite. Any one of them could see sRGB and decide it's a gamma of 2.2 instead (and any one could be careless with rounding calculations).
Ichoran
@Ichoran
Mar 07 04:44
Do you care that much about the identity of pixel values? If yes, can you use PNG instead?
kylegoetz
@kylegoetz
Mar 07 04:51
The only reason I care about identity of pixel values is because I've got a DB of MD5s computed based on pixel data using Scala code and am writing a program that computes MD5s in Rust and compares to the values in the DB. Dupe detector, basically. It means no JPG dupe will be detected. But really I'm just learning Scala and Rust by porting a Python program I wrote that does this, so I don't really care so much as I was curious about this when I ran into it.
Just means I need to add a RUST_MD5 field to my table schema and can't just piggyback off the Scala MD5s while I'm writing and testing my code. :)
or spin up a second Dockerized mariadb instance for Rust to use
Ichoran
@Ichoran
Mar 07 04:54
Hm. I can't think of a good way to solve that one. Even if you found, after much sleuthing, the Rust code which was responsible for the difference (you're not going to change the Java code any time soon, so I'd look into it on the Rust side), it would be a huge hassle to maintain a nonstandard JPEG decoder just for this purpose.
(Scala defers to Java libraries for all of its image processing, as you know, but I'm putting it here for the record, since otherwise it doesn't make sense that I'm talking about Java.)
kylegoetz
@kylegoetz
Mar 07 04:58
Yeah I'm not going to bother with trying to solve it since this is just an obstacle I've run into while learning Rust and Scala, not a bug that actually needs to be solved for a production application. Thanks for helping me figure this out.
Ingvar Stepanyan
@RReverser
Mar 07 14:47

but that should only affect the product of a WRITE

Not really - JPEG doesn't store pixels (in the same sense as BMP / PNG / ... do), and so decoding itself is lossy.

Ichoran
@Ichoran
Mar 07 14:53
Decoding should be deterministic, but there is enough wiggle room in applying interpolation and gamma that in practice it isn't always identical between implementations (apparently!).
Cayle Sharrock
@CjS77
Mar 07 14:54
Hiya, I have a simple example of nested Generic Structs implementing a trait (https://gist.github.com/rust-play/d8553a3eab4781810eba011685be03bf); The first 3 lines of main() run as expected, but if I nest the objects, it won't compile, citing a missing implementation. Is there any way of making this work in general? Or do we need to implement the specific type indicated?
Ingvar Stepanyan
@RReverser
Mar 07 14:55
@Ichoran It's deterministic only to a given precision. As long as errors are within margin, implementations are allowed to vary by standard.
And the result can be affected not only by external things like colour profiles as such, but also even by floating precision of operations used in a particular implementation.
Ichoran
@Ichoran
Mar 07 15:06
@RReverser - Yeah, that's an elaboration of what I said. I was just quibbling with the idea that the decoding is "lossy".
Denis Lisov
@tanriol
Mar 07 15:45
@CjS77 Just remove the M: Add<M, Output=M> requirement
Cayle Sharrock
@CjS77
Mar 07 17:01
Well, damn! Thanks @tanriol
Riley Cat
@WreckedAvent
Mar 07 20:29
given a "newtype" Vec: struct Wrapper(Vec<SomeType>), what's the idiomatic way to access the inner vec? just making it pub and doing .0?
Joey
@OddCoincidence
Mar 07 20:30
Depends on the exact purpose of the newtype really - e.g. if the purpose is to enforce some invariant on the contents of the Vec you wouldn't want to make it public.
Brian Knapp
@knappador
Mar 07 22:20
@xoac public, open source