Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
jdsample.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define JPEG_INTERNALS
00022 #include "jinclude.h"
00023 #include "jpeglib.h"
00024
00025
00026
00027 typedef JMETHOD(void, upsample1_ptr,
00028 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00029 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
00030
00031
00032
00033 typedef struct {
00034 struct jpeg_upsampler pub;
00035
00036
00037
00038
00039
00040
00041
00042
00043 JSAMPARRAY color_buf[MAX_COMPONENTS];
00044
00045
00046 upsample1_ptr methods[MAX_COMPONENTS];
00047
00048 int next_row_out;
00049 JDIMENSION rows_to_go;
00050
00051
00052 int rowgroup_height[MAX_COMPONENTS];
00053
00054
00055
00056
00057 UINT8 h_expand[MAX_COMPONENTS];
00058 UINT8 v_expand[MAX_COMPONENTS];
00059 } my_upsampler;
00060
00061 typedef my_upsampler * my_upsample_ptr;
00062
00063
00064
00065
00066
00067
00068 METHODDEF(void)
00069 start_pass_upsample (j_decompress_ptr cinfo)
00070 {
00071 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00072
00073
00074 upsample->next_row_out = cinfo->max_v_samp_factor;
00075
00076 upsample->rows_to_go = cinfo->output_height;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 METHODDEF(void)
00089 sep_upsample (j_decompress_ptr cinfo,
00090 JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00091 JDIMENSION in_row_groups_avail,
00092 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00093 JDIMENSION out_rows_avail)
00094 {
00095 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00096 int ci;
00097 jpeg_component_info * compptr;
00098 JDIMENSION num_rows;
00099
00100
00101 if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
00102 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00103 ci++, compptr++) {
00104
00105
00106
00107 (*upsample->methods[ci]) (cinfo, compptr,
00108 input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
00109 upsample->color_buf + ci);
00110 }
00111 upsample->next_row_out = 0;
00112 }
00113
00114
00115
00116
00117 num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
00118
00119
00120
00121 if (num_rows > upsample->rows_to_go)
00122 num_rows = upsample->rows_to_go;
00123
00124 out_rows_avail -= *out_row_ctr;
00125 if (num_rows > out_rows_avail)
00126 num_rows = out_rows_avail;
00127
00128 (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
00129 (JDIMENSION) upsample->next_row_out,
00130 output_buf + *out_row_ctr,
00131 (int) num_rows);
00132
00133
00134 *out_row_ctr += num_rows;
00135 upsample->rows_to_go -= num_rows;
00136 upsample->next_row_out += num_rows;
00137
00138 if (upsample->next_row_out >= cinfo->max_v_samp_factor)
00139 (*in_row_group_ctr)++;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 METHODDEF(void)
00157 fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00158 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00159 {
00160 *output_data_ptr = input_data;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 METHODDEF(void)
00170 noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00171 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00172 {
00173 *output_data_ptr = NULL;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 METHODDEF(void)
00189 int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00190 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00191 {
00192 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00193 JSAMPARRAY output_data = *output_data_ptr;
00194 register JSAMPROW inptr, outptr;
00195 register JSAMPLE invalue;
00196 register int h;
00197 JSAMPROW outend;
00198 int h_expand, v_expand;
00199 int inrow, outrow;
00200
00201 h_expand = upsample->h_expand[compptr->component_index];
00202 v_expand = upsample->v_expand[compptr->component_index];
00203
00204 inrow = outrow = 0;
00205 while (outrow < cinfo->max_v_samp_factor) {
00206
00207 inptr = input_data[inrow];
00208 outptr = output_data[outrow];
00209 outend = outptr + cinfo->output_width;
00210 while (outptr < outend) {
00211 invalue = *inptr++;
00212 for (h = h_expand; h > 0; h--) {
00213 *outptr++ = invalue;
00214 }
00215 }
00216
00217 if (v_expand > 1) {
00218 jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
00219 v_expand-1, cinfo->output_width);
00220 }
00221 inrow++;
00222 outrow += v_expand;
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231
00232 METHODDEF(void)
00233 h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00234 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00235 {
00236 JSAMPARRAY output_data = *output_data_ptr;
00237 register JSAMPROW inptr, outptr;
00238 register JSAMPLE invalue;
00239 JSAMPROW outend;
00240 int inrow;
00241
00242 for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
00243 inptr = input_data[inrow];
00244 outptr = output_data[inrow];
00245 outend = outptr + cinfo->output_width;
00246 while (outptr < outend) {
00247 invalue = *inptr++;
00248 *outptr++ = invalue;
00249 *outptr++ = invalue;
00250 }
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259
00260 METHODDEF(void)
00261 h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00262 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00263 {
00264 JSAMPARRAY output_data = *output_data_ptr;
00265 register JSAMPROW inptr, outptr;
00266 register JSAMPLE invalue;
00267 JSAMPROW outend;
00268 int inrow, outrow;
00269
00270 inrow = outrow = 0;
00271 while (outrow < cinfo->max_v_samp_factor) {
00272 inptr = input_data[inrow];
00273 outptr = output_data[outrow];
00274 outend = outptr + cinfo->output_width;
00275 while (outptr < outend) {
00276 invalue = *inptr++;
00277 *outptr++ = invalue;
00278 *outptr++ = invalue;
00279 }
00280 jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
00281 1, cinfo->output_width);
00282 inrow++;
00283 outrow += 2;
00284 }
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 METHODDEF(void)
00304 h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00305 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00306 {
00307 JSAMPARRAY output_data = *output_data_ptr;
00308 register JSAMPROW inptr, outptr;
00309 register int invalue;
00310 register JDIMENSION colctr;
00311 int inrow;
00312
00313 for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
00314 inptr = input_data[inrow];
00315 outptr = output_data[inrow];
00316
00317 invalue = GETJSAMPLE(*inptr++);
00318 *outptr++ = (JSAMPLE) invalue;
00319 *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
00320
00321 for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
00322
00323 invalue = GETJSAMPLE(*inptr++) * 3;
00324 *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
00325 *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
00326 }
00327
00328
00329 invalue = GETJSAMPLE(*inptr);
00330 *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
00331 *outptr++ = (JSAMPLE) invalue;
00332 }
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 METHODDEF(void)
00345 h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00346 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00347 {
00348 JSAMPARRAY output_data = *output_data_ptr;
00349 register JSAMPROW inptr0, inptr1, outptr;
00350 #if BITS_IN_JSAMPLE == 8
00351 register int thiscolsum, lastcolsum, nextcolsum;
00352 #else
00353 register INT32 thiscolsum, lastcolsum, nextcolsum;
00354 #endif
00355 register JDIMENSION colctr;
00356 int inrow, outrow, v;
00357
00358 inrow = outrow = 0;
00359 while (outrow < cinfo->max_v_samp_factor) {
00360 for (v = 0; v < 2; v++) {
00361
00362 inptr0 = input_data[inrow];
00363 if (v == 0)
00364 inptr1 = input_data[inrow-1];
00365 else
00366 inptr1 = input_data[inrow+1];
00367 outptr = output_data[outrow++];
00368
00369
00370 thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
00371 nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
00372 *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
00373 *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
00374 lastcolsum = thiscolsum; thiscolsum = nextcolsum;
00375
00376 for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
00377
00378
00379 nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
00380 *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
00381 *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
00382 lastcolsum = thiscolsum; thiscolsum = nextcolsum;
00383 }
00384
00385
00386 *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
00387 *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
00388 }
00389 inrow++;
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398 GLOBAL(void)
00399 jinit_upsampler (j_decompress_ptr cinfo)
00400 {
00401 my_upsample_ptr upsample;
00402 int ci;
00403 jpeg_component_info * compptr;
00404 boolean need_buffer, do_fancy;
00405 int h_in_group, v_in_group, h_out_group, v_out_group;
00406
00407 upsample = (my_upsample_ptr)
00408 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00409 SIZEOF(my_upsampler));
00410 cinfo->upsample = (struct jpeg_upsampler *) upsample;
00411 upsample->pub.start_pass = start_pass_upsample;
00412 upsample->pub.upsample = sep_upsample;
00413 upsample->pub.need_context_rows = FALSE;
00414
00415 if (cinfo->CCIR601_sampling)
00416 ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
00417
00418
00419
00420
00421 do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
00422
00423
00424
00425
00426 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00427 ci++, compptr++) {
00428
00429
00430
00431 h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
00432 cinfo->min_DCT_scaled_size;
00433 v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
00434 cinfo->min_DCT_scaled_size;
00435 h_out_group = cinfo->max_h_samp_factor;
00436 v_out_group = cinfo->max_v_samp_factor;
00437 upsample->rowgroup_height[ci] = v_in_group;
00438 need_buffer = TRUE;
00439 if (! compptr->component_needed) {
00440
00441 upsample->methods[ci] = noop_upsample;
00442 need_buffer = FALSE;
00443 } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
00444
00445 upsample->methods[ci] = fullsize_upsample;
00446 need_buffer = FALSE;
00447 } else if (h_in_group * 2 == h_out_group &&
00448 v_in_group == v_out_group) {
00449
00450 if (do_fancy && compptr->downsampled_width > 2)
00451 upsample->methods[ci] = h2v1_fancy_upsample;
00452 else
00453 upsample->methods[ci] = h2v1_upsample;
00454 } else if (h_in_group * 2 == h_out_group &&
00455 v_in_group * 2 == v_out_group) {
00456
00457 if (do_fancy && compptr->downsampled_width > 2) {
00458 upsample->methods[ci] = h2v2_fancy_upsample;
00459 upsample->pub.need_context_rows = TRUE;
00460 } else
00461 upsample->methods[ci] = h2v2_upsample;
00462 } else if ((h_out_group % h_in_group) == 0 &&
00463 (v_out_group % v_in_group) == 0) {
00464
00465 upsample->methods[ci] = int_upsample;
00466 upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
00467 upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
00468 } else
00469 ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
00470 if (need_buffer) {
00471 upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
00472 ((j_common_ptr) cinfo, JPOOL_IMAGE,
00473 (JDIMENSION) jround_up((long) cinfo->output_width,
00474 (long) cinfo->max_h_samp_factor),
00475 (JDIMENSION) cinfo->max_v_samp_factor);
00476 }
00477 }
00478 }