#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 [] |
| 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 }
const Char8* suffixArray[] [static] |
1.5.5