dibbmp.cpp
上传用户:lbr_007
上传日期:2019-05-31
资源大小:282k
文件大小:13k
源码类别:

传真(Fax)编程

开发平台:

Visual C++

  1. // dibbmp.cpp
  2. //
  3. #include "stdafx.h"
  4. #include <dibbmp.h>
  5. #define EVEN_NUMBER(i) ((i%2)==0?1:0)
  6. int OpenBMP2DIB(const char * filename, DIBSection& dib)
  7. {
  8. int result = 0;
  9. FILE * fp = fopen(filename,"rb");
  10. if (fp)
  11. {
  12.   // seek to the end of the file
  13. fseek(fp,0l,SEEK_END);
  14.   // get the file position in bytes (file size)
  15. UINT32 fileSize = ftell(fp);
  16.   // seek back to the beginning again
  17. fseek(fp,0l,SEEK_SET);
  18.   // if the file has data: pull it in and interpret
  19. if (fileSize > 0)
  20. {
  21. unsigned char * fileData = new unsigned char[fileSize];
  22. if (fileData)
  23. {
  24. memset(fileData,0,(size_t)fileSize);
  25. if (fread(fileData,sizeof(char),fileSize,fp) == fileSize)
  26. {
  27. result = ReadDIBFile(fileSize,fileData,dib);
  28. }
  29.   // ok, the file data has been pulled in and hopefully
  30.   // it has been interpreted, so we have no more use for it
  31. delete [] fileData;
  32. }
  33. }
  34. }
  35. return result;
  36. }
  37. int SaveDIB2BMP(const char * filename, DIBSection& dib)
  38. {
  39. int result = 0;
  40. FILE * fp = fopen(filename,"wb");
  41. if (fp)
  42. {
  43. if (dib.IsCreated())
  44. {
  45. BITMAPFILEHEADER bmfHeader;
  46. BITMAPINFO bmInfo;
  47.   // zero out everything
  48. memset(&bmfHeader,0,sizeof(BITMAPFILEHEADER));
  49. memset(&bmInfo,0,sizeof(BITMAPINFO));
  50. UINT32 h = dib.Height();
  51. UINT32 w = dib.Width();
  52. UINT32 rowBytes = w * 3;
  53. UINT32 totalRowBytes = ((((int) rowBytes * 8) + 31) & ~31) >> 3;
  54. UINT32 tw = dib.GetTotalWidth();
  55. UINT32 sizeBMF = sizeof(BITMAPFILEHEADER);
  56. UINT32 sizeBMI = sizeof(BITMAPINFOHEADER);
  57.   // now set up necessary members of the file header
  58. memcpy(&bmfHeader.bfType,"BM",2);
  59. bmfHeader.bfSize = sizeBMF + sizeBMI + (totalRowBytes * h);
  60. bmfHeader.bfOffBits = sizeBMF + sizeBMI;
  61.   // now set up bitmap info structure
  62.   // only going to save bitmaps as 24-bit true color...these
  63.   // days there isn't much point in saving less than 24-bit
  64. bmInfo.bmiHeader.biSizeImage = totalRowBytes * h;
  65. bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  66. bmInfo.bmiHeader.biCompression = BI_RGB;
  67. bmInfo.bmiHeader.biPlanes = 1;
  68. bmInfo.bmiHeader.biBitCount = 24;
  69. bmInfo.bmiHeader.biWidth = w;
  70. bmInfo.bmiHeader.biHeight = h;
  71. if (fwrite(&bmfHeader,1,sizeBMF,fp) == sizeBMF)
  72. {
  73. if (fwrite(&bmInfo,1,sizeBMI,fp) == sizeBMI)
  74. {
  75. unsigned char * dibPtr = (unsigned char *)dib.GetBits();
  76. unsigned char * rowPtr;
  77. UINT32 off, row;
  78. switch (dib.GetBitCount()){
  79. case 24:
  80. {
  81.   // assume success
  82. result++;
  83. for (row=0; row<h; row++){
  84. off = 3 * tw * row;
  85. rowPtr = &dibPtr[off];
  86. if (fwrite(rowPtr,1,totalRowBytes,fp) != totalRowBytes)
  87. {
  88. result = 0;
  89. }
  90. }
  91. }
  92. break;
  93. case 32:
  94. {
  95. }
  96. break;
  97. }
  98. }
  99. }
  100. }
  101. fclose(fp);
  102. }
  103. return result;
  104. }
  105. int ReadDIBFile(UINT32 dataSize, unsigned char * dataBits, DIBSection& dib)
  106. {
  107. int result = 0;
  108. BITMAPFILEHEADER bmfHeader;
  109. BITMAPINFO bmInfo;
  110. UINT32 off = 0;
  111.   // check to see if we actually have some data to interpret
  112. if ((dataSize > 0) && dataBits)
  113. {
  114. unsigned long bmfHeaderSize = sizeof(bmfHeader);
  115. if ((off + bmfHeaderSize) > dataSize)
  116. {
  117.   // doh
  118. return result;
  119. }
  120. memcpy(&bmfHeader,&dataBits[off],bmfHeaderSize);
  121. off += bmfHeaderSize;
  122. unsigned long bmInfoSize = sizeof(BITMAPINFOHEADER);
  123. if ((off + bmInfoSize) > dataSize)
  124. {
  125.   // doh
  126. return result;
  127. }
  128. memcpy(&bmInfo,&dataBits[off],bmInfoSize);
  129. off += bmInfoSize;
  130. int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 
  131. 1 << bmInfo.bmiHeader.biBitCount;
  132. int w = bmInfo.bmiHeader.biWidth;
  133. int h = bmInfo.bmiHeader.biHeight;
  134. int bitcount = 24;
  135. if ((w > 0) && (h > 0))
  136. {
  137. dib.Create(w,h,bitcount);
  138. if (dib.IsCreated())
  139. {
  140. unsigned char * dst = (unsigned char *)dib.GetBits();
  141. unsigned long total_width = dib.GetTotalWidth();
  142. DWORD remainder = dataSize - bmfHeaderSize - bmInfo.bmiHeader.biSize;
  143. if ((off + remainder) > dataSize)
  144. {
  145. return result;
  146. }
  147. unsigned char * bits = new unsigned char[remainder];
  148. if (!bits)
  149. {
  150.   // outta memory
  151. return result;
  152. }
  153. memcpy(bits,&dataBits[off],remainder);
  154. int compr = BI_RGB;
  155.   // different encoding schemes are used for different bit counts
  156. switch (bmInfo.bmiHeader.biBitCount){
  157. case 1:
  158. {
  159. unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
  160. RGBQUAD * color_src = (RGBQUAD *)bits;
  161. INT32 color_index;
  162. INT32 dest_index;
  163. UINT32 pix_data_length = (w * h) / 8;
  164. CompBlock block(pix_data_length,src);
  165. short num;
  166. INT32 byte_count = bitcount/8;
  167. for (int row=0;row<h;row++){
  168. for (int col=0;col<w;col++){
  169. block.PopNumber(1,num);
  170. color_index = num;
  171. dest_index = byte_count*(row * total_width + col);
  172. dst[dest_index] = color_src[color_index].rgbBlue;
  173. dst[++dest_index] = color_src[color_index].rgbGreen;
  174. dst[++dest_index] = color_src[color_index].rgbRed;
  175. }
  176. }
  177. result++;
  178. }
  179. break;
  180. case 4:
  181. {
  182. if (bmInfo.bmiHeader.biCompression == BI_RGB)
  183. {
  184. unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
  185. RGBQUAD * color_src = (RGBQUAD *)bits;
  186. INT32 dest_index;
  187. UINT32 bytes_per_row = (w * 4 + 7)/8;
  188. if (!EVEN_NUMBER(bytes_per_row)) bytes_per_row += 3;
  189. UINT32 total_bytes = bytes_per_row * h;
  190. UINT32 extra_pixels = bytes_per_row*2 - w;
  191. CompBlock block(total_bytes,src);
  192. short num;
  193. INT32 byte_count = bitcount/8;
  194. int row = 0;
  195. int col = 0;
  196. UINT32 pixel = 0;
  197. UINT32 total_pixels = w * h;
  198. while (pixel < total_pixels){
  199. block.PopNumber(4,num);
  200. dest_index = byte_count*(row * total_width + col);
  201. dst[dest_index] = color_src[num].rgbBlue;
  202. dst[++dest_index] = color_src[num].rgbGreen;
  203. dst[++dest_index] = color_src[num].rgbRed;
  204. col++;
  205. if (col == w)
  206. {
  207. row++;
  208. col = 0;
  209. for (int i=0;i<extra_pixels;i++) block.PopNumber(4,num);
  210. }
  211. pixel++;
  212. }
  213. result++;
  214. }
  215. else if (bmInfo.bmiHeader.biCompression == BI_RLE4)
  216. {
  217. unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
  218. RGBQUAD * color_src = (RGBQUAD *)bits;
  219. INT32 dest_index;
  220. INT32 byte_count = bitcount/8;
  221. UINT32 found_end = 0;
  222. INT32 ndx = 0;
  223. UINT32 repeats;
  224. UINT32 code;
  225. int row = 0;
  226. int col = 0;
  227. while (!found_end){
  228. code = src[ndx++];
  229. if (code == 0)
  230. {
  231. code = src[ndx++];
  232. if (code == 0)
  233. {
  234. row++;
  235. col = 0;
  236. }
  237. else if (code == 1)
  238. {
  239. found_end++;
  240. }
  241. else if (code == 2)
  242. {
  243. code = src[ndx++];
  244. col += code;
  245. code = src[ndx++];
  246. row += code;
  247. }
  248. else
  249. {
  250.   // here we have a bunch of literal values
  251. repeats = code;
  252. UINT32 color1, color2;
  253. for (int i=0;i<repeats;i++){
  254. code = src[ndx++];
  255. dest_index = byte_count * (row * total_width + col);
  256. col++;
  257. color1 = (code >> 4) & 15;
  258. color2 = (code & 15);
  259. if (EVEN_NUMBER(i))
  260. {
  261. dst[dest_index] = color_src[color2].rgbBlue;
  262. dst[++dest_index] = color_src[color2].rgbGreen;
  263. dst[++dest_index] = color_src[color2].rgbRed;
  264. }
  265. else
  266. {
  267. dst[dest_index] = color_src[color1].rgbBlue;
  268. dst[++dest_index] = color_src[color1].rgbGreen;
  269. dst[++dest_index] = color_src[color1].rgbRed;
  270. }
  271. }
  272. if ((repeats%2) != 0) ndx++;
  273. }
  274. }
  275. else
  276. {
  277.   // here we're handling repeats
  278. repeats = code;
  279. code = src[ndx++];
  280. UINT32 color1 = (code >> 4) & 15;
  281. UINT32 color2 = (code & 15);
  282. for (int i=0;i<repeats;i++){
  283. dest_index = byte_count * (row * total_width + col);
  284. col++;
  285. if (EVEN_NUMBER(i))
  286. {
  287. dst[dest_index] = color_src[color2].rgbBlue;
  288. dst[++dest_index] = color_src[color2].rgbGreen;
  289. dst[++dest_index] = color_src[color2].rgbRed;
  290. }
  291. else
  292. {
  293. dst[dest_index] = color_src[color1].rgbBlue;
  294. dst[++dest_index] = color_src[color1].rgbGreen;
  295. dst[++dest_index] = color_src[color1].rgbRed;
  296. }
  297. }
  298. }
  299. }
  300. result++;
  301. }
  302. }
  303. break;
  304. case 8:
  305. {
  306. switch (bmInfo.bmiHeader.biCompression){
  307. case BI_RGB:
  308. {
  309. unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
  310. RGBQUAD * color_src = (RGBQUAD *)bits;
  311. INT32 color_index;
  312. INT32 dest_index;
  313. INT32 byte_count = bitcount/8;
  314. for (int row=0;row<h;row++){
  315. for (int col=0;col<w;col++){
  316. color_index = src[row*total_width + col];
  317. dest_index = byte_count*(row * total_width + col);
  318. dst[dest_index] = color_src[color_index].rgbBlue;
  319. dst[++dest_index] = color_src[color_index].rgbGreen;
  320. dst[++dest_index] = color_src[color_index].rgbRed;
  321. }
  322. }
  323. result++;
  324. }
  325. break;
  326. case BI_RLE8:
  327. {
  328. unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
  329. RGBQUAD * color_src = (RGBQUAD *)bits;
  330. INT32 dest_index;
  331. INT32 byte_count = bitcount/8;
  332. UINT32 found_end = 0;
  333. INT32 ndx = 0;
  334. UINT32 repeats;
  335. UINT32 code;
  336. int row = 0;
  337. int col = 0;
  338. while (!found_end){
  339. code = src[ndx++];
  340. if (code == 0)
  341. {
  342. code = src[ndx++];
  343. if (code == 0)
  344. {
  345. row++;
  346. col = 0;
  347. }
  348. else if (code == 1)
  349. {
  350. found_end++;
  351. }
  352. else if (code == 2)
  353. {
  354. code = src[ndx++];
  355. col += code;
  356. code = src[ndx++];
  357. row += code;
  358. }
  359. else
  360. {
  361.   // here we have a bunch of literal values
  362. repeats = code;
  363. for (int i=0;i<repeats;i++){
  364. code = src[ndx++];
  365. dest_index = byte_count * (row * total_width + col);
  366. col++;
  367. dst[dest_index] = color_src[code].rgbBlue;
  368. dst[++dest_index] = color_src[code].rgbGreen;
  369. dst[++dest_index] = color_src[code].rgbRed;
  370. }
  371. if ((repeats%2) != 0) ndx++;
  372. }
  373. }
  374. else
  375. {
  376.   // here we're handling repeats
  377. repeats = code;
  378. code = src[ndx++];
  379. for (int i=0;i<repeats;i++){
  380. dest_index = byte_count * (row * total_width + col);
  381. col++;
  382. dst[dest_index] = color_src[code].rgbBlue;
  383. dst[++dest_index] = color_src[code].rgbGreen;
  384. dst[++dest_index] = color_src[code].rgbRed;
  385. }
  386. }
  387. }
  388. result++;
  389. }
  390. break;
  391. }
  392. }
  393. break;
  394. case 16:
  395. {
  396. switch (bmInfo.bmiHeader.biCompression){
  397. case BI_RGB:
  398. {
  399. }
  400. break;
  401. case BI_BITFIELDS:
  402. {
  403. }
  404. break;
  405. }
  406. }
  407. break;
  408. case 24:
  409. {
  410.   // assuming compression equals BI_RGB
  411. unsigned long dst_offset;
  412. unsigned long src_offset;
  413. UINT32 bytespp, dst_row_bytes, src_row_bytes;
  414. bytespp = bitcount/8;
  415. dst_row_bytes = total_width * bytespp;
  416. //row_mod = 4 - (w%4);
  417. src_row_bytes = (w * bytespp);
  418. src_row_bytes = ((((int) src_row_bytes * 8) + 31) & ~31) >> 3;
  419. for (int row=0;row<h;row++){
  420. dst_offset = row * dst_row_bytes;
  421. src_offset = row * src_row_bytes;
  422. memcpy(&dst[dst_offset],&bits[src_offset],src_row_bytes);
  423. }
  424. result++;
  425. }
  426. break;
  427. case 32:
  428. {
  429. switch (bmInfo.bmiHeader.biCompression){
  430. case BI_RGB:
  431. {
  432. }
  433. break;
  434. case BI_BITFIELDS:
  435. {
  436. }
  437. break;
  438. }
  439. }
  440. break;
  441. }
  442. delete [] bits;
  443. }
  444. }
  445. }
  446. return result;
  447. }