static void initialization (JPEG_ENCODER_STRUCTURE * jpeg, UINT32 image_format,UINT32 image_width, UINT32 image_height)
{
UINT16 mcu_width, mcu_height, bytes_per_pixel;
lcode = 0;
bitindex = 0;
jpeg->mcu_width = mcu_width = 16;
jpeg->horizontal_mcus = (UINT16) ((image_width + mcu_width - 1) >> 4);
jpeg->mcu_height = mcu_height = 8;
jpeg->vertical_mcus =
(UINT16) ((image_height + mcu_height - 1) >> 3);
bytes_per_pixel = 2;
read_format = read_422_format;
jpeg->rows_in_bottom_mcus =(UINT16) (image_height - (jpeg->vertical_mcus - 1) * mcu_height);
jpeg->cols_in_right_mcus =(UINT16) (image_width - (jpeg->horizontal_mcus - 1) * mcu_width);
jpeg->length_minus_mcu_width =(UINT16) ((image_width - mcu_width) * bytes_per_pixel);
jpeg->length_minus_width =(UINT16) ((image_width - jpeg->cols_in_right_mcus) * bytes_per_pixel);
jpeg->mcu_width_size = (UINT16) (mcu_width * bytes_per_pixel);
jpeg->offset =(UINT16) ((image_width * (mcu_height - 1) -(mcu_width - jpeg->cols_in_right_mcus)) * bytes_per_pixel);
jpeg->ldc1 = 0;
jpeg->ldc2 = 0;
jpeg->ldc3 = 0;
}
/* Multiply Quantization table with quality factor to get LQT and CQT */
void initialize_quantization_tables (UINT32 quality_factor)
{
UINT16 i, index;
UINT32 value;
UINT8 luminance_quant_table[] = {
16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13,
16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37,
56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78,
87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99
};
UINT8 chrominance_quant_table[] = {
17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26,
56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99
};
for (i = 0; i < 64; i++)
{
index = zigzag_table[i];
/* luminance quantization table * quality factor */
value = luminance_quant_table[i] * quality_factor;
value = (value + 0x200) >> 10;
if (value == 0)
value = 1;
else if (value > 255)
value = 255;
Lqt[index] = (UINT8) value;
ILqt[i] = DSP_Division (0x8000, value);
/* chrominance quantization table * quality factor */
value = chrominance_quant_table[i] * quality_factor;
value = (value + 0x200) >> 10;
if (value == 0)
value = 1;
else if (value > 255)
value = 255;
Cqt[index] = (UINT8) value;
ICqt[i] = DSP_Division (0x8000, value);
}
}
UINT8 * close_bitstream (UINT8 * output_ptr)
{
UINT16 i, count;
UINT8 * ptr;
if (bitindex > 0)
{
lcode <<= (32 - bitindex);
count = (bitindex + 7) >> 3;
ptr = (UINT8 *) & lcode + 3;
for (i = count; i > 0; i--)
{
if ((*output_ptr++ = *ptr--) == 0xff)
*output_ptr++ = 0;
}
}
// End of image marker
*output_ptr++ = 0xFF;
*output_ptr++ = 0xD9;
return output_ptr;
}
/* DCT for One block(8x8) */
static void DCT (INT16 * data)
{
UINT16 i;
INT32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
/* All values are shifted left by 10
and rounded off to nearest integer */
static const UINT16 c1 = 1420; /* cos PI/16 * root(2) */
static const UINT16 c2 = 1338; /* cos PI/8 * root(2) */
static const UINT16 c3 = 1204; /* cos 3PI/16 * root(2) */
static const UINT16 c5 = 805; /* cos 5PI/16 * root(2) */
static const UINT16 c6 = 554; /* cos 3PI/8 * root(2) */
static const UINT16 c7 = 283; /* cos 7PI/16 * root(2) */
static const UINT16 s1 = 3;
static const UINT16 s2 = 10;
static const UINT16 s3 = 13;
for (i = 8; i > 0; i--)
{
x8 = data[0] + data[7];
x0 = data[0] - data[7];
x7 = data[1] + data[6];
x1 = data[1] - data[6];
x6 = data[2] + data[5];
x2 = data[2] - data[5];
x5 = data[3] + data[4];
x3 = data[3] - data[4];
x4 = x8 + x5;
x8 -= x5;
x5 = x7 + x6;
x7 -= x6;
data[0] = (INT16) (x4 + x5);
data[4] = (INT16) (x4 - x5);
data[2] = (INT16) ((x8 * c2 + x7 * c6) >> s2);
data[6] = (INT16) ((x8 * c6 - x7 * c2) >> s2);
data[7] = (INT16) ((x0 * c7 - x1 * c5 + x2 * c3 - x3 * c1) >> s2);
data[5] = (INT16) ((x0 * c5 - x1 * c1 + x2 * c7 + x3 * c3) >> s2);
data[3] = (INT16) ((x0 * c3 - x1 * c7 - x2 * c1 - x3 * c5) >> s2);
data[1] = (INT16) ((x0 * c1 + x1 * c3 + x2 * c5 + x3 * c7) >> s2);
data += 8;
}
data -= 64;
for (i = 8; i > 0; i--)
{
x8 = data[0] + data[56];
x0 = data[0] - data[56];
x7 = data[8] + data[48];
x1 = data[8] - data[48];
x6 = data[16] + data[40];
x2 = data[16] - data[40];
x5 = data[24] + data[32];
x3 = data[24] - data[32];
x4 = x8 + x5;
x8 -= x5;
x5 = x7 + x6;
x7 -= x6;
data[0] = (INT16) ((x4 + x5) >> s1);
data[32] = (INT16) ((x4 - x5) >> s1);
data[16] = (INT16) ((x8 * c2 + x7 * c6) >> s3);
data[48] = (INT16) ((x8 * c6 - x7 * c2) >> s3);
data[56] = (INT16) ((x0 * c7 - x1 * c5 + x2 * c3 - x3 * c1) >> s3);
data[40] = (INT16) ((x0 * c5 - x1 * c1 + x2 * c7 + x3 * c3) >> s3);
data[24] = (INT16) ((x0 * c3 - x1 * c7 - x2 * c1 - x3 * c5) >> s3);
data[8] = (INT16) ((x0 * c1 + x1 * c3 + x2 * c5 + x3 * c7) >> s3);
data++;
}
}
/* multiply DCT Coefficients with Quantization table and store in ZigZag location */
void quantization (INT16 * const data, UINT16 * const quant_table_ptr)
{
INT16 i;
INT32 value;
for (i = 63; i >= 0; i--)
{
value = data[i] * quant_table_ptr[i];
value = (value + 0x4000) >> 15;
Temp[zigzag_table[i]] = (INT16) value;
}
}
//huffman算法
UINT8 * huffman (JPEG_ENCODER_STRUCTURE * jpeg_encoder_structure,UINT16 component, UINT8 * output_ptr)
{
UINT16 i;
UINT16 * DcCodeTable, *DcSizeTable, *AcCodeTable, *AcSizeTable;
INT16 * Temp_Ptr, Coeff, LastDc;
UINT16 AbsCoeff, HuffCode, HuffSize, RunLength = 0, DataSize = 0, index;
INT16 bits_in_next_word;
UINT16 numbits;
UINT32 data;
Temp_Ptr = Temp;
Coeff = *Temp_Ptr++;
if (component == 1)
{
DcCodeTable = luminance_dc_code_table;
DcSizeTable = luminance_dc_size_table;
AcCodeTable = luminance_ac_code_table;
AcSizeTable = luminance_ac_size_table;
LastDc = jpeg_encoder_structure->ldc1;
jpeg_encoder_structure->ldc1 = Coeff;
}
else
{
DcCodeTable = chrominance_dc_code_table;
DcSizeTable = chrominance_dc_size_table;
AcCodeTable = chrominance_ac_code_table;
AcSizeTable = chrominance_ac_size_table;
if (component == 2)
{
LastDc = jpeg_encoder_structure->ldc2;
jpeg_encoder_structure->ldc2 = Coeff;
}
else
{
LastDc = jpeg_encoder_structure->ldc3;
jpeg_encoder_structure->ldc3 = Coeff;
}
}
Coeff -= LastDc;
AbsCoeff = (Coeff < 0) ? -Coeff-- : Coeff;
while (AbsCoeff != 0)
{
AbsCoeff >>= 1;
DataSize++;
}
HuffCode = DcCodeTable[DataSize];
HuffSize = DcSizeTable[DataSize];
Coeff &= (1 << DataSize) - 1;
data = (HuffCode << DataSize) | Coeff;
numbits = HuffSize + DataSize;
//PUTBITS
{
bits_in_next_word = (INT16) (bitindex + numbits - 32);
if (bits_in_next_word < 0)
{
lcode = (lcode << numbits) | data;
bitindex += numbits;
}
else
{
lcode = (lcode << (32 - bitindex)) | (data >> bits_in_next_word);
if ((*output_ptr++ = (UINT8) (lcode >> 24)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 16)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 8)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) lcode) == 0xff)
*output_ptr++ = 0;
lcode = data;
bitindex = bits_in_next_word;
}
}
for (i = 63; i > 0; i--)
{
if ((Coeff = *Temp_Ptr++) != 0)
{
while (RunLength > 15)
{
RunLength -= 16;
data = AcCodeTable[161];
numbits = AcSizeTable[161];
//PUTBITS
{
bits_in_next_word = (INT16) (bitindex + numbits - 32);
if (bits_in_next_word < 0)
{
lcode = (lcode << numbits) | data;
bitindex += numbits;
}
else
{
lcode = (lcode << (32 - bitindex)) | (data >> bits_in_next_word);
if ((*output_ptr++ = (UINT8) (lcode >> 24)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 16)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 8)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) lcode) == 0xff)
*output_ptr++ = 0;
lcode = data;
bitindex = bits_in_next_word;
}
}
}
AbsCoeff = (Coeff < 0) ? -Coeff-- : Coeff;
if (AbsCoeff >> 8 == 0)
DataSize = bitsize[AbsCoeff];
else
DataSize = bitsize[AbsCoeff >> 8] + 8;
index = RunLength * 10 + DataSize;
HuffCode = AcCodeTable[index];
HuffSize = AcSizeTable[index];
Coeff &= (1 << DataSize) - 1;
data = (HuffCode << DataSize) | Coeff;
numbits = HuffSize + DataSize;
// PUTBITS
{
bits_in_next_word = (INT16) (bitindex + numbits - 32);
if (bits_in_next_word < 0)
{
lcode = (lcode << numbits) | data;
bitindex += numbits;
}
else
{
lcode = (lcode << (32 - bitindex)) | (data >> bits_in_next_word);
if ((*output_ptr++ = (UINT8) (lcode >> 24)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 16)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 8)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) lcode) == 0xff)
*output_ptr++ = 0;
lcode = data;
bitindex = bits_in_next_word;
}
}
RunLength = 0;
}
else
RunLength++;
}
if (RunLength != 0)
{
data = AcCodeTable[0];
numbits = AcSizeTable[0];
// PUTBITS
{
bits_in_next_word = (INT16) (bitindex + numbits - 32);
if (bits_in_next_word < 0)
{
lcode = (lcode << numbits) | data;
bitindex += numbits;
}
else
{
lcode = (lcode << (32 - bitindex)) | (data >> bits_in_next_word);
if ((*output_ptr++ = (UINT8) (lcode >> 24)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 16)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) (lcode >> 8)) == 0xff)
*output_ptr++ = 0;
if ((*output_ptr++ = (UINT8) lcode) == 0xff)
*output_ptr++ = 0;
lcode = data;
bitindex = bits_in_next_word;
}
}
}
return output_ptr;
}
static UINT8 *encodeMCU (JPEG_ENCODER_STRUCTURE * jpeg_encoder_structure,UINT32 image_format, UINT8 * output_ptr)
{
DCT (Y1);
quantization (Y1, ILqt);
output_ptr = huffman (jpeg_encoder_structure, 1, output_ptr);
if (image_format == FOUR_ZERO_ZERO)
return output_ptr;
DCT (Y2);
quantization (Y2, ILqt);
output_ptr = huffman (jpeg_encoder_structure, 1, output_ptr);
if (image_format == FOUR_TWO_TWO)
goto chroma;
DCT (Y3);
quantization (Y3, ILqt);
output_ptr = huffman (jpeg_encoder_structure, 1, output_ptr);
DCT (Y4);
quantization (Y4, ILqt);
output_ptr = huffman (jpeg_encoder_structure, 1, output_ptr);
chroma:DCT (CB);
quantization (CB, ICqt);
output_ptr = huffman (jpeg_encoder_structure, 2, output_ptr);
DCT (CR);
quantization (CR, ICqt);
output_ptr = huffman (jpeg_encoder_structure, 3, output_ptr);
return output_ptr;
}
UINT32 encode_image (UINT8 * input_ptr, UINT8 * output_ptr,UINT32 quality_factor, UINT32 image_format,UINT32 image_width, UINT32 image_height)
{
UINT16 i, j;
UINT8 * output;
JPEG_ENCODER_STRUCTURE JpegStruct;
JPEG_ENCODER_STRUCTURE * jpeg_encoder_structure = &JpegStruct;
output = output_ptr;
image_format = FOUR_TWO_TWO;
RGB_2_422 (input_ptr, output_ptr, image_width, image_height);
/* Initialization of JPEG control structure */
initialization (jpeg_encoder_structure, image_format, image_width,
image_height);
/* Quantization Table Initialization */
initialize_quantization_tables (quality_factor);
/* Writing Marker Data */
output_ptr =
write_markers (output_ptr, image_format, image_width, image_height);
for (i = 1; i <= jpeg_encoder_structure->vertical_mcus; i++)
{
if (i < jpeg_encoder_structure->vertical_mcus)
jpeg_encoder_structure->rows = jpeg_encoder_structure->mcu_height;
else
jpeg_encoder_structure->rows =
jpeg_encoder_structure->rows_in_bottom_mcus;
for (j = 1; j <= jpeg_encoder_structure->horizontal_mcus; j++)
{
if (j < jpeg_encoder_structure->horizontal_mcus)
{
jpeg_encoder_structure->cols =
jpeg_encoder_structure->mcu_width;
jpeg_encoder_structure->incr =
jpeg_encoder_structure->length_minus_mcu_width;
}
else
{
jpeg_encoder_structure->cols =
jpeg_encoder_structure->cols_in_right_mcus;
jpeg_encoder_structure->incr =
jpeg_encoder_structure->length_minus_width;
}
read_format (jpeg_encoder_structure, input_ptr);
/* Encode the data in MCU */
output_ptr =encodeMCU (jpeg_encoder_structure, image_format, output_ptr);
input_ptr += jpeg_encoder_structure->mcu_width_size;
}
input_ptr += jpeg_encoder_structure->offset;
}
/* Close Routine */
output_ptr = close_bitstream (output_ptr);
return (UINT32) (output_ptr - output);
}
void main()
{
int size=1280*720*3,sizeout=0,x,y;
unsigned char *outpict ;
outpict = (unsigned char *) malloc (size);
unsigned char *inpict ;
inpict = (unsigned char *) malloc (size);
for(x=0;x<1280;x++)//inpict初始化成RGB模式
for (y=0;y<720;y++)
{
*(inpict+x*3+y*1280*3)=y%2;
*(inpict+x*3+y*1280*3+1)=x%2;
*(inpict+x*3+y*1280*3+2)=y%2;
}
sizeout = encode_image (inpict,outpict,1,0,1280,720);
free(outpict);
free(inpict);
return 1;
}
(dog0138) |