Integral Rotations

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
*void

Integral Rotations

Post by *void »

I would like to plead for the addition of a method to the MagickWand API which would be a MagickWand wrapper to IntegralRotateImage. Implementation should be simple and obvious. I fully realize that MagickRotateImage ultimately degenerates to IntegralRotateImage if the argument is recognized as an exact multiple of 90 degrees. However:

1. When I want exact integers, I don't use real numeric types in my software. From long experience, I am leery of hoping integers passed as reals will be correctly recognized 100% of the time as exact integers. I visualize images rotated "almost" 90 degrees going to a printer which will then magnify the error, all because fuzz got set too tight in some part of the program. Maybe it can't happen but.....

2. I expect 99.9% of the rotate calls in any program I write will be integral rotates. The extra baggage of creating a dummy "filler" PixelWand that is unneeded for those calls is a pain, and also wasteful. I suggest that is also true for 99% of other programmers who might use MagickWand.

3. Why pay the extra overhead of the more general method, when my program knows in advance it wants an exact multiple of 90 degree rotations? The extra overhead may be relatively small, but if I have a few thousand to do...

I hope this will be given serious consideration in a future release.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Post by magick »

Its unlikely we will add IntegralRotateImage() to the MagickWand API. A good API design strives to have only one way to do one thing and you can integral rotate already with angles of 0.0, 90.0, 180.0 and 360.0.
*void

Post by *void »

Magick wrote: A good API design strives to have only one way to do one thing and you can integral rotate already with angles of 0.0, 90.0, 180.0 and 360.0.

If that is the reason, then why are there MagickBorderImage and MagickFrameImage? Near as I can determine, borderimage is just frameimage with both bevels set to 0. Given a little time, I could probably cite a dozen more redundancies.

And also, why export IntegralRotateImage from the core API? But, on the other hand:
Emerson wrote: A foolish consistency is the hobgoblin of little minds, adored by little statesmen and philosophers and divines.
:D
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Post by magick »

If there are certain redundancies we don't want to add any more. FYI, IntergralRotateImage() is not exported in MagickCore. Its a static/private method.
*void

Post by *void »

magick wrote: FYI, IntergralRotateImage() is not exported in MagickCore. Its a static/private method.

I didn't realize that. Ca. 2003 I used the API and IntegralRotateImage was available at that time. It was the only rotate I used at that time. It is a pity you took it out of the API.

Rotate and Frame offer an interesting contrast:

On the one hand, a fundamentally singular function "frame" is made to APPEAR to be two different things at the API, with no apparent advantage to anyone. I would be highly unlikely to ever use "border", since all I have to do is pass a couple of integer 0's on the stack to get it.

On the other hand, two fundamentally different implementations at the code level are forced to APPEAR to be the same thing at the API, at a significant programming disadvantage.

My last word on it. I promise.

Certainly, at a human (non-programming) level, rotate is rotate, and frame is different from border. But, we are not discussing a human interface. We are discussing a programming interface. I honestly can't comprehend how it can be argued that hiding the fundamentally unique IntegralRotateImage from an API can be advantageous from anyone's perspective. I.E.: I must cast cast an integer count of 90 degree rotations to real 90.0, 180.0, etc degrees, only to have these floating point numbers turned back into an integral count of 90's later on for the actual operation. Plus, I have to allocate, pass along, and ultimately relinquish a structure that will never be used. I certainly can't see how the argument "there should only be one way to do a thing" can be applied here, since in fact there is not "a thing" but rather "two things". And if two things are ultimately not needed, why does IntegralRotateImage even exist? We both know the answer to that. It would be horribly inefficient to apply the general rotation method to 90 degree multiples.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Post by magick »

Regarding Border/FrameImage(). We have two methods because BorderImage() was written first and we do not remove an API method once its public. Note IntergralRotateImage() was available in the API but was never public. Public API methods were methods published in the web pages. There is 500 or 600 public API methods and there are 500 to 600 private methods. Over the years some folks did use the private methods but its at your own risk. Private method signatures can change. Theoretically public method signatures do not.

We could publish the IntegralRotateImage() method if we saw some advantage. We know it takes an unsigned long rather than a double and RotateImage() makes a couple of computations before/after it call IntegralRotateImage(). Other than that we don't see any advantages and the disadvantage is namespace pollution and adding another redundant method (more than one way to do the same thing). If we're still missing something here we're willing to reconsider.
Post Reply