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

📄 yuvscaler_bicubic.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		output_p+=output_offset;		line_top+=local_padded_width;		// BOTTOM LINE		cspline_wp=cspline_w;		in_col_p=in_col;		for (out_col = 0; out_col < local_output_active_width; out_col++)		  {		     line = line_bot + *(in_col_p++);		     value1=*(line++)*(*(cspline_wp++));		     for (w=1;w<width_neighbors-1;w++) 		       value1+=*(line++)*(*(cspline_wp++));		     value1+=*(line)*(*(cspline_wp++));		     if (zero_width_neighbors)		       cspline_wp++;		     		     if (value1 < 0) *(output_p++) = 0;		     else {			value = (value1 + FLOAT2INTOFFSET) >> FLOAT2INTEGERPOWER;			if (value > 255) *(output_p++) = 255;			else *(output_p++) = (uint8_t) value;		     }		  }		// a bottom line on output is now finished. We jump to the beginning of the next top line		output_p+=output_offset;		line_bot+=local_padded_width;	     }	}      break;     case 5:      // We only scale on height, not width	{	   cspline_hp0=cspline_h;	   in_line_p=in_line;	   for (out_line = 0; out_line < (local_output_active_height>>1); out_line++)	     {		// TOP LINE		line_begin=padded_top + *(in_line_p) * local_padded_width;		for (out_col = 0; out_col < local_output_active_width; out_col++)		  {		     cspline_hp=cspline_hp0;		     value1 = *(line_begin)*(*(cspline_hp++));		     for (h=1;h<height_neighbors-1;h++)		       value1 += (*(line_begin+h*local_padded_width))*(*(cspline_hp++));		     value1 += (*((line_begin++)+h*local_padded_width))*(*(cspline_hp));		     if (value1 < 0) *(output_p++) = 0;		     else {			value = (value1 + FLOAT2INTOFFSET) >> FLOAT2INTEGERPOWER;			if (value > 255) *(output_p++) = 255;			else *(output_p++) = (uint8_t) value;		     }		  }		// a top line on output is now finished. We jump to the beginning of the next bottom line		output_p+=output_offset;				// BOTTTOM LINE		line_begin=padded_bottom + *(in_line_p++) * local_padded_width;		for (out_col = 0; out_col < local_output_active_width-1; out_col++)		  {		     cspline_hp=cspline_hp0;		     value1 = *(line_begin)*(*(cspline_hp++));		     for (h=1;h<height_neighbors-1;h++)		       value1 += (*(line_begin+h*local_padded_width))*(*(cspline_hp++));		     value1 += (*((line_begin++)+h*local_padded_width))*(*(cspline_hp));		     if (value1 < 0) *(output_p++) = 0;		     else {			value = (value1 + FLOAT2INTOFFSET) >> FLOAT2INTEGERPOWER;			if (value > 255) *(output_p++) = 255;			else *(output_p++) = (uint8_t) value;		     }		  }		// last out_col to be treated => cspline_hp0 incremented => we use the C "++" facility		value1 = *(line_begin)*(*(cspline_hp0++));		for (h=1;h<height_neighbors;h++)		  value1 += (*(line_begin+h*local_padded_width))*(*(cspline_hp0++));		if (zero_height_neighbors)		  cspline_hp0++;				if (value1 < 0) *(output_p++) = 0;		else {		   value = (value1 + FLOAT2INTOFFSET) >> FLOAT2INTEGERPOWER;		   if (value > 255) *(output_p++) = 255;		   else *(output_p++) = (uint8_t) value;		}		// a bottom line on output is now finished. We jump to the beginning of the next top line		output_p+=output_offset;	     }	}      break;   }   /* *INDENT-ON* */   //   mjpeg_debug ("End of cubic_scale");   return (0);   }// *************************************************************************************// // *************************************************************************************int16_tcubic_spline (float x, unsigned int multiplicative){  // Implementation of the Mitchell-Netravalli cubic spline, with recommended parameters B and C  // [after Reconstruction filters in Computer Graphics by P. Mitchel and N. Netravali : Computer Graphics, Volume 22, Number 4, pp 221-228]  // Normally, coefficiants are float, but they are transformed into integer with 1/FLOAT2INTEGER = 1/2"11 precision for speed reasons.  // Please note that these coefficient may over and under shoot in the sense that they may be <0.0 and >1.0  // Given out values of B and C, maximum value is (x=0) 8/9 and undeshoot is bigger than -0.04 (x#1.5)  const float B = 1.0 / 3.0;  const float C = 1.0 / 3.0;  if (fabs (x) < 1)    return ((int16_t)	    floor (0.5 +		   (((12.0 - 9.0 * B - 6.0 * C)  * fabs (x) * fabs (x) * fabs (x) 		  + (-18.0 + 12.0 * B + 6.0 * C) * fabs (x) * fabs (x) 		  + (6.0 - 2.0 * B)) / 6.0		    ) * multiplicative));  if (fabs (x) <= 2)    return ((int16_t)	    floor (0.5 +		   (((-B - 6.0 * C) * fabs (x) * fabs (x) * fabs (x) +		     (6.0 * B + 30.0 * C) * fabs (x) * fabs (x) +		     (-12.0 * B - 48.0 * C) * fabs (x) + (8.0 * B +							  24.0 * C)) /		    6.0) * multiplicative));  if (fabs (x) <= 3)     return (0);  mjpeg_info("In function cubic_spline: x=%f >3",x);  return (0);}// *************************************************************************************// *************************************************************************************intpadding (uint8_t * padded_input, uint8_t * input, unsigned int half, 	 uint16_t left_offset, uint16_t top_offset, uint16_t right_offset, uint16_t bottom_offset,	 uint16_t width_pad){  // In cubic interpolation, output pixel are evaluated from the 4*4 to 12*12 nearest neigbors.   // For border pixels, this requires that input datas along the edge to be padded.   // We choose to pad border pixel with black pixel, since border pixel along width are much of the time non-visible  // (TV set for example) and along the height they are either non-visible or black borders are displayed   // This padding functions requires output_interlaced==0  unsigned int local_input_useful_width = input_useful_width >> half;  unsigned int local_input_useful_height = input_useful_height >> half;  unsigned int local_padded_width = local_input_useful_width + width_pad;  unsigned int local_input_width = input_width >> half;  unsigned int line;  uint8_t black,*uint8_pad,*uint8_inp;  unsigned long int nb_top=top_offset*local_padded_width;  // mjpeg_debug ("Start of padding, left_offset=%d,top_offset=%d,right_offset=%d,bottom_offset=%d,width_pad=%d",//	       left_offset,top_offset,right_offset,bottom_offset,width_pad);  if (half)     black=128;  else     black=16;  // PADDING  // vertical offset of top_offset lines  // Black pixel on the left_offset left pixels  // Content Copy with left_offset pixels offset on the left and right_offset pixels of the right  // Black pixel on the right_offset right pixels  // vertical offset of the last bottom_offset lines    memset(padded_input,black,nb_top);  uint8_inp=input;  uint8_pad=padded_input+nb_top;  for (line = 0; line < local_input_useful_height; line++)      {	memset(uint8_pad,black,left_offset);	uint8_pad+=left_offset;	memcpy (uint8_pad, uint8_inp, local_input_useful_width);	uint8_pad+=local_input_useful_width;	uint8_inp+=local_input_width; // it is local_input_width, not local_input_useful_width, see yuvscaler_implementation.txt	memset(uint8_pad,black,right_offset);	uint8_pad+=right_offset;     }  memset(uint8_pad,black,bottom_offset*local_padded_width);  // mjpeg_debug ("End of padding");  return (0);}// *************************************************************************************// *************************************************************************************intpadding_interlaced (uint8_t * padded_top, uint8_t * padded_bottom, uint8_t * input, unsigned int half,		    uint16_t left_offset, uint16_t top_offset, uint16_t right_offset, uint16_t bottom_offset,		    uint16_t width_pad){  unsigned int local_input_useful_width = input_useful_width >> half;  unsigned int local_input_useful_height = input_useful_height >> half;  unsigned int local_padded_width = local_input_useful_width + width_pad;  unsigned int local_input_width = input_width >> half;  unsigned int line;  uint8_t black, * uint8_ptop, * uint8_pbot, * uint8_inp;  unsigned long int nb_top=top_offset*local_padded_width;  unsigned long int nb_bot=bottom_offset*local_padded_width;  // mjpeg_debug ("Start of padding_interlaced, left_offset=%d,top_offset=%d,right_offset=%d,bottom_offset=%d,width_pad=%d",//	       left_offset,top_offset,right_offset,bottom_offset,width_pad);  if (half)     black=128;  else     black=16;  // PADDING  // vertical offset of top_offset lines  // Black pixel on the left_offset left pixels  // Content Copy with left_offset pixels offset on the left and right_offset pixels of the right  // Black pixel on the right_offset right pixels  // vertical offset of the last bottom_offset lines    memset(padded_top,black,nb_top);  memset(padded_bottom,black,nb_top);  uint8_inp=input;  uint8_ptop=padded_top+nb_top;  uint8_pbot=padded_bottom+nb_top;  for (line = 0; line < (local_input_useful_height >> 1); line++)      {	memset(uint8_ptop,black,left_offset);	uint8_ptop+=left_offset;	memset(uint8_pbot,black,left_offset);	uint8_pbot+=left_offset;	memcpy (uint8_ptop, uint8_inp, local_input_useful_width);	uint8_ptop+=local_input_useful_width;	uint8_inp +=local_input_width; // it is local_input_width, not local_input_useful_width, see yuvscaler_implementation.txt	memcpy (uint8_pbot, uint8_inp, local_input_useful_width);	uint8_pbot+=local_input_useful_width;	uint8_inp +=local_input_width; // it is local_input_width, not local_input_useful_width, see yuvscaler_implementation.txt	memset(uint8_ptop,black,right_offset);	uint8_ptop+=right_offset;	memset(uint8_pbot,black,right_offset);	uint8_pbot+=right_offset;     }  memset(uint8_ptop,black,nb_bot);  memset(uint8_pbot,black,nb_bot);  // mjpeg_debug ("End of padding_interlaced");  return (0);}// *************************************************************************************				  // THE FOLLOWING LINE "if (!mmx) mmx=0;" DOES NO USEFUL CALCULATION BUT				  // it is necessary when gcc compilation with -O2 flag 				  // to calculate correct values for value1+=(mmx_res[0]+mmx_res[1])*(*csplineh[h]);				  // I know this sounds incredible, but believe me, it is true !				  // On the other hand, using only gcc -O1, this line is no more necessary.				  // And in both case, mmx_res[0],mmx_res[1] and *csplineh[h] have the same values				  // Indeed, the corresponding machine code is totally different with or without				  // this line with gcc -O2.				  // The line value1+=(mmx_res[0]+mmx_res[1])*(*csplineh[h]) is compiled into				  // (From DDD):				  // Right calculation, that is including the "if (!mmx) mmx=0;" line				  // --> 0x804f07f <cubic_scale+1615>:pmaddwd %mm0,%mm6				  // --> 0x804f082 <cubic_scale+1618>:movq   %mm6,(%ecx)				  //     0x804f085 <cubic_scale+1621>:mov    (%ecx),%edx				  //     0x804f087 <cubic_scale+1623>:mov    0x4(%ecx),%eax				  //     0x804f08a <cubic_scale+1626>:mov    0xffffffbc(%ebp),%ebx				  //     0x804f08d <cubic_scale+1629>:add    %edx,%eax				  //     0x804f08f <cubic_scale+1631>:mov    (%ebx,%edi,4),%edx				  // --> 0x804f092 <cubic_scale+1634>:inc    %edi				  // Wrong calculation, that is not including the "if (!mmx) mmx=0;" line				  // --> 0x804f062 <cubic_scale+1586>:pmaddwd %mm0,%mm6				  // --> 0x804f065 <cubic_scale+1589>:movq   %mm6,(%ecx)				  //     0x804f068 <cubic_scale+1592>:mov    0xffffffbc(%ebp),%ebx				  //     0x804f06b <cubic_scale+1595>:mov    (%ecx),%eax				  //     0x804f06d <cubic_scale+1597>:mov    (%ebx,%edi,4),%edx				  //     0x804f070 <cubic_scale+1600>:add    %esi,%eax				  // --> 0x804f072 <cubic_scale+1602>:inc    %edi				  //				  if (!mmx)//				    mmx=0;

⌨️ 快捷键说明

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