-
Notifications
You must be signed in to change notification settings - Fork 0
/
bitmap.cpp
127 lines (95 loc) · 3.2 KB
/
bitmap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <assert.h>
#include "bitmap.h"
#include "error.h"
UINT LoadBitmapFromFile(IN CONST CHAR *filename, OUT Bitmap *pstBitmap){
FILE* pfile = NULL;
WORD fileType;
UINT uiErrCode = ERROR_SUCCESS;
assert(filename != NULL);
assert(pstBitmap != NULL);
pfile = fopen(filename, "rb");
if(NULL == pfile) {
return ERROR_FILE_NOT_EXIST;
} else {
fread(&fileType, 1, sizeof(WORD), pfile);
if(fileType != 0x4d42) {
return ERROR_FILE_NOT_BITMAP;
}
pstBitmap->stBmpFileHeader.usType = fileType;
fread(&pstBitmap->stBmpFileHeader.ulSize, 1, sizeof(BitmapFileHeader) - sizeof(WORD), pfile);
//读取位图信息头信息
fread(&pstBitmap->stBmpInfoHeader, 1, sizeof(BitmapInfoHeader), pfile);
}
// 仅支持24位和32位
assert(24==pstBitmap->stBmpInfoHeader.usBitCount ||
32==pstBitmap->stBmpInfoHeader.usBitCount );
UINT width = pstBitmap->stBmpInfoHeader.lWidth;
UINT height = pstBitmap->stBmpInfoHeader.lHeight;
// 分配内存空间把源图存入内存
// 计算位图的实际宽度并确保它为32的倍数
UINT l_width = GETIMAGESTORAGEWIDTH(width, pstBitmap->stBmpInfoHeader.usBitCount);
BYTE *pColorData = (BYTE *)malloc(height * l_width);
memset(pColorData, 0, height * l_width);
ULONG ulDataSize = height * l_width;
//把位图数据信息读到数组里
fread(pColorData, 1, ulDataSize, pfile);
pstBitmap->pColorData = pColorData;
fclose(pfile);
return uiErrCode;
}
STATIC UINT _file_write(const void* buffer, size_t size, FILE* stream) {
size_t remain = size;
size_t tmp = 0;
UINT uiFaildCnt = 0;
assert(NULL != buffer);
assert(NULL != stream);
while(0 < remain) {
tmp = fwrite(buffer, 1, remain, stream);
remain -= tmp;
if(tmp <=0 ) {
++uiFaildCnt;
}
if(uiFaildCnt>=5) {
return ERROR_FILE_WRITE_FAILD;
}
}
return ERROR_SUCCESS;
}
UINT SaveBitmapToFile(IN CONST CHAR *filename, IN CONST Bitmap *pstBitmap) {
UINT uiErrCode = ERROR_FAILD;
FILE* pfile = NULL;
assert(filename != NULL);
assert(pstBitmap != NULL);
pfile = fopen(filename, "wb");
if(NULL == pfile) {
uiErrCode = ERROR_FILE_OPEN_FAILD;
} else {
uiErrCode = _file_write(&pstBitmap->stBmpFileHeader, sizeof(pstBitmap->stBmpFileHeader), pfile);
if(ERROR_SUCCESS == uiErrCode)
uiErrCode = _file_write(&pstBitmap->stBmpInfoHeader, sizeof(pstBitmap->stBmpInfoHeader), pfile);
if(ERROR_SUCCESS == uiErrCode)
uiErrCode = _file_write(pstBitmap->pColorData, pstBitmap->stBmpInfoHeader.ulSizeImage, pfile);
}
fclose(pfile);
return uiErrCode;
}
UINT ReleaseBitmap(IN Bitmap *pstBitmap) {
if(NULL != pstBitmap->pColorData) {
free(pstBitmap->pColorData);
pstBitmap->pColorData = NULL;
}
return ERROR_SUCCESS;
}
UINT CloneBitmap(CONST IN Bitmap *pstBitmap, OUT Bitmap *pstNewBitmap) {
assert(NULL != pstBitmap);
assert(NULL != pstNewBitmap);
*pstNewBitmap = *pstBitmap;
pstNewBitmap->pColorData = NULL;
pstNewBitmap->pColorData = malloc(pstBitmap->stBmpInfoHeader.ulSizeImage);
if(NULL == pstNewBitmap->pColorData)
return ERROR_MALLOC_FAILD;
return ERROR_SUCCESS;
}