PSDTranslator: Add export to psd support (uncompressed only)
This commit is contained in:
@@ -13,6 +13,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
PSDTranslatorApp.cpp
|
PSDTranslatorApp.cpp
|
||||||
PSDTranslator.cpp
|
PSDTranslator.cpp
|
||||||
PSDLoader.cpp
|
PSDLoader.cpp
|
||||||
|
PSDWriter.cpp
|
||||||
ConfigView.cpp
|
ConfigView.cpp
|
||||||
: be translation
|
: be translation
|
||||||
[ MultiArchDefaultGristFiles libtranslatorsutils.a ]
|
[ MultiArchDefaultGristFiles libtranslatorsutils.a ]
|
||||||
@@ -28,5 +29,6 @@ DoCatalogs PSDTranslator :
|
|||||||
PSDTranslatorApp.cpp
|
PSDTranslatorApp.cpp
|
||||||
PSDTranslator.cpp
|
PSDTranslator.cpp
|
||||||
PSDLoader.cpp
|
PSDLoader.cpp
|
||||||
|
PSDWriter.cpp
|
||||||
ConfigView.cpp
|
ConfigView.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "ConfigView.h"
|
#include "ConfigView.h"
|
||||||
#include "PSDTranslator.h"
|
#include "PSDTranslator.h"
|
||||||
#include "PSDLoader.h"
|
#include "PSDLoader.h"
|
||||||
|
#include "PSDWriter.h"
|
||||||
|
|
||||||
const char *kDocumentCount = "/documentCount";
|
const char *kDocumentCount = "/documentCount";
|
||||||
const char *kDocumentIndex = "/documentIndex";
|
const char *kDocumentIndex = "/documentIndex";
|
||||||
@@ -20,13 +21,21 @@ const char *kDocumentIndex = "/documentIndex";
|
|||||||
|
|
||||||
static const translation_format sInputFormats[] = {
|
static const translation_format sInputFormats[] = {
|
||||||
{
|
{
|
||||||
|
B_TRANSLATOR_BITMAP,
|
||||||
|
B_TRANSLATOR_BITMAP,
|
||||||
|
BITS_IN_QUALITY,
|
||||||
|
BITS_IN_CAPABILITY,
|
||||||
|
"image/x-be-bitmap",
|
||||||
|
"Be Bitmap Format (PSDTranslator)"
|
||||||
|
},
|
||||||
|
{
|
||||||
PSD_IMAGE_FORMAT,
|
PSD_IMAGE_FORMAT,
|
||||||
B_TRANSLATOR_BITMAP,
|
B_TRANSLATOR_BITMAP,
|
||||||
PSD_IN_QUALITY,
|
PSD_IN_QUALITY,
|
||||||
PSD_IN_CAPABILITY,
|
PSD_IN_CAPABILITY,
|
||||||
kPSDMimeType,
|
kPSDMimeType,
|
||||||
kPSDName
|
kPSDName
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const translation_format sOutputFormats[] = {
|
static const translation_format sOutputFormats[] = {
|
||||||
@@ -38,6 +47,14 @@ static const translation_format sOutputFormats[] = {
|
|||||||
"image/x-be-bitmap",
|
"image/x-be-bitmap",
|
||||||
"Be Bitmap Format (PSDTranslator)"
|
"Be Bitmap Format (PSDTranslator)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
PSD_IMAGE_FORMAT,
|
||||||
|
B_TRANSLATOR_BITMAP,
|
||||||
|
PSD_OUT_QUALITY,
|
||||||
|
PSD_OUT_CAPABILITY,
|
||||||
|
kPSDMimeType,
|
||||||
|
kPSDName
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -46,8 +63,10 @@ static const TranSetting sDefaultSettings[] = {
|
|||||||
{B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false}
|
{B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false}
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint32 kNumInputFormats = 1;
|
const uint32 kNumInputFormats = sizeof(sInputFormats)
|
||||||
const uint32 kNumOutputFormats = 1;
|
/ sizeof(translation_format);
|
||||||
|
const uint32 kNumOutputFormats = sizeof(sOutputFormats)
|
||||||
|
/ sizeof(translation_format);
|
||||||
const uint32 kNumDefaultSettings = sizeof(sDefaultSettings)
|
const uint32 kNumDefaultSettings = sizeof(sDefaultSettings)
|
||||||
/ sizeof(TranSetting);
|
/ sizeof(TranSetting);
|
||||||
|
|
||||||
@@ -102,7 +121,8 @@ PSDTranslator::DerivedTranslate(BPositionIO *source,
|
|||||||
const translator_info *info, BMessage *ioExtension,
|
const translator_info *info, BMessage *ioExtension,
|
||||||
uint32 outType, BPositionIO *target, int32 baseType)
|
uint32 outType, BPositionIO *target, int32 baseType)
|
||||||
{
|
{
|
||||||
if (outType != B_TRANSLATOR_BITMAP)
|
if (outType != B_TRANSLATOR_BITMAP
|
||||||
|
&& outType != PSD_IMAGE_FORMAT)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
switch (baseType) {
|
switch (baseType) {
|
||||||
@@ -117,13 +137,62 @@ PSDTranslator::DerivedTranslate(BPositionIO *source,
|
|||||||
|
|
||||||
return psdFile.Decode(target);
|
return psdFile.Decode(target);
|
||||||
}
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if (outType == PSD_IMAGE_FORMAT)
|
||||||
|
return _TranslateFromBits(source, ioExtension, outType, target);
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PSDTranslator::_TranslateFromBits(BPositionIO* stream,
|
||||||
|
BMessage* ioExtension, uint32 outType,
|
||||||
|
BPositionIO* target)
|
||||||
|
{
|
||||||
|
TranslatorBitmap bitsHeader;
|
||||||
|
status_t result;
|
||||||
|
result = identify_bits_header(stream, NULL, &bitsHeader);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (bitsHeader.colors != B_RGB32
|
||||||
|
&& bitsHeader.colors != B_RGBA32)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
|
uint32 width = bitsHeader.bounds.IntegerWidth() + 1;
|
||||||
|
uint32 height = bitsHeader.bounds.IntegerHeight() + 1;
|
||||||
|
|
||||||
|
int32 layerSize = height * width;
|
||||||
|
int32 layersCount = bitsHeader.colors == B_RGB32 ? 3 : 4;
|
||||||
|
|
||||||
|
uint8 *buff = new uint8[layerSize * layersCount];
|
||||||
|
|
||||||
|
uint8 *ptr = buff;
|
||||||
|
for(int i = 0; i < layerSize; i++) {
|
||||||
|
uint8 rgba[4];
|
||||||
|
stream->Read(rgba, sizeof(uint32));
|
||||||
|
ptr[i] = rgba[2];
|
||||||
|
ptr[i+layerSize] = rgba[1];
|
||||||
|
ptr[i+layerSize+layerSize] = rgba[0];
|
||||||
|
if (layersCount == 4)
|
||||||
|
ptr[i+layerSize+layerSize+layerSize] = rgba[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
PSDWriter psdFile(stream);
|
||||||
|
psdFile.EncodeFromRGBA(target, buff, layersCount, width, height);
|
||||||
|
|
||||||
|
delete buff;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PSDTranslator::DerivedCanHandleImageSize(float width, float height) const
|
PSDTranslator::DerivedCanHandleImageSize(float width, float height) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,13 +21,18 @@
|
|||||||
#define DOCUMENT_COUNT "/documentCount"
|
#define DOCUMENT_COUNT "/documentCount"
|
||||||
#define DOCUMENT_INDEX "/documentIndex"
|
#define DOCUMENT_INDEX "/documentIndex"
|
||||||
|
|
||||||
#define PSD_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1, 1, 3)
|
#define PSD_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1, 2, 0)
|
||||||
#define PSD_IMAGE_FORMAT 'PSD '
|
#define PSD_IMAGE_FORMAT 'PSD '
|
||||||
|
|
||||||
#define PSD_IN_QUALITY 0.5
|
#define PSD_IN_QUALITY 0.7
|
||||||
#define PSD_IN_CAPABILITY 0.5
|
#define PSD_IN_CAPABILITY 0.6
|
||||||
#define BITS_OUT_QUALITY 1
|
#define PSD_OUT_QUALITY 0.5
|
||||||
#define BITS_OUT_CAPABILITY 0.9
|
#define PSD_OUT_CAPABILITY 0.6
|
||||||
|
|
||||||
|
#define BITS_IN_QUALITY 0.7
|
||||||
|
#define BITS_IN_CAPABILITY 0.6
|
||||||
|
#define BITS_OUT_QUALITY 0.7
|
||||||
|
#define BITS_OUT_CAPABILITY 0.6
|
||||||
|
|
||||||
class PSDTranslator : public BaseTranslator {
|
class PSDTranslator : public BaseTranslator {
|
||||||
public:
|
public:
|
||||||
@@ -48,6 +53,9 @@ class PSDTranslator : public BaseTranslator {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~PSDTranslator();
|
virtual ~PSDTranslator();
|
||||||
|
private:
|
||||||
|
status_t _TranslateFromBits(BPositionIO* stream,
|
||||||
|
BMessage* settings, uint32 outType, BPositionIO* target);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *kDocumentCount;
|
extern const char *kDocumentCount;
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Gerasim Troeglazov, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
|
|
||||||
|
#include "BaseTranslator.h"
|
||||||
|
#include "PSDWriter.h"
|
||||||
|
|
||||||
|
|
||||||
|
PSDWriter::PSDWriter(BPositionIO *stream)
|
||||||
|
{
|
||||||
|
fStream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PSDWriter::~PSDWriter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PSDWriter::EncodeFromRGBA(BPositionIO *target, uint8 *buff,
|
||||||
|
int32 layers, int32 width, int32 height)
|
||||||
|
{
|
||||||
|
int32 channelSize = width * height;
|
||||||
|
|
||||||
|
_WriteUInt32ToStream(target, 0x38425053); // 8BPS
|
||||||
|
_WriteUInt16ToStream(target, 1); // Version = 1
|
||||||
|
_WriteFillBlockToStream(target, 0, 6); // reserved
|
||||||
|
_WriteInt16ToStream(target, layers); // Channels = 4
|
||||||
|
_WriteInt32ToStream(target, height); // Height
|
||||||
|
_WriteInt32ToStream(target, width); // Width
|
||||||
|
_WriteInt16ToStream(target, 8); // Depth = 8
|
||||||
|
_WriteInt16ToStream(target, PSD_COLOR_MODE_RGB); // ColorMode
|
||||||
|
_WriteUInt32ToStream(target, 0); // ColorModeBlockSize = 0
|
||||||
|
|
||||||
|
size_t sizePos = target->Position();
|
||||||
|
_WriteUInt32ToStream(target, 0); // ImageResourceBlockSize = 0 for now
|
||||||
|
_WriteUInt32ToStream(target, 0x3842494D); // 8BIM
|
||||||
|
_WriteUInt16ToStream(target, 1005);
|
||||||
|
_WriteUInt16ToStream(target, 0);
|
||||||
|
_WriteUInt32ToStream(target, 16);
|
||||||
|
uint8 resBlock[16] = {0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
|
||||||
|
0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01};
|
||||||
|
_WriteBlockToStream(target, resBlock, 16);
|
||||||
|
|
||||||
|
// current layer info
|
||||||
|
_WriteUInt32ToStream(target, 0x3842494D); // 8BIM
|
||||||
|
_WriteUInt16ToStream(target, 1024);
|
||||||
|
_WriteUInt16ToStream(target, 0);
|
||||||
|
_WriteUInt32ToStream(target, 2);
|
||||||
|
_WriteUInt16ToStream(target, 0); // Set current layer to 0
|
||||||
|
|
||||||
|
int32 resBlockSize = target->Position() - sizePos;
|
||||||
|
size_t lastPos = target->Position();
|
||||||
|
target->Seek(sizePos, SEEK_SET);
|
||||||
|
_WriteUInt32ToStream(target, resBlockSize - sizeof(uint32));
|
||||||
|
target->Seek(lastPos, SEEK_SET);
|
||||||
|
|
||||||
|
sizePos = target->Position();
|
||||||
|
_WriteUInt32ToStream(target, 0); // Layer & mask block size = 0
|
||||||
|
_WriteUInt32ToStream(target, 0); // Layer info block size = 0
|
||||||
|
|
||||||
|
_WriteUInt16ToStream(target, 1); // Layers count
|
||||||
|
|
||||||
|
_WriteUInt32ToStream(target, 0); // Layer rect
|
||||||
|
_WriteUInt32ToStream(target, 0);
|
||||||
|
_WriteUInt32ToStream(target, height);
|
||||||
|
_WriteUInt32ToStream(target, width);
|
||||||
|
|
||||||
|
_WriteInt16ToStream(target, layers); // Layer Channels
|
||||||
|
|
||||||
|
for (int channels = 0; channels < 3; channels++) {
|
||||||
|
_WriteInt16ToStream(target, channels); // Channel num
|
||||||
|
_WriteUInt32ToStream(target, channelSize + 2); // Layer data size
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layers == 4) {
|
||||||
|
uint8 resBlock2[2] = {0xFF, 0xFF};
|
||||||
|
_WriteBlockToStream(target, resBlock2, 2);
|
||||||
|
_WriteUInt32ToStream(target, channelSize + 2); // Alpha layer data size
|
||||||
|
}
|
||||||
|
|
||||||
|
_WriteUInt32ToStream(target, 0x3842494D); // 8BIM
|
||||||
|
|
||||||
|
uint8 blendModeKey[4] = {'n','o','r','m'};
|
||||||
|
_WriteBlockToStream(target, blendModeKey, 4); // Blend mode norm
|
||||||
|
|
||||||
|
_WriteUInt8ToStream(target, 255); // Alpha
|
||||||
|
|
||||||
|
_WriteUInt8ToStream(target, 0); // Clipping
|
||||||
|
_WriteUInt8ToStream(target, 1); // Flags
|
||||||
|
_WriteUInt8ToStream(target, 0); // Flags
|
||||||
|
|
||||||
|
_WriteUInt32ToStream(target, 4 + 4 + 16); // Extra data length
|
||||||
|
_WriteUInt32ToStream(target, 0); // Mask info
|
||||||
|
_WriteUInt32ToStream(target, 0);
|
||||||
|
|
||||||
|
_WriteUInt8ToStream(target, 15); // Layer name length
|
||||||
|
uint8 layerName[16] = {"Layer #1 "};
|
||||||
|
_WriteBlockToStream(target, layerName, 15); // Layer name
|
||||||
|
|
||||||
|
for (int dataChannel = 0; dataChannel < layers; dataChannel++) {
|
||||||
|
_WriteInt16ToStream(target, PSD_COMPRESSED_RAW); // Compression mode
|
||||||
|
_WriteBlockToStream(target, buff + dataChannel * channelSize,
|
||||||
|
channelSize); // Layer image data
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 layerBlockSize = target->Position() - sizePos;
|
||||||
|
|
||||||
|
/* if (layerBlockSize % 2 != 0) {
|
||||||
|
_WriteUInt8ToStream(target, 0);
|
||||||
|
layerBlockSize++;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
lastPos = target->Position();
|
||||||
|
target->Seek(sizePos, SEEK_SET);
|
||||||
|
_WriteUInt32ToStream(target, layerBlockSize - 4);
|
||||||
|
_WriteUInt32ToStream(target, layerBlockSize - 8);
|
||||||
|
target->Seek(lastPos, SEEK_SET);
|
||||||
|
|
||||||
|
_WriteUInt16ToStream(target, PSD_COMPRESSED_RAW); // Compression mode
|
||||||
|
_WriteBlockToStream(target, buff, channelSize * layers);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteInt32ToStream(BPositionIO *stream, int32 val)
|
||||||
|
{
|
||||||
|
val = B_HOST_TO_BENDIAN_INT32(val);
|
||||||
|
stream->Write(&val, sizeof(int32));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteUInt32ToStream(BPositionIO *stream, uint32 val)
|
||||||
|
{
|
||||||
|
val = B_HOST_TO_BENDIAN_INT32(val);
|
||||||
|
stream->Write(&val, sizeof(uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteInt16ToStream(BPositionIO *stream, int16 val)
|
||||||
|
{
|
||||||
|
val = B_HOST_TO_BENDIAN_INT16(val);
|
||||||
|
stream->Write(&val, sizeof(int16));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteUInt16ToStream(BPositionIO *stream, uint16 val)
|
||||||
|
{
|
||||||
|
val = B_HOST_TO_BENDIAN_INT16(val);
|
||||||
|
stream->Write(&val, sizeof(int16));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteInt8ToStream(BPositionIO *stream, int8 val)
|
||||||
|
{
|
||||||
|
stream->Write(&val, sizeof(int8));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteUInt8ToStream(BPositionIO *stream, uint8 val)
|
||||||
|
{
|
||||||
|
stream->Write(&val, sizeof(uint8));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteFillBlockToStream(BPositionIO *stream,
|
||||||
|
uint8 val, size_t count)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < count; i++)
|
||||||
|
stream->Write(&val, sizeof(uint8));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PSDWriter::_WriteBlockToStream(BPositionIO *stream,
|
||||||
|
uint8 *val, size_t count)
|
||||||
|
{
|
||||||
|
stream->Write(val, count);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Gerasim Troeglazov, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PSD_WRITER_H
|
||||||
|
#define PSD_WRITER_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Translator.h>
|
||||||
|
#include <TranslatorFormats.h>
|
||||||
|
#include <TranslationDefs.h>
|
||||||
|
#include <GraphicsDefs.h>
|
||||||
|
#include <InterfaceDefs.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <DataIO.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
#include "PSDLoader.h"
|
||||||
|
|
||||||
|
class PSDWriter {
|
||||||
|
public:
|
||||||
|
PSDWriter(BPositionIO *stream);
|
||||||
|
~PSDWriter();
|
||||||
|
|
||||||
|
status_t EncodeFromRGBA(BPositionIO *target, uint8 *buff,
|
||||||
|
int32 layers, int32 width, int32 height);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _WriteInt32ToStream(BPositionIO *stream, int32);
|
||||||
|
void _WriteUInt32ToStream(BPositionIO *stream, uint32);
|
||||||
|
void _WriteInt16ToStream(BPositionIO *stream, int16);
|
||||||
|
void _WriteUInt16ToStream(BPositionIO *stream, uint16);
|
||||||
|
void _WriteInt8ToStream(BPositionIO *stream, int8);
|
||||||
|
void _WriteUInt8ToStream(BPositionIO *stream, uint8);
|
||||||
|
void _WriteFillBlockToStream(BPositionIO *stream,
|
||||||
|
uint8 val, size_t count);
|
||||||
|
void _WriteBlockToStream(BPositionIO *stream,
|
||||||
|
uint8 *block, size_t count);
|
||||||
|
|
||||||
|
BPositionIO *fStream;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PSD_WRITER_H */
|
||||||
Reference in New Issue
Block a user