GLOBAL(void)
jpeg_write_coefficients(j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
{ if (cinfo->master->lossless)
ERREXIT(cinfo, JERR_NOTIMPL);
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); /* Mark all tables to be written */
jpeg_suppress_tables(cinfo, FALSE); /* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo);
(*cinfo->dest->init_destination) (cinfo); /* Perform master selection of active modules */
transencode_master_selection(cinfo, coef_arrays); /* Wait for jpeg_finish_compress() call */
cinfo->next_scanline = 0; /* so jpeg_write_marker works */
cinfo->global_state = CSTATE_WRCOEFS;
}
typedefstruct { struct jpeg_c_coef_controller pub; /* public fields */
JDIMENSION iMCU_row_num; /* iMCU row # within image */
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ int MCU_vert_offset; /* counts MCU rows within iMCU row */ int MCU_rows_per_iMCU_row; /* number of such rows needed */
/* Virtual block array for each component. */
jvirt_barray_ptr *whole_image;
/* Workspace for constructing dummy blocks at right/bottom edges. */
JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
} my_coef_controller;
typedef my_coef_controller *my_coef_ptr;
LOCAL(void)
start_iMCU_row(j_compress_ptr cinfo) /* Reset within-iMCU-row counters for a new row */
{
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
/* In an interleaved scan, an MCU row is the same as an iMCU row. *Inanoninterleavedscan,aniMCUrowhasv_samp_factorMCUrows. *Butatthebottomoftheimage,processonlywhat'sleft.
*/ if (cinfo->comps_in_scan > 1) {
coef->MCU_rows_per_iMCU_row = 1;
} else { if (coef->iMCU_row_num < (cinfo->total_iMCU_rows - 1))
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; else
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
}
METHODDEF(boolean)
compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; int blkn, ci, xindex, yindex, yoffset, blockcnt;
JDIMENSION start_col;
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
JBLOCKROW buffer_ptr;
jpeg_component_info *compptr;
/* Align the virtual buffers for the components used in this scan. */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
buffer[ci] = (*cinfo->mem->access_virt_barray)
((j_common_ptr)cinfo, coef->whole_image[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION)compptr->v_samp_factor, FALSE);
}
/* Loop to process one whole iMCU row */ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
yoffset++) { for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
MCU_col_num++) { /* Construct list of pointers to DCT blocks belonging to this MCU */
blkn = 0; /* index of current DCT block within MCU */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
start_col = MCU_col_num * compptr->MCU_width;
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width :
compptr->last_col_width; for (yindex = 0; yindex < compptr->MCU_height; yindex++) { if (coef->iMCU_row_num < last_iMCU_row ||
yindex + yoffset < compptr->last_row_height) { /* Fill in pointers to real blocks in this row */
buffer_ptr = buffer[ci][yindex + yoffset] + start_col; for (xindex = 0; xindex < blockcnt; xindex++)
MCU_buffer[blkn++] = buffer_ptr++;
} else { /* At bottom of image, need a whole row of dummy blocks */
xindex = 0;
} /* Fill in any dummy blocks needed in this row. *Dummyblocksarefilledinthesamewayasinjccoefct.c: *allzeroesintheACentries,DCentriesequaltoprevious *block'sDCvalue.Theinitroutinehasalreadyzeroedthe *ACentries,soweneedonlysettheDCentriescorrectly.
*/ for (; xindex < compptr->MCU_width; xindex++) {
MCU_buffer[blkn] = coef->dummy_buffer[blkn];
MCU_buffer[blkn][0][0] = MCU_buffer[blkn - 1][0][0];
blkn++;
}
}
} /* Try to write the MCU. */ if (!(*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { /* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
coef->mcu_ctr = MCU_col_num; returnFALSE;
}
} /* Completed an MCU row, but perhaps not an iMCU row */
coef->mcu_ctr = 0;
} /* Completed the iMCU row, advance counters for next one */
coef->iMCU_row_num++;
start_iMCU_row(cinfo); return TRUE;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.