?? jcdctmgr.c
字號:
/*
* 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.
*/
#include "jpeg.h"
extern const int jpeg_zigzag_order[DCTSIZE2];
/* Quantize/descale the coefficients, and store into coef_blocks[] */
void jpeg_quant(short * data, WORD *multipliers, WORD *rounds)
{
short buffer[64];
int temp;
int i;
for (i = 0; i < DCTSIZE2; i++)
{
temp = data[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.
*/
#define DIVIDE_BY(a,b) (a = (((a+rounds[i])*multipliers[i]) >> 16))
if (temp < 0) {
temp = -temp;
DIVIDE_BY(temp, qval);
temp = -temp;
} else {
DIVIDE_BY(temp, qval);
}
buffer[jpeg_zigzag_order[i]] = (short) temp;
}
memcpy(data, buffer, 128);
}
/*
* Perform forward DCT on one or more blocks of a component.
* This version is used for integer DCT implementations.
* 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[].
*/
void forward_DCT(PBYTE sample_data, short *data,
WORD *multipliers, WORD *rounds, int width)
{
int i;
// 計算差分
for (i = 0; i < 8; i ++)
{
*data++ = sample_data[0] - CENTERJSAMPLE;
*data++ = sample_data[1] - CENTERJSAMPLE;
*data++ = sample_data[2] - CENTERJSAMPLE;
*data++ = sample_data[3] - CENTERJSAMPLE;
*data++ = sample_data[4] - CENTERJSAMPLE;
*data++ = sample_data[5] - CENTERJSAMPLE;
*data++ = sample_data[6] - CENTERJSAMPLE;
*data++ = sample_data[7] - CENTERJSAMPLE;
sample_data += width;
}
data -= 64;
/* Perform the DCT */
jpeg_fdct_islow_ti (data);
jpeg_quant(data, multipliers, rounds);
}
/*
* Compression initialization.
* Before calling this, all parameters and a data destination must be set up.
*
* We require a write_all_tables parameter as a failsafe check when writing
* multiple datastreams from the same compression object. Since prior runs
* will have left all the tables marked sent_table=TRUE, a subsequent run
* would emit an abbreviated stream (no tables) by default. This may be what
* is wanted, but for safety's sake it should not be the default behavior:
* programmers should have to make a deliberate choice to emit abbreviated
* images. Therefore the documentation and examples should encourage people
* to pass write_all_tables=TRUE; then it will take active thought to do the
* wrong thing.
*/
int jpeg_start_compress (j_compress_ptr cinfo, Bitstream *bs, int width, int height)
{
bs->ptr = bs->buffer;
/* Initialize bit buffer to empty */
bs->byte_buf = 0;
bs->cnt = 0;
/* Write the datastream header (SOI) immediately.
* Frame and scan headers are postponed till later.
* This lets application insert special markers after the SOI.
*/
return write_file_header(cinfo, bs, width, height);
}
/*
* Finish JPEG compression.
*
* If a multipass operating mode was selected, this may do a great deal of
* work including most of the actual output.
*/
int jpeg_finish_compress (Bitstream *bs)
{
/* The entropy coder always needs an end-of-pass call,
* either to analyze statistics or to flush its output buffer.
*/
finish_pass_huff(bs);
/* Write EOI, do final cleanup */
// Write datastream trailer.
write_file_trailer(bs);
return (bs->ptr - bs->buffer);
}
/*
* Process some data in the single-pass case.
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor block rows for each component in the image.
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
*
* NB: input_buf contains a plane for each component in image,
* which we index according to the component's SOF position.
*/
int JPEG_Compress(JPEG_COMPRESS_PARAM *cinfo, JPEG_IMAGE_PARAM *image)
{
short data[6][64];
int last_dc_val[3]; // last DC coef for each component
int pix_x, pix_y;
Bitstream bitstream;
unsigned short *rounds, *multipliers;
PBYTE imgY, imgU, imgV;
int width, height;
// check parameters
if(cinfo == NULL) return 0;
if(image == NULL) return 0;
if(image->bitstream == 0) return 0;
if(image->frame == 0) return 0;
if((image->width % 16) || (image->height % 16)) return 0;
// init
rounds = cinfo->rounds;
multipliers = cinfo->multipliers;
width = image->width;
height = image->height;
imgY = image->frame->y;
imgU = image->frame->u;
imgV = image->frame->v;
bitstream.buffer = image->bitstream;
bitstream.size = image->size;
// Start compressor
if(!jpeg_start_compress(cinfo, &bitstream, width, height))
{
return 0;
}
last_dc_val[0] = 0;
last_dc_val[1] = 0;
last_dc_val[2] = 0;
for(pix_y = 0; pix_y < height; pix_y += 16)
{
for(pix_x = 0; pix_x < width; pix_x += 16)
{
forward_DCT(imgY , data[0], multipliers, rounds, width);
forward_DCT(imgY+8 , data[1], multipliers, rounds, width);
forward_DCT(imgY+width*8 , data[2], multipliers, rounds, width);
forward_DCT(imgY+width*8+8, data[3], multipliers, rounds, width);
forward_DCT(imgU , data[4], multipliers+64, rounds+64, width/2);
forward_DCT(imgV , data[5], multipliers+64, rounds+64, width/2);
// Try to write the MCU. In event of a suspension failure, we will
// re-DCT the MCU on restart (a bit inefficient, could be fixed...)
encode_mcu_huff(cinfo, &bitstream, data, last_dc_val);
if(bitstream.ptr > bitstream.buffer + bitstream.size - 512)
{
//DebugPrint("\nERROR! bitstream over!\n");
return 0;
}
imgY += 16;
imgU += 8;
imgV += 8;
}
imgY += width*15;
imgU += width/2*7;
imgV += width/2*7;
}
image->length = jpeg_finish_compress(&bitstream);
return image->length;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -