Пример #1
0
int w_ImageData_encode(lua_State *L)
{
	std::string ext;
	const char *fmt;
	ImageData::Format format = ImageData::FORMAT_MAX_ENUM;
	ImageData *t = luax_checkimagedata(L, 1);

	if (lua_isstring(L, 2))
		luax_convobj(L, 2, "filesystem", "newFile");
	love::filesystem::File *file = luax_checktype<love::filesystem::File>(L, 2, "File", FILESYSTEM_FILE_T);

	if (lua_isnoneornil(L, 3))
	{
		ext = file->getExtension();
		fmt = ext.c_str();
		ImageData::getConstant(fmt, format);
	}
	else
	{
		fmt = luaL_checkstring(L, 3);
		if (!ImageData::getConstant(fmt, format))
			luaL_error(L, "Invalid image format.");
	}

	try
	{
		t->encode(file, format);
	}
	catch(love::Exception &e)
	{
		return luaL_error(L, e.what());
	}
	return 0;
}
Пример #2
0
ImageData ReadLUTFile(const char *lutfile)
{
	PathSeperator sep(lutfile);
	if(sep.extension == "jpg") {
		return ReadJPEGFile(lutfile);
	}
	else {
		std::string fn = lutfile;
		fn = std::string(fn.begin(), fn.begin()+fn.find('#'));
		std::string num( ++( sep.extension.begin() + sep.extension.find('#') ), sep.extension.end());
		int lutIndex = atoi(num.c_str());

		int nbeads, nplanes, nsteps;
		FILE *f = fopen(fn.c_str(), "rb");

		if (!f)
			throw std::runtime_error("Can't open " + fn);

		fread(&nbeads, 4, 1, f);
		fread(&nplanes, 4, 1, f);
		fread(&nsteps, 4, 1, f);


		fseek(f, 12 + 4* (nsteps*nplanes * lutIndex), SEEK_SET);
		ImageData lut = ImageData::alloc(nsteps,nplanes);
		fread(lut.data, 4, nsteps*nplanes,f);
		fclose(f);
		lut.normalize();
		return lut;
	}
}
Пример #3
0
int w_ImageData_setPixel(lua_State *L)
{
	ImageData *t = luax_checkimagedata(L, 1);
	int x = luaL_checkint(L, 2);
	int y = luaL_checkint(L, 3);
	pixel c;

	if (lua_istable(L, 4))
	{
		for (int i = 1; i <= 4; i++)
			lua_rawgeti(L, 4, i);

		c.r = (unsigned char)luaL_checkinteger(L, -4);
		c.g = (unsigned char)luaL_checkinteger(L, -3);
		c.b = (unsigned char)luaL_checkinteger(L, -2);
		c.a = (unsigned char)luaL_optinteger(L, -1, 255);

		lua_pop(L, 4);
	}
	else
	{
		c.r = (unsigned char)luaL_checkinteger(L, 4);
		c.g = (unsigned char)luaL_checkinteger(L, 5);
		c.b = (unsigned char)luaL_checkinteger(L, 6);
		c.a = (unsigned char)luaL_optinteger(L, 7, 255);
	}

	luax_catchexcept(L, [&](){ t->setPixel(x, y, c); });
	return 0;
}
Пример #4
0
int w_ImageData_mapPixel(lua_State *L)
{
	ImageData *t = luax_checkimagedata(L, 1);

	if (!lua_isfunction(L, 2))
		return luaL_error(L, "Function expected");

	int w = t->getWidth();
	int h = t->getHeight();

	for (int i = 0; i < w; i++)
	{
		for (int j = 0; j < h; j++)
		{
			lua_pushvalue(L, 2);
			lua_pushnumber(L, i);
			lua_pushnumber(L, j);
			pixel c = t->getPixel(i, j);
			lua_pushnumber(L, c.r);
			lua_pushnumber(L, c.g);
			lua_pushnumber(L, c.b);
			lua_pushnumber(L, c.a);
			lua_call(L, 6, 4);
			c.r = luaL_optint(L, -4, 0);
			c.g = luaL_optint(L, -3, 0);
			c.b = luaL_optint(L, -2, 0);
			c.a = luaL_optint(L, -1, 0);
			t->setPixel(i, j, c);
			lua_pop(L, 4);
		}
	}
	return 0;
}
Пример #5
0
bool AreImagesEqual(
    const ImageData& image1,
    const ImageData& image2,
    const double diff_tolerance) {

  const int num_channels = image1.GetNumChannels();
  if (num_channels != image2.GetNumChannels()) {
    std::cout << "Images do not have the same number of channels: "
              << num_channels << " vs. "
              << image2.GetNumChannels() << std::endl;
    return false;
  }

  // If the given diff_tolerance is zero, use "epsilon" to account for possible
  // double precision numerical errors.
  double applied_diff_tolerance = diff_tolerance;
  if (diff_tolerance < std::numeric_limits<double>::epsilon()) {
    applied_diff_tolerance = std::numeric_limits<double>::epsilon();
  }

  for (int channel_index = 0; channel_index < num_channels; ++channel_index) {
    if (!AreMatricesEqual(
          image1.GetChannelImage(channel_index),
          image2.GetChannelImage(channel_index),
          applied_diff_tolerance)) {
      return false;
    }
  }

  return true;
}
Пример #6
0
// Thread-safe wrapper for the above function.
int w_ImageData_mapPixel(lua_State *L)
{
	ImageData *t = luax_checkimagedata(L, 1);
	luaL_checktype(L, 2, LUA_TFUNCTION);
	int sx = luaL_optint(L, 3, 0);
	int sy = luaL_optint(L, 4, 0);
	int w = luaL_optint(L, 5, t->getWidth());
	int h = luaL_optint(L, 6, t->getHeight());

	lua_pushcfunction(L, w_ImageData_mapPixelUnsafe);
	lua_pushvalue(L, 1);
	lua_pushvalue(L, 2);
	lua_pushinteger(L, sx);
	lua_pushinteger(L, sy);
	lua_pushinteger(L, w);
	lua_pushinteger(L, h);

	int ret = 0;

	// Lock this ImageData's mutex during the entire mapPixel. We pcall instead
	// of call because lua_error longjmp's without calling object destructors.
	{
		love::thread::Lock lock(t->getMutex());
		ret = lua_pcall(L, 6, 0, 0);
	}

	if (ret != 0)
		return lua_error(L);

	return 0;
}
Пример #7
0
    ImageData NativeTextureGLES::lock(lock_flags flags, const Rect* src)
    {
        assert(_lockFlags == 0);


        _lockFlags = flags;
        Rect r(0, 0, _width, _height);

        if (src)
            r = *src;

        OX_ASSERT(r.getX() + r.getWidth() <= _width);
        OX_ASSERT(r.getY() + r.getHeight() <= _height);

        _lockRect = r;

        assert(_lockFlags != 0);

        if (_lockRect.isEmpty())
        {
            OX_ASSERT(!"_lockRect.IsEmpty()");
            return ImageData();
        }

        if (_data.empty())
        {
            //_data.resize(_width)
        }

        ImageData im =  ImageData(_width, _height, (int)(_data.size() / _height), _format, &_data.front());
        return im.getRect(_lockRect);
    }
