JPEGView/Independent JPEG Group/jcprepct.c

1 line
5.2 KiB
C
Raw Normal View History

/* * jcprepct.c * * Copyright (C) 1994, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains the compression preprocessing controller. * This controller manages the color conversion, downsampling, * and edge expansion steps. */ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" /* Private buffer controller object */ typedef struct { struct jpeg_c_prep_controller pub; /* public fields */ /* Downsampling input buffer. This buffer holds color-converted data * until we have enough to do a downsample step. */ JSAMPARRAY color_buf[MAX_COMPONENTS]; int rows_in_buf; /* counts rows stored in color_buf */ JDIMENSION rows_to_go; /* counts rows remaining in source image */ } my_prep_controller; typedef my_prep_controller * my_prep_ptr; /* * Initialize for a processing pass. */ METHODDEF void start_pass (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { my_prep_ptr prep = (my_prep_ptr) cinfo->prep; switch (pass_mode) { case JBUF_PASS_THRU: break; default: ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); break; } /* Mark the conversion buffer empty */ prep->rows_in_buf = 0; /* Initialize total-height counter for detecting bottom of image */ prep->rows_to_go = cinfo->image_height; } /* * Expand an image vertically from height input_rows to height output_rows, * by duplicating the bottom row. */ LOCAL void expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows, int output_rows) { register int row; for (row = input_rows; row < output_rows; row++) { jcopy_sample_rows(image_data, input_rows-1, image_data, row, 1, num_cols); } } /* * Process some data. * * Preprocessor output data is counted in "row groups". A row group * is defined to be v_samp_factor sample rows of each component. * Downsampling will produce this much data from each max_v_samp_factor * input rows. */ METHODDEF void pre_process_data (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail, JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, JDIMENSION out_row_groups_avail) { my_prep_ptr prep = (my_prep_ptr) cinfo->prep; int numrows, ci; JDIMENSION inrows; jpeg_component_info * compptr; while (*in_row_ctr < in_rows_avail && *out_row_group_ctr < out_row_groups_avail) { /* Do color conversion to fill the conversion buffer. */ inrows = in_rows_avail - *in_row_ctr; numrows = cinfo->max_v_samp_factor - prep->rows_in_buf; numrows = (int) MIN((JDIMENSION) numrows, inrows); (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, prep->color_buf, (JDIMENSION) prep->rows_in_buf, numrows); *in_row_ctr += numrows; prep->rows_in_buf += numrows; prep->rows_to_go -= numrows; /* If at bottom of image, pad to fill the conversion buffer. */ if (prep->rows_to_go == 0 && prep->rows_in_buf < cinfo->max_v_samp_factor) { for (ci = 0; ci < cinfo->num_components; ci++) { expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, prep->rows_in_buf, cinfo->max_v_samp_factor); } prep->rows_in_buf = cinfo->max_v_samp_factor; } /* If we've filled the conversion buffer, empty it. */ if (prep->rows_in_buf == cinfo->max_v_samp_factor) { (*cinfo->downsample->downsample) (cinfo, prep->color_buf, output_buf, *out_row_group_ctr); prep->rows_in_buf = 0; (*out_row_group_ctr)++; } /* If at bottom of image, pad the output to a full MCU height. * Note we assume the caller is providing a one-MCU-height output buffer! */ if (prep->rows_to_go == 0 && *out_row_group_ctr < out_row_groups_avail) { for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { expand_bottom_edge(output_buf[ci], compptr->width_in_blocks * DCTSIZE, (int) (*out_row_group_ctr * compptr->v_samp_factor),