src/3rdparty/libjpeg/jcsample.c
changeset 30 5dc02b23752f
parent 0 1918ee327afb
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    60 typedef struct {
    60 typedef struct {
    61   struct jpeg_downsampler pub;	/* public fields */
    61   struct jpeg_downsampler pub;	/* public fields */
    62 
    62 
    63   /* Downsampling method pointers, one per component */
    63   /* Downsampling method pointers, one per component */
    64   downsample1_ptr methods[MAX_COMPONENTS];
    64   downsample1_ptr methods[MAX_COMPONENTS];
       
    65 
       
    66   /* Height of an output row group for each component. */
       
    67   int rowgroup_height[MAX_COMPONENTS];
       
    68 
       
    69   /* These arrays save pixel expansion factors so that int_downsample need not
       
    70    * recompute them each time.  They are unused for other downsampling methods.
       
    71    */
       
    72   UINT8 h_expand[MAX_COMPONENTS];
       
    73   UINT8 v_expand[MAX_COMPONENTS];
    65 } my_downsampler;
    74 } my_downsampler;
    66 
    75 
    67 typedef my_downsampler * my_downsample_ptr;
    76 typedef my_downsampler * my_downsample_ptr;
    68 
    77 
    69 
    78 
   121   JSAMPARRAY in_ptr, out_ptr;
   130   JSAMPARRAY in_ptr, out_ptr;
   122 
   131 
   123   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
   132   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
   124        ci++, compptr++) {
   133        ci++, compptr++) {
   125     in_ptr = input_buf[ci] + in_row_index;
   134     in_ptr = input_buf[ci] + in_row_index;
   126     out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
   135     out_ptr = output_buf[ci] +
       
   136 	      (out_row_group_index * downsample->rowgroup_height[ci]);
   127     (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
   137     (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
   128   }
   138   }
   129 }
   139 }
   130 
   140 
   131 
   141 
   138 
   148 
   139 METHODDEF(void)
   149 METHODDEF(void)
   140 int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   150 int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   141 		JSAMPARRAY input_data, JSAMPARRAY output_data)
   151 		JSAMPARRAY input_data, JSAMPARRAY output_data)
   142 {
   152 {
       
   153   my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
   143   int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
   154   int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
   144   JDIMENSION outcol, outcol_h;	/* outcol_h == outcol*h_expand */
   155   JDIMENSION outcol, outcol_h;	/* outcol_h == outcol*h_expand */
   145   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
   156   JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
   146   JSAMPROW inptr, outptr;
   157   JSAMPROW inptr, outptr;
   147   INT32 outvalue;
   158   INT32 outvalue;
   148 
   159 
   149   h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
   160   h_expand = downsample->h_expand[compptr->component_index];
   150   v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
   161   v_expand = downsample->v_expand[compptr->component_index];
   151   numpix = h_expand * v_expand;
   162   numpix = h_expand * v_expand;
   152   numpix2 = numpix/2;
   163   numpix2 = numpix/2;
   153 
   164 
   154   /* Expand input data enough to let all the output samples be generated
   165   /* Expand input data enough to let all the output samples be generated
   155    * by the standard loop.  Special-casing padded output would be more
   166    * by the standard loop.  Special-casing padded output would be more
   156    * efficient.
   167    * efficient.
   157    */
   168    */
   158   expand_right_edge(input_data, cinfo->max_v_samp_factor,
   169   expand_right_edge(input_data, cinfo->max_v_samp_factor,
   159 		    cinfo->image_width, output_cols * h_expand);
   170 		    cinfo->image_width, output_cols * h_expand);
   160 
   171 
   161   inrow = 0;
   172   inrow = outrow = 0;
   162   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
   173   while (inrow < cinfo->max_v_samp_factor) {
   163     outptr = output_data[outrow];
   174     outptr = output_data[outrow];
   164     for (outcol = 0, outcol_h = 0; outcol < output_cols;
   175     for (outcol = 0, outcol_h = 0; outcol < output_cols;
   165 	 outcol++, outcol_h += h_expand) {
   176 	 outcol++, outcol_h += h_expand) {
   166       outvalue = 0;
   177       outvalue = 0;
   167       for (v = 0; v < v_expand; v++) {
   178       for (v = 0; v < v_expand; v++) {
   171 	}
   182 	}
   172       }
   183       }
   173       *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
   184       *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
   174     }
   185     }
   175     inrow += v_expand;
   186     inrow += v_expand;
       
   187     outrow++;
   176   }
   188   }
   177 }
   189 }
   178 
   190 
   179 
   191 
   180 /*
   192 /*
   189 {
   201 {
   190   /* Copy the data */
   202   /* Copy the data */
   191   jcopy_sample_rows(input_data, 0, output_data, 0,
   203   jcopy_sample_rows(input_data, 0, output_data, 0,
   192 		    cinfo->max_v_samp_factor, cinfo->image_width);
   204 		    cinfo->max_v_samp_factor, cinfo->image_width);
   193   /* Edge-expand */
   205   /* Edge-expand */
   194   expand_right_edge(output_data, cinfo->max_v_samp_factor,
   206   expand_right_edge(output_data, cinfo->max_v_samp_factor, cinfo->image_width,
   195 		    cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
   207 		    compptr->width_in_blocks * compptr->DCT_h_scaled_size);
   196 }
   208 }
   197 
   209 
   198 
   210 
   199 /*
   211 /*
   200  * Downsample pixel values of a single component.
   212  * Downsample pixel values of a single component.
   210 
   222 
   211 METHODDEF(void)
   223 METHODDEF(void)
   212 h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   224 h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   213 		 JSAMPARRAY input_data, JSAMPARRAY output_data)
   225 		 JSAMPARRAY input_data, JSAMPARRAY output_data)
   214 {
   226 {
   215   int outrow;
   227   int inrow;
   216   JDIMENSION outcol;
   228   JDIMENSION outcol;
   217   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
   229   JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
   218   register JSAMPROW inptr, outptr;
   230   register JSAMPROW inptr, outptr;
   219   register int bias;
   231   register int bias;
   220 
   232 
   221   /* Expand input data enough to let all the output samples be generated
   233   /* Expand input data enough to let all the output samples be generated
   222    * by the standard loop.  Special-casing padded output would be more
   234    * by the standard loop.  Special-casing padded output would be more
   223    * efficient.
   235    * efficient.
   224    */
   236    */
   225   expand_right_edge(input_data, cinfo->max_v_samp_factor,
   237   expand_right_edge(input_data, cinfo->max_v_samp_factor,
   226 		    cinfo->image_width, output_cols * 2);
   238 		    cinfo->image_width, output_cols * 2);
   227 
   239 
   228   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
   240   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
   229     outptr = output_data[outrow];
   241     outptr = output_data[inrow];
   230     inptr = input_data[outrow];
   242     inptr = input_data[inrow];
   231     bias = 0;			/* bias = 0,1,0,1,... for successive samples */
   243     bias = 0;			/* bias = 0,1,0,1,... for successive samples */
   232     for (outcol = 0; outcol < output_cols; outcol++) {
   244     for (outcol = 0; outcol < output_cols; outcol++) {
   233       *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
   245       *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
   234 			      + bias) >> 1);
   246 			      + bias) >> 1);
   235       bias ^= 1;		/* 0=>1, 1=>0 */
   247       bias ^= 1;		/* 0=>1, 1=>0 */
   249 h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   261 h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   250 		 JSAMPARRAY input_data, JSAMPARRAY output_data)
   262 		 JSAMPARRAY input_data, JSAMPARRAY output_data)
   251 {
   263 {
   252   int inrow, outrow;
   264   int inrow, outrow;
   253   JDIMENSION outcol;
   265   JDIMENSION outcol;
   254   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
   266   JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
   255   register JSAMPROW inptr0, inptr1, outptr;
   267   register JSAMPROW inptr0, inptr1, outptr;
   256   register int bias;
   268   register int bias;
   257 
   269 
   258   /* Expand input data enough to let all the output samples be generated
   270   /* Expand input data enough to let all the output samples be generated
   259    * by the standard loop.  Special-casing padded output would be more
   271    * by the standard loop.  Special-casing padded output would be more
   260    * efficient.
   272    * efficient.
   261    */
   273    */
   262   expand_right_edge(input_data, cinfo->max_v_samp_factor,
   274   expand_right_edge(input_data, cinfo->max_v_samp_factor,
   263 		    cinfo->image_width, output_cols * 2);
   275 		    cinfo->image_width, output_cols * 2);
   264 
   276 
   265   inrow = 0;
   277   inrow = outrow = 0;
   266   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
   278   while (inrow < cinfo->max_v_samp_factor) {
   267     outptr = output_data[outrow];
   279     outptr = output_data[outrow];
   268     inptr0 = input_data[inrow];
   280     inptr0 = input_data[inrow];
   269     inptr1 = input_data[inrow+1];
   281     inptr1 = input_data[inrow+1];
   270     bias = 1;			/* bias = 1,2,1,2,... for successive samples */
   282     bias = 1;			/* bias = 1,2,1,2,... for successive samples */
   271     for (outcol = 0; outcol < output_cols; outcol++) {
   283     for (outcol = 0; outcol < output_cols; outcol++) {
   274 			      + bias) >> 2);
   286 			      + bias) >> 2);
   275       bias ^= 3;		/* 1=>2, 2=>1 */
   287       bias ^= 3;		/* 1=>2, 2=>1 */
   276       inptr0 += 2; inptr1 += 2;
   288       inptr0 += 2; inptr1 += 2;
   277     }
   289     }
   278     inrow += 2;
   290     inrow += 2;
       
   291     outrow++;
   279   }
   292   }
   280 }
   293 }
   281 
   294 
   282 
   295 
   283 #ifdef INPUT_SMOOTHING_SUPPORTED
   296 #ifdef INPUT_SMOOTHING_SUPPORTED
   292 h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   305 h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
   293 			JSAMPARRAY input_data, JSAMPARRAY output_data)
   306 			JSAMPARRAY input_data, JSAMPARRAY output_data)
   294 {
   307 {
   295   int inrow, outrow;
   308   int inrow, outrow;
   296   JDIMENSION colctr;
   309   JDIMENSION colctr;
   297   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
   310   JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
   298   register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
   311   register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
   299   INT32 membersum, neighsum, memberscale, neighscale;
   312   INT32 membersum, neighsum, memberscale, neighscale;
   300 
   313 
   301   /* Expand input data enough to let all the output samples be generated
   314   /* Expand input data enough to let all the output samples be generated
   302    * by the standard loop.  Special-casing padded output would be more
   315    * by the standard loop.  Special-casing padded output would be more
   319    */
   332    */
   320 
   333 
   321   memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
   334   memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
   322   neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
   335   neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
   323 
   336 
   324   inrow = 0;
   337   inrow = outrow = 0;
   325   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
   338   while (inrow < cinfo->max_v_samp_factor) {
   326     outptr = output_data[outrow];
   339     outptr = output_data[outrow];
   327     inptr0 = input_data[inrow];
   340     inptr0 = input_data[inrow];
   328     inptr1 = input_data[inrow+1];
   341     inptr1 = input_data[inrow+1];
   329     above_ptr = input_data[inrow-1];
   342     above_ptr = input_data[inrow-1];
   330     below_ptr = input_data[inrow+2];
   343     below_ptr = input_data[inrow+2];
   376 		GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
   389 		GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
   377     membersum = membersum * memberscale + neighsum * neighscale;
   390     membersum = membersum * memberscale + neighsum * neighscale;
   378     *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
   391     *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
   379 
   392 
   380     inrow += 2;
   393     inrow += 2;
       
   394     outrow++;
   381   }
   395   }
   382 }
   396 }
   383 
   397 
   384 
   398 
   385 /*
   399 /*
   390 
   404 
   391 METHODDEF(void)
   405 METHODDEF(void)
   392 fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
   406 fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
   393 			    JSAMPARRAY input_data, JSAMPARRAY output_data)
   407 			    JSAMPARRAY input_data, JSAMPARRAY output_data)
   394 {
   408 {
   395   int outrow;
   409   int inrow;
   396   JDIMENSION colctr;
   410   JDIMENSION colctr;
   397   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
   411   JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
   398   register JSAMPROW inptr, above_ptr, below_ptr, outptr;
   412   register JSAMPROW inptr, above_ptr, below_ptr, outptr;
   399   INT32 membersum, neighsum, memberscale, neighscale;
   413   INT32 membersum, neighsum, memberscale, neighscale;
   400   int colsum, lastcolsum, nextcolsum;
   414   int colsum, lastcolsum, nextcolsum;
   401 
   415 
   402   /* Expand input data enough to let all the output samples be generated
   416   /* Expand input data enough to let all the output samples be generated
   413    */
   427    */
   414 
   428 
   415   memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
   429   memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
   416   neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
   430   neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
   417 
   431 
   418   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
   432   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
   419     outptr = output_data[outrow];
   433     outptr = output_data[inrow];
   420     inptr = input_data[outrow];
   434     inptr = input_data[inrow];
   421     above_ptr = input_data[outrow-1];
   435     above_ptr = input_data[inrow-1];
   422     below_ptr = input_data[outrow+1];
   436     below_ptr = input_data[inrow+1];
   423 
   437 
   424     /* Special case for first column */
   438     /* Special case for first column */
   425     colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
   439     colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
   426 	     GETJSAMPLE(*inptr);
   440 	     GETJSAMPLE(*inptr);
   427     membersum = GETJSAMPLE(*inptr++);
   441     membersum = GETJSAMPLE(*inptr++);
   465 {
   479 {
   466   my_downsample_ptr downsample;
   480   my_downsample_ptr downsample;
   467   int ci;
   481   int ci;
   468   jpeg_component_info * compptr;
   482   jpeg_component_info * compptr;
   469   boolean smoothok = TRUE;
   483   boolean smoothok = TRUE;
       
   484   int h_in_group, v_in_group, h_out_group, v_out_group;
   470 
   485 
   471   downsample = (my_downsample_ptr)
   486   downsample = (my_downsample_ptr)
   472     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
   487     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
   473 				SIZEOF(my_downsampler));
   488 				SIZEOF(my_downsampler));
   474   cinfo->downsample = (struct jpeg_downsampler *) downsample;
   489   cinfo->downsample = (struct jpeg_downsampler *) downsample;
   480     ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
   495     ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
   481 
   496 
   482   /* Verify we can handle the sampling factors, and set up method pointers */
   497   /* Verify we can handle the sampling factors, and set up method pointers */
   483   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
   498   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
   484        ci++, compptr++) {
   499        ci++, compptr++) {
   485     if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
   500     /* Compute size of an "output group" for DCT scaling.  This many samples
   486 	compptr->v_samp_factor == cinfo->max_v_samp_factor) {
   501      * are to be converted from max_h_samp_factor * max_v_samp_factor pixels.
       
   502      */
       
   503     h_out_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
       
   504 		  cinfo->min_DCT_h_scaled_size;
       
   505     v_out_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
       
   506 		  cinfo->min_DCT_v_scaled_size;
       
   507     h_in_group = cinfo->max_h_samp_factor;
       
   508     v_in_group = cinfo->max_v_samp_factor;
       
   509     downsample->rowgroup_height[ci] = v_out_group; /* save for use later */
       
   510     if (h_in_group == h_out_group && v_in_group == v_out_group) {
   487 #ifdef INPUT_SMOOTHING_SUPPORTED
   511 #ifdef INPUT_SMOOTHING_SUPPORTED
   488       if (cinfo->smoothing_factor) {
   512       if (cinfo->smoothing_factor) {
   489 	downsample->methods[ci] = fullsize_smooth_downsample;
   513 	downsample->methods[ci] = fullsize_smooth_downsample;
   490 	downsample->pub.need_context_rows = TRUE;
   514 	downsample->pub.need_context_rows = TRUE;
   491       } else
   515       } else
   492 #endif
   516 #endif
   493 	downsample->methods[ci] = fullsize_downsample;
   517 	downsample->methods[ci] = fullsize_downsample;
   494     } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
   518     } else if (h_in_group == h_out_group * 2 &&
   495 	       compptr->v_samp_factor == cinfo->max_v_samp_factor) {
   519 	       v_in_group == v_out_group) {
   496       smoothok = FALSE;
   520       smoothok = FALSE;
   497       downsample->methods[ci] = h2v1_downsample;
   521       downsample->methods[ci] = h2v1_downsample;
   498     } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
   522     } else if (h_in_group == h_out_group * 2 &&
   499 	       compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
   523 	       v_in_group == v_out_group * 2) {
   500 #ifdef INPUT_SMOOTHING_SUPPORTED
   524 #ifdef INPUT_SMOOTHING_SUPPORTED
   501       if (cinfo->smoothing_factor) {
   525       if (cinfo->smoothing_factor) {
   502 	downsample->methods[ci] = h2v2_smooth_downsample;
   526 	downsample->methods[ci] = h2v2_smooth_downsample;
   503 	downsample->pub.need_context_rows = TRUE;
   527 	downsample->pub.need_context_rows = TRUE;
   504       } else
   528       } else
   505 #endif
   529 #endif
   506 	downsample->methods[ci] = h2v2_downsample;
   530 	downsample->methods[ci] = h2v2_downsample;
   507     } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
   531     } else if ((h_in_group % h_out_group) == 0 &&
   508 	       (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
   532 	       (v_in_group % v_out_group) == 0) {
   509       smoothok = FALSE;
   533       smoothok = FALSE;
   510       downsample->methods[ci] = int_downsample;
   534       downsample->methods[ci] = int_downsample;
       
   535       downsample->h_expand[ci] = (UINT8) (h_in_group / h_out_group);
       
   536       downsample->v_expand[ci] = (UINT8) (v_in_group / v_out_group);
   511     } else
   537     } else
   512       ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
   538       ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
   513   }
   539   }
   514 
   540 
   515 #ifdef INPUT_SMOOTHING_SUPPORTED
   541 #ifdef INPUT_SMOOTHING_SUPPORTED