Introduction
Here is a quick way to load color, alpha and selection channel data from an
flattened* Adobe Photoshop image file.
* If Photoshop's save file
preference is set to maximize compatibility with older versions the file will
contain a pre-composited version of the image will be saved along with the
layers. ).
Example Use
typedef BPT::TPSDFileLoader<ExampleSurface> loader_type;
typedef loader_type::channel_collection_type::iterator channel_iterator;
loader_type psdLoader;
loader_type::channel_collection_type * pChannels = psdLoader.Load( pszFilename );
if ( pChannels ){
int channelCount = pChannels->size();
std::cout << "There are " << channelCount << "channels.\n" << std::endl;
int channel = 1;
for ( channel_iterator it = pChannels->begin(); it != pChannels->end(); it++ ) {
ExampleSurface * pSurface = *it;
if ( 1 == channel ) {
std::cout << "Red ";
} else if ( 2 == channel ) {
std:cout << "Green ";
} else if ( 3 == channel ) {
std:cout << "Blue ";
} else {
std:cout << "Alpha ";
}
std::cout << "Channel " << channel << "of " << channelCount;
std::cout << " Width " << pSurface->Width();
std::cout << " Height " << pSurface->Height();
std::cout << endl;
++channel;
}
psdLoader.Unload( pChannels );
}
The TPSDFileLoader template parameters
template<
class CHANNEL_SURFACE
,class CHANNEL_COLLECTION = std::list<CHANNEL_SURFACE *>
,class INPUT_POLICY = TFileIO<>
,class SIZE_COLLECTION = std::vector<int>
>
class TPSDFileLoader {
The default template parameters are reasonable defaults for use in a Win32
environment. However if you want to bring the code to a slightly different
platform or you have specific storage needs you can override defaults with your
types. If you are fine with the defaults, the CHANNEL_SURFACE
is
the only type you *must* specify.
CHANNEL_SURFACE
The loader references only four methods ( Create()
,
Width()
, Height()
and Iterator()
) and
one exposed type ( pixel_iterator
) from the
CHANNEL_SURFACE
type. The interface is relatively small it
should be easy to write an adaptor class for most bitmap representations.
Here is an example surface that conforms to the loader's
CHANNEL_SURFACE
use.
struct ExampleSurface {
typedef BYTE pixel_type;
typedef pixel_type * pixel_iterator;
SIZE m_Size;
pixel_iterator m_Storage;
int Width() { return m_Size.cx; }
int Height() { return m_Size.cy; }
pixel_iterator Iterator( const int x, const int y ) {
if ( !m_Storage ) return 0;
return m_Storage + (y * m_Size.cx) + x;
}
void Destroy() {
if ( m_Storage ) {
delete [] m_Storage;
m_Storage = 0;
}
m_Size.cx = m_Size.cy = 0;
}
bool Create( const int width, const int height ) {
Destroy();
m_Storage = new pixel_type [ width * height ];
m_Size.cx = width; m_Size.cy = height;
return (0 != m_Storage);
}
~ExampleSurface() { Destroy(); }
ExampleSurface() : m_Storage(0) { m_Size.cx = m_Size.cy = 0; }
};
CHANNEL_COLLECTION
CHANNEL_COLLECTION
is the collection type that will be used to
return the channel data.
class CHANNEL_COLLECTION = std::list<CHANNEL_SURFACE *>
INPUT_POLICY
This policy class is used to provide low-level input capabilities; the
default class is simply a wrapper around the fopen/fclose and related basic read
methods. It has methods for reading 16 bit and 32 bit values stored in endian
specific fashion. In addition to providing the necessary read interface it
also hides memory allocation/deallocation details when reading chunks of data
into memory.
struct ExampleInputPolicy {
bool Open( const char * filename, const char * access );
void Close();
void Seek( const int pos, const int mode );
int Read_Byte();
int Read_m16();
int Read_m32();
BYTE * LoadData( const int nBytes );
void UnloadData( BYTE * ptr );
};
SIZE_COLLECTION
Internally the size of each channel is temporarily cached to make the loader
implementation simpler.
class SIZECOLLECTION = std::vector<int>
STL
if you want to eliminate the dependency on the STL you can do so by
specifying a different collection type for both the SIZE_COLLECTION
and CHANNEL_COLLECTION
.
Includes
If you plan on using the default implementation you will need to include the
list, vector headers.
#include <list>
#include <vector>
#include "psd_load_src.h"
Public Methods
Unload()
destroys the returned channel collection.
void Unload( CHANNEL_COLLECTION * pLoadedData );
LoadFromAbstraction()
is the low-level public method, it is used
to read from the IO
policy object passed.
template< class INPUT > CHANNEL_COLLECTION *
LoadFromAbstraction( INPUT & input, const int nLoadChannelCountMax = 0 );
Load()
-- accepts a null terminated string and uses the
INPUT_POLICY
and LoadFromAbstraction()
to load the
channel data.
CHANNEL_COLLECTION *
Load( const char * filename, const int nLoadChannelCountMax = 0 );
Usage
It's common to need access to the individual channel data in an
Adobe Photoshop file, so this template saves a lot of time and effort.