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

📄 pluginbmp.cpp

📁 这是VCF框架的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// ==========================================================// BMP Loader and Writer//// Design and implementation by// - Floris van den Berg (flvdberg@wxs.nl)// - Markus Loibl (markus.loibl@epost.de)// - Martin Weber (martweb@gmx.net)//// This file is part of FreeImage 2//// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER// THIS DISCLAIMER.//// Use at your own risk!// ==========================================================#include <assert.h>#include "thirdparty/common/FreeImage/Source/FreeImage.h"#include "thirdparty/common/FreeImage/Source/Utilities.h"// ----------------------------------------------------------//   Constants + headers// ----------------------------------------------------------const int RLE_COMMAND     = 0;const int RLE_ENDOFLINE   = 0;const int RLE_ENDOFBITMAP = 1;const int RLE_DELTA       = 2;#define BI_RGB        0L#define BI_RLE8       1L#define BI_RLE4       2L#define BI_BITFIELDS  3L// ----------------------------------------------------------#ifdef WIN32#pragma pack(push, 1)#else#pragma pack(1)#endiftypedef struct tagBITMAPCOREHEADER {  DWORD   bcSize;  WORD    bcWidth;  WORD    bcHeight;  WORD    bcPlanes;  WORD    bcBitCnt;} BITMAPCOREHEADER, *PBITMAPCOREHEADER; typedef struct tagBITMAPINFOOS2_1X_HEADER {  DWORD  biSize;  WORD   biWidth;  WORD   biHeight;   WORD   biPlanes;   WORD   biBitCount;} BITMAPINFOOS2_1X_HEADER, *PBITMAPINFOOS2_1X_HEADER; typedef struct tagBITMAPFILEHEADER {  WORD    bfType;   DWORD   bfSize;  WORD    bfReserved1;   WORD    bfReserved2;  DWORD   bfOffBits; } BITMAPFILEHEADER, *PBITMAPFILEHEADER;typedef struct tagRGBTRIPLE {   BYTE rgbtBlue;   BYTE rgbtGreen;   BYTE rgbtRed; } RGBTRIPLE; #ifdef WIN32#pragma pack(pop)#else#pragma pack(4)#endif// ==========================================================// Plugin Interface// ==========================================================static int s_format_id;// ==========================================================// Internal functions// ==========================================================static FIBITMAP *LoadWindowsBMP(FreeImage &freeimage, FreeImageIO &io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {	FIBITMAP *dib;	try {		// load the info header		BITMAPINFOHEADER bih;		io.read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);		// keep some general information about the bitmap		int used_colors = bih.biClrUsed;		int width       = bih.biWidth;		int height      = bih.biHeight;		int bit_count   = bih.biBitCount;		int compression = bih.biCompression;		int pitch       = CalculatePitch(CalculateLine(width, bit_count));		switch (bit_count) {			case 1 :			case 4 :			case 8 :			{				if ((used_colors <= 0) || (used_colors > CalculateUsedColors(bit_count)))					used_colors = CalculateUsedColors(bit_count);													// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette				dib = freeimage.allocate_proc(width, height, bit_count, 0, 0, 0);				if (dib == NULL)					throw "DIB allocation failed";										BITMAPINFOHEADER *pInfoHeader = freeimage.get_info_header_proc(dib);				pInfoHeader->biXPelsPerMeter = bih.biXPelsPerMeter;				pInfoHeader->biYPelsPerMeter = bih.biYPelsPerMeter;								// load the palette				io.read_proc(freeimage.get_palette_proc(dib), used_colors * sizeof(RGBQUAD), 1, handle);				// seek to the actual pixel data.				// this is needed because sometimes the palette is larger than the entries it contains predicts				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * sizeof(RGBQUAD))))					io.seek_proc(handle, bitmap_bits_offset, SEEK_SET);								// read the pixel data				switch (compression) {					case BI_RGB :						if (height > 0) {							io.read_proc((void *)freeimage.get_bits_proc(dib), height * pitch, 1, handle);						} else {							for (int c = 0; c < abs(height); ++c) {								io.read_proc((void *)freeimage.get_scanline_proc(dib, height - c - 1), pitch, 1, handle);															}						}												return dib;					case BI_RLE4 :					{						BYTE status_byte = 0;						BYTE second_byte = 0;						int scanline = 0;						int bits = 0;						BOOL low_nibble = FALSE;						for (;;) {							io.read_proc(&status_byte, sizeof(BYTE), 1, handle);							switch (status_byte) {								case RLE_COMMAND :									io.read_proc(&status_byte, sizeof(BYTE), 1, handle);									switch (status_byte) {										case RLE_ENDOFLINE :											bits = 0;											scanline++;											low_nibble = FALSE;											break;										case RLE_ENDOFBITMAP :											return (FIBITMAP *)dib;										case RLE_DELTA :										{											// read the delta values											BYTE delta_x;											BYTE delta_y;											io.read_proc(&delta_x, sizeof(BYTE), 1, handle);											io.read_proc(&delta_y, sizeof(BYTE), 1, handle);											// apply them											bits       += delta_x / 2;											scanline   += delta_y;											break;										}										default :											io.read_proc(&second_byte, sizeof(BYTE), 1, handle);											BYTE *sline = freeimage.get_scanline_proc(dib, scanline);											for (int i = 0; i < status_byte; i++) {												if (low_nibble) {													*(sline + bits) |= LOWNIBBLE(second_byte);													if (i != status_byte - 1)														io.read_proc(&second_byte, sizeof(BYTE), 1, handle);													bits++;												} else {													*(sline + bits) |= HINIBBLE(second_byte);												}																								low_nibble = !low_nibble;											}											if (((status_byte / 2) & 1 )== 1)												io.read_proc(&second_byte, sizeof(BYTE), 1, handle);																							break;									};									break;								default :								{									BYTE *sline = freeimage.get_scanline_proc(dib, scanline);									io.read_proc(&second_byte, sizeof(BYTE), 1, handle);									for (unsigned i = 0; i < status_byte; i++) {										if (low_nibble) {											*(sline + bits) |= LOWNIBBLE(second_byte);											bits++;										} else {											*(sline + bits) |= HINIBBLE(second_byte);										}																								low_nibble = !low_nibble;									}								}								break;							};						}						break;					}					case BI_RLE8 :					{						BYTE status_byte = 0;						BYTE second_byte = 0;						int scanline = 0;						int bits = 0;						for (;;) {							io.read_proc(&status_byte, sizeof(BYTE), 1, handle);							switch (status_byte) {								case RLE_COMMAND :									io.read_proc(&status_byte, sizeof(BYTE), 1, handle);									switch (status_byte) {										case RLE_ENDOFLINE :											bits = 0;											scanline++;											break;										case RLE_ENDOFBITMAP :											return (FIBITMAP *)dib;										case RLE_DELTA :										{											// read the delta values											BYTE delta_x;											BYTE delta_y;											io.read_proc(&delta_x, sizeof(BYTE), 1, handle);											io.read_proc(&delta_y, sizeof(BYTE), 1, handle);											// apply them											bits     += delta_x;											scanline += delta_y;											break;										}										default :											io.read_proc((void *)(freeimage.get_scanline_proc(dib, scanline) + bits), sizeof(BYTE) * status_byte, 1, handle);																						// align run length to even number of bytes 											if ((status_byte & 1) == 1)												io.read_proc(&second_byte, sizeof(BYTE), 1, handle);																							bits += status_byte;																								break;																	};									break;								default :									BYTE *sline = freeimage.get_scanline_proc(dib, scanline);									io.read_proc(&second_byte, sizeof(BYTE), 1, handle);									for (unsigned i = 0; i < status_byte; i++) {										*(sline + bits) = second_byte;										bits++;														}									break;							};						}						break;					}					default :														throw "compression type not supported";				}				break;			}			case 16 :			{				if (bih.biCompression == BI_BITFIELDS) {					DWORD bitfields[3];					io.read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);					dib = freeimage.allocate_proc(width, height, bit_count, bitfields[2], bitfields[1], bitfields[0]);				} else {					dib = freeimage.allocate_proc(width, height, bit_count, 0x1F, 0x3E0, 0x7C00);				}				if (dib == NULL)					throw "DIB allocation failed";										BITMAPINFOHEADER *pInfoHeader = freeimage.get_info_header_proc(dib);				pInfoHeader->biXPelsPerMeter = bih.biXPelsPerMeter;				pInfoHeader->biYPelsPerMeter = bih.biYPelsPerMeter;				io.read_proc(freeimage.get_bits_proc(dib), height * pitch, 1, handle);				return dib;			}			case 24 :			case 32 :			{				if (bih.biCompression == BI_BITFIELDS) {					throw "bitfields in 32-bit BMPs are currently unsupported";				} else {					dib = freeimage.allocate_proc(width, height, bit_count, 0xFF, 0xFF00, 0xFF0000);					if (dib == NULL)						throw "DIB allocation failed";											BITMAPINFOHEADER *pInfoHeader = freeimage.get_info_header_proc(dib);					pInfoHeader->biXPelsPerMeter = bih.biXPelsPerMeter;					pInfoHeader->biYPelsPerMeter = bih.biYPelsPerMeter;					// Skip over the optional palette 					// A 24 or 32 bit DIB may contain a palette for faster color reduction					if (pInfoHeader->biClrUsed > 0)						io.seek_proc(handle, pInfoHeader->biClrUsed * sizeof(RGBQUAD), SEEK_CUR);										// read in the bitmap bits					io.read_proc(freeimage.get_bits_proc(dib), height * pitch, 1, handle);					// check if the bitmap contains transparency, if so enable it in the header					freeimage.set_transparent_proc(dib, (freeimage.get_color_type_proc(dib) == FIC_RGBALPHA));					return dib;				}			}		}	} catch(const char *message) {		freeimage.output_message_proc(s_format_id, message);	}	return NULL;}static FIBITMAP *LoadOS22XBMP(FreeImage &freeimage, FreeImageIO &io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {	FIBITMAP *dib = NULL;	try {		// load the info header		BITMAPINFOHEADER bih;		io.read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);		// keep some general information about the bitmap		int used_colors = bih.biClrUsed;		int width       = bih.biWidth;		int height      = bih.biHeight;		int bit_count   = bih.biBitCount;		int compression = bih.biCompression;		int pitch       = CalculatePitch(CalculateLine(width, bit_count));				switch (bit_count) {			case 1 :			case 4 :			case 8 :			{				if ((used_colors <= 0) || (used_colors > CalculateUsedColors(bit_count)))					used_colors = CalculateUsedColors(bit_count);									// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette				dib = freeimage.allocate_proc(width, height, bit_count, 0, 0, 0);				if (dib == NULL)					throw "DIB allocation failed";				BITMAPINFOHEADER *pInfoHeader = freeimage.get_info_header_proc(dib);				pInfoHeader->biXPelsPerMeter = bih.biXPelsPerMeter;				pInfoHeader->biYPelsPerMeter = bih.biYPelsPerMeter;								// load the palette				io.seek_proc(handle, sizeof(BITMAPFILEHEADER) + bih.biSize, SEEK_SET);				RGBQUAD *pal = freeimage.get_palette_proc(dib);				for (int count = 0; count < used_colors; count++) {					RGBTRIPLE triple;					io.read_proc(&triple, sizeof(RGBTRIPLE), 1, handle);										pal[count].rgbRed = triple.rgbtRed;					pal[count].rgbGreen = triple.rgbtGreen;					pal[count].rgbBlue = triple.rgbtBlue;				}				// seek to the actual pixel data.				// this is needed because sometimes the palette is larger than the entries it contains predicts				if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))					io.seek_proc(handle, bitmap_bits_offset, SEEK_SET);				// read the pixel data				switch (compression) {					case BI_RGB :						if (height > 0) {							io.read_proc((void *)freeimage.get_bits_proc(dib), height * pitch, 1, handle);						} else {							for (int c = 0; c < abs(height); ++c) {								io.read_proc((void *)freeimage.get_scanline_proc(dib, height - c - 1), pitch, 1, handle);															}						}												return dib;					case BI_RLE4 :					{						BYTE status_byte = 0;						BYTE second_byte = 0;						int scanline = 0;						int bits = 0;						BOOL low_nibble = FALSE;						for (;;) {							io.read_proc(&status_byte, sizeof(BYTE), 1, handle);							switch (status_byte) {								case RLE_COMMAND :									io.read_proc(&status_byte, sizeof(BYTE), 1, handle);									switch (status_byte) {										case RLE_ENDOFLINE :											bits = 0;											scanline++;											low_nibble = FALSE;											break;										case RLE_ENDOFBITMAP :											return (FIBITMAP *)dib;										case RLE_DELTA :										{											// read the delta values											BYTE delta_x;											BYTE delta_y;											io.read_proc(&delta_x, sizeof(BYTE), 1, handle);											io.read_proc(&delta_y, sizeof(BYTE), 1, handle);											// apply them											bits       += delta_x / 2;											scanline   += delta_y;											break;										}										default :

⌨️ 快捷键说明

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