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

📄 photoshopreader.cpp

📁 网络泡泡被.net管理
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	if (m_green_channel == 0)
	// assume it's grayscale if only the red channel exists
	{
		assert( m_red_channel != 0 );
		m_red_channel->set( x, y, pixel.red );
	}
	else
	{
		assert( m_channels.size() >= 3 );
		m_red_channel->set( x, y, pixel.red );
		m_green_channel->set( x, y, pixel.green );
		m_blue_channel->set( x, y, pixel.blue );
	}
	if (m_alpha_channel != 0)
		m_alpha_channel->set( x, y, pixel.alpha );
}

// ------------------------------------------------------------------------
// photoshop layer
// ------------------------------------------------------------------------
PIX32 t_photoshop_layer::get_pixel( int x, int y, const PIX24* palette ) const
{
	PIX32 result;
	int          index;

	assert( m_channels.size() > 0 );
	index = m_channels[0]->get( x, y );
	result.red   = palette[index].red;
	result.green = palette[index].green;
	result.blue  = palette[index].blue;
	if (m_alpha_channel != 0)
		result.alpha = m_alpha_channel->get( x, y );
	else
		result.alpha = 255;
	return result;
}


// ------------------------------------------------------------------------
// photoshop layer
// ------------------------------------------------------------------------
const char* k_layer_info_keys[] =
{
	"levl", // Levels
	"curv", // Curves
	"brit", //=Brightness/contrast
	"blnc", // '=Color balance
	"hue ", // '=Old Hue/saturation, Photoshop 4.0
	"hue2", // '=New Hue/saturation, Photoshop 5.0
	"selc", // '=Selective color
	"thrs", // '=Threshold
	"nvrt", // '=Invert
	"post", // Posterize};
	"lrFx", // effects layer
	"tySh", // type tool
	"luni", // unicode name
	"lyid", // unique id
	""
};

enum t_layer_info_type
{
	k_layer_levels,
	k_layer_curves,
	k_layer_brightness,
	k_layer_balance,
	k_layer_hue_4,
	k_layer_hue_5,
	k_layer_selective,
	k_layer_threshold,
	k_layer_invert,
	k_layer_posterize,
	k_layer_effects,
	k_layer_text,
	k_layer_unicode_name,
	k_layer_id,
	k_layer_info_max
};

bool t_photoshop_layer::read( std::streambuf& infile )
{
	t_layer_header       header;
	int                  channel_index;
	t_photoshop_channel* channel;

	::read( infile, &header, sizeof(header));
	m_top = header.top;
	m_left = header.left;
	m_bottom = header.bottom;
	m_right = header.right;

	for (channel_index = 0; channel_index < header.channel_count; channel_index++)
	{
		t_mac_short id;
		t_mac_long  length;

		infile >> id;
		infile >> length;

		channel = new t_photoshop_channel( id, m_right - m_left, m_bottom - m_top );
		m_channels.push_back( channel );
		m_channel_lengths.push_back( length );
		switch (id)
		{
		    case 0:
				m_red_channel = channel;
				break;
			case 1:
				m_green_channel = channel;
				break;
			case 2:
				m_blue_channel = channel;
				break;
			case 0xFFFF:
				m_alpha_channel = channel;
				break;
		}
	}
	
	char signature[4];

	::read( infile, signature, sizeof(signature) );
	if (memcmp( signature, "8BIM", 4 ) != 0)
		return false;

	char blend_key[4];

	::read( infile, blend_key, sizeof(blend_key) );

	m_blend = static_cast<t_photoshop_blend>(0);
	while ( memcmp( blend_key, k_blend_keys[m_blend], sizeof( blend_key )) != 0)
	{
		m_blend = static_cast<t_photoshop_blend>(m_blend + 1);
		if (k_blend_keys[m_blend][0] == 0)
			return false;
	}

	BYTE clipping;

	infile >> m_opacity;
	infile >> clipping;
	infile >> m_flags;
	infile.sbumpc(); // skip filler byte
	
	t_mac_long length;
	t_mac_long layer_mask_length;
	t_mac_long blending_length;

	infile >> length; // overall length of extra fields.
	infile >> layer_mask_length; // length of layer mask information
	infile.pubseekoff( layer_mask_length, std::ios::cur );
	infile >> blending_length; // length of blending information
	infile.pubseekoff( blending_length, std::ios::cur );

	t_pascal_string name(4);

	name.read( infile );
	m_name = name.get();

	length = length - (layer_mask_length + blending_length + name.get_size() + 8);

	// begin reading tags
	while (length >= 8)
	{
		char       signature[4];
		char       key[4];
		t_mac_long item_length;
		int        next_position;

		::read( infile, signature, sizeof( signature ));
		if (memcmp( signature, "8BIM", 4 ) != 0)
			return false;
		::read( infile, key, sizeof(key));
		infile >> item_length;
		next_position = tell( infile ) + item_length;
		if (memcmp( key, "luni", 4 ) == 0)
		{
			int        i;
			t_mac_long string_length;

			infile >> string_length;
			m_name = "";
			for (i = 0; i < string_length; i++)
			{
				infile.sbumpc();
				m_name += infile.sbumpc();
			}
		}
		infile.pubseekpos( next_position );
		length = length - 12 - item_length;
	}
	if (length > 0)
		infile.pubseekoff( length, std::ios::cur );
	return true;
}

bool t_photoshop_layer::read_channels( std::streambuf& infile, CDxFileProgress* file_progress )
{
	int channel_index;
	int length;

	for (channel_index = 0; channel_index < m_channels.size(); channel_index++)
	{
		length = infile.pubseekoff( 0, std::ios::cur );
		if (!m_channels[channel_index]->read( infile, file_progress ))
			return false;
		length = tell( infile ) - length;
		if (length != m_channel_lengths[channel_index])
			return false;
	}
	return true;
}

