I am talking with some people on the ASWF Slack, and they pointed me to the
OpenImageIO timeline C bindings project, which probably has a lot of good
lessons learned/things to borrow.

https://github.com/PixarAnimationStudios/OpenTimelineIO/pull/696
https://github.com/PixarAnimationStudios/OpenTimelineIO/tree/c-otio

On Mon, Oct 19, 2020 at 8:35 PM Scott Wilson <[email protected]> wrote:

> Works for me!
>
> Also, some other questions.
>
> - In the case of TypeDesc, we could probably have a 1:1 interface between
> C and C++. But something like ImageSpec would either have to replace the
> std::string with *char or we may need to make ImageSpec completely opaque.
> If we go for the latter, how do we want attrs such as width, height, etc to
> be exposed?
> - There's some cases where std::vectors are used. Two ways we could handle
> this are either to have structs that represent an owned or borrowed array
> (something like struct StringVector { String *ptr, size_t length }), or
> functions take a pointer + length in the arguments and structs hold a
> pointer and length. I personally like option 1, because it keeps all that
> information close together, and it makes the APIs have less arguments. The
> only problem with it that I can think of is how do we want to handle
> creating/deleting those structs? And do we want to have structs that are
> explicitly owning the data they point to, or borrowing them (to borrow some
> Rust terminology)?
> - This may be a small thing, but when it comes to deleting objects, even
> if they don't have pointers/own data, do we want to always include a
> Type_delete method? For example, TypeDesc doesn't have/need a destructor.
> If we say everything has a destructor, then would there be a problem with
> that?
> - How do we want to handle overrides? For example, if we have
> OIIO::ImageSpec.attribute("my_attr", 1.0), would we want to convert that
> into OIIO_ImageSpec_attribute_float("my_attr", 1.0)? What about with an
> unsigned integer? I'm assuming we'd want to call it
> OIIO_ImageSpec_attribute_uint(...). Also, in ImageInput, we have spec()
> with a reference to the ImageSpec, and spec(subimage, miplevel). I'm
> assuming the first will be OIIO_ImageInput_spec(), and the second will be
> OIIO_ImageInput_spec_with_subimage_miplevel(...) or something like that.
> - Since we're probably going to be passing around ImageInput and ImageBuf
> as pointers (since they're a unique_ptr in C++), do we want to always
> assume that a pointer to an ImageInput/Output/Buf are not null, or add a
> check in the code for that?
> - Does OIIO have exceptions? Either way, probably want to make sure any
> exceptions passed from C++ don't cross over to the other side.
>
> Unrelated, but I think I may have been making extra work for me with cxx
> in Rust. We may not actually need the header, but I haven't confirmed that.
> Either that, or we could probably put everything in the header. Either way,
> it's not related to the C project.
>
> On Mon, Oct 19, 2020 at 8:10 PM Anders Langlands <
> [email protected]> wrote:
>
>> I’d argue for Type_new and Type_delete when the underlying code is just
>> calling “new Type” and “delete Type” to make that explicit. Then overloads
>> would be Type_new_with_XXX.
>>
>> On Tue, 20 Oct 2020 at 15:31, Scott Wilson <[email protected]> wrote:
>>
>>> I've taken a look at a few C libraries, and here's my initial results:
>>>
>>> Git: (Example from commit.h)
>>> GIT_EXTERN(const git_oid *) git_commit_id(const git_commit *commit);
>>>
>>> Tensorflow:
>>> https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h
>>>
>>> SDL:
>>> https://github.com/SDL-mirror/SDL/blob/master/include/SDL_vulkan.h
>>>
>>> - Prefix is still important
>>> - It looks like the struct is prefixed, and the methods for the struct
>>> are prefixed with the struct. So, there may be a struct called
>>> git_repository, and the method would be called something like
>>> git_repository_open. For the most part, it looks like structs would be
>>> named something like OIIO_ImageBuf vs OIIOImageBuf. I personally don't like
>>> the _ in class/struct names, but I come from Python.
>>> - There doesn't seem to be a consensus on constructor/destructor naming.
>>> I'm guessing we may want to go for Type_init and Type_free? Or there's the
>>> Rust way Type_new and Type_drop.
>>> - If we want to borrow some conventions from Rust:
>>> https://rust-lang.github.io/api-guidelines/naming.html For example, a
>>> constructor is usually called Type::new(some_args: Arg) -> Type, or
>>> Type::with_something(something: Something) -> Type.
>>>
>>> On Mon, Oct 19, 2020 at 5:53 PM Larry Gritz <[email protected]> wrote:
>>>
>>>> As much as I'd like things as short as possible, I'd prefer names and
>>>> capitalization have as much symmetry as possible between the C++ and C
>>>> interfaces. For users trying to make sense of the APIs, we want to honor
>>>> the "principle of least surprise."
>>>>
>>>> But I'd certainly defer to modern C sensibilities, however they have
>>>> evolved their practices without true namespaces and classes.
>>>>
>>>>
>>>>
>>>> On Oct 19, 2020, at 5:23 PM, Scott Wilson <[email protected]>
>>>> wrote:
>>>>
>>>> Yeah, I think we'd want to target C99, because as far as I know, most
>>>> things with a C ffi target C99.
>>>>
>>>> I'll try to gather a list of C projects to see how they name things.
>>>> Also, I'll probably share some of how Rust names functions and methods to
>>>> hopefully gather some more options.
>>>>
>>>> On Mon., Oct. 19, 2020, 3:55 p.m. Anders Langlands, <
>>>> [email protected]> wrote:
>>>>
>>>>> I’d personally prefer to see if we could shorten the names a little so
>>>>> “oiio_ii_open” instead of “OIIO_ImageInput_open” if we could make sure 
>>>>> that
>>>>> there wouldn’t be any abbreviation conflicts. The long form does have the
>>>>> advantage that it’s unambiguous though.
>>>>>
>>>>> Regarding standards, Visual Studio has only just added support for C11
>>>>> and C17 in preview and I don’t think we’d need anything beyond C99 for an
>>>>> API wrapper anyway?
>>>>>
>>>>>
>>>>>
>>>>> On Tue, 20 Oct 2020 at 10:18, Larry Gritz <[email protected]> wrote:
>>>>>
>>>>>> I've been in C++ land for so long that I'm afraid I don't know the
>>>>>> idioms that modern C culture likes these days. Is what you describe
>>>>>> OIIO_ImageInput_open or OIIO_ImageBufAlgo_add... does that look like the
>>>>>> way a 2020 C programmer would try to "namespace" things in C that has no
>>>>>> namespaces? Or would a C programmer scoff at how wordy it is?
>>>>>>
>>>>>> As far as how to name overloads... I think it might be instructive to
>>>>>> look at a few individual cases first and what feels right, then see if 
>>>>>> they
>>>>>> generalize into an overall rule. I'm hesitant to propose a rule first
>>>>>> without examples to know if we're going to hate it in practice.
>>>>>>
>>>>>> Which C standard would you want to target?
>>>>>>
>>>>>> -- lg
>>>>>>
>>>>>>
>>>>>> On Oct 19, 2020, at 1:51 PM, Scott Wilson <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>> Sounds good to me. Also, if you want to automate the c bindings to
>>>>>> some degree, then you can look at
>>>>>> https://github.com/EmbarkStudios/physx-rs for inspiration. There's a
>>>>>> talk in the readme with their c bindings builder. Failing that, I'm fine
>>>>>> with going through the legwork of making the c interface.
>>>>>>
>>>>>> If I may make a suggestion for the naming, I'd suggest more or less
>>>>>> following what OIIO does in C++. So, for example,
>>>>>> OIIO::ImageInput.open(...) would be OIIO_ImageInput_open(...) and
>>>>>> classes/structs would be OIIOImageInput.
>>>>>>
>>>>>> The only question I have at the moment is how do we want to handle
>>>>>> naming functions with overrides?
>>>>>>
>>>>>> On Mon., Oct. 19, 2020, 1:00 p.m. Anders Langlands, <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Branching this thread to talk specifics...
>>>>>>>
>>>>>>> So to summarize the different approaches we've each taken, in my
>>>>>>> repo (https://github.com/anderslanglands/oiio-rs/tree/master/coiio)
>>>>>>> I have a small shim library that creates a C interface to OIIO by 
>>>>>>> wrapping
>>>>>>> with functions like:
>>>>>>>
>>>>>>> ImageBuf ImageBuf_create(const char* filename) {
>>>>>>>     return new OIIO::ImageBuf(OIIO::string_view(filename));
>>>>>>> }
>>>>>>>
>>>>>>> When building the rust crate, this is compiled into a static library
>>>>>>> by Cargo using CMake, with the environment variable OIIO_ROOT specifying
>>>>>>> the path to the OIIO installation. Currently the build script errors 
>>>>>>> out if
>>>>>>> OIIO_ROOT is not specified, but it would be trivial to have it default 
>>>>>>> to
>>>>>>> /usr/local etc. I also at one point had it downloading OIIO and 
>>>>>>> building it
>>>>>>> directly, but cmake-rs had some issues with always rebuilding OIIO on 
>>>>>>> any
>>>>>>> change to the crate, which made development interminable, so I stripped
>>>>>>> that out. That was nearly two years ago so may have been fixed. A good
>>>>>>> alternative would be to provide a separate (bash or python) build script
>>>>>>> that would download deps and run the build manually as a pre-process.
>>>>>>>
>>>>>>> From what I can tell from Scott's repo, cxx is doing essentially the
>>>>>>> same thing, but cxx handles building the shim library internally, so
>>>>>>> there's no need for invoking CMake from build.rs. Presumably you'd
>>>>>>> still need to specify the path to (and potentially build) OIIO and its 
>>>>>>> deps
>>>>>>> using this method. If you compare the code in Scott's repo to mine, you 
>>>>>>> can
>>>>>>> see they're very similar indeed.
>>>>>>>
>>>>>>> The issue I see here is that I don't think cxx actually saves you
>>>>>>> anything. In fact there's *more* code in the cxx case because you're
>>>>>>> specifying both the implementation (ffi.cpp) and the interface (ffi.h),
>>>>>>> whereas I only have to specify the implementation (coiio.cpp) and the
>>>>>>> interface is declared solely in ffi.rs.
>>>>>>>
>>>>>>> Building and linking the static library is the easiest part of the
>>>>>>> process, and is also the part that would be more generally useful 
>>>>>>> outside
>>>>>>> of just Rust - you could use that C interface to trivially bind any
>>>>>>> language you want, so I think we want to preserve that.
>>>>>>>
>>>>>>> That leaves the question of how do we generate the C interface in
>>>>>>> the first place. I've been doing it manually, which is a tedious 
>>>>>>> process,
>>>>>>> but works. Since it's just calling the C++ directly I think it's also
>>>>>>> reasonably sturdy against changes to the underlying OIIO API, since the
>>>>>>> compiler should catch most misuses, although I'm sure there are plenty 
>>>>>>> of
>>>>>>> opportunities for subtle bugs still. Not to mention bikeshedding about
>>>>>>> naming conventions and code styles :)
>>>>>>>
>>>>>>> My idea for how to make the binding generation more automatic was to
>>>>>>> try and leverage libclang to generate the C wrappers semi-automatically.
>>>>>>> This would still require a fair amount of code: first writing the 
>>>>>>> binding
>>>>>>> generator, then writing the rules for how to wrap the C++ API, but 
>>>>>>> should
>>>>>>> allow generating the C API automatically, rather than maintaining it
>>>>>>> manually for every release. The downside is obviously this tool doesn't
>>>>>>> exist yet, and it would add a (optional) dependency on clang to the 
>>>>>>> project.
>>>>>>>
>>>>>>> I think the best course of action here would be to write a C wrapper
>>>>>>> in OIIO itself that could be maintained along with the rest of the 
>>>>>>> project.
>>>>>>> This would build a little C99 library that could be installed alongside 
>>>>>>> the
>>>>>>> C++ library. This would unfortunately mean manually writing a header to 
>>>>>>> go
>>>>>>> with it, although that part could probably be automated with a little
>>>>>>> scripting.
>>>>>>>
>>>>>>> Then oiio-rs should be a completely separate Rust crate that just
>>>>>>> uses bindgen to generate the unsafe API from the C library 
>>>>>>> automatically,
>>>>>>> and provides a safe API on top of that. (Larry - Rust/Cargo kinda 
>>>>>>> assumes
>>>>>>> that Cargo is the thing doing all the building and dependency 
>>>>>>> management,
>>>>>>> so trying to provide a Rust artefact from the OIIO build process would 
>>>>>>> be
>>>>>>> painful if it's possible at all).
>>>>>>>
>>>>>>> Let me know what you think.
>>>>>>>
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Anders
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, 20 Oct 2020 at 02:53, Alvaro Castaneda <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi Larry and Anders
>>>>>>>> I'm helping Scott with the Rust Wrapper.
>>>>>>>> using CXX is been good, it is a very manual process and makes it
>>>>>>>> only usable in Rust, Larry you mentioned a minimal C API, that would 
>>>>>>>> make
>>>>>>>> it much simpler to wrap to Rust, that would also mean in can be 
>>>>>>>> wrapped to
>>>>>>>> many other languages,
>>>>>>>> So far we didn't want to go the C route, but that might not be a
>>>>>>>> bad idea since it would open the library a lot more and it might make 
>>>>>>>> it
>>>>>>>> simpler to automate, at least the bulk of it, for Rust.
>>>>>>>>
>>>>>>>> We need to discuss the approach.
>>>>>>>>
>>>>>>>> On Sun, Oct 18, 2020 at 8:40 PM Anders Langlands <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Scott, yes please do add me to the repo I’d love to take a look
>>>>>>>>> and pitch in as time allows.
>>>>>>>>>
>>>>>>>>> On Mon, 19 Oct 2020 at 13:43, Scott Wilson <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Hey Anders,
>>>>>>>>>>
>>>>>>>>>> Cxx has so far been pretty okay. It's pretty manual (hopefully
>>>>>>>>>> autocxx makes it better, but as far as I know, it's still nowhere 
>>>>>>>>>> ready for
>>>>>>>>>> using it on OpenImageIO). Right now the process looks something like 
>>>>>>>>>> this:
>>>>>>>>>>
>>>>>>>>>> 1. Create a header/cpp file that contains all of your class
>>>>>>>>>> methods as functions.
>>>>>>>>>> 2. Create an unsafe Rust interferface that's a 1 to 1 copy of the
>>>>>>>>>> C++ side.
>>>>>>>>>> 3. Create a safe Rust interface.
>>>>>>>>>>
>>>>>>>>>> For me, the really nice thing is I don't need to worry about the
>>>>>>>>>> C++ -> C -> Rust steps. It drops the C step, but I still need to 
>>>>>>>>>> write that
>>>>>>>>>> C++ "ugly" interface.
>>>>>>>>>>
>>>>>>>>>> Also, if you want to join in on the fun, our repo is currently
>>>>>>>>>> private while we get things to a working state. But, I can add you 
>>>>>>>>>> to the
>>>>>>>>>> repo. Otherwise, I'm up for a discussion on how to take both designs 
>>>>>>>>>> and
>>>>>>>>>> come up with the best one.
>>>>>>>>>>
>>>>>>>>>> On Sun, Oct 18, 2020 at 4:51 PM Anders Langlands <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Wrapping C in Rust is a two-stage process: first writing an
>>>>>>>>>>> "unsafe" FFI binding to the C API, which is usually almost 
>>>>>>>>>>> completely
>>>>>>>>>>> automated with a crate called bindgen, then writing a "safe" crate 
>>>>>>>>>>> that
>>>>>>>>>>> provides a Rust-y API using the unsafe FFI bindings. Wrapping C++ 
>>>>>>>>>>> means
>>>>>>>>>>> writing a C API first, then binding that to Rust, which is what my 
>>>>>>>>>>> crate
>>>>>>>>>>> does.
>>>>>>>>>>>
>>>>>>>>>>> I've been meaning to return to this (and OSL, OpenSubdiv and
>>>>>>>>>>> others) at some point and try to make a project-specific C-binding
>>>>>>>>>>> generator using libclang, as manually maintaining the C stubs is 
>>>>>>>>>>> laborious
>>>>>>>>>>> and error-prone.
>>>>>>>>>>>
>>>>>>>>>>> Scott, I'd be curious to know how you're getting on with cxx,
>>>>>>>>>>> I've been meaning to look into that. I'd be happy to collaborate on
>>>>>>>>>>> something we could integrate into the main project as Larry 
>>>>>>>>>>> suggests.
>>>>>>>>>>>
>>>>>>>>>>> On Mon, 19 Oct 2020 at 12:30, Larry Gritz <[email protected]>
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Feel free to have the discussion on-list, I'm sure it would be
>>>>>>>>>>>> of interest to many.
>>>>>>>>>>>>
>>>>>>>>>>>> If there was consensus on what the Rust APIs should look like,
>>>>>>>>>>>> I would welcome adding a set of Rust bindings to the main OIIO
>>>>>>>>>>>> distribution. Assuming that makes sense, I was thinking it would 
>>>>>>>>>>>> be much
>>>>>>>>>>>> like we now have with the Python bindings. The advantage to making 
>>>>>>>>>>>> Rust
>>>>>>>>>>>> bindings part of the main build would be that it could be built 
>>>>>>>>>>>> and tested
>>>>>>>>>>>> as part of our CI, versioned along with the rest of OIIO, and 
>>>>>>>>>>>> essentially
>>>>>>>>>>>> never allowed to break. Also, just like we would never accept a PR 
>>>>>>>>>>>> that
>>>>>>>>>>>> added C++ functionality without making sure the Python bindings 
>>>>>>>>>>>> kept up, we
>>>>>>>>>>>> could ensure that nothing is left out of the Rust bindings. While 
>>>>>>>>>>>> I can
>>>>>>>>>>>> appreciate the cleanliness and independence of it being a separate 
>>>>>>>>>>>> project,
>>>>>>>>>>>> I can't help but think that it will be a neverending nightmare to 
>>>>>>>>>>>> try to
>>>>>>>>>>>> keep the bindings in sync with the main project.
>>>>>>>>>>>>
>>>>>>>>>>>> I don't know how automated it is to make Rust bindings for C (I
>>>>>>>>>>>> know it's a PITA for C++), but if making Rust bindings is 
>>>>>>>>>>>> substantially
>>>>>>>>>>>> easier if you had minimal plain C wrappers for the major C++ 
>>>>>>>>>>>> classes, I'm
>>>>>>>>>>>> sure there would be a lot of happy consumers of that even outside 
>>>>>>>>>>>> the Rust
>>>>>>>>>>>> interest group.
>>>>>>>>>>>>
>>>>>>>>>>>> I haven't had time to try Rust myself for any programming
>>>>>>>>>>>> project, though I've followed it from afar and like the idea of 
>>>>>>>>>>>> helping
>>>>>>>>>>>> that community. TBH, the main thing that keeps me from spending 
>>>>>>>>>>>> any time on
>>>>>>>>>>>> Rust is just that I can't contemplate the hassle of trying to 
>>>>>>>>>>>> program
>>>>>>>>>>>> without my favourite libraries, and having OIIO (and its many 
>>>>>>>>>>>> utilities
>>>>>>>>>>>> that I reuse in basically everything I write) available in Rust 
>>>>>>>>>>>> will
>>>>>>>>>>>> substantially lower the bar for me to dabble in it more.
>>>>>>>>>>>>
>>>>>>>>>>>> -- lg
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Oct 18, 2020, at 4:12 PM, Scott Wilson <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> Hey Anders,
>>>>>>>>>>>>
>>>>>>>>>>>> We were inspired by what you did, and also decided to see if we
>>>>>>>>>>>> can take this in a slightly different direction/ use cxx. If you're
>>>>>>>>>>>> interested in discussing the wrapper more we can take it off the 
>>>>>>>>>>>> list.
>>>>>>>>>>>>
>>>>>>>>>>>> On Sun, Oct 18, 2020 at 3:35 PM Anders Langlands <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> I also have a rust binding here if you're interested:
>>>>>>>>>>>>> https://github.com/anderslanglands/oiio-rs
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Sun, 18 Oct 2020 at 04:43, Scott Wilson <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Awesome, thank you very much! I'll try this out and see how
>>>>>>>>>>>>>> badly I break things.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Sat., Oct. 17, 2020, 1:02 a.m. Larry Gritz, <
>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If you know the true legal extent of the memory allocation
>>>>>>>>>>>>>>> in which that data pointer is located (in this case, the 
>>>>>>>>>>>>>>> beginning and
>>>>>>>>>>>>>>> ending of the vector, if you are passing a pointer to one of 
>>>>>>>>>>>>>>> the elements
>>>>>>>>>>>>>>> of that vector), then I think you could certainly consider it 
>>>>>>>>>>>>>>> an error if
>>>>>>>>>>>>>>> any of these addresses lay outside that buffer:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     data + xstride*width - 1
>>>>>>>>>>>>>>>     data + ystride*height - 1
>>>>>>>>>>>>>>>     data + ystride*(height - 1) + xstride*width - 1
>>>>>>>>>>>>>>>     data + zstride*depth
>>>>>>>>>>>>>>>     data + zstride*(depth - 1) + ystride*height - 1
>>>>>>>>>>>>>>>     data + zstride*(depth - 1) + ystride*(height - 1) +
>>>>>>>>>>>>>>> xstride*width - 1
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> There may be a more succinct way to put that, but I think it
>>>>>>>>>>>>>>> covers all the cases of + and - strides.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Oct 17, 2020, at 12:42 AM, Scott Wilson <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks! I guess to come from this at a different angle,
>>>>>>>>>>>>>>> let's say I'm doing something like this:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> std::vector<uint8_t> pixels(10*10*3*1);
>>>>>>>>>>>>>>> ImageInput.read_image(TypeDesc::UINT8, @pixels[0])
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Would there be a case where I could pick a stride value that
>>>>>>>>>>>>>>> would fall outside the pixels vector?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> PS: Thanks! I'm working on this with a friend, and hope to
>>>>>>>>>>>>>>> have something released in the near future.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Fri., Oct. 16, 2020, 11:47 p.m. Larry Gritz, <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Oops, my math was wrong (in an unimportant detail): If you
>>>>>>>>>>>>>>>> are making a mosaic of 16x5 of these 10x10 images, it is 80 
>>>>>>>>>>>>>>>> small images
>>>>>>>>>>>>>>>> you are assembling in total, not 40.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Oct 16, 2020, at 11:43 PM, Larry Gritz <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The strides don't describe the size of the image, they are
>>>>>>>>>>>>>>>> the spacing in memory of where you want the values to be 
>>>>>>>>>>>>>>>> placed upon being
>>>>>>>>>>>>>>>> read (or taken from in order to write). There is no invalid 
>>>>>>>>>>>>>>>> set of strides,
>>>>>>>>>>>>>>>> because the caller might want them to end up anywhere in 
>>>>>>>>>>>>>>>> memory.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Or am I misunderstanding?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> For a fully "contiguous" memory buffer where you intend for
>>>>>>>>>>>>>>>> every plane, scanline, pixel, and channel immediately follows 
>>>>>>>>>>>>>>>> the previous
>>>>>>>>>>>>>>>> one, then in our example the strides would be xstride=3, 
>>>>>>>>>>>>>>>> ystride=30,
>>>>>>>>>>>>>>>> zstride=300. (Though for a 2D image, the zstride is not used.)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Here's an example of where you might have a stride range
>>>>>>>>>>>>>>>> that is wildly outside this: Let's say that you have 40 of 
>>>>>>>>>>>>>>>> these 10 x 10 x
>>>>>>>>>>>>>>>> 3 x uint8 image files and you are trying to read them in and 
>>>>>>>>>>>>>>>> assemble them
>>>>>>>>>>>>>>>> into a single RGBA mosaic image of 16x5 x 4 x uint8 (the 
>>>>>>>>>>>>>>>> additional channel
>>>>>>>>>>>>>>>> is alpha, which you will separately fill in as 1.0 [or 255 
>>>>>>>>>>>>>>>> uint8] because
>>>>>>>>>>>>>>>> it's not in your RGB files).  Here's a cartoon to illustrate 
>>>>>>>>>>>>>>>> this:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   +-----------------------------------------+
>>>>>>>>>>>>>>>>   | | | | | | | | | | | | | | | | | | | | | |
>>>>>>>>>>>>>>>>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
>>>>>>>>>>>>>>>>   | | | | | | | | | | | | | | | | | | | | | |
>>>>>>>>>>>>>>>>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
>>>>>>>>>>>>>>>>   | | | | | | | | | |X| | | | | | | | | | | |
>>>>>>>>>>>>>>>>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
>>>>>>>>>>>>>>>>   | | | | | | | | | | | | | | | | | | | | | |
>>>>>>>>>>>>>>>>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
>>>>>>>>>>>>>>>>   | | | | | | | | | | | | | | | | | | | | | |
>>>>>>>>>>>>>>>>   +-----------------------------------------+
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Each of my little grid cells is a 10x10 image. But that
>>>>>>>>>>>>>>>> 10x10 image denoted by the "X" needs to be placed in memory in 
>>>>>>>>>>>>>>>> the right
>>>>>>>>>>>>>>>> portion of the 16x10 x 5x10 mosaic. So what are the strides we 
>>>>>>>>>>>>>>>> use for the
>>>>>>>>>>>>>>>> read? Well, the xstride is 4 because we're making room for an 
>>>>>>>>>>>>>>>> alpha channel
>>>>>>>>>>>>>>>> that wasn't present in the file, the ystride is 640 (= 
>>>>>>>>>>>>>>>> 10*16*4), because
>>>>>>>>>>>>>>>> each scanline of the little 10x10 image that you read needs to 
>>>>>>>>>>>>>>>> be placed on
>>>>>>>>>>>>>>>> the proper scanline of the 160x50 mosaic you are assembling in 
>>>>>>>>>>>>>>>> memory.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --  lg
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> P.S. Woo-hoo for making a Rust wrapper. I think that's a
>>>>>>>>>>>>>>>> totally great thing.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Oct 16, 2020, at 10:46 PM, Scott Wilson <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm experimenting with a Rust wrapper for OIIO, and had
>>>>>>>>>>>>>>>> some questions about the stride.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Let's say I have an image that is 10x10 pixels, and 3
>>>>>>>>>>>>>>>> channels, and 1 byte per channel. What strides would be 
>>>>>>>>>>>>>>>> invalid for that
>>>>>>>>>>>>>>>> image? I'm guessing that anything between -10 * 10 * 3 * 1 to 
>>>>>>>>>>>>>>>> 10 * 10 * 3 *
>>>>>>>>>>>>>>>> 1 and the AutoStride would be valid, and everything else may 
>>>>>>>>>>>>>>>> try to access
>>>>>>>>>>>>>>>> memory that isn't initialized. Is this assumption correct, or 
>>>>>>>>>>>>>>>> am I missing
>>>>>>>>>>>>>>>> something?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks!
>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Larry Gritz
>>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Larry Gritz
>>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> Larry Gritz
>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>>>
>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>
>>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>>
>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>
>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Larry Gritz
>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>
>>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>>
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>>> [email protected]
>>>>>>>>>>>
>>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> Oiio-dev mailing list
>>>>>>>>>> [email protected]
>>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> Oiio-dev mailing list
>>>>>>>>> [email protected]
>>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> Oiio-dev mailing list
>>>>>>>> [email protected]
>>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> Oiio-dev mailing list
>>>>>>> [email protected]
>>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>>
>>>>>> _______________________________________________
>>>>>> Oiio-dev mailing list
>>>>>> [email protected]
>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Larry Gritz
>>>>>> [email protected]
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> Oiio-dev mailing list
>>>>>> [email protected]
>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>>
>>>>> _______________________________________________
>>>>> Oiio-dev mailing list
>>>>> [email protected]
>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>>
>>>> _______________________________________________
>>>> Oiio-dev mailing list
>>>> [email protected]
>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>
>>>>
>>>> --
>>>> Larry Gritz
>>>> [email protected]
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Oiio-dev mailing list
>>>> [email protected]
>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>>
>>> _______________________________________________
>>> Oiio-dev mailing list
>>> [email protected]
>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>
>> _______________________________________________
>> Oiio-dev mailing list
>> [email protected]
>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>
>
_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to