1/*
2 * Copyright 2013, Gerasim Troeglazov, 3dEyes@gmail.com. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "PSDTranslator.h"
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include <Catalog.h>
14
15#include "ConfigView.h"
16#include "PSDLoader.h"
17#include "PSDWriter.h"
18
19#undef B_TRANSLATION_CONTEXT
20#define B_TRANSLATION_CONTEXT "PSDTranslator"
21
22const char *kDocumentCount = "/documentCount";
23const char *kDocumentIndex = "/documentIndex";
24
25#define kPSDMimeType "image/vnd.adobe.photoshop"
26#define kPSDName "Photoshop image"
27
28static const translation_format sInputFormats[] = {
29	{
30		B_TRANSLATOR_BITMAP,
31		B_TRANSLATOR_BITMAP,
32		BITS_IN_QUALITY,
33		BITS_IN_CAPABILITY,
34		"image/x-be-bitmap",
35		"Be Bitmap Format (PSDTranslator)"
36	},
37	{
38		PSD_IMAGE_FORMAT,
39		B_TRANSLATOR_BITMAP,
40		PSD_IN_QUALITY,
41		PSD_IN_CAPABILITY,
42		kPSDMimeType,
43		kPSDName
44	}
45};
46
47static const translation_format sOutputFormats[] = {
48	{
49		B_TRANSLATOR_BITMAP,
50		B_TRANSLATOR_BITMAP,
51		BITS_OUT_QUALITY,
52		BITS_OUT_CAPABILITY,
53		"image/x-be-bitmap",
54		"Be Bitmap Format (PSDTranslator)"
55	},
56	{
57		PSD_IMAGE_FORMAT,
58		B_TRANSLATOR_BITMAP,
59		PSD_OUT_QUALITY,
60		PSD_OUT_CAPABILITY,
61		kPSDMimeType,
62		kPSDName
63	}
64};
65
66
67static const TranSetting sDefaultSettings[] = {
68	{B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false},
69	{B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false},
70	{PSD_SETTING_COMPRESSION, TRAN_SETTING_INT32, PSD_COMPRESSED_RLE},
71	{PSD_SETTING_VERSION, TRAN_SETTING_INT32, PSD_FILE}
72};
73
74const uint32 kNumInputFormats = sizeof(sInputFormats)
75	/ sizeof(translation_format);
76const uint32 kNumOutputFormats = sizeof(sOutputFormats)
77	/ sizeof(translation_format);
78const uint32 kNumDefaultSettings = sizeof(sDefaultSettings)
79	/ sizeof(TranSetting);
80
81
82PSDTranslator::PSDTranslator()
83	: BaseTranslator(B_TRANSLATE(kPSDName),
84		B_TRANSLATE("Photoshop image translator"),
85		PSD_TRANSLATOR_VERSION,
86		sInputFormats, kNumInputFormats,
87		sOutputFormats, kNumOutputFormats,
88		"PSDTranslator",
89		sDefaultSettings, kNumDefaultSettings,
90		B_TRANSLATOR_BITMAP, PSD_IMAGE_FORMAT)
91{
92}
93
94
95PSDTranslator::~PSDTranslator()
96{
97}
98
99
100status_t
101PSDTranslator::DerivedIdentify(BPositionIO *stream,
102	const translation_format *format, BMessage *ioExtension,
103	translator_info *info, uint32 outType)
104{
105	if (!outType)
106		outType = B_TRANSLATOR_BITMAP;
107	if (outType != B_TRANSLATOR_BITMAP && outType != PSD_IMAGE_FORMAT)
108		return B_NO_TRANSLATOR;
109
110	PSDLoader psdFile(stream);
111	if (!psdFile.IsSupported())
112		return B_ILLEGAL_DATA;
113
114	info->type = PSD_IMAGE_FORMAT;
115	info->group = B_TRANSLATOR_BITMAP;
116	info->quality = PSD_IN_QUALITY;
117	info->capability = PSD_IN_CAPABILITY;
118	snprintf(info->name, sizeof(info->name),
119		B_TRANSLATE(kPSDName " (%s)"),
120		psdFile.ColorFormatName().String());
121	strcpy(info->MIME, kPSDMimeType);
122
123	return B_OK;
124}
125
126
127status_t
128PSDTranslator::DerivedTranslate(BPositionIO *source,
129	const translator_info *info, BMessage *ioExtension,
130	uint32 outType, BPositionIO *target, int32 baseType)
131{
132	if (outType != B_TRANSLATOR_BITMAP
133		&& outType != PSD_IMAGE_FORMAT) {
134		return B_NO_TRANSLATOR;
135	}
136
137	switch (baseType) {
138		case 0:
139		{
140			if (outType != B_TRANSLATOR_BITMAP)
141				return B_NO_TRANSLATOR;
142
143			PSDLoader psdFile(source);
144			if (!psdFile.IsLoaded())
145				return B_NO_TRANSLATOR;
146
147			return psdFile.Decode(target);
148		}
149		case 1:
150		{
151			if (outType == PSD_IMAGE_FORMAT) {
152				PSDWriter psdFile(source);
153
154				uint32 compression =
155					fSettings->SetGetInt32(PSD_SETTING_COMPRESSION);
156				uint32 version =
157					fSettings->SetGetInt32(PSD_SETTING_VERSION);
158
159				psdFile.SetCompression(compression);
160				psdFile.SetVersion(version);
161
162				if (psdFile.IsReady())
163					return psdFile.Encode(target);
164			}
165			return B_NO_TRANSLATOR;
166		}
167		default:
168			return B_NO_TRANSLATOR;
169	}
170}
171
172
173status_t
174PSDTranslator::DerivedCanHandleImageSize(float width, float height) const
175{
176	return B_OK;
177}
178
179
180BView *
181PSDTranslator::NewConfigView(TranslatorSettings *settings)
182{
183	return new ConfigView(settings);
184}
185
186
187BTranslator *
188make_nth_translator(int32 n, image_id you, uint32 flags, ...)
189{
190	if (n != 0)
191		return NULL;
192
193	return new PSDTranslator();
194}
195
196