1/* 2 * Copyright 2008, J��r��me Duval. All rights reserved. 3 * Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 4 * Digital Ltd. LLC 5 * Distributed under the terms of the MIT License. 6 */ 7 8#include <Catalog.h> 9 10#include "ConfigView.h" 11#include "EXRGamma.h" 12#include "EXRTranslator.h" 13#include "ImfArray.h" 14#undef min 15#undef max 16#include "ImfRgbaFile.h" 17#include "IStreamWrapper.h" 18 19#undef B_TRANSLATION_CONTEXT 20#define B_TRANSLATION_CONTEXT "EXRTranslator" 21 22 23// The input formats that this translator supports. 24static const translation_format sInputFormats[] = { 25 { 26 EXR_IMAGE_FORMAT, 27 B_TRANSLATOR_BITMAP, 28 EXR_IN_QUALITY, 29 EXR_IN_CAPABILITY, 30 "image/exr", 31 "EXR" 32 }, 33}; 34 35// The output formats that this translator supports. 36static const translation_format sOutputFormats[] = { 37 { 38 B_TRANSLATOR_BITMAP, 39 B_TRANSLATOR_BITMAP, 40 BITS_OUT_QUALITY, 41 BITS_OUT_CAPABILITY, 42 "image/x-be-bitmap", 43 "Be Bitmap Format (EXRTranslator)" 44 }, 45}; 46 47// Default settings for the Translator 48static const TranSetting sDefaultSettings[] = { 49 {B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false}, 50 {B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false} 51}; 52 53const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format); 54const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format); 55const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting); 56 57 58 59 60// #pragma mark - 61 62 63EXRTranslator::EXRTranslator() 64 : BaseTranslator(B_TRANSLATE("EXR images"), 65 B_TRANSLATE("EXR image translator"), 66 EXR_TRANSLATOR_VERSION, 67 sInputFormats, kNumInputFormats, 68 sOutputFormats, kNumOutputFormats, 69 "EXRTranslator_Settings", 70 sDefaultSettings, kNumDefaultSettings, 71 B_TRANSLATOR_BITMAP, EXR_IMAGE_FORMAT) 72{ 73} 74 75 76EXRTranslator::~EXRTranslator() 77{ 78} 79 80 81status_t 82EXRTranslator::DerivedIdentify(BPositionIO *stream, 83 const translation_format *format, BMessage *settings, 84 translator_info *outInfo, uint32 outType) 85{ 86 if (!outType) 87 outType = B_TRANSLATOR_BITMAP; 88 if (outType != B_TRANSLATOR_BITMAP) 89 return B_NO_TRANSLATOR; 90 91 try { 92 IStreamWrapper istream("filename", stream); 93 RgbaInputFile inputFile(istream); 94 95 if (outInfo) { 96 outInfo->type = EXR_IMAGE_FORMAT; 97 outInfo->group = B_TRANSLATOR_BITMAP; 98 outInfo->quality = EXR_IN_QUALITY; 99 outInfo->capability = EXR_IN_CAPABILITY; 100 strcpy(outInfo->MIME, "image/exr"); 101 strlcpy(outInfo->name, B_TRANSLATE("EXR image"), 102 sizeof(outInfo->name)); 103 } 104 } catch (...) { 105 return B_NO_TRANSLATOR; 106 } 107 108 return B_OK; 109} 110 111 112status_t 113EXRTranslator::DerivedTranslate(BPositionIO* source, 114 const translator_info* info, BMessage* settings, 115 uint32 outType, BPositionIO* target, int32 baseType) 116{ 117 if (!outType) 118 outType = B_TRANSLATOR_BITMAP; 119 if (outType != B_TRANSLATOR_BITMAP || baseType != 0) 120 return B_NO_TRANSLATOR; 121 122 status_t err = B_NO_TRANSLATOR; 123 try { 124 IStreamWrapper istream("filename", source); 125 RgbaInputFile in(istream); 126 127 //Imath::Box2i dw = in.dataWindow(); 128 const Imath::Box2i &displayWindow = in.displayWindow(); 129 const Imath::Box2i &dataWindow = in.dataWindow(); 130 //float a = in.pixelAspectRatio(); // TODO take into account the aspect ratio 131 int dataWidth = dataWindow.max.x - dataWindow.min.x + 1; 132 int dataHeight = dataWindow.max.y - dataWindow.min.y + 1; 133 int displayWidth = displayWindow.max.x - displayWindow.min.x + 1; 134 int displayHeight = displayWindow.max.y - displayWindow.min.y + 1; 135 136 // Write out the data to outDestination 137 // Construct and write Be bitmap header 138 TranslatorBitmap bitsHeader; 139 bitsHeader.magic = B_TRANSLATOR_BITMAP; 140 bitsHeader.bounds.left = 0; 141 bitsHeader.bounds.top = 0; 142 bitsHeader.bounds.right = displayWidth - 1; 143 bitsHeader.bounds.bottom = displayHeight - 1; 144 bitsHeader.rowBytes = 4 * displayWidth; 145 bitsHeader.colors = B_RGBA32; 146 bitsHeader.dataSize = bitsHeader.rowBytes * displayHeight; 147 if (swap_data(B_UINT32_TYPE, &bitsHeader, 148 sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN) != B_OK) { 149 return B_ERROR; 150 } 151 target->Write(&bitsHeader, sizeof(TranslatorBitmap)); 152 153 Array2D <Rgba> pixels(dataHeight, dataWidth); 154 in.setFrameBuffer (&pixels[0][0] - dataWindow.min.y * dataWidth - dataWindow.min.x, 1, dataWidth); 155 in.readPixels (dataWindow.min.y, dataWindow.max.y); 156 157 float _gamma = 0.4545f; 158 float _exposure = 0.0f; 159 float _defog = 0.0f; 160 float _kneeLow = 0.0f; 161 float _kneeHigh = 5.0f; 162 163 float _fogR = 0.0f; 164 float _fogG = 0.0f; 165 float _fogB = 0.0f; 166 167 halfFunction<float> 168 rGamma (Gamma (_gamma, 169 _exposure, 170 _defog * _fogR, 171 _kneeLow, 172 _kneeHigh), 173 -HALF_MAX, HALF_MAX, 174 0.f, 255.f, 0.f, 0.f); 175 176 halfFunction<float> 177 gGamma (Gamma (_gamma, 178 _exposure, 179 _defog * _fogG, 180 _kneeLow, 181 _kneeHigh), 182 -HALF_MAX, HALF_MAX, 183 0.f, 255.f, 0.f, 0.f); 184 185 halfFunction<float> 186 bGamma (Gamma (_gamma, 187 _exposure, 188 _defog * _fogB, 189 _kneeLow, 190 _kneeHigh), 191 -HALF_MAX, HALF_MAX, 192 0.f, 255.f, 0.f, 0.f); 193 194 for (int y = displayWindow.min.y; y <= displayWindow.max.y; ++y) { 195 if (y < dataWindow.min.y 196 || y > dataWindow.max.y) { 197 unsigned char sp[4]; 198 sp[0] = 128; 199 sp[1] = 128; 200 sp[2] = 128; 201 sp[3] = 255; 202 for (int x = displayWindow.min.x; x <= displayWindow.max.x; ++x) { 203 target->Write(sp, 4); 204 } 205 continue; 206 } 207 208 for (int x = displayWindow.min.x; x <= displayWindow.max.x; ++x) { 209 unsigned char sp[4]; 210 if (x < dataWindow.min.x 211 || x > dataWindow.max.x) { 212 sp[0] = 128; 213 sp[1] = 128; 214 sp[2] = 128; 215 sp[3] = 255; 216 } else { 217 const Imf::Rgba &rp = pixels[y][x]; 218 219 sp[0] = (unsigned char)bGamma(rp.b); 220 sp[1] = (unsigned char)gGamma(rp.g); 221 sp[2] = (unsigned char)rGamma(rp.r); 222 sp[3] = 255; 223 } 224 target->Write(sp, 4); 225 } 226 } 227 228 err = B_OK; 229// } catch (const std::exception &e) { 230// std::cerr << e.what() << std::endl; 231 } catch (...) { 232 } 233 return err; 234} 235 236 237BView * 238EXRTranslator::NewConfigView(TranslatorSettings *settings) 239{ 240 return new ConfigView(); 241} 242 243 244// #pragma mark - 245 246 247BTranslator * 248make_nth_translator(int32 n, image_id you, uint32 flags, ...) 249{ 250 if (n != 0) 251 return NULL; 252 253 return new EXRTranslator(); 254} 255