Add server JSON endpoint

Reserved endpoints for fully encoded arbitrary requests, though, where we can pass through auth info to the upstream gateway

HTTP caching at build layer

maybe move imageflow_abi header gen to a test? probably adds to build time.

Add security policies


Add server configuration via TOML (or JSON API?) We need a form of persistence that is lightweight and not always tied to the filesystem.


///img hash https://github.com/abonander/img_hash is interesting


https://github.com/luser/integrating-rust-into-existing-projects


### For troubleshooting and reporting panics.

--troubleshoot-package [optional file name - otherwise use current params set to create it]

Add a 'troubleshooting' module which can load (or use) one of these data structures, then perform various transformations on it.
We'll call these experiments. The experiments will help narrow down the problem area, or shrink the repro case.

If the unmodified job fails, but the translated/portable job has a different error (or none), then it may be I/O related.
If the translated job fails, but we can read dimensions of all input images and decode them, then it is related to the job.
If we replace jpegs with blank jpegs of the same size, and 24 and 32-bit PNGs with  blank 24 and 32-bit PNGs of the same size,
and the error is not reproduced, then we know that a detail of the original files is triggering it. If the error is reproduced,
then we can further shrink the problem.
We can then use 3x3 (or a tiny, but similar ratio size to original) images, and see if the problem is still reproduced.
We can then (whether 3x3 works or not, or blanks work or not), start deleting nodes from the encoders inward,
until we get a success.
When calling the child imageflow_tool process, we must differentiate between JSON syntax errors and true panics. Thus
we should return JSON for errors that are unquestionably the user's and use a different exit code.

We store the results of these experiments in JSON, but also in a plain-text human readable summary.
If we have record of previous experiments results from a different platform, we show a table of comparisons on succeed/fail and exit codes.


We store the commit ID of imageflow_tool used alone in a file named "imageflow_commit_id" in the root of the .zip package.

We upload to S3, and have CreateObject trigger an AWS lambda.
AWS lambda fetches package, then fetches the Imageflow build for that commit ID and a matching glibc. We run that
imageflow_tool in --troubleshoot-package mode against the uploaded file, and let it augment the report on a different OS.
We then ship that report to lilith@imazen.io, or some other system, and upload the
complete pacakge (perhaps in interactive HTML form) to Amazon S3 again.

If we want to store image output for multiple experiments, we should rename them to their checksum and edit the experiment JSON.

We could also enable graph exporting, and store that result for each experiment.
Rendering with https://stackoverflow.com/questions/22595493/reading-dot-files-in-javascript-d3 ?

We need to be able to 'fast-forward' a case to a newer commit; see if it changes.

.zip files are the universal container format: https://mvdnes.github.io/rust-docs/zip-rs/zip/write/struct.ZipWriter.html
compression quality doesn't matter much.

We will end up with many columns (rows per experiment), including (original version on user OS), (linux, same version), (linux, latest version). (linux, latest version that doesn't fail), (linux, next failing version)

 We want an S3 listing that makes it easy to go through and fast-forward everything. Should we use UTC date of plus a hash? Shuffle forward based on success?





## For troubleshooting visual bugs

- Let the user try png32 output first.

- These can also be platform-specific.

- for certain known graphs we could craft an equivalent ImageMagick command/script and the compare the result

--result-is-wrong





Create constraint node
https://github.com/riapi/riapi/blob/master/level-1.md
width/height/mode/scale/anchor

Create server

Create RIAPI wrapper

Create backend-agnostic Client API (takes binary blobs online). It can use FFI, server, or command-line tool.


* GIF codec
* Animated GIF codec
* quantization API
* Composition API
* White balance API
* cost estimation


Refine the JSON API

Reconsider graph_recording design
Reconsider no_gamma_correction flag placement



We probably need a way for clients to hint they're going to reuse an input soon

-----

Port visual helpers to Rust and add upload support. Make more general, add JSON support?

Put all graph recording results in a graph_recording subfolder

Test pulling from a decoder into several different nodes

Roundtrip and compare various things (like flips)


## Unhappy path work below
-------------------------

4. Validate nodes/inputs/outputs

Define error handling convention

Rust panic sources
* OOM panics, but we want to rescue it.
* Some invalid input will panic (most, until later in development)
* Bugs should panic (but some may fail Result instead)

Context error sources:
* OOM
* I/O error
* Not implemented
* Invalid/null argument, invalid dimensions/format, other invalid args
* Encoding/decoding failed
* Item does not exist

Rust error sources:
* JSON parsing error
* Node validation
* Graph validation
* lots of other things

Constraints:
* Panics must *always* be caught at the FFI boundary
* Panics and unwinding are expensive, and should never happen in normal situations.

Hacks
* We can change the value Panics-on-OOM provide, to treat them differently.
* backtrace-rs lets us resolve symbols/filenames/line numbers directly.


Thoughts:
Mirror JSON and Context error data, always. If a message doesn't have a successful response, they need to call
clear_error. We can probably condense status codes, though.




Don't panic on bad JSON or input; return a Result, and get it right.

It's okay to panic on OOM, but catch it


## Rust todo

Error 0495 is missing from the compiler error index
https://is.gd/Y228qT

Examples of visibility and access would be good
Examples of &mut self issues and resolutions
Examples of 'static being the default for owned types, etc.

https://github.com/servo/rust-smallvec

Expired patents: https://vision.arc.nasa.gov/publications/MinimumPerceptualError.pdf
https://vision.arc.nasa.gov/publications/patent97.pdf
https://vision.arc.nasa.gov/publications/publications.html#compression


## From Readme


### Algorithm implementation work

- [x] Fast image resampling (scaling) with superb quality & speed
- [x] Basic operations (crop, rotate, flip, expand canvas, fill rectangle)
- [x] Support color profile, convert to sRGB
- [x] Image blending and composition (no external API yet)
- [x] Whitespace detection/cropping (no external API yet)
- [x] Ideal scaling-integrated sharpening for subpixel accuracy.
- [x] Automatic white balance correction.  (no external API yet)
- [ ] Time-constant gaussian approximation (%97) blur (1 bug remaining)
- [ ] Improve contrast/saturation/luma adjustment ergonomics
- [x] Integrate libjpeg-turbo (read/write)
- [x] Create correct and optimized IDCT downscaling for libjpeg-turbo (linear light, robidoux filter)
- [x] Integrate libpng (read/write) (32-bit only)
- [ ] Integrate Rust gif codec
- [ ] Support animated gifs
- [ ] Support metadata reading and writing (exif orientation and color profile support done)
- [ ] Histogram support
- [ ] Document type detection
- [ ] Generic convolution support
- [ ] Add 128-bit color depth support for all operations (most already use 128-bit internally)
- [ ] Integrate libimagequant for optimal 8-bit png and gif file sizes.
- [x] Build command-line tool for users to experiment with during Kickstarter. 
- [ ] Implement cost estimation for all operations
- [ ] Add subpixel cropping during scale to compensate for IDCT block scaling where subpixel accuracy can be reduced.
- [x] Auto-generate animated gifs of the operation graph evolution during execution.  
- [ ] Create face and object detection plugin for smart cropping. Not in main binary, though. 
- [ ] Reason about signal-to-noise ratio changes, decoder hints, and determine best codec tuning for optimal quality. Let's make a better photocopier (jpeg). 


### API Work
- [x] Expose an xplat API (using direct operation graph construction) and test via Ruby FFI bindings.
- [x] Validate basic functionality via simple ruby REST [RIAPI](http://riapi.org) server to wrap libimageflow
- [x] Design correct error handling protocol so all APIs report detailed stacktrace w/ line numbers and useful error messages for all API surfaces. 
- [x] Expose flexible I/O interface so a variety if I/O types can be cleanly supported from host languages (I.e, .NET Stream, FILE *, membuffer, circular buffer, etc)
- [x] Replace direct graph manipulation with JSON API
- [ ] Finish API design and test coverage for image composition, whitespace detection/cropping, sharpening, blurring, contrast/saturation, and white balance (algorithms already complete or well defined). 
- [ ] Create plugin interface for codecs 
- [ ] Create documentation
- [ ] Create .NET Full/Core bindings
- [ ] Create Node bindings 

### Refactorings

- [ ] replace zlib with zlib-ng
- [ ] Look into replacing parts of the jpeg codec with concurrent alternatives. 
- [ ] Add fuzz testing for JSON and I/O 
- [ ] Find cleaner way to use SSE2 constructs with scalar fallbacks, it is messy in a few areas.

