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