📄 photoshopreader.cpp
字号:
item_length = m_name.length();
outfile << item_length;
for (i = 0; i < m_name.length() ; i++)
{
outfile.sputc( 0 );
outfile.sputc( m_name[i] );
}
item_length = 4;
id = index;
outfile.sputn( "8BIMlyid", 8 );
outfile << item_length;
outfile << id;
int extra_field_end = tell(outfile );
length = extra_field_end - extra_field_start - sizeof(length);
outfile.pubseekpos( extra_field_start );
outfile << length;
outfile.pubseekpos( extra_field_end );
return true;
}
// ------------------------------------------------------------------------
// photoshop layer
// ------------------------------------------------------------------------
bool t_photoshop_layer::write_channels( std::streambuf& outfile, int channel_block_start,
CDxFileProgress* file_progress )
{
int channel_index;
int channel_start;
int channel_end;
std::vector<long> channel_lengths;
for (channel_index = 0; channel_index < m_channels.size(); channel_index++)
{
channel_start = tell( outfile );
if (!m_channels[channel_index]->write( outfile, file_progress ))
return false;
channel_end = tell( outfile );
channel_lengths.push_back( channel_end - channel_start );
}
int file_end = tell( outfile );
outfile.pubseekpos( channel_block_start );
for (channel_index = 0; channel_index < m_channels.size(); channel_index++)
{
t_mac_short id;
t_mac_long length;
id = m_channels[channel_index]->get_id();
length = channel_lengths[channel_index];
outfile << id;
outfile << length;
}
outfile.pubseekpos( file_end );
return true;
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
t_photoshop_image::~t_photoshop_image()
{
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
t_photoshop_layer_ptr t_photoshop_image::get_layer( const char* name )
{
int i;
i = m_layers.size();
while (i--)
if (strcmp( name, m_layers[i]->get_name().c_str() ) == 0)
return m_layers[i];
return 0;
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
bool t_photoshop_image::read_resources( std::streambuf& infile, long length )
{
infile.pubseekoff( length, std::ios::cur );
return true;
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
bool t_photoshop_image::read_layers( std::streambuf& infile, CDxFileProgress* file_progress,
int bar_size )
{
t_mac_long length;
t_mac_short layer_count;
int layer_index;
t_photoshop_layer_ptr layer;
infile >> length;
if (length == 0)
return true;
infile >> layer_count;
int layer_max = static_cast<signed short>(layer_count.get());
layer_max = abs( layer_max );
for (layer_index = 0; layer_index < layer_max; layer_index++)
{
layer = new t_photoshop_layer;
m_layers.push_back( layer );
if (!layer->read( infile ))
return false;
bar_size += ((layer->get_width() * layer->get_height() + k_file_progress_unit - 1)
/ k_file_progress_unit) * layer->get_channel_count();
}
if (file_progress != 0)
file_progress->set_max_value( bar_size );
for (layer_index = 0; layer_index < layer_max; layer_index++)
if (!m_layers[layer_index]->read_channels( infile, file_progress ))
return false;
int position = tell(infile);
if ((position & 1) == 1)
infile.sbumpc();
return true;
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
bool t_photoshop_image::read( std::streambuf& infile, CDxFileProgress* file_progress )
{
t_photoshop_file_header file_header;
::read( infile, &file_header, sizeof(file_header));
if (memcmp( file_header.signature, "8BPS", 4 ) != 0)
return false;
if (file_header.version != 1)
return false;
m_height = file_header.rows;
m_width = file_header.columns;
m_color_mode = file_header.color_mode;
int i;
for (i = 0; i < sizeof( file_header.reserved ); i++)
if (file_header.reserved[i] != 0)
return false;
if (file_header.channel_count < 1 || file_header.channel_count > 24)
return false;
// read color mode information
t_mac_long length;
infile >> length;
if (length != 0)
{
if (length != 256 * 3)
return false;
BYTE buffer[256];
::read( infile, buffer, sizeof(buffer));
for (i = 0; i < 256; i++)
m_palette[i].red = buffer[i];
::read( infile, buffer, sizeof(buffer));
for (i = 0; i < 256; i++)
m_palette[i].green = buffer[i];
::read( infile, buffer, sizeof(buffer));
for (i = 0; i < 256; i++)
m_palette[i].blue = buffer[i];
}
infile >> length;
if (!read_resources( infile, length ))
return false;
int bar_size = ((m_width * m_height + k_file_progress_unit - 1) /
k_file_progress_unit ) * file_header.channel_count;
infile >> length;
if (length > 0)
{
if (!read_layers( infile, file_progress, bar_size ))
return false;
// read global layer mask (and discard)
infile >> length;
infile.pubseekoff( length, std::ios::cur );
}
else
{
if (file_progress != 0)
file_progress->set_max_value( bar_size );
}
// read background channels
return m_background.read_background( infile, file_header.columns, file_header.rows,
file_header.channel_count,
file_header.bits_per_channel, m_color_mode,
file_progress );
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
bool t_photoshop_image::write_resources( std::streambuf& outfile )
{
t_image_resource_header header;
int block_start = tell( outfile );
t_mac_long length;
length = 0;
outfile << length;
return true;
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
bool t_photoshop_image::write_layers( std::streambuf& outfile, CDxFileProgress* file_progress )
{
t_mac_long length;
t_mac_short layer_count;
int layer_index;
t_photoshop_layer_ptr layer;
std::vector<int> channel_block_starts;
int channel_count = m_background.get_channel_count();
int block_start = tell(outfile );
outfile << length;
layer_count = m_layers.size();
outfile << layer_count;
channel_block_starts.resize( m_layers.size() );
for (layer_index = 0; layer_index < m_layers.size(); layer_index++)
{
if (!m_layers[layer_index]->write( outfile, &channel_block_starts[layer_index], layer_index + 1 ))
return false;
channel_count += m_layers[layer_index]->get_channel_count();
}
if (file_progress != 0)
file_progress->set_max_value( ((m_width * m_height + k_file_progress_unit - 1)
/ k_file_progress_unit ) * channel_count );
for (layer_index = 0; layer_index < m_layers.size(); layer_index++)
if (!m_layers[layer_index]->write_channels( outfile, channel_block_starts[layer_index],
file_progress ))
return false;
if ((tell( outfile ) & 1) == 1)
outfile.sputc( 0 );
int block_end = tell( outfile );
outfile.pubseekpos( block_start );
length = block_end - block_start - sizeof(length);
outfile << length;
outfile.pubseekpos( block_end );
return true;
}
// ------------------------------------------------------------------------
// clear all elements of a channel
// ------------------------------------------------------------------------
void t_photoshop_channel::clear()
{
memset( m_data.begin(), 0, m_width * m_height );
}
// ------------------------------------------------------------------------
// clear all elements of a layer
// ------------------------------------------------------------------------
void t_photoshop_layer::clear()
{
int i;
for (i = 0; i < m_channels.size(); i++)
m_channels[i]->clear();
}
// ------------------------------------------------------------------------
// create the background layers from the foreground layers
// ------------------------------------------------------------------------
void t_photoshop_image::create_background()
{
if (m_layers.size() == 0)
return;
// clear background
int i;
int x, y;
PIX32 pixel;
GRECT rect;
t_photoshop_layer_ptr layer;
m_background.clear();
for (i = 0; i < m_layers.size(); i++)
{
layer = m_layers[i];
rect = intersection( layer->get_rect(), m_background.get_rect() );
for (y = rect.top; y < rect.bottom; y++)
for (x = rect.left; x < rect.right; x++)
{
pixel = layer->get_pixel( x, y );
if (pixel.alpha > 0)
m_background.set_pixel( x, y, pixel );
}
}
}
// --------------------------------------------------------------------------------
// photoshop image
// --------------------------------------------------------------------------------
bool t_photoshop_image::write( std::streambuf& outfile, CDxFileProgress* file_progress )
{
t_photoshop_file_header file_header;
file_header.bits_per_channel = 8;
file_header.channel_count = m_background.get_channel_count();
file_header.color_mode = m_color_mode;
file_header.rows = m_height;
file_header.columns = m_width;
file_header.version = 1;
memcpy( file_header.signature, "8BPS", 4 );
memset( file_header.reserved, 0, sizeof( file_header.reserved ) );
::write( outfile, &file_header, sizeof(file_header));
// read color mode information
t_mac_long length;
if ( m_color_mode != k_color_mode_indexed )
{
length = 0;
outfile << length;
}
else
{
length = 256 * 3;
outfile << length;
BYTE buffer[256];
int i;
for (i = 0; i < 256; i++)
buffer[i] = m_palette[i].red;
::write( outfile, buffer, sizeof(buffer));
for (i = 0; i < 256; i++)
buffer[i] = m_palette[i].green;
::write( outfile, buffer, sizeof(buffer));
for (i = 0; i < 256; i++)
buffer[i] = m_palette[i].blue;
::write( outfile, buffer, sizeof(buffer));
}
write_resources( outfile );
int layer_start = tell( outfile );
outfile << length;
if (m_layers.size() > 0)
{
write_layers( outfile, file_progress );
// write global layer mask
length = 0;
outfile << length;
}
else
{
if (file_progress != 0)
file_progress->set_max_value( ((m_width * m_height + k_file_progress_unit - 1)
/ k_file_progress_unit)
* m_background.get_channel_count() );
}
int layer_end = tell( outfile );
outfile.pubseekpos( layer_start );
length = layer_end - layer_start - sizeof(length);
outfile << length;
outfile.pubseekpos( layer_end );
create_background();
return m_background.write_background( outfile, file_progress );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -