Exemplo n.º 1
0
METHODDEF void
dump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
/* Dump the MCUs saved in whole_scan_MCUs to the output method. */
/* The method may be either the entropy encoder or some routine supplied */
/* by the entropy optimizer. */
{
  /* On an 80x86 machine, the entropy encoder expects the passed data block
   * to be in NEAR memory (for performance reasons), so we have to copy it
   * back from the big array to a local array.  On less brain-damaged CPUs
   * we needn't do that.
   */
#ifdef NEED_FAR_POINTERS
  JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
#endif
  long mcurow, mcuindex, next_row;
  int next_index;
  JBLOCKARRAY rowptr = NULL;	/* init only to suppress compiler complaint */

  next_row = 0;
  next_index = MCUs_in_big_row;

  for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) {
    (*cinfo->methods->progress_monitor) (cinfo, mcurow,
					 cinfo->MCU_rows_in_scan);
    for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
      if (next_index >= MCUs_in_big_row) {
	rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
							next_row, FALSE);
	next_row++;
	next_index = 0;
      }
#ifdef NEED_FAR_POINTERS
      jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU,
		      (JBLOCKROW) MCU_data, /* casts near to far pointer! */
		      (long) cinfo->blocks_in_MCU);
      (*output_method) (cinfo, MCU_data);
#else
      (*output_method) (cinfo, rowptr[0] + next_index * cinfo->blocks_in_MCU);
#endif
      next_index++;
    }
  }

  cinfo->completed_passes++;
}
Exemplo n.º 2
0
METHODDEF void
MCU_output_catcher (compress_info_ptr cinfo, JBLOCK *MCU_data)
/* Output method for siphoning off extract_MCUs output into a big array */
{
  static JBLOCKARRAY rowptr;

  if (next_MCU_index >= MCUs_in_big_row) {
    rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
						    next_whole_row, TRUE);
    next_whole_row++;
    next_MCU_index = 0;
  }

  /*
   * note that on 80x86, the cast applied to MCU_data implies
   * near to far pointer conversion.
   */
  jcopy_block_row((JBLOCKROW) MCU_data,
		  rowptr[0] + next_MCU_index * cinfo->blocks_in_MCU,
		  (long) cinfo->blocks_in_MCU);
  next_MCU_index++;
}
Exemplo n.º 3
0
do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
	   jvirt_barray_ptr *src_coef_arrays,
	   jvirt_barray_ptr *dst_coef_arrays)
/* Vertical flip */
{
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
  int ci, i, j, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JBLOCKROW src_row_ptr, dst_row_ptr;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  /* We output into a separate array because we can't touch different
   * rows of the source virtual array simultaneously.  Otherwise, this
   * is a pretty straightforward analog of horizontal flip.
   * Within a DCT block, vertical mirroring is done by changing the signs
   * of odd-numbered rows.
   * Partial iMCUs at the bottom edge are copied verbatim.
   */
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_height = MCU_rows * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
	 dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
      if (dst_blk_y < comp_height) {
	/* Row is within the mirrorable area. */
	src_buffer = (*srcinfo->mem->access_virt_barray)
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
	   comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
      } else {
	/* Bottom-edge blocks will be copied verbatim. */
	src_buffer = (*srcinfo->mem->access_virt_barray)
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
      }
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
	if (dst_blk_y < comp_height) {
	  /* Row is within the mirrorable area. */
	  dst_row_ptr = dst_buffer[offset_y];
	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
	       dst_blk_x++) {
	    dst_ptr = dst_row_ptr[dst_blk_x];
	    src_ptr = src_row_ptr[dst_blk_x];
	    for (i = 0; i < DCTSIZE; i += 2) {
	      /* copy even row */
	      for (j = 0; j < DCTSIZE; j++)
		*dst_ptr++ = *src_ptr++;
	      /* copy odd row with sign change */
	      for (j = 0; j < DCTSIZE; j++)
		*dst_ptr++ = - *src_ptr++;
	    }
	  }
	} else {
	  /* Just copy row verbatim. */
	  jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
			  compptr->width_in_blocks);
	}
      }
    }
  }
}
Exemplo n.º 4
0
decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) {
    my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    JDIMENSION block_num, last_block_column;
    int ci, block_row, block_rows, access_rows;
    JBLOCKARRAY buffer;
    JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
    JSAMPARRAY output_ptr;
    JDIMENSION output_col;
    jpeg_component_info *compptr;
    inverse_DCT_method_ptr inverse_DCT;
    boolean first_row, last_row;
    JBLOCK workspace;
    int *coef_bits;
    JQUANT_TBL *quanttbl;
    INT32 Q00, Q01, Q02, Q10, Q11, Q20, num;
    int DC1, DC2, DC3, DC4, DC5, DC6, DC7, DC8, DC9;
    int Al, pred;

    /* Force some input to be done if we are getting ahead of the input. */
    while (cinfo->input_scan_number <= cinfo->output_scan_number &&
           !cinfo->inputctl->eoi_reached) {
        if (cinfo->input_scan_number == cinfo->output_scan_number) {
            /* If input is working on current scan, we ordinarily want it to
             * have completed the current row.  But if input scan is DC,
             * we want it to keep one row ahead so that next block row's DC
             * values are up to date.
             */
            JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
            if (cinfo->input_iMCU_row > cinfo->output_iMCU_row + delta)
                break;
        }
        if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
            return JPEG_SUSPENDED;
    }

    /* OK, output from the virtual arrays. */
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
         ci++, compptr++) {
        /* Don't bother to IDCT an uninteresting component. */
        if (!compptr->component_needed)
            continue;
        /* Count non-dummy DCT block rows in this iMCU row. */
        if (cinfo->output_iMCU_row < last_iMCU_row) {
            block_rows = compptr->v_samp_factor;
            access_rows = block_rows * 2; /* this and next iMCU row */
            last_row = FALSE;
        } else {
            /* NB: can't use last_row_height here; it is input-side-dependent! */
            block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
            if (block_rows == 0) block_rows = compptr->v_samp_factor;
            access_rows = block_rows; /* this iMCU row only */
            last_row = TRUE;
        }
        /* Align the virtual buffer for this component. */
        if (cinfo->output_iMCU_row > 0) {
            access_rows += compptr->v_samp_factor; /* prior iMCU row too */
            buffer = (*cinfo->mem->access_virt_barray)
                    ((j_common_ptr) cinfo, coef->whole_image[ci],
                     (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
                     (JDIMENSION) access_rows, FALSE);
            buffer += compptr->v_samp_factor;    /* point to current iMCU row */
            first_row = FALSE;
        } else {
            buffer = (*cinfo->mem->access_virt_barray)
                    ((j_common_ptr) cinfo, coef->whole_image[ci],
                     (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
            first_row = TRUE;
        }
        /* Fetch component-dependent info */
        coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
        quanttbl = compptr->quant_table;
        Q00 = quanttbl->quantval[0];
        Q01 = quanttbl->quantval[Q01_POS];
        Q10 = quanttbl->quantval[Q10_POS];
        Q20 = quanttbl->quantval[Q20_POS];
        Q11 = quanttbl->quantval[Q11_POS];
        Q02 = quanttbl->quantval[Q02_POS];
        inverse_DCT = cinfo->idct->inverse_DCT[ci];
        output_ptr = output_buf[ci];
        /* Loop over all DCT blocks to be processed. */
        for (block_row = 0; block_row < block_rows; block_row++) {
            buffer_ptr = buffer[block_row];
            if (first_row && block_row == 0)
                prev_block_row = buffer_ptr;
            else
                prev_block_row = buffer[block_row - 1];
            if (last_row && block_row == block_rows - 1)
                next_block_row = buffer_ptr;
            else
                next_block_row = buffer[block_row + 1];
            /* We fetch the surrounding DC values using a sliding-register approach.
             * Initialize all nine here so as to do the right thing on narrow pics.
             */
            DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
            DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
            DC7 = DC8 = DC9 = (int) next_block_row[0][0];
            output_col = 0;
            last_block_column = compptr->width_in_blocks - 1;
            for (block_num = 0; block_num <= last_block_column; block_num++) {
                /* Fetch current DCT block into workspace so we can modify it. */
                jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
                /* Update DC values */
                if (block_num < last_block_column) {
                    DC3 = (int) prev_block_row[1][0];
                    DC6 = (int) buffer_ptr[1][0];
                    DC9 = (int) next_block_row[1][0];
                }
                /* Compute coefficient estimates per K.8.
                 * An estimate is applied only if coefficient is still zero,
                 * and is not known to be fully accurate.
                 */
                /* AC01 */
                if ((Al = coef_bits[1]) != 0 && workspace[1] == 0) {
                    num = 36 * Q00 * (DC4 - DC6);
                    if (num >= 0) {
                        pred = (int) (((Q01 << 7) + num) / (Q01 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                    } else {
                        pred = (int) (((Q01 << 7) - num) / (Q01 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                        pred = -pred;
                    }
                    workspace[1] = (JCOEF) pred;
                }
                /* AC10 */
                if ((Al = coef_bits[2]) != 0 && workspace[8] == 0) {
                    num = 36 * Q00 * (DC2 - DC8);
                    if (num >= 0) {
                        pred = (int) (((Q10 << 7) + num) / (Q10 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                    } else {
                        pred = (int) (((Q10 << 7) - num) / (Q10 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                        pred = -pred;
                    }
                    workspace[8] = (JCOEF) pred;
                }
                /* AC20 */
                if ((Al = coef_bits[3]) != 0 && workspace[16] == 0) {
                    num = 9 * Q00 * (DC2 + DC8 - 2 * DC5);
                    if (num >= 0) {
                        pred = (int) (((Q20 << 7) + num) / (Q20 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                    } else {
                        pred = (int) (((Q20 << 7) - num) / (Q20 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                        pred = -pred;
                    }
                    workspace[16] = (JCOEF) pred;
                }
                /* AC11 */
                if ((Al = coef_bits[4]) != 0 && workspace[9] == 0) {
                    num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
                    if (num >= 0) {
                        pred = (int) (((Q11 << 7) + num) / (Q11 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                    } else {
                        pred = (int) (((Q11 << 7) - num) / (Q11 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                        pred = -pred;
                    }
                    workspace[9] = (JCOEF) pred;
                }
                /* AC02 */
                if ((Al = coef_bits[5]) != 0 && workspace[2] == 0) {
                    num = 9 * Q00 * (DC4 + DC6 - 2 * DC5);
                    if (num >= 0) {
                        pred = (int) (((Q02 << 7) + num) / (Q02 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                    } else {
                        pred = (int) (((Q02 << 7) - num) / (Q02 << 8));
                        if (Al > 0 && pred >= (1 << Al))
                            pred = (1 << Al) - 1;
                        pred = -pred;
                    }
                    workspace[2] = (JCOEF) pred;
                }
                /* OK, do the IDCT */
                (*inverse_DCT)(cinfo, compptr, (JCOEFPTR) workspace,
                               output_ptr, output_col);
                /* Advance for next column */
                DC1 = DC2;
                DC2 = DC3;
                DC4 = DC5;
                DC5 = DC6;
                DC7 = DC8;
                DC8 = DC9;
                buffer_ptr++, prev_block_row++, next_block_row++;
                output_col += compptr->DCT_scaled_size;
            }
            output_ptr += compptr->DCT_scaled_size;
        }
    }

    if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
        return JPEG_ROW_COMPLETED;
    return JPEG_SCAN_COMPLETED;
}
METHODDEF void
smooth_coefficients (decompress_info_ptr cinfo,
		     jpeg_component_info *compptr,
		     JBLOCKROW above,
		     JBLOCKROW currow,
		     JBLOCKROW below,
		     JBLOCKROW output)
{
  QUANT_TBL_PTR Qptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
  long blocks_in_row = compptr->downsampled_width / DCTSIZE;
  long col;

  /* First, copy the block row as-is.
   * This takes care of the first & last blocks in the row, the top/bottom
   * special cases, and the higher-order coefficients in each block.
   */
  jcopy_block_row(currow, output, blocks_in_row);

  /* Now apply the smoothing calculation, but not to any blocks on the
   * edges of the image.
   */

  if (above != NULL && below != NULL) {
    for (col = 1; col < blocks_in_row-1; col++) {

      /* See section K.8 of the JPEG standard.
       *
       * As I understand it, this produces approximations
       * for the low frequency AC components, based on the
       * DC values of the block and its eight neighboring blocks.
       * (Thus it can't be used for blocks on the image edges.)
       */

      /* The layout of these variables corresponds to text and figure in K.8 */
      
      JCOEF DC1, DC2, DC3;
      JCOEF DC4, DC5, DC6;
      JCOEF DC7, DC8, DC9;
      
      long       AC01, AC02;
      long AC10, AC11;
      long AC20;
      
      DC1 = above [col-1][0];
      DC2 = above [col  ][0];
      DC3 = above [col+1][0];
      DC4 = currow[col-1][0];
      DC5 = currow[col  ][0];
      DC6 = currow[col+1][0];
      DC7 = below [col-1][0];
      DC8 = below [col  ][0];
      DC9 = below [col+1][0];
      
#define DIVIDE_256(x)	x = ( (x) < 0 ? -((128-(x))/256) : ((x)+128)/256 )
      
      AC01 = (36 * (DC4 - DC6));
      DIVIDE_256(AC01);
      AC10 = (36 * (DC2 - DC8));
      DIVIDE_256(AC10);
      AC20 = (9 * (DC2 + DC8 - 2*DC5));
      DIVIDE_256(AC20);
      AC11 = (5 * ((DC1 - DC3) - (DC7 - DC9)));
      DIVIDE_256(AC11);
      AC02 = (9 * (DC4 + DC6 - 2*DC5));
      DIVIDE_256(AC02);
      
      /* I think that this checks to see if the quantisation
       * on the transmitting side would have produced this
       * answer. If so, then we use our (hopefully better)
       * estimate.
       */

#define ABS(x)	((x) < 0 ? -(x) : (x))

#define COND_ASSIGN(_ac,_n,_z)   if ((ABS(output[col][_n] - (_ac))<<1) <= Qptr[_z]) output[col][_n] = (JCOEF) (_ac)

      COND_ASSIGN(AC01,  1, 1);
      COND_ASSIGN(AC02,  2, 5);
      COND_ASSIGN(AC10,  8, 2);
      COND_ASSIGN(AC11,  9, 4);
      COND_ASSIGN(AC20, 16, 3);
    }
  }
}