1 /* 2 * Copyright 2009, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Michael Lotz, mmlr@mlotz.ch 7 */ 8 9 #include "HVIFTranslator.h" 10 #include "HVIFView.h" 11 12 #include <Bitmap.h> 13 #include <BitmapStream.h> 14 #include <Catalog.h> 15 #include <IconUtils.h> 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 21 #define HVIF_FORMAT_CODE 'HVIF' 22 #define HVIF_TRANSLATION_QUALITY 1.0 23 #define HVIF_TRANSLATION_CAPABILITY 1.0 24 25 #undef B_TRANSLATION_CONTEXT 26 #define B_TRANSLATION_CONTEXT "HVIFTranslator" 27 28 29 static const translation_format sInputFormats[] = { 30 { 31 HVIF_FORMAT_CODE, 32 B_TRANSLATOR_BITMAP, 33 HVIF_TRANSLATION_QUALITY, 34 HVIF_TRANSLATION_CAPABILITY, 35 "application/x-vnd.Haiku-icon", 36 "Native Haiku vector icon" 37 } 38 }; 39 40 41 static const translation_format sOutputFormats[] = { 42 { 43 B_TRANSLATOR_BITMAP, 44 B_TRANSLATOR_BITMAP, 45 0.4, 46 0.4, 47 "image/x-be-bitmap", 48 "Be Bitmap format (HVIFTranslator)" 49 } 50 }; 51 52 53 static const TranSetting sDefaultSettings[] = { 54 { HVIF_SETTING_RENDER_SIZE, TRAN_SETTING_INT32, 64 } 55 }; 56 57 const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format); 58 const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format); 59 const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting); 60 61 62 63 BTranslator * 64 make_nth_translator(int32 n, image_id image, uint32 flags, ...) 65 { 66 if (n == 0) 67 return new HVIFTranslator(); 68 return NULL; 69 } 70 71 72 HVIFTranslator::HVIFTranslator() 73 : BaseTranslator(B_TRANSLATE("HVIF icons"), 74 B_TRANSLATE("Haiku vector icon translator"), 75 HVIF_TRANSLATOR_VERSION, 76 sInputFormats, kNumInputFormats, 77 sOutputFormats, kNumOutputFormats, 78 "HVIFTranslator_Settings", 79 sDefaultSettings, kNumDefaultSettings, 80 B_TRANSLATOR_BITMAP, HVIF_FORMAT_CODE) 81 { 82 } 83 84 85 HVIFTranslator::~HVIFTranslator() 86 { 87 } 88 89 90 status_t 91 HVIFTranslator::DerivedIdentify(BPositionIO *inSource, 92 const translation_format *inFormat, BMessage *ioExtension, 93 translator_info *outInfo, uint32 outType) 94 { 95 // TODO: we do the fully work twice! 96 if (outType != B_TRANSLATOR_BITMAP) 97 return B_NO_TRANSLATOR; 98 99 // filter out invalid sizes 100 off_t size = inSource->Seek(0, SEEK_END); 101 if (size <= 0 || size > 256 * 1024 || inSource->Seek(0, SEEK_SET) != 0) 102 return B_NO_TRANSLATOR; 103 104 uint8 *buffer = (uint8 *)malloc(size); 105 if (buffer == NULL) 106 return B_NO_MEMORY; 107 108 if (inSource->Read(buffer, size) != size) { 109 free(buffer); 110 return B_NO_TRANSLATOR; 111 } 112 113 BBitmap dummy(BRect(0, 0, 1, 1), B_BITMAP_NO_SERVER_LINK, B_RGBA32); 114 if (BIconUtils::GetVectorIcon(buffer, size, &dummy) != B_OK) { 115 free(buffer); 116 return B_NO_TRANSLATOR; 117 } 118 119 if (outInfo) { 120 outInfo->type = sInputFormats[0].type; 121 outInfo->group = sInputFormats[0].group; 122 outInfo->quality = sInputFormats[0].quality; 123 outInfo->capability = sInputFormats[0].capability; 124 strcpy(outInfo->MIME, sInputFormats[0].MIME); 125 strcpy(outInfo->name, sInputFormats[0].name); 126 } 127 128 free(buffer); 129 return B_OK; 130 } 131 132 133 status_t 134 HVIFTranslator::DerivedTranslate(BPositionIO *inSource, 135 const translator_info *inInfo, BMessage *ioExtension, uint32 outType, 136 BPositionIO *outDestination, int32 baseType) 137 { 138 if (outType != B_TRANSLATOR_BITMAP) 139 return B_NO_TRANSLATOR; 140 141 // filter out invalid sizes 142 off_t size = inSource->Seek(0, SEEK_END); 143 if (size <= 0 || size > 256 * 1024 || inSource->Seek(0, SEEK_SET) != 0) 144 return B_NO_TRANSLATOR; 145 146 uint8 *buffer = (uint8 *)malloc(size); 147 if (buffer == NULL) 148 return B_NO_MEMORY; 149 150 if (inSource->Read(buffer, size) != size) { 151 free(buffer); 152 return B_NO_TRANSLATOR; 153 } 154 155 int32 renderSize = fSettings->SetGetInt32(HVIF_SETTING_RENDER_SIZE); 156 if (renderSize <= 0 || renderSize > 1024) 157 renderSize = 64; 158 159 BBitmap rendered(BRect(0, 0, renderSize - 1, renderSize - 1), 160 B_BITMAP_NO_SERVER_LINK, B_RGBA32); 161 if (BIconUtils::GetVectorIcon(buffer, size, &rendered) != B_OK) { 162 free(buffer); 163 return B_NO_TRANSLATOR; 164 } 165 166 BBitmapStream stream(&rendered); 167 stream.Seek(0, SEEK_SET); 168 ssize_t read = 0; 169 170 while ((read = stream.Read(buffer, size)) > 0) 171 outDestination->Write(buffer, read); 172 173 BBitmap *dummy = NULL; 174 stream.DetachBitmap(&dummy); 175 free(buffer); 176 return B_OK; 177 } 178 179 180 BView * 181 HVIFTranslator::NewConfigView(TranslatorSettings *settings) 182 { 183 return new HVIFView(B_TRANSLATE("HVIFTranslator Settings"), 184 B_WILL_DRAW, settings); 185 } 186