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_TRANSLATE_CONTEXT 26 #define B_TRANSLATE_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 strcpy(outInfo->name, B_TRANSLATE("WonderBrush image")); 138 } 139 } else { 140 delete wbImage; 141 wbImage = NULL; 142 } 143 if (!_wbImage) { 144 // close WonderBrushImage if caller is not interested in handle 145 delete wbImage; 146 } else { 147 // leave WonderBrushImage open (if it is) and return handle if 148 // caller needs it 149 *_wbImage = wbImage; 150 } 151 152 return status; 153 } 154 155 156 status_t 157 WonderBrushTranslator::DerivedIdentify(BPositionIO* inSource, 158 const translation_format* inFormat, BMessage* ioExtension, 159 translator_info* outInfo, uint32 outType) 160 { 161 return identify_wbi_header(inSource, outInfo, outType); 162 } 163 164 165 status_t 166 WonderBrushTranslator::DerivedTranslate(BPositionIO* inSource, 167 const translator_info* inInfo, BMessage* ioExtension, 168 uint32 outType, BPositionIO* outDestination, int32 baseType) 169 { 170 if (baseType == 0) 171 // if inSource is NOT in bits format 172 return _TranslateFromWBI(inSource, outType, outDestination); 173 else 174 // if BaseTranslator did not properly identify the data as 175 // bits or not bits 176 return B_NO_TRANSLATOR; 177 } 178 179 180 BView* 181 WonderBrushTranslator::NewConfigView(TranslatorSettings* settings) 182 { 183 return new WonderBrushView(BRect(0, 0, 225, 175), 184 B_TRANSLATE("WBI Settings"), B_FOLLOW_ALL, B_WILL_DRAW, settings); 185 } 186 187 188 // #pragma mark - 189 190 191 status_t 192 WonderBrushTranslator::_TranslateFromWBI(BPositionIO* inSource, uint32 outType, 193 BPositionIO* outDestination) 194 { 195 // if copying WBI_FORMAT to WBI_FORMAT 196 if (outType == WBI_FORMAT) { 197 translate_direct_copy(inSource, outDestination); 198 return B_OK; 199 } 200 201 WonderBrushImage* wbImage = NULL; 202 ssize_t ret = identify_wbi_header(inSource, NULL, outType, &wbImage); 203 if (ret < B_OK) 204 return ret; 205 206 bool headerOnly = false; 207 bool dataOnly = false; 208 209 BBitmap* bitmap = wbImage->Bitmap(); 210 if (!bitmap) 211 return B_ERROR; 212 213 uint32 width = bitmap->Bounds().IntegerWidth() + 1; 214 uint32 height = bitmap->Bounds().IntegerHeight() + 1; 215 color_space format = bitmap->ColorSpace(); 216 uint32 bytesPerRow = bitmap->BytesPerRow(); 217 218 if (!dataOnly) { 219 // Construct and write Be bitmap header 220 TranslatorBitmap bitsHeader; 221 bitsHeader.magic = B_TRANSLATOR_BITMAP; 222 bitsHeader.bounds.left = 0; 223 bitsHeader.bounds.top = 0; 224 bitsHeader.bounds.right = width - 1; 225 bitsHeader.bounds.bottom = height - 1; 226 bitsHeader.rowBytes = bytesPerRow; 227 bitsHeader.colors = format; 228 bitsHeader.dataSize = bitsHeader.rowBytes * height; 229 if ((ret = swap_data(B_UINT32_TYPE, &bitsHeader, 230 sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN)) < B_OK) { 231 delete bitmap; 232 delete wbImage; 233 return ret; 234 } else 235 ret = outDestination->Write(&bitsHeader, sizeof(TranslatorBitmap)); 236 } 237 238 if (ret >= B_OK && !headerOnly) { 239 // read one row at a time and write out the results 240 uint8* row = (uint8*)bitmap->Bits(); 241 for (uint32 y = 0; y < height && ret >= B_OK; y++) { 242 ret = outDestination->Write(row, bytesPerRow); 243 row += bytesPerRow; 244 } 245 246 } 247 248 delete bitmap; 249 delete wbImage; 250 251 if (ret >= B_OK) 252 ret = B_OK; 253 254 return (status_t)ret; 255 } 256 257 258