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

📄 load_save.c

📁 linux下实现的bmp的读写,主function与load_save分开写,有Makefile
💻 C
字号:
#include "load_save.h"

static unsigned short read_word(FILE *fp);
static unsigned int   read_dword(FILE *fp);
static int            read_long(FILE *fp);

static int            write_word(FILE *fp, unsigned short w);
static int            write_dword(FILE *fp, unsigned int dw);
static int            write_long(FILE *fp, int l);

U8* loadbitmap(const char *filename, BITMAPINFO **info)
{
	 FILE        *fp;          // Open file pointer 
    U8          *bits;        // Bitmap pixel bits 
    U8          *ptr;         // Pointer into bitmap 
    U8          temp;         // Temporary variable to swap red and blue 
    int         i, x, y;      // X and Y position in image 
    int         length;       // Line length 
    int         bitsize;      // Size of bitmap 
    int         infosize;     // Size of header information 
    BmpHead header;       		// File header 

    // Try opening the file; use "rb" mode to read this *binary* file. 
    if ((fp = fopen(filename, "rb")) == NULL){
       printf("open read_file erro!\n");
       return (NULL);
	 }
    // Read the file header and any following bitmap information... 
    header.filetype      = read_word(fp);
    header.filesize      = read_dword(fp);
    header.bland1 = read_word(fp);
    header.bland2 = read_word(fp);
    header.startPosition   = read_dword(fp);

    if (header.filetype != 0x4d42)  // Check for BM reversed... 
    {
        printf(" Not a bitmap file - return NULL... \n");
        fclose(fp);
        return (NULL);
    }

    infosize = header.startPosition - 14;
    if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFO))) == NULL)
    {
        printf(" Couldn't allocate memory for bitmap info - return NULL..\n");
        fclose(fp);
        return (NULL);
    }


    (*info)->InfoHead.Length			= read_dword(fp);
    (*info)->InfoHead.width         = read_long(fp);
    (*info)->InfoHead.height        = read_long(fp);
    (*info)->InfoHead.colorPlane    = read_word(fp);
    (*info)->InfoHead.bitColor      = read_word(fp);
    (*info)->InfoHead.zipFormat   	= read_dword(fp);
    (*info)->InfoHead.realSize     	= read_dword(fp);
    (*info)->InfoHead.xPels 			= read_long(fp);
    (*info)->InfoHead.yPels 			= read_long(fp);
    (*info)->InfoHead.colorUse      = read_dword(fp);
    (*info)->InfoHead.colorImportant= read_dword(fp);

    if (infosize > 40)
		if (fread((*info)->bmiColors, infosize - 40, 1, fp) < 1)
      {
            printf("Couldn't read the bitmap header - return NULL...\n"); 
            free(*info);
            fclose(fp);
            return (NULL);
            }

   // Now that we have all the header info read in, allocate memory for the bitmap and read *it* in...                                    
    if ((bitsize = (*info)->InfoHead.realSize) == 0)
        bitsize = ((*info)->InfoHead.width *
                   (*info)->InfoHead.bitColor + 7) / 8 *
  	           abs((*info)->InfoHead.height);

    if ((bits = (U8 *)malloc(sizeof(U8)*bitsize)) == NULL)
    {
        printf("Couldn't allocate memory - return NULL! \n");
        free(*info);
        fclose(fp);
        return (NULL);
    }

    if (fread(bits, 1, bitsize, fp) < bitsize)
    {
        printf("Couldn't read bitmap - free memory and return NULL! \n");
        free(*info);
        free(bits);
        fclose(fp);
        return (NULL);
      }

    // Swap red and blue 
/*
    length = ((*info)->InfoHead.width * 3 + 3) & ~3;
    for (y = 0; y < (*info)->InfoHead.height; y ++)
        for (ptr = bits + y * length, x = (*info)->InfoHead.width;
             x > 0;
	     x --, ptr += 3)
	    {
	    temp   = ptr[0];
	    ptr[0] = ptr[2];
	    ptr[2] = temp;
	    }
	for(i=0;i<1024;i++)
		printf("%x ", bits[i]);
*/
    // OK, everything went fine - return the allocated bitmap... 
    fclose(fp);
    return (bits);
}

  // O - 0 = success, -1 = failure 
int savebitmap(const char *filename, BITMAPINFO **info, U8 *bits)  // target filename , BitMap infomation, image data
{
    FILE *fp;                      // Open file pointer 
    int  size,                     // Size of file 
         infosize,                 // Size of bitmap info 
         bitsize;                  // Size of bitmap pixels 

   // Try opening the file; use "wb" mode to write this *binary* file. 
    if ((fp = fopen(filename, "wb")) == NULL){
        printf("open write file error\n");
        return (-1);
        }

    // Figure out the bitmap size 
    if ((*info)->InfoHead.realSize == 0)
		bitsize = ((*info)->InfoHead.width *
        	   (*info)->InfoHead.bitColor + 7) / 8 *
		((*info)->InfoHead.height);
    else
		bitsize = (*info)->InfoHead.realSize;

    // Figure out the header size 
	switch((*info)->InfoHead.bitColor)
	{
		case 4:
			infosize=108;
			break;
		case 8:
			infosize=1064;
			break;
		case 16:
		case 24:
		case 32:
			infosize=40;
			break;
	}
   switch ((*info)->InfoHead.zipFormat)
	{/*
	case BI_BITFIELDS :
            infosize += 12; // Add 3 RGB doubleword masks 
            if ((*info)->InfoHead.colorUse == 0)
	      break;*/
	case 0 :
            if ((*info)->InfoHead.bitColor > 8 &&
        	(*info)->InfoHead.colorUse == 0)
	      break;/*
	case BI_RLE8 :
	case BI_RLE4 :
            if ((*info)->InfoHead.colorUse == 0)
              infosize += (1 << (*info)->InfoHead.bitColor) * 4;
	    else
              infosize += (*info)->InfoHead.colorUse * 4;
	    break;*/
	}

    size = sizeof(BmpHead) + infosize + bitsize;
    // Write the file header, bitmap information, and bitmap pixel data... 
    write_word(fp, 0x4d42);        	// bfType 
    write_dword(fp, size);          // bfSize 
    write_word(fp, 0);              // bfReserved1 
    write_word(fp, 0);              // bfReserved2 
    write_dword(fp, 14 + infosize); // bfOffBits 

    write_dword(fp, (*info)->InfoHead.Length);
    write_long(fp, (*info)->InfoHead.width);
    write_long(fp, (*info)->InfoHead.height);
    write_word(fp, (*info)->InfoHead.colorPlane);
    write_word(fp, (*info)->InfoHead.bitColor);
    write_dword(fp, (*info)->InfoHead.zipFormat);
    write_dword(fp, (*info)->InfoHead.realSize);
    write_long(fp, (*info)->InfoHead.xPels);
    write_long(fp, (*info)->InfoHead.yPels);
    write_dword(fp, (*info)->InfoHead.colorUse);
    write_dword(fp, (*info)->InfoHead.colorImportant);

    if (infosize > 40)
		if (fwrite((*info)->bmiColors, infosize - 40, 1, fp) < 1)
      {
          printf("Couldn't write the bitmap header - return... \n");
          fclose(fp);
          return (-1);
       }

    if (fwrite(bits, 1, bitsize, fp) < bitsize)
    {
        printf(" Couldn't write the bitmap - return... \n");
        fclose(fp);
        return (-1);
     }

    // OK, everything went fine - return... 
    fclose(fp);
    return (0);
    }


 // 'read_word()' - Read a 16-bit unsigned integer.

// O - 16-bit unsigned integer 
static unsigned short read_word(FILE *fp)       //  File read from 
{
    unsigned char b0, b1; // Bytes from file 
    b0 = getc(fp);
    b1 = getc(fp);
    return ((b1 << 8) | b0);
}

 // 'read_dword()' - Read a 32-bit unsigned integer.

// O - 32-bit unsigned integer 
static unsigned int read_dword(FILE *fp)        // File read from 
{
    unsigned char b0, b1, b2, b3; 					// Bytes from file 

    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);

    return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}

// 'read_long()' - Read a 32-bit signed integer.

// O - 32-bit signed integer 
static int read_long(FILE *fp)               	// File read from 
{
    unsigned char b0, b1, b2, b3; // Bytes from file

    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);

    return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}

// 'write_word()' - Write a 16-bit unsigned integer.

 // O - 0 on success, -1 on error 
static int write_word(FILE *fp, unsigned short w)   // target file pointer , Integer to write 
{
    putc(w, fp);
    return (putc(w >> 8, fp));
}

// 'write_dword()' - Write a 32-bit unsigned integer.

// O - 0 on success, -1 on error 
static int write_dword(FILE *fp, unsigned int dw)  // target file pointer write , Integer to write 
{
    putc(dw, fp);
    putc(dw >> 8, fp);
    putc(dw >> 16, fp);
    return (putc(dw >> 24, fp));
}

// 'write_long()' - Write a 32-bit signed integer.

// O - 0 on success, -1 on error 
static int write_long(FILE *fp, int  l)   // target file pointer of write  ,Integer to write 
{
    putc(l, fp);
    putc(l >> 8, fp);
    putc(l >> 16, fp);
    return (putc(l >> 24, fp));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -