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

📄 photoshopreader.cpp

📁 网络泡泡被.net管理
💻 CPP
📖 第 1 页 / 共 4 页
字号:

#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 + -