379
//qDebug() << "blending block data length" << blendingDataLength << ", pos" << io->pos();
399
//dbgFile << "blending block data length" << blendingDataLength << ", pos" << io->pos();
381
401
blendingRanges.data = io->read(blendingDataLength);
382
402
if ((quint32)blendingRanges.data.size() != blendingDataLength) {
383
403
error = QString("Got %1 bytes for the blending range block, needed %2").arg(blendingRanges.data.size(), blendingDataLength);
386
// XXX: reading this block correctly failed, I have more channel ranges than I'd expected.
388
if (!psdread(io, &blendingRanges.blackValues[0]) ||
389
!psdread(io, &blendingRanges.blackValues[1]) ||
390
!psdread(io, &blendingRanges.whiteValues[0]) ||
391
!psdread(io, &blendingRanges.whiteValues[1]) ||
392
!psdread(io, &blendingRanges.compositeGrayBlendDestinationRange)) {
394
error = "Could not read blending black/white values";
398
for (int i = 0; i < nChannels; ++i) {
401
if (!psdread(io, &src) || !psdread(io, &dst)) {
402
error = QString("could not read src/dst range for channel %1").arg(i);
406
// XXX: reading this block correctly failed, I have more channel ranges than I'd expected.
408
if (!psdread(io, &blendingRanges.blackValues[0]) ||
409
!psdread(io, &blendingRanges.blackValues[1]) ||
410
!psdread(io, &blendingRanges.whiteValues[0]) ||
411
!psdread(io, &blendingRanges.whiteValues[1]) ||
412
!psdread(io, &blendingRanges.compositeGrayBlendDestinationRange)) {
414
error = "Could not read blending black/white values";
405
dbgFile << "\tread range " << src << "to" << dst << "for channel" << i;
406
blendingRanges.sourceDestinationRanges << QPair<quint32, quint32>(src, dst);
418
for (int i = 0; i < nChannels; ++i) {
421
if (!psdread(io, &src) || !psdread(io, &dst)) {
422
error = QString("could not read src/dst range for channel %1").arg(i);
425
dbgFile << "\tread range " << src << "to" << dst << "for channel" << i;
426
blendingRanges.sourceDestinationRanges << QPair<quint32, quint32>(src, dst);
409
429
dbgFile << "\tGoing to read layer name at" << io->pos();
410
430
quint8 layerNameLength;
411
431
if (!psdread(io, &layerNameLength)) {
480
bool PSDLayerRecord::write(QIODevice* io)
485
error = "Cannot write an invalid Layer Record object";
488
qFatal("TODO: implement writing the layer record");
524
bool PSDLayerRecord::write(QIODevice* io, KisNodeSP node)
526
dbgFile << "writing layer info record" << node->name() << "at" << io->pos();
530
dbgFile << "saving layer record for " << layerName << "at pos" << io->pos();
531
dbgFile << "\ttop" << top << "left" << left << "bottom" << bottom << "right" << right << "number of channels" << nChannels;
532
Q_ASSERT(left <= right);
533
Q_ASSERT(top <= bottom);
534
Q_ASSERT(nChannels > 0);
535
psdwrite(io, (quint32)top);
536
psdwrite(io, (quint32)left);
537
psdwrite(io, (quint32)bottom);
538
psdwrite(io, (quint32)right);
539
psdwrite(io, (quint16)nChannels);
541
foreach(ChannelInfo *channel, channelInfoRecords) {
542
psdwrite(io, (quint16)channel->channelId);
543
channel->channelInfoPosition = io->pos();
544
dbgFile << "ChannelInfo record position:" << channel->channelInfoPosition << "channel id" << channel->channelId;
545
psdwrite(io, (quint32)0); // to be filled in when we know how big each channel block is going to be
549
io->write("8BIM", 4);
550
dbgFile << "blendModeKey" << blendModeKey << "pos" << io->pos();
551
io->write(blendModeKey.toLatin1());
554
psdwrite(io, opacity);
557
psdwrite(io, clipping);
559
// visibility and protection
561
if (transparencyProtected) flags |= 1;
562
if (!visible) flags |= 2;
566
// padding byte to make the length even
567
psdwrite(io, (quint8)0);
569
// position of the extra data size
570
quint64 extraDataPos = io->pos();
571
psdwrite(io, (quint32)0); // length of the extra data fields
573
// layer mask data: not implemented for now, so zero
574
psdwrite(io, quint32(0));
576
// Layer blending ranges: not implemented for now, so zero
577
psdwrite(io, quint32(0));
579
// layer name: Pascal string, padded to a multiple of 4 bytes.
580
psdwrite_pascalstring(io, layerName, 4);
582
// write luni data block
584
quint32 len = qMin(layerName.length(), 255);
585
quint32 xdBlockSize = len;
588
xdBlockSize = len + 1;
590
xdBlockSize = (xdBlockSize * 2) + 4;
592
io->write("8BIMluni", 8);
593
psdwrite(io, xdBlockSize);
596
const ushort *chars = layerName.utf16();
597
for (uint i = 0; i < len; i++) {
598
psdwrite(io, (quint16)chars[i]);
602
psdwrite(io, (quint16)0); // padding
605
// write real length for extra data
607
quint64 eofPos = io->pos();
608
io->seek(extraDataPos);
609
psdwrite(io, (quint32)(eofPos - extraDataPos - sizeof(quint32)));
610
dbgFile << "ExtraData size" << (eofPos - extraDataPos - sizeof(quint32))
611
<< "extra data pos" << extraDataPos
612
<< "eofpos" << eofPos;
614
// retor to eof to continue writing
620
bool PSDLayerRecord::writePixelData(QIODevice *io)
622
dbgFile << "writing pixel data for layer" << layerName << "at" << io->pos();
624
KisPaintDeviceSP dev = m_node->projection();
626
// now write all the channels in display order
627
QRect rc = dev->extent();
629
// yeah... we read the entire layer into a vector of quint8 arrays
630
dbgFile << "layer" << layerName;
631
dbgFile << "\tnode x" << m_node->x() << "paint device x" << dev->x() << "extent x" << rc.x();
632
dbgFile << "\tnode y" << m_node->y() << "paint device x" << dev->y() << "extent y" << rc.y();
633
QVector<quint8* > tmp = dev->readPlanarBytes(rc.x() - m_node->x(), rc.y() -m_node->y(), rc.width(), rc.height());
635
// KisPaintDeviceSP dev2 = new KisPaintDevice(dev->colorSpace());
636
// dev2->writePlanarBytes(tmp, 0, 0, rc.width(), rc.height());
637
// dev2->convertToQImage(0).save(layerName + ".png");
639
// then reorder the planes to fit the psd model -- alpha first, then display order
640
QVector<quint8* > planes;
641
foreach(KoChannelInfo *ch, KoChannelInfo::displayOrderSorted(dev->colorSpace()->channels())) {
642
if (ch->channelType() == KoChannelInfo::ALPHA) {
643
planes.insert(0, tmp[ch->pos()]);
646
planes.append(tmp[ch->pos()]);
651
// here's where we save the total size of the channel data
652
for (int channelInfoIndex = 0; channelInfoIndex < nChannels; ++channelInfoIndex) {
654
dbgFile << "\tWriting channel" << channelInfoIndex << "psd channel id" << channelInfoRecords[channelInfoIndex]->channelId;
656
// if the bitdepth > 8, place the bytes in the right order
657
// if cmyk, invert the pixel value
658
if (m_header.channelDepth == 8) {
659
if (channelInfoRecords[channelInfoIndex]->channelId >= 0 && (m_header.colormode == CMYK || m_header.colormode == CMYK64)) {
660
for (int i = 0; i < rc.width() * rc.height(); ++i) {
661
planes[channelInfoIndex][i] = 255 - planes[channelInfoIndex][i];
665
else if (m_header.channelDepth == 16) {
667
for (int i = 0; i < rc.width() * rc.height(); ++i) {
668
val = reinterpret_cast<quint16*>(planes[channelInfoIndex])[i];
670
if (channelInfoRecords[channelInfoIndex]->channelId >= 0 && (m_header.colormode == CMYK || m_header.colormode == CMYK64)) {
671
val = quint16_MAX - val;
673
reinterpret_cast<quint16*>(planes[channelInfoIndex])[i] = val;
680
// where this block starts, for the total size calculation
681
quint64 startChannelBlockPos = io->pos();
683
// XXX: make the compression settting configurable. For now, always use RLE.
684
psdwrite(io, (quint16)Compression::RLE);
685
len += sizeof(quint16);
687
// where this block starts, for the total size calculation
688
quint64 channelRLESizePos = io->pos();
690
// write zero's for the channel lengths section
691
for(int i = 0; i < rc.height(); ++i) {
692
psdwrite(io, (quint16)0);
694
len += rc.height() * sizeof(quint16);
696
// here the actual channel data starts; that's where we return after writing
697
// the size of the current row
698
quint64 channelStartPos = io->pos();
700
quint8 *plane = planes[channelInfoIndex];
701
quint32 stride = (m_header.channelDepth / 8) * rc.width();
702
for (qint32 row = 0; row < rc.height(); ++row) {
704
QByteArray uncompressed = QByteArray::fromRawData((const char*)plane + row * stride, stride);
705
QByteArray compressed = Compression::compress(uncompressed, Compression::RLE);
706
quint16 size = compressed.size();
708
io->seek(channelRLESizePos);
710
channelRLESizePos +=2;
711
io->seek(channelStartPos);
713
if (!io->write(compressed) == size) {
714
error = "Could not write image data";
719
// dbgFile << "\t\tUncompressed:" << uncompressed.size() << "compressed" << compressed.size();
720
// QByteArray control = Compression::uncompress(rc.width(), compressed, Compression::RLE);
721
// Q_ASSERT(qstrcmp(control, uncompressed) == 0);
724
// If the layer's size, and therefore the data, is odd, a pad byte will be inserted
725
// at the end of the row. (weirdly enough, that's not true for the image data)
726
// if ((size & 0x01) != 0) {
727
// psdwrite(io, (quint8)0);
731
channelStartPos += size;
733
// write the size of the channel image data block in the channel info block
734
quint64 currentPos = io->pos();
735
io->seek(channelInfoRecords[channelInfoIndex]->channelInfoPosition);
736
Q_ASSERT(len == currentPos - startChannelBlockPos);
737
dbgFile << "\t\ttotal length" << len << "calculated length" << currentPos - startChannelBlockPos << "writing at" << channelInfoRecords[channelInfoIndex]->channelInfoPosition;
738
psdwrite(io, (quint32)(currentPos - startChannelBlockPos));
739
io->seek(currentPos);
492
747
bool PSDLayerRecord::valid()
752
1020
{ quint64 oldPosition = io->pos();
754
1022
quint64 width = right - left;
755
int channelSize = m_header.channelDepth / 8;
756
int uncompressedLength = width * channelSize;
758
if (channelInfoRecords.first()->compressionType == Compression::ZIP
759
|| channelInfoRecords.first()->compressionType == Compression::ZIPWithPrediction) {
761
// Zip needs to be implemented here.
765
KisHLineIteratorSP it = dev->createHLineIteratorNG(left, top, width);
766
for (int row = top ; row < bottom; row++)
769
QMap<quint16, QByteArray> channelBytes;
771
foreach(ChannelInfo *channelInfo, channelInfoRecords) {
773
io->seek(channelInfo->channelDataStart + channelInfo->channelOffset);
775
if (channelInfo->compressionType == Compression::Uncompressed) {
776
channelBytes[channelInfo->channelId] = io->read(uncompressedLength);
777
channelInfo->channelOffset += uncompressedLength;
779
else if (channelInfo->compressionType == Compression::RLE) {
780
int rleLength = channelInfo->rleRowLengths[row - top];
781
QByteArray compressedBytes = io->read(rleLength);
782
QByteArray uncompressedBytes = Compression::uncompress(uncompressedLength, compressedBytes, channelInfo->compressionType);
783
channelBytes.insert(channelInfo->channelId, uncompressedBytes);
784
channelInfo->channelOffset += rleLength;
789
for (quint64 col = 0; col < width; col++){
791
if (channelSize == 1) {
792
quint8 opacity = OPACITY_OPAQUE_U8;
793
if (channelBytes.contains(-1)) {
794
opacity = channelBytes[-1].constData()[col];
796
KoLabTraits<quint8>::setOpacity(it->rawData(), opacity, 1);
798
quint8 L = ntohs(reinterpret_cast<const quint8 *>(channelBytes[0].constData())[col]);
799
KoLabTraits<quint8>::setL(it->rawData(),L);
801
quint8 A = ntohs(reinterpret_cast<const quint8 *>(channelBytes[1].constData())[col]);
802
KoLabTraits<quint8>::setA(it->rawData(),A);
804
quint8 B = ntohs(reinterpret_cast<const quint8 *>(channelBytes[2].constData())[col]);
805
KoLabTraits<quint8>::setB(it->rawData(),B);
810
else if (channelSize == 2) {
812
quint16 opacity = quint16_MAX;
813
if (channelBytes.contains(-1)) {
814
opacity = channelBytes[-1].constData()[col];
816
// We don't have a convenient setOpacity function :-(
817
memcpy(it->rawData() + KoLabU16Traits::alpha_pos, &opacity, sizeof(quint16));
818
// KoLabTraits<quint16>::setOpacity(it->rawData(), opacity, 1);
820
quint16 L = ntohs(reinterpret_cast<const quint16 *>(channelBytes[0].constData())[col]);
821
KoLabTraits<quint16>::setL(it->rawData(),L);
823
quint16 A = ntohs(reinterpret_cast<const quint16 *>(channelBytes[1].constData())[col]);
824
KoLabTraits<quint16>::setA(it->rawData(),A);
826
quint16 B = ntohs(reinterpret_cast<const quint16 *>(channelBytes[2].constData())[col]);
827
KoLabTraits<quint16>::setB(it->rawData(),B);
830
// Unsupported channel sizes for now
838
// go back to the old position, because we've been seeking all over the place
839
io->seek(oldPosition);
1023
int channelSize = m_header.channelDepth / 8;
1024
int uncompressedLength = width * channelSize;
1026
if (channelInfoRecords.first()->compressionType == Compression::ZIP
1027
|| channelInfoRecords.first()->compressionType == Compression::ZIPWithPrediction) {
1029
// Zip needs to be implemented here.
1033
KisHLineIteratorSP it = dev->createHLineIteratorNG(left, top, width);
1034
for (int row = top ; row < bottom; row++)
1037
QMap<quint16, QByteArray> channelBytes;
1039
foreach(ChannelInfo *channelInfo, channelInfoRecords) {
1041
io->seek(channelInfo->channelDataStart + channelInfo->channelOffset);
1043
if (channelInfo->compressionType == Compression::Uncompressed) {
1044
channelBytes[channelInfo->channelId] = io->read(uncompressedLength);
1045
channelInfo->channelOffset += uncompressedLength;
1047
else if (channelInfo->compressionType == Compression::RLE) {
1048
int rleLength = channelInfo->rleRowLengths[row - top];
1049
QByteArray compressedBytes = io->read(rleLength);
1050
QByteArray uncompressedBytes = Compression::uncompress(uncompressedLength, compressedBytes, channelInfo->compressionType);
1051
channelBytes.insert(channelInfo->channelId, uncompressedBytes);
1052
channelInfo->channelOffset += rleLength;
1057
for (quint64 col = 0; col < width; col++){
1059
if (channelSize == 1) {
1060
quint8 opacity = OPACITY_OPAQUE_U8;
1061
if (channelBytes.contains(-1)) {
1062
opacity = channelBytes[-1].constData()[col];
1064
KoLabTraits<quint8>::setOpacity(it->rawData(), opacity, 1);
1066
quint8 L = ntohs(reinterpret_cast<const quint8 *>(channelBytes[0].constData())[col]);
1067
KoLabTraits<quint8>::setL(it->rawData(),L);
1069
quint8 A = ntohs(reinterpret_cast<const quint8 *>(channelBytes[1].constData())[col]);
1070
KoLabTraits<quint8>::setA(it->rawData(),A);
1072
quint8 B = ntohs(reinterpret_cast<const quint8 *>(channelBytes[2].constData())[col]);
1073
KoLabTraits<quint8>::setB(it->rawData(),B);
1078
else if (channelSize == 2) {
1080
quint16 opacity = quint16_MAX;
1081
if (channelBytes.contains(-1)) {
1082
opacity = channelBytes[-1].constData()[col];
1084
// We don't have a convenient setOpacity function :-(
1085
memcpy(it->rawData() + KoLabU16Traits::alpha_pos, &opacity, sizeof(quint16));
1086
// KoLabTraits<quint16>::setOpacity(it->rawData(), opacity, 1);
1088
quint16 L = ntohs(reinterpret_cast<const quint16 *>(channelBytes[0].constData())[col]);
1089
KoLabTraits<quint16>::setL(it->rawData(),L);
1091
quint16 A = ntohs(reinterpret_cast<const quint16 *>(channelBytes[1].constData())[col]);
1092
KoLabTraits<quint16>::setA(it->rawData(),A);
1094
quint16 B = ntohs(reinterpret_cast<const quint16 *>(channelBytes[2].constData())[col]);
1095
KoLabTraits<quint16>::setB(it->rawData(),B);
1098
// Unsupported channel sizes for now
1106
// go back to the old position, because we've been seeking all over the place
1107
io->seek(oldPosition);