Example #1
0
CL_XMLTokenizer::CL_XMLTokenizer(CL_IODevice &input) : impl(new CL_XMLTokenizer_Generic)
{
	impl->input = input;
	impl->size = input.get_size();
	impl->pos = 0;

	CL_DataBuffer buffer(impl->size);
	input.receive(buffer.get_data(), buffer.get_size(), true);

	CL_StringHelp::BOMType bom_type = CL_StringHelp::detect_bom(buffer.get_data(), buffer.get_size());
	switch (bom_type)
	{
	default:
	case CL_StringHelp::bom_none:
		impl->data = CL_StringHelp::utf8_to_text(CL_StringRef8(buffer.get_data(), buffer.get_size(), false));
		break;
	case CL_StringHelp::bom_utf32_be:
	case CL_StringHelp::bom_utf32_le:
		throw CL_Exception("UTF-16 XML files not supported yet");
		break;
	case CL_StringHelp::bom_utf16_be:
	case CL_StringHelp::bom_utf16_le:
		throw CL_Exception("UTF-32 XML files not supported yet");
		break;
	case CL_StringHelp::bom_utf8:
		impl->data = CL_StringHelp::utf8_to_text(CL_StringRef8(buffer.get_data()+3, buffer.get_size()-3, false));
		break;
	}

}
CL_ShaderObject CL_ShaderObject::load(CL_GraphicContext &gc, const CL_StringRef &resource_id, CL_ResourceManager *resources)
{
	CL_Resource resource = resources->get_resource(resource_id);
	CL_String filename = resource.get_element().get_attribute("file");
	CL_String type = resource.get_element().get_tag_name();
	
	CL_ShaderType shader_type;
	if (type == "fragment-shader")
		shader_type = cl_shadertype_fragment;
	else if (type == "vertex-shader")
		shader_type = cl_shadertype_vertex;
	else
		throw CL_Exception("CL_ShaderObject: Unknown shader type: " + type);

	CL_VirtualDirectory directory = resources->get_directory(resource);

	CL_IODevice file = directory.open_file(filename, CL_File::open_existing, CL_File::access_read, CL_File::share_read);
	int size = file.get_size();
	CL_String8 source(size, 0);
	file.read(&source[0], size);

	CL_ShaderObject shader_object(gc, shader_type, CL_StringHelp::local8_to_text(source));

	if (resource.get_element().get_attribute("compile", "true") == "true")
		if(!shader_object.compile())
			throw CL_Exception(cl_format("Unable to compiler shader program %1: %2", resource_id, shader_object.get_info_log()));

	return shader_object;
}
CL_ShaderObject CL_ShaderObject::load(CL_GraphicContext &gc, CL_ShaderType shader_type, CL_IODevice &file)
{
	int size = file.get_size();
	CL_String8 source(size, 0);
	file.read(&source[0], size);

	return CL_ShaderObject(gc, shader_type, CL_StringHelp::local8_to_text(source));
}
CL_PCXProvider_Impl::CL_PCXProvider_Impl(
	CL_IODevice &datafile)
{
	image = NULL;

	bool little_endian = datafile.is_little_endian();
	if (!little_endian)
		datafile.set_little_endian_mode();

	read_pcx(datafile);

	if (!little_endian)
		datafile.set_big_endian_mode();

}
Example #5
0
cl_byte64 CL_ZipReader_Impl::deflate_read(void *data, cl_byte64 size, bool read_all)
{
	zs.next_out = (Bytef *) data;
	zs.avail_out = size;
	// Continue feeding zlib data until we get our data:
	while (zs.avail_out > 0)
	{
		// zlib needs more data:
		if (zs.avail_in == 0 && compressed_pos < local_header.compressed_size)
		{
			// Read some compressed data:
			int received_input = 0;
			while (received_input < 16*1024)
			{
				received_input += input.receive(zbuffer, int(cl_min(16*1024, local_header.compressed_size - compressed_pos)), true);
				if (compressed_pos + received_input == local_header.compressed_size) break;
			}
			compressed_pos += received_input;

			zs.next_in = (Bytef *) zbuffer;
			zs.avail_in = received_input;
		}

		// Decompress data:
		int result = inflate(&zs, (compressed_pos == local_header.compressed_size) ? Z_FINISH : Z_NO_FLUSH);
		if (result == Z_STREAM_END) break;
		if (result == Z_NEED_DICT) throw CL_Exception("Zlib inflate wants a dictionary!");
		if (result == Z_DATA_ERROR) throw CL_Exception("Zip data stream is corrupted");
		if (result == Z_STREAM_ERROR) throw CL_Exception("Zip stream structure was inconsistent!");
		if (result == Z_MEM_ERROR) throw CL_Exception("Zlib did not have enough memory to decompress file!");
		if (result == Z_BUF_ERROR) throw CL_Exception("Not enough data in buffer when Z_FINISH was used");
		if (result != Z_OK) throw CL_Exception("Zlib inflate failed while decompressing zip file!");
	}
	return size - zs.avail_out;
}
void CL_CSSDocument_Impl::load(const CL_String &filename, const CL_VirtualDirectory &directory)
{
	CL_String path = CL_PathHelp::get_fullpath(filename, CL_PathHelp::path_type_file);

	// Load document into a buffer:

	CL_IODevice input = directory.open_file_read(filename);

	int size = input.get_size();
	if (size < 0)
		throw CL_Exception("IODevice does not support get_size()");
	CL_DataBuffer data(size);
	int bytes_read = input.read(data.get_data(), data.get_size());
	data.set_size(bytes_read);

	// Start parsing:

	unsigned char *data_ptr = (unsigned char *) data.get_data();
	whitespace_comments(data_ptr, bytes_read);

	int pos = 0;
	while (pos < bytes_read)
	{
		unsigned char ch = data_ptr[pos];
		switch (ch)
		{
		case ' ':
		case '\t':
		case '\r':
		case '\n':
			pos++;
			break;

		case '@': // import
			pos = load_import(data_ptr, pos, bytes_read, directory, path);
			break;

		default: // ruleset
			pos = load_ruleset(data_ptr, pos, bytes_read);
			break;
		}
	}
}
unsigned int CL_SoundProvider_Wave_Impl::find_subchunk(const char *chunk, CL_IODevice &source, unsigned int file_offset, unsigned int max_offset )
{
	char subchunk1_id[4];

	max_offset -= 8;	// Each subchunk must contains at least name and size
	while(file_offset < max_offset)
	{
		source.seek(file_offset);
		source.read(subchunk1_id, 4);
		cl_ubyte32 subchunk1_size = source.read_uint32();
		if (!memcmp(subchunk1_id, chunk, 4))
		{
			// Found chunk
			return subchunk1_size;
		}
		file_offset += subchunk1_size + 8;
	}
	throw CL_Exception("Block not found!");

}
void CL_CSSDocument_Impl::load(const CL_StringRef &path, CL_IODevice &input)
{
	// Load document into a buffer:

	int size = input.get_size();
	if (size < 0)
		throw CL_Exception("IODevice does not support get_size()");
	CL_DataBuffer data(size);
	int bytes_read = input.read(data.get_data(), data.get_size());
	data.set_size(bytes_read);

	// Start parsing:

	unsigned char *data_ptr = (unsigned char *) data.get_data();
	whitespace_comments(data_ptr, bytes_read);

	int pos = 0;
	while (pos < bytes_read)
	{
		unsigned char ch = data_ptr[pos];
		switch (ch)
		{
		case ' ':
		case '\t':
		case '\r':
		case '\n':
			pos++;
			break;

		case '@': // import
			pos = load_import(data_ptr, pos, bytes_read, path);
			break;

		default: // ruleset
			pos = load_ruleset(data_ptr, pos, bytes_read);
			break;
		}
	}
}
void CL_PCXProvider_Impl::read_pcx(
	CL_IODevice &_datafile)
{
	// Read the file header and initialize the variables
	// This method was created to breakup the PCX decoding code
	// so the initializing code was separated from the actual
	// decoding algorithm

	unsigned char header[128];  

	{
		int read = _datafile.read(header, 128);
		if (read != 128)
			throw CL_Exception("File not big enough to read the PCX header");
	}

	// only the useful fields that will be used more than once
	struct PCXHeader {
		unsigned char version;
		unsigned char encoding;
		unsigned char bits_per_pixel_per_plane;
		short xmin;
		short ymin;
		short xmax;
		short ymax;
		unsigned char color_map[48];
		unsigned char nplanes;
		unsigned short bytes_per_line;
	} pcx_header;

	if (header[0] != 10)
		throw CL_Exception("Not a PCX file");

	pcx_header.version = header[1];
	pcx_header.encoding = header[2];
	pcx_header.bits_per_pixel_per_plane = header[3];
	pcx_header.xmin = (header[5] << 8) | header[4];	
	pcx_header.ymin = (header[7] << 8) | header[6];
	pcx_header.xmax = (header[9] << 8) | header[8];
	pcx_header.ymax = (header[11] << 8) | header[10];

	const int width = (pcx_header.xmax - pcx_header.xmin) + 1;
	const int height = (pcx_header.ymax - pcx_header.ymin) + 1;

	memcpy(pcx_header.color_map, &header[16], sizeof(pcx_header.color_map));
	pcx_header.nplanes = header[65];
	pcx_header.bytes_per_line = (header[67] << 8) | header[66];

	// both 8bit with palette and 24bit rgb modes require version 5
	if (pcx_header.version < 5)
		throw CL_Exception("PCX version unsupported");

	const int total_line_bytes = pcx_header.bytes_per_line * pcx_header.nplanes;

	int pitch = 0;

	// decide which pixelformat to use (8 bit palette or 24 bit)
	if (pcx_header.nplanes == 3 && pcx_header.bits_per_pixel_per_plane == 8)
	{
		// 24 bit RGB mode
		pitch = width * 3;
		image = new unsigned char[pitch * height];
		if (image == 0)
			throw CL_Exception("Unable to allocate memory for pcx image");

		unsigned char *p = image;
		const int extra = total_line_bytes - pitch;

		// get the data
		if (!pcx_header.encoding)
		{
			// uncompressed
			for (int y = 0; y < height; y++)
			{
				_datafile.read(p, pitch);
				if (extra > 0)
					_datafile.seek(extra, CL_IODevice::seek_cur);
				p += pitch;
			}
		}
		else
		{
			// compressed
			for (int y = 0; y < height; y++)
			{
				int count;
				// first red component
				int x = 0, xx = 0, comp = 0;
				while (x < total_line_bytes)
				{
					int ch = _datafile.read_uint8();
					if ((ch & 0xC0) == 0xC0)
					{
						count = ch & 0x3F;
						ch = _datafile.read_uint8();
					}
					else
						count = 1;

					while (count--)
					{
						if (xx < width)
							image[(y * pitch) + ((xx * 3) + comp)] = ch;
						x++;
						if (x == pcx_header.bytes_per_line)
						{
							// blue component now
							comp = 1;
							xx = 0;
						}
						else if (x == pcx_header.bytes_per_line*2)
						{
							// green component now
							comp = 2;
							xx = 0;
						}
						else
							xx++;
					}
				}
			}
		}
		CL_PCXProvider_Impl::sized_format = cl_bgr8;
		CL_PCXProvider_Impl::pitch = pitch;
		CL_PCXProvider_Impl::width = width;
		CL_PCXProvider_Impl::height = height;
	}
	else if (pcx_header.nplanes == 1 && pcx_header.bits_per_pixel_per_plane == 8)
	{
		// 8 bit indexed mode
		pitch = width;
		image = new unsigned char[pitch * height];
		if (image == 0)
			throw CL_Exception("Unable to allocate memory for pcx image");

		unsigned char *p = image;
		const int extra = total_line_bytes - pitch;

		// get the data
		if (!pcx_header.encoding)
		{
			// uncompressed
			for (int y = 0; y < height; y++)
			{
				_datafile.read(p, pitch);
				if (extra > 0)
					_datafile.seek(extra, CL_IODevice::seek_cur);
				p += pitch;
			}
		}
		else
		{
			// compressed
			for (int y = 0; y < height; y++)
			{
				int count;
				int x = 0;
				while (x < total_line_bytes)
				{
					int ch = _datafile.read_uint8();
					if ((ch & 0xC0) == 0xC0)
					{
						count = ch & 0x3F;
						ch = _datafile.read_uint8();
					}
					else
						count = 1;
					
					while (count--)
					{
						if (x < width)
						{
							*p = ch;
							p++;
						}
						x++;
					}
				}
			}
		}

		// read the palette
		if (_datafile.read_int8() != 12)
		{
			delete[] image;
			throw CL_Exception("Palette not found");
		}
		for (int i = 0; i < 256; i++)
		{
			const int r = _datafile.read_uint8();
			const int g = _datafile.read_uint8();
			const int b = _datafile.read_uint8();
			palette[i].set_color(r, g, b);
		}

		CL_PCXProvider_Impl::sized_format = cl_color_index;
		CL_PCXProvider_Impl::pitch = pitch;
		CL_PCXProvider_Impl::width = width;
		CL_PCXProvider_Impl::height = height;
	}
	else
		throw CL_Exception("Unsupported PCX format");
}
Example #10
0
void CustomIOFunctions::write( png_structp png_ptr, png_bytep data, png_size_t length )
{
	CL_IODevice *iodev = (CL_IODevice*)png_get_io_ptr(png_ptr);
	iodev->write(data, length);
}
void CL_SoundProvider_Wave_Impl::load(CL_IODevice &source)
{
	source.set_little_endian_mode();

	char chunk_id[4];
	source.read(chunk_id, 4);
	if (memcmp(chunk_id, "RIFF", 4))
		throw CL_Exception("Expected RIFF header!");
	cl_ubyte32 chunk_size = source.read_uint32();

	char format_id[4];
	source.read(format_id, 4);
	if (memcmp(format_id, "WAVE", 4))
		throw CL_Exception("Expected WAVE header!");

	cl_ubyte32 subchunk_pos = source.get_position();
	cl_ubyte32 subchunk1_size = find_subchunk("fmt ", source, subchunk_pos, chunk_size);

	cl_ubyte16 audio_format = source.read_uint16();
	num_channels = source.read_uint16();
	frequency = source.read_uint32();
	cl_ubyte32 byte_rate = source.read_uint32();
	cl_ubyte16 block_align = source.read_uint16();
	cl_ubyte16 bits_per_sample = source.read_uint16();

	if (bits_per_sample == 16)
		format = sf_16bit_signed;
	else if (bits_per_sample == 8)
		format = sf_8bit_unsigned;
	else
		throw CL_Exception("Unsupported wave sample format");

	cl_ubyte32 subchunk2_size = find_subchunk("data", source, subchunk_pos, chunk_size);

	data = new char[subchunk2_size];
	source.read(data, subchunk2_size);

	num_samples = subchunk2_size / block_align;
}
void CL_ZipFileHeader::load(CL_IODevice &input)
{
	signature = input.read_int32();
	if (signature != 0x02014b50)
	{
		throw CL_Exception("Incorrect File Header signature");
	}
	version_made_by = input.read_int16();
	version_needed_to_extract = input.read_int16();
	general_purpose_bit_flag = input.read_int16();
	compression_method = input.read_int16();
	last_mod_file_time = input.read_int16();
	last_mod_file_date = input.read_int16();
	crc32 = input.read_uint32();
	compressed_size = input.read_int32();
	uncompressed_size = input.read_int32();
	file_name_length = input.read_int16();
	extra_field_length = input.read_int16();
	file_comment_length = input.read_int16();
	disk_number_start = input.read_int16();
	internal_file_attributes = input.read_int16();
	external_file_attributes = input.read_int32();
	relative_offset_of_local_header = input.read_int32();
	filename.resize(file_name_length);

	char *str1 = new char[file_name_length];
	char *str2 = new char[extra_field_length];
	char *str3 = new char[file_comment_length];
	try
	{
		input.read(str1, file_name_length);
		input.read(str2, extra_field_length);
		input.read(str3, file_comment_length);
		if (general_purpose_bit_flag & CL_ZIP_USE_UTF8)
		{
			filename = CL_StringHelp::utf8_to_text(CL_StringRef8(str1, file_name_length, false));
			file_comment = CL_StringHelp::utf8_to_text(CL_StringRef8(str3, file_comment_length, false));
		}
		else
		{
			filename = CL_StringHelp::cp437_to_text(CL_StringRef8(str1, file_name_length, false));
			file_comment = CL_StringHelp::cp437_to_text(CL_StringRef8(str3, file_comment_length, false));
		}

		extra_field = CL_DataBuffer(str2, extra_field_length);

		delete[] str1;
		delete[] str2;
		delete[] str3;
	}
	catch (...)
	{
		delete[] str1;
		delete[] str2;
		delete[] str3;
		throw;
	}
}
void CL_ZipFileHeader::save(CL_IODevice &output)
{
	CL_String8 str_filename;
	CL_String8 str_comment;
	if (general_purpose_bit_flag & CL_ZIP_USE_UTF8)
	{
		str_filename = CL_StringHelp::text_to_utf8(filename);
		str_comment = CL_StringHelp::text_to_utf8(file_comment);
	}
	else
	{
		str_filename = CL_StringHelp::text_to_cp437(filename);
		str_comment = CL_StringHelp::text_to_cp437(file_comment);
	}

	file_name_length = str_filename.length();
	file_comment_length = str_comment.length();

	output.write_int32(signature);
	output.write_int16(version_made_by);
	output.write_int16(version_needed_to_extract);
	output.write_int16(general_purpose_bit_flag);
	output.write_int16(compression_method);
	output.write_int16(last_mod_file_time);
	output.write_int16(last_mod_file_date);
	output.write_uint32(crc32);
	output.write_int32(compressed_size);
	output.write_int32(uncompressed_size);
	output.write_int16(file_name_length);
	output.write_int16(extra_field_length);
	output.write_int16(file_comment_length);
	output.write_int16(disk_number_start);
	output.write_int16(internal_file_attributes);
	output.write_int32(external_file_attributes);
	output.write_int32(relative_offset_of_local_header);
	output.write(str_filename.data(), file_name_length);
	output.write(extra_field.get_data(), extra_field_length);
	output.write(file_comment.data(), file_comment_length);
}