⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yuvscaler.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }  // END OF RESAMPLE RESAMPLE RESAMPLE              // BICUBIC BICUBIC BICUBIC    if (algorithm == 1)    {                    // SPECIFIC      // Is a specific downscaling speed enhanced treatment available?              // We only downscale on height, not width.       // Ex: 16/9 to 4/3 conversion      if ((output_width_slice == 1) && (input_width_slice == 1))	specific = 5;       // We only downscale on width, not height       // Ex: Full size to SVCD       if ((output_height_slice == 1) && (input_height_slice == 1))	specific = 1;       if (specific)	 mjpeg_info ("Specific downscaling routing number %u", specific);       //       specific=0;       // Let us tabulate several values which are explained below:       //        // Given the scaling factor "height_scale" on height and "width_scale" on width, to an output pixel of coordinates (out_col,out_line)       // corresponds an input pixel of coordinates (in_col,in_line), where in_col = out_col/width_scale and in_line = out_line/height_scale.       // As pixel coordinates are integer values, we take for in_col and out_col the nearest smaller integer       // value: in_col = floor(out_col/width_scale) and in_line = floor(out_line/height_scale).       // The input pixel of coordinates (in_col,in_line) is called the base input pixel       // Thus, we make an error conventionnally named "b" for columns and "a" for lines       // with b = out_col/width_scale - floor(out_col/width_scale) and a = out_line/height_scale - floor(out_line/height_scale).        // Please note that a and b are inside range [0,1[.        //        // For upscaling along w (resp. h), we need to take into account the 4 nearest neighbors along w (resp. h) of the base input pixel.       // For downscaling along w (resp. h), we need to take into account AT LEAST 6 nearest neighbors of the base input p顇el.        // And the real number of neighbors pixel from the base input pixel to be taken into account depends on the scaling ratios.        // We have to take into account "width_neighbors" neighbors on the width and "height_neighbors" on the height;        // with width_neighbors = 2*nearest_higher_integer(2/width_scale),  or 4 if upscaling (output_width_slice>input_width_slice)       // and width_offset=(width_neighbors/2)-1;       // with height_neighbors = 2*nearest_higher_integer(2/height_scale), or 4 if upscaling (output_height_slice>input_height_slice)       // and height_offset=(height_neighbors/2)-1;       //        // *****************       // The general formula giving the value of the output pixel as a function of the input pixels is:       // OutputPixel(out_col,out_line)=       // Sum(h=-height_offset,...(height_neigbors-height_offset-1))Sum(w=-width_offset,...(width_neigbors-width_offset-1))       // InputPixel(in_col+w,in_line+h)*BicubicCoefficient((b-w)*scale_width)*BicubicCoefficient((a-h)*scale_height)*scale_height*scale_width       // *****************       // Please note that [theoretically] (a-h)*scale_height is [-2:2], as well as (b-w)*scale_width.        // But, as height_neigbors is the nearest higher integer, the practical range for "(a-h)*scale_height" and "(b-w)*scale_width" is       // extended from theorital [-2:2] to [-3:3] => "(a-h)*scale_height" and "(b-w)*scale_width" are considered 0 outside of [-2:2].       // Please note also that for upscaling only, scale_height and scale_width are artifially taken as 1.0 in the formula.       //        // For an easier implementation, it is preferable that h and w start from 0. Therefore, in the general formula, we will replace       // "h" by "h-height_offset" and "w" by "w-width_offset".       //        // Moreover, the output pixel value depends on at least the 4x4 nearest neighbors from the base input pixel in the input image.        // As a consequence, if the base input pixel is at on the border of the image, the bicubic algorithm will try to find values       // outside the input image => to avoid this, we will pad the input image height_offset pixel on the top, width_offset pixels on the left,       // (and right_offset pixels on the right and bottom_offset pixels at the bottom).        // Therefore, in the general formula, we will replace InputPixel(x,y) by PaddedInputPixel(x+width_offset,y+height_offset).       //        // *****************       // Finally, the general formula may be rewritten as:       // OutputPixel(out_col,out_line)=       // Sum(h=0,...(height_neigbors-1))Sum(w=0...(width_neigbors-1))       // PaddedInputPixel(in_col+w,in_line+h)*BicubicCoefficient((b-w+width_offset)*scale_width)*BicubicCoefficient((a-h+height_offset)*scale_height)*scale_height*scale_width       // *****************       //        //        // *****************       // IMPLEMENTATION       // *****************       // To insure a fast implementation of the general formula, we will pre-calculate all possible values of        // BicubicCoefficient((b-w+width_offset)*scale_width)*scale_width, and tabulate them as cspline_w:       // cspline_w[w,out_col]=BicubicCoefficient((b[out_col]-w+width_offset)*scale_width)*scale_width.        // And the same stands for height:       // cspline_h[h,out_line]=BicubicCoefficient((a[out_line]-h+height_offset)*scale_height)*scale_height       //        // To be continued ...             height_scale=(float)output_height_slice/(float)input_height_slice;       if (height_scale>1.0)	 height_scale=1.0;              width_scale=(float)output_width_slice/(float)input_width_slice;       if (width_scale>1.0)	 width_scale=1.0;       width_neighbors = (2 * input_width_slice ) / output_width_slice;        if (((2 * input_width_slice ) % output_width_slice)!=0)	 width_neighbors++;       width_neighbors*=2;       if (width_neighbors < 4)	 width_neighbors = 4;       width_offset = left_offset = width_neighbors/2-1;       width_pad=width_neighbors - 1;       right_offset=width_neighbors/2;       height_neighbors = (2 * input_height_slice ) / output_height_slice;        if (((2 * input_height_slice ) % output_height_slice)!=0)	 height_neighbors++;       height_neighbors*=2;       if (height_neighbors < 4)	 height_neighbors = 4;       height_offset = top_offset = height_neighbors/2-1;       height_pad=height_neighbors - 1;       bottom_offset=height_neighbors/2;       mjpeg_debug("height_scale=%f, width_scale=%f, width_neighbors=%d, height_neighbors=%d",height_scale,width_scale,width_neighbors,height_neighbors);      // Memory allocations       #ifdef HAVE_ASM_MMX      if (!(mmx_res =	       (int32_t *) malloc (2 * sizeof (int32_t) + ALIGNEMENT)))	mjpeg_error_exit1	  ("Could not allocate memory for mmx registers. STOP!");      // alignement instructions      if (((unsigned long int) mmx_res % ALIGNEMENT) != 0)	mmx_res =	  (int32_t *) ((((unsigned long int) mmx_res / ALIGNEMENT) + 1) *		       ALIGNEMENT);              if (mmx==1)	 {	    if (width_neighbors <= MAXWIDTHNEIGHBORS)	      {		 mjpeg_info("MMX accelerated treatment activated");		 mmx = 1;	      }	    else 	      {		 mmx=0;		 mjpeg_warn("MMX accelerated treatment not available for downscaling ratio larger than 4 to 1");		 mjpeg_warn("If you still want to use an MMX treatment (not really useful for such a large downscaling ratio");		 mjpeg_warn("please use multiple yuvscaler downscaling to achieve the desired downscaling ratio");	      }	 }#endif// Il faudrait peut-阾re aligner correctement tous ces pointeurs, en particulier cspline_w_neighbors et cspline_h_neighbors// qui sont amplement utilis閟 dans les routines de scaling => il faut aussi aligner cspline_w et cspline_h      if (	  !(cspline_w =            (int16_t *) malloc ( width_neighbors  * output_active_width  * sizeof (int16_t))) ||	  !(cspline_h =            (int16_t *) malloc ( height_neighbors * output_active_height * sizeof (int16_t))) ||	  !(in_col =          (unsigned int *) malloc ( output_active_width  * sizeof (unsigned int))) ||	  !(b =                      (float *) malloc ( output_active_width  * sizeof (float))) ||	  !(in_line =         (unsigned int *) malloc ( output_active_height * sizeof (unsigned int))) ||	  !(a =                      (float *) malloc ( output_active_height * sizeof (float)))	  )	mjpeg_error_exit1	  ("Could not allocate memory for bicubic tables. STOP!");       // Initialisation of bicubic tables       pointer=cspline_h;       for (out_line = 0; out_line < output_active_height; out_line++)	 {	    in_line[out_line] = (out_line * input_height_slice) / output_height_slice;	    //	    mjpeg_debug("in_line[%u]=%u",out_line,in_line[out_line]);	    a[out_line] = 	      (float) ((out_line * input_height_slice) % output_height_slice) /	      (float) output_height_slice;	    somme=0;	    for (h=0;h<height_neighbors;h++)	      {		 cspline_value=cubic_spline ((a[out_line] + height_offset -h)*height_scale, bicubic_div_height)*height_scale;		 mjpeg_debug("cspline_value=%d,cspline=%d,a[%u]=%g,height_offset=%d,height_scale=%g,h=%lu",cspline_value,cubic_spline ((a[out_line] + height_offset -h)*height_scale, bicubic_div_height),out_line,a[out_line],height_offset,height_scale,h);		 somme+=cspline_value;		 *(pointer++)=cspline_value;	      }	    if (cspline_value!=0)	      zero_height_neighbors=0;	    // Normalisation test and normalisation of cspline 	    if (somme != bicubic_div_height) 	      *(pointer-2) += bicubic_div_height-somme; 	 }              pointer=cspline_w;       for (out_col = 0; out_col < output_active_width; out_col++)	 {	    in_col[out_col] = (out_col * input_width_slice) / output_width_slice;	    b[out_col] = 	      (float) ((out_col * input_width_slice) % output_width_slice) /	      (float) output_width_slice;	    somme=0;	    for (w=0;w<width_neighbors;w++)	      {//		 mjpeg_debug("b[%u]=%g,width_offset=%d,width_scale=%g,w=%lu",out_col,b[out_col],width_offset,width_scale,w);		 cspline_value=cubic_spline ((b[out_col] + width_offset -w)*width_scale, bicubic_div_width)*width_scale;		 mjpeg_debug("cspline_value=%d,b[%u]=%g,height_offset=%d,height_scale=%g,w=%lu",cspline_value,out_col,b[out_col],height_offset,height_scale,w);		 somme+=cspline_value;		 *(pointer++)=cspline_value;	      }	    if (cspline_value!=0)	      zero_width_neighbors=0;	    // Normalisation test and normalisation of cspline 	    if (somme != bicubic_div_width) 	      *(pointer-2) += bicubic_div_width-somme; 	 }       // Added +2*ALIGNEMENT for MMX scaling routines that loads a higher number of pixels than necessary (memory overflow)       if (interlaced == Y4M_ILACE_NONE)	{	  if (!(padded_input =		(uint8_t *) malloc ((input_useful_width + width_neighbors) *				    (input_useful_height + height_neighbors)+2*ALIGNEMENT)))	    mjpeg_error_exit1	      ("Could not allocate memory for padded_input table. STOP!");	}      else	{	  if (!(padded_top =		(uint8_t *) malloc ((input_useful_width + width_neighbors) *				    (input_useful_height / 2 + height_neighbors)+2*ALIGNEMENT)) ||	      !(padded_bottom =		(uint8_t *) malloc ((input_useful_width + width_neighbors) *				    (input_useful_height / 2 + height_neighbors)+2*ALIGNEMENT)))	    mjpeg_error_exit1	      ("Could not allocate memory for padded_top|bottom tables. STOP!");	}       if (!(intermediate = (int32_t *) malloc(output_active_width*(input_useful_height + height_neighbors)*sizeof(int32_t)))) 	     mjpeg_error_exit1	     ("Could not allocate memory for intermediate. STOP!");           }      // END OF BICUBIC BICUBIC BICUBIC       // Pointers allocations  if (!(input = malloc (((input_width * input_height * 3) / 2) + ALIGNEMENT)) ||      !(output = malloc (((output_width * output_height * 3) / 2) + ALIGNEMENT))      )    mjpeg_error_exit1      ("Could not allocate memory for input or output tables. STOP!");  // input and output pointers alignement  mjpeg_debug ("before alignement: input=%p output=%p", input, output);  if (((unsigned long) input % ALIGNEMENT) != 0)    input =      (uint8_t *) ((((unsigned long) input / ALIGNEMENT) + 1) * ALIGNEMENT);  if (((unsigned long) output % ALIGNEMENT) != 0)    output =      (uint8_t *) ((((unsigned long) output / ALIGNEMENT) + 1) * ALIGNEMENT);  mjpeg_debug ("after alignement: input=%p output=%p", input, output);  // if skip_col==1  if (!(frame_y_p = (uint8_t **) malloc (display_height * sizeof (uint8_t *)))      || !(frame_u_p =	   (uint8_t **) malloc (display_height / 2 * sizeof (uint8_t *)))      || !(frame_v_p =	   (uint8_t **) malloc (display_height / 2 * sizeof (uint8_t *))))    mjpeg_error_exit1      ("Could not allocate memory for frame_y_p, frame_u_p or frame_v_p tables. STOP!");  // Incorporate blacks lines and columns directly into output matrix since this will never change.   // BLACK pixel in YUV = (16,128,128)  if (black == 1)    {      u_c_p = output;      // Y component      for (i = 0; i < output_black_line_above * output_width; i++)	*(u_c_p++) = blacky;      if (black_col == 0)	u_c_p += output_active_height * output_width;      else	{	  for (i = 0; i < output_active_height; i++)	    {	      for (j = 0; j < output_black_col_left; j++)		*(u_c_p++) = blacky;	      u_c_p += output_active_width;	      for (j = 0; j < output_black_col_right; j++)		*(u_c_p++) = blacky;	    }	}      for (i = 0; i < output_black_line_under * output_width; i++)	*(u_c_p++) = blacky;      // U component      //   u_c_p=output+output_width*output_height;      for (i = 0; i < output_black_line_above / 2 * output_width / 2; i++)	*(u_c_p++) = blackuv;      if (black_col == 0)	u_c_p += output_active_height / 2 * output_width / 2;      else	{	  for (i = 0; i < output_active_height / 2; i++)	    {	      for (j = 0; j < output_black_col_left / 2; j++)		*(u_c_p++) = blackuv;	      u_c_p += output_active_width / 2;	      for (j = 0; j < output_black_col_right / 2; j++)		*(u_c_p++) = blackuv;	    }	}      for (i = 0; i < output_black_line_under / 2 * output_width / 2; i++)	*(u_c_p++) = blackuv;      // V component      //   u_c_p=output+(output_width*output_height*5)/4;      for (i = 0; i < output_black_line_above / 2 * output_width / 2; i++)	*(u_c_p++) = blackuv;      if (black_col == 0)	u_c_p += output_active_height / 2 * output_width / 2;      else	{	  for (i = 0; i < output_active_height / 2; i++)	    {	      for (j = 0; j < output_black_col_left / 2; j++)		*(u_c_p++) = blackuv;	      u_c_p += output_active_width / 2;	      for (j = 0; j < output_black_col_right / 2; j++)		*(u_c_p++) = blackuv;	    }	}      for (i = 0; i < output_black_line_under / 2 * output_width / 2; i++)	*(u_c_p++) = blackuv;    }  // MONOCHROME FRAMES  if (mono == 1)    {      // the U and V components of output frame will always be 128      u_c_p = output + output_width * output_height;      for (i = 0; i < 2 * output_width / 2 * output_height / 2; i++)	*(u_c_p++) = blackuv;    }  // Various initialisatiosn for variables concerning input and output     out_nb_col_slice = output_active_width / output_width_slice;  out_nb_line_slice = output_active_height / output_height_slice;  input_y =    input + input_discard_line_above * input_width + input_discard_col_left;  input_u =    input + input_width * input_height +    input_discard_line_above / 2 * input_width / 2 +    input_discard_col_left / 2;  input_v =    input + (input_height * input_width * 5) / 4 +    input_discard_line_above / 2 * input_width / 2 +    input_discard_col_left / 2;  output_y =    output + output_black_line_above * output_width + output_black_col_left;  output_u =    output + output_width * output_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -