// A BMP truecolor to JPEG encoder
// Copyright 1999 Cristi Cuturicu
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jtypes.h"
#include "jglobals.h"
#include "jtables.h"
void write_APP0info()
//Nothing to overwrite for APP0info
{
writeword(APP0info.marker);
writeword(APP0info.length);
writebyte('J');writebyte('F');writebyte('I');writebyte('F');writebyte(0);
writebyte(APP0info.versionhi);writebyte(APP0info.versionlo);
writebyte(APP0info.xyunits);
writeword(APP0info.xdensity);writeword(APP0info.ydensity);
writebyte(APP0info.thumbnwidth);writebyte(APP0info.thumbnheight);
}
void write_SOF0info()
// We should overwrite width and height
{
writeword(SOF0info.marker);
writeword(SOF0info.length);
writebyte(SOF0info.precision);
writeword(SOF0info.height);writeword(SOF0info.width);
writebyte(SOF0info.nrofcomponents);
writebyte(SOF0info.IdY);writebyte(SOF0info.HVY);writebyte(SOF0info.QTY);
writebyte(SOF0info.IdCb);writebyte(SOF0info.HVCb);writebyte(SOF0info.QTCb);
writebyte(SOF0info.IdCr);writebyte(SOF0info.HVCr);writebyte(SOF0info.QTCr);
}
void write_DQTinfo()
{
BYTE i;
writeword(DQTinfo.marker);
writeword(DQTinfo.length);
writebyte(DQTinfo.QTYinfo);for (i=0;i<64;i++) writebyte(DQTinfo.Ytable[i]);
writebyte(DQTinfo.QTCbinfo);for (i=0;i<64;i++) writebyte(DQTinfo.Cbtable[i]);
}
void set_quant_table(BYTE *basic_table,BYTE scale_factor,BYTE *newtable)
// Set quantization table and zigzag reorder it
{
BYTE i;
long temp;
for (i = 0; i < 64; i++) {
temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
/* limit the values to the valid range */
if (temp <= 0L) temp = 1L;
if (temp > 255L) temp = 255L; /* limit to baseline range if requested */
newtable[zigzag[i]] = (WORD) temp;
}
}
void set_DQTinfo()
{
BYTE scalefactor=50;// scalefactor controls the visual quality of the image
// the smaller is, the better image we'll get, and the smaller
// compression we'll achieve
DQTinfo.marker=0xFFDB;
DQTinfo.length=132;
DQTinfo.QTYinfo=0;
DQTinfo.QTCbinfo=1;
set_quant_table(std_luminance_qt,scalefactor,DQTinfo.Ytable);
set_quant_table(std_chrominance_qt,scalefactor,DQTinfo.Cbtable);
}
void write_DHTinfo()
{
BYTE i;
writeword(DHTinfo.marker);
writeword(DHTinfo.length);
writebyte(DHTinfo.HTYDCinfo);
for (i=0;i<16;i++) writebyte(DHTinfo.YDC_nrcodes[i]);
for (i=0;i<=11;i++) writebyte(DHTinfo.YDC_values[i]);
writebyte(DHTinfo.HTYACinfo);
for (i=0;i<16;i++) writebyte(DHTinfo.YAC_nrcodes[i]);
for (i=0;i<=161;i++) writebyte(DHTinfo.YAC_values[i]);
writebyte(DHTinfo.HTCbDCinfo);
for (i=0;i<16;i++) writebyte(DHTinfo.CbDC_nrcodes[i]);
for (i=0;i<=11;i++) writebyte(DHTinfo.CbDC_values[i]);
writebyte(DHTinfo.HTCbACinfo);
for (i=0;i<16;i++) writebyte(DHTinfo.CbAC_nrcodes[i]);
for (i=0;i<=161;i++) writebyte(DHTinfo.CbAC_values[i]);
}
void set_DHTinfo()
{
BYTE i;
DHTinfo.marker=0xFFC4;
DHTinfo.length=0x01A2;
DHTinfo.HTYDCinfo=0;
for (i=0;i<16;i++) DHTinfo.YDC_nrcodes[i]=std_dc_luminance_nrcodes[i+1];
for (i=0;i<=11;i++) DHTinfo.YDC_values[i]=std_dc_luminance_values[i];
DHTinfo.HTYACinfo=0x10;
for (i=0;i<16;i++) DHTinfo.YAC_nrcodes[i]=std_ac_luminance_nrcodes[i+1];
for (i=0;i<=161;i++) DHTinfo.YAC_values[i]=std_ac_luminance_values[i];
DHTinfo.HTCbDCinfo=1;
for (i=0;i<16;i++) DHTinfo.CbDC_nrcodes[i]=std_dc_chrominance_nrcodes[i+1];
for (i=0;i<=11;i++) DHTinfo.CbDC_values[i]=std_dc_chrominance_values[i];
DHTinfo.HTCbACinfo=0x11;
for (i=0;i<16;i++) DHTinfo.CbAC_nrcodes[i]=std_ac_chrominance_nrcodes[i+1];
for (i=0;i<=161;i++) DHTinfo.CbAC_values[i]=std_ac_chrominance_values[i];
}
void write_SOSinfo()
//Nothing to overwrite for SOSinfo
{
writeword(SOSinfo.marker);
writeword(SOSinfo.length);
writebyte(SOSinfo.nrofcomponents);
writebyte(SOSinfo.IdY);writebyte(SOSinfo.HTY);
writebyte(SOSinfo.IdCb);writebyte(SOSinfo.HTCb);
writebyte(SOSinfo.IdCr);writebyte(SOSinfo.HTCr);
writebyte(SOSinfo.Ss);writebyte(SOSinfo.Se);writebyte(SOSinfo.Bf);
}
void write_comment(BYTE *comment)
{
WORD i,length;
writeword(0xFFFE); //The COM marker
length=strlen((const char *)comment);
writeword(length+2);
for (i=0;i<length;i++) writebyte(comment[i]);
}
void writebits(bitstring bs)
// A portable version; it should be done in assembler
{
WORD value;
SBYTE posval;//bit position in the bitstring we read, should be<=15 and >=0
value=bs.value;
posval=bs.length-1;
while (posval>=0)
{
if (value & mask[posval]) bytenew|=mask[bytepos];
posval--;bytepos--;
if (bytepos<0) { if (bytenew==0xFF) {writebyte(0xFF);writebyte(0);}
else {writebyte(bytenew);}
bytepos=7;bytenew=0;
}
}
}
void compute_Huffman_table(BYTE *nrcodes,BYTE *std_table,bitstring *HT)
{
BYTE k,j;
BYTE pos_in_table;
WORD codevalue;
codevalue=0; pos_in_table=0;
for (k=1;k<=16;k++)
{
for (j=1;j<=nrcodes[k];j++) {HT[std_table[pos_in_table]].value=codevalue;
HT[std_table[pos_in_table]].length=k;
pos_in_table++;
codevalue++;
}
codevalue*=2;
}
}
void init_Huffman_tables()
{
compute_Huffman_table(std_dc_luminance_nrcodes,std_dc_luminance_values,YDC_HT);
compute_Huffman_table(std_dc_chrominance_nrcodes,std_dc_chrominance_values,CbDC_HT);
compute_Huffman_table(std_ac_luminance_nrcodes,std_ac_luminance_values,YAC_HT);
compute_Huffman_table(std_ac_chrominance_nrcodes,std_ac_chrominance_values,CbAC_HT);
}
void exitmessage(char *error_message)
{
printf("%s\n",error_message);exit(EXIT_FAILURE);
}
void set_numbers_category_and_bitcode()
{
SDWORD nr;
SDWORD nrlower,nrupper;
BYTE cat,value;
category_alloc=(BYTE *)malloc(65535*sizeof(BYTE));
if (category_alloc==NULL) exitmessage("Not enough memory.");
category=category_alloc+32767; //allow negative subscripts
bitcode_alloc=(bitstring *)malloc(65535*sizeof(bitstring));
if (bitcode_alloc==NULL) exitmessage("Not enough memory.");
bitcode=bitcode_alloc+32767;
nrlower=1;nrupper=2;
for (cat=1;cat<=15;cat++) {
//Positive numbers
for (nr=nrlower;nr<nrupper;nr++)
{ category[nr]=cat;
bitcode[nr].length=cat;
bitcode[nr].value=(WORD)nr;
}
//Negative numbers
for (nr=-(nrupper-1);nr<=-nrlower;nr++)
{ category[nr]=cat;
bitcode[nr].length=cat;
bitcode[nr].value=(WORD)(nrupper-1+nr);
}
nrlower<<=1;
nrupper<<=1;
}
}
void precalculate_YCbCr_tables()
{
WORD R,G,B;
for (R=0;R<=255;R++) {YRtab[R]=(SDWORD)(65536*0.299+0.5)*R;
CbRtab[R]=(SDWORD)(65536*-0.16874+0.5)*R;
CrRtab[R]=(SDWORD)(32768)*R;
}
for (G=0;G<=255;G++) {YGtab[G]=(SDWORD)(65536*0.587+0.5)*G;
CbGtab[G]=(SDWORD)(65536*-0.33126+0.5)*G;
CrGtab[G]=(SDWORD)(65536*-0.41869+0.5)*G;
}
for (B=0;B<=255;B++) {YBtab[B]=(SDWORD)(65536*0.114+0.5)*B;
CbBtab[B]=(SDWORD)(32768)*B;
CrBtab[B]=(SDWORD)(65536*-0.08131+0.5)*B;
}
}
// Using a bit modified form of the FDCT routine from IJG's C source:
// Forward DCT routine idea taken from Independent JPEG Group's C source for
// JPEG encoders/decoders
/* 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. */
void prepare_quant_tables()
{
double aanscalefactor[8] = {1.0, 1.387039845, 1.306562965, 1.175875602,
1.0, 0.785694958, 0.541196100, 0.275899379};
BYTE row, col;
BYTE i = 0;
for (row = 0; row < 8; row++)
{
for (col = 0; col < 8; col++)
{
fdtbl_Y[i] = (float) (1.0 / ((double) DQTinfo.Ytable[zigzag[i]] *
aanscalefactor[
jpeg.rar_C语言JPEG_JPEG编码器
版权申诉
24 浏览量
2022-09-14
16:35:01
上传
评论
收藏 9KB RAR 举报
钱亚锋
- 粉丝: 88
- 资源: 1万+
最新资源
- 基于yolov8+dlib实现视觉识别的安全驾驶监测系统部署到jetson NX平台源码+模型.zip
- Qt框架+OpenCV+动态爱心+编程教学+520
- 基于opencv+yolov8实现目标追踪及驻留时长统计源码.zip
- 水稻病害基于Yolov8算法优化目标检测识别与AI辅助决策python源码+模型+使用说明.zip
- 海尔618算价表_七海5.20_16.00xlsx(1)(2).xlsx
- WebCrawler.scr
- 【计算机专业毕业设计】大学生就业信息管理系统设计源码.zip
- YOLO 数据集:8种路面缺陷病害检测【包含划分好的数据集、类别class文件、数据可视化脚本】
- JAVA实现Modbus RTU或Modbus TCPIP案例.zip
- 基于YOLOv8的FPS TPS AI自动锁定源码+使用步骤说明.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