Commit a55008dd authored by Halla Rempt's avatar Halla Rempt

Save the various resource blocks to PSD

The duotone specfication block for grayscale images was already loaded
as an annotation; save it as well. Also check whether there are any
PSD image resource block annotations there are and save those.

This should fully roundtrip all image resource blocks.
parent 6b025df8
......@@ -152,6 +152,15 @@ KisImageBuilder_Result PSDLoader::decode(const KUrl& uri)
m_image->addAnnotation(resourceBlock);
}
// Preserve the duotone colormode block for saving back to psd
if (header.colormode == DuoTone) {
KisAnnotationSP annotation = new KisAnnotation("DuotoneColormodeBlock",
i18n("Duotone Colormode Block"),
colorModeBlock.data);
m_image->addAnnotation(annotation);
}
// read the projection into our single layer
if (layerSection.nLayers == 0) {
dbgFile << "Position" << f.pos() << "Going to read the projection into the first layer, which Photoshop calls 'Background'";
......
......@@ -260,17 +260,32 @@ bool PSDResourceBlock::read(QIODevice* io)
bool PSDResourceBlock::write(QIODevice* io)
{
if (!resource->valid()) {
dbgFile << "Writing Resource Block" << PSDResourceSection::idToString((PSDResourceSection::PSDResourceID)identifier) << identifier;
if (resource && !resource->valid()) {
error = QString("Cannot write an invalid Resource Block");
return false;
}
QByteArray ba;
if (!resource->createBlock(ba)) {
// createBlock returns true by default but does not change the data.
if (resource && !resource->createBlock(ba)) {
error = resource->error;
return false;
}
else if (!resource) {
// reconstruct from the data
QBuffer buf(&ba);
buf.open(QBuffer::WriteOnly);
buf.write("8BIM", 4);
psdwrite(&buf, identifier);
psdwrite_pascalstring(&buf, name);
psdwrite(&buf, dataSize);
buf.write(data);
buf.close();
}
if (!io->write(ba.constData(), ba.size()) == ba.size()) {
error = QString("Could not write complete resource");
return false;
......
......@@ -37,6 +37,8 @@
#include <kis_paint_device.h>
#include <kis_transaction.h>
#include <kis_debug.h>
#include <kis_annotation.h>
#include <kis_types.h>
#include "psd.h"
#include "psd_header.h"
......@@ -147,6 +149,12 @@ KisImageBuilder_Result PSDSaver::buildFile(const KUrl& uri)
// COLORMODE BlOCK
PSDColorModeBlock colorModeBlock(header.colormode);
// XXX: check for annotations that contain the duotone spec
KisAnnotationSP annotation = m_image->annotation("DuotoneColormodeBlock");
if (annotation) {
colorModeBlock.duotoneSpecification = annotation->annotation();
}
dbgFile << "colormode block" << f.pos();
if (!colorModeBlock.write(&f)) {
dbgFile << "Failed to write colormode block. Error:" << colorModeBlock.error << f.pos();
......@@ -156,12 +164,36 @@ KisImageBuilder_Result PSDSaver::buildFile(const KUrl& uri)
// IMAGE RESOURCES SECTION
PSDResourceSection resourceSection;
vKisAnnotationSP_it it = m_image->beginAnnotations();
vKisAnnotationSP_it endIt = m_image->endAnnotations();
while (it != endIt) {
KisAnnotationSP annotation = (*it);
if (!annotation || annotation->type().isEmpty()) {
dbgFile << "Warning: empty annotation";
it++;
continue;
}
dbgFile << "Annotation:" << annotation->type() << annotation->description();
if (annotation->type().startsWith(QString("PSD Resource Block:"))) { //
PSDResourceBlock *resourceBlock = dynamic_cast<PSDResourceBlock*>(annotation.data());
if (resourceBlock) {
dbgFile << "Adding PSD Resource Block" << resourceBlock->identifier;
resourceSection.resources[(PSDResourceSection::PSDResourceID)resourceBlock->identifier] = resourceBlock;
}
}
it++;
}
// Add resolution block
{
RESN_INFO_1005 *resInfo = new RESN_INFO_1005;
resInfo->hRes = INCH_TO_POINT(m_image->xRes());
resInfo->vRes = INCH_TO_POINT(m_image->yRes());
PSDResourceBlock *block = new PSDResourceBlock;
block->identifier = PSDResourceSection::RESN_INFO;
block->resource = resInfo;
resourceSection.resources[PSDResourceSection::RESN_INFO] = block;
}
......@@ -171,12 +203,12 @@ KisImageBuilder_Result PSDSaver::buildFile(const KUrl& uri)
ICC_PROFILE_1039 *profileInfo = new ICC_PROFILE_1039;
profileInfo->icc = m_image->profile()->rawData();
PSDResourceBlock *block = new PSDResourceBlock;
block->identifier = PSDResourceSection::ICC_PROFILE;
block->resource = profileInfo;
resourceSection.resources[PSDResourceSection::ICC_PROFILE] = block;
}
// XXX: Add other blocks...
dbgFile << "resource section" << f.pos();
if (!resourceSection.write(&f)) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment