1 /*
2 * Copyright 2006-2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 */
8
9 #include "WonderBrushTranslator.h"
10
11 #include <new>
12 #include <stdio.h>
13 #include <string.h>
14
15 #include <Bitmap.h>
16 #include <Catalog.h>
17 #include <OS.h>
18
19 #include "blending.h"
20
21 #include "WonderBrushImage.h"
22 #include "WonderBrushView.h"
23
24
25 #undef B_TRANSLATION_CONTEXT
26 #define B_TRANSLATION_CONTEXT "WonderBrushTranslator"
27
28
29 using std::nothrow;
30
31 // The input formats that this translator supports.
32 static const translation_format sInputFormats[] = {
33 /*{
34 B_TRANSLATOR_BITMAP,
35 B_TRANSLATOR_BITMAP,
36 BBT_IN_QUALITY,
37 BBT_IN_CAPABILITY,
38 "image/x-be-bitmap",
39 "Be Bitmap Format (WonderBrushTranslator)"
40 },*/
41 {
42 WBI_FORMAT,
43 B_TRANSLATOR_BITMAP,
44 WBI_IN_QUALITY,
45 WBI_IN_CAPABILITY,
46 "image/x-wonderbrush",
47 "WonderBrush image"
48 }
49 };
50
51 // The output formats that this translator supports.
52 static const translation_format sOutputFormats[] = {
53 {
54 B_TRANSLATOR_BITMAP,
55 B_TRANSLATOR_BITMAP,
56 BBT_OUT_QUALITY,
57 BBT_OUT_CAPABILITY,
58 "image/x-be-bitmap",
59 "Be Bitmap Format (WonderBrushTranslator)"
60 }/*,
61 {
62 WBI_FORMAT,
63 B_TRANSLATOR_BITMAP,
64 WBI_OUT_QUALITY,
65 WBI_OUT_CAPABILITY,
66 "image/x-wonderbrush",
67 "WonderBrush image"
68 }*/
69 };
70
71
72 // Default settings for the Translator
73 static const TranSetting sDefaultSettings[] = {
74 { B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false },
75 { B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false }
76 };
77
78 const uint32 kNumInputFormats = sizeof(sInputFormats) /
79 sizeof(translation_format);
80 const uint32 kNumOutputFormats = sizeof(sOutputFormats) /
81 sizeof(translation_format);
82 const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) /
83 sizeof(TranSetting);
84
85
86 BTranslator*
make_nth_translator(int32 n,image_id you,uint32 flags,...)87 make_nth_translator(int32 n, image_id you, uint32 flags, ...)
88 {
89 if (!n)
90 return new WonderBrushTranslator();
91 else
92 return NULL;
93 }
94
95
WonderBrushTranslator()96 WonderBrushTranslator::WonderBrushTranslator()
97 : BaseTranslator(B_TRANSLATE("WonderBrush images"),
98 B_TRANSLATE("WonderBrush image translator"),
99 WBI_TRANSLATOR_VERSION,
100 sInputFormats, kNumInputFormats,
101 sOutputFormats, kNumOutputFormats,
102 "WBITranslator_Settings",
103 sDefaultSettings, kNumDefaultSettings,
104 B_TRANSLATOR_BITMAP, WBI_FORMAT)
105 {
106 #if GAMMA_BLEND
107 init_gamma_blending();
108 #endif
109 }
110
111
~WonderBrushTranslator()112 WonderBrushTranslator::~WonderBrushTranslator()
113 {
114 #if GAMMA_BLEND
115 uninit_gamma_blending();
116 #endif
117 }
118
119
120 status_t
identify_wbi_header(BPositionIO * inSource,translator_info * outInfo,uint32 outType,WonderBrushImage ** _wbImage=NULL)121 identify_wbi_header(BPositionIO* inSource, translator_info* outInfo,
122 uint32 outType, WonderBrushImage** _wbImage = NULL)
123 {
124 status_t status = B_NO_MEMORY;
125 // construct new WonderBrushImage object and set it to the provided BPositionIO
126 WonderBrushImage* wbImage = new(nothrow) WonderBrushImage();
127 if (wbImage)
128 status = wbImage->SetTo(inSource);
129
130 if (status >= B_OK) {
131 if (outInfo) {
132 outInfo->type = WBI_FORMAT;
133 outInfo->group = B_TRANSLATOR_BITMAP;
134 outInfo->quality = WBI_IN_QUALITY;
135 outInfo->capability = WBI_IN_CAPABILITY;
136 strcpy(outInfo->MIME, "image/x-wonderbrush");
137 strlcpy(outInfo->name, B_TRANSLATE("WonderBrush image"),
138 sizeof(outInfo->name));
139 }
140 } else {
141 delete wbImage;
142 wbImage = NULL;
143 }
144 if (!_wbImage) {
145 // close WonderBrushImage if caller is not interested in handle
146 delete wbImage;
147 } else {
148 // leave WonderBrushImage open (if it is) and return handle if
149 // caller needs it
150 *_wbImage = wbImage;
151 }
152
153 return status;
154 }
155
156
157 status_t
DerivedIdentify(BPositionIO * inSource,const translation_format * inFormat,BMessage * ioExtension,translator_info * outInfo,uint32 outType)158 WonderBrushTranslator::DerivedIdentify(BPositionIO* inSource,
159 const translation_format* inFormat, BMessage* ioExtension,
160 translator_info* outInfo, uint32 outType)
161 {
162 return identify_wbi_header(inSource, outInfo, outType);
163 }
164
165
166 status_t
DerivedTranslate(BPositionIO * inSource,const translator_info * inInfo,BMessage * ioExtension,uint32 outType,BPositionIO * outDestination,int32 baseType)167 WonderBrushTranslator::DerivedTranslate(BPositionIO* inSource,
168 const translator_info* inInfo, BMessage* ioExtension,
169 uint32 outType, BPositionIO* outDestination, int32 baseType)
170 {
171 if (baseType == 0)
172 // if inSource is NOT in bits format
173 return _TranslateFromWBI(inSource, outType, outDestination);
174 else
175 // if BaseTranslator did not properly identify the data as
176 // bits or not bits
177 return B_NO_TRANSLATOR;
178 }
179
180
181 BView*
NewConfigView(TranslatorSettings * settings)182 WonderBrushTranslator::NewConfigView(TranslatorSettings* settings)
183 {
184 return new WonderBrushView(BRect(0, 0, 225, 175),
185 B_TRANSLATE("WBI Settings"), B_FOLLOW_ALL, B_WILL_DRAW, settings);
186 }
187
188
189 // #pragma mark -
190
191
192 status_t
_TranslateFromWBI(BPositionIO * inSource,uint32 outType,BPositionIO * outDestination)193 WonderBrushTranslator::_TranslateFromWBI(BPositionIO* inSource, uint32 outType,
194 BPositionIO* outDestination)
195 {
196 // if copying WBI_FORMAT to WBI_FORMAT
197 if (outType == WBI_FORMAT) {
198 translate_direct_copy(inSource, outDestination);
199 return B_OK;
200 }
201
202 WonderBrushImage* wbImage = NULL;
203 ssize_t ret = identify_wbi_header(inSource, NULL, outType, &wbImage);
204 if (ret < B_OK)
205 return ret;
206
207 bool headerOnly = false;
208 bool dataOnly = false;
209
210 BBitmap* bitmap = wbImage->Bitmap();
211 if (!bitmap)
212 return B_ERROR;
213
214 uint32 width = bitmap->Bounds().IntegerWidth() + 1;
215 uint32 height = bitmap->Bounds().IntegerHeight() + 1;
216 color_space format = bitmap->ColorSpace();
217 uint32 bytesPerRow = bitmap->BytesPerRow();
218
219 if (!dataOnly) {
220 // Construct and write Be bitmap header
221 TranslatorBitmap bitsHeader;
222 bitsHeader.magic = B_TRANSLATOR_BITMAP;
223 bitsHeader.bounds.left = 0;
224 bitsHeader.bounds.top = 0;
225 bitsHeader.bounds.right = width - 1;
226 bitsHeader.bounds.bottom = height - 1;
227 bitsHeader.rowBytes = bytesPerRow;
228 bitsHeader.colors = format;
229 bitsHeader.dataSize = bitsHeader.rowBytes * height;
230 if ((ret = swap_data(B_UINT32_TYPE, &bitsHeader,
231 sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN)) < B_OK) {
232 delete bitmap;
233 delete wbImage;
234 return ret;
235 } else
236 ret = outDestination->Write(&bitsHeader, sizeof(TranslatorBitmap));
237 }
238
239 if (ret >= B_OK && !headerOnly) {
240 // read one row at a time and write out the results
241 uint8* row = (uint8*)bitmap->Bits();
242 for (uint32 y = 0; y < height && ret >= B_OK; y++) {
243 ret = outDestination->Write(row, bytesPerRow);
244 row += bytesPerRow;
245 }
246
247 }
248
249 delete bitmap;
250 delete wbImage;
251
252 if (ret >= B_OK)
253 ret = B_OK;
254
255 return (status_t)ret;
256 }
257
258
259