Пример #8
0
int w_ImageData_getDimensions(lua_State *L)
{
	ImageData *t = luax_checkimagedata(L, 1);
	lua_pushinteger(L, t->getWidth());
	lua_pushinteger(L, t->getHeight());
	return 2;
}
Пример #9
0
JSValue jsImageDataHeight(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSImageData* castedThis = static_cast<JSImageData*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    ImageData* imp = static_cast<ImageData*>(castedThis->impl());
    JSValue result = jsNumber(imp->height());
    return result;
}
Пример #10
0
int w_ImageData_getPixel(lua_State *L)
{
	ImageData *t = luax_checkimagedata(L, 1);
	int x = luaL_checkint(L, 2);
	int y = luaL_checkint(L, 3);
	pixel c;

	EXCEPT_GUARD(c = t->getPixel(x, y);)
Пример #11
0
	int w_newEncodedImageData(lua_State * L) {
		ImageData * t = luax_checkimagedata(L, 1);
		const char * fmt = luaL_checkstring(L, 2);
		EncodedImageData::Format f;
		EncodedImageData::getConstant(fmt, f);
		EncodedImageData * eid = t->encode(f);
		luax_newtype(L, "EncodedImageData", IMAGE_ENCODED_IMAGE_DATA_T, (void*)eid);
		return 1;
	}
Пример #12
0
CDLL_EXPORT void DLL_CALLCONV QTrkBuildLUTFromFrame(QueuedTracker* qtrk, ImageData* frame, QTRK_PixelDataType pdt, int plane, ROIPosition* roipos, int numroi)
{
	ImageData extracted = ImageData::alloc(qtrk->cfg.width, qtrk->cfg.height*numroi);
	for (int i=0;i<numroi;i++){
		frame->copyTo(extracted, roipos[i].x, roipos[i].y, 0, i*qtrk->cfg.height, qtrk->cfg.width,qtrk->cfg.height);
	}
	qtrk->BuildLUT(extracted.data, sizeof(float)*qtrk->cfg.width, QTrkFloat, plane);
	extracted.free();
}
Пример #13
0
// ImageData:mapPixel. Not thread-safe! See the wrapper function below.
static int w_ImageData_mapPixelUnsafe(lua_State *L)
{
	ImageData *t = luax_checkimagedata(L, 1);
	luaL_checktype(L, 2, LUA_TFUNCTION);

	// No optints because we assume they're done in the wrapper function.
	int sx = (int) lua_tonumber(L, 3);
	int sy = (int) lua_tonumber(L, 4);
	int w  = (int) lua_tonumber(L, 5);
	int h  = (int) lua_tonumber(L, 6);

	if (!(t->inside(sx, sy) && t->inside(sx+w-1, sy+h-1)))
		return luaL_error(L, "Invalid rectangle dimensions.");

	// Cache-friendlier loop. :)
	for (int y = sy; y < sy+h; y++)
	{
		for (int x = sx; x < sx+w; x++)
		{
			lua_pushvalue(L, 2);
			lua_pushnumber(L, x);
			lua_pushnumber(L, y);
			pixel c = t->getPixel(x, y);
			lua_pushnumber(L, c.r);
			lua_pushnumber(L, c.g);
			lua_pushnumber(L, c.b);
			lua_pushnumber(L, c.a);
			lua_call(L, 6, 4);

			// If we used luaL_checkX / luaL_optX then we would get messy error
			// messages (e.g. Error: bad argument #-1 to '?'), so while this is
			// messier code, at least the errors are a bit more descriptive.

			// Treat the pixel as an array for less code duplication. :(
			unsigned char *parray = (unsigned char *) &c;
			for (int i = 0; i < 4; i++)
			{
				int ttype = lua_type(L, -4 + i);

				if (ttype == LUA_TNUMBER)
					parray[i] = (unsigned char) lua_tonumber(L, -4 + i);
				else if (i == 3 && (ttype == LUA_TNONE || ttype == LUA_TNIL))
					parray[i] = 255; // Alpha component defaults to 255.
				else
					// Error (level 2 because this is function will be wrapped.)
					return luax_retnumbererror(L, 2, i + 1, ttype);
			}

			// Pop return values.
			lua_pop(L, 4);

			// We're locking the entire function, instead of each setPixel call.
			t->setPixelUnsafe(x, y, c);
		}
	}
	return 0;
}
    void RawImageReader::updateResult(DataContainer& data) {
        size_t dimensionality = 3;
        if (p_size.getValue().z == 1) {
            dimensionality = (p_size.getValue().y == 1) ? 1 : 2;
        }

        ImageData* image = new ImageData(dimensionality, p_size.getValue(), p_numChannels.getValue());
        ImageRepresentationDisk::create(image, p_url.getValue(), p_baseType.getOptionValue(), p_offset.getValue(), p_endianness.getOptionValue());
        image->setMappingInformation(ImageMappingInformation(p_size.getValue(), p_imageOffset.getValue(), p_voxelSize.getValue()));
        data.addData(p_targetImageID.getValue(), image);
    }
Пример #15
0
buffer_t ImageToBuffer(const ImageData &im) {
    buffer_t buf;
    memset(&buf, 0, sizeof(buffer_t));
    buf.host = (uint8_t *)im.data();
    buf.extent[0] = im.size().width();
    buf.stride[0] = 1;
    buf.extent[1] = im.size().height();
    buf.stride[1] = im.stride()/4;
    buf.elem_size = 4;
    return buf;
}
Пример #16
0
	int w_ImageData_getPixel(lua_State * L)
	{
		ImageData * t = luax_checkimagedata(L, 1);
		int x = luaL_checkint(L, 2);
		int y = luaL_checkint(L, 3);
		pixel c = t->getPixel(x, y);
		lua_pushnumber(L, c.r);
		lua_pushnumber(L, c.g);
		lua_pushnumber(L, c.b);
		lua_pushnumber(L, c.a);
		return 4;
	}
Пример #17
0
bool Color2Gray::connectionTest( DesignNet::Port* src, DesignNet::Port* target )
{
	if(target == &m_inputPort)
	{
		ImageData *srcData = qobject_cast<ImageData*>(src->data());
		if (!srcData || srcData->imageType() != ImageData::IMAGE_BGR)
		{
			return false;
		}
		return true;
	}
	return false;
}
Пример #18
0
int w_ImageData_paste(lua_State *L)
{
	ImageData *t = luax_checkimagedata(L, 1);
	ImageData *src = luax_checkimagedata(L, 2);
	int dx = luaL_checkint(L, 3);
	int dy = luaL_checkint(L, 4);
	int sx = luaL_optint(L, 5, 0);
	int sy = luaL_optint(L, 6, 0);
	int sw = luaL_optint(L, 7, src->getWidth());
	int sh = luaL_optint(L, 8, src->getHeight());
	t->paste((love::image::ImageData *)src, dx, dy, sx, sy, sw, sh);
	return 0;
}
Пример #19
0
static v8::Handle<v8::Value> dataAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.ImageData.data._get");
    ImageData* imp = V8ImageData::toNative(info.Holder());
    RefPtr<CanvasPixelArray> result = imp->data();
    v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>();
    if (wrapper.IsEmpty()) {
        wrapper = toV8(result.get());
        if (!wrapper.IsEmpty())
            V8DOMWrapper::setHiddenReference(info.Holder(), wrapper);
    }
    return wrapper;
}
Пример #20
0
	int w_ImageData_setPixel(lua_State * L)
	{
		ImageData * t = luax_checkimagedata(L, 1);
		int x = luaL_checkint(L, 2);
		int y = luaL_checkint(L, 3);
		pixel c;
		c.r = luaL_checkint(L, 4);
		c.g = luaL_checkint(L, 5);
		c.b = luaL_checkint(L, 6);
		c.a = luaL_checkint(L, 7);
		t->setPixel(x, y, c);
		return 0;
	}
Пример #21
0
String ImageDataToDataURL(const ImageData& source, const String& mimeType, const double* quality)
{
    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
        
    RetainPtr<CGImageRef> image;
    RetainPtr<CGDataProviderRef> dataProvider;

    unsigned char* data = source.data()->data()->data();
    RetainPtr<CFStringRef> uti = utiFromMIMEType(mimeType);
    ASSERT(uti);
    Vector<uint8_t> dataVector;
    if (CFEqual(uti.get(), jpegUTI())) {
        // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
        dataVector.resize(4 * source.width() * source.height());
        unsigned char *out = dataVector.data();
        
        for (int i = 0; i < source.width() * source.height(); i++) {
            // Multiply color data by alpha, and set alpha to 255.
            int alpha = data[4 * i + 3];
            if (alpha != 255) {
                out[4 * i + 0] = data[4 * i + 0] * alpha / 255;
                out[4 * i + 1] = data[4 * i + 1] * alpha / 255;
                out[4 * i + 2] = data[4 * i + 2] * alpha / 255;
            } else {
                out[4 * i + 0] = data[4 * i + 0];
                out[4 * i + 1] = data[4 * i + 1];
                out[4 * i + 2] = data[4 * i + 2];
            }
            out[4 * i + 3] = 255;
        }

        data = out;
    }
    
    dataProvider.adoptCF(CGDataProviderCreateWithData(0, data,
                                                      4 * source.width() * source.height(), 0));
    
    if (!dataProvider)
        return "data:,";

    image.adoptCF(CGImageCreate(source.width(), source.height(), 8, 32, 4 * source.width(),
                                CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrderDefault | kCGImageAlphaLast,
                                dataProvider.get(), 0, false, kCGRenderingIntentDefault));
                                
        
    if (!image)
        return "data:,";

    return CGImageToDataURL(image.get(), mimeType, quality);
}
Пример #22
0
/*
   Load a list of image names from a file.  Appears to also populate
   some of the meta-info about where to get key files from/dump them 
   to.
*/
void BaseApp::LoadImageNamesFromFile(FILE *f)
{
// m_image_names.clear();
m_image_data.clear();

char buf[256];
int idx = 0;

while (fgets(buf, 256, f)) 
 {
  ImageData data;
  data.InitFromString(buf, m_image_directory, m_fisheye);

  // Try to find a keypoint file in key directory, or in current directory.
  if (strcmp(m_key_directory, ".") != 0) 
   {
    char key_buf[256];
    data.GetBaseName(key_buf);

    char key_path[512];
    sprintf(key_path, "%s/%s.key", m_key_directory, key_buf);
    data.m_key_name = strdup(key_path);
   } 
  else 
   {
    // FIXME: I think this causes a memory leak 
    // TODO:  Assumes that filename related to data.m_name.
    char key_buf[256];
    strcpy(key_buf, data.m_name);
    int len = strlen(key_buf);
    key_buf[len - 3] = 'k';
    key_buf[len - 2] = 'e';
    key_buf[len - 1] = 'y';
    data.m_key_name = strdup(key_buf);
   }

  m_image_data.push_back(data);
  idx++;
 }

// Create an empty match table
m_matches = MatchTable(GetNumImages());
RemoveAllMatches();

m_matches_computed = true;
m_num_original_images = GetNumImages();

if (m_use_intrinsics)
  ReadIntrinsicsFile();
}
Пример #23
0
void JNIFUNCF(JNILibCurve, initWarp, jobject bitmap, jint w, jint h) {


    width = w;
    height = h;
	imgData.Resize(width, height, 4);
	unsigned char* destination = 0;
	AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
	memcpy(imgData.Data, destination, imgData.ScanWidth * height);
	warper = new Warper(imgData);
//	warper->BeginWarp(pt, 150, WARPER_TRANSLATE);
//
//	for(int i=0; i <1; i++) {
//		warpedImg = warper->UpdateWarp(pt2);
//	}
//	warpedImg = warper->EndWarp(warpedImg);
//
//	tempData =  warper->m_imgOriginal;
	AndroidBitmap_unlockPixels(env, bitmap);
//	jbyte *byte = (jbyte*)tempData->Data;
//	jbyteArray rgbBuf = env->NewByteArray(width*height*4);
//	env->SetByteArrayRegion(rgbBuf, 0, width*height*4, byte);
	//释放
//	(*env)->ReleaseByteArrayElements(env,yuvBuf,arr,0);

//	return rgbBuf;

//	__android_log_print(ANDROID_LOG_FATAL, "wrap", "NativeFilters %d  %d  %d", warpedImg->Image.Width, warpedImg->Image.Height, width);
//	__android_log_print(ANDROID_LOG_FATAL, "LOG", "NativeFilters %d  %d  %d", imgData.ScanWidth, height, width);
}
Пример #24
0
bool Color2Gray::process()
{
	emit logout("Color2Gray::process()");
	ImageData *idata = qobject_cast<ImageData *>(m_inputPort.data());
	if(idata)
	{
		cv::Mat mat;
		cv::cvtColor(idata->imageData(), mat, CV_RGB2GRAY);
		ImageData grayData;
		grayData.setImageData(mat);
		pushData(&grayData, "grayImage");
		emit logout("Color2Gray::process() OK");
		return true;
	}
	return false;
}
Пример #25
0
void QueuedTracker::ComputeZBiasCorrection(int bias_planes, CImageData* result, int smpPerPixel, bool useSplineInterp)
{
	int count,zlut_planes,radialsteps;
	GetRadialZLUTSize(count, zlut_planes, radialsteps);
	float* zlut_data = new float[count*zlut_planes*radialsteps];
	GetRadialZLUT(zlut_data);

	std::vector<float> qi_rweights = ComputeRadialBinWindow(cfg.qi_radialsteps);
	std::vector<float> zlut_rweights = ComputeRadialBinWindow(cfg.zlut_radialsteps);

	if (zlut_bias_correction)
		delete zlut_bias_correction;

	zlut_bias_correction = new CImageData(bias_planes, count);

	parallel_for(count*bias_planes, [&](int job) {
	//for (int job=0;job<count*bias_planes;job++) {
		int bead = job/bias_planes;
		int plane = job%bias_planes;
		
		float *zlut_ptr = &zlut_data[ bead * (zlut_planes*radialsteps) ];
		CPUTracker trk (cfg.width,cfg.height);
		ImageData zlut(zlut_ptr, radialsteps, zlut_planes);
		trk.SetRadialZLUT(zlut.data, zlut.h, zlut.w, 1, cfg.zlut_minradius,cfg.zlut_maxradius, false, false);
		trk.SetRadialWeights(&zlut_rweights[0]);

		vector3f pos(cfg.width/2,cfg.height/2, plane /(float) bias_planes * zlut_planes );
		ImageData img = ImageData::alloc(cfg.width,cfg.height);
		GenerateImageFromLUT(&img, &zlut, cfg.zlut_minradius, cfg.zlut_maxradius, pos, useSplineInterp,smpPerPixel);

		bool bhit;
		trk.SetImageFloat(img.data);
		vector2f com = trk.ComputeMeanAndCOM();
		vector2f qi = trk.ComputeQI(com, 2, cfg.qi_radialsteps, cfg.qi_angstepspq, cfg.qi_angstep_factor, cfg.qi_minradius, cfg.qi_maxradius, bhit, &qi_rweights[0]);
		float z = trk.ComputeZ(qi, cfg.zlut_angularsteps, 0);
		zlut_bias_correction->at(plane, bead) = z - pos.z;

		//trk.ComputeRadialProfile(
		img.free();
		if ((job%(count*bias_planes/10)) == 0) 
			dbgprintf("job=%d\n", job);
//	}
	});

	if (result)
		*result = *zlut_bias_correction;
}
Пример #26
0
void ApplyGaussianNoise(ImageData& img, float sigma)
{
	for (int k=0;k<img.numPixels();k++) {
		float v = img.data[k] + sigma * rand_normal<float>();
		if (v<0.0f) v= 0.0f;
		img.data[k]=v;
	}
}
Пример #27
0
bool Texture::LoadFromFile(const char* filename)
{
	bool ret = false;
	ImageData imageData;

	CHECK(filename);
	CHECK(imageData.LoadFromFile(filename));

	mWidth = imageData.GetWidth();
	mHeight = imageData.GetHegiht();

	ret = Create(mWidth, mHeight, imageData.GetBits());

	ret = true;
Exit0:
	return ret;
}
Пример #28
0
void GenerateTestImage(ImageData& img, float xp, float yp, float size, float SNratio)
{
	float S = 1.0f/sqrt(size);
	for (int y=0;y<img.h;y++) {
		for (int x=0;x<img.w;x++) {
			float X = x - xp;
			float Y = y - yp;
			float r = sqrtf(X*X+Y*Y)+1;
			float v = sinf(r/(5*S)) * expf(-r*r*S*0.001f);
			img.at(x,y)=v;
		}
	}

	if (SNratio>0) {
		ApplyGaussianNoise(img, 1.0f/SNratio);
	}
	img.normalize();
}
Пример #29
0
 void balanceComponents_(f64 norm, ImageData &posSums, ImageData &negSums) {
   for (i32 kji = 0; kji < components_.size(3); ++kji) {
     for (i32 tji = 0; tji < components_.size(2); ++tji) {
       for (i32 ni = 0; ni < posSums.height(); ++ni) {
         for (i32 tani = 0; tani < posSums.width(); ++tani) {
           ImageData &kernel = components_(tani, ni, tji, kji);
           
           i32 kernElems = kernel.numElems();
           for (i32 i = 0; i < kernElems; i++) {
             kernel[i] *= norm/(kernel[i] >= 0 ?
                                posSums(tani, ni) :
                                negSums(tani, ni));
           }
         }
       }
     }
   }
 }
void GlGradientVolumeGenerator::updateResult(DataContainer& data) {
    ImageRepresentationGL::ScopedRepresentation img(data, p_inputImage.getValue());

    if (img != 0) {
        const cgt::svec3& size = img->getSize();

        cgt::TextureUnit inputUnit;
        inputUnit.activate();

        // create texture for result
        cgt::Texture* resultTexture = new cgt::Texture(GL_TEXTURE_3D, cgt::ivec3(size), GL_RGB16F, cgt::Texture::LINEAR);

        // activate shader and bind textures
        _shader->activate();
        img->bind(_shader, inputUnit);

        // activate FBO and attach texture
        _fbo->activate();
        glViewport(0, 0, static_cast<GLsizei>(size.x), static_cast<GLsizei>(size.y));

        // render quad to compute difference measure by shader
        for (int z = 0; z < static_cast<int>(size.z); ++z) {
            float zTexCoord = static_cast<float>(z)/static_cast<float>(size.z) + .5f/static_cast<float>(size.z);
            _shader->setUniform("_zTexCoord", zTexCoord);
            _fbo->attachTexture(resultTexture, GL_COLOR_ATTACHMENT0, 0, z);
            QuadRdr.renderQuad();
        }
        _fbo->detachAll();
        _fbo->deactivate();
        _shader->deactivate();

        // put resulting image into DataContainer
        ImageData* id = new ImageData(3, size, 3);
        ImageRepresentationGL::create(id, resultTexture);
        id->setMappingInformation(img->getParent()->getMappingInformation());
        data.addData(p_outputImage.getValue(), id);

        cgt::TextureUnit::setZeroUnit();
        LGL_ERROR;
    }
    else {
        LDEBUG("No suitable input image found.");
    }
}