OSGPSDImageFileType.cpp File Reference

#include "OSGConfig.h"
#include "OSGBaseFunctions.h"
#include "OSGPSDImageFileType.h"
#include <OSGLog.h>

Go to the source code of this file.

Namespaces

namespace  osg

Classes

struct  PSDHeader

Functions

static UInt32 parseUInt32 (char *&ptr)
static UInt16 parseUInt16 (char *&ptr)
static bool readHeader (std::istream &is, PSDHeader &header)
static bool readColorModeData (std::istream &is, const PSDHeader &header, char *colormap)
static bool readResource (std::istream &is, UInt32 &length, Int16 &transparentIndex)
static bool readImageResources (std::istream &is, Int16 &transparentIndex)
static bool readLayerAndMaskInformation (std::istream &is)
static bool readImageData (std::istream &is, const PSDHeader &header, UInt16 relevantChannels, char *colormap, Int16 &transparentIndex, UInt8 *data)

Variables

static const Char8 * suffixArray []


Function Documentation

static UInt32 parseUInt32 ( char *&  ptr  )  [static]

Definition at line 65 of file OSGPSDImageFileType.cpp.

Referenced by osg::readBitmapFileHeader(), osg::readBitmapInfoHeader(), readColorModeData(), readHeader(), readImageResources(), readLayerAndMaskInformation(), and readResource().

00066 {
00067   UInt32 result =
00068     (static_cast<UInt32>(static_cast<UInt8>(ptr[0])) << 24) |
00069     (static_cast<UInt32>(static_cast<UInt8>(ptr[1])) << 16) |
00070     (static_cast<UInt32>(static_cast<UInt8>(ptr[2])) <<  8) |
00071     (static_cast<UInt32>(static_cast<UInt8>(ptr[3])) <<  0);
00072   ptr += 4;
00073   return result;
00074 }

static UInt16 parseUInt16 ( char *&  ptr  )  [static]

Definition at line 76 of file OSGPSDImageFileType.cpp.

Referenced by osg::readBitmapFileHeader(), osg::readBitmapInfoHeader(), readHeader(), readImageData(), and readResource().

00077 {
00078   UInt16 result =
00079     (static_cast<UInt32>(static_cast<UInt8>(ptr[0])) << 8) |
00080     (static_cast<UInt32>(static_cast<UInt8>(ptr[1])) << 0);
00081   ptr +=2;
00082   return result;
00083 }

static bool readHeader ( std::istream &  is,
PSDHeader header 
) [static]

Definition at line 98 of file OSGPSDImageFileType.cpp.

References PSDHeader::channels, PSDHeader::columns, PSDHeader::depth, PSDHeader::mode, parseUInt16(), parseUInt32(), PSDHeader::reserved, PSDHeader::rows, PSDHeader::signature, and PSDHeader::version.

Referenced by osg::PSDImageFileType::read().

00099 {
00100   // Read the header into the buffer
00101   char buffer[26];
00102   is.read(buffer, 26);
00103   if (is.gcount() != 26)
00104     return false;
00105 
00106   // Parse the header
00107   char *ptr = buffer;
00108   memcpy(header.signature, ptr, 4);
00109   ptr += 4;
00110   header.version = parseUInt16(ptr);
00111   memcpy(header.reserved, ptr, 6);
00112   ptr += 6;
00113   header.channels = parseUInt16(ptr);
00114   header.rows = parseUInt32(ptr);
00115   header.columns = parseUInt32(ptr);
00116   header.depth = parseUInt16(ptr);
00117   header.mode = parseUInt16(ptr);
00118 
00119   // Check the header
00120   if (memcmp(header.signature, "8BPS", 4) != 0)
00121     return false;
00122   if (header.version != 1)
00123     return false;
00124 
00125   return true;
00126 }

static bool readColorModeData ( std::istream &  is,
const PSDHeader header,
char *  colormap 
) [static]

Definition at line 128 of file OSGPSDImageFileType.cpp.

References PSDHeader::mode, and parseUInt32().

Referenced by osg::PSDImageFileType::read().

00129 {
00130   // Read the length of the color mode data into the buffer
00131   char buffer[4];
00132   is.read(buffer, 4);
00133   if (is.gcount() != 4)
00134     return false;
00135 
00136   // Parse the length
00137   char *ptr = buffer;
00138   UInt32 length = parseUInt32(ptr);
00139 
00140   // Parse the color palette
00141   if (header.mode == 2)
00142   {
00143     if (length != 768)
00144       return false;
00145     length = 0;
00146     is.read(colormap, 768);
00147     if (static_cast<UInt32>(is.gcount()) != 768)
00148       return false;
00149   }
00150 
00151   // Ignore remaining data
00152   is.ignore(length);
00153   if (static_cast<UInt32>(is.gcount()) != length)
00154     return false;
00155 
00156   return true;
00157 }

static bool readResource ( std::istream &  is,
UInt32 &  length,
Int16 &  transparentIndex 
) [static]

Definition at line 159 of file OSGPSDImageFileType.cpp.

References parseUInt16(), and parseUInt32().

Referenced by readImageResources().

00160 {
00161   // Parse type, id, name and size
00162   if (length < 8)
00163     return false;
00164   char buffer[8];
00165   is.read(buffer, 6);
00166   if (is.gcount() != 6)
00167     return false;
00168   length -= 6;
00169   char *ptr = buffer + 4;
00170   UInt16 id = parseUInt16(ptr);
00171   int c = is.get();
00172   if (c == EOF)
00173     return false;
00174   length -= 1;
00175   if ((c & 1) == 0)
00176     ++c;
00177   if (static_cast<UInt32>(c) > length)
00178     return false;
00179   is.ignore(c);
00180   if (is.gcount() != c)
00181     return false;
00182   length -= c;
00183   ptr = buffer + 4;
00184   is.read(ptr, 4);
00185   if (is.gcount() != 4)
00186     return false;
00187   length -= 4;
00188   UInt32 size = parseUInt32(ptr);
00189   if (size > length)
00190     return false;
00191 
00192   if (memcmp(buffer, "8BIM", 4) == 0)
00193   {
00194     switch (id)
00195     {
00196     case 0x417:
00197       if (size == 2)
00198       {
00199         ptr = buffer + 4;
00200         is.read(ptr, 2);
00201         if (is.gcount() != 2)
00202           return false;
00203         size = 0;
00204         length -= 2;
00205         transparentIndex = parseUInt16(ptr);
00206       }
00207       break;
00208     }
00209   }
00210 
00211   if ((size & 1) != 0)
00212     ++size;
00213   is.ignore(size);
00214   if (static_cast<UInt32>(is.gcount()) != size)
00215     return false;
00216   length -= size;
00217 
00218   return true;
00219 }

static bool readImageResources ( std::istream &  is,
Int16 &  transparentIndex 
) [static]

Definition at line 221 of file OSGPSDImageFileType.cpp.

References parseUInt32(), and readResource().

Referenced by osg::PSDImageFileType::read().

00222 {
00223   // Read the length of the image resources into the buffer
00224   char buffer[4];
00225   is.read(buffer, 4);
00226   if (is.gcount() != 4)
00227     return false;
00228 
00229   // Parse the length
00230   char *ptr = buffer;
00231   UInt32 length = parseUInt32(ptr);
00232 
00233   // Parse resources
00234   while (length > 0)
00235     if (readResource(is, length, transparentIndex) == false)
00236       return false;
00237 
00238   return true;
00239 }

static bool readLayerAndMaskInformation ( std::istream &  is  )  [static]

Definition at line 241 of file OSGPSDImageFileType.cpp.

References parseUInt32().

Referenced by osg::PSDImageFileType::read().

00242 {
00243   // Read the length of the layer and mask information into the buffer
00244   char buffer[4];
00245   is.read(buffer, 4);
00246   if (is.gcount() != 4)
00247     return false;
00248 
00249   // Parse the length
00250   char *ptr = buffer;
00251   UInt32 length = parseUInt32(ptr);
00252 
00253   // Ignore data
00254   is.ignore(length);
00255   if (static_cast<UInt32>(is.gcount()) != length)
00256     return false;
00257 
00258   return true;
00259 }

static bool readImageData ( std::istream &  is,
const PSDHeader header,
UInt16  relevantChannels,
char *  colormap,
Int16 &  transparentIndex,
UInt8 *  data 
) [static]

Definition at line 261 of file OSGPSDImageFileType.cpp.

References PSDHeader::channels, PSDHeader::columns, PSDHeader::depth, PSDHeader::mode, parseUInt16(), and PSDHeader::rows.

Referenced by osg::PSDImageFileType::read().

