衆所周知,bing搜尋網站首頁每日會更新一張圖檔,張張漂亮(額,也有一些不合我口味的),特别适合用來做電腦桌面。
我們想要将bing網站背景圖檔設定為電腦桌面背景的通常做法是:
- 上網,搜尋bing
- 找到圖檔的下載下傳連結,并下載下傳之
- 将圖檔設定為桌面背景(也有部分浏覽器支援直接在網頁中右擊圖檔設定為桌面)
- 可能你還會删除下載下傳下來的圖檔
作為一枚coder,你不會覺得麻煩嘛?至少需要三個步驟呢!
So...我就用C++語言寫了一個小程式,用于擷取bing網站的圖檔,并将其設定為桌面背景。整個過程隻需要點選.exe檔案,一鍵完成!
當然,你也可以通過本程式,窺見Windows API的些許用法,活學活用C++知識!
當然網上也存在片片斷斷的程式,我的部分程式也借鑒了它們的思想,在此感謝網際網路和辛勤的貢獻者們。
以下是程式設計的技術要點:
--------------------------------------------------------------
技術要點:
1、擷取網絡位址 直接使用網絡位址或下載下傳 注意若下載下傳下來後,要将\轉換為/,當然也可以用\\
網絡位址可以從這裡擷取:http://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1
在傳回的xml頁面中(images->image->url)找到具體的圖檔位址(xml解析),拼接到bing域名後面構成完整位址
注:xml解析用了TinyXml2
2、轉換圖檔格式(jpg->bmp),本程式中的SystemParametersInfoA函數隻支援bmp
在程式中自動轉換(單單改字尾名是沒有用的),轉換用的程式是從網上下載下傳的,用C語言編寫而成
考慮到需要改字尾名,那就直接下載下傳圖檔好了,順便存儲之
3、圖檔儲存路徑為C:/Users/Administrator/bingPicture/,格式為.jpg 友善以後浏覽
注意:部分使用者電腦可能不存在路徑C:/Users/Administrator/,造成程式無法執行,可以直接在C槽根目錄下建立路徑,如C:/bingPicture/
注意不儲存轉換後的bmp格式圖檔(設定背景後即删除),因為體積較大
判斷檔案夾是否存在,若不存在,則自動建立檔案夾
4、注意本程式擷取的圖檔尺寸是1366x768,若你的螢幕分辨率為1920x1080,還需要對Xml解析出來的圖檔Url位址進行字元串替換(将1366x768換成1920x1080即可)
前提:針對1920x1080尺寸的圖檔位址存在
5、若此程式若在國際網絡下運作,擷取的就是國際版bing桌面;若在國内網絡下運作,擷取的就是中國版bing桌面。是以在同一天内,在不同網絡環境下擷取的圖檔可能不同
*未實作的功能*:
1、擷取每日桌面的故事(利用bing故事接口) ,更新桌面後顯示在執行框中
2、開機自啟動,并隐藏到托盤中(為減少CPU占用并增加趣味性,設定為開機自動啟動,提示網絡連接配接,并輸入"go"才執行功能)
電腦若未關機,則在24:00自動啟動,更換背景
3、軟體自動更新版本功能
程式在文章後面提供,源碼已注釋很詳細,不再贅述。
注意,使用程式之前,務必看以下注意事項:
請注意:
1、本軟體使用Qt開發,您也可以将檔案加入自己的工程,使用其他IDE開發
需要注意的一點是,本軟體需要加入URLMON.DLL(源碼包中有)
2、本軟體開源(源碼位于xiaoxi666的部落格園以及github,不對其他位址給出的連結負責),僅用于學習交流,請勿用于商業用途
3、為防止軟體被加入惡意功能,不提供可執行檔案,若需使用請重新編譯,編譯器需要支援c++11
4、本軟體程式中内含删除臨時檔案功能,請在更改前仔細确認,避免路徑錯誤而删除其他重要檔案
然而許多小夥伴要體驗效果,我就一并把可執行檔案放出來吧(請勿随意傳播.exe檔案防止有人添加惡意功能。當然源碼開放可共享)
下載下傳區:
- 源碼
- 可執行檔案(可執行檔案中圖檔儲存位址為C:/bingPicture/)
但一定要注意核對檔案校驗碼(以保證安全):
- 可執行檔案壓縮包WallPaper校驗碼
MD5: 48173BA7DCF2120F2822226A5D4A90CF
SHA1: CEB0ED570AF613EC3829AC8FDE4F8C50DDEF4101
- 可執行檔案WallPaper_1366x768_Common校驗碼(此版本用于1366x768分辨率)
MD5: ACDA8E5E4CF0B2916254B233D1243FD3
SHA1: 6041C813DC8E2AE29EA8675EF279CFC0E7921D53
- 可執行檔案WallPaper_1920x1080_Common校驗碼(此版本用于1920x1080分辨率)
MD5: 474570808A56EFDC7B589F605D08C5B6
SHA1: B78921AD655B35F079076904A22F1A0E5122EB7F
為友善浏覽,貼出主要源程式:
main.cpp檔案
1 //main.cpp
2 /******************windows桌面背景更換C++程式***********************************************************
3 功能:擷取每日bing搜尋首頁圖檔,設定為當日桌面桌面。并将其下載下傳儲存至本地檔案夾友善以後浏覽
4 作者:xiaoxi666
5 日期:2017/03/12
6
7 技術要點:
8 1、擷取網絡位址 直接使用網絡位址或下載下傳 注意若下載下傳下來後,要将\轉換為/,當然也可以用\\
9 網絡位址可以從這裡擷取:http://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1
10 在傳回 的xml頁面中(images->image->url)找到具體的圖檔位址(xml解析),拼接到bing域名後面,構成完整位址
11 注:xml解析用了TinyXml2
12
13 2、轉換圖檔格式(jpg->bmp),本程式中的SystemParametersInfoA函數隻支援bmp
14 在程式中自動轉換(單單改字尾名是沒有用的),轉換用的程式是從網上下載下傳的,用C語言編寫而成
15 考慮到需要改字尾名,那就直接下載下傳圖檔好了,順便存儲之
16
17 3、圖檔儲存路徑為C:\bingPicture\,格式為.jpg 友善以後浏覽
18 注意不儲存轉換後的bmp格式圖檔(設定背景後即删除),因為體積較大
19 判斷檔案夾是否存在,若不存在,則自動建立檔案夾
20
21 *未實作的功能*:
22 ***擷取每日桌面的故事(利用bing故事接口) ,更新桌面後顯示在執行框中
23
24 ***開機自啟動,并隐藏到托盤中(為減少CPU占用并增加趣味性,設定為開機自動啟動,提示網絡連接配接,并輸入"go"才執行功能)
25 電腦若未關機,則在24:00自動啟動,更換背景
26
27 ***軟體自動更新版本功能
28
29 ******************************************************************************************************/
30
31 #include <iostream> //輸入輸出
32 #include <cstring> //檔案命名處理需要用字元串
33 #include <windows.h> //調用作業系統各種API
34 #include <ctime> //擷取時間,各種檔案命名
35 #include <UrlMon.h> //包含提供下載下傳服務的API
36 #include "tinyxml2.h" //解析XML
37 #include <io.h> //判斷檔案夾是否存在
38 #include <direct.h> //建立檔案夾
39 extern "C"
40 {
41 #include "jpeg.h" //轉換圖檔格式jpg->bmp 轉換格式的程式使用C語言寫的
42 }
43
44 //建立本地bingPicture路徑和Tmp路徑
45 void createDir()
46 {
47 //本地bingPicture路徑
48 std::string LocalFolder="C:/bingPicture/";
49
50 if(0!=access(LocalFolder.c_str(),0)) //判斷檔案夾是否存在,若不存在則建立
51 if(0!=mkdir(LocalFolder.c_str()))
52 std::cout<<"建立檔案夾bingPicture失敗!"<<std::endl;
53 else
54 std::cout<<"建立檔案夾bingPicture成功!"<<std::endl;
55 else
56 std::cout<<"檔案夾bingPicture已存在!"<<std::endl;
57
58 //本地Tmp路徑
59 std::string LocalXmlFolder="C:/bingPicture/Tmp/";
60
61 if(0!=access(LocalXmlFolder.c_str(),0)) //判斷檔案夾是否存在,若不存在則建立
62 if(0!=mkdir(LocalXmlFolder.c_str()))
63 std::cout<<"建立臨時檔案夾Tmp失敗!"<<std::endl;
64 else
65 std::cout<<"建立臨時檔案夾Tmp成功!"<<std::endl;
66 else
67 std::cout<<"臨時檔案夾Tmp已存在!"<<std::endl;
68
69 }
70
71 /**************************************************************************************
72 首先明白一個概念,即string替換所有字元串,将"12212"這個字元串的所有"12"都替換成"21",結果是什麼?
73 可以是22211,也可以是21221,有時候應用的場景不同,就會希望得到不同的結果,是以這兩種答案都做了實作。
74 **************************************************************************************/
75 //替換字元串方法1(完全輪詢,替換一次後接着再次掃描,因為替換一次後可能又出現了滿足替換條件的字元串)
76 std::string & replace_all(std::string& str,const std::string& old_value,const std::string& new_value)
77 {
78 while(true) {
79 std::string::size_type pos(0);
80 if((pos=str.find(old_value))!=std::string::npos)
81 str.replace(pos,old_value.length(),new_value);
82 else
83 break;
84 }
85 return str;
86 }
87
88 //替換字元串方法2(隻替換一次) 本項目中,隻替換\為/用方法2即可
89 std::string & replace_all_distinct(std::string& str,const std::string& old_value,const std::string& new_value)
90 {
91 for(std::string::size_type pos(0); pos!=std::string::npos; pos+=new_value.length())
92 {
93 if((pos=str.find(old_value,pos))!=std::string::npos)
94 str.replace(pos,old_value.length(),new_value);
95 else break;
96 }
97 return str;
98 }
99
100 //擷取年月日(命名用)
101 std::string getYearMonthDay()
102 {
103 time_t timer;
104 time(&timer);
105 tm* t_tm = localtime(&timer);
106
107 std::string Year=std::to_string(t_tm->tm_year+1900);
108 std::string Month=std::to_string(t_tm->tm_mon+1);
109 std::string Day=std::to_string(t_tm->tm_mday);
110 std::string PictureName=Year+"_"+Month+"_"+Day;
111
112 return PictureName;
113 }
114
115 //擷取圖檔的Xml并解析圖檔的url路徑
116 std::string getPicTureXmlAndUrl()
117 {
118 //網絡上的XML路徑
119 std::string WebXmlpath ="http://cn.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1";
120 //本地Xml路徑
121 std::string LocalXmlFolder="C:/bingPicture/Tmp/";
122 std::string LocalXmleach=getYearMonthDay();
123 std::string LocalXmlFullpath=LocalXmlFolder+LocalXmleach+".xml";
124
125 if(URLDownloadToFileA(NULL,
126 WebXmlpath.c_str(),
127 LocalXmlFullpath.c_str(),
128 0,
129 NULL)
130 ==S_OK)
131 {
132 std::cout<<"Xml下載下傳成功!即将解析今日桌面Url!"<<std::endl;
133
134 /***************下面開始解析xml中的url路徑*******************/
135 tinyxml2::XMLDocument doc;
136 if(tinyxml2::XML_SUCCESS != doc.LoadFile(LocalXmlFullpath.c_str()))
137 std::cout<<"讀取Xml檔案異常!"<<std::endl;
138 tinyxml2::XMLElement *images=doc.RootElement();
139 tinyxml2::XMLElement *image =images->FirstChildElement("image");
140
141 //圖檔Url
142 std::string WebPicturedomain="http://cn.bing.com";
143 std::string WebPictureUrl="";
144
145 if(image!=NULL)
146 WebPictureUrl=image->FirstChildElement("url")->GetText();
147
148 std::string WebPictureFullpath1366x768 =WebPicturedomain+WebPictureUrl;
149 std::cout<<"今日桌面Url解析成功!"<<std::endl;
150 /*********************************************************/
151 return WebPictureFullpath1366x768;
152 // //将1366x768換成1920x1080
153 // std::string WebPictureFullpath1920x1080 =replace_all_distinct(WebPictureFullpath1366x768,"1366x768","1920x1080");
154
155 // return WebPictureFullpath1920x1080;
156 }
157 else
158 {
159 std::cout<<"Xml下載下傳失敗!無法擷取圖檔Url!請檢查網絡連接配接是否正常!"<<std::endl;
160 return "error";
161 }
162
163 }
164
165 //從網絡上下載下傳圖檔并存儲到本地
166 std::string getPicture(std::string WebFullpath)
167 {
168 //本地存儲路徑
169 std::string LocalFolder="C:/bingPicture/";
170 std::string Localeach=getYearMonthDay();
171 std::string LocalFullpath=LocalFolder+Localeach+".jpg";
172
173 if(URLDownloadToFileA(NULL,
174 WebFullpath.c_str(),
175 LocalFullpath.c_str(),
176 0,
177 NULL)
178 ==S_OK)
179 {
180 std::cout<<"今日桌面下載下傳成功!"<<std::endl;
181
182 /***************下面轉換圖檔格式jpg->bmp******************/
183 //臨時檔案夾Tmp路徑
184 std::string TmpFolder="C:/bingPicture/Tmp/";
185 //.bmp圖檔路徑
186 std::string bmpFolder=TmpFolder+getYearMonthDay()+".bmp";
187 LoadJpegFile(const_cast<char *>(LocalFullpath.c_str()),const_cast<char *>(bmpFolder.c_str()));
188 /*******************************************************/
189 return bmpFolder;
190 }
191 else
192 {
193 std::cout<<"桌面下載下傳失敗!請檢查網絡連接配接是否正常!"<<std::endl;
194 return "error";
195 }
196 }
197
198 //改變桌面背景成功後,删除bmp檔案和xml檔案(隻保留jpg檔案),此步驟需要小心,避免删除錯誤路徑下的内容
199 void deleteBmpAndXml()
200 {
201 //臨時檔案夾Tmp路徑
202 std::string TmpFolder="C:/bingPicture/Tmp/";
203 //.bmp圖檔路徑
204 std::string bmpFolder=TmpFolder+getYearMonthDay()+".bmp";
205 //xml檔案路徑
206 std::string xmlFolder=TmpFolder+getYearMonthDay()+".xml";
207
208 if(0==access("C:/bingPicture/Tmp/",0)) //判斷檔案夾是否存在,若存在則删除
209 {
210 //删除bmp圖檔
211 if(0==access(bmpFolder.c_str(),0))
212 {
213 if(0==remove(bmpFolder.c_str()))
214 std::cout<<"删除臨時bmp格式圖檔成功!"<<std::endl;
215 else
216 std::cout<<"删除臨時bmp格式圖檔失敗!"<<std::endl;
217 }
218 else
219 std::cout<<"臨時bmp格式圖檔不存在!"<<std::endl;
220
221 //删除xml檔案
222 if(0==access(xmlFolder.c_str(),0))
223 {
224 if(0==remove(xmlFolder.c_str()))
225 std::cout<<"删除xml檔案成功!"<<std::endl;
226 else
227 std::cout<<"删除xml檔案失敗!"<<std::endl;
228 }
229 else
230 std::cout<<"xml檔案不存在!"<<std::endl;
231
232 //删除Tmp檔案夾(注意此函數隻能删除空檔案夾,是以要先删除檔案夾中的檔案)
233 if(0==rmdir(TmpFolder.c_str()))
234 std::cout<<"臨時檔案夾Tmp已删除!"<<std::endl;
235 else
236 std::cout<<"臨時檔案夾Tmp删除失敗!"<<std::endl;
237 }
238 else
239 std::cout<<"臨時檔案夾Tmp不存在!"<<std::endl;
240
241 }
242
243 //改變桌面背景(PictureFullpath:圖檔完整路徑)
244 void changePicture(std::string PictureFullpath)
245 {
246 bool result=false;
247 result=SystemParametersInfoA(SPI_SETDESKWALLPAPER,
248 0,
249 (PVOID)PictureFullpath.c_str(),
250 0);
251 if(result==false)
252 {
253 std::cout<<"今日桌面更新失敗!請聯系開發人員!"<<std::endl;
254 }
255
256 else
257 {
258 SystemParametersInfoA(SPI_SETDESKWALLPAPER,
259 0,
260 (PVOID)PictureFullpath.c_str(),
261 SPIF_SENDCHANGE);
262 //deleteBmpAndXml(); //windows8及其以上會變成黑色,把這條語句放到main最後面就沒問題,具體原因未知
263 system("cls");
264 std::cout<<"version:1.0.0 (Author:xiaoxi666)"<<std::endl<<std::endl;
265 std::cout<<"今日桌面更新成功!"<<std::endl<<std::endl;
266 std::cout<<"美好的一天開始啦!用心享受吧!"<<std::endl<<std::endl;
267 }
268 }
269
270 int main()
271 {
272 std::string startOrder="";
273 std::cout<<"嗨!小夥伴!你的貼心桌面小助手已啟動!将為你設定今日桌面哦!"<<std::endl<<std::endl;
274 std::cout<<"請確定電腦網絡連接配接狀況良好,準備好後輸入go"<<std::endl<<std::endl;
275 std::cout<<"請輸入指令: ";
276 std::cin>>startOrder;
277 while("go"!=startOrder)
278 {
279 std::cout<<"哎呀輸錯了呢,重新輸入吧: ";
280 std::cin>>startOrder;
281 }
282 if("go"==startOrder)
283 {
284 createDir();
285 changePicture(getPicture(getPicTureXmlAndUrl()));
286 }
287
288 /*******************************以下為個性化字幕輸出,與程式核心功能無關************************/
289 std::string umua0=" ** ** ******** ******* ******* *** *** ";
290 std::string umua1=" ** ** ******** ******* ******* *** *** ";
291 std::string umua2=" ** ** ** ** ** ** *** ** *** *** ";
292 std::string umua3=" ** ** ** ** ** ** *** ** ** ** ";
293 std::string umua4=" ********* ******** ******* ******* * * ";
294 std::string umua5=" ********* ******** ******* ** ** ";
295 std::string umua6=" ** ** ** ** ** ** ** ";
296 std::string umua7=" ** ** ** ** ** ** ** ";
297 std::string umua8=" ** ** ** ** ** ** ** ";
298 std::string umua9=" ** ** ** ** ** ** ** ";
299
300 #define mua(n) std::cout<<umua##n<<std::endl;
301 std::cout<<std::endl<<std::endl;
302 mua(0);mua(1);mua(2);mua(3);mua(4);mua(5);mua(6);mua(7);mua(8);mua(9);
303 std::cout<<std::endl<<std::endl<<std::endl;
304 system("pause");
305 /******************************************************************************************/
306 deleteBmpAndXml();
307 return 0;
308 }
View Code
圖檔格式轉換程式(這個是網上下載下傳的C源碼,我改了一下接口,在此感謝)
jpeg.h
//頭檔案jpeg.h,配合程式jpeg2bmp.c使用
//若用于c++程式中,請用extern "C"包含此頭檔案
//功能:用于将圖檔從jpg類型轉換為bmp類型,調用函數LoadJpegFile即可,參數1:jpg檔案路徑;參數2:bmp檔案路徑
#define M_SOF0 0xc0
#define M_DHT 0xc4
#define M_EOI 0xd9
#define M_SOS 0xda
#define M_DQT 0xdb
#define M_DRI 0xdd
#define M_APP0 0xe0
static int Zig_Zag[8][8]={{0,1,5,6,14,15,27,28},
{2,4,7,13,16,26,29,42},
{3,8,12,17,25,30,41,43},
{9,11,18,24,37,40,44,53},
{10,19,23,32,39,45,52,54},
{20,22,33,38,46,51,55,60},
{21,34,37,47,50,56,59,61},
{35,36,48,49,57,58,62,63}
};
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
int LoadJpegFile (char *JpegFileName,char *bmpFileName);
jpeg2bmp.c
//jpeg.c
//本程式用C語言編寫,若用于c++程式中,請用extern "C"包含頭檔案jpeg.h
//功能:用于将圖檔從jpg類型轉換為bmp類型,調用函數LoadJpegFile即可,參數1:jpg檔案路徑;參數2:bmp檔案路徑
#include "jpeg.h"
#include "memory.h"
#include "math.h"
#include "stdio.h"
#include "windows.h"
//macro definition
#define WIDTHBYTES(i) ((i+31)/32*4)
#define PI 3.1415926535
//define return value of function
#define FUNC_OK 0
#define FUNC_MEMORY_ERROR 1
#define FUNC_FILE_ERROR 2
#define FUNC_FORMAT_ERROR 3
//////////////////////////////////////////////////
//Jpeg functions
//int LoadJpegFile (char *JpegFileName,char *bmpFileName);
void showerror(int funcret);
int InitTag();
void InitTable();
int Decode();
int DecodeMCUBlock();
int HufBlock(unsigned char dchufindex,unsigned char achufindex);
int DecodeElement();
void IQtIZzMCUComponent(short flag);
void IQtIZzBlock(short *s ,int * d,short flag);
void GetYUV(short flag);
void StoreBuffer();
BYTE ReadByte();
void Initialize_Fast_IDCT();
void Fast_IDCT(int * block);
void idctrow(int * blk);
void idctcol(int * blk);
//////////////////////////////////////////////////
//global variable declaration
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
HBITMAP hBitmap=NULL;
HGLOBAL hImgData=NULL;
DWORD NumColors;
DWORD LineBytes;
DWORD ImgWidth=0 , ImgHeight=0;
unsigned int PcxBytesPerLine;
LPSTR lpPtr;
//////////////////////////////////////////////////
//variables used in jpeg function
short SampRate_Y_H,SampRate_Y_V;
short SampRate_U_H,SampRate_U_V;
short SampRate_V_H,SampRate_V_V;
short H_YtoU,V_YtoU,H_YtoV,V_YtoV;
short Y_in_MCU,U_in_MCU,V_in_MCU;
unsigned char *lpJpegBuf;
unsigned char *lp;
short qt_table[3][64];
short comp_num;
BYTE comp_index[3];
BYTE YDcIndex,YAcIndex,UVDcIndex,UVAcIndex;
BYTE HufTabIndex;
short *YQtTable,*UQtTable,*VQtTable;
BYTE And[9]={0,1,3,7,0xf,0x1f,0x3f,0x7f,0xff};
short code_pos_table[4][16],code_len_table[4][16];
unsigned short code_value_table[4][256];
unsigned short huf_max_value[4][16],huf_min_value[4][16];
short BitPos,CurByte;
short rrun,vvalue;
short MCUBuffer[10*64];
int QtZzMCUBuffer[10*64];
short BlockBuffer[64];
short ycoef,ucoef,vcoef;
BOOL IntervalFlag;
short interval=0;
int Y[4*64],U[4*64],V[4*64];
DWORD sizei,sizej;
short restart;
static long iclip[1024];
static long *iclp;
////////////////////////////////////////////////////////////////
int LoadJpegFile (char *JpegFileName,char *bmpFileName)
{
HFILE hfjpg;
DWORD ImgSize;
DWORD JpegBufSize;
HFILE hfbmp;
HGLOBAL hJpegBuf;
int funcret;
LPBITMAPINFOHEADER lpImgData;
if((hfjpg=_lopen(JpegFileName,OF_READ))==HFILE_ERROR)
{
showerror(FUNC_FILE_ERROR);
return 0;
}
//get jpg file length
JpegBufSize=_llseek(hfjpg,0L,SEEK_END);
//rewind to the beginning of the file
_llseek(hfjpg,0L,SEEK_SET);
if((hJpegBuf=GlobalAlloc(GHND,JpegBufSize))==NULL)
{
_lclose(hfjpg);
showerror(FUNC_MEMORY_ERROR);
return 0;
}
lpJpegBuf=(unsigned char *)GlobalLock(hJpegBuf);
_hread(hfjpg,(unsigned char *)lpJpegBuf,JpegBufSize);
_lclose(hfjpg);
InitTable();
if((funcret=InitTag())!=FUNC_OK)
{
GlobalUnlock(hJpegBuf);
GlobalFree(hJpegBuf);
showerror(funcret);
return 0;
}
//create new bitmapfileheader and bitmapinfoheader
memset((char *)&bf,0,sizeof(BITMAPFILEHEADER));
memset((char *)&bi,0,sizeof(BITMAPINFOHEADER));
bi.biSize=(DWORD)sizeof(BITMAPINFOHEADER);
bi.biWidth=(LONG)(ImgWidth);
bi.biHeight=(LONG)(ImgHeight);
bi.biPlanes=1;
bi.biBitCount=24;
bi.biClrUsed=0;
bi.biClrImportant=0;
bi.biCompression=BI_RGB;
NumColors=0;
LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
ImgSize=(DWORD)LineBytes*bi.biHeight;
bf.bfType=0x4d42;
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
bf.bfOffBits=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
if((hImgData=GlobalAlloc(GHND,ImgSize))==NULL)
{
GlobalUnlock(hJpegBuf);
GlobalFree(hJpegBuf);
showerror(FUNC_MEMORY_ERROR);
return FALSE;
}
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
lpPtr=(char *)lpImgData;
if((SampRate_Y_H==0)||(SampRate_Y_V==0))
{
GlobalUnlock(hJpegBuf);
GlobalFree(hJpegBuf);
GlobalUnlock(hImgData);
GlobalFree(hImgData);
hImgData=NULL;
showerror(FUNC_FORMAT_ERROR);
return FALSE ;
}
funcret=Decode();
if(funcret==FUNC_OK)
{
hfbmp=_lcreat(bmpFileName,0);
_lwrite(hfbmp,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); //寫BMP檔案頭
_lwrite(hfbmp,(LPSTR)&bi,sizeof(BITMAPINFOHEADER)); //寫BMP檔案資訊
_lwrite(hfbmp,(LPSTR)lpImgData,ImgSize); //寫BMP位圖資料
_lclose(hfbmp);
GlobalUnlock(hJpegBuf);
GlobalFree(hJpegBuf);
GlobalUnlock(hImgData);
return TRUE;
}
else
{
GlobalUnlock(hJpegBuf);
GlobalFree(hJpegBuf);
GlobalUnlock(hImgData);
GlobalFree(hImgData);
hImgData=NULL;
showerror(funcret);
return FALSE;
}
}
/////////////////////////////////////////////////
void showerror(int funcret)
{
switch(funcret)
{
case FUNC_MEMORY_ERROR:
printf("Error alloc memory!\n");
exit(1);
break;
case FUNC_FILE_ERROR:
printf("File not found!!\n");
exit(1);
break;
case FUNC_FORMAT_ERROR:
printf("File format error!\n");
exit(1);
break;
}
}
////////////////////////////////////////////////////////////////////////////////
int InitTag()
{
BOOL finish=FALSE;
BYTE id;
short llength;
short i,j,k;
short huftab1,huftab2;
short huftabindex;
BYTE hf_table_index;
BYTE qt_table_index;
BYTE comnum;
unsigned char *lptemp;
short ccount;
lp=lpJpegBuf+2;
while (!finish)
{
id=*(lp+1);
lp+=2;
switch (id)
{
case M_APP0:
llength=MAKEWORD(*(lp+1),*lp);
lp+=llength;
break;
case M_DQT:
llength=MAKEWORD(*(lp+1),*lp);
qt_table_index=(*(lp+2))&0x0f;
lptemp=lp+3;
if(llength<80)
{
for(i=0;i<64;i++)
qt_table[qt_table_index][i]=(short)*(lptemp++);
}
else
{
for(i=0;i<64;i++)
qt_table[qt_table_index][i]=(short)*(lptemp++);
qt_table_index=(*(lptemp++))&0x0f;
for(i=0;i<64;i++)
qt_table[qt_table_index][i]=(short)*(lptemp++);
}
lp+=llength;
break;
case M_SOF0:
llength=MAKEWORD(*(lp+1),*lp);
ImgHeight=MAKEWORD(*(lp+4),*(lp+3));
ImgWidth=MAKEWORD(*(lp+6),*(lp+5));
comp_num=*(lp+7);
if((comp_num!=1)&&(comp_num!=3))
return FUNC_FORMAT_ERROR;
if(comp_num==3)
{
comp_index[0]=*(lp+8);
SampRate_Y_H=(*(lp+9))>>4;
SampRate_Y_V=(*(lp+9))&0x0f;
YQtTable=(short *)qt_table[*(lp+10)];
comp_index[1]=*(lp+11);
SampRate_U_H=(*(lp+12))>>4;
SampRate_U_V=(*(lp+12))&0x0f;
UQtTable=(short *)qt_table[*(lp+13)];
comp_index[2]=*(lp+14);
SampRate_V_H=(*(lp+15))>>4;
SampRate_V_V=(*(lp+15))&0x0f;
VQtTable=(short *)qt_table[*(lp+16)];
}
else
{
comp_index[0]=*(lp+8);
SampRate_Y_H=(*(lp+9))>>4;
SampRate_Y_V=(*(lp+9))&0x0f;
YQtTable=(short *)qt_table[*(lp+10)];
comp_index[1]=*(lp+8);
SampRate_U_H=1;
SampRate_U_V=1;
UQtTable=(short *)qt_table[*(lp+10)];
comp_index[2]=*(lp+8);
SampRate_V_H=1;
SampRate_V_V=1;
VQtTable=(short *)qt_table[*(lp+10)];
}
lp+=llength;
break;
case M_DHT:
llength=MAKEWORD(*(lp+1),*lp);
if (llength<0xd0)
{
huftab1=(short)(*(lp+2))>>4; //huftab1=0,1
huftab2=(short)(*(lp+2))&0x0f; //huftab2=0,1
huftabindex=huftab1*2+huftab2;
lptemp=lp+3;
for (i=0; i<16; i++)
code_len_table[huftabindex][i]=(short)(*(lptemp++));
j=0;
for (i=0; i<16; i++)
if(code_len_table[huftabindex][i]!=0)
{
k=0;
while(k<code_len_table[huftabindex][i])
{
code_value_table[huftabindex][k+j]=(short)(*(lptemp++));
k++;
}
j+=k;
}
i=0;
while (code_len_table[huftabindex][i]==0)
i++;
for (j=0;j<i;j++)
{
huf_min_value[huftabindex][j]=0;
huf_max_value[huftabindex][j]=0;
}
huf_min_value[huftabindex][i]=0;
huf_max_value[huftabindex][i]=code_len_table[huftabindex][i]-1;
for (j=i+1;j<16;j++)
{
huf_min_value[huftabindex][j]=(huf_max_value[huftabindex][j-1]+1)<<1;
huf_max_value[huftabindex][j]=huf_min_value[huftabindex][j]+code_len_table[huftabindex][j]-1;
}
code_pos_table[huftabindex][0]=0;
for (j=1;j<16;j++)
code_pos_table[huftabindex][j]=code_len_table[huftabindex][j-1]+code_pos_table[huftabindex][j-1];
lp+=llength;
} //if
else
{
hf_table_index=*(lp+2);
lp+=2;
while (hf_table_index!=0xff)
{
huftab1=(short)hf_table_index>>4; //huftab1=0,1
huftab2=(short)hf_table_index&0x0f; //huftab2=0,1
huftabindex=huftab1*2+huftab2;
lptemp=lp+1;
ccount=0;
for (i=0; i<16; i++)
{
code_len_table[huftabindex][i]=(short)(*(lptemp++));
ccount+=code_len_table[huftabindex][i];
}
ccount+=17;
j=0;
for (i=0; i<16; i++)
if(code_len_table[huftabindex][i]!=0)
{
k=0;
while(k<code_len_table[huftabindex][i])
{
code_value_table[huftabindex][k+j]=(short)(*(lptemp++));
k++;
}
j+=k;
}
i=0;
while (code_len_table[huftabindex][i]==0)
i++;
for (j=0;j<i;j++)
{
huf_min_value[huftabindex][j]=0;
huf_max_value[huftabindex][j]=0;
}
huf_min_value[huftabindex][i]=0;
huf_max_value[huftabindex][i]=code_len_table[huftabindex][i]-1;
for (j=i+1;j<16;j++)
{
huf_min_value[huftabindex][j]=(huf_max_value[huftabindex][j-1]+1)<<1;
huf_max_value[huftabindex][j]=huf_min_value[huftabindex][j]+code_len_table[huftabindex][j]-1;
}
code_pos_table[huftabindex][0]=0;
for (j=1;j<16;j++)
code_pos_table[huftabindex][j]=code_len_table[huftabindex][j-1]+code_pos_table[huftabindex][j-1];
lp+=ccount;
hf_table_index=*lp;
} //while
} //else
break;
case M_DRI:
llength=MAKEWORD(*(lp+1),*lp);
restart=MAKEWORD(*(lp+3),*(lp+2));
lp+=llength;
break;
case M_SOS:
llength=MAKEWORD(*(lp+1),*lp);
comnum=*(lp+2);
if(comnum!=comp_num)
return FUNC_FORMAT_ERROR;
lptemp=lp+3;
for (i=0;i<comp_num;i++)
{
if(*lptemp==comp_index[0])
{
YDcIndex=(*(lptemp+1))>>4; //Y
YAcIndex=((*(lptemp+1))&0x0f)+2;
}
else{
UVDcIndex=(*(lptemp+1))>>4; //U,V
UVAcIndex=((*(lptemp+1))&0x0f)+2;
}
lptemp+=2;
}
lp+=llength;
finish=TRUE;
break;
case M_EOI:
return FUNC_FORMAT_ERROR;
break;
default:
if ((id&0xf0)!=0xd0)
{
llength=MAKEWORD(*(lp+1),*lp);
lp+=llength;
}
else lp+=2;
break;
} //switch
} //while
return FUNC_OK;
}
/////////////////////////////////////////////////////////////////
void InitTable()
{
short i,j;
sizei=sizej=0;
ImgWidth=ImgHeight=0;
rrun=vvalue=0;
BitPos=0;
CurByte=0;
IntervalFlag=FALSE;
restart=0;
for(i=0;i<3;i++)
for(j=0;j<64;j++)
qt_table[i][j]=0;
comp_num=0;
HufTabIndex=0;
for(i=0;i<3;i++)
comp_index[i]=0;
for(i=0;i<4;i++)
for(j=0;j<16;j++)
{
code_len_table[i][j]=0;
code_pos_table[i][j]=0;
huf_max_value[i][j]=0;
huf_min_value[i][j]=0;
}
for(i=0;i<4;i++)
for(j=0;j<256;j++)
code_value_table[i][j]=0;
for(i=0;i<10*64;i++)
{
MCUBuffer[i]=0;
QtZzMCUBuffer[i]=0;
}
for(i=0;i<4*64;i++)
{
Y[i]=0;
U[i]=0;
V[i]=0;
}
for(i=0;i<64;i++)
BlockBuffer[i]=0;
ycoef=ucoef=vcoef=0;
}
/////////////////////////////////////////////////////////////////////////
int Decode()
{
int funcret;
Y_in_MCU=SampRate_Y_H*SampRate_Y_V;
U_in_MCU=SampRate_U_H*SampRate_U_V;
V_in_MCU=SampRate_V_H*SampRate_V_V;
H_YtoU=SampRate_Y_H/SampRate_U_H;
V_YtoU=SampRate_Y_V/SampRate_U_V;
H_YtoV=SampRate_Y_H/SampRate_V_H;
V_YtoV=SampRate_Y_V/SampRate_V_V;
Initialize_Fast_IDCT();
while((funcret=DecodeMCUBlock())==FUNC_OK)
{
interval++;
if((restart)&&(interval % restart==0))
IntervalFlag=TRUE;
else
IntervalFlag=FALSE;
IQtIZzMCUComponent(0);
IQtIZzMCUComponent(1);
IQtIZzMCUComponent(2);
GetYUV(0);
GetYUV(1);
GetYUV(2);
StoreBuffer();
sizej+=SampRate_Y_H*8;
if(sizej>=ImgWidth)
{
sizej=0;
sizei+=SampRate_Y_V*8;
}
if ((sizej==0)&&(sizei>=ImgHeight))
break;
}
return funcret;
}
/////////////////////////////////////////////////////////////////////////////////////////
void GetYUV(short flag)
{
short H,VV;
short i,j,k,h;
int *buf;
int *pQtZzMCU;
switch(flag)
{
case 0:
H=SampRate_Y_H;
VV=SampRate_Y_V;
buf=Y;
pQtZzMCU=QtZzMCUBuffer;
break;
case 1:
H=SampRate_U_H;
VV=SampRate_U_V;
buf=U;
pQtZzMCU=QtZzMCUBuffer+Y_in_MCU*64;
break;
case 2:
H=SampRate_V_H;
VV=SampRate_V_V;
buf=V;
pQtZzMCU=QtZzMCUBuffer+(Y_in_MCU+U_in_MCU)*64;
break;
}
for (i=0;i<VV;i++)
for(j=0;j<H;j++)
for(k=0;k<8;k++)
for(h=0;h<8;h++)
buf[(i*8+k)*SampRate_Y_H*8+j*8+h]=*pQtZzMCU++;
}
///////////////////////////////////////////////////////////////////////////////
void StoreBuffer()
{
short i,j;
unsigned char *lpbmp;
unsigned char R,G,B;
int y,u,v,rr,gg,bb;
for(i=0;i<SampRate_Y_V*8;i++)
{
if((sizei+i)<ImgHeight)
{
lpbmp=((unsigned char *)lpPtr+(DWORD)(ImgHeight-sizei-i-1)*LineBytes+sizej*3);
for(j=0;j<SampRate_Y_H*8;j++)
{
if((sizej+j)<ImgWidth)
{
y=Y[i*8*SampRate_Y_H+j];
u=U[(i/V_YtoU)*8*SampRate_Y_H+j/H_YtoU];
v=V[(i/V_YtoV)*8*SampRate_Y_H+j/H_YtoV];
rr=((y<<8)+18*u+367*v)>>8;
gg=((y<<8)-159*u-220*v)>>8;
bb=((y<<8)+411*u-29*v)>>8;
R=(unsigned char)rr;
G=(unsigned char)gg;
B=(unsigned char)bb;
if (rr&0xffffff00) if (rr>255) R=255; else if (rr<0) R=0;
if (gg&0xffffff00) if (gg>255) G=255; else if (gg<0) G=0;
if (bb&0xffffff00) if (bb>255) B=255; else if (bb<0) B=0;
*lpbmp++=B;
*lpbmp++=G;
*lpbmp++=R;
}
else break;
}
}
else break;
}
}
///////////////////////////////////////////////////////////////////////////////
int DecodeMCUBlock()
{
short *lpMCUBuffer;
short i,j;
int funcret;
if (IntervalFlag)
{
lp+=2;
ycoef=ucoef=vcoef=0;
BitPos=0;
CurByte=0;
}
switch(comp_num)
{
case 3:
lpMCUBuffer=MCUBuffer;
for (i=0;i<SampRate_Y_H*SampRate_Y_V;i++) //Y
{
funcret=HufBlock(YDcIndex,YAcIndex);
if (funcret!=FUNC_OK)
return funcret;
BlockBuffer[0]=BlockBuffer[0]+ycoef;
ycoef=BlockBuffer[0];
for (j=0;j<64;j++)
*lpMCUBuffer++=BlockBuffer[j];
}
for (i=0;i<SampRate_U_H*SampRate_U_V;i++) //U
{
funcret=HufBlock(UVDcIndex,UVAcIndex);
if (funcret!=FUNC_OK)
return funcret;
BlockBuffer[0]=BlockBuffer[0]+ucoef;
ucoef=BlockBuffer[0];
for (j=0;j<64;j++)
*lpMCUBuffer++=BlockBuffer[j];
}
for (i=0;i<SampRate_V_H*SampRate_V_V;i++) //V
{
funcret=HufBlock(UVDcIndex,UVAcIndex);
if (funcret!=FUNC_OK)
return funcret;
BlockBuffer[0]=BlockBuffer[0]+vcoef;
vcoef=BlockBuffer[0];
for (j=0;j<64;j++)
*lpMCUBuffer++=BlockBuffer[j];
}
break;
case 1:
lpMCUBuffer=MCUBuffer;
funcret=HufBlock(YDcIndex,YAcIndex);
if (funcret!=FUNC_OK)
return funcret;
BlockBuffer[0]=BlockBuffer[0]+ycoef;
ycoef=BlockBuffer[0];
for (j=0;j<64;j++)
*lpMCUBuffer++=BlockBuffer[j];
for (i=0;i<128;i++)
*lpMCUBuffer++=0;
break;
default:
return FUNC_FORMAT_ERROR;
}
return FUNC_OK;
}
//////////////////////////////////////////////////////////////////
int HufBlock(BYTE dchufindex,BYTE achufindex)
{
short count=0;
short i;
int funcret;
//dc
HufTabIndex=dchufindex;
funcret=DecodeElement();
if(funcret!=FUNC_OK)
return funcret;
BlockBuffer[count++]=vvalue;
//ac
HufTabIndex=achufindex;
while (count<64)
{
funcret=DecodeElement();
if(funcret!=FUNC_OK)
return funcret;
if ((rrun==0)&&(vvalue==0))
{
for (i=count;i<64;i++)
BlockBuffer[i]=0;
count=64;
}
else
{
for (i=0;i<rrun;i++)
BlockBuffer[count++]=0;
BlockBuffer[count++]=vvalue;
}
}
return FUNC_OK;
}
//////////////////////////////////////////////////////////////////////////////
int DecodeElement()
{
int thiscode,tempcode;
unsigned short temp,valueex;
short codelen;
BYTE hufexbyte,runsize,tempsize,sign;
BYTE newbyte,lastbyte;
if(BitPos>=1)
{
BitPos--;
thiscode=(BYTE)CurByte>>BitPos;
CurByte=CurByte&And[BitPos];
}
else
{
lastbyte=ReadByte();
BitPos--;
newbyte=CurByte&And[BitPos];
thiscode=lastbyte>>7;
CurByte=newbyte;
}
codelen=1;
while ((thiscode<huf_min_value[HufTabIndex][codelen-1])||
(code_len_table[HufTabIndex][codelen-1]==0)||
(thiscode>huf_max_value[HufTabIndex][codelen-1]))
{
if(BitPos>=1)
{
BitPos--;
tempcode=(BYTE)CurByte>>BitPos;
CurByte=CurByte&And[BitPos];
}
else
{
lastbyte=ReadByte();
BitPos--;
newbyte=CurByte&And[BitPos];
tempcode=(BYTE)lastbyte>>7;
CurByte=newbyte;
}
thiscode=(thiscode<<1)+tempcode;
codelen++;
if(codelen>16)
return FUNC_FORMAT_ERROR;
} //while
temp=thiscode-huf_min_value[HufTabIndex][codelen-1]+code_pos_table[HufTabIndex][codelen-1];
hufexbyte=(BYTE)code_value_table[HufTabIndex][temp];
rrun=(short)(hufexbyte>>4);
runsize=hufexbyte&0x0f;
if(runsize==0)
{
vvalue=0;
return FUNC_OK;
}
tempsize=runsize;
if(BitPos>=runsize)
{
BitPos-=runsize;
valueex=(BYTE)CurByte>>BitPos;
CurByte=CurByte&And[BitPos];
}
else
{
valueex=CurByte;
tempsize-=BitPos;
while(tempsize>8)
{
lastbyte=ReadByte();
valueex=(valueex<<8)+(BYTE)lastbyte;
tempsize-=8;
} //while
lastbyte=ReadByte();
BitPos-=tempsize;
valueex=(valueex<<tempsize)+(lastbyte>>BitPos);
CurByte=lastbyte&And[BitPos];
} //else
sign=valueex>>(runsize-1);
if(sign)
vvalue=valueex;
else
{
valueex=valueex^0xffff;
temp=0xffff<<runsize;
vvalue=-(short)(valueex^temp);
}
return FUNC_OK;
}
/////////////////////////////////////////////////////////////////////////////////////
void IQtIZzMCUComponent(short flag)
{
short H,VV;
short i,j;
int *pQtZzMCUBuffer;
short *pMCUBuffer;
switch(flag)
{
case 0:
H=SampRate_Y_H;
VV=SampRate_Y_V;
pMCUBuffer=MCUBuffer;
pQtZzMCUBuffer=QtZzMCUBuffer;
break;
case 1:
H=SampRate_U_H;
VV=SampRate_U_V;
pMCUBuffer=MCUBuffer+Y_in_MCU*64;
pQtZzMCUBuffer=QtZzMCUBuffer+Y_in_MCU*64;
break;
case 2:
H=SampRate_V_H;
VV=SampRate_V_V;
pMCUBuffer=MCUBuffer+(Y_in_MCU+U_in_MCU)*64;
pQtZzMCUBuffer=QtZzMCUBuffer+(Y_in_MCU+U_in_MCU)*64;
break;
}
for(i=0;i<VV;i++)
for (j=0;j<H;j++)
IQtIZzBlock(pMCUBuffer+(i*H+j)*64,pQtZzMCUBuffer+(i*H+j)*64,flag);
}
//////////////////////////////////////////////////////////////////////////////////////////
void IQtIZzBlock(short *s ,int * d,short flag)
{
short i,j;
short tag;
short *pQt;
int buffer2[8][8];
int *buffer1;
short offset;
switch(flag)
{
case 0:
pQt=YQtTable;
offset=128;
break;
case 1:
pQt=UQtTable;
offset=0;
break;
case 2:
pQt=VQtTable;
offset=0;
break;
}
for(i=0;i<8;i++)
for(j=0;j<8;j++)
{
tag=Zig_Zag[i][j];
buffer2[i][j]=(int)s[tag]*(int)pQt[tag];
}
buffer1=(int *)buffer2;
Fast_IDCT(buffer1);
for(i=0;i<8;i++)
for(j=0;j<8;j++)
d[i*8+j]=buffer2[i][j]+offset;
}
///////////////////////////////////////////////////////////////////////////////
void Fast_IDCT(int * block)
{
short i;
for (i=0; i<8; i++)
idctrow(block+8*i);
for (i=0; i<8; i++)
idctcol(block+i);
}
///////////////////////////////////////////////////////////////////////////////
BYTE ReadByte()
{
BYTE i;
i=*(lp++);
if(i==0xff)
lp++;
BitPos=8;
CurByte=i;
return i;
}
///////////////////////////////////////////////////////////////////////
void Initialize_Fast_IDCT()
{
short i;
iclp = iclip+512;
for (i= -512; i<512; i++)
iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
}
////////////////////////////////////////////////////////////////////////
void idctrow(int * blk)
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
//intcut
if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
{
blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
return;
}
x0 = (blk[0]<<11) + 128; // for proper rounding in the fourth stage
//first stage
x8 = W7*(x4+x5);
x4 = x8 + (W1-W7)*x4;
x5 = x8 - (W1+W7)*x5;
x8 = W3*(x6+x7);
x6 = x8 - (W3-W5)*x6;
x7 = x8 - (W3+W5)*x7;
//second stage
x8 = x0 + x1;
x0 -= x1;
x1 = W6*(x3+x2);
x2 = x1 - (W2+W6)*x2;
x3 = x1 + (W2-W6)*x3;
x1 = x4 + x6;
x4 -= x6;
x6 = x5 + x7;
x5 -= x7;
//third stage
x7 = x8 + x3;
x8 -= x3;
x3 = x0 + x2;
x0 -= x2;
x2 = (181*(x4+x5)+128)>>8;
x4 = (181*(x4-x5)+128)>>8;
//fourth stage
blk[0] = (x7+x1)>>8;
blk[1] = (x3+x2)>>8;
blk[2] = (x0+x4)>>8;
blk[3] = (x8+x6)>>8;
blk[4] = (x8-x6)>>8;
blk[5] = (x0-x4)>>8;
blk[6] = (x3-x2)>>8;
blk[7] = (x7-x1)>>8;
}
//////////////////////////////////////////////////////////////////////////////
void idctcol(int * blk)
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
//intcut
if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
(x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
{
blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]
=blk[8*6]=blk[8*7]=iclp[(blk[8*0]+32)>>6];
return;
}
x0 = (blk[8*0]<<8) + 8192;
//first stage
x8 = W7*(x4+x5) + 4;
x4 = (x8+(W1-W7)*x4)>>3;
x5 = (x8-(W1+W7)*x5)>>3;
x8 = W3*(x6+x7) + 4;
x6 = (x8-(W3-W5)*x6)>>3;
x7 = (x8-(W3+W5)*x7)>>3;
//second stage
x8 = x0 + x1;
x0 -= x1;
x1 = W6*(x3+x2) + 4;
x2 = (x1-(W2+W6)*x2)>>3;
x3 = (x1+(W2-W6)*x3)>>3;
x1 = x4 + x6;
x4 -= x6;
x6 = x5 + x7;
x5 -= x7;
//third stage
x7 = x8 + x3;
x8 -= x3;
x3 = x0 + x2;
x0 -= x2;
x2 = (181*(x4+x5)+128)>>8;
x4 = (181*(x4-x5)+128)>>8;
//fourth stage
blk[8*0] = iclp[(x7+x1)>>14];
blk[8*1] = iclp[(x3+x2)>>14];
blk[8*2] = iclp[(x0+x4)>>14];
blk[8*3] = iclp[(x8+x6)>>14];
blk[8*4] = iclp[(x8-x6)>>14];
blk[8*5] = iclp[(x0-x4)>>14];
blk[8*6] = iclp[(x3-x2)>>14];
blk[8*7] = iclp[(x7-x1)>>14];
}
//main( )
//{
// LoadJpegFile("test.jpg");
//}
xml解析,我用的是TinyXml2開源庫,這個就不貼源碼了。
關于Qt項目圖示制作
我用的Qt版本是4.8.5。
步驟如下:
- 在Qt工程目錄下建立一個文本檔案,并将其名稱改為 *.rc (名字任取)
- 将你的圖示檔案.ico添加到項目中
- 打開該 rc 檔案,在該rc檔案裡面加入以下一行文本(将文本中的*換成你的圖示的名字):
IDI_ICON ICON DISCARDABLE "*.ico"
- 在項目檔案.pro中加入以下文本(将*換成你的rc檔案名字):
RC_FILE = \
*.rc
5. 重新編譯工程即可
關于Qt項目的釋出
Qt項目釋出最麻煩的就是動态依賴庫,常用的工具是hap-depends,它可以檢視軟體的依賴庫(*.dll),直接用它打開你的.exe檔案,檢視缺失哪些.dll檔案,找到它們後和exe放在相同目錄即可。
當然,釋出之前需要經過多個平台的測試。
最後祝大家生活愉快!
『注:本文來自部落格園“小溪的部落格”,若非聲明均為原創内容,請勿用于商業用途,轉載請注明出處http://www.cnblogs.com/xiaoxi666/』