// ------------------------------------------------------------------------
// photoshop layer
// ------------------------------------------------------------------------
bool t_photoshop_layer::read_background( std::streambuf& infile, int width, int height, 
										 int channels, int bits_per_channel, 
										 t_photoshop_color_mode mode, 
										 CDxFileProgress* file_progress )
{
	m_top = 0;
	m_left = 0;
	m_bottom = height;
	m_right = width;
	m_blend = k_blend_normal;
	m_opacity = 255;
	m_name = "background";

	int                  channel_index;
	t_photoshop_channel *channel;
	t_mac_short          compressed;
	std::vector<int>         scan_lengths;

	infile >> compressed;
	scan_lengths.resize( channels * height );
	if (compressed != 0)
	{
		int i;
		std::vector<t_mac_short> mac_scan_lengths;

		mac_scan_lengths.resize( channels * height );
		::read( infile, mac_scan_lengths.begin(), sizeof(t_mac_short) * channels * height );
		for (i = 0; i < mac_scan_lengths.size(); i++)
			scan_lengths[i] = mac_scan_lengths[i];
	}

	for (channel_index = 0; channel_index < channels; channel_index++)
	{
		channel = new t_photoshop_channel( channel_index, width, height );
		m_channels.push_back( channel );
		if (!channel->read_background( infile, compressed != 0,
			                           scan_lengths.begin() + channel_index * height,
									   file_progress ))
			return false;
	}

	if (mode == k_color_mode_RGB)
	{
		m_red_channel = m_channels[0];
		m_green_channel = m_channels[1];
		m_blue_channel = m_channels[2];
		if (m_channels.size() > 3)
			m_alpha_channel = m_channels[3];
	}
	if (mode == k_color_mode_indexed && m_channels.size() > 1)
		m_alpha_channel = m_channels[1];

	return true;
}


// ------------------------------------------------------------------------
// photoshop layer
// ------------------------------------------------------------------------
bool t_photoshop_layer::write_background( std::streambuf& outfile, CDxFileProgress* file_progress )
{
	int                  channel_index;
	t_mac_short          compressed;
	std::vector<int>     scan_lengths;
	int                  height = m_bottom - m_top;

	compressed = 1;
	outfile << compressed;
	scan_lengths.resize( m_channels.size() * height );

	int i;
	int scan_block_start;

	std::vector<t_mac_short> mac_scan_lengths;

	scan_block_start = tell( outfile );
	mac_scan_lengths.resize( m_channels.size() * height );
	::write( outfile, mac_scan_lengths.begin(), sizeof(t_mac_short) * m_channels.size() * height );

	channel_index = 0;
	if (!m_red_channel->write_background( outfile, scan_lengths.begin(), file_progress ))
		return false;
	channel_index++;
	if (m_green_channel != 0)
	{
		if (!m_green_channel->write_background( outfile, 
			                                    scan_lengths.begin() + channel_index * height,
												file_progress ))
			return false;
		channel_index++;
	}
	if (m_blue_channel != 0)
	{
		if (!m_blue_channel->write_background( outfile, 
			                                    scan_lengths.begin() + channel_index * height,
												file_progress ))
			return false;
		channel_index++;
	}
	if (m_alpha_channel != 0)
	{
		if (!m_alpha_channel->write_background( outfile, 
			                                    scan_lengths.begin() + channel_index * height,
												file_progress ))
			return false;
		channel_index++;
	}
	assert( channel_index == m_channels.size() );

	for (i = 0; i < mac_scan_lengths.size(); i++)
		mac_scan_lengths[i] = scan_lengths[i];
	
	int file_end = tell( outfile );
	
	outfile.pubseekpos( scan_block_start );
	::write( outfile, mac_scan_lengths.begin(), sizeof(t_mac_short) * m_channels.size() * height);
	outfile.pubseekpos( file_end );
	return true;
}

// ------------------------------------------------------------------------
// photoshop layer
// ------------------------------------------------------------------------
bool t_photoshop_layer::write( std::streambuf& outfile, int* channel_block_start, int index )
{
	t_layer_header       header;
	int                  channel_index;

	header.top = m_top;
	header.left = m_left;
	header.bottom = m_bottom;
	header.right = m_right;
	header.channel_count = m_channels.size();
	::write( outfile, &header, sizeof(header));

	*channel_block_start = tell( outfile );
	for (channel_index = 0; channel_index < header.channel_count; channel_index++)
	{
		t_mac_short id;
		t_mac_long  length;

		id = 0;
		length = 0;
		outfile << id;
		outfile << length;
	}
	
	outfile.sputn( "8BIM", 4 );
	outfile.sputn( k_blend_keys[m_blend], 4 );

	outfile << m_opacity;
	outfile.sputc( 0 );// clipping = base
	outfile.sputc( m_flags ); // flags = visible
	outfile.sputc( 0 ); // filler byte
	
	t_mac_long length;
	t_mac_long layer_mask_length;
	t_mac_long blending_length;

	int extra_field_start = tell( outfile );

	length = 0;
	layer_mask_length = 0;
	blending_length = 0;
	outfile << length; // overall length of extra fields.
	outfile << layer_mask_length; // length of layer mask information
	outfile << blending_length; // length of blending information

	t_pascal_string name(4);

	name.set( m_name.c_str() );
	name.write( outfile );

	// write layer id
	t_mac_long item_length;
	t_mac_long id;
	int        i;

	item_length = 4 + m_name.length() * 2;
	outfile.sputn( "8BIMluni", 8 );
	outfile << item_length;

⌨️ 快捷键说明

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