anchor.diff:  unlock(this.javaObj);
   ----
   
  -Note that `memmapfile` assumes that the data doesn't change and internally only returns a pointer to the underlying data. Thus, we need to force a copy, e.g., by multiplying by one. Also, the simplified code snippet above does not guarantee correct behavior as users could interrupt the execution (ctrl+c) between the `lock` and `unlock` operations. We can solve this by doing one of the following
  +Note that the code could be interrupted (ctrl+c) at any line, so we would need to use a custom locking mechanism that can handle bad states, or guarantee unlocking via a destructor or link:https://mathworks.com/help/matlab/ref/oncleanup.html[onCleanup].
  +
  +The multiplication by one forces a copy of the data. This is necessary because under-the-hood `memmapfile` only returns a pointer to the underlying memory.
  +
  +////
  +We can solve this by doing one of the following
   
   * Make the internal logic smart enough to handle cases where users didn't call `unlock`
   * Use link:https://mathworks.com/help/matlab/ref/oncleanup.html[onCleanup] to guarantee unlocking, e.g., `c = onCleanup(@()unlock(this.javaObj))`
   * Create a custom class that locks in the constructor and unlocks in the destructor
   
   However, even if the `unlock` call is in a destructor (guaranteed to run when exiting scope), the Java logic still needs to handle cases where the code gets interrupted before the `lock` call.
  +////
   
   == Results
   
  
positive.code: 
  *5. MATLAB Layout as Shared Memory*
  
  This approach is the same as 4. with the difference being that the data is exchanged through shared memory using link:https://mathworks.com/help/matlab/ref/memmapfile.html[memmapfile], thus bypassing the Java translation layer entirely. Shared memory is typically used for inter-process communication, but it can also be used within a single process. Running it in the same process also simplifies synchronization since we can use standard Java locks.
  
  [source,matlab]
  ----
  
negative.code: 
  == Data Translation
  
  We compared five different ways to get image data from Java into MATLAB. Note that the benchmarks in this section measure only the overhead on the MATLAB main thread. The reason for this is that while additional overhead in a background thread may increase overall latency, it doesn't impact the time budget available for the processing. The full benchmark code is available link:https://github.com/HebiRobotics/HebiCam/tree/benchmark[here].
  
  *1. Default 3D Array*
  
  By default MATLAB image matrices convert to `byte[height][width][channels]` Java arrays. However, when converting back to MATLAB there are some additional problems:
  
  * `byte` gets converted to `int8` instead of `uint8`, resulting in an invalid image matrix
  * a standard cast calling `uint8(matrix)` doesn't work because it sets all negative values to zero
  