dibbmp.cpp
上传用户:lbr_007
上传日期:2019-05-31
资源大小:282k
文件大小:13k
- // dibbmp.cpp
- //
- #include "stdafx.h"
- #include <dibbmp.h>
- #define EVEN_NUMBER(i) ((i%2)==0?1:0)
- int OpenBMP2DIB(const char * filename, DIBSection& dib)
- {
- int result = 0;
- FILE * fp = fopen(filename,"rb");
- if (fp)
- {
- // seek to the end of the file
- fseek(fp,0l,SEEK_END);
-
- // get the file position in bytes (file size)
- UINT32 fileSize = ftell(fp);
- // seek back to the beginning again
- fseek(fp,0l,SEEK_SET);
- // if the file has data: pull it in and interpret
- if (fileSize > 0)
- {
- unsigned char * fileData = new unsigned char[fileSize];
- if (fileData)
- {
- memset(fileData,0,(size_t)fileSize);
- if (fread(fileData,sizeof(char),fileSize,fp) == fileSize)
- {
- result = ReadDIBFile(fileSize,fileData,dib);
- }
- // ok, the file data has been pulled in and hopefully
- // it has been interpreted, so we have no more use for it
- delete [] fileData;
- }
- }
- }
- return result;
- }
- int SaveDIB2BMP(const char * filename, DIBSection& dib)
- {
- int result = 0;
- FILE * fp = fopen(filename,"wb");
- if (fp)
- {
- if (dib.IsCreated())
- {
- BITMAPFILEHEADER bmfHeader;
- BITMAPINFO bmInfo;
- // zero out everything
- memset(&bmfHeader,0,sizeof(BITMAPFILEHEADER));
- memset(&bmInfo,0,sizeof(BITMAPINFO));
- UINT32 h = dib.Height();
- UINT32 w = dib.Width();
- UINT32 rowBytes = w * 3;
- UINT32 totalRowBytes = ((((int) rowBytes * 8) + 31) & ~31) >> 3;
- UINT32 tw = dib.GetTotalWidth();
-
- UINT32 sizeBMF = sizeof(BITMAPFILEHEADER);
- UINT32 sizeBMI = sizeof(BITMAPINFOHEADER);
- // now set up necessary members of the file header
- memcpy(&bmfHeader.bfType,"BM",2);
- bmfHeader.bfSize = sizeBMF + sizeBMI + (totalRowBytes * h);
- bmfHeader.bfOffBits = sizeBMF + sizeBMI;
- // now set up bitmap info structure
- // only going to save bitmaps as 24-bit true color...these
- // days there isn't much point in saving less than 24-bit
- bmInfo.bmiHeader.biSizeImage = totalRowBytes * h;
- bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmInfo.bmiHeader.biCompression = BI_RGB;
- bmInfo.bmiHeader.biPlanes = 1;
- bmInfo.bmiHeader.biBitCount = 24;
- bmInfo.bmiHeader.biWidth = w;
- bmInfo.bmiHeader.biHeight = h;
- if (fwrite(&bmfHeader,1,sizeBMF,fp) == sizeBMF)
- {
- if (fwrite(&bmInfo,1,sizeBMI,fp) == sizeBMI)
- {
- unsigned char * dibPtr = (unsigned char *)dib.GetBits();
- unsigned char * rowPtr;
- UINT32 off, row;
- switch (dib.GetBitCount()){
- case 24:
- {
- // assume success
- result++;
- for (row=0; row<h; row++){
- off = 3 * tw * row;
- rowPtr = &dibPtr[off];
- if (fwrite(rowPtr,1,totalRowBytes,fp) != totalRowBytes)
- {
- result = 0;
- }
- }
- }
- break;
- case 32:
- {
- }
- break;
- }
- }
- }
- }
- fclose(fp);
- }
- return result;
- }
- int ReadDIBFile(UINT32 dataSize, unsigned char * dataBits, DIBSection& dib)
- {
- int result = 0;
- BITMAPFILEHEADER bmfHeader;
- BITMAPINFO bmInfo;
- UINT32 off = 0;
- // check to see if we actually have some data to interpret
- if ((dataSize > 0) && dataBits)
- {
- unsigned long bmfHeaderSize = sizeof(bmfHeader);
- if ((off + bmfHeaderSize) > dataSize)
- {
- // doh
- return result;
- }
- memcpy(&bmfHeader,&dataBits[off],bmfHeaderSize);
- off += bmfHeaderSize;
- unsigned long bmInfoSize = sizeof(BITMAPINFOHEADER);
- if ((off + bmInfoSize) > dataSize)
- {
- // doh
- return result;
- }
- memcpy(&bmInfo,&dataBits[off],bmInfoSize);
- off += bmInfoSize;
- int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
- 1 << bmInfo.bmiHeader.biBitCount;
- int w = bmInfo.bmiHeader.biWidth;
- int h = bmInfo.bmiHeader.biHeight;
- int bitcount = 24;
- if ((w > 0) && (h > 0))
- {
- dib.Create(w,h,bitcount);
- if (dib.IsCreated())
- {
- unsigned char * dst = (unsigned char *)dib.GetBits();
- unsigned long total_width = dib.GetTotalWidth();
- DWORD remainder = dataSize - bmfHeaderSize - bmInfo.bmiHeader.biSize;
- if ((off + remainder) > dataSize)
- {
- return result;
- }
- unsigned char * bits = new unsigned char[remainder];
- if (!bits)
- {
- // outta memory
- return result;
- }
- memcpy(bits,&dataBits[off],remainder);
- int compr = BI_RGB;
- // different encoding schemes are used for different bit counts
- switch (bmInfo.bmiHeader.biBitCount){
- case 1:
- {
- unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
- RGBQUAD * color_src = (RGBQUAD *)bits;
- INT32 color_index;
- INT32 dest_index;
- UINT32 pix_data_length = (w * h) / 8;
- CompBlock block(pix_data_length,src);
- short num;
- INT32 byte_count = bitcount/8;
-
- for (int row=0;row<h;row++){
- for (int col=0;col<w;col++){
- block.PopNumber(1,num);
- color_index = num;
- dest_index = byte_count*(row * total_width + col);
- dst[dest_index] = color_src[color_index].rgbBlue;
- dst[++dest_index] = color_src[color_index].rgbGreen;
- dst[++dest_index] = color_src[color_index].rgbRed;
- }
- }
- result++;
- }
- break;
- case 4:
- {
- if (bmInfo.bmiHeader.biCompression == BI_RGB)
- {
- unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
- RGBQUAD * color_src = (RGBQUAD *)bits;
- INT32 dest_index;
- UINT32 bytes_per_row = (w * 4 + 7)/8;
- if (!EVEN_NUMBER(bytes_per_row)) bytes_per_row += 3;
- UINT32 total_bytes = bytes_per_row * h;
- UINT32 extra_pixels = bytes_per_row*2 - w;
- CompBlock block(total_bytes,src);
- short num;
- INT32 byte_count = bitcount/8;
-
- int row = 0;
- int col = 0;
- UINT32 pixel = 0;
- UINT32 total_pixels = w * h;
- while (pixel < total_pixels){
- block.PopNumber(4,num);
- dest_index = byte_count*(row * total_width + col);
- dst[dest_index] = color_src[num].rgbBlue;
- dst[++dest_index] = color_src[num].rgbGreen;
- dst[++dest_index] = color_src[num].rgbRed;
- col++;
- if (col == w)
- {
- row++;
- col = 0;
- for (int i=0;i<extra_pixels;i++) block.PopNumber(4,num);
- }
- pixel++;
- }
- result++;
- }
- else if (bmInfo.bmiHeader.biCompression == BI_RLE4)
- {
- unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
- RGBQUAD * color_src = (RGBQUAD *)bits;
- INT32 dest_index;
- INT32 byte_count = bitcount/8;
- UINT32 found_end = 0;
- INT32 ndx = 0;
- UINT32 repeats;
- UINT32 code;
- int row = 0;
- int col = 0;
- while (!found_end){
- code = src[ndx++];
- if (code == 0)
- {
- code = src[ndx++];
- if (code == 0)
- {
- row++;
- col = 0;
- }
- else if (code == 1)
- {
- found_end++;
- }
- else if (code == 2)
- {
- code = src[ndx++];
- col += code;
- code = src[ndx++];
- row += code;
- }
- else
- {
- // here we have a bunch of literal values
- repeats = code;
- UINT32 color1, color2;
- for (int i=0;i<repeats;i++){
- code = src[ndx++];
- dest_index = byte_count * (row * total_width + col);
- col++;
- color1 = (code >> 4) & 15;
- color2 = (code & 15);
- if (EVEN_NUMBER(i))
- {
- dst[dest_index] = color_src[color2].rgbBlue;
- dst[++dest_index] = color_src[color2].rgbGreen;
- dst[++dest_index] = color_src[color2].rgbRed;
- }
- else
- {
- dst[dest_index] = color_src[color1].rgbBlue;
- dst[++dest_index] = color_src[color1].rgbGreen;
- dst[++dest_index] = color_src[color1].rgbRed;
- }
- }
- if ((repeats%2) != 0) ndx++;
- }
- }
- else
- {
- // here we're handling repeats
- repeats = code;
- code = src[ndx++];
- UINT32 color1 = (code >> 4) & 15;
- UINT32 color2 = (code & 15);
- for (int i=0;i<repeats;i++){
- dest_index = byte_count * (row * total_width + col);
- col++;
- if (EVEN_NUMBER(i))
- {
- dst[dest_index] = color_src[color2].rgbBlue;
- dst[++dest_index] = color_src[color2].rgbGreen;
- dst[++dest_index] = color_src[color2].rgbRed;
- }
- else
- {
- dst[dest_index] = color_src[color1].rgbBlue;
- dst[++dest_index] = color_src[color1].rgbGreen;
- dst[++dest_index] = color_src[color1].rgbRed;
- }
- }
- }
- }
- result++;
- }
- }
- break;
- case 8:
- {
- switch (bmInfo.bmiHeader.biCompression){
- case BI_RGB:
- {
- unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
- RGBQUAD * color_src = (RGBQUAD *)bits;
- INT32 color_index;
- INT32 dest_index;
- INT32 byte_count = bitcount/8;
-
- for (int row=0;row<h;row++){
- for (int col=0;col<w;col++){
- color_index = src[row*total_width + col];
- dest_index = byte_count*(row * total_width + col);
- dst[dest_index] = color_src[color_index].rgbBlue;
- dst[++dest_index] = color_src[color_index].rgbGreen;
- dst[++dest_index] = color_src[color_index].rgbRed;
- }
- }
- result++;
- }
- break;
- case BI_RLE8:
- {
- unsigned char * src = &bits[nColors*sizeof(RGBQUAD)];
- RGBQUAD * color_src = (RGBQUAD *)bits;
- INT32 dest_index;
- INT32 byte_count = bitcount/8;
- UINT32 found_end = 0;
- INT32 ndx = 0;
- UINT32 repeats;
- UINT32 code;
- int row = 0;
- int col = 0;
- while (!found_end){
- code = src[ndx++];
- if (code == 0)
- {
- code = src[ndx++];
- if (code == 0)
- {
- row++;
- col = 0;
- }
- else if (code == 1)
- {
- found_end++;
- }
- else if (code == 2)
- {
- code = src[ndx++];
- col += code;
- code = src[ndx++];
- row += code;
- }
- else
- {
- // here we have a bunch of literal values
- repeats = code;
- for (int i=0;i<repeats;i++){
- code = src[ndx++];
- dest_index = byte_count * (row * total_width + col);
- col++;
- dst[dest_index] = color_src[code].rgbBlue;
- dst[++dest_index] = color_src[code].rgbGreen;
- dst[++dest_index] = color_src[code].rgbRed;
- }
- if ((repeats%2) != 0) ndx++;
- }
- }
- else
- {
- // here we're handling repeats
- repeats = code;
- code = src[ndx++];
- for (int i=0;i<repeats;i++){
- dest_index = byte_count * (row * total_width + col);
- col++;
- dst[dest_index] = color_src[code].rgbBlue;
- dst[++dest_index] = color_src[code].rgbGreen;
- dst[++dest_index] = color_src[code].rgbRed;
- }
- }
- }
- result++;
- }
- break;
- }
- }
- break;
- case 16:
- {
- switch (bmInfo.bmiHeader.biCompression){
- case BI_RGB:
- {
- }
- break;
- case BI_BITFIELDS:
- {
- }
- break;
- }
- }
- break;
- case 24:
- {
- // assuming compression equals BI_RGB
- unsigned long dst_offset;
- unsigned long src_offset;
- UINT32 bytespp, dst_row_bytes, src_row_bytes;
- bytespp = bitcount/8;
- dst_row_bytes = total_width * bytespp;
- //row_mod = 4 - (w%4);
- src_row_bytes = (w * bytespp);
- src_row_bytes = ((((int) src_row_bytes * 8) + 31) & ~31) >> 3;
- for (int row=0;row<h;row++){
- dst_offset = row * dst_row_bytes;
- src_offset = row * src_row_bytes;
- memcpy(&dst[dst_offset],&bits[src_offset],src_row_bytes);
- }
- result++;
- }
- break;
- case 32:
- {
- switch (bmInfo.bmiHeader.biCompression){
- case BI_RGB:
- {
- }
- break;
- case BI_BITFIELDS:
- {
- }
- break;
- }
- }
- break;
- }
- delete [] bits;
- }
- }
- }
- return result;
- }