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