コード例 #1
0
ファイル: targa_loader.cpp プロジェクト: ARMCoderCHS/ClanLib
void TargaLoader::read_image_data()
{
	image_data = DataBuffer(bytes_per_pixel_entry * image_width * image_height);

	if (image_type == 9 || image_type == 10 || image_type == 11) // RLE compressed
	{
		DataBuffer rle_data(file.get_size() - file.get_position());
		file.read(rle_data.get_data(), rle_data.get_size());

		unsigned char *input = reinterpret_cast<unsigned char*>(rle_data.get_data());
		unsigned char *output = reinterpret_cast<unsigned char*>(image_data.get_data());
		int pixels_left = image_width * image_height;
		int input_available = rle_data.get_size();
		while (pixels_left > 0 && input_available > 0)
		{
			int code = *input;
			int count = (code & 0x7f) + 1;
			bool rle_packet = (code & 0x80) != 0;

			input++;
			input_available--;

			if (rle_packet)
			{
				if (bytes_per_pixel_entry > input_available && pixels_left >= count) // Check for buffer overruns
					break;

				for (int i = 0; i < count; i++)
					memcpy(output + i * bytes_per_pixel_entry, input, bytes_per_pixel_entry);

				input += bytes_per_pixel_entry;
			}
			else
			{
				if (count * bytes_per_pixel_entry >= input_available && pixels_left >= count) // Check for buffer overruns
					break;

				memcpy(output, input, count * bytes_per_pixel_entry);

				input += count * bytes_per_pixel_entry;
			}

			output += bytes_per_pixel_entry * count;
			pixels_left -= count;
		}
	}
	else
	{
		file.read(image_data.get_data(), image_data.get_size());
	}
}
コード例 #2
0
ファイル: huffman.cpp プロジェクト: Fulg/mame
huffman_error huffman_context_base::export_tree_huffman(bitstream_out &bitbuf)
{
	// first RLE compress the lengths of all the nodes
	dynamic_buffer rle_data(m_numcodes);
	UINT8 *dest = &rle_data[0];
	std::vector<UINT16> rle_lengths(m_numcodes/3);
	UINT16 *lengths = &rle_lengths[0];
	int last = ~0;
	int repcount = 0;

	// use a small huffman context to create a tree (ignoring RLE lengths)
	huffman_encoder<24, 6> smallhuff;

	// RLE-compress the lengths
	for (int curcode = 0; curcode < m_numcodes; curcode++)
	{
		// if this is the end of a repeat, flush any accumulation
		int newval = m_huffnode[curcode].m_numbits;
		if (newval != last && repcount > 0)
		{
			if (repcount == 1)
				smallhuff.histo_one(*dest++ = last + 1);
			else
				smallhuff.histo_one(*dest++ = 0), *lengths++ = repcount - 2;
		}

		// if same as last, just track repeats
		if (newval == last)
			repcount++;

		// otherwise, write it and start a new run
		else
		{
			smallhuff.histo_one(*dest++ = newval + 1);
			last = newval;
			repcount = 0;
		}
	}

	// flush any final RLE counts
	if (repcount > 0)
	{
		if (repcount == 1)
			smallhuff.histo_one(*dest++ = last + 1);
		else
			smallhuff.histo_one(*dest++ = 0), *lengths++ = repcount - 2;
	}

	// compute an optimal tree
	smallhuff.compute_tree_from_histo();

	// determine the first and last non-zero nodes
	int first_non_zero = 31, last_non_zero = 0;
	for (int index = 1; index < smallhuff.m_numcodes; index++)
		if (smallhuff.m_huffnode[index].m_numbits != 0)
		{
			if (first_non_zero == 31)
				first_non_zero = index;
			last_non_zero = index;
		}

	// clamp first non-zero to be 8 at a maximum
	first_non_zero = MIN(first_non_zero, 8);

	// output the lengths of the each small tree node, starting with the RLE
	// token (0), followed by the first_non_zero value, followed by the data
	// terminated by a 7
	bitbuf.write(smallhuff.m_huffnode[0].m_numbits, 3);
	bitbuf.write(first_non_zero - 1, 3);
	for (int index = first_non_zero; index <= last_non_zero; index++)
		bitbuf.write(smallhuff.m_huffnode[index].m_numbits, 3);
	bitbuf.write(7, 3);

	// determine the maximum length of an RLE count
	UINT32 temp = m_numcodes - 9;
	UINT8 rlefullbits = 0;
	while (temp != 0)
		temp >>= 1, rlefullbits++;

	// now encode the RLE data
	lengths = &rle_lengths[0];
	for (UINT8 *src = &rle_data[0]; src < dest; src++)
	{
		// encode the data
		UINT8 data = *src;
		smallhuff.encode_one(bitbuf, data);

		// if this is an RLE token, encode the length following
		if (data == 0)
		{
			int count = *lengths++;
			if (count < 7)
				bitbuf.write(count, 3);
			else
				bitbuf.write(7, 3), bitbuf.write(count - 7, rlefullbits);
		}
	}

	// flush the final buffer
	return bitbuf.overflow() ? HUFFERR_OUTPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
}