First try with Magick Core 7

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
Alan Hadley
Posts: 48
Joined: 2010-03-31T12:17:55-07:00
Authentication code: 8675308

First try with Magick Core 7

Post by Alan Hadley »

I have started converting the Windows Interface for Image Magick that I am developing so that it will be compatible with IM7. Is this the correct place to discuss this?

I am only at the start of the convertion but I can already load and display images with one to 3 colour channels and with or without an alpha channel. I have also got my painting routine working, this needs an alpha channel on source, destination and background images which I add with SetImageAlphaChannel(). Displaying images on Windows is made a little tricky as it is best to premultiply by alpha, and convert to 8 bit channel data. So I use IM to sample an image down to the dfisplay size (I should convert to RGB if necessary too), and then AcquireVirtualCacheView() and GetCacheViewVirtualPixels() so that I can process the raw data premultiplying and converting to 8-bit channels in a single step.

So far it seems that there is no noticeable slow down when drawing IM7 (floating point) images compared with IM6 (16 bits per channel) images. I can still move a magnifying glass over an image and get smoothe movement in the magnified image, I have a Quad core Win7 64 bit PC.

I am using the alpha version of IM, ImageMagick-7.0.0-0-Q16-windows-x64-dll.exe, I can not compile the source code as I am using an Express edition of C++ which does not allow certain windows components to be used.

I have a few questions about the new Pixel format of the raw data etc. if anyone can answer them.

1. I have a need to get the value of a single pixel, I am using GetOneAuthenticPixel(), which works fine the channel values are returned in an array. I first tried allocating the array big enough to hold one pixels worth of data, but it overflowed, it seems that this array needs to be 32 floats long. Does this imply that there will be a hard limit on pixel size?

2. Am I correct in calculating pixel size in bytes as (number_channels+number_meta_channels)*sizeof(float)?

3. Presumably the order of the channels is important when deciding which one is red, green, blue and black and these channels will be followed by the primary alpha channel if there is one will the next channel be the mask if there is one? Or do I always need to check for the appropriate channel_map entry?

4. Will all of the above channels be included in number_channels?

5. Which number_* will other alpha blending, and modifyable channels be included with? I am guessing the number_channels, so that IM knows which channels to ignore when processing.

6. Is ChannelMask still necessary?

I realize that this is only an Alpha version but I would like to be 'on the ball' when Beta testing comes along.

Alan Hadley
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: First try with Magick Core 7

Post by magick »

1. I have a need to get the value of a single pixel, I am using GetOneAuthenticPixel(), which works fine the channel values are returned in an array. I first tried allocating the array big enough to hold one pixels worth of data, but it overflowed, it seems that this array needs to be 32 floats long. Does this imply that there will be a hard limit on pixel size?
Use the MaxPixelChannels to define the pixel array size.
2. Am I correct in calculating pixel size in bytes as (number_channels+number_meta_channels)*sizeof(float)?
Instead of sizeof(float) use sizeof(Quantum). In IMv7 we default to float but it could be char, short, a word, or double word.
3. Presumably the order of the channels is important when deciding which one is red, green, blue and black and these channels will be followed by the primary alpha channel if there is one will the next channel be the mask if there is one? Or do I always need to check for the appropriate channel_map entry?
Channels could be in any order. For a specific channel, use the pixel accessors defined in MagickCore/pixel-accessor.
4. Will all of the above channels be included in number_channels?
Some channels may not be available, for example if you want alpha but its a non-alpha image. That is why its good to use the pixel accessors, they default to reasonable values when a channel is not available. For alpha, if the alpha channel is not defined, GetPixelAlpha() returns OpaqueAlpha.

Note, if you don't care about the channel types, you can simply iterate over all the channels. There is a bit more overhead when using the pixel accessors. However, the overhead is modest.
5. Which number_* will other alpha blending, and modifyable channels be included with? I am guessing the number_channels, so that IM knows which channels to ignore when processing.
Huh?
6. Is ChannelMask still necessary?
The channel mask allows nearly all algorithms to operate on arbitrary channels. For example, you might want to blur only the green channel, use a channel mask to set operate on only the green channel before you call BlurImage(), then restore the original channel mask to ensure all future algorithms operate on all the channels.
I realize that this is only an Alpha version but I would like to be 'on the ball' when Beta testing comes along.
We're shooting for a Beta release 20131015 but that date may slip.
Alan Hadley
Posts: 48
Joined: 2010-03-31T12:17:55-07:00
Authentication code: 8675308

Re: First try with Magick Core 7

Post by Alan Hadley »

Thank's for your help -:) I have converted my image dispolay routine and I think it is now indipendant of the IM pixel layout and quantum size.

I have used ExportImagePixels() to convert from RGBA.anysize to RBGA.float and there is still no noticeable slowdown.

A request I would like to make is for ExportImagePixels() to include exporting a mask channel. If there is a mask I show it as a tinted overlay on an image. At the moment I export "RGBAP".float channels then use a for loop to change the Ps to the corresponding mask channel value before sending the buffer on for further processing.

Alan Hadley
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: First try with Magick Core 7

Post by anthony »

Note that you can have multiple masking channels. (Read such as alpha, and write as in a clip mask)
I have not looking into the programming mechanics involved with it as yet.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Alan Hadley
Posts: 48
Joined: 2010-03-31T12:17:55-07:00
Authentication code: 8675308

Re: First try with Magick Core 7

Post by Alan Hadley »

On testing some functions on an image with a Mask channel I get various results, some of which differ from what IM 6.8 produces. Typical examples are:-

1. AddNoise adds noise in the unmasked area in both versions of IM with the mask removed from the result

2. Draw only draws in the unmasked area, and removes the mask in 6.8 but draws everywhere and copies the mask in 7.0

3. Crop in IM 6.8 copies the requested area including what is under the mask and removes the mask from the result. While in 7.0 IM crops as above but also sets the area under the mask to black and switches the mask on in this area, so that the whole result now has a mask.

P.S. I know that there are multiple alpha channels but I have not worked out how to use them yet, nor how to switch on and use user channels. With a graphical interface such as mine it is good for the user to still be able to see the area under the mask for positioning things etc. Also it would be confusing for a user to have one of the available alpha channels behave differently to the others. Also having a mask channel leads to a more intuitive way of, for example, adding noise to an image but leaving part of the image unaffected. The IM version 6 use of the mask is consistant in that IM functions that draw on an image in some way without altering it's size are masked, while those that may alter the size of the image simply remove the mask from the result. Would it be possible in version 7 to have the option to preserve and resize, or reshape the mask channel along with other channels?

Alan Hadley
Alan Hadley
Posts: 48
Joined: 2010-03-31T12:17:55-07:00
Authentication code: 8675308

Re: First try with Magick Core 7

Post by Alan Hadley »

Please ignore the parts of the last message that say that IM 6.8 removes the Mask from the result in some circumstances. I discovered that my code was resetting the image->mask entry to zero when a new image was created.

Alan Hadley
Post Reply