// JPEG解码
// 输入JPEG后输出Bitmap
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable : 4996)
unsigned int BuffIndex; // JPEG数据的位置
unsigned int BuffSize; // JPEG数据的大小
unsigned int BuffX; // 图像的横向尺寸
unsigned int BuffY; // 图像的垂直尺寸
unsigned int BuffBlockX; // 横向MCU个数
unsigned int BuffBlockY; // 纵向MCU个数
unsigned char *Buff; // 装入解压数据的缓冲器
unsigned char TableDQT[4][64]; // 量化表
unsigned short TableDHT[4][162]; // 霍夫曼表格
unsigned short TableHT[4][16]; // 霍夫曼起始表
unsigned char TableHN[4][16]; // 霍夫曼起始号
unsigned char BitCount = 0; // 压缩数据的读取位置
unsigned int LineData; // 解压缩时使用的数据
unsigned int NextData; // 解压缩时使用的数据
unsigned int PreData[3]; // 用于DC分量的储存缓冲器
unsigned char CompCount; // 组件数
unsigned char CompNum[4]; // 组件号(未使用)
unsigned char CompSample[4];
unsigned char CompDQT[4]; // 组件的DQT表号
unsigned char CompDHT[4]; // 组件的DHT表号
unsigned char CompSampleX, CompSampleY;
// 反Zig-Zag表
int zigzag_table[]={
0 , 1, 8, 16, 9 , 2 , 3 , 10,
17, 24,32, 25, 18, 11, 4 , 5,
12, 19,26, 33, 40, 48, 41, 34,
27, 20,13, 6 , 7 , 14, 21, 28,
35, 42,49, 56, 57, 50, 43, 36,
29, 22,15, 23, 30, 37, 44, 51,
58, 59,52, 45, 38, 31, 39, 46,
53, 60,61, 54, 47, 55, 62, 63, 0
};
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef int LONG;
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
//////////////////////////////////////////////////////////////////////////////
// Bitmap输出
// file: 文件名称
// x,y: 图像的尺寸
// b: 字节计数(1个点的字节数)
//////////////////////////////////////////////////////////////////////////////
void BmpSave(char *file,unsigned char *buff,unsigned int x,unsigned int y,unsigned int b)
{
BITMAPFILEHEADER lpBf;
BITMAPINFOHEADER lpBi;
unsigned char tbuff[4];
FILE *fp;
unsigned char str;
int i,k;
if((fp = fopen(file,"wb")) == NULL)
{
perror(0);
exit(0);
}
// 文件现在的设定
tbuff[0] = 'B';
tbuff[1] = 'M';
fwrite(tbuff,2,1,fp);
tbuff[3] = ((14 +40 +x *y *b) >> 24) & 0xff;
tbuff[2] = ((14 +40 +x *y *b) >> 16) & 0xff;
tbuff[1] = ((14 +40 +x *y *b) >> 8) & 0xff;
tbuff[0] = ((14 +40 +x *y *b) >> 0) & 0xff;
fwrite(tbuff,4,1,fp);
tbuff[1] = 0;
tbuff[0] = 0;
fwrite(tbuff,2,1,fp);
fwrite(tbuff,2,1,fp);
tbuff[3] = 0;
tbuff[2] = 0;
tbuff[1] = 0;
tbuff[0] = 54;
fwrite(tbuff,4,1,fp);
// 信息的设定
lpBi.biSize = 40;
lpBi.biWidth = x;
lpBi.biHeight = y;
lpBi.biPlanes = 1;
lpBi.biBitCount = b*8;
lpBi.biCompression = 0;
lpBi.biSizeImage = x*y*b;
lpBi.biXPelsPerMeter = 300;
lpBi.biYPelsPerMeter = 300;
lpBi.biClrUsed = 0;
lpBi.biClrImportant = 0;
fwrite(&lpBi,1,40,fp);
// 上下反转
for(k=0;k<y/2;k++)
{
for(i=0;i<x*3;i++)
{
str = buff[k*x*3+i];
buff[k*x*3+i] = buff[((y-1)*x*3 -k*x*3) +i];
buff[((y-1)*x*3-k*x*3) +i] = str;
}
}
fwrite(buff,1,x*y*b,fp);
fclose(fp);
}
// 1Byte取得
unsigned char get_byte(unsigned char *buff)
{
if(BuffIndex >= BuffSize) return 0;
return buff[BuffIndex++];
}
//////////////////////////////////////////////////////////////////////////////
// 2Byte取得
unsigned short get_word(unsigned char *buff)
{
unsigned char h,l;
h = get_byte(buff);
l = get_byte(buff);
return (h<<8)|l;
}
// 32位数据取得(仅在解压缩时使用)
unsigned int get_data(unsigned char *buff)
{
unsigned char str = 0;
unsigned
二、基于C语言的JPEG解码代码详解
最新推荐文章于 2024-05-10 11:43:36 发布
本文详细介绍了一种从JPEG格式图像解码至Bitmap的过程。包括读取JPEG数据、解析JPEG的头部信息、处理如DQT、DHT等关键字段、进行Huffman解码、逆量化及逆DCT变换,最终实现从JPEG到Bitmap的完整转换流程。

最低0.47元/天 解锁文章
1186

被折叠的 条评论
为什么被折叠?



