⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winbmp.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $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  40

typedef 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 + -