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