⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jcdctmgr.c

📁 jpeg编解码器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * jcdctmgr.c * * Copyright (C) 1994-1996, 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 forward-DCT management logic. * This code selects a particular DCT implementation to be used, * and it performs related housekeeping chores including coefficient * quantization. */#define JPEG_INTERNALS#include "jinclude.h"#include "jpeglib.h"#include "jdct.h"		/* Private declarations for DCT subsystem */#include "cpu_accel.h"#include "mmx.h"/* Private subobject for this module */typedef enum { QUANT_INT,					/* Integer quantiser requiring scaling */  QUANT_INT16,					/* Fast unscaled integer quantiser */  QUANT_FLOAT32					/* Fast unscaler float quantiser  */} quant_kind;typedef struct {  struct jpeg_forward_dct pub;	/* public fields */	/* Pointer to the DCT routine actually in use */	forward_DCT_method_ptr do_dct;	float32_quant_method_ptr do_float32_quant;	quant_kind fast_quantiser;	/* The actual post-DCT divisors --- not identical to the quant table	 * entries, because of scaling (especially for an unnormalized DCT).	 * Each table is given in normal array order.	 */	DCTELEM * divisors[NUM_QUANT_TBLS];	UINT16 *int16_divisors[NUM_QUANT_TBLS];	FLOAT32 *float32_divisors[NUM_QUANT_TBLS];	unsigned int shift;#ifdef DCT_FLOAT_SUPPORTED	/* Same as above for the floating-point case. */	float_DCT_method_ptr do_float_dct;	FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];#endif} my_fdct_controller;typedef my_fdct_controller * my_fdct_ptr;METHODDEF(UINT8*)	simd_aligned_smallbuf( j_compress_ptr cinfo,						   size_t bufsize ){	UINT8 *rawbuf = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, 												JPOOL_IMAGE,												bufsize+SIMD_ALIGN );	unsigned int odd_bytes = ((size_t)rawbuf)%SIMD_ALIGN;	return odd_bytes == 0 ? rawbuf : rawbuf + SIMD_ALIGN-odd_bytes;	}/* * Initialize for a processing pass. * Verify that all referenced Q-tables are present, and set up * the divisor table for each one. * In the current implementation, DCT of all components is done during * the first pass, even if only some components will be output in the * first scan.  Hence all components should be examined here. */METHODDEF(void)start_pass_fdctmgr (j_compress_ptr cinfo){	my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;	int ci, qtblno, i;	jpeg_component_info *compptr;	JQUANT_TBL * qtbl;	DCTELEM * dtbl;	UINT16 *idtbl;	FAST_FLOAT * fdtbl;  	for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;		 ci++, compptr++) {		qtblno = compptr->quant_tbl_no;		/* Make sure specified quantization table is present */		if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||			cinfo->quant_tbl_ptrs[qtblno] == NULL)			ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);		qtbl = cinfo->quant_tbl_ptrs[qtblno];		/* Compute divisors for this quant table */		/* We may do this more than once for same table, but it's not a big deal */		switch (cinfo->dct_method) {#ifdef DCT_ISLOW_SUPPORTED		case JDCT_ISLOW:			/* For LL&M IDCT method, divisors are equal to raw quantization			 * coefficients multiplied by 8 (to counteract scaling).			 */			if (fdct->divisors[qtblno] == NULL) {				fdct->divisors[qtblno] = (DCTELEM *)					(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,												DCTSIZE2 * SIZEOF(DCTELEM));			}			dtbl = fdct->divisors[qtblno];			for (i = 0; i < DCTSIZE2; i++) {				dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;			}			break;#endif#ifdef DCT_IFAST_SUPPORTED		case JDCT_IFAST:		{			/* For AA&N IDCT method, divisors are equal to quantization			 * coefficients scaled by scalefactor[row]*scalefactor[col], where			 *   scalefactor[0] = 1			 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7			 * We apply a further scale factor of 8.			 */#define CONST_BITS 14			static const INT16 aanscales[DCTSIZE2] = {				/* precomputed values scaled up by 14 bits */				16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,				22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,				21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,				19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,				16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,				12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,				8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,				4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247			};			SHIFT_TEMPS;			/* Allocate arrays of quantisation factors for the various			 * kinds of fast quantiser			 */			switch( fdct->fast_quantiser)			{			case QUANT_INT16 :				if (fdct->int16_divisors[qtblno] == NULL) {					fdct->int16_divisors[qtblno] = (INT16 *)						simd_aligned_smallbuf( cinfo, DCTSIZE2 * SIZEOF(INT16));				}			case QUANT_INT :				if (fdct->divisors[qtblno] == NULL) {					fdct->divisors[qtblno] = (DCTELEM *)						simd_aligned_smallbuf( cinfo, DCTSIZE2 * SIZEOF(DCTELEM));				}				break;			case QUANT_FLOAT32 :				if (fdct->float32_divisors[qtblno] == NULL) {					fdct->float32_divisors[qtblno] = (FLOAT32 *)						simd_aligned_smallbuf( cinfo, DCTSIZE2 * SIZEOF(FLOAT32) );				}				break;			}			dtbl = fdct->divisors[qtblno];			idtbl = fdct->int16_divisors[qtblno];			fdtbl = fdct->float32_divisors[qtblno];			switch( fdct->fast_quantiser )			{			case QUANT_INT :				for (i = 0; i < DCTSIZE2; i++) 				{					dtbl[i] = (DCTELEM)						DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],											  (INT32) aanscales[i]),								CONST_BITS-3);				}				break;			case QUANT_INT16 :			{				int overflow = 0;				unsigned int scalebase = 1<<17;				unsigned int shift = 4;				unsigned int divprod;				for (i = 0; i < DCTSIZE2; i++) 				{				restart:					divprod = scalebase/qtbl->quantval[i];					/*					  Rescale product coefficients if quantisation is too					  low					*/										if( divprod >= (1U<<15) )					{						i = 0;						--shift;						scalebase = (scalebase >> 1);						goto restart;					}					idtbl[i] = (UINT16)divprod;					dtbl[i] = qtbl->quantval[i];				}				fdct->shift = shift;				break;			}			case QUANT_FLOAT32 :				for (i = 0; i < DCTSIZE2; i++) 				{					fdtbl[i] = 1.0f/((FLOAT32)(qtbl->quantval[i]<<3));				}				break;			}		}		break;#endif#ifdef DCT_FLOAT_SUPPORTED		case JDCT_FLOAT:		{			/* For float AA&N IDCT method, divisors are equal to quantization			 * coefficients scaled by scalefactor[row]*scalefactor[col], where			 *   scalefactor[0] = 1			 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7			 * We apply a further scale factor of 8.			 * What's actually stored is 1/divisor so that the inner loop can			 * use a multiplication rather than a division.			 */			FAST_FLOAT * fdtbl;			int row, col;			static const double aanscalefactor[DCTSIZE] = {				1.0, 1.387039845, 1.306562965, 1.175875602,				1.0, 0.785694958, 0.541196100, 0.275899379			};			if (fdct->float_divisors[qtblno] == NULL) {				fdct->float_divisors[qtblno] = (FAST_FLOAT *)					(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,												DCTSIZE2 * SIZEOF(FAST_FLOAT));			}			fdtbl = fdct->float_divisors[qtblno];			i = 0;			for (row = 0; row < DCTSIZE; row++) {				for (col = 0; col < DCTSIZE; col++) {					fdtbl[i] = (FAST_FLOAT)						(1.0 / (((double) qtbl->quantval[i] *								 aanscalefactor[row] * aanscalefactor[col] * 8.0)));					i++;				}			}		}		break;#endif		default:			ERREXIT(cinfo, JERR_NOT_COMPILED);			break;		}	}}static INT16 int16_centrejsample[8] ATTR_ALIGN(8) = { CENTERJSAMPLE, CENTERJSAMPLE,CENTERJSAMPLE, CENTERJSAMPLE,  CENTERJSAMPLE, CENTERJSAMPLE,CENTERJSAMPLE, CENTERJSAMPLE};METHODDEF(void)jcquant_int16( DCTELEM *workspace, INT16 *output_ptr,  			   DCTELEM *divisors, INT16 *idivisors){ 	register int temp;	register int i;	for (i = 0; i < DCTSIZE2; i++) {		temp = workspace[i];		/* Divide the coefficient value by qval, ensuring proper rounding.		 * Since C does not specify the direction of rounding for negative		 * quotients, we have to force the dividend positive for portability.		 */		if (temp < 0) {			temp = -temp;			temp += divisors[i]>>1;	/* for rounding */			temp *= idivisors[i];			temp = -(temp+(1<<(16+2))>>(16+3));		} else {			temp += divisors[i]>>1;	/* for rounding */			temp *= idivisors[i];			temp = (temp+(1<<(16+2)))>>(16+3);					}		output_ptr[i] = (JCOEF) temp;	}}METHODDEF(void)jcquant_int( DCTELEM *workspace, INT16 *output_ptr,  DCTELEM *divisors ){ 	register DCTELEM temp, qval;	register int i;	for (i = 0; i < DCTSIZE2; i++) {		qval = divisors[i];		temp = workspace[i];		/* Divide the coefficient value by qval, ensuring proper rounding.		 * Since C does not specify the direction of rounding for negative		 * quotients, we have to force the dividend positive for portability.		 *		 * In most files, at least half of the output values will be zero		 * (at default quantization settings, more like three-quarters...)		 * so we should ensure that this case is fast.  On many machines,		 * a comparison is enough cheaper than a divide to make a special test		 * a win.  Since both inputs will be nonnegative, we need only test		 * for a < b to discover whether a/b is 0.		 * If your machine's division is fast enough, define FAST_DIVIDE.		 */#ifdef FAST_DIVIDE#define DIVIDE_BY(a,b)	a /= b#else#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0#endif		if (temp < 0) {			temp = -temp;			temp += qval>>1;	/* for rounding */			DIVIDE_BY(temp, qval);			temp = -temp;		} else {			temp += qval>>1;	/* for rounding */			DIVIDE_BY(temp, qval);		}		output_ptr[i] = (JCOEF) temp;	}}/* * Perform forward DCT on one or more blocks of a component. * * The input samples are taken from the sample_data[] array starting at * position start_row/start_col, and moving to the right for any additional * blocks. The quantized coefficients are returned in coef_blocks[]. */METHODDEF(void)forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,	     JDIMENSION start_row, JDIMENSION start_col,	     JDIMENSION num_blocks)/* This version is used for integer DCT implementations. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -