| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| typedef struct { |
| struct jpeg_d_main_controller pub; |
| |
| |
| JSAMPARRAY buffer[MAX_COMPONENTS]; |
| |
| boolean buffer_full; |
| JDIMENSION rowgroup_ctr; |
| |
| |
| |
| |
| JSAMPIMAGE xbuffer[2]; |
| |
| int whichptr; |
| int context_state; |
| JDIMENSION rowgroups_avail; |
| JDIMENSION iMCU_row_ctr; |
| } my_main_controller; |
| |
| typedef my_main_controller * my_main_ptr; |
| |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(void) process_data_simple_main |
| JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, |
| JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); |
| METHODDEF(void) process_data_context_main |
| JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, |
| JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); |
| |
| METHODDEF(void) process_data_crank_post |
| JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, |
| JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); |
| |
| |
| |
| LOCAL(void) |
| alloc_funny_pointers (j_decompress_ptr cinfo) |
| |
| |
| |
| { |
| my_main_ptr mainp = (my_main_ptr) cinfo->main; |
| int ci, rgroup; |
| int M = cinfo->min_DCT_v_scaled_size; |
| jpeg_component_info *compptr; |
| JSAMPARRAY xbuf; |
| |
| |
| |
| |
| mainp->xbuffer[0] = (JSAMPIMAGE) |
| (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); |
| mainp->xbuffer[1] = mainp->xbuffer[0] + cinfo->num_components; |
| |
| for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; |
| ci++, compptr++) { |
| rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / |
| cinfo->min_DCT_v_scaled_size; |
| |
| |
| |
| xbuf = (JSAMPARRAY) |
| (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); |
| xbuf += rgroup; |
| mainp->xbuffer[0][ci] = xbuf; |
| xbuf += rgroup * (M + 4); |
| mainp->xbuffer[1][ci] = xbuf; |
| } |
| } |
| |
| |
| LOCAL(void) |
| make_funny_pointers (j_decompress_ptr cinfo) |
| |
| |
| |
| |
| |
| |
| { |
| my_main_ptr mainp = (my_main_ptr) cinfo->main; |
| int ci, i, rgroup; |
| int M = cinfo->min_DCT_v_scaled_size; |
| jpeg_component_info *compptr; |
| JSAMPARRAY buf, xbuf0, xbuf1; |
| |
| for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; |
| ci++, compptr++) { |
| rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / |
| cinfo->min_DCT_v_scaled_size; |
| xbuf0 = mainp->xbuffer[0][ci]; |
| xbuf1 = mainp->xbuffer[1][ci]; |
| |
| buf = mainp->buffer[ci]; |
| for (i = 0; i < rgroup * (M + 2); i++) { |
| xbuf0[i] = xbuf1[i] = buf[i]; |
| } |
| |
| for (i = 0; i < rgroup * 2; i++) { |
| xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; |
| xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; |
| } |
| |
| |
| |
| |
| |
| for (i = 0; i < rgroup; i++) { |
| xbuf0[i - rgroup] = xbuf0[0]; |
| } |
| } |
| } |
| |
| |
| LOCAL(void) |
| set_wraparound_pointers (j_decompress_ptr cinfo) |
| |
| |
| |
| { |
| my_main_ptr mainp = (my_main_ptr) cinfo->main; |
| int ci, i, rgroup; |
| int M = cinfo->min_DCT_v_scaled_size; |
| jpeg_component_info *compptr; |
| JSAMPARRAY xbuf0, xbuf1; |
| |
| for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; |
| ci++, compptr++) { |
| rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / |
| cinfo->min_DCT_v_scaled_size; |
| xbuf0 = mainp->xbuffer[0][ci]; |
| xbuf1 = mainp->xbuffer[1][ci]; |
| for (i = 0; i < rgroup; i++) { |
| xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; |
| xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; |
| xbuf0[rgroup*(M+2) + i] = xbuf0[i]; |
| xbuf1[rgroup*(M+2) + i] = xbuf1[i]; |
| } |
| } |
| } |
| |
| |
| LOCAL(void) |
| set_bottom_pointers (j_decompress_ptr cinfo) |
| |
| |
| |
| |
| { |
| my_main_ptr mainp = (my_main_ptr) cinfo->main; |
| int ci, i, rgroup, iMCUheight, rows_left; |
| jpeg_component_info *compptr; |
| JSAMPARRAY xbuf; |
| |
| for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; |
| ci++, compptr++) { |
| |
| iMCUheight = compptr->v_samp_factor * compptr->DCT_v_scaled_size; |
| rgroup = iMCUheight / cinfo->min_DCT_v_scaled_size; |
| |
| rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); |
| if (rows_left == 0) rows_left = iMCUheight; |
| |
| |
| |
| if (ci == 0) { |
| mainp->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); |
| } |
| |
| |
| |
| xbuf = mainp->xbuffer[mainp->whichptr][ci]; |
| for (i = 0; i < rgroup * 2; i++) { |
| xbuf[rows_left + i] = xbuf[rows_left-1]; |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| METHODDEF(void) |
| start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) |
| { |
| my_main_ptr mainp = (my_main_ptr) cinfo->main; |
| |
| switch (pass_mode) { |
| case JBUF_PASS_THRU: |
| if (cinfo->upsample->need_context_rows) { |
| mainp->pub.process_data = process_data_context_main; |
| make_funny_pointers(cinfo); |
| mainp->whichptr = 0; |
| mainp->context_state = CTX_PREPARE_FOR_IMCU; |
| mainp->iMCU_row_ctr = 0; |
| } else { |
| |
| mainp->pub.process_data = process_data_simple_main; |
| } |
| mainp->buffer_full = FALSE; |
| mainp->rowgroup_ctr = 0; |
| break; |
| |
| case JBUF_CRANK_DEST: |
| |
| mainp->pub.process_data = process_data_crank_post; |
| break; |
| |
| default: |
| ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); |
| break; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(void) |
| process_data_simple_main (j_decompress_ptr cinfo, |
| JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, |
| JDIMENSION out_rows_avail) |
| { |
| my_main_ptr mainp = (my_main_ptr) cinfo->main; |
| JDIMENSION rowgroups_avail; |
| |
| |
| if (! mainp->buffer_full) { |
| if (! (*cinfo->coef->decompress_data) (cinfo, mainp->buffer)) |
| return; |
| mainp->buffer_full = TRUE; |
| } |
| |
| |
| rowgroups_avail = (JDIMENSION) cinfo->min_DCT_v_scaled_size; |
| |
| |
| |
| |
| |
| |
| (*cinfo->post->post_process_data) (cinfo, mainp->buffer, |
| &mainp->rowgroup_ctr, rowgroups_avail, |
| output_buf, out_row_ctr, out_rows_avail); |
| |
| |
| if (mainp->rowgroup_ctr >= rowgroups_avail) { |
| mainp->buffer_full = FALSE; |
| mainp->rowgroup_ctr = 0; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(void) |
| process_data_context_main (j_decompress_ptr cinfo, |
| JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, |
| JDIMENSION out_rows_avail) |
| { |
| my_main_ptr mainp = (my_main_ptr) cinfo->main; |
| |
| |
| if (! mainp->buffer_full) { |
| if (! (*cinfo->coef->decompress_data) (cinfo, |
| mainp->xbuffer[mainp->whichptr])) |
| return; |
| mainp->buffer_full = TRUE; |
| mainp->iMCU_row_ctr++; |
| } |
| |
| |
| |
| |
| |
| |
| switch (mainp->context_state) { |
| case CTX_POSTPONED_ROW: |
| |
| (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr], |
| &mainp->rowgroup_ctr, mainp->rowgroups_avail, |
| output_buf, out_row_ctr, out_rows_avail); |
| if (mainp->rowgroup_ctr < mainp->rowgroups_avail) |
| return; |
| mainp->context_state = CTX_PREPARE_FOR_IMCU; |
| if (*out_row_ctr >= out_rows_avail) |
| return; |
| |
| case CTX_PREPARE_FOR_IMCU: |
| |
| mainp->rowgroup_ctr = 0; |
| mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1); |
| |
| |
| |
| if (mainp->iMCU_row_ctr == cinfo->total_iMCU_rows) |
| set_bottom_pointers(cinfo); |
| mainp->context_state = CTX_PROCESS_IMCU; |
| |
| case CTX_PROCESS_IMCU: |
| |
| (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr], |
| &mainp->rowgroup_ctr, mainp->rowgroups_avail, |
| output_buf, out_row_ctr, out_rows_avail); |
| if (mainp->rowgroup_ctr < mainp->rowgroups_avail) |
| return; |
| |
| if (mainp->iMCU_row_ctr == 1) |
| set_wraparound_pointers(cinfo); |
| |
| mainp->whichptr ^= 1; |
| mainp->buffer_full = FALSE; |
| |
| |
| mainp->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1); |
| mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2); |
| mainp->context_state = CTX_POSTPONED_ROW; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(void) |
| process_data_crank_post (j_decompress_ptr cinfo, |
| JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, |
| JDIMENSION out_rows_avail) |
| { |
| (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, |
| (JDIMENSION *) NULL, (JDIMENSION) 0, |
| output_buf, out_row_ctr, out_rows_avail); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| GLOBAL(void) |
| jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) |
| { |
| my_main_ptr mainp; |
| int ci, rgroup, ngroups; |
| jpeg_component_info *compptr; |
| |
| mainp = (my_main_ptr) |
| (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| SIZEOF(my_main_controller)); |
| cinfo->main = &mainp->pub; |
| mainp->pub.start_pass = start_pass_main; |
| |
| if (need_full_buffer) |
| ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); |
| |
| |
| |
| |
| if (cinfo->upsample->need_context_rows) { |
| if (cinfo->min_DCT_v_scaled_size < 2) |
| ERREXIT(cinfo, JERR_NOTIMPL); |
| alloc_funny_pointers(cinfo); |
| ngroups = cinfo->min_DCT_v_scaled_size + 2; |
| } else { |
| ngroups = cinfo->min_DCT_v_scaled_size; |
| } |
| |
| for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; |
| ci++, compptr++) { |
| rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / |
| cinfo->min_DCT_v_scaled_size; |
| mainp->buffer[ci] = (*cinfo->mem->alloc_sarray) |
| ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size), |
| (JDIMENSION) (rgroup * ngroups)); |
| } |
| } |