Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PSDParser.cpp view on Meta::CPAN
FreeImage_Unload(bitmap);
SAFE_DELETE_ARRAY(line_start);
throw std::bad_alloc();
}
io->read_proc(rleLineSizeList, 2, nChannels * nHeight, handle);
WORD largestRLELine = 0;
for(unsigned ch = 0; ch < nChannels; ++ch) {
for(unsigned h = 0; h < nHeight; ++h) {
const unsigned index = ch * nHeight + h;
#ifndef FREEIMAGE_BIGENDIAN
SwapShort(&rleLineSizeList[index]);
#endif
if(largestRLELine < rleLineSizeList[index]) {
largestRLELine = rleLineSizeList[index];
}
}
}
BYTE* rle_line_start = new (std::nothrow) BYTE[largestRLELine];
if(!rle_line_start) {
FreeImage_Unload(bitmap);
SAFE_DELETE_ARRAY(line_start);
SAFE_DELETE_ARRAY(rleLineSizeList);
throw std::bad_alloc();
}
// Read the RLE data (assume 8-bit)
const BYTE* const line_end = line_start + lineSize;
for (unsigned ch = 0; ch < nChannels; ch++) {
const unsigned channelOffset = ch * bytes;
BYTE* dst_line_start = dst_first_line;
for(unsigned h = 0; h < nHeight; ++h, dst_line_start -= dstLineSize) {//<*** flipped
const unsigned index = ch * nHeight + h;
// - read and uncompress line -
const WORD rleLineSize = rleLineSizeList[index];
io->read_proc(rle_line_start, rleLineSize, 1, handle);
for (BYTE* rle_line = rle_line_start, *line = line_start;
rle_line < rle_line_start + rleLineSize, line < line_end;) {
int len = *rle_line++;
// NOTE len is signed byte in PackBits RLE
if ( len < 128 ) { //<- MSB is not set
// uncompressed packet
// (len + 1) bytes of data are copied
++len;
// assert we don't write beyound eol
memcpy(line, rle_line, line + len > line_end ? line_end - line : len);
line += len;
rle_line += len;
}
else if ( len > 128 ) { //< MSB is set
// RLE compressed packet
// One byte of data is repeated (âlen + 1) times
len ^= 0xFF; // same as (-len + 1) & 0xFF
len += 2; //
// assert we don't write beyound eol
memset(line, *rle_line++, line + len > line_end ? line_end - line : len);
line += len;
}
else if ( 128 == len ) {
// Do nothing
}
}//< rle_line
// - write line to destination -
if(ch >= dstChannels) {
// @todo write to extra channels
break;
}
// byte by byte copy a single channel to pixel
for (BYTE *line = line_start, *dst_line = dst_line_start; line < line_start + lineSize;
line += bytes, dst_line += dstBpp) {
#ifdef FREEIMAGE_BIGENDIAN
memcpy(dst_line + channelOffset, line, bytes);
#else
// reverse copy bytes
for (unsigned b = 0; b < bytes; ++b) {
dst_line[channelOffset + b] = line[(bytes-1) - b];
}
#endif // FREEIMAGE_BIGENDIAN
}
}//< h
}//< ch
SAFE_DELETE_ARRAY(line_start);
SAFE_DELETE_ARRAY(rleLineSizeList);
SAFE_DELETE_ARRAY(rle_line_start);
}
break;
case 2: // ZIP without prediction, no specification
break;
case 3: // ZIP with prediction, no specification
break;
default: // Unknown format
break;
}
// --- Further process the bitmap ---
if((mode == PSDP_CMYK || mode == PSDP_MULTICHANNEL)) {
// CMYK values are "inverted", invert them back
if(mode == PSDP_MULTICHANNEL) {
invertColor(bitmap);
} else {
FreeImage_Invert(bitmap);
}
( run in 1.942 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )