pytroll / aggdraw

Python package wrapping AGG2 drawing functionality

Home Page:https://aggdraw.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Upgrade to agg 2.4

karimbahgat opened this issue · comments

I agree with @djhoese in this thread that upgrading to v2.4 would require a more solid set of tests. So I hope the tests get in place in order that we can do the upgrade to 2.4, the API isn't that complicated luckily. The reason being that it's the most recent (and final) version, and once we start doing changes to aggdraw it's going to get more and more difficult to upgrade the underlaying agg version. So in my view it should be a priority to get this done at an early stage.

Agreed. I've been thinking the same thing. To me this also leads to the question of changing what method is used for wrapping the C code. Handling the unicode/str conversions in the bare C extension was some of the most annoying code I've had to write in the last year because of my inexperience with the python C API. We could switch to using cython for 99% of the code and import the C library from there. This should make the code easier to understand on the aggdraw side and be less error prone.

We could also switch to using something like SWIG but I've never used myself.

If the migration to 2.4 is going to be done with the C extension code as it is currently then I think python 2 support should be dropped unless the migration is trivial (doubt it). Supporting python 2 doesn't make sense anymore IMO.

Lastly it looks like 2.5 is the newest: http://antigrain.com/download/index.html

I'm marking this as a 2.0 feature but that depends entirely on what is required to do this upgrade. If the interfaces are close enough then updating the existing extension code should be good enough and could be released as a 1.4 release. Switching to SWIG or Cython (my preference) could/should include some interface changes and some analysis of PIL's interfaces to see if anything can be shared. This should probably be considered a 2.0-worthy set of changes.

Another issue to consider: agg 2.4 is dual licensed, agg 2.5 is GPL: http://www.antigrain.com/license/index.html#PAGE_LICENSE

Aggdraw is under a custom license with copyrights from multiple people/groups. If we update the version of agg2 that is used/bundled then we'll have to update the copyright here: https://github.com/pytroll/aggdraw/blob/master/LICENSE.txt

My understanding is we can't change the software license for aggdraw without getting permission from all previous developers. I'm not so sure that is going to happen.

Good points. Ok so then the newest one is 2.5, and it seems the current agg version that aggdraw is based on is 2.0. I hadn't thought of the licensing issue, and this may depend what license 2.0 uses (the license page only mentions 2.4 and 2.5). So if I understand you correctly, if the agg license for 2.0 (current) differs from 2.4/2.5 then we can't update to that version due to the issues you mention?

Regarding the C code wrapping method, when you say bare C extension, do you mean Python's built in C++ wrapping interface (ie the .cxx file)? I don't have much experience wrapping C/++ code either. Switching to SWIG or Cython, would that require a dependency for the end-users, or only for the developers?

In the final analysis, I suppose it may also boil down to whether it's even worth the effort to update to the newer version. I.e. what additional features have been added in 2.4/2.5 vs 2.0, is something that should be explored. If nothing important, then probably no point even going down this route.

Regarding the licenses, we should be theoretically fine except for in aggdraw's specific case which involves bundling agg2 with aggdraw. If agg 2.5 is GPL then bundling inside aggdraw could be seen as "linking" or "distributing" it with aggdraw which due to the way GPL works would mean that aggdraw would also need to be GPL. That would mean changing the license of aggdraw to GPL which in theory requires the approval of all aggdraw contributors. If agg 2.4 is BSD-based then we should be fine...I think. I'm not a lawyer.

Yes, by bare C extension I meant the .cxx file currently in aggdraw, which is directly using the python C API. In the case of SWIG I think there may be some dependencies on some swig stuff. In the case of cython, when done properly, it should only mean another dependency for the developers. Cython takes files that are very similar to python but can have a lot of added information related to C typing and links to C header files. Developers would use cython to take these files and convert them to C/C++ files that directly use the python C API (a "bare" extension).

You made a good point earlier that we may want to at least use the newest interface so future updates aren't that bad. That said, if it works the way it is then you're right it depends on what features could be added. If I recall correctly @mraspaud has mentioned that alpha handling isn't great in aggdraw and sometimes you get unexpected results.

Note that I ported aggdraw to 2.4 already a few years back. See repo at http://github.com/dov/aggdraw . This version also includes a few bugfixes and extensions (e.g. 8-bit gray image) that I made to agg.

When I'll have time I'll have a look at the differences and will see how difficult it will be to create a pull request.

Note that agg 2.2 is geometrically unstable, and agg 2.4 is much improved.

Just a few comments about agg that I have had a lot of experience with. As I said in my previous comments agg 2.2 and earlier are unstable geometrically. This means things like if you anchor a triangle at a vertex and you scale it, you will get different rasterization around the same vertex. For our use case that was completely unacceptable, and we found 2.4 to be much more stable.

Regarding agg itself, the original author, Maxim Shemanarev, who sadly passed away a few years back, changed the license between version 2.4 and 2.5 from BSD to GPL, but did not make any changes to the code. There is therefore in principle no difference in targeting 2.4 and 2.5 and I prefer 2.4 because of its more liberal license.

I would recommend in keeping the Python C-API code. agg is using C++ in a quite a special way, by building pipelines that are connected through C++ templates. There is no automatic parsing like Cython, SWIG, that has any chance of dealing with that. It is not clear to me if and how to express such complex pipelines in python and how to map that to agg. See e.g. the line_patterns.cpp example on the demo page.

In any case, I'm happy to see that this project isn't dead.

I almost finished the merge between this version and my version, though a couple of tests are still failing. (See the branch troll in my repo).

@dov Thanks for the update, information, and all the work. Sounds like agg 2.4 is the way to go. Once you've gotten things working and make a pull request, I'll make sure to more thoroughly review it.

As for a more python-friendly C++ wrapper, I think Cython should be perfectly fine handling C++ templates. See https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html#templates
I'm not super experienced with C++ but I have converted C code to C++ to take advantage of templates and then linked that to a cython module. Worst case we would have to explicitly declare each of the accepted types (don't you have to do that anyway with C++ templates?).

I'm not sure I mentioned it here but started an issue for it in #43, the classes in aggdraw are not standard python classes, but rather functions that create new types/objects. Doing things with Cython should make this less of a headache to convert/fix. Nothing urgent, but thought I'd mention it here.

Done in #48 . :-)

I believe this issue may be closed as my 2.4 branch has been merged.

Yep, thanks.