00262 {
00263   // Read the compression into the buffer
00264   std::vector<char> buffer;
00265   buffer.resize(2);
00266   char *ptr = &(buffer.front());
00267   is.read(ptr, 2);
00268   if (is.gcount() != 2)
00269     return false;
00270 
00271   // Parse the compression
00272   UInt16 compression = parseUInt16(ptr);
00273   if (compression > 1)
00274     return false;
00275 
00276   // Calculate the bytes per line
00277   UInt32 bpl = (header.columns * header.depth + 7) / 8;
00278   UInt32 dstBpl;
00279   if (header.mode == 2) // Indexed color
00280     dstBpl = header.columns * (transparentIndex != -1 ? 4 : 3);
00281   else
00282     dstBpl = header.columns * relevantChannels;
00283 
00284   // When the image data is compressed, we have to read the
00285   // lengths of the lines
00286   std::vector<UInt16> lineLength;
00287   if (compression == 1)
00288   {
00289     UInt32 numLines = header.rows * header.channels;
00290     lineLength.resize(numLines);
00291     UInt32 size = numLines * 2;
00292     buffer.resize(size);
00293     ptr = &(buffer.front());
00294     is.read(ptr, size);
00295     if (static_cast<UInt32>(is.gcount()) != size)
00296       return false;
00297     UInt16 maxLength = 0;
00298     for (UInt32 i = 0; i < numLines; ++i)
00299     {
00300       UInt16 length = parseUInt16(ptr);
00301       lineLength[i] = length;
00302       if (length > maxLength)
00303         maxLength = length;
00304     }
00305     buffer.resize(maxLength);
00306   }
00307   else
00308     buffer.resize(bpl);
00309 
00310   UInt32 lineNumber = 0;
00311   std::vector<char> line(bpl);
00312   UInt8 *dstPtr;
00313   for (UInt16 c = 0; c < header.channels; ++c)
00314   {
00315     dstPtr = data + c + dstBpl * (header.rows - 1);
00316     for (UInt32 y = 0; y < header.rows; ++y)
00317     {
00318       // Read the line
00319       UInt32 size;
00320       if (compression == 1)
00321       {
00322         ptr = &(buffer.front());
00323         size = lineLength[lineNumber];
00324       }
00325       else
00326       {
00327         ptr = &(line.front());
00328         size = bpl;
00329       }
00330       is.read(ptr, size);
00331       if (static_cast<UInt32>(is.gcount()) != size)
00332         return false;
00333 
00334       if (c < relevantChannels)
00335       {
00336         // Decompress the line
00337         if (compression == 1)
00338         {
00339           UInt32 src = 0, dst = 0;
00340           while (src < size)
00341           {
00342             UInt8 runCount = buffer[src++];
00343             if (runCount & 0x80)
00344             {
00345               runCount = -runCount + 1;
00346               if (dst + runCount > bpl)
00347                 return false;
00348               for (; runCount > 0; --runCount)
00349                 line[dst++] = buffer[src];
00350               ++src;
00351             }
00352             else
00353             {
00354               ++runCount;
00355               if (dst + runCount > bpl)
00356                 return false;
00357               for (; runCount > 0; --runCount)
00358                 line[dst++] = buffer[src++];
00359             }
00360           }
00361           if (dst != bpl)
00362             return false;
00363         }
00364 
00365         // Copy the line into the image
00366         UInt8 *lineDstPtr = dstPtr;
00367         switch (header.depth)
00368         {
00369         case 1:
00370           for (UInt32 x = 0; x < header.columns; ++x)
00371           {
00372             UInt8 v = line[x / 8] & (1 << (7 - (x & 7)));
00373             *lineDstPtr = v != 0 ? 0 : 255;
00374             lineDstPtr += relevantChannels;
00375           }
00376           break;
00377         case 8:
00378           if (header.mode == 2)
00379             for (UInt32 x = 0; x < header.columns; ++x)
00380             {
00381               UInt8 index = line[x];
00382               *lineDstPtr++ = colormap[index];
00383               *lineDstPtr++ = colormap[index + 256];
00384               *lineDstPtr++ = colormap[index + 512];
00385               if (transparentIndex != -1)
00386                 *lineDstPtr++ = index == transparentIndex ? 0 : 255;
00387             }
00388           else
00389             for (UInt32 x = 0; x < header.columns; ++x)
00390             {
00391               *lineDstPtr = line[x];
00392               lineDstPtr += relevantChannels;
00393             }
00394           break;
00395         case 16:
00396           for (UInt32 x = 0; x < header.columns; ++x)
00397           {
00398             *lineDstPtr = line[x * 2];
00399             lineDstPtr += relevantChannels;
00400           }
00401           break;
00402         }
00403       }
00404       dstPtr -= dstBpl;
00405 
00406       ++lineNumber;
00407     }
00408   }
00409 
00410   return true;
00411 }


Variable Documentation

const Char8* suffixArray[] [static]

Initial value:

 {
  "psd"
}

Definition at line 415 of file OSGPSDImageFileType.cpp.


Generated on Mon Mar 17 11:10:14 2008 for OpenSG by  doxygen 1.5.5