Example #1
0
static void freeSetting(struct Setting *setting)
{
	if (setting == NULL)
		return;

	sgFree(setting->name);
	sgFree(setting->value);
	sgFree(setting->defaultValue);
	sgFree(setting);
}
Example #2
0
static void
listfree(struct node *lp)
{
	struct node *lq;

	while (lp != NULL) {
		lq = lp->n_next;
		sgFree(lp->n_name);
		sgFree(lp);
		lp = lq;
	}
}
Example #3
0
void setRealmToStrip(const char *value)
{
	if (realm)
		sgFree(realm);
	realm = sgStrdup(value);

	stripRealm = 1;
}
Example #4
0
void Pixmap::cleanupData ()
{
    if ( m_pixels != 0 )
        sgFree ( m_pixels );
    m_pixels = 0;
    m_width = 0;
    m_height = 0;
    m_error[0] = '\0';
}
Example #5
0
static void authzExtra(struct AccessList *acl)
{
	char msg[MAX_BUF];
	char *escaped = NULL;

	snprintf(msg, MAX_BUF, "Request matched rule %s", acl->name);
	escaped = HTEscape(msg, URL_XALPHAS);
	fprintf(stdout, " log=%s", escaped);
	fprintf(stdout, " message=%s", escaped);
	sgFree(escaped);

	if (acl->tag) {
		escaped = HTEscape(acl->tag, URL_XALPHAS);
		fprintf(stdout, " tag=%s", escaped);
		sgFree(escaped);
	}

	fflush(stdout);
}
    bool sgGLShader::prepareShader(void)
    {
		std::string errInfo = std::string("    ") + std::string(this->getFilename().getStr()) + std::string("    sgGLShader::prepareShader");

        // create
        sgAssert(glCreateShader , "no function glCreateShader");
		mShaderId = glCreateShader(mShaderType);
        if(mShaderId == 0)
        {
            sgLogSystem::instance()->error(SG_CHECK_GL_ERROR() + errInfo);
            return false;
        }

        // compile
        const GLchar *s[1];
        s[0] = mShaderSource.c_str();
        glShaderSource(mShaderId, 1, s , 0);
        
        std::string err;
        err = SG_CHECK_GL_ERROR();
        if(!err.empty())
        {
            sgLogSystem::instance()->error(err + errInfo);
            return false;
        }
        
        glCompileShader(mShaderId);
        err = SG_CHECK_GL_ERROR();
        if(!err.empty())
        {
            sgLogSystem::instance()->error(err + errInfo);
            return false;
        }
        
        //check error
        GLsizei temp;
        glGetShaderiv(mShaderId, GL_COMPILE_STATUS, &temp);
        if(temp == GL_FALSE)
        {
            glGetShaderiv(mShaderId, GL_INFO_LOG_LENGTH, &temp);
            char *log = (char*)sgMalloc(temp);
            glGetShaderInfoLog(mShaderId, temp, &temp, log);
            sgLogSystem::instance()->error(std::string(log) + errInfo);
            
            sgFree(log);
            
            return false;
        }
        
        return true;
    }
Example #7
0
void addUserToSource(struct SourceList *list, const char *ident)
{
	char *user = sgStrdup(ident);
	char *lc;

	for (lc = user; *lc != '\0'; lc++) /* convert username to lowercase chars */
		*lc = tolower(*lc);

	addUserPermanently(list, user);

	sgLogDebug("Added User: %s", user);

	sgFree(user);
}
Example #8
0
static void allowOnError(const char *message)
{
	char *escaped = NULL;

	if (!authzMode) {
		fprintf(stdout, "\n");
		fflush(stdout);
	}

	escaped = HTEscape(message, URL_XALPHAS);
	fprintf(stdout, "OK log=%s message=%s\n", escaped, escaped);
	sgFree(escaped);

	fflush(stdout);
}
Example #9
0
void setSetting(const char *key, const char *value)
{
	struct Setting *setting;

	sgLogDebug("set setting '%s', value '%s'", key, value);

	if ((setting = findSetting(key)) == NULL) {
		sgLogWarn("setting '%s' is not registered (value='%s')", key, value);
		setting = newSetting(key, value);
	} else {
		sgFree(setting->value);
		setting->value = sgStrdup(value);
	}

	if (setting->cb)
		setting->cb(value);
}
Example #10
0
static void denyOnError(const char *message)
{
	char *escaped = NULL;

	escaped = HTEscape(message, URL_XALPHAS);

	if (!authzMode) {
		const char *redir = (errorRedirect && *errorRedirect) ? errorRedirect : "Error:";
		if (!strchr(redir,'?')) {
			fprintf(stdout, "%s?message=%s\n", redir, escaped);
		} else {
			fprintf(stdout, "%s&message=%s\n", redir, escaped);
		}
	} else {
		fprintf(stdout, "ERR log=%s message=%s\n", escaped, escaped);
	}
	sgFree(escaped);
	fflush(stdout);
}
    bool sgGLGpuProgram::getParameters(void)
    {
		int count;
		int maxChar;
		GLint size;
		GLenum type;
		glGetProgramiv(mProgramId, GL_ACTIVE_UNIFORMS, &count);
		glGetProgramiv(mProgramId, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxChar);
        mParameterList.clear();
		char *name = (char*)sgMalloc(maxChar);
		for(int i=0; i<count; ++i)
		{
			glGetActiveUniform(mProgramId, i, maxChar, NULL, &size, &type, name);
			// check is predefined uniform variant
            std::string strName = name;
			if(sgStringUtil::start_with(strName, "gl_"))
			{
				continue;
			}
			if(sgStringUtil::start_with(strName, "[0]"))
			{
				size_t index = strName.find_first_of('[');
				strName = strName.substr(0, index);
			}
            
            sgGpuParameter param;
            param.name = strName;
			param.type = sgGetRendererDataType(type);
            param.location = glGetUniformLocation(mProgramId, name);

            mParameterList.insert(std::make_pair(sgStrHandle(strName.c_str()), param));
            
		}
		sgFree(name);
        
        std::string err = SG_CHECK_GL_ERROR();
        if(!err.empty())
            return false;
        else
            return true;

    }
    bool sgGLGpuProgram::getAttributes(void)
    {
        int count;
		int maxChar;
		GLint size;
		GLenum type;
		glGetProgramiv(mProgramId, GL_ACTIVE_ATTRIBUTES, &count);
		glGetProgramiv(mProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxChar);
        
        mAttributeList.clear();
        
		char *name = (char*)sgMalloc(maxChar);
		for(int i=0; i<count; ++i)
		{
			glGetActiveAttrib(mProgramId, i, maxChar, NULL, &size, &type, name);
            // check is predefined attribute variant
			std::string strName = name;
			if(sgStringUtil::start_with(strName, "gl_"))
			{
				continue;
			}
            
            sgGpuAttribute attr;
            attr.name = strName;
			attr.type = sgGetRendererDataType(type);
            attr.location = glGetAttribLocation(mProgramId, name);
            mAttributeList.insert(std::make_pair(sgStrHandle(strName.c_str()), attr));
		}
        sgFree(name);
        
		std::string err = SG_CHECK_GL_ERROR();
        if(!err.empty())
            return false;
        else
            return true;
		
    }
Example #13
0
static int parseUrl(char *url, struct SquidInfo *s)
{
	char *p = NULL;
	char *d = NULL;
	size_t l = 0;
	size_t n = 0;
	char *domain = NULL;
	char *sdomain = NULL;

	char *pathcp = sgStrdup(url);

	memset(pathcp, 0, strlen(url));

	strncpy(s->orig, url, sizeof(s->orig));

	/* Now convert url to lowercase chars */
	for (p = url; *p != '\0'; p++)
		*p = tolower(*p);

	if ((p = strstr(url, "://")) == NULL) {
		strcpy(s->protocol, "unknown");
		p = url;
	} else {
		*p = 0;
		strcpy(s->protocol, url);
		p += 3;
	}

	/* p points to the begining of the host part, find first slash that ends it */
	domain = p;
	if ((d = strchr(p, '/')) != NULL) {
		p = d + 1;
		*d = 0;
	} else {
		p = NULL;
	}

	/* p now is either NULL or points to the first char in the path part*/
	if (p != NULL) {
		char *to = pathcp;
		char *from = p;

		/* skip leading slashes */
		while (*from == '/')
			from++;

		while (*from != 0 && *from != '?') {
			/* skip double slashes */
			if (*from == '/' && *(from + 1) == '/') {
				from++;
				continue;
			}
			*to = *from;
			to++; from++;
		}

		/* keep the query part when present */
		if (*from == '?')
			strcat(to, from);
	}

	/* skip authentication */
	if ((d = strchr(domain, '@')) != NULL)
		domain = d + 1;

	/* look for a port */
	if ((d = strrchr(domain, ':')) != NULL) {
		n = strspn(d + 1, "0123456789");
		if (*(d + n + 1) == 0) {
			s->port = atoi(d + 1);
			*d = 0;
		}
	}

	if (*domain == 0)
		return 0;

	strcpy(s->domain, domain);
	l = strlen(s->domain);

	if (strspn(s->domain, ".0123456789") == l) {
		/* may be an IPv4 address */
		unsigned char binaddr[sizeof(struct in_addr)];
		int changed = 0;

		if (inet_pton(AF_INET, s->domain, &binaddr) > 0) {
			struct hostent *hp = NULL;

			if (reverselookup) {
				if ((hp = gethostbyaddr(binaddr, sizeof(binaddr), AF_INET)) != NULL) {
					if (strlen(hp->h_name) < sizeof(s->domain)) {
						strcpy(s->domain, hp->h_name);
						changed = 0;
					}
				}
			}

			if (!changed)
				s->isAddress = 1;
		}
	} else if (s->domain[0] == '[' && s->domain[l - 1] == ']' &&
		   (strspn(s->domain + 1, ":0123456789abcdef") == l - 2)) {
		/* may be an IPv6 address */
		unsigned char binaddr[sizeof(struct in6_addr)];
		int changed = 0;

		s->domain[l - 1] = 0;

		if (inet_pton(AF_INET6, s->domain + 1, &binaddr) > 0) {
			struct hostent *hp = NULL;

			if (reverselookup) {
				if ((hp = gethostbyaddr(binaddr, sizeof(binaddr), AF_INET6)) != NULL) {
					if (strlen(hp->h_name) < sizeof(s->domain)) {
						strcpy(s->domain, hp->h_name);
						changed = 1;
					}
				}
			}

			if (!changed)
				s->isAddress = 1;
		}

		if (!changed)
			s->domain[l - 1] = ']';
	}

	/* strip trailing dot from domain */
	if ((d = s->domain + strlen(s->domain) - 1) >= s->domain)
		if (*d == '.')
			*d = 0;

	/* strip common host names like www.foo.com or web01.bar.org  */
	sdomain = s->domain;

	if ((domain[0] == 'w' && domain[1] == 'w' && domain[2] == 'w') ||
	    (domain[0] == 'w' && domain[1] == 'e' && domain[2] == 'b') ||
	    (domain[0] == 'f' && domain[1] == 't' && domain[2] == 'p')) {
		sdomain += 3;
		while (sdomain[0] >= '0' && sdomain[0] <= '9')
			sdomain++;

		if (sdomain[0] == '.')
			sdomain++;
		else
			sdomain = domain;
	}

	if (s->port > 0) {
		sprintf(s->furl, "%s:%d/%s", domain, s->port, pathcp);
		sprintf(s->surl, "%s:%d/%s", sdomain, s->port, pathcp);
	} else {
		sprintf(s->furl, "%s/%s", domain, pathcp);
		sprintf(s->surl, "%s/%s", sdomain, pathcp);
	}

	sgLogDebug("furl: %s domain: '%s' sdomain: '%s'", s->furl, s->domain, sdomain);

	sgFree(pathcp);

	return 1;
}
Example #14
0
int main(int argc, char **argv, char **envp)
{
	struct ReadBuffer * buf = newReadBuffer(fileno(stdin));
	char * line = NULL;
	size_t linesz = 0;
	int act = 0;

	setupSignals();

	openlog("squidGuard", LOG_PID | LOG_NDELAY | LOG_CONS, SYSLOG_FAC);

	if (!parseOptions(argc, argv)) {
		closelog();
		exit(1);
	}

	registerSettings();

	//sgSetGlobalErrorLogFile();
	sgReadConfig(configFile);
	sgSetGlobalErrorLogFile();

	sgLogInfo("squidGuard %s started", VERSION);

	if (globalUpdate || globalCreateDb != NULL) {
		sgLogInfo("db update done");
		sgLogInfo("squidGuard stopped.");
		closelog();

		freeAllLists();
		exit(0);
	}

	sgLogInfo("squidGuard ready for requests");

	while ((act = doBufferRead(buf, &line, &linesz)) >= 0) {
		struct AccessList *acl;
		static struct SquidInfo request;

		if (act == 0) {
			sgReloadConfig(configFile);
			continue;
		}

		if (authzMode == 1) {
			if (parseAuthzLine(line, &request) != 1) {
				sgLogError("Error parsing squid acl helper line");
				denyOnError("Error parsing squid acl helper line");
				continue;
			}
		} else {
			if (parseLine(line, &request) != 1) {
				sgLogError("Error parsing squid redirector line");
				denyOnError("Error parsing squid redirector line");
				continue;
			}
		}

		if (inEmergencyMode) {
			const char *message = "squidGuard is in emergency mode, check configuration";
			if (passthrough)
				allowOnError(message);
			else
				denyOnError(message);
			continue;
		}

		for (acl = getFirstAccessList(); acl; acl = acl->next) {
			char *redirect = NULL;
			enum AccessResults access = checkAccess(acl, &request, &redirect);

			if (access == ACCESS_UNDEFINED)
				continue;

			if (access == ACCESS_GRANTED) {
				grantAccess(acl);
				break;
			}

			denyAccess(acl, redirect, &request);
			sgFree(redirect);

			break;
		}

		fflush(stdout);
	}

	sgLogNotice("squidGuard stopped");
	closelog();
	freeAllLists();
	sgFree(line);
	freeReadBuffer(buf);
	exit(0);
}
Example #15
0
void freeErrorRedirect()
{
	sgFree(errorRedirect);
	errorRedirect = NULL;
}
Example #16
0
void sgFreeAllLists()
{
#define FREE_LIST(type, head, func) \
       { \
               struct type *next; \
               while(head != NULL) { \
                       next = head->next; \
                       func(head); \
                       head = next; \
               } \
       }

       /* settings linked list */
       FREE_LIST(Setting, Setting, sgFreeSetting)
       lastSetting = NULL;
       Setting = NULL;

       /* sources */
       FREE_LIST(Source, Source, sgFreeSource)
       lastSource = NULL;
       Source = NULL;
       lastActiveSource = NULL;

       /* dests */
       FREE_LIST(Destination, Dest, sgFreeDestination)
       lastDest = NULL;
       Dest = NULL;

       /* rewrites */
       FREE_LIST(sgRewrite, Rewrite, sgFreeRewrite)
       lastRewrite = NULL;
       Rewrite = NULL;
       lastRewriteRegExec = NULL;

       /* time structures */
       FREE_LIST(Time, Time, sgFreeTime)
       lastTime = NULL;
       Time = NULL;
       lastTimeElement = NULL;
       TimeElement = NULL;

       /* log file stats */
       FREE_LIST(LogFileStat, LogFileStat, sgFreeLogFileStat)
       lastLogFileStat = NULL;
       LogFileStat = NULL;

       /* access control lists */
       FREE_LIST(Acl, Acl, sgFreeAcl)
       lastAcl = NULL;
       defaultAcl = NULL;
       Acl = NULL;
       lastAclDest = NULL;


       /* single variables */
       free(globalLogDir);
       globalLogDir = NULL;

       sgFree(TimeElementsEvents);
       TimeElementsEvents = NULL;
}
Example #17
0
static void freeSourceDomainPrivate(void *priv)
{
	freeDb(((struct SourceDomainPrivate *)priv)->db);
	sgFree(priv);
}
    bool sgGLGpuProgram::prepareProgram(void)
    {
        if(mProgramId == 0)
            return false;

		std::string errInfo = "    sgGLGpuProgram::prepareProgram";

        sgShader *vs = this->getVertexShader();
        if(!vs->isActive() || vs->getShaderType() != GL_VERTEX_SHADER)
        {
            sgLogSystem::instance()->error(std::string("No vertex shader") + errInfo);
            return false;
        }
        sgShader *fs = this->getFragmentShader();
        if(!fs->isActive() || fs->getShaderType() != GL_FRAGMENT_SHADER)
        {
            sgLogSystem::instance()->error(std::string("No fragment shader") + errInfo);
            return false;
        }
        
        glAttachShader(mProgramId, vs->getShaderId());
        std::string err = SG_CHECK_GL_ERROR();
        if(!err.empty())
        {
            sgLogSystem::instance()->error(err + errInfo);
            return false;
        }
        glAttachShader(mProgramId, fs->getShaderId());
        err = SG_CHECK_GL_ERROR();
        if(!err.empty())
        {
            sgLogSystem::instance()->error(err + errInfo);
            return false;
        }
        
        glLinkProgram(mProgramId);
        err = SG_CHECK_GL_ERROR();
        if(!err.empty())
        {
            sgLogSystem::instance()->error(err);
            return false;
        }
        
        //check error
        GLsizei temp;
        glGetProgramiv(mProgramId, GL_LINK_STATUS, &temp);
        if(temp == GL_FALSE)
        {
            glGetProgramiv(mProgramId, GL_INFO_LOG_LENGTH, &temp);
            char *log = (char*)sgMalloc(temp);
            glGetProgramInfoLog(mProgramId, temp, &temp, log);
            sgFree(log);
            
            sgLogSystem::instance()->error(std::string(log) + errInfo);
            
            return false;
        }
        
        if(!getParameters() || !getAttributes())
            return false;
        
        return true;
    }
 void sgMemObject::operator delete(void *ptr, void*)
 {
     sgFree(ptr);
 }
 void sgMemObject::operator delete[](void *ptr)
 {
     sgFree(ptr);
 }
Example #21
0
static void freeNetgroupMatch(void *o)
{
	sgFree(o);
}
Example #22
0
void Pixmap::resample_Y ( u32 newHeight )
{
    Color* newPixels = (Color *)sgMalloc ( sizeof(Color) * m_width * newHeight );
    
    if ( newHeight < m_height )
    {
        float ratio = m_height / (float)newHeight;
        for ( u32 w = 0; w < m_width; ++w )
        {
            u32 h = 0;
            for ( float y = 0.0f; h < newHeight; y += ratio, ++h )
            {
                float from = y;
                float to = min((float)m_height, y + ratio);

                u32 absoluteValue = (u32)floor(from);
                float fractionaryPart = from-absoluteValue;
                float pixelAccum [ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f };

                if ( fractionaryPart > 0.000001f )
                {
                    float factor = 1.0f - fractionaryPart;
                    Color& color = m_pixels [ m_width*absoluteValue + w ];
                    pixelAccum[0] += ( color.r() / 255.0f ) * factor;
                    pixelAccum[1] += ( color.g() / 255.0f ) * factor;
                    pixelAccum[2] += ( color.b() / 255.0f ) * factor;
                    pixelAccum[3] += ( color.a() / 255.0f ) * factor;
                    from = absoluteValue + 1;
                }
                from = floor(from);
                
                while ( to-from > 1.0f )
                {
                    Color& color = m_pixels [ m_width*(u32)from + w ];
                    pixelAccum[0] += color.r() / 255.0f;
                    pixelAccum[1] += color.g() / 255.0f;
                    pixelAccum[2] += color.b() / 255.0f;
                    pixelAccum[3] += color.a() / 255.0f;
                    ++from;
                }
                
                if ( fabs(to-from) > 0.000001f )
                {
                    float factor = fabs(to-from);
                    Color& color = m_pixels [ m_width*(u32)from + w ];
                    pixelAccum[0] += (color.r() / 255.0f) * factor;
                    pixelAccum[1] += (color.g() / 255.0f) * factor;
                    pixelAccum[2] += (color.b() / 255.0f) * factor;
                    pixelAccum[3] += (color.a() / 255.0f) * factor;
                }
                
                newPixels [ m_width*h + w ] = Color ( pixelAccum[0] / ratio * 255.0f,
                                                      pixelAccum[1] / ratio * 255.0f,
                                                      pixelAccum[2] / ratio * 255.0f,
                                                      pixelAccum[3] / ratio * 255.0f );
            }
        }
    }
    else if ( newHeight > m_height )
    {
        float ratio = m_height / (float)newHeight;
        for ( u32 w = 0; w < m_width; ++w )
        {
            for ( u32 h = 0; h < newHeight; ++h )
            {
                u32 up = (u32)floor(h * ratio);
                u32 down = min(m_height-1, up+1);
                u32 upPrev = up > 0 ? up-1 : 0;
                u32 downNext = min(m_height-1, down+1);
                
                Color& u = m_pixels [ up*m_width + w ];
                Color& d = m_pixels [ down*m_width + w ];
                Color& u_ = m_pixels [ upPrev*m_width + w ];
                Color& dn = m_pixels [ downNext*m_width + w ];
                
                float colorValues [ 4 ][ 4 ] =
                {
                    { u.r() / 255.0f,  u.g() / 255.0f,  u.b() / 255.0f,  u.a() / 255.0f },
                    { d.r() / 255.0f,  d.g() / 255.0f,  d.b() / 255.0f,  d.a() / 255.0f },
                    { u_.r() / 255.0f, u_.g() / 255.0f, u_.b() / 255.0f, u_.a() / 255.0f },
                    { dn.r() / 255.0f, dn.g() / 255.0f, dn.b() / 255.0f, dn.a() / 255.0f }
                };
                float tangents [ 2 ][ 4 ] =
                {
                    { colorValues[1][0]-colorValues[2][0], colorValues[1][1]-colorValues[2][1], colorValues[1][2]-colorValues[2][2], colorValues[1][3]-colorValues[2][3] },
                    { colorValues[3][0]-colorValues[0][0], colorValues[3][1]-colorValues[0][1], colorValues[3][2]-colorValues[0][2], colorValues[3][3]-colorValues[0][3] }
                };
                
                float interpolatedValues [ 4 ];
                float alpha = h*ratio;
                alpha = alpha - floor(alpha);
                
                interpolatedValues[0] = clamp(0.0f, cubic_interpolate(colorValues[0][0], tangents[0][0], alpha, colorValues[1][0], tangents[1][0]), 1.0f);
                interpolatedValues[1] = clamp(0.0f, cubic_interpolate(colorValues[0][1], tangents[0][1], alpha, colorValues[1][1], tangents[1][1]), 1.0f);
                interpolatedValues[2] = clamp(0.0f, cubic_interpolate(colorValues[0][2], tangents[0][2], alpha, colorValues[1][2], tangents[1][2]), 1.0f);
                interpolatedValues[3] = clamp(0.0f, cubic_interpolate(colorValues[0][3], tangents[0][3], alpha, colorValues[1][3], tangents[1][3]), 1.0f);
                newPixels [ h*m_width + w ] = Color ( interpolatedValues[0] * 255.0f,
                                                      interpolatedValues[1] * 255.0f,
                                                      interpolatedValues[2] * 255.0f,
                                                      interpolatedValues[3] * 255.0f );
            }
        }
    }
    
    sgFree ( m_pixels );
    m_pixels = newPixels;
    m_height = newHeight;
}
Example #23
0
void Pixmap::resample_X ( u32 newWidth )
{
    Color* newPixels = (Color *)sgMalloc ( sizeof(Color) * newWidth * m_height );
    
    if ( newWidth < m_width )
    {
        float ratio = m_width / (float)newWidth;
        for ( u32 h = 0; h < m_height; ++h )
        {
            u32 w = 0;
            for ( float x = 0.0f; w < newWidth; x += ratio, ++w )
            {
                float from = x;
                float to = min((float)m_width, x + ratio);

                u32 absoluteValue = (u32)floor(from);
                float fractionaryPart = from-absoluteValue;
                float pixelAccum [ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f };

                if ( fractionaryPart > 0.000001f )
                {
                    float factor = 1.0f - fractionaryPart;
                    Color& color = m_pixels [ m_width*h + absoluteValue ];
                    pixelAccum[0] += ( color.r() / 255.0f ) * factor;
                    pixelAccum[1] += ( color.g() / 255.0f ) * factor;
                    pixelAccum[2] += ( color.b() / 255.0f ) * factor;
                    pixelAccum[3] += ( color.a() / 255.0f ) * factor;
                    from = absoluteValue + 1;
                }
                from = floor(from);
                
                while ( to-from > 1.0f )
                {
                    Color& color = m_pixels [ m_width*h + (u32)from ];
                    pixelAccum[0] += color.r() / 255.0f;
                    pixelAccum[1] += color.g() / 255.0f;
                    pixelAccum[2] += color.b() / 255.0f;
                    pixelAccum[3] += color.a() / 255.0f;
                    ++from;
                }
                
                if ( fabs(to-from) > 0.000001f )
                {
                    float factor = fabs(to-from);
                    Color& color = m_pixels [ m_width*h + (u32)from ];
                    pixelAccum[0] += (color.r() / 255.0f) * factor;
                    pixelAccum[1] += (color.g() / 255.0f) * factor;
                    pixelAccum[2] += (color.b() / 255.0f) * factor;
                    pixelAccum[3] += (color.a() / 255.0f) * factor;
                }
                
                newPixels [ newWidth*h + w ] = Color ( pixelAccum[0] / ratio * 255.0f,
                                                       pixelAccum[1] / ratio * 255.0f,
                                                       pixelAccum[2] / ratio * 255.0f,
                                                       pixelAccum[3] / ratio * 255.0f );
            }
        }
    }
    else if ( newWidth > m_width )
    {
        float ratio = m_width / (float)newWidth;
        for ( u32 h = 0; h < m_height; ++h )
        {
            for ( u32 w = 0; w < newWidth; ++w )
            {
                u32 left = (u32)floor(w * ratio);
                u32 right = min(m_width-1, left+1);
                u32 leftPrev = left > 0 ? left-1 : 0;
                u32 rightNext = min(m_width-1, right+1);
                
                Color& l = m_pixels [ h*m_width + left ];
                Color& r = m_pixels [ h*m_width + right ];
                Color& lp = m_pixels [ h*m_width + leftPrev ];
                Color& rn = m_pixels [ h*m_width + rightNext ];
                
                float colorValues [ 4 ][ 4 ] =
                {
                    { l.r() / 255.0f,  l.g() / 255.0f,  l.b() / 255.0f,  l.a() / 255.0f },
                    { r.r() / 255.0f,  r.g() / 255.0f,  r.b() / 255.0f,  r.a() / 255.0f },
                    { lp.r() / 255.0f, lp.g() / 255.0f, lp.b() / 255.0f, lp.a() / 255.0f },
                    { rn.r() / 255.0f, rn.g() / 255.0f, rn.b() / 255.0f, rn.a() / 255.0f }
                };
                float tangents [ 2 ][ 4 ] =
                {
                    { colorValues[1][0]-colorValues[2][0], colorValues[1][1]-colorValues[2][1], colorValues[1][2]-colorValues[2][2], colorValues[1][3]-colorValues[2][3] },
                    { colorValues[3][0]-colorValues[0][0], colorValues[3][1]-colorValues[0][1], colorValues[3][2]-colorValues[0][2], colorValues[3][3]-colorValues[0][3] }
                };
                
                float interpolatedValues [ 4 ];
                float alpha = w*ratio;
                alpha = alpha - floor(alpha);
                
                interpolatedValues[0] = clamp(0.0f, cubic_interpolate(colorValues[0][0], tangents[0][0], alpha, colorValues[1][0], tangents[1][0]), 1.0f);
                interpolatedValues[1] = clamp(0.0f, cubic_interpolate(colorValues[0][1], tangents[0][1], alpha, colorValues[1][1], tangents[1][1]), 1.0f);
                interpolatedValues[2] = clamp(0.0f, cubic_interpolate(colorValues[0][2], tangents[0][2], alpha, colorValues[1][2], tangents[1][2]), 1.0f);
                interpolatedValues[3] = clamp(0.0f, cubic_interpolate(colorValues[0][3], tangents[0][3], alpha, colorValues[1][3], tangents[1][3]), 1.0f);
                newPixels [ h*newWidth + w ] = Color ( interpolatedValues[0] * 255.0f,
                                                       interpolatedValues[1] * 255.0f,
                                                       interpolatedValues[2] * 255.0f,
                                                       interpolatedValues[3] * 255.0f );
            }
        }
    }
    
    sgFree ( m_pixels );
    m_pixels = newPixels;
    m_width = newWidth;
}