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* 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 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 112 WonderBrushTranslator::~WonderBrushTranslator() 113 { 114 #if GAMMA_BLEND 115 uninit_gamma_blending(); 116 #endif 117 } 118 119 120 status_t 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 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 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* 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 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