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

📄 plugintarga.cpp

📁 这是VCF框架的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ==========================================================// TARGA Loader//// Design and implementation by// - Floris van den Berg (flvdberg@wxs.nl)// - Jani Kajala (janik@remedy.fi)// - Martin Weber (martweb@gmx.net)// - Machiel ten Brinke (brinkem@uni-one.nl)//// 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// ----------------------------------------------------------#ifdef WIN32#pragma pack(push, 1)#else#pragma pack(1)#endiftypedef struct tagRGBTRIPLE {   BYTE rgbtBlue;   BYTE rgbtGreen;  BYTE rgbtRed;} RGBTRIPLE; typedef struct tagBGRAQUAD {   BYTE bgraBlue;   BYTE bgraGreen;   BYTE bgraRed;  BYTE bgraAlpha;} BGRAQUAD; struct tagTGAHEADER {	BYTE id_length;	BYTE color_map_type;	BYTE image_type;	WORD cm_first_entry;	WORD cm_length;	BYTE cm_size;	WORD is_xorigin;	WORD is_yorigin;	WORD is_width;	WORD is_height;	BYTE is_pixel_depth;	BYTE is_image_descriptor;};#ifdef WIN32#pragma pack(pop)#else#pragma pack(4)#endif// ==========================================================// Internal functions// ==========================================================static BYTE *Internal_GetScanLine(FreeImage &freeimage, FIBITMAP *dib, int scanline, int flipvert) {	//assert ((scanline >= 0) && (scanline < (int)freeimage.get_height_proc(dib)));	if (flipvert) {		return freeimage.get_scanline_proc(dib, scanline);	} else {		return freeimage.get_scanline_proc(dib, freeimage.get_height_proc(dib) - scanline - 1);	}}// ==========================================================// Plugin Interface// ==========================================================static int s_format_id;// ==========================================================// Plugin Implementation// ==========================================================static const char * DLL_CALLCONVFormat() {	return "TARGA";}static const char * DLL_CALLCONVDescription() {	return "Truevision Targa";}static const char * DLL_CALLCONVExtension() {	return "tga,targa";}static const char * DLL_CALLCONVRegExpr() {	return NULL;}// ----------------------------------------------------------static FIBITMAP * DLL_CALLCONVLoad(FreeImage &freeimage, FreeImageIO &io, fi_handle handle, int page, int flags, void *data) {	if (handle) {		try {			// remember the start offset			long start_offset = io.tell_proc(handle);			// read and process the bitmap's header			FIBITMAP *dib = NULL;			tagTGAHEADER header;			io.read_proc(&header, sizeof(tagTGAHEADER), 1, handle);			int line = CalculateLine(header.is_width, header.is_pixel_depth);			int pitch = CalculatePitch(line);			int alphabits = header.is_image_descriptor & 0x0f;			int fliphoriz = (header.is_image_descriptor & 0x10) ? 0 : 1;			int flipvert = (header.is_image_descriptor & 0x20) ? 1 : 0;			io.seek_proc(handle, header.id_length, SEEK_CUR);			switch (header.is_pixel_depth) {				case 8 :				{					dib = freeimage.allocate_proc(header.is_width, header.is_height, 8, 0, 0, 0);					if (dib == NULL) {						throw "DIB allocation failed";					}					// read the palette					RGBQUAD *palette = freeimage.get_palette_proc(dib);					if (header.color_map_type == 0)						for (unsigned i = 0; i < 256; i++) {							palette[i].rgbRed	= i;							palette[i].rgbGreen = i;							palette[i].rgbBlue	= i;						}					else if (alphabits) {						for (unsigned count = header.cm_first_entry; count < header.cm_length; count++) {							BGRAQUAD quad;							io.read_proc(&quad, sizeof(RGBTRIPLE), 1, handle);													palette[count].rgbBlue = quad.bgraBlue;							palette[count].rgbRed = quad.bgraRed;							palette[count].rgbGreen = quad.bgraGreen;							palette[count].rgbReserved = quad.bgraAlpha;						}					}					else {						for (unsigned count = header.cm_first_entry; count < header.cm_length; count++) {							RGBTRIPLE triple;							io.read_proc(&triple, sizeof(RGBTRIPLE), 1, handle);													palette[count].rgbRed = triple.rgbtRed;							palette[count].rgbGreen = triple.rgbtGreen;							palette[count].rgbBlue = triple.rgbtBlue;						}					}										// read in the bitmap bits					switch (header.image_type) {						case 1 :						case 3 :						{							if (fliphoriz) {								for (unsigned count = header.is_height; count > 0; count--)									io.read_proc(Internal_GetScanLine(freeimage, dib, count - 1, flipvert), line, 1, handle);							}							else {								for (unsigned count = 0; count < header.is_height; count++)									io.read_proc(Internal_GetScanLine(freeimage, dib, count, flipvert), line, 1, handle);							}														break;						}						case 9 :						case 11:						{							int x = 0;							int y = 0;							BYTE *bits;							if (fliphoriz)								bits = Internal_GetScanLine(freeimage, dib, header.is_height - y - 1, flipvert);							else								bits = Internal_GetScanLine(freeimage, dib, y, flipvert);							BYTE rle;														while(1) {								io.read_proc(&rle,1, 1, handle);																if (rle>127) {									rle -= 127;									BYTE triple;									io.read_proc(&triple, 1, 1, handle);									for (int ix = 0; ix < rle; ix++) {										bits[x++] = triple;										if (x >= line) {											x = 0;											y++;											if (y >= header.is_height)												goto done89;																						if(fliphoriz)												bits = Internal_GetScanLine(freeimage, dib, header.is_height-y-1, flipvert);											else												bits = Internal_GetScanLine(freeimage, dib, y, flipvert);										}									}								} else {									rle++;									for (int ix = 0; ix < rle; ix++) {										BYTE triple;												io.read_proc(&triple, 1, 1, handle);										bits[x++] = triple;																				if (x >= line) {											x = 0;											y++;											if (y >= header.is_height)												goto done89;																						if(fliphoriz)												bits = Internal_GetScanLine(freeimage, dib, header.is_height-y-1, flipvert);											else												bits = Internal_GetScanLine(freeimage, dib, y, flipvert);										}									}								}							}					done89 :							break;						}												default :							freeimage.free_proc(dib);							return NULL;					}					break;				}				case 15 :				case 16 :				{					int pixel_bits;					// allocate the dib					if (TARGA_LOAD_RGB888 & flags) {						pixel_bits = 24;						dib = freeimage.allocate_proc(header.is_width, header.is_height, pixel_bits, 0xFF, 0xFF00, 0xFF0000);					} else {									pixel_bits = 16;						dib = freeimage.allocate_proc(header.is_width, header.is_height, pixel_bits, 0x1F, 0x3E0, 0x7C00);					}					if (dib == NULL)						throw "DIB allocation failed";					int line = CalculateLine(header.is_width, pixel_bits);					int pitch = CalculatePitch(line);					const unsigned pixel_size = unsigned(pixel_bits) / 8;					// note header.cm_size is a misleading name, it should be seen as header.cm_bits 					// ignore current position in file and set filepointer explicitly from the beginning of the file					int garblen = 0;					if (header.color_map_type != 0)						garblen = (int)((header.cm_size + 7) / 8) * header.cm_length; /* should byte align */					else						garblen = 0;					io.seek_proc(handle, start_offset, SEEK_SET);					io.seek_proc(handle, sizeof(tagTGAHEADER) + header.id_length + garblen, SEEK_SET);					// read in the bitmap bits					WORD pixel;												switch (header.image_type) {						case 2 :						{							for (int y = 0; y < header.is_height; y++) {								BYTE *bits;								if(fliphoriz)									bits = Internal_GetScanLine(freeimage, dib, header.is_height-y-1, flipvert);								else									bits = Internal_GetScanLine(freeimage, dib, y, flipvert);								for (int x = 0; x < line; ) {									io.read_proc(&pixel, sizeof(WORD), 1, handle);																	if (TARGA_LOAD_RGB888 & flags) {										bits[x + 0] = ((pixel & 0x1F) * 0xFF) / 0x1F;										bits[x + 1] = (((pixel & 0x3E0) >> 5) * 0xFF) / 0x1F;										bits[x + 2] = (((pixel & 0x7C00) >> 10) * 0xFF) / 0x1F;									} else {										*reinterpret_cast<WORD*>(bits + x) = 0x7FFF & pixel;									}									x += pixel_size;								}							}							break;						}						case 10 :						{							int x = 0;							int y = 0;							BYTE rle;							WORD pixel;							while(1) {								BYTE *bits;								if(fliphoriz)									bits = Internal_GetScanLine(freeimage, dib, header.is_height-y-1, flipvert);								else									bits = Internal_GetScanLine(freeimage, dib, y, flipvert);										io.read_proc(&rle,1, 1, handle);																// compressed block																if (rle > 127) {									rle -= 127;									io.read_proc(&pixel, sizeof(WORD), 1, handle);																	for (int ix = 0; ix < rle; ix++) {										if (TARGA_LOAD_RGB888 & flags) {											bits[x + 0] = ((pixel & 0x1F) * 0xFF) / 0x1F;											bits[x + 1] = (((pixel & 0x3E0) >> 5) * 0xFF) / 0x1F;											bits[x + 2] = (((pixel & 0x7C00) >> 10) * 0xFF) / 0x1F;										} else {											*reinterpret_cast<WORD *>(bits + x) = 0x7FFF & pixel;										}										x += pixel_size;																				if (x >= line) {											x = 0;											y++;											if (y >= header.is_height)												goto done2;																										}									}								} else {									rle++;									for (int ix = 0; ix < rle; ix++) {										io.read_proc(&pixel, sizeof(WORD), 1, handle);										if (TARGA_LOAD_RGB888 & flags) {											bits[x + 0] = ((pixel & 0x1F) * 0xFF) / 0x1F;											bits[x + 1] = (((pixel & 0x3E0) >> 5) * 0xFF) / 0x1F;											bits[x + 2] = (((pixel & 0x7C00) >> 10) * 0xFF) / 0x1F;										} else {											*reinterpret_cast<WORD*>(bits + x) = 0x7FFF & pixel;										}										x += pixel_size;										if (x >= line) {											x = 0;											y++;											if (y >= header.is_height)												goto done2;																										}

⌨️ 快捷键说明

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