Page 1 of 1

How can I access pixel index?

Posted: 2016-09-24T01:54:12-07:00
by idries
Hi,

I'm trying to read the pixel index data from a palettized image. I've tried a lot of different approaches but my naive implementation is:

Code: Select all

	int x, y;
	size_t width;
	PixelIterator* pixel_iterator = NewPixelIterator(read_wand);

	for (y = 0; y < (long)MagickGetImageHeight(read_wand); y++)
	{
		PixelInfo pixel_info;
		PixelWand** pixels = PixelGetNextIteratorRow(pixel_iterator, &width);

		if ((pixels == (PixelWand **)NULL))
			break;

		for (x = 0; x < (long)width; x++)
		{
			int index = PixelGetIndex(pixels[x]);

			// process index here
		}
	}
I would expect this to give me index values, but they are always 0. More confusingly, I've had a look inside the implementation of PixelGetIndex:

Code: Select all

WandExport Quantum PixelGetIndex(const PixelWand *wand)
{
  assert(wand != (const PixelWand *) NULL);
  assert(wand->signature == MagickWandSignature);
  if (wand->debug != MagickFalse)
    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
  return((Quantum) wand->pixel.black);
}
I would have expected this to return the 'index' field. Checking in the debugger the index field for all my pixels is 0 as well.

The image I've originally loaded is a 24 BPP png, but I've used ImageMagick to remap it to a 55 colour palette (the image only uses 29 of the colours). When I save the image:

Code: Select all

MagickWriteImage(read_wand, dest_file_name);
I get an 8 bpp png so ImageMagick clearly knows it's a palettized image.

I called the following functions to try and 'force' ImageMagick to palettize the image:

Code: Select all

	SetImageStorageClass(extent_image, PseudoClass, exception);
	SetImageType(extent_image, PaletteType, exception);
These do change the fields in the structure but don't make black or index fields get populated.

I took a look at the colormap of the image. It seems to be completely correct, so obviously I could look up each pixel's rbg values to find the palette index, but this seems silly.

Any ideas?

Re: How can I access pixel index?

Posted: 2016-09-24T08:57:02-07:00
by snibgo
You don't say what version IM you are using. V6.9.3-7 has different code for PixelGetIndex(), in pixel-wand.c, to what you quoted.

Code: Select all

WandExport IndexPacket PixelGetIndex(const PixelWand *wand)
{
  assert(wand != (const PixelWand *) NULL);
  assert(wand->signature == WandSignature);
  if (wand->debug != MagickFalse)
    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
  return((IndexPacket) wand->pixel.index);
}

Re: How can I access pixel index?

Posted: 2016-10-08T22:54:01-07:00
by idries
I am on 7.0.3-0.

Does the index field contain reasonable data in your version?

Re: How can I access pixel index?

Posted: 2016-10-09T08:20:46-07:00
by snibgo
I don't know why, in v7, PixelGetIndex() returns wand.pixel->black. The corresponding function PixelSetIndex() sets wand.pixel->index.

I don't use the Wand interface for pixel data, nor do I use indexes. PixelGetIndex() doesn't seem to be called anywhere within ImageMagick, so a bug in that function would go unnoticed.

Re: How can I access pixel index?

Posted: 2016-10-09T08:34:36-07:00
by dlemstra
PixelGetIndex should return wand.pixel->index instead. I just pushed a fix to make sure this is resolved in the next version of ImageMagick.