惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Troy Hunt's Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Schneier on Security
Schneier on Security
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Help Net Security
Help Net Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Palo Alto Networks Blog
P
Privacy International News Feed
AWS News Blog
AWS News Blog
Forbes - Security
Forbes - Security
N
News and Events Feed by Topic
L
LINUX DO - 最新话题
A
Arctic Wolf
Hacker News: Ask HN
Hacker News: Ask HN
P
Proofpoint News Feed
N
News and Events Feed by Topic
S
Security @ Cisco Blogs
Cyberwarzone
Cyberwarzone
Google Online Security Blog
Google Online Security Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
PCI Perspectives
PCI Perspectives
Know Your Adversary
Know Your Adversary
The Hacker News
The Hacker News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Tenable Blog
S
Security Affairs
P
Privacy & Cybersecurity Law Blog
W
WeLiveSecurity
Jina AI
Jina AI
The GitHub Blog
The GitHub Blog
S
Securelist
AI
AI
Latest news
Latest news
T
The Blog of Author Tim Ferriss
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
Cybersecurity and Infrastructure Security Agency CISA
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
G
GRAHAM CLULEY
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
V
Visual Studio Blog
L
LangChain Blog

Hub's wlog

Hub's wlog - Dia with GTK 3 Hub's wlog - Dev Log August 2023 Hub's wlog - Niepce July 2023 updates Hub's wlog - Niepce June 2023 updates Hub's wlog - Life update Hub's wlog - Niepce May 2023 updates Hub's wlog - Niepce April 2023 updates Hub's wlog - Niepce March 2023 updates Hub's wlog - Integrating the RawTherapee engine Hub's wlog - Niepce February 2023 updates Hub's wlog - Implementing i18n-format, a Rust procedural macro Hub's wlog - Niepce January 2023 updates Hub's wlog - i18n-format for Rust Hub's wlog - Introducing Toot That! Hub's wlog - Niepce December 2022 updates Hub's wlog - Niepce November 2022 updates Hub's wlog - Fall of releases Hub's wlog - Introducing Compiano Hub's wlog - RTKit, portals, and Pipewire Hub's wlog - Release day Hub's wlog - Update on Niepce Hub's wlog - New Again
Hub's wlog - libopenraw Rust with C API
:: Hubert Figuière · 2023-08-28 · via Hub's wlog

2023.08.28

As I previously talked about, I started porting libopenraw to Rust. It is now in a state where it has more feature than the original.

When I started writing this post, I didn't have 100% of the code Rust, but since I have removed the last bit of C++, for which I had cut corners to make sure to have a functional API for C.

The only C++ code left is the various utilities and the C++ test suite to validate.

The goal

The goal of the Rust rewrite is to have the digital camera raw parsing library written in Rust instead of C++, while still being available with a C API.

The goal of the updated C API is to be close to the original API. However it's also a good time to do some breaking changes. Notably most of the "objects" are now immutable.

Rewrite

I did the rewrite in a branch, aiming to provide the same level of functionality as the C++ code. One of the first step was to rewrite the test suite to use the same data set. Doing so did allow verifying the consistency in behaviour, a progressively implement all the features and formats.

The C++ code use inheritance a bit to override some of the behaviours based on which file format it was. One of the thing most camera raw file have in common is that they are mostly a TIFF file. However Rust doesn't do object-oriented. It has traits that allow implementing some level of polymorphism, but in that case the concept had to be rethought a little bit.

Benefits

This is where Rust shines.

First there are a lot of things Rust, or the ecosystem around, did for me. In C++ I had re-implemented a stream system to allow IO on buffers and handling endianess. In Rust you can just read from a slice (a fixed size array of data) with the Read trait, and there are built-in functions to read endian-specific values. I still have the memory of trying to figure out which include to add depending on the UNIX flavour, between Linux, macOS and the BSD.

Second, the Debug trait. Just derive Debug (it's a simple macro) and you can "print" an type like that, using string formats. In C++, well, it's a lot of work. And on enum types it will print a human readable value, ie the one you write in code.

Third, the safety. A lot of the safety feature of Rust prevent mistake. And at runtime, the bounds checking catch of a lot of things too. Being required to use Option<> or Result<> to handle cases where in C++ you'd get some null value.

At that point, a few bugs I identified porting / rewriting the code made their way to the 0.3.x series in C++.

Drawbacks

libopenraw requires a Rust compiler (technically it already did, but I know some packagers that did disable Rust1. This mean that non current architecture might not be supported. To me it's not a big issue, I target modern computers.

Testing

As mentioned I rewrote the test suite with the same data set. This is an essential part of making sure the features work as previously.

I also rewrote ordiag and the dumper ordumper. The dumper allow analyzing the structure of the file, and I didn't have this one in C++ (instead I had a more primitive exifdump). The dumper is heavily inspired from exifprobe that has served me well and that I forked. Really I can see the amount of work I didn't need to do with Rust.

To add to this I wrote libopenraw-viewer, a small Rust application to view the content of camera raw files. This allow much more easily to see the output. This has helped me to find fundamental bugs in some of the parsing that led to some fixes "upstream", namely into the C++ version (0.3.x branch). I should have done that a long time ago. This also allow me to test the Rust API.

C API adaptation

Last but not least I had to provide a C API. This allow using the library.

Rust to C ffi has limitations. You can basically pass numbers, pointers, and eventually simple structures.

The libopenraw API did return several types of "ref" which are just pointers to opaque types. The idea was always to only have opaque types through the API, which internally were C++ instances.

One of the key change is that the only object that can be explicitly be created with the API is ORRawFileRef, because it's the entry point. Very few need to be released, most are held by the containing objects.

Some other constraints of the C API directed some choices in the Rust API.

  • Raw files are no longer Box<> but Rc<> due to the need to retain them for the iterator.2
  • Metadata::String() contain a Vec<u8> instead of a String to allow for the NUL terminated strings in the C API. They are maybe not NUL terminated but ASCII.

New features

Meanwhile I added a few new features:

  • extracting the white balance on most files (saveral Nikon are not yet handled).
  • color converting from the camera space to sRGB on rendering.
  • a multi stage processing pipeline.

This is still not enough to have a complete processing pipeline, but it's a start. It's going towards the only two issue left in the issue tracker. Not that I don't expect more but it's a nice goal post.

Integration

I submitted a PR for Miniaturo to use the Rust version of the library. This is not ready to be merged, but this actually allowed me to fix a few API bits. The new Rust API is relatively close to the old API that was the Rust to C bindings.