📄 djpeg.c
字号:
//////////////////////////////////////////////////////////////////////////////
// JPEG僨僐乕僪
// 2005擭10寧26擔 V1.0
// All Rights Reserved, Copyright (c) Hidemi Ishihara
//////////////////////////////////////////////////////////////////////////////
//
// JPEG傪擖椡偡傞偲Bitmap傪弌椡偟傑偡丅
//
// % gcc -o djpeg fjpeg.c
// % djpeg 擖椡僼傽僀儖柤丂弌椡僼傽僀儖柤
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
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惉暘梡偺挋傔僶僢僼傽
// 僕僌僓僌僥乕僽儖
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 long DWORD;
typedef long 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(unsigned 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;
}
//////////////////////////////////////////////////////////////////////////////
// 32bit僨乕僞庢摼(怢挿帪偺傒巊梡偡傞)
unsigned int get_data(unsigned char *buff){
unsigned char str = 0;
unsigned int data = 0;
str = get_byte(buff);
if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
data = str;
str = get_byte(buff);
if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
data = (data << 8) | str;
str = get_byte(buff);
if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
data = (data << 8) | str;
str = get_byte(buff);
if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
data = (data << 8) | str;
//printf(" Get Data: %08x\n",data);
return data;
}
//////////////////////////////////////////////////////////////////////////////
// APP0張棟
void GetAPP0(unsigned char *buff){
unsigned short data;
unsigned char str;
unsigned int i;
data = get_word(buff); // Lp(儗儞僌僗)
// APP0偼撉傑側偔偰傕偄偄偺偱庢傝崌偊偢儗儞僌僗暘僗僉僢僾偡傞
for(i=0;i<data-2;i++){
str = get_byte(buff);
}
/*
str = get_byte(buff); // 幆暿巕(5暥帤,"JFIF"偲[00])
str = get_byte(buff);
str = get_byte(buff);
str = get_byte(buff);
str = get_byte(buff);
data = get_word(buff); // 僶乕僕儑儞
str = get_byte(buff); // 夝憸搙偺扨埵
data = get_word(buff); // 墶曽岦偺夝憸搙
data = get_word(buff); // 廲曽岦偺夝憸搙
data = get_word(buff); // 僒儉僱僀儖偺墶僺僋僙儖悢
data = get_word(buff); // 僒儉僱僀儖偺廲僺僋僙儖悢
data = get_word(buff); // 僒儉僱僀儖僨乕僞(偁傞応崌偩偗)
*/
}
//////////////////////////////////////////////////////////////////////////////
// DQT張棟
void GetDQT(unsigned char *buff){
unsigned short data;
unsigned char str;
unsigned int i;
unsigned int tablenum;
data = get_word(buff);
str = get_byte(buff); // 僥乕僽儖斣崋
//printf("*** DQT Table %d\n",str);
for(i=0;i<64;i++){
TableDQT[str][i] = get_byte(buff);
//printf(" %2d: %2x\n",i,TableDQT[str][i]);
}
}
//////////////////////////////////////////////////////////////////////////////
// DHT張棟
void GetDHT(unsigned char *buff){
unsigned short data;
unsigned char str;
unsigned int i;
unsigned char max,count;
unsigned short ShiftData = 0x8000,HuffmanData =0x0000;
unsigned int tablenum;
data = get_word(buff);
str = get_byte(buff);
switch(str){
case 0x00:
tablenum = 0x00;
break;
case 0x10:
tablenum = 0x01;
break;
case 0x01:
tablenum = 0x02;
break;
case 0x11:
tablenum = 0x03;
break;
}
//printf("*** DHT Table/Number %d\n",tablenum);
// 僥乕僽儖傪嶌惉偡傞
max = 0;
for(i=0;i<16;i++){
count = get_byte(buff);
TableHT[tablenum][i] = HuffmanData;
TableHN[tablenum][i] = max;
//printf(" %2d: %4x,%2x\n",i,TableHT[tablenum][i],TableHN[tablenum][i]);
max = max + count;
while(!(count==0)){
HuffmanData += ShiftData;
count--;
}
ShiftData = ShiftData >> 1; // 塃偵1bit僔僼僩偡傞
}
//printf("*** DHT Table %d\n",tablenum);
for(i=0;i<max;i++){
TableDHT[tablenum][i] = get_byte(buff);
//printf(" %2d: %2x\n",i,TableDHT[tablenum][i]);
}
}
//////////////////////////////////////////////////////////////////////////////
// SOF張棟
void GetSOF(unsigned char *buff){
unsigned short data;
unsigned char str;
unsigned int i;
unsigned char count;
data = get_word(buff);
str = get_byte(buff);
BuffY = get_word(buff); // 夋憸偺墶僒僀僘
BuffX = get_word(buff); // 夋憸偺廲僒僀僘
count = get_byte(buff); // 僨乕僞偺僐儞億乕僱儞僩悢
for(i=0;i<count;i++){
str = get_byte(buff); // 僐儞億乕僱儞僩斣崋
str = get_byte(buff); // 僒儞僾儕儞僌斾棪
str = get_byte(buff); // DQT僥乕僽儖斣崋
}
// MCU偺僒僀僘傪嶼弌偡傞
BuffBlockX = (int)(BuffX /16);
if(BuffX % 16 >0) BuffBlockX++;
BuffBlockY = (int)(BuffY /16);
if(BuffY % 16 >0) BuffBlockY++;
Buff = (unsigned char*)malloc(BuffBlockY*16*BuffBlockX*16*3);
//printf(" size : %d x %d,(%d x %d)\n",BuffX,BuffY,BuffBlockX,BuffBlockY);
}
//////////////////////////////////////////////////////////////////////////////
// SOS張棟
void GetSOS(unsigned char *buff){
unsigned short data;
unsigned char str;
unsigned int i;
unsigned char count;
data = get_word(buff);
count = get_byte(buff);
for(i=0;i<count;i++){
str = get_byte(buff);
str = get_byte(buff);
}
str = get_byte(buff);
str = get_byte(buff);
str = get_byte(buff);
}
//////////////////////////////////////////////////////////////////////////////
// 僴僼儅儞僨僐乕僪亄媡検巕壔亄媡僕僌僓僌
void HuffmanDecode(unsigned char *buff, unsigned char table, int *BlockData){
unsigned int data;
unsigned char zero;
unsigned short code,huffman;
unsigned char count =0;
unsigned int BitData;
unsigned int i;
unsigned char tabledqt,tabledc,tableac,tablen;
unsigned char ZeroCount,DataCount;
int DataCode;
for(i=0;i<64;i++) BlockData[i] = 0x0; // 僨乕僞偺儕僙僢僩
// 僥乕僽儖斣崋傪愝掕偡傞
if(table ==0x00){
tabledqt =0x00;
tabledc =0x00;
tableac =0x01;
}else if(table ==0x01){
tabledqt =0x01;
tabledc =0x02;
tableac =0x03;
}else{
tabledqt =0x01;
tabledc =0x02;
tableac =0x03;
}
count = 0; // 擮偺偨傔偵
while(count <64){
// 價僢僩僇僂儞僩偺埵抲偑32傪墇偊偨応崌丄怴偨偵僨乕僞傪庢摼偡傞
if(BitCount >=32){
LineData = NextData;
NextData = get_data(buff);
BitCount -= 32;
}
// Huffman僨僐乕僪偱巊梡偡傞僨乕僞偵抲偒姺偊傞
if(BitCount >0){
BitData = (LineData << BitCount) | (NextData >> (32 - BitCount));
}else{
BitData = LineData;
}
//printf(" Haffuman BitData(%2d,%2d): %8x\n",table,count,BitData);
// 巊梡偡傞僥乕僽儖偺僙儗僋僩
if(count ==0) tablen = tabledc; else tablen = tableac;
code = (unsigned short)(BitData >> 16); // 僐乕僪偼16價僢僩巊梡偡傞
// 僴僼儅儞僐乕僪偑偳偺價僢僩悢偵偄傞偐妱傝弌偡
for(i=0;i<16;i++) {
//printf(" Haff hit(%2d:%2d): %8x,%8x\n",table,i,TableHT[tablen][i],code);
if(TableHT[tablen][i]>code) break;
}
i--;
code = (unsigned short)(code >> (15 - i)); // 僐乕僪偺壓埵傪懙偊傞
huffman = (unsigned short)(TableHT[tablen][i] >> (15 - i));
//printf(" PreUse Dht Number(%2d): %8x,%8x,%8x\n",i,code,huffman,TableHN[tablen][i]);
// 僴僼儅儞僥乕僽儖偺応強傪嶼弌偡傞
code = code - huffman + TableHN[tablen][i];
//printf(" Use Dht Number: %8x\n",code);
ZeroCount = (TableDHT[tablen][code] >> 4) & 0x0F; // 僛儘儗儞僌僗偺屄悢
DataCount = (TableDHT[tablen][code]) & 0x0F; // 懕偔僨乕僞偺價僢僩挿
//printf(" Dht Table: %8x,%8x\n",ZeroCount,DataCount);
// 僴僼儅儞僐乕僪傪敳偒丄懕偔僨乕僞傪庢摼偡傞
DataCode = (BitData << (i + 1)) >> (16 + (16 - DataCount));
// 愭摢價僢僩偑"0"偱偁傟偽晧偺僨乕僞丄忋埵價僢僩偵侾傪棫偰偰丄侾傪懌偡
//if(!(DataCode & (1<<(DataCount-1)))) DataCode=DataCode-(1<<DataCount)+1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -