Toshihiro Shimizu 890ddd
#include <stdexcept>		/* std::domain_error(-) */</stdexcept>
Toshihiro Shimizu 890ddd
#include "igs_ifx_common.h" /* igs::image::rgba */
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void change_channel_(
Toshihiro Shimizu 890ddd
	T *ima, const int pix_size, const int channels)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int ii = 0; ii < pix_size; ++ii, ima += channels) {
Toshihiro Shimizu 890ddd
		ima[0] = ~ima[0];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void change_multiplied_rgb(
Toshihiro Shimizu 890ddd
	T *ima, T *alp, const int pix_size, const int channels)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int ii = 0; ii < pix_size; ++ii, ima += channels, alp += channels) {
Toshihiro Shimizu 890ddd
		if (alp[0] < ima[0]) {
Toshihiro Shimizu 890ddd
			ima[0] = 0;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			ima[0] = alp[0] - ima[0];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void change_template_(
Toshihiro Shimizu 890ddd
	T *ima,
Toshihiro Shimizu 890ddd
	const int hh,
Toshihiro Shimizu 890ddd
	const int ww,
Toshihiro Shimizu 890ddd
	const int ch,
Toshihiro Shimizu 890ddd
	const bool *sw /* each channels switch */
Toshihiro Shimizu 890ddd
	)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int sz = hh * ww;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (igs::image::rgba::siz == ch) {
Toshihiro Shimizu 890ddd
		using namespace igs::image::rgba;
Toshihiro Shimizu 890ddd
		if (sw[0]) {
Toshihiro Shimizu 890ddd
			change_multiplied_rgb(&ima[red], &ima[alp], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (sw[1]) {
Toshihiro Shimizu 890ddd
			change_multiplied_rgb(&ima[gre], &ima[alp], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (sw[2]) {
Toshihiro Shimizu 890ddd
			change_multiplied_rgb(&ima[blu], &ima[alp], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (sw[3]) {
Toshihiro Shimizu 890ddd
			change_channel_(&ima[alp], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else if (igs::image::rgb::siz == ch) {
Toshihiro Shimizu 890ddd
		using namespace igs::image::rgb;
Toshihiro Shimizu 890ddd
		if (sw[0]) {
Toshihiro Shimizu 890ddd
			change_channel_(&ima[red], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (sw[1]) {
Toshihiro Shimizu 890ddd
			change_channel_(&ima[gre], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (sw[2]) {
Toshihiro Shimizu 890ddd
			change_channel_(&ima[blu], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else if (1 == ch) { /* Grayscale */
Toshihiro Shimizu 890ddd
		if (sw[0]) {
Toshihiro Shimizu 890ddd
			change_channel_(&ima[0], sz, ch);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
#include <limits></limits>
Toshihiro Shimizu 890ddd
#include "igs_negate.h"
Toshihiro Shimizu 890ddd
void igs::negate::change(
Toshihiro Shimizu 890ddd
	unsigned char *image_array,
Toshihiro Shimizu 890ddd
	const int height,
Toshihiro Shimizu 890ddd
	const int width,
Toshihiro Shimizu 890ddd
	const int channels,
Toshihiro Shimizu 890ddd
	const int bits,
Toshihiro Shimizu 890ddd
	const bool *sw_array /* each channel switch  */
Toshihiro Shimizu 890ddd
	)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if ((igs::image::rgba::siz != channels) &&
Toshihiro Shimizu 890ddd
		(igs::image::rgb::siz != channels) &&
Toshihiro Shimizu 890ddd
		(1 != channels) /* bit(monoBW) */
Toshihiro Shimizu 890ddd
		) {
Toshihiro Shimizu 890ddd
		throw std::domain_error("Bad channels,Not rgba/rgb/grayscale");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
Toshihiro Shimizu 890ddd
		change_template_(
Toshihiro Shimizu 890ddd
			image_array,
Toshihiro Shimizu 890ddd
			height, width, channels, sw_array);
Toshihiro Shimizu 890ddd
	} else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
Toshihiro Shimizu 890ddd
		change_template_(
Toshihiro Shimizu 890ddd
			reinterpret_cast<unsigned *="" short="">(image_array),</unsigned>
Toshihiro Shimizu 890ddd
			height, width, channels, sw_array);
Toshihiro Shimizu 890ddd
	} else if (1 == bits) {
Toshihiro Shimizu 890ddd
		const int bi = width * channels * bits;
Toshihiro Shimizu 890ddd
		const int dg = std::numeric_limits<unsigned char="">::digits;</unsigned>
Toshihiro Shimizu 890ddd
		const int sl_bytes = bi / dg + ((0 != (bi % dg)) ? 1 : 0);
Toshihiro Shimizu 890ddd
		const int image_size = height * sl_bytes;
Toshihiro Shimizu 890ddd
		for (int ii = 0; ii < image_size; ++ii) {
Toshihiro Shimizu 890ddd
			image_array[ii] = ~image_array[ii];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		throw std::domain_error("Bad bits,Not uchar/ushort/bit");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}