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 }