src/sampler.cc
branchpyrit
changeset 77 dbe8438d5dca
parent 53 228cb8bfdd54
child 82 930a2d3ecaed
equal deleted inserted replaced
76:3b60fd0bea64 77:dbe8438d5dca
    38 {
    38 {
    39 	static const int gridsamples[] = {1,5,9,16};
    39 	static const int gridsamples[] = {1,5,9,16};
    40 	const int samples = gridsamples[oversample];
    40 	const int samples = gridsamples[oversample];
    41 	if ( phase == 0 )
    41 	if ( phase == 0 )
    42 	{
    42 	{
    43 		phase++;
    43 		if (subsample > 1)
       
    44 		{
       
    45 			phase = 1;
       
    46 			sx = -1;
       
    47 			return (w/subsample+1)*(h/subsample+1);
       
    48 		}
       
    49 		else
       
    50 		{
       
    51 			phase = 2;
       
    52 			sx = -1;
       
    53 			return w*h*samples;
       
    54 		}
       
    55 	}
       
    56 	if ( phase == 1 )
       
    57 	{
       
    58 		// finalize subsampling
       
    59 		const Float subsample2 = 1.0/(subsample*subsample);
       
    60 		int num_samples = 0;
       
    61 		Colour ic;
       
    62 		phase = 2;
    44 		sx = -1;
    63 		sx = -1;
    45 		return w*h*samples;
    64 		for (int y = 0; y < h/subsample; y++)
    46 	}
    65 			for (int x = 0; x < w/subsample; x++)
    47 	else if ( phase == 1 && oversample )
    66 			{
    48 	{
    67 				int x1 = x*subsample;
    49 		phase = -1;
    68 				int y1 = y*subsample;
       
    69 				int x2 = (x+1)*subsample;
       
    70 				int y2 = (y+1)*subsample;
       
    71 				if (x2 > w-1)	x2 = w-1;
       
    72 				if (y2 > h-1)	y2 = h-1;
       
    73 				if (x1 == x2 || y1 == y2)
       
    74 					continue;
       
    75 				Float *p;
       
    76 				p = buffer + 3*(y1*w + x1);
       
    77 				Colour c1(*p, *(p+1), *(p+2));
       
    78 				p = buffer + 3*(y1*w + x2);
       
    79 				Colour c2(*p, *(p+1), *(p+2));
       
    80 				p = buffer + 3*(y2*w + x1);
       
    81 				Colour c3(*p, *(p+1), *(p+2));
       
    82 				p = buffer + 3*(y2*w + x2);
       
    83 				Colour c4(*p, *(p+1), *(p+2));
       
    84 				Float m = (c1-c2).mag2();
       
    85 				m = max(m, (c2-c3).mag2());
       
    86 				m = max(m, (c3-c4).mag2());
       
    87 				m = max(m, (c4-c1).mag2());
       
    88 				if (m < 0.002)
       
    89 				{
       
    90 					// interpolate
       
    91 					for (int i = 0; i < subsample; i++)
       
    92 						for (int j = 0; j < subsample; j++)
       
    93 						{
       
    94 							ic = c1*(subsample-i)*(subsample-j)*subsample2
       
    95 								+ c2*(i)*(subsample-j)*subsample2
       
    96 								+ c3*(subsample-i)*(j)*subsample2
       
    97 								+ c4*(i)*(j)*subsample2;
       
    98 							p = buffer + 3*((y1+j)*w + x1+i);
       
    99 							*(p + 0) = ic.r;
       
   100 							*(p + 1) = oversample ? -ic.g : ic.g;
       
   101 							*(p + 2) = ic.b;
       
   102 						}
       
   103 				}
       
   104 				else
       
   105 				{
       
   106 					// mark as to be computed
       
   107 					num_samples += subsample * subsample;
       
   108 					for (int i = 0; i < subsample; i++)
       
   109 						for (int j = 0; j < subsample; j++)
       
   110 							if (oversample || i != 0 || j != 0)
       
   111 								*(buffer + 3*((y1+j)*w + x1+i)) = -1.;
       
   112 				}
       
   113 			}
       
   114 		return num_samples;
       
   115 	}
       
   116 	if ( phase == 2 && oversample )
       
   117 	{
       
   118 		// finalize oversampling
    50 		Float *buf;
   119 		Float *buf;
    51 		for (buf = buffer; buf != buffer + w*h*3; buf++)
   120 		if (subsample > 1)
    52 			*buf = *buf * (1.0/samples);
   121 			for (buf = buffer; buf != buffer + w*h*3; buf += 3)
    53 		return 0;
   122 				if (*(buf+1) < 0)
    54 	}
   123 				{
    55 	else
   124 					// interpolated
    56 	{
   125 					*(buf+1) = -*(buf+1);
    57 		phase = -1;
   126 				}
    58 		return 0;
   127 				else
    59 	}
   128 				{
       
   129 					*buf = *buf * (1.0/samples);
       
   130 					*(buf+1) = *(buf+1) * (1.0/samples);
       
   131 					*(buf+2) = *(buf+2) * (1.0/samples);
       
   132 				}
       
   133 		else
       
   134 			for (buf = buffer; buf != buffer + w*h*3; buf++)
       
   135 				*buf = *buf * (1.0/samples);
       
   136 	}
       
   137 	phase = -1;
       
   138 	return 0;
    60 }
   139 }
    61 
   140 
    62 bool DefaultSampler::nextSample(Sample* s)
   141 bool DefaultSampler::nextSample(Sample* s)
    63 {
   142 {
    64 	/* grid oversampling */
   143 	if (phase == 1)
    65 	static const int gridsamples[] = {1,5,9,16};
   144 	{
    66 	static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4};
   145 		// subsampling
    67 	static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4};
   146 		if (sx < 0)
    68 	static const Float osa9x[] = {-0.34,  0.00, +0.34,
   147 		{
    69 		-0.34,  0.00, +0.34, -0.34,  0.00, +0.34};
   148 			// first sample
    70 	static const Float osa9y[] = {-0.34, -0.34, -0.34,
   149 			s->x = -(Float)w/h/2.0;
    71 			0.00,  0.00,  0.00, +0.34, +0.34, +0.34};
   150 			s->y = -0.5;
    72 	static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375,
   151 			sx = 0;
    73 		-0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375,
   152 			sy = 0;
    74 		-0.375, -0.125, +0.125, +0.375};
   153 			osa_samp = 0;
    75 	static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375,
   154 		}
    76 		-0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125,
   155 		else
    77 		+0.375, +0.375, +0.375, +0.375};
   156 		{
    78 	static const Float *osaSx[] = {NULL, osa5x, osa9x, osa16x};
   157 			if (sx == w-1)
    79 	static const Float *osaSy[] = {NULL, osa5y, osa9y, osa16y};
   158 			{
    80 	const int samples = gridsamples[oversample];
   159 				if (sy == h-1)
    81 	const Float *osax = osaSx[oversample];
   160 					return false;
    82 	const Float *osay = osaSy[oversample];
   161 				sy += subsample;
    83 
   162 				if (sy > h-1)
    84 	if (sx < 0)
   163 					sy = h-1;
    85 	{
       
    86 		// first sample
       
    87 		s->x = -(Float)w/h/2.0;
       
    88 		s->y = -0.5;
       
    89 		sx = 0;
       
    90 		sy = 0;
       
    91 		osa_samp = 0;
       
    92 	}
       
    93 	else
       
    94 	{
       
    95 		osa_samp++;
       
    96 
       
    97 		if (oversample && oversample <= 3 && osa_samp < samples)
       
    98 		{
       
    99 			s->x = osax[osa_samp]/h + (Float)sx/h - (Float)w/h/2.0;
       
   100 			s->y = osay[osa_samp]/h + (Float)sy/h - 0.5;
       
   101 		}
       
   102 		else
       
   103 		{
       
   104 			sx++;
       
   105 			if (sx >= w)
       
   106 			{
       
   107 				sx = 0;
   164 				sx = 0;
   108 				sy++;
   165 			}
   109 			}
   166 			else
   110 
   167 			{
   111 			if (sy >= h)
   168 				sx += subsample;
   112 				return false;
   169 				if (sx > w-1)
       
   170 					sx = w-1;
       
   171 			}
   113 
   172 
   114 			s->x = (Float)sx/h - (Float)w/h/2.0;
   173 			s->x = (Float)sx/h - (Float)w/h/2.0;
   115 			s->y = (Float)sy/h - 0.5;
   174 			s->y = (Float)sy/h - 0.5;
       
   175 		}
       
   176 	}
       
   177 	else if (phase == 2)
       
   178 	{
       
   179 		/* grid oversampling */
       
   180 		static const int gridsamples[] = {1,5,9,16};
       
   181 		static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4};
       
   182 		static const Float osa5y[] = {0.0, -0.4, -0.4, +0.4, +0.4};
       
   183 		static const Float osa9x[] = {-0.34,  0.00, +0.34,
       
   184 			-0.34,  0.00, +0.34, -0.34,  0.00, +0.34};
       
   185 		static const Float osa9y[] = {-0.34, -0.34, -0.34,
       
   186 				0.00,  0.00,  0.00, +0.34, +0.34, +0.34};
       
   187 		static const Float osa16x[] = {-0.375, -0.125, +0.125, +0.375,
       
   188 			-0.375, -0.125, +0.125, +0.375, -0.375, -0.125, +0.125, +0.375,
       
   189 			-0.375, -0.125, +0.125, +0.375};
       
   190 		static const Float osa16y[] = {-0.375, -0.375, -0.375, -0.375,
       
   191 			-0.125, -0.125, -0.125, -0.125, +0.125, +0.125, +0.125, +0.125,
       
   192 			+0.375, +0.375, +0.375, +0.375};
       
   193 		static const Float *osaSx[] = {NULL, osa5x, osa9x, osa16x};
       
   194 		static const Float *osaSy[] = {NULL, osa5y, osa9y, osa16y};
       
   195 		const int samples = gridsamples[oversample];
       
   196 		const Float *osax = osaSx[oversample];
       
   197 		const Float *osay = osaSy[oversample];
       
   198 
       
   199 		if (sx < 0)
       
   200 		{
       
   201 			// first sample
       
   202 			s->x = -(Float)w/h/2.0;
       
   203 			s->y = -0.5;
       
   204 			sx = 0;
       
   205 			sy = 0;
   116 			osa_samp = 0;
   206 			osa_samp = 0;
   117 		}
   207 		}
   118 	}
   208 		else
   119 
   209 		{
   120 	if (osa_samp == 0 && oversample && oversample <= 3)
   210 			osa_samp++;
   121 	{
   211 
   122 		s->x += osax[0]/h;
   212 			if (oversample && oversample <= 3 && osa_samp < samples)
   123 		s->y += osay[0]/h;
   213 			{
   124 		Float *buf = buffer + 3*(sy*w + sx);
   214 				s->x = osax[osa_samp]/h + (Float)sx/h - (Float)w/h/2.0;
   125 		*(buf++) = 0;
   215 				s->y = osay[osa_samp]/h + (Float)sy/h - 0.5;
   126 		*(buf++) = 0;
   216 			}
   127 		*(buf++) = 0;
   217 			else
       
   218 			{
       
   219 				sx++;
       
   220 				if (sx >= w)
       
   221 				{
       
   222 					sx = 0;
       
   223 					sy++;
       
   224 				}
       
   225 				if (sy >= h)
       
   226 					return false;
       
   227 
       
   228 				if (subsample > 1)
       
   229 				{
       
   230 					// find next not interpolated pixel
       
   231 					while ( *(buffer + 3*(sy*w + sx)) >= 0. )
       
   232 					{
       
   233 						sx++;
       
   234 						if (sx >= w)
       
   235 						{
       
   236 							sx = 0;
       
   237 							sy++;
       
   238 						}
       
   239 						if (sy >= h)
       
   240 							return false;
       
   241 					}
       
   242 				}
       
   243 
       
   244 				s->x = (Float)sx/h - (Float)w/h/2.0;
       
   245 				s->y = (Float)sy/h - 0.5;
       
   246 				osa_samp = 0;
       
   247 			}
       
   248 		}
       
   249 
       
   250 		if (osa_samp == 0 && oversample && oversample <= 3)
       
   251 		{
       
   252 			s->x += osax[0]/h;
       
   253 			s->y += osay[0]/h;
       
   254 			Float *buf = buffer + 3*(sy*w + sx);
       
   255 			*(buf++) = 0;
       
   256 			*(buf++) = 0;
       
   257 			*(buf++) = 0;
       
   258 		}
   128 	}
   259 	}
   129 
   260 
   130 	s->sx = sx;
   261 	s->sx = sx;
   131 	s->sy = sy;
   262 	s->sy = sy;
   132 	s->osa_samp = osa_samp;
   263 	s->osa_samp = osa_samp;
   135 }
   266 }
   136 
   267 
   137 void DefaultSampler::saveSample(Sample &samp, Colour &col)
   268 void DefaultSampler::saveSample(Sample &samp, Colour &col)
   138 {
   269 {
   139 	Float *buf = buffer + 3*(samp.sy * w + samp.sx);
   270 	Float *buf = buffer + 3*(samp.sy * w + samp.sx);
   140 	if (oversample)
   271 	if (phase == 2 && oversample)
   141 	{
   272 	{
   142 		*(buf+0) += col.r;
   273 		*(buf+0) += col.r;
   143 		*(buf+1) += col.g;
   274 		*(buf+1) += col.g;
   144 		*(buf+2) += col.b;
   275 		*(buf+2) += col.b;
   145 	}
   276 	}