📄 photoshopreader.cpp
字号:
#include "stdafx.h"
#include "photoshopreader.h"
#include <assert.h>
namespace // begin unnamed namespace
{
#pragma pack(push, 1)
int const k_file_progress_unit = 100000;
// --------------------------------------------------------------------------------
// class to hold a short in big-endian (68000) format. Used for reading & writing
// mac-type shorts.
// --------------------------------------------------------------------------------
class t_mac_short
{
public:
unsigned short get() const;
void set( unsigned short arg );
unsigned short operator=(unsigned short arg);
operator unsigned short() const;
protected:
unsigned short m_data;
};
// --------------------------------------------------------------------------------
// inlines for t_mac_short
// --------------------------------------------------------------------------------
inline unsigned short t_mac_short::get() const
{
return ((m_data & 0xFF) << 8) | (m_data >> 8);
}
inline void t_mac_short::set( unsigned short arg )
{
m_data = ((arg & 0xFF) << 8) | (arg >> 8);
}
inline unsigned short t_mac_short::operator =(unsigned short arg)
{
set( arg );
return arg;
}
inline t_mac_short::operator unsigned short() const
{
return get();
}
inline std::streambuf& operator<<(std::streambuf& buffer, t_mac_short const& arg)
{
buffer.sputn( reinterpret_cast<char const*>(&arg), sizeof(arg));
return buffer;
}
inline std::streambuf& operator>>(std::streambuf& buffer, t_mac_short& arg)
{
buffer.sgetn( reinterpret_cast<char*>(&arg), sizeof(arg));
return buffer;
}
// --------------------------------------------------------------------------------
// class to hold an enum in big-endian (68000) format. Used for reading & writing
// mac-type enums.
// --------------------------------------------------------------------------------
template <class type>
class t_mac_enum : public t_mac_short
{
public:
type get() const;
type operator=(type arg);
operator type() const;
};
// --------------------------------------------------------------------------------
// inlines for t_mac_enum
// --------------------------------------------------------------------------------
template <class type>
type t_mac_enum<type>::get() const
{
return static_cast<type>(t_mac_short::get());
}
template <class type>
type t_mac_enum<type>::operator=(type arg)
{
set( arg );
return get();
}
template <class type>
t_mac_enum<type>::operator type() const
{
return get();
}
// --------------------------------------------------------------------------------
// class to hold a long in big-endian (68000) format. Used for reading & writing
// mac-type longs.
// --------------------------------------------------------------------------------
class t_mac_long
{
public:
unsigned long get() const;
void set( unsigned long arg );
unsigned long operator=(unsigned long arg);
operator unsigned long() const;
protected:
unsigned long m_data;
};
// --------------------------------------------------------------------------------
// inlines for t_mac_long
// --------------------------------------------------------------------------------
inline unsigned long t_mac_long::get() const
{
return ((m_data & 0xFF) << 24) | ((m_data & 0xFF00) << 8) | ((m_data & 0xFF0000) >> 8)
| (m_data >> 24);
}
inline void t_mac_long::set( unsigned long arg )
{
m_data = ((arg & 0xFF) << 24) | ((arg & 0xFF00) << 8) | ((arg & 0xFF0000) >> 8)
| (arg >> 24);
}
inline unsigned long t_mac_long::operator =( unsigned long arg )
{
set( arg );
return arg;
}
inline t_mac_long::operator unsigned long() const
{
return get();
}
inline std::streambuf& operator<<(std::streambuf& buffer, t_mac_long const& arg)
{
buffer.sputn( reinterpret_cast<char const*>(&arg), sizeof(arg));
return buffer;
}
inline std::streambuf& operator>>(std::streambuf& buffer, t_mac_long& arg)
{
buffer.sgetn( reinterpret_cast<char*>(&arg), sizeof(arg));
return buffer;
}
// --------------------------------------------------------------------------------
// basic file header for photoshop files
// --------------------------------------------------------------------------------
struct t_photoshop_file_header
{
char signature[4]; // should always be '8BPS'
t_mac_short version; // should always be 1.
char reserved[6]; // should always be 0.
t_mac_short channel_count; // # of channels, including alpha channels, 1-24
t_mac_long rows; // pixel height
t_mac_long columns; // pixel width
t_mac_short bits_per_channel; // 1, 8, or 16. 8 = 24 bit.
t_mac_enum<t_photoshop_color_mode> color_mode;
};
// --------------------------------------------------------------------------------
// pascal type string, padding to total length (including length byte) is even
// --------------------------------------------------------------------------------
class t_pascal_string
{
public:
t_pascal_string( int alignment = 2 );
std::string get() const;
long get_size() const; // get padded size on disk
bool read( std::streambuf& infile );
void set( const char* arg );
bool write( std::streambuf& infile ) const;
protected:
int m_alignment;
std::string m_data;
};
inline t_pascal_string::t_pascal_string( int alignment )
{
m_alignment = alignment;
}
inline std::string t_pascal_string::get() const
{
return m_data;
}
inline long t_pascal_string::get_size() const
{
return ((m_data.length() + m_alignment) / m_alignment) * m_alignment;
}
inline void t_pascal_string::set( const char* arg )
{
m_data = arg;
}
// --------------------------------------------------------------------------------
// thumbnail header
// --------------------------------------------------------------------------------
struct t_thumbnail_header
{
t_mac_long format; // format = 1 (kJpegRGB). Also supports kRawRGB (0).
t_mac_long width; // Width of thumbnail in pixels.
t_mac_long height; // Height of thumbnail in pixels.
t_mac_long bytes; // Padded row bytes as (width * bitspixel + 31) / 32 * 4.
t_mac_long total_size; // Total size as widthbytes * height * planes
t_mac_long compressed_size; // Size after compression. Used for consistentcy check.
t_mac_short bits_per_pixel; // Bits per pixel.
t_mac_short planes; // Number of planes.
};
// --------------------------------------------------------------------------------
// read an image resource header
// --------------------------------------------------------------------------------
enum t_resource_type
{
k_mac_print_info = 1001, // Macintosh print manager print info record.
k_resolution_info = 1005, // ResolutionInfo structure. See Appendix A in Photoshop SDK
k_alpha_channel_names = 1006, // Names of the alpha channels as a series of Pascal strings.
k_display_info = 1007, // DisplayInfo structure. See Appendix A in Photoshop SDK Guide.pdf.
k_caption = 1008, // The caption as a Pascal string.
k_border_information = 1009, // Border formation. Contains a fixed-number for the border width
k_background_color = 1010, // Background color. See the Colors additional file information.
k_print_flags = 1011, // Print flags. A series of one byte boolean values
k_grayscale_halftones = 1012, // Grayscale and multichannel halftoning information.
k_color_halftones = 1013, // Color halftoning information.
k_duotone_halftones = 1014, // duotone halftoning information.
k_grayscale_transfer = 1015, // Grayscale and multichannel transfer function.
k_color_transfer = 1016, // Color transfer functions.
k_duotone_transfer = 1017, // Duotone transfer functions.
k_duotone_image = 1018, // Duotone image information.
k_black_and_white_values = 1019, // Two bytes for the effective black and white values for the dot range.
k_EPS_options = 1021, // EPS options.
k_quick_mask = 1022, // Quick Mask information. 2 bytes containing Quick Mask channel ID,
k_layer_state = 1024, // Layer state information. 2 bytes containing the index of target layer.
k_working_path = 1025, // Working path (not saved). See path resource format later in this
k_layer_group_info = 1026, // Layers group information. 2 bytes per layer containing a group ID
k_IPTC_NAA_info = 1028, // IPTC-NAA record. This contains the File Info... information.
k_raw_image_mode_info = 1029, // Image mode for raw format files.
k_JPEG_quality = 1030, // JPEG quality. Private.
k_grid_values = 1032, // Grid and guides information.
k_thumnail_resource = 1033, // Thumbnail resource.
k_copyright_flag = 1034, // Copyright flag.
k_URL = 1035, // URL. Handle of a text string with uniform resource locator. Can be
k_version_5_thumbnail = 1036, // Thumbnail resource.
k_global_angle = 1037, // Global Angle.
k_color_samplers = 1038, // Color samplers resource. See color samplers resource format later in
k_ICC_profile = 1039, // ICC Profile. The raw bytes of an ICC format profile, see the ICC34.pdf
k_watermark = 1040, // One byte for Watermark.
k_ICC_untagged = 1041, // ICC Untagged. 1 byte that disables any assumed profile handling
k_effects_visible = 1042, // Effects visible. 1 byte global flag to show/hide all the effects layer.
k_spot_halftone = 1043, // Spot Halftone. 4 bytes for version, 4 bytes for length, and the vari-able
k_document_ids = 1044, // Document specific IDs, layer IDs will be generated starting at this
k_unicode_alpha_names = 1045, // Unicode Alpha Names. 4 bytes for length and the string as a unicode
k_path_information = 2000, // 2000-2998 ath Information (saved paths). See path resource format later in
k_clipping_path = 2999, // Name of clipping path. See path resource format later in this
k_print_flags_2 = 10000, // Print flags information. 2 bytes version (=1), 1 byte center crop
};
class t_image_resource_header
{
public:
long get_length() const;
std::string get_name() const;
t_resource_type get_type() const;
long get_total_length() const;
bool read( std::streambuf& infile );
bool write( std::streambuf& outfile, t_resource_type type, const char* name );
bool write_length( std::streambuf& outfile );
protected:
t_mac_enum<t_resource_type> m_resource_type;
t_pascal_string m_name;
t_mac_long m_length;
int m_header_end;
};
inline long t_image_resource_header::get_length() const
{
return m_length;
}
inline std::string t_image_resource_header::get_name() const
{
return m_name.get();
}
inline long t_image_resource_header::get_total_length() const
{
return m_name.get_size() + 10 + m_length.get();
}
inline t_resource_type t_image_resource_header::get_type() const
{
return m_resource_type;
}
// --------------------------------------------------------------------------------
// resolution info structure
// --------------------------------------------------------------------------------
enum t_display_units
{
k_unit_inches = 1,
k_unit_centimeters,
k_unit_points,
k_unit_picas,
k_unit_columns
};
struct t_resolution_info
{
t_mac_long horizontal_resolution;
t_mac_enum<t_display_units> horizontal_unit;
t_mac_enum<t_display_units> width_unit;
t_mac_long vertical_resolution;
t_mac_enum<t_display_units> vertical_unit;
t_mac_enum<t_display_units> height_unit;
};
// --------------------------------------------------------------------------------
// layer header
// --------------------------------------------------------------------------------
struct t_layer_header
{
t_mac_long top;
t_mac_long left;
t_mac_long bottom;
t_mac_long right;
t_mac_short channel_count;
};
#pragma pack(pop)
}; // end unnammed namespace
// --------------------------------------------------------------------------------
// pascal type string, padding to total length (including length byte) is even
// --------------------------------------------------------------------------------
bool t_pascal_string::read( std::streambuf& infile )
{
BYTE length;
int padding;
length = infile.sbumpc();
m_data.resize( length );
infile.sgetn( m_data.begin(), length );
// read padding bytes, if any, to make total length even.
padding = m_alignment - (length + 1) % m_alignment;
if (padding < m_alignment)
infile.pubseekoff( padding, std::ios::cur );
return true;
}
// --------------------------------------------------------------------------------
// pascal type string, padding to total length (including length byte) is even
// --------------------------------------------------------------------------------
bool t_pascal_string::write( std::streambuf& outfile ) const
{
BYTE length;
int padding;
length = m_data.length();
outfile.sputc( length );
outfile.sputn( m_data.begin(), length );
// write padding byte, if any, to make total length even.
padding = m_alignment - (length + 1) % m_alignment;
if (padding < m_alignment)
while (padding--)
outfile.sputc( 0 );
return true;
}
// --------------------------------------------------------------------------------
// read an image resource header
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -