00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define JPEG_INTERNALS
00036 #include "jinclude.h"
00037 #include "jpeglib.h"
00038
00039 #ifdef UPSAMPLE_MERGING_SUPPORTED
00040
00041
00042
00043
00044 typedef struct {
00045 struct jpeg_upsampler pub;
00046
00047
00048 JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
00049 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00050 JSAMPARRAY output_buf));
00051
00052
00053 int * Cr_r_tab;
00054 int * Cb_b_tab;
00055 INT32 * Cr_g_tab;
00056 INT32 * Cb_g_tab;
00057
00058
00059
00060
00061
00062
00063 JSAMPROW spare_row;
00064 boolean spare_full;
00065
00066 JDIMENSION out_row_width;
00067 JDIMENSION rows_to_go;
00068 } my_upsampler;
00069
00070 typedef my_upsampler * my_upsample_ptr;
00071
00072 #define SCALEBITS 16
00073 #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
00074 #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
00075
00076
00077
00078
00079
00080
00081
00082 LOCAL(void)
00083 build_ycc_rgb_table (j_decompress_ptr cinfo)
00084 {
00085 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00086 int i;
00087 INT32 x;
00088 SHIFT_TEMPS
00089
00090 upsample->Cr_r_tab = (int *)
00091 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00092 (MAXJSAMPLE+1) * SIZEOF(int));
00093 upsample->Cb_b_tab = (int *)
00094 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00095 (MAXJSAMPLE+1) * SIZEOF(int));
00096 upsample->Cr_g_tab = (INT32 *)
00097 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00098 (MAXJSAMPLE+1) * SIZEOF(INT32));
00099 upsample->Cb_g_tab = (INT32 *)
00100 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00101 (MAXJSAMPLE+1) * SIZEOF(INT32));
00102
00103 for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
00104
00105
00106
00107 upsample->Cr_r_tab[i] = (int)
00108 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
00109
00110 upsample->Cb_b_tab[i] = (int)
00111 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
00112
00113 upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
00114
00115
00116 upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
00117 }
00118 }
00119
00120
00121
00122
00123
00124
00125 METHODDEF(void)
00126 start_pass_merged_upsample (j_decompress_ptr cinfo)
00127 {
00128 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00129
00130
00131 upsample->spare_full = FALSE;
00132
00133 upsample->rows_to_go = cinfo->output_height;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 METHODDEF(void)
00144 merged_2v_upsample (j_decompress_ptr cinfo,
00145 JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00146 JDIMENSION in_row_groups_avail,
00147 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00148 JDIMENSION out_rows_avail)
00149
00150 {
00151 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00152 JSAMPROW work_ptrs[2];
00153 JDIMENSION num_rows;
00154
00155 if (upsample->spare_full) {
00156
00157 jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
00158 1, upsample->out_row_width);
00159 num_rows = 1;
00160 upsample->spare_full = FALSE;
00161 } else {
00162
00163 num_rows = 2;
00164
00165 if (num_rows > upsample->rows_to_go)
00166 num_rows = upsample->rows_to_go;
00167
00168 out_rows_avail -= *out_row_ctr;
00169 if (num_rows > out_rows_avail)
00170 num_rows = out_rows_avail;
00171
00172 work_ptrs[0] = output_buf[*out_row_ctr];
00173 if (num_rows > 1) {
00174 work_ptrs[1] = output_buf[*out_row_ctr + 1];
00175 } else {
00176 work_ptrs[1] = upsample->spare_row;
00177 upsample->spare_full = TRUE;
00178 }
00179
00180 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
00181 }
00182
00183
00184 *out_row_ctr += num_rows;
00185 upsample->rows_to_go -= num_rows;
00186
00187 if (! upsample->spare_full)
00188 (*in_row_group_ctr)++;
00189 }
00190
00191
00192 METHODDEF(void)
00193 merged_1v_upsample (j_decompress_ptr cinfo,
00194 JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00195 JDIMENSION in_row_groups_avail,
00196 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00197 JDIMENSION out_rows_avail)
00198
00199 {
00200 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00201
00202
00203 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
00204 output_buf + *out_row_ctr);
00205
00206 (*out_row_ctr)++;
00207 (*in_row_group_ctr)++;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 METHODDEF(void)
00226 h2v1_merged_upsample (j_decompress_ptr cinfo,
00227 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00228 JSAMPARRAY output_buf)
00229 {
00230 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00231 register int y, cred, cgreen, cblue;
00232 int cb, cr;
00233 register JSAMPROW outptr;
00234 JSAMPROW inptr0, inptr1, inptr2;
00235 JDIMENSION col;
00236
00237 register JSAMPLE * range_limit = cinfo->sample_range_limit;
00238 int * Crrtab = upsample->Cr_r_tab;
00239 int * Cbbtab = upsample->Cb_b_tab;
00240 INT32 * Crgtab = upsample->Cr_g_tab;
00241 INT32 * Cbgtab = upsample->Cb_g_tab;
00242 SHIFT_TEMPS
00243
00244 inptr0 = input_buf[0][in_row_group_ctr];
00245 inptr1 = input_buf[1][in_row_group_ctr];
00246 inptr2 = input_buf[2][in_row_group_ctr];
00247 outptr = output_buf[0];
00248
00249 for (col = cinfo->output_width >> 1; col > 0; col--) {
00250
00251 cb = GETJSAMPLE(*inptr1++);
00252 cr = GETJSAMPLE(*inptr2++);
00253 cred = Crrtab[cr];
00254 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00255 cblue = Cbbtab[cb];
00256
00257 y = GETJSAMPLE(*inptr0++);
00258 outptr[RGB_RED] = range_limit[y + cred];
00259 outptr[RGB_GREEN] = range_limit[y + cgreen];
00260 outptr[RGB_BLUE] = range_limit[y + cblue];
00261 outptr += RGB_PIXELSIZE;
00262 y = GETJSAMPLE(*inptr0++);
00263 outptr[RGB_RED] = range_limit[y + cred];
00264 outptr[RGB_GREEN] = range_limit[y + cgreen];
00265 outptr[RGB_BLUE] = range_limit[y + cblue];
00266 outptr += RGB_PIXELSIZE;
00267 }
00268
00269 if (cinfo->output_width & 1) {
00270 cb = GETJSAMPLE(*inptr1);
00271 cr = GETJSAMPLE(*inptr2);
00272 cred = Crrtab[cr];
00273 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00274 cblue = Cbbtab[cb];
00275 y = GETJSAMPLE(*inptr0);
00276 outptr[RGB_RED] = range_limit[y + cred];
00277 outptr[RGB_GREEN] = range_limit[y + cgreen];
00278 outptr[RGB_BLUE] = range_limit[y + cblue];
00279 }
00280 }
00281
00282
00283
00284
00285
00286
00287 METHODDEF(void)
00288 h2v2_merged_upsample (j_decompress_ptr cinfo,
00289 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00290 JSAMPARRAY output_buf)
00291 {
00292 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00293 register int y, cred, cgreen, cblue;
00294 int cb, cr;
00295 register JSAMPROW outptr0, outptr1;
00296 JSAMPROW inptr00, inptr01, inptr1, inptr2;
00297 JDIMENSION col;
00298
00299 register JSAMPLE * range_limit = cinfo->sample_range_limit;
00300 int * Crrtab = upsample->Cr_r_tab;
00301 int * Cbbtab = upsample->Cb_b_tab;
00302 INT32 * Crgtab = upsample->Cr_g_tab;
00303 INT32 * Cbgtab = upsample->Cb_g_tab;
00304 SHIFT_TEMPS
00305
00306 inptr00 = input_buf[0][in_row_group_ctr*2];
00307 inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
00308 inptr1 = input_buf[1][in_row_group_ctr];
00309 inptr2 = input_buf[2][in_row_group_ctr];
00310 outptr0 = output_buf[0];
00311 outptr1 = output_buf[1];
00312
00313 for (col = cinfo->output_width >> 1; col > 0; col--) {
00314
00315 cb = GETJSAMPLE(*inptr1++);
00316 cr = GETJSAMPLE(*inptr2++);
00317 cred = Crrtab[cr];
00318 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00319 cblue = Cbbtab[cb];
00320
00321 y = GETJSAMPLE(*inptr00++);
00322 outptr0[RGB_RED] = range_limit[y + cred];
00323 outptr0[RGB_GREEN] = range_limit[y + cgreen];
00324 outptr0[RGB_BLUE] = range_limit[y + cblue];
00325 outptr0 += RGB_PIXELSIZE;
00326 y = GETJSAMPLE(*inptr00++);
00327 outptr0[RGB_RED] = range_limit[y + cred];
00328 outptr0[RGB_GREEN] = range_limit[y + cgreen];
00329 outptr0[RGB_BLUE] = range_limit[y + cblue];
00330 outptr0 += RGB_PIXELSIZE;
00331 y = GETJSAMPLE(*inptr01++);
00332 outptr1[RGB_RED] = range_limit[y + cred];
00333 outptr1[RGB_GREEN] = range_limit[y + cgreen];
00334 outptr1[RGB_BLUE] = range_limit[y + cblue];
00335 outptr1 += RGB_PIXELSIZE;
00336 y = GETJSAMPLE(*inptr01++);
00337 outptr1[RGB_RED] = range_limit[y + cred];
00338 outptr1[RGB_GREEN] = range_limit[y + cgreen];
00339 outptr1[RGB_BLUE] = range_limit[y + cblue];
00340 outptr1 += RGB_PIXELSIZE;
00341 }
00342
00343 if (cinfo->output_width & 1) {
00344 cb = GETJSAMPLE(*inptr1);
00345 cr = GETJSAMPLE(*inptr2);
00346 cred = Crrtab[cr];
00347 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00348 cblue = Cbbtab[cb];
00349 y = GETJSAMPLE(*inptr00);
00350 outptr0[RGB_RED] = range_limit[y + cred];
00351 outptr0[RGB_GREEN] = range_limit[y + cgreen];
00352 outptr0[RGB_BLUE] = range_limit[y + cblue];
00353 y = GETJSAMPLE(*inptr01);
00354 outptr1[RGB_RED] = range_limit[y + cred];
00355 outptr1[RGB_GREEN] = range_limit[y + cgreen];
00356 outptr1[RGB_BLUE] = range_limit[y + cblue];
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 GLOBAL(void)
00370 jinit_merged_upsampler (j_decompress_ptr cinfo)
00371 {
00372 my_upsample_ptr upsample;
00373
00374 upsample = (my_upsample_ptr)
00375 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00376 SIZEOF(my_upsampler));
00377 cinfo->upsample = (struct jpeg_upsampler *) upsample;
00378 upsample->pub.start_pass = start_pass_merged_upsample;
00379 upsample->pub.need_context_rows = FALSE;
00380
00381 upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
00382
00383 if (cinfo->max_v_samp_factor == 2) {
00384 upsample->pub.upsample = merged_2v_upsample;
00385 upsample->upmethod = h2v2_merged_upsample;
00386
00387 upsample->spare_row = (JSAMPROW)
00388 (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00389 (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
00390 } else {
00391 upsample->pub.upsample = merged_1v_upsample;
00392 upsample->upmethod = h2v1_merged_upsample;
00393
00394 upsample->spare_row = NULL;
00395 }
00396
00397 build_ycc_rgb_table(cinfo);
00398 }
00399
00400 #endif