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