?? winbmp.c
字號:
pixel = fp_igetw (f); /* read the gap */ bits += pitch; }}/* __mg_load_bmp: * Loads a Windows BMP file, returning in the my_bitmap structure and storing * the palette data in the specified palette (this should be an array of * at least 256 RGB structures). * * Thanks to Seymour Shlien for contributing this function. */int __mg_load_bmp (MG_RWops* fp, MYBITMAP* bmp, RGB* pal){ BITMAPFILEHEADER fileheader; BITMAPINFOHEADER infoheader; int effect_depth; DWORD rmask = 0x001f, gmask = 0x03e0, bmask = 0x7c00; unsigned long biSize; BYTE* bits; int pitch; int ncol; if (read_bmfileheader (fp, &fileheader) != 0) { return ERR_BMP_IMAGE_TYPE; } biSize = fp_igetl (fp); if (biSize >= WININFOHEADERSIZE) { if (read_win_bminfoheader (fp, &infoheader) != 0) { return ERR_BMP_LOAD; } MGUI_RWseek (fp, biSize - WININFOHEADERSIZE, SEEK_CUR); /* compute number of colors recorded */ ncol = (fileheader.bfOffBits - biSize - 14) / 4; read_bmicolors (ncol, pal, fp, 1); } else if (biSize == OS2INFOHEADERSIZE) { if (read_os2_bminfoheader (fp, &infoheader) != 0) { return ERR_BMP_LOAD; } /* compute number of colors recorded */ ncol = (fileheader.bfOffBits - 26) / 3; read_bmicolors (ncol, pal, fp, 0); } else return ERR_BMP_LOAD; /* Compute the size and pitch of the image */ if (infoheader.biBitCount == 16) effect_depth = 24; else effect_depth = infoheader.biBitCount; bmpComputePitch (effect_depth, infoheader.biWidth, &pitch, TRUE); biSize = pitch * infoheader.biHeight; if( !(bits = malloc (biSize)) ) { return ERR_BMP_MEM; } bmp->bits = bits; bmp->flags = MYBMP_TYPE_BGR | MYBMP_FLOW_UP; switch (infoheader.biCompression) { case BI_BITFIELDS: /* ignore the bit fileds */ MGUI_RWseek (fp, -16, SEEK_CUR); rmask = fp_igetl (fp); gmask = fp_igetl (fp); bmask = fp_igetl (fp); //fprintf (stderr, "__mg_load_bmp: discard the bit masks: %lx, %lx, %lx.\n", rmask, gmask, bmask); case BI_RGB: if (infoheader.biBitCount == 16) { bmp->flags |= MYBMP_RGBSIZE_3; read_16bit_image (fp, bits, pitch, &infoheader, gmask); } else if (infoheader.biBitCount == 32) { bmp->flags |= MYBMP_RGBSIZE_4; MGUI_RWread (fp, bits, sizeof(char), biSize); } else { bmp->flags |= MYBMP_RGBSIZE_3; MGUI_RWread (fp, bits, sizeof(char), biSize); } break; case BI_RLE8: read_RLE8_compressed_image (fp, bits, pitch, &infoheader); break; case BI_RLE4: read_RLE4_compressed_image (fp, bits, pitch, &infoheader); break; default: return ERR_BMP_NOT_SUPPORTED; } bmp->depth = effect_depth; bmp->w = infoheader.biWidth; bmp->h = infoheader.biHeight; bmp->pitch = pitch; bmp->frames = 1; bmp->size = biSize; return ERR_BMP_OK;}BOOL __mg_check_bmp (MG_RWops* fp){ WORD bfType = fp_igetw (fp); if (bfType != 19778) return FALSE; return TRUE;}#ifdef _SAVE_BITMAPstatic void bmpGet16CScanline (BYTE* bits, BYTE* scanline, int pixels){ int i; for (i = 0; i < pixels; i++) { if (i % 2 == 0) *scanline = (bits [i] << 4) & 0xF0; else { *scanline |= bits [i] & 0x0F; scanline ++; } }}static inline void bmpGet256CScanline (BYTE* bits, BYTE* scanline, int pixels){ memcpy (scanline, bits, pixels);}inline void pixel2rgb (gal_pixel pixel, GAL_Color* color, int depth){ switch (depth) { case 24: case 32: color->r = (gal_uint8) ((pixel >> 16) & 0xFF); color->g = (gal_uint8) ((pixel >> 8) & 0xFF); color->b = (gal_uint8) (pixel & 0xFF); break; case 15: color->r = (gal_uint8)((pixel & 0x7C00) >> 7) | 0x07; color->g = (gal_uint8)((pixel & 0x03E0) >> 2) | 0x07; color->b = (gal_uint8)((pixel & 0x001F) << 3) | 0x07; break; case 16: color->r = (gal_uint8)((pixel & 0xF800) >> 8) | 0x07; color->g = (gal_uint8)((pixel & 0x07E0) >> 3) | 0x03; color->b = (gal_uint8)((pixel & 0x001F) << 3) | 0x07; break; }}static void bmpGetHighCScanline (BYTE* bits, BYTE* scanline, int pixels, int bpp, int depth){ int i; gal_pixel c; GAL_Color color; for (i = 0; i < pixels; i++) { c = *((gal_pixel*)bits); pixel2rgb (c, &color, depth); *(scanline) = color.b; *(scanline + 1) = color.g; *(scanline + 2) = color.r; bits += bpp; scanline += 3; }}inline static int depth2bpp (int depth){ switch (depth) { case 4: case 8: return 1; case 15: case 16: return 2; case 24: return 3; case 32: return 4; } return 1;}int __mg_save_bmp (MG_RWops* fp, MYBITMAP* bmp, RGB* pal){ BYTE* scanline = NULL; int i, bpp; int scanlinebytes; BITMAPFILEHEADER bmfh; WINBMPINFOHEADER bmih; memset (&bmfh, 0, sizeof (BITMAPFILEHEADER)); bmfh.bfType = MAKEWORD ('B', 'M'); bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; memset (&bmih, 0, sizeof (WINBMPINFOHEADER)); bmih.biSize = (DWORD)(WININFOHEADERSIZE); bmih.biWidth = (DWORD)(bmp->w); bmih.biHeight = (DWORD)(bmp->h); bmih.biPlanes = 1; bmih.biCompression = BI_RGB; bpp = depth2bpp (bmp->depth); switch (bmp->depth) { case 4: scanlinebytes = (bmih.biWidth + 1)>>1; scanlinebytes = ((scanlinebytes + 3)>>2)<<2;#ifdef HAVE_ALLOCA if (!(scanline = alloca (scanlinebytes))) return ERR_BMP_MEM;#else if (!(scanline = malloc (scanlinebytes))) return ERR_BMP_MEM;#endif memset (scanline, 0, scanlinebytes); bmih.biSizeImage = (DWORD)(bmih.biHeight*scanlinebytes); bmfh.bfOffBits = SIZEOF_BMFH + SIZEOF_BMIH + (SIZEOF_RGBQUAD<<4); bmfh.bfSize = (DWORD)(bmfh.bfOffBits + bmih.biSizeImage); bmih.biBitCount = 4; bmih.biClrUsed = 16L; bmih.biClrImportant = 16L; MGUI_RWwrite (fp, &bmfh.bfType, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfSize, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmfh.bfReserved1, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfReserved2, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfOffBits, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biSize, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biWidth, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biHeight, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biPlanes, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmih.biBitCount, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmih.biCompression, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biSizeImage, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biXPelsPerMeter, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biYPelsPerMeter, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biClrUsed, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biClrImportant, sizeof (DWORD), 1); for (i = 0; i < 16; i++) { RGBQUAD rgbquad; rgbquad.rgbRed = pal [i].r; rgbquad.rgbBlue = pal [i].b; rgbquad.rgbGreen = pal [i].g; MGUI_RWwrite (fp, &rgbquad, sizeof (char), sizeof (RGBQUAD)); } for (i = bmp->h - 1; i >= 0; i--) { bmpGet16CScanline (bmp->bits + i * bmp->pitch, scanline, bmp->w); MGUI_RWwrite (fp, scanline, sizeof (char), scanlinebytes); } break; case 8: scanlinebytes = bmih.biWidth; scanlinebytes = ((scanlinebytes + 3)>>2)<<2;#ifdef HAVE_ALLOCA if (!(scanline = alloca (scanlinebytes))) return ERR_BMP_MEM;#else if (!(scanline = malloc (scanlinebytes))) return ERR_BMP_MEM;#endif memset (scanline, 0, scanlinebytes); bmih.biSizeImage = bmih.biHeight*scanlinebytes; bmfh.bfOffBits = SIZEOF_BMFH + SIZEOF_BMIH + (SIZEOF_RGBQUAD<<8); bmfh.bfSize = bmfh.bfOffBits + bmih.biSizeImage; bmih.biBitCount = 8; bmih.biClrUsed = 256; bmih.biClrImportant = 256; MGUI_RWwrite (fp, &bmfh.bfType, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfSize, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmfh.bfReserved1, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfReserved2, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfOffBits, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biSize, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biWidth, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biHeight, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biPlanes, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmih.biBitCount, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmih.biCompression, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biSizeImage, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biXPelsPerMeter, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biYPelsPerMeter, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biClrUsed, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biClrImportant, sizeof (DWORD), 1); for (i = 0; i < 256; i++) { RGBQUAD rgbquad; rgbquad.rgbRed = pal [i].r; rgbquad.rgbBlue = pal [i].b; rgbquad.rgbGreen = pal [i].g; MGUI_RWwrite (fp, &rgbquad, sizeof (char), sizeof (RGBQUAD)); } for (i = bmp->h - 1; i >= 0; i--) { bmpGet256CScanline (bmp->bits + bmp->pitch * i, scanline, bmp->w); MGUI_RWwrite (fp, scanline, sizeof (char), scanlinebytes); } break; default: scanlinebytes = bmih.biWidth*3; scanlinebytes = ((scanlinebytes + 3)>>2)<<2;#ifdef HAVE_ALLOCA if (!(scanline = alloca (scanlinebytes))) return ERR_BMP_MEM;#else if (!(scanline = malloc (scanlinebytes))) return ERR_BMP_MEM;#endif memset (scanline, 0, scanlinebytes); bmih.biSizeImage = bmih.biHeight*scanlinebytes; bmfh.bfOffBits = SIZEOF_BMFH + SIZEOF_BMIH; bmfh.bfSize = bmfh.bfOffBits + bmih.biSizeImage; bmih.biBitCount = 24; MGUI_RWwrite (fp, &bmfh.bfType, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfSize, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmfh.bfReserved1, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfReserved2, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmfh.bfOffBits, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biSize, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biWidth, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biHeight, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biPlanes, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmih.biBitCount, sizeof (WORD), 1); MGUI_RWwrite (fp, &bmih.biCompression, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biSizeImage, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biXPelsPerMeter, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biYPelsPerMeter, sizeof (LONG), 1); MGUI_RWwrite (fp, &bmih.biClrUsed, sizeof (DWORD), 1); MGUI_RWwrite (fp, &bmih.biClrImportant, sizeof (DWORD), 1); for (i = bmp->h - 1; i >= 0; i--) { bmpGetHighCScanline (bmp->bits + i * bmp->pitch, scanline, bmp->w, bpp, bmp->depth); MGUI_RWwrite (fp, scanline, sizeof (char), scanlinebytes); } break; }#ifndef HAVE_ALLOCA free (scanline);#endif return ERR_BMP_OK;}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -