Example #1
0
File: io.cs Project: soywiz/nwebp
		//------------------------------------------------------------------------------
		// RGBA rescaling

		// import new contributions until one row is ready to be output, or all input
		// is consumed.
		static int Import(byte* src, int src_stride,
						  int new_lines, WebPRescaler* wrk) {
		  int num_lines_in = 0;
		  while (num_lines_in < new_lines && wrk.y_accum > 0) {
			ImportRow(src, wrk);
			src += src_stride;
			++num_lines_in;
			wrk.y_accum -= wrk.y_sub;
		  }
		  return num_lines_in;
		}
Example #2
0
File: io.cs Project: soywiz/nwebp
		//------------------------------------------------------------------------------
		// YUV rescaling (no final RGB conversion needed)

		static int Rescale(byte* src, int src_stride,
						   int new_lines, WebPRescaler* wrk) {
		  int num_lines_out = 0;
		  while (new_lines-- > 0) {    // import new contribution of one source row.
			ImportRow(src, wrk);
			src += src_stride;
			wrk.y_accum -= wrk.y_sub;
			while (wrk.y_accum <= 0) {      // emit output row(s)
			  ExportRow(wrk);
			  ++num_lines_out;
			}
		  }
		  return num_lines_out;
		}
Example #3
0
File: io.cs Project: soywiz/nwebp
		static void ImportRow(byte* src,
										  WebPRescaler* wrk) {
		  int x_in = 0;
		  int x_out;
		  int accum = 0;
		  if (!wrk.x_expand) {
			int sum = 0;
			for (x_out = 0; x_out < wrk.dst_width; ++x_out) {
			  accum += wrk.x_add;
			  for (; accum > 0; accum -= wrk.x_sub) {
				sum += src[x_in++];
			  }
			  {        // Emit next horizontal pixel.
				int base = src[x_in++];
				int frac = base * (-accum);
				wrk.frow[x_out] = (sum + base) * wrk.x_sub - frac;
				// fresh fractional start for next pixel
				sum = MULT(frac, wrk.fx_scale);
			  }
			}
		  } else {        // simple bilinear interpolation
			int left = src[0], right = src[0];
			for (x_out = 0; x_out < wrk.dst_width; ++x_out) {
			  if (accum < 0) {
				left = right;
				right = src[++x_in];
				accum += wrk.x_add;
			  }
			  wrk.frow[x_out] = right * wrk.x_add + (left - right) * accum;
			  accum -= wrk.x_sub;
			}
		  }
		  // Accumulate the new row's contribution
		  for (x_out = 0; x_out < wrk.dst_width; ++x_out) {
			wrk.irow[x_out] += wrk.frow[x_out];
		  }
		}
Example #4
0
File: io.cs Project: soywiz/nwebp
		static void ExportRow(WebPRescaler* wrk) {
		  int x_out;
		  int yscale = wrk.fy_scale * (-wrk.y_accum);
		  assert(wrk.y_accum <= 0);
		  for (x_out = 0; x_out < wrk.dst_width; ++x_out) {
			int frac = MULT(wrk.frow[x_out], yscale);
			int v = (int)MULT(wrk.irow[x_out] - frac, wrk.fxy_scale);
			wrk.dst[x_out] = (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
			wrk.irow[x_out] = frac;   // new fractional start
		  }
		  wrk.y_accum += wrk.y_add;
		  wrk.dst += wrk.dst_stride;
		}
Example #5
0
File: io.cs Project: soywiz/nwebp
		static void InitRescaler(WebPRescaler* wrk,
								 int src_width, int src_height,
								 byte* dst,
								 int dst_width, int dst_height, int dst_stride,
								 int x_add, int x_sub, int y_add, int y_sub,
								 int* work) {
		  wrk.x_expand = (src_width < dst_width);
		  wrk.src_width = src_width;
		  wrk.src_height = src_height;
		  wrk.dst_width = dst_width;
		  wrk.dst_height = dst_height;
		  wrk.dst = dst;
		  wrk.dst_stride = dst_stride;
		  // for 'x_expand', we use bilinear interpolation
		  wrk.x_add = wrk.x_expand ? (x_sub - 1) : x_add - x_sub;
		  wrk.x_sub = wrk.x_expand ? (x_add - 1) : x_sub;
		  wrk.y_accum = y_add;
		  wrk.y_add = y_add;
		  wrk.y_sub = y_sub;
		  wrk.fx_scale = (1 << RFIX) / x_sub;
		  wrk.fy_scale = (1 << RFIX) / y_sub;
		  wrk.fxy_scale = wrk.x_expand ?
			  ((long)dst_height << RFIX) / (x_sub * src_height) :
			  ((long)dst_height << RFIX) / (x_add * src_height);
		  wrk.irow = work;
		  wrk.frow = work + dst_width;
		}