Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Adobe Photoshop file loader template class

0.00/5 (No votes)
29 Jan 2002 1  
A template class to making loading Adobe Photoshop files easier

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. 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here