1 /* 2 * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "RAWTranslator.h" 8 #include "ConfigView.h" 9 #include "RAW.h" 10 11 #include <TranslatorRoster.h> 12 13 #include <stdlib.h> 14 #include <stdio.h> 15 #include <string.h> 16 17 18 // Extensions that ShowImage supports 19 const char *kDocumentCount = "/documentCount"; 20 const char *kDocumentIndex = "/documentIndex"; 21 22 // The input formats that this translator supports. 23 translation_format sInputFormats[] = { 24 { 25 RAW_IMAGE_FORMAT, 26 B_TRANSLATOR_BITMAP, 27 RAW_IN_QUALITY, 28 RAW_IN_CAPABILITY, 29 "image/x-vnd.adobe-dng", 30 "Adobe Digital Negative" 31 }, 32 { 33 RAW_IMAGE_FORMAT, 34 B_TRANSLATOR_BITMAP, 35 RAW_IN_QUALITY, 36 RAW_IN_CAPABILITY, 37 "image/x-vnd.photo-raw", 38 "Digital Photo RAW image" 39 }, 40 }; 41 42 // The output formats that this translator supports. 43 translation_format sOutputFormats[] = { 44 { 45 B_TRANSLATOR_BITMAP, 46 B_TRANSLATOR_BITMAP, 47 BITS_OUT_QUALITY, 48 BITS_OUT_CAPABILITY, 49 "x-be-bitmap", 50 "Be Bitmap image" 51 }, 52 }; 53 54 // Default settings for the Translator 55 static TranSetting sDefaultSettings[] = { 56 {B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false}, 57 {B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false} 58 }; 59 60 const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format); 61 const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format); 62 const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting); 63 64 65 RAWTranslator::RAWTranslator() 66 : BaseTranslator("Raw Images", "Raw Image Translator", 67 RAW_TRANSLATOR_VERSION, 68 sInputFormats, kNumInputFormats, 69 sOutputFormats, kNumOutputFormats, 70 "RawTranslator_Settings", 71 sDefaultSettings, kNumDefaultSettings, 72 B_TRANSLATOR_BITMAP, RAW_IMAGE_FORMAT) 73 { 74 } 75 76 77 RAWTranslator::~RAWTranslator() 78 { 79 } 80 81 82 status_t 83 RAWTranslator::DerivedIdentify(BPositionIO *stream, 84 const translation_format *format, BMessage *settings, 85 translator_info *info, uint32 outType) 86 { 87 if (!outType) 88 outType = B_TRANSLATOR_BITMAP; 89 if (outType != B_TRANSLATOR_BITMAP) 90 return B_NO_TRANSLATOR; 91 92 DCRaw raw(*stream); 93 status_t status; 94 95 try { 96 status = raw.Identify(); 97 } catch (status_t error) { 98 status = error; 99 } 100 101 if (status < B_OK) 102 return B_NO_TRANSLATOR; 103 104 image_meta_info meta; 105 raw.GetMetaInfo(meta); 106 107 if (settings) { 108 int32 count = raw.CountImages(); 109 110 // Add page count to ioExtension 111 settings->RemoveName(kDocumentCount); 112 settings->AddInt32(kDocumentCount, count); 113 114 // Check if a document index has been specified 115 int32 index; 116 if (settings->FindInt32(kDocumentIndex, &index) == B_OK) 117 index--; 118 else 119 index = 0; 120 121 if (index < 0 || index >= count) 122 return B_NO_TRANSLATOR; 123 } 124 125 info->type = RAW_IMAGE_FORMAT; 126 info->group = B_TRANSLATOR_BITMAP; 127 info->quality = RAW_IN_QUALITY; 128 info->capability = RAW_IN_CAPABILITY; 129 snprintf(info->name, sizeof(info->name), "%s RAW image", meta.manufacturer); 130 strcpy(info->MIME, "image/x-vnd.photo-raw"); 131 132 return B_OK; 133 } 134 135 136 status_t 137 RAWTranslator::DerivedTranslate(BPositionIO* source, 138 const translator_info* info, BMessage* settings, 139 uint32 outType, BPositionIO* target, int32 baseType) 140 { 141 if (!outType) 142 outType = B_TRANSLATOR_BITMAP; 143 if (outType != B_TRANSLATOR_BITMAP || baseType != 0) 144 return B_NO_TRANSLATOR; 145 146 bool headerOnly = false; 147 if (settings != NULL) 148 settings->FindBool(B_TRANSLATOR_EXT_HEADER_ONLY, &headerOnly); 149 150 DCRaw raw(*source); 151 152 int32 imageIndex = 0; 153 uint8* buffer = NULL; 154 size_t bufferSize; 155 status_t status; 156 157 try { 158 status = raw.Identify(); 159 160 if (status == B_OK && settings) { 161 // Check if a document index has been specified 162 if (settings->FindInt32(kDocumentIndex, &imageIndex) == B_OK) 163 imageIndex--; 164 else 165 imageIndex = 0; 166 167 if (imageIndex < 0 || imageIndex >= (int32)raw.CountImages()) 168 status = B_BAD_VALUE; 169 } 170 if (status == B_OK && !headerOnly) 171 status = raw.ReadImageAt(imageIndex, buffer, bufferSize); 172 } catch (status_t error) { 173 status = error; 174 } 175 176 if (status < B_OK) 177 return B_NO_TRANSLATOR; 178 179 image_meta_info meta; 180 raw.GetMetaInfo(meta); 181 182 image_data_info data; 183 raw.ImageAt(imageIndex, data); 184 185 if (!data.is_raw) { 186 // let others handle embedded JPEG data 187 BMemoryIO io(buffer, bufferSize); 188 BTranslatorRoster* roster = BTranslatorRoster::Default(); 189 return roster->Translate(&io, NULL, settings, target, outType); 190 } 191 192 uint32 dataSize = data.output_width * 4 * data.output_height; 193 194 TranslatorBitmap header; 195 header.magic = B_TRANSLATOR_BITMAP; 196 header.bounds.Set(0, 0, data.output_width - 1, data.output_height - 1); 197 header.rowBytes = data.output_width * 4; 198 header.colors = B_RGB32; 199 header.dataSize = dataSize; 200 201 // write out Be's Bitmap header 202 swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap), 203 B_SWAP_HOST_TO_BENDIAN); 204 ssize_t bytesWritten = target->Write(&header, sizeof(TranslatorBitmap)); 205 if (bytesWritten < B_OK) 206 return bytesWritten; 207 208 if ((size_t)bytesWritten != sizeof(TranslatorBitmap)) 209 return B_IO_ERROR; 210 211 if (headerOnly) 212 return B_OK; 213 214 bytesWritten = target->Write(buffer, dataSize); 215 if (bytesWritten < B_OK) 216 return bytesWritten; 217 218 if ((size_t)bytesWritten != dataSize) 219 return B_IO_ERROR; 220 221 return B_OK; 222 } 223 224 225 BView * 226 RAWTranslator::NewConfigView(TranslatorSettings *settings) 227 { 228 return new ConfigView(BRect(0, 0, 225, 175)); 229 } 230 231 232 // #pragma mark - 233 234 235 BTranslator * 236 make_nth_translator(int32 n, image_id you, uint32 flags, ...) 237 { 238 if (n != 0) 239 return NULL; 240 241 return new RAWTranslator(); 242 } 243 244