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

📄 pcx_provider_generic.cpp

📁 这是一款2d游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						//Use background/green/red/yellow palette
						unsigned char cga_pal2[12] = 
							{ 0,0,0,
							0,255,0,
							255,0,0,
							255,255,0 };
						memcpy (cga_pal, cga_pal2, 12);
					}
					
					//set the background color palette
					unsigned char backcolors[3][16] =
						{ {0,0,0,
						0,0,128,
						0,128,0,
						0,128,128,
						128,0,0,
						128},{0,128,
						192,96,0,
						192,192,192,
						128,128,128,
						0,0,255,
						0,255},{0,
						0,255,255,
						255,0,0,
						255,0,255,
						255,255,0,
						255,255,255}};
					 memcpy (cga_pal, &backcolors[0][header[16] & 240 >> 4], 3);

					//set the intensity
					for (int x=3;x < 12; x++)
					{
						if (!(header[19] & 32) && cga_pal[x])
						{
							cga_pal[x] = 128;
						}
					}

					for (int i=0; i<4; i++)
						palette[i].set_color(cga_pal[i*3],cga_pal[i*3+1],cga_pal[i*3+2]);
				}

				//1 color plane, 4 bits per pixel per plane				
				if (bits_per_pixel_per_plane == 4)
				{
					//This is an EGA image.
					//the palette needs to normalized
					
					//normalize the EGA palette before loading it
					//Clanlib needs palette manipulation functions...  
					if (bits_per_pixel_per_plane == 4)
					{
						for (int x = 0; x < 48; x++)
						{

							header[16+x]=header[16+x]/64*64;
						}
					}
					for (int i=0; i<16; i++)
						palette[i].set_color(header[16+i*3], header[16+i*3+1], header[16+i*3+2]);
				}
			}
			break;
		case 2:
			//nothing special to do here.  A 4 color palette is used (already loaded).
			break;
		case 3:
			{
				if (bits_per_pixel_per_plane == 1)
				{
					//Assign the 8 possible combinations of RGB to the palette 
					//to simulate 8 color RGB display.  Otherwise, it is a 256
					//color picture.  
					//8 color untested.  256 color working.
					unsigned char rgb3_pal[24] = 
						{ 0,0,0,
						0,0,255,
						0,255,0,
						0,255,255,
						255,0,0,
						255,0,255,
						255,255,0,
						255,255,255 };

					for (int i=0; i<8; i++)
						palette[i].set_color(rgb3_pal[i*3],rgb3_pal[i*3+1],rgb3_pal[i*3+2]);
				}
			}
			break;
		case 4:
			//This is a 16 color arbitrary palette image.
			//working.
			break; 
		}
	}
	else
	{
		//This is an RGBA8888 image.
	}

	//This is number of bytes to allocate for the final image
	bytes_to_allocate = (8 / bits_per_pixel_per_plane) * pitch * height * dest_num_planes;

	//allocate the image
	image = new unsigned char[bytes_to_allocate];
	cl_assert(image != NULL);

	if (pixelformat == 8)
	{
		//Set all pixels to be opaque for RGBA8888
		memset(image, 255, bytes_to_allocate);
	}
	else
	{
		//initialize bits to 0 so that bitwise operations work correctly
		memset(image, 0, bytes_to_allocate);
	}
}

void CL_PCXProvider_Generic::read_data()
{
	// Do not run if we already have image data
	if (image != NULL) return;

	// open the file and make sure its valid
	cl_assert(provider != NULL);
	CL_InputSource *datafile = provider->open_source(name.c_str());
	cl_assert(datafile != NULL);
	
	// Read the file header and initialize the variables
	read_header(datafile);

	// This section reads the file data into memory
	datafile->seek(128, CL_InputSource::seek_set);
	int size_data = datafile->size() - 128;
	unsigned char *temp = new unsigned char[size_data];
	int read = datafile->read(temp, size_data);
	if (read != size_data)
		throw CL_Error("Invalid pcx file!?");
	delete datafile;
	
	//init decoding variables
	unsigned char *p = temp;
	unsigned char *cur_line = image;
	// unsigned char *base = image;
	unsigned char packed_byte;
	unsigned char bitmask = 0;
	int skip_planes = 0;

	//used later to select bits in bit depths less than 8.
	switch (bits_per_pixel_per_plane)
	{
	case 1:
		bitmask = 0x01;
		break;
	case 2:
		bitmask = 0x03;
		break;
	case 4:
		bitmask = 0x0F;
		break;
	case 8:
		bitmask = 0xFF;
		break;
	}

	if (pixelformat == 32)
			skip_planes = 1;
	
	//This section decodes the PCX data.
	for (int scanline=0;scanline<height;scanline++)
	{
		//For every scanline
		for (int plane = num_planes - 1; plane >= 0; plane--)
		{
			//for every plane (count backward to convert from RGB to ABGR)

			//tracks bytes decoded from data
			int decoded_bytes = 0;
			//tracks position within final image
			int line_position = 0;

			while (decoded_bytes < decode_pitch)
			{
				//while we have not reached the end of the decoded line
				
				//increment the data pointer
				packed_byte = *(p++);

				if (packed_byte < 192)
				{
					// top two bits are off... this byte is data
					//The processing is now broken down to bit depths of 1, 2, 4, or 8.
					for (int bitcounter = 0; bitcounter < 8; bitcounter += bits_per_pixel_per_plane)
					{
						//For every pixel to be decoded (8 / bits_per_pixel_per_plane

						if (bits_per_pixel_per_plane < 8)
						{
							//The bit depth is below 8.  Because we are converting all
							//bit depths below 8 to 8, the current line_position is
							//always where we are writing data.    
							
							//This line pulls the packed bits out of the data.
							unsigned char packed_bits = ((packed_byte >> (8 - bits_per_pixel_per_plane - bitcounter)) & bitmask);
							
							//This part pulls bits from multiple planes.  Because the bits
							//of a palette reference may be spread across multiple planes,
							//we modify the data that is already at the line position
							//(rather than simply overwriting it).
							packed_bits = (packed_bits << (num_planes - plane - 1));
							
							//Add bits to current position.  In the case of a 
							//palette that is referenced by bits in only one plane, 
							//this is only executed once per line_position.
							cur_line[line_position] = cur_line[line_position] + packed_bits;
						}
						else
						{
							//The image is 8 bit/pallete or 24 bit.  In either case,
							//we simply add the number of color planes to the line position.
							//Then we add 1 plane for alpha support in a 24(32) bit image
							//to skip over the alpha channel (which we assume has been set
							//to 0xFF).
							int image_dest = line_position *dest_num_planes + plane + skip_planes;						
							cur_line[image_dest] = packed_byte; 
						}
						line_position++;
					}
					if (transparent && packed_byte != trans_col)
					{
						if (decoded_bytes < bounding_left) bounding_left = decoded_bytes;
						if (scanline < bounding_top) bounding_top = scanline;
						if (decoded_bytes > bounding_right) bounding_right = decoded_bytes;
						if (scanline > bounding_bottom) bounding_bottom = scanline;
					}
					decoded_bytes++;
				}
				else 
				// top two bits are on... This is a run.  The other bits contain
				// a run count for the RLE compression.  The next byte will
				// contain data to repeat.
				{ 
					unsigned char rle_count = packed_byte&0x3f;
					packed_byte = *(p++);	
					//get data byte to repeat.

					for(unsigned char rle_iterator = 0; rle_iterator < rle_count; rle_iterator++)
					//repeat data value based on rle_count
					{
						//check for end of plane
						if (decoded_bytes >= decode_pitch)
						{
							plane--;
							decoded_bytes = 0;
							line_position = 0;
						}
						
						//The processing is now broken down to bit depths of 1, 2, 4, or 8
						for (int bitcounter = 0; bitcounter < 8; bitcounter += bits_per_pixel_per_plane)
						{
							// The decoding process here is the same as above (in the non-RLE code)
							if (bits_per_pixel_per_plane < 8)
							{
								unsigned char packed_bits = ((packed_byte >> (8 - bits_per_pixel_per_plane - bitcounter)) & bitmask);
								packed_bits = (packed_bits << (num_planes - plane - 1));
								cur_line[line_position] = cur_line[line_position] + packed_bits;
							}
							else
							{
								int image_dest = line_position *dest_num_planes + plane + skip_planes;						
								cur_line[image_dest] = packed_byte; 
							}
							line_position++;
						}						
						if (transparent && packed_byte != trans_col)
						{
							if ((decoded_bytes+rle_iterator) < bounding_left) bounding_left = decoded_bytes+rle_iterator;
							if (scanline < bounding_top) bounding_top = scanline;
							if ((decoded_bytes+rle_iterator) > bounding_right) bounding_right = decoded_bytes+rle_iterator;
							if (scanline > bounding_bottom) bounding_bottom = scanline;
						}
						decoded_bytes++;
					}
				}
			}
		}
		cur_line += pitch;
	}	
	delete[] temp;
}

⌨️ 快捷键说明

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