Creating a custom indexed color space

Q:
We need to create some 1 bit per pixel images that use indexed color
spaces, however, I cannot find an example of doing this.
As I understand it, the the colorspace can either be global to the
document, or local to the image it is used in (please tell me if I am
wrong).

What I want to do is define 2 global indexed color spaces for [white
and black] and [black and white]. Futher, I want to be able to create
custom indexed color spaces “on the fly” and use them with single
images.

Below is a code fragment showing what I trying to do.

//Create an array that is global to the document
Obj* indexcolorarray = doc.CreateIndirectArray();

//Create an array that is local to the image [Need code for an array
that is local to the image here]

//Define array entries that have two index colors (black and white)
indexcolorarray->PushBack(new Name(“Indexed”)); //For global
colorspaces, should this be unique?
indexcolorarray->PushBack(new Name(“DeviceRGB”)); PushBack(new
indexcolorarray->Number(1)); //Base PushBack(new Number(0));
indexcolorarray->PushBack(new Number(0)); PushBack(new Number(0));
indexcolorarray->PushBack(new Number(255)); PushBack(new Number(255));
indexcolorarray->PushBack(new Number(255));

//Create an indexed colorspace here with the array data. How?

//use the indexed colorspace… How?
ing= Image::Create(*doc.GetSDFDoc(),
lpimageDataOut,
ImageSize,
ImageWidth,
ImageHeight,
1,
ColorSpace::CreateDeviceGray()); //This
should be the indexed colorspace! How?


A:

We need to create some 1 bit per pixel images that use indexed color
spaces, however, I cannot find an example of doing this.

It seems that a 1 BPP image mask would be a better match than the
indexed color space.
Why do you need to use indexed color space?

the the colorspace can either be global to the document, or local to
the image it is used in

The color space is usually local to the image, but sometimes they can
be shared.

It seems that you only need to invert bits of the image mask. If this
is the case, you can add Decode parameter to the existing image
dictionary.

In case you still need to use an indexed color space, the answers for
your questions are below:

//Create an array that is local to the image [Need code for an array
that is local to the image here]

Obj* indexcolorarray = new SDF::Array();

//Create an indexed colorspace here with the array data. How?

ColorSpace indexed_cs(indexcolorarray);

… = Image::Create(*doc.GetSDFDoc(),
lpimageDataOut,
ImageSize,
ImageWidth,
ImageHeight,
1,
indexed_cs);

Q: I have tried the code you suggested, but it throws an exception on
the line here the color space is defined:
Obj* indexcolorarray = new SDF::Array();

indexcolorarray->PushBack(new Name(“Indexed”));

indexcolorarray->PushBack(new Name(“DeviceRGB”));

indexcolorarray->PushBack(new Number(1)); //HighVal
indexcolorarray->PushBack(new Number(255));
indexcolorarray->PushBack(new Number(0));
indexcolorarray->PushBack(new Number(0));
indexcolorarray->PushBack(new Number(0));
indexcolorarray->PushBack(new Number(0));
indexcolorarray->PushBack(new Number(255));

ColorSpace cs(indexcolorarray); // CRASH!! //


A:
There is an error in your indexed CS specification.

You need something like this:

Obj* indexcolorarray = new SDF::Array();

indexcolorarray->PushBack(new Name(“Indexed”));

indexcolorarray->PushBack(new Name(“DeviceRGB”));

// maximum index in the palette (HighVal)
indexcolorarray->PushBack(new Number(1));

unsigned char* palette = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF };
indexcolorarray->PushBack(new Str(buf, palette));

// Initialise the color space using the
ColorSpace cs(indexcolorarray);