HYi Roger
On Mon, 20 Nov 2023, Roger Kaufman wrote:
> On 11/19/2023 5:42 AM, Adrian Rossiter wrote:
>> If reversing colormaps is something you use, you could add a special
>> index to index colormap that does this, e.g. reverseN:I, where I is the
>> base index for the reversal (default 0) and N is the number of elements,
>> (starting at I) for the flip, such that I and N-1 will be exchanged. With
>> this, your second command above would be
>>
>> off_color_radial geo_9_4 -m reverse256,rainbow -E f -V e | antiview -v 0.01
>
> I was wondering there could be a general operation for this. I've looked that
> colormap code for a bit and I can't see how this would be coded. (and I
> haven't seen the format you are showing where the first map would alter the
> second map).
I have appended some example code that adds in a "reverse" map. The
two parameter form is different to what I say above (which I didn't
write correctly anyway!)
reverseN - reverses a map, switching index numbers 0 and N-1
reverseI:J reverses a map, switching index numbers I and J
The one parameter form reverses a map with N entries (but also will
process index numbers outside that range). The second form provides
easy to understand parameters for a reflection at any point.
The following are equivalent
reverse256
reverse0:255
I considered that the first parameter could be N in both cases, but
it made the two parameter form very difficult to use. Anyway, if the
code is of interest, feel free to change the parameter meaning.
Adrian.
======== colormap.cc, after ColorMapDeal definition
/// A colour map that reverses index numbers
class ColorMapReverse : public ColorMap {
private:
vector<int> switch_idxs = {0, 16};
public:
/// Initialise from a string
/**\param map_name the map name.
* \return status, evaluates to \c true if the map could be initialised
* (possibly with warnings) otherwise \c false. */
virtual Status init(const char *map_name);
/// Get a copy of the map
/**\return a pointer to the dynamically allocated copy,
* which must be freed by the caller with \c delete, 0 indicates
* that the clone failed. */
ColorMap *clone() const { return new ColorMapReverse(*this); }
/// Get the colour value for an index number.
/**\param idx the index.
* \return The colour. */
virtual Color get_col(int idx) const;
};
Status ColorMapReverse::init(const char *map_name)
{
// Make a copy for parsing
string name_str(map_name);
char *name = &name_str[0];
Status stat = init_strip(name);
if (stat.is_error())
return stat;
Split vals(name, ":", true);
if (vals.size() > 2)
return Status::error("map_name contains more than one ':'");
// Formats:
// N - Reverse to switch N-1 and 0
// I:J - Reverse to switch I and J
vector<int> params;
int param;
for(size_t i=0; i<vals.size(); i++) {
if (vals.size() > i && *vals[i]) {
if (!(stat = read_int(vals[i], ¶m))) {
const vector<string> param_names = {"first", "second"};
return Status::error(msg_str("%s parameter: '%s' %s",
param_names[i].c_str(), vals[i],
stat.c_msg()));
}
else
params.push_back(param);
}
}
if(vals.size()==2) // format I:J
switch_idxs = params;
else if (vals.size()==1) // format N
switch_idxs = {0, params[0]-1};
else // default
switch_idxs = {0, 16};
return Status::ok();
}
Color ColorMapReverse::get_col(int idx) const
{
int eff_idx = get_effective_index(idx);
int new_idx = switch_idxs[0] + switch_idxs[1] - eff_idx;
return Color(new_idx);
}
======== colormap.cc, colormap_from_name_generated, after "deal" check
else if (strcmp(name, "reverse") == 0) {
auto *cmr = new ColorMapReverse;
if (cmr) {
if ((*stat = cmr->init(map_name + name_len)))
cmap = cmr;
else
delete cmr;
}
}