?? dcbm.c
字號:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crblib/inc.h>
#include <crblib/fileutil.h>
#include "dcbm.h"
#include "winutil.h"
#pragma warning(disable : 4244)
/*********************************************/
#define LBM_cleanUp(err) if(1) { char str[200]; strcpy(str,fName); strcat(str,":"); strcat(str,err); MessageBox( windowH, str , "loadBitMap error", MB_OK ); return( NULL); } else
#define GET_2B(array,offset) ((uword) (ubyte)(array[offset+0]) + \
(((uword) (ubyte)(array[offset+1])) << 8))
#define GET_4B(array,offset) ((ulong) (ubyte)(array[offset+0]) + \
(((ulong) (ubyte)(array[offset+1])) << 8) + \
(((ulong) (ubyte)(array[offset+2])) << 16) + \
(((ulong) (ubyte)(array[offset+3])) << 24))
HBITMAP LoadBitMap(HWND windowH, HDC hdc, char * fName )
{
FILE * inFile;
BITMAPINFO * bmi;
void * bmdata;
HBITMAP hbm;
if ( (inFile = fopen(fName,"rb")) == NULL ) {
char errstr[80];
sprintf(errstr,"fopen failed, error : %d\n\0",errno);
perror("fopen bitmap:");
LBM_cleanUp(errstr);
}
{
ubyte bmpfileheader[14];
ubyte bmpinfoheader[64];
ulong bfOffBits;
ulong headerSize;
ulong biWidth = 0;
long biHeight = 0;
uword biPlanes;
ulong biCompression;
ulong biClrUsed = 0;
int mapentrysize = 0; /* 0 indicates no colormap */
long bPad;
ulong row_width;
uword bits_per_pixel;
/* Read and verify the bitmap file header */
if (! FReadOk(inFile, bmpfileheader, 14))
LBM_cleanUp("read short");
if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */
LBM_cleanUp("bmp sign");
bfOffBits = (ulong) GET_4B(bmpfileheader,10);
/* We ignore the remaining fileheader fields */
/* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
* or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which.
*/
if (! FReadOk(inFile, bmpinfoheader, 4))
LBM_cleanUp("read short");
headerSize = (ulong) GET_4B(bmpinfoheader,0);
if (headerSize < 12 || headerSize > 64)
LBM_cleanUp("bad header size");
if (! FReadOk(inFile, bmpinfoheader+4, headerSize-4))
LBM_cleanUp("read short");
switch ((int) headerSize) {
/* OS/2 1.x support removed */
case 40:
case 64:
/* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
/* or OS/2 2.x header, which has additional fields that we ignore */
biWidth = GET_4B(bmpinfoheader,4);
biHeight = GET_4B(bmpinfoheader,8);
biPlanes = GET_2B(bmpinfoheader,12);
bits_per_pixel = (int) GET_2B(bmpinfoheader,14);
biCompression = GET_4B(bmpinfoheader,16);
biClrUsed = GET_4B(bmpinfoheader,32);
if ( biClrUsed == 0 ) biClrUsed = 256;
/* biSizeImage, biClrImportant fields are ignored */
switch (bits_per_pixel) {
case 8: /* colormapped image */
mapentrysize = 4; /* Windows uses RGBQUAD colormap */
break;
case 24: /* RGB image */
mapentrysize = 0;
break;
default:
LBM_cleanUp("bad depth");
break;
}
break;
default:
LBM_cleanUp("bad header len");
break;
}
/* Compute distance to bitmap data --- will adjust for colormap below */
bPad = bfOffBits - (headerSize + 14);
if ( ( bmi = malloc( sizeof(BITMAPINFO) + (mapentrysize * biClrUsed) ) ) == NULL )
LBM_cleanUp("malloc");
memcpy((char *)bmi,bmpinfoheader,headerSize);
/* Read the colormap, if any */
if (mapentrysize > 0 && biClrUsed > 0) {
if (! FReadOk(inFile, ((char *)bmi) + headerSize , (mapentrysize * biClrUsed)))
LBM_cleanUp("read short");
/* account for size of colormap */
bPad -= biClrUsed * mapentrysize;
}
/* Skip any remaining pad bytes */
if (bPad < 0) /* incorrect bfOffBits value? */
LBM_cleanUp("bad header length");
else if ( bPad > 0 ) {
fseek(inFile,bPad,SEEK_CUR);
}
/* Compute row width in file, including padding to 4-byte boundary */
if (bits_per_pixel == 24)
row_width = biWidth * 3;
else
row_width = biWidth;
row_width = ((((row_width-1)>>2) + 1)<<2) ;
if ( (bmdata = malloc(row_width * abs(biHeight))) == NULL )
LBM_cleanUp("malloc failed");
FRead(inFile,bmdata,row_width * abs(biHeight)); // may read short due to compression
}
fclose(inFile);
hbm = CreateDIBitmap( hdc, &(bmi->bmiHeader) , CBM_INIT , bmdata, bmi , DIB_RGB_COLORS );
if ( hbm == NULL )
LBM_cleanUp("CreateDIBitmap failed!");
free(bmdata);
free(bmi);
return hbm;
}
DCBM * LoadDCBM( HWND hwnd, HDC hdc, char *file)
{
HBITMAP bmp;
DCBM * ret;
bmp = LoadBitMap(hwnd,hdc,file);
if ( ! bmp ) return NULL;
ret = MakeDCBM(hdc,bmp);
DeleteObject(bmp);
return ret;
}
DCBM * MakeDCBM( HDC hdc, HBITMAP bitmap )
{
DCBM *dcbm;
BITMAP bitmapbuff;
HDC memorydc;
POINT size;
bool good = false;
if ( (memorydc = CreateCompatibleDC( hdc )) == NULL ) {
ShowLastError("Create memory DC");
return 0;
}
SelectObject( memorydc, bitmap );
SetMapMode( memorydc, GetMapMode( hdc ) );
GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );
DPtoLP( memorydc, &size, 1 );
if ( (dcbm = malloc(sizeof(DCBM))) ) {
dcbm->size.x = bitmapbuff.bmWidth;
dcbm->size.y = bitmapbuff.bmHeight;
dcbm->rasterOp = SRCCOPY;
if ( (dcbm->bitmapdc = CreateCompatibleDC( hdc )) ) {
SelectObject(dcbm->bitmapdc,
CreateBitmap(dcbm->size.x,dcbm->size.y,bitmapbuff.bmPlanes,bitmapbuff.bmBitsPixel,NULL) );
SetMapMode( dcbm->bitmapdc, GetMapMode( hdc ) );
if ( BitBlt( dcbm->bitmapdc, 0, 0, dcbm->size.x, dcbm->size.y, memorydc, 0, 0, dcbm->rasterOp) ) {
good = true;
} else {
ShowLastError("Bit Blt");
}
} else {
ShowLastError("Create Compatible DC");
}
}
DeleteDC( memorydc );
if ( ! good ) {
FreeDCBM(dcbm);
return NULL;
}
return(dcbm);
}
DCBM * MakeDCBMHalf( HDC hdc, HBITMAP bitmap )
{
DCBM *dcbm;
BITMAP bitmapbuff;
HDC memorydc;
POINT size;
if ( (memorydc = CreateCompatibleDC( hdc )) == NULL ) {
ShowLastError("Create memory DC");
return 0;
}
SelectObject( memorydc, bitmap );
SetMapMode( memorydc, GetMapMode( hdc ) );
GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );
size.x = bitmapbuff.bmWidth;
size.y = bitmapbuff.bmHeight;
DPtoLP( memorydc, &size, 1 );
dcbm = new(DCBM);
dcbm->size.x = size.x/2;
dcbm->size.y = size.y/2;
dcbm->bitmapdc = CreateCompatibleDC( hdc );
SelectObject(dcbm->bitmapdc,
CreateBitmap(dcbm->size.x,dcbm->size.y,bitmapbuff.bmPlanes,bitmapbuff.bmBitsPixel,NULL) );
SetMapMode( dcbm->bitmapdc, GetMapMode( hdc ) );
SetStretchBltMode(memorydc,HALFTONE);
SetBrushOrgEx(memorydc,0,0,NULL);
if ( ! StretchBlt( dcbm->bitmapdc, 0, 0, dcbm->size.x, dcbm->size.y, memorydc, 0, 0, size.x, size.y, dcbm->rasterOp) ) {
FreeDCBM(dcbm);
dcbm = NULL;
}
DeleteDC( memorydc );
dcbm->rasterOp = SRCCOPY;
return(dcbm);
}
DCBM * MakeDCBMscaled( HDC hdc, HBITMAP bitmap, float x_scale, float y_scale)
{
DCBM *dcbm;
BITMAP bitmapbuff;
HDC memorydc;
POINT size;
int x,y,sizex,sizey;
if ( (memorydc = CreateCompatibleDC( hdc )) == NULL ) {
ShowLastError("Create memory DC");
return 0;
}
SelectObject( memorydc, bitmap );
SetMapMode( memorydc, GetMapMode( hdc ) );
GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );
size.x = bitmapbuff.bmWidth;
size.y = bitmapbuff.bmHeight;
DPtoLP( memorydc, &size, 1 );
dcbm = malloc(sizeof(DCBM));
dcbm->size.x = abs(x_scale) * size.x;
dcbm->size.y = abs(y_scale) * size.y;
dcbm->bitmapdc = CreateCompatibleDC( hdc );
SelectObject(dcbm->bitmapdc,
CreateBitmap(dcbm->size.x,dcbm->size.y,bitmapbuff.bmPlanes,bitmapbuff.bmBitsPixel,NULL) );
SetMapMode( dcbm->bitmapdc, GetMapMode( hdc ) );
SetStretchBltMode(memorydc,HALFTONE);
SetBrushOrgEx(memorydc,0,0,NULL);
x = y = 0;
sizex = x_scale * size.x;
sizey = y_scale * size.y;
if ( sizex < 0 ) x += abs(sizex) -1;
if ( sizey < 0 ) y += abs(sizey) -1;
if ( ! StretchBlt( dcbm->bitmapdc, x, y, sizex, sizey, memorydc, 0, 0, size.x, size.y, dcbm->rasterOp) ) {
FreeDCBM(dcbm);
dcbm = NULL;
}
DeleteDC( memorydc );
dcbm->rasterOp = SRCCOPY;
return(dcbm);
}
DCBM * CopyDCBM_stretching(DCBM *src,float x_scale,float y_scale)
{
DCBM *dcbm;
int sizex,sizey,x,y;
if ( (dcbm = malloc(sizeof(DCBM))) == NULL )
return NULL;
sizex = (((float)src->size.x) * x_scale);
sizey = (((float)src->size.y) * y_scale);
dcbm->size.x = abs(sizex);
dcbm->size.y = abs(sizey);
dcbm->bitmapdc = CreateCompatibleDC( src->bitmapdc );
SelectObject(dcbm->bitmapdc,
CreateCompatibleBitmap(src->bitmapdc,dcbm->size.x,dcbm->size.y));
SetMapMode( dcbm->bitmapdc, GetMapMode( src->bitmapdc ) );
SetStretchBltMode(src->bitmapdc,HALFTONE);
SetBrushOrgEx(src->bitmapdc,0,0,NULL);
x = y = 0;
if ( sizex < 0 ) x += abs(sizex) -1;
if ( sizey < 0 ) y += abs(sizey) -1;
if ( ! StretchBlt( dcbm->bitmapdc, x, y, sizex, sizey,
src->bitmapdc, 0, 0, src->size.x, src->size.y,
dcbm->rasterOp) ) {
FreeDCBM(dcbm);
dcbm = NULL;
}
return dcbm;
}
DCBMA * CopyDCBMA_stretching(DCBMA *src,float x_scale,float y_scale)
{
DCBMA * a;
int i;
if ( (a = malloc(sizeof(DCBMA))) == NULL ) return NULL;
a->numFrames = src->numFrames;
if ( (a->frames = malloc(a->numFrames*sizeofpointer) ) == NULL ) { free(a); return NULL; }
a->size.x = a->size.y = 0;
for(i=0;i<a->numFrames;i++) {
a->frames[i] = CopyDCBM_stretching(src->frames[i],x_scale,y_scale);
if ( a->frames[i] == NULL ) {
FreeDCBMA(a);
return NULL;
} else {
if ( a->frames[i]->size.x > a->size.x )
a->size.x = a->frames[i]->size.x;
if ( a->frames[i]->size.y > a->size.y )
a->size.y = a->frames[i]->size.y;
}
}
return a;
}
void FreeDCBM( DCBM * dcbm )
{
DeleteDC( dcbm->bitmapdc );
free(dcbm);
}
void DrawDCBMcenter( HDC hdc, DCBM *dcbm, long x, long y )
{
x -= dcbm->size.x>>1;
y -= dcbm->size.y>>1;
DrawDCBM(hdc,dcbm,x,y);
}
void DrawDCBMinRectnoGrow( HDC hdc, DCBM *dcbm, RECT *r )
{
if ( dcbm->size.x < width(*r) && dcbm->size.y < height(*r) ) {
DrawDCBMcenter(hdc,dcbm,midx(*r),midy(*r));
} else {
DrawDCBMScaling(hdc,dcbm,r->left,r->top,width(*r),height(*r));
}
}
void DrawDCBMinRect( HDC hdc, DCBM *dcbm, RECT *r )
{
DrawDCBMScaling(hdc,dcbm,r->left,r->top,width(*r),height(*r));
}
void DrawDCBMScaling( HDC hdc, DCBM *dcbm, long x, long y, long sizex, long sizey )
{
if ( ! dcbm ) return;
SetStretchBltMode(dcbm->bitmapdc,HALFTONE);
SetBrushOrgEx(dcbm->bitmapdc,0,0,NULL);
if ( sizex < 0 ) x += abs(sizex) -1;
if ( sizey < 0 ) y += abs(sizey) -1;
StretchBlt( hdc, x, y, sizex, sizey,
dcbm->bitmapdc, 0, 0, dcbm->size.x, dcbm->size.y,
dcbm->rasterOp);
}
void DrawDCBM( HDC hdc, DCBM *dcbm, long x, long y )
{
if ( ! dcbm ) return;
BitBlt( hdc, x, y, dcbm->size.x, dcbm->size.y, dcbm->bitmapdc, 0, 0, dcbm->rasterOp);
}
DCBMA * LoadDCBMA(HWND windowH,int frames,char ** files)
{
DCBMA * a;
HBITMAP bmp;
HDC hdc;
int i;
if ( (a = malloc(sizeof(DCBMA))) == NULL ) return NULL;
a->numFrames = frames;
if ( (a->frames = malloc(frames*sizeofpointer)) == NULL ) { free(a); return NULL; }
hdc = GetDC(windowH);
for(i=0;i<frames;i++) {
bmp = LoadBitMap(windowH,hdc,files[i]);
a->frames[i] = MakeDCBM(hdc,bmp);
DeleteObject(bmp);
}
ReleaseDC(windowH,hdc);
a->size.x = a->size.y = 0;
for(i=0;i<frames;i++) {
if ( a->frames[i] == NULL ) {
FreeDCBMA(a);
return NULL;
} else {
if ( a->frames[i]->size.x > a->size.x )
a->size.x = a->frames[i]->size.x;
if ( a->frames[i]->size.y > a->size.y )
a->size.y = a->frames[i]->size.y;
}
}
return a;
}
void DrawDCBMA( HWND w, DCBMA *DCBMA, long x, long y )
{
int i;
HDC hdc;
for (i=0;i<DCBMA->numFrames;i++) {
hdc = GetDC(w);
DrawDCBM(hdc,DCBMA->frames[i],x,y);
ReleaseDC(w,hdc);
await(50); /* wait a 20th of a second. very half-assed */
}
}
void DrawDCBMAScaling( HWND w, DCBMA *DCBMA, long x, long y, long sizex, long sizey )
{
int i;
HDC hdc;
for (i=0;i<DCBMA->numFrames;i++) {
hdc = GetDC(w);
DrawDCBMScaling(hdc,DCBMA->frames[i],x,y,sizex,sizey);
ReleaseDC(w,hdc);
await(50); /* wait a 20th of a second. very half-assed */
}
}
void DrawDCBMAcenter( HWND w, DCBMA *DCBMA, long x, long y )
{
x -= DCBMA->size.x>>1;
y -= DCBMA->size.y>>1;
DrawDCBMA(w,DCBMA,x,y);
}
void DrawDCBMAcenterScaling( HWND w, DCBMA *DCBMA, long x, long y, long sizex, long sizey )
{
x -= sizex>>1;
y -= sizey>>1;
DrawDCBMAScaling(w,DCBMA,x,y,sizex,sizey);
}
void FreeDCBMA( DCBMA * dcbma )
{
int i;
if ( !dcbma ) return;
for (i=0;i<dcbma->numFrames;i++) {
if ( dcbma->frames[i] ) FreeDCBM(dcbma->frames[i]);
}
free(dcbma->frames);
free(dcbma);
}
void DrawBitMap( HDC hdc, HBITMAP bitmap, long x, long y )
{
BITMAP bitmapbuff;
HDC memorydc;
POINT origin;
POINT size;
if ( ! bitmap ) return;
memorydc = CreateCompatibleDC( hdc );
SelectObject( memorydc, bitmap );
SetMapMode( memorydc, GetMapMode( hdc ) );
GetObject( bitmap, sizeof( BITMAP ), (LPSTR) &bitmapbuff );
origin.x = x;
origin.y = y;
size.x = bitmapbuff.bmWidth;
size.y = bitmapbuff.bmHeight;
DPtoLP( hdc, &origin, 1 );
DPtoLP( memorydc, &size, 1 );
BitBlt( hdc, origin.x, origin.y, size.x, size.y, memorydc, 0, 0, SRCCOPY);
DeleteDC( memorydc );
} /* DrawBitmap */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -