/*! \page tutorial PCIDSK API Tutorial The PCIDSK file format is a geospatial file format which includes raster channels (or bands) and auxilary segments which include information like georeferencing, color lookup tables, vector feature data and many other special data types. The PCIDSK SDK provides C++ classes to interface to the various different components of the file format. The PCIDSKFile is used to interface with the file as a whole. The PCIDSKChannel is used to interface with a raster channel (or band). The PCIDSKSegment is the generic interface to auxilary segments. There are additional interface classes available for some of the specific segment types. \section tut_prelimin Include files, and Namespaces The PCIDSK classes and interfaces are defined in a variety of include files, but generally it is sufficient to include just the main include file, pcidsk.h. \code #include \endcode All PCIDSK classes are part of the C++ PCIDSK namespace. It is often convenient to use this namespace explicitly making all classes and methods directly available. This can be accomplished by putting the follow declaration after the include of pcidsk.h. \code using namespace PCIDSK; \endcode However, for the balance of this tutorial we will explicitly include the namespace when accessing classes to make it clearer which definitions are coming from the SDK. \section tut_open Opening the File We start with a fairly trivial program using the SDK. In this program we open the desired file (irvine.pix), and print out general information on the number of pixels, lines and channels. \code #include "gdal_priv.h" int main() { PCIDSK::PCIDSKFile *file = PCIDSK::Open( "irvine.pix", "r", NULL ); printf( "File: %dC x %dR x %dC (%s)\n", file->GetWidth(), file->GetHeight(), file->GetChannels(), file->GetInterleaving().c_str() ); delete file; } \endcode Note the use of the PCIDSK:: prefix for classes (like PCIDSKFile) and functions (like Open()) coming from the PCIDSK namespace. The PCIDSK::Open function is used to open the file, and various methods on the object are used to get the number of pixels, lines and channels as well as the interleaving. The PCIDSK SDK API takes and returns strings using the std::string class, so to get a C printable string out we use the c_str() method on the returned string from the PCIDSK::PCIDSKFile::GetInterleaving() method. \section tut_readraster Reading Image Data The PCIDSK::PCIDSKChannel class is used to interface with raster image channels. Normally raster access is accomplished one band at a time as demonstrated in this snippit derived from tests/pcidsk_read.cpp. \code for( int channel = 1; channel <= file->GetChannels(); channel++ ) { PCIDSK::PCIDSKChannel *channel = file->GetChannel( channel ); printf( "Channel %d of type %s.\n", channel, PCIDSK::DataTypeName(channel->GetType()).c_str() );; int i_block; int x_block_count = (channel->GetWidth() + channel->GetBlockWidth()-1) / channel->GetBlockWidth(); int y_block_count = (channel->GetHeight() + channel->GetBlockHeight()-1) / channel->GetBlockHeight(); int block_size = PCIDSK::DataTypeSize(channel->GetType()) * channel->GetBlockWidth() * channel->GetBlockHeight(); void *block_buffer = malloc( block_size ); int block_count = x_block_count * y_block_count; for( i_block = 0; i_block < block_count; i_block++ ) { channel->ReadBlock( i_block, block_buffer ); /* ... do something with the imagery ... */ } free( block_buffer ); } \endcode Note that there is no effort to destroy the PCIDSKChannel object when no longer needed. Component objects like channels and segments are owned by the PCIDSK::PCIDSKFile and should not be destroyed directly. The accessors like GetChannel() return a pointer that remains owned by the file. In this case we loop through all the channels, report the channel number and type, and then loop through all the blocks in the channel reading them. For simplicity we don't actually do anything with them here. The PCIDSK::PCIDSKChannel::ReadBlock() method is used to read imagery. It reads exactly one block on the "natural block boundary" and it is read in the original data type of the channel (8U, 16U, 16S or 32R). The blocking depends on the organization of the data on disk. For pixel interleaved or band interleaved files this is one scanline while for tiled files this is one tile. The block size is established with the PCIDSK::PCIDSKChannel::GetBlockWidth() and PCIDSK::PCIDSKChannel::GetBlockHeight() methods on the channel. The data type is determined with the PCIDSK::PCIDSKChannel::GetType() method. The ReadBlock() method also has optional parameter to read a subwindow, but the PCIDSK SDK does *not* provide a generic high level "read an arbitrary window of the image" method such as is provided by libraries like GDAL or PCI's own GeoGateway/GDB. This is in keeping with the PCIDSK SDK policy of providing low level "file organization oriented" data access with a minimum of convenience services. It is intended that higher level libraries would provide caching, windowing and other convenience services. */