?? winbmp.c
字號:
/* $Id: winbmp.c,v 1.14 2004/10/19 07:34:54 weiym Exp $**** Low-level Windows bitmap read/save function.**** Copyright (C) 2003 Feynman Software.** Copyright (C) 2000 ~ 2002 Wei Yongming.**** Create date: 2000/08/26, derived from original bitmap.c**** Current maintainer: Wei Yongming.*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "gdi.h"#include "readbmp.h"/************************* Bitmap-related structures ************************/typedef struct tagRGBTRIPLE{ BYTE rgbtBlue; BYTE rgbtGreen; BYTE rgbtRed;} RGBTRIPLE;typedef RGBTRIPLE* PRGBTRIPLE;typedef struct tagRGBQUAD{ BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved;} RGBQUAD;typedef RGBQUAD* PRGBQUAD;#define SIZEOF_RGBQUAD 4#define BI_RGB 0#define BI_RLE8 1#define BI_RLE4 2#define BI_BITFIELDS 3#define SIZEOF_BMFH 14#define SIZEOF_BMIH 40#define OS2INFOHEADERSIZE 12#define WININFOHEADERSIZE 40typedef struct BITMAPFILEHEADER{ unsigned short bfType; unsigned long bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned long bfOffBits;} BITMAPFILEHEADER;/* Used for both OS/2 and Windows BMP. * Contains only the parameters needed to load the image */typedef struct BITMAPINFOHEADER{ unsigned long biWidth; unsigned long biHeight; unsigned short biBitCount; unsigned long biCompression;} BITMAPINFOHEADER;typedef struct WINBMPINFOHEADER /* size: 40 */{ unsigned long biSize; unsigned long biWidth; unsigned long biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned long biCompression; unsigned long biSizeImage; unsigned long biXPelsPerMeter; unsigned long biYPelsPerMeter; unsigned long biClrUsed; unsigned long biClrImportant;} WINBMPINFOHEADER;typedef struct OS2BMPINFOHEADER /* size: 12 */{ unsigned long biSize; unsigned short biWidth; unsigned short biHeight; unsigned short biPlanes; unsigned short biBitCount;} OS2BMPINFOHEADER;/* read_bmfileheader: * Reads a BMP file header and check that it has the BMP magic number. */static int read_bmfileheader(MG_RWops *f, BITMAPFILEHEADER *fileheader){ fileheader->bfType = fp_igetw(f); fileheader->bfSize= fp_igetl(f); fileheader->bfReserved1= fp_igetw(f); fileheader->bfReserved2= fp_igetw(f); fileheader->bfOffBits= fp_igetl(f); if (fileheader->bfType != 19778) return -1; return 0;}/* read_win_bminfoheader: * Reads information from a BMP file header. */static int read_win_bminfoheader(MG_RWops *f, BITMAPINFOHEADER *infoheader){ WINBMPINFOHEADER win_infoheader; win_infoheader.biWidth = fp_igetl(f); win_infoheader.biHeight = fp_igetl(f); win_infoheader.biPlanes = fp_igetw(f); win_infoheader.biBitCount = fp_igetw(f); win_infoheader.biCompression = fp_igetl(f); win_infoheader.biSizeImage = fp_igetl(f); win_infoheader.biXPelsPerMeter = fp_igetl(f); win_infoheader.biYPelsPerMeter = fp_igetl(f); win_infoheader.biClrUsed = fp_igetl(f); win_infoheader.biClrImportant = fp_igetl(f); infoheader->biWidth = win_infoheader.biWidth; infoheader->biHeight = win_infoheader.biHeight; infoheader->biBitCount = win_infoheader.biBitCount; infoheader->biCompression = win_infoheader.biCompression; return 0;}/* read_os2_bminfoheader: * Reads information from an OS/2 format BMP file header. */static int read_os2_bminfoheader(MG_RWops *f, BITMAPINFOHEADER *infoheader){ OS2BMPINFOHEADER os2_infoheader; os2_infoheader.biWidth = fp_igetw(f); os2_infoheader.biHeight = fp_igetw(f); os2_infoheader.biPlanes = fp_igetw(f); os2_infoheader.biBitCount = fp_igetw(f); infoheader->biWidth = os2_infoheader.biWidth; infoheader->biHeight = os2_infoheader.biHeight; infoheader->biBitCount = os2_infoheader.biBitCount; infoheader->biCompression = 0; return 0;}/* read_bmicolors: * Loads the color palette for 1,4,8 bit formats. */static void read_bmicolors (int ncols, RGB *pal, MG_RWops *f, int win_flag){ int i; for (i=0; i<ncols; i++) { pal[i].b = fp_getc(f); pal[i].g = fp_getc(f); pal[i].r = fp_getc(f); if (win_flag) fp_getc(f); }}/* read_RLE8_compressed_image: * For reading the 8 bit RLE compressed BMP image format. */static void read_RLE8_compressed_image (MG_RWops *f, BYTE *bits, int pitch, BITMAPINFOHEADER *infoheader){ unsigned char count, val, val0; int j, pos, line; int eolflag, eopicflag; eopicflag = 0; line = infoheader->biHeight - 1; while (eopicflag == 0) { pos = 0; /* x position in bitmap */ eolflag = 0; /* end of line flag */ while ((eolflag == 0) && (eopicflag == 0)) { count = fp_getc(f); val = fp_getc(f); if (count > 0) { /* repeat pixel count times */ for (j=0;j<count;j++) { bits [pos] = val; pos++; } } else { switch (val) { case 0: /* end of line flag */ eolflag=1; break; case 1: /* end of picture flag */ eopicflag=1; break; case 2: /* displace picture */ count = fp_getc(f); val = fp_getc(f); pos += count; line -= val; break; default: /* read in absolute mode */ for (j=0; j<val; j++) { val0 = fp_getc(f); bits [pos] = val0; pos++; } if (j%2 == 1) val0 = fp_getc(f); /* align on word boundary */ break; } } if (pos-1 > (int)infoheader->biWidth) eolflag=1; } bits += pitch; line--; if (line < 0) eopicflag = 1; }}/* read_RLE4_compressed_image: * For reading the 4 bit RLE compressed BMP image format. */static void read_RLE4_compressed_image (MG_RWops *f, BYTE *bits, int pitch, BITMAPINFOHEADER *infoheader){ unsigned char b[8]; unsigned char count; unsigned short val0, val; int j, k, pos, line; int eolflag, eopicflag; eopicflag = 0; /* end of picture flag */ line = infoheader->biHeight - 1; while (eopicflag == 0) { pos = 0; eolflag = 0; /* end of line flag */ while ((eolflag == 0) && (eopicflag == 0)) { count = fp_getc(f); val = fp_getc(f); if (count > 0) { /* repeat pixels count times */ b[1] = val & 15; b[0] = (val >> 4) & 15; for (j=0; j<count; j++) { if (pos % 2 == 0) bits [pos/2] = b[j%2] << 4; else bits [pos/2] = bits [pos/2] | b[j%2]; pos++; } } else { switch (val) { case 0: /* end of line */ eolflag=1; break; case 1: /* end of picture */ eopicflag=1; break; case 2: /* displace image */ count = fp_getc(f); val = fp_getc(f); pos += count; line -= val; break; default: /* read in absolute mode */ for (j=0; j<val; j++) { if ((j%4) == 0) { val0 = fp_igetw(f); for (k=0; k<2; k++) { b[2*k+1] = val0 & 15; val0 = val0 >> 4; b[2*k] = val0 & 15; val0 = val0 >> 4; } } if (pos % 2 == 0) bits [pos/2] = b[j%4] << 4; else bits [pos/2] = bits [pos/2] | b[j%4]; pos++; } break; } } if (pos-1 > (int)infoheader->biWidth) eolflag=1; } bits += pitch; line--; if (line < 0) eopicflag = 1; }}/* read_16bit_image: * For reading the 16-bit BMP image format. * This only support bit masks specific to Windows 95. */static void read_16bit_image (MG_RWops *f, BYTE *bits, int pitch, BITMAPINFOHEADER *infoheader, DWORD gmask){ int i, j; WORD pixel; BYTE *line; for (i = 0; i < infoheader->biHeight; i++) { line = bits; for (j = 0; j < infoheader->biWidth; j++) { pixel = fp_igetw (f); if (gmask == 0x03e0) /* 5-5-5 */ { line [2] = ((pixel >> 10) & 0x1f) << 3; line [1] = ((pixel >> 5) & 0x1f) << 3; line [0] = (pixel & 0x1f) << 3; } else /* 5-6-5 */ { line [2] = ((pixel >> 11) & 0x1f) << 3; line [1] = ((pixel >> 5) & 0x3f) << 2; line [0] = (pixel & 0x1f) << 3; } line += 3; } if (infoheader->biWidth & 0x01)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -