1/* 2 * Copyright 2005, Axel D��rfler, axeld@pinc-software.de. All rights reserved. 3 * Copyright 2012, Gerasim Troeglazov, 3dEyes@gmail.com. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7#include "ICNSTranslator.h" 8 9#include <stdlib.h> 10#include <stdio.h> 11#include <string.h> 12 13#include "ConfigView.h" 14#include "ICNSLoader.h" 15 16#include <Catalog.h> 17 18#undef B_TRANSLATION_CONTEXT 19#define B_TRANSLATION_CONTEXT "ICNSTranslator" 20 21extern "C" { 22#include "icns.h" 23} 24 25const char *kDocumentCount = "/documentCount"; 26const char *kDocumentIndex = "/documentIndex"; 27 28#define kICNSMimeType "image/icns" 29#define kICNSName "Apple Icon" 30 31// The input formats that this translator supports. 32static const translation_format sInputFormats[] = { 33 { 34 ICNS_IMAGE_FORMAT, 35 B_TRANSLATOR_BITMAP, 36 ICNS_IN_QUALITY, 37 ICNS_IN_CAPABILITY, 38 kICNSMimeType, 39 kICNSName 40 }, 41 { 42 B_TRANSLATOR_BITMAP, 43 B_TRANSLATOR_BITMAP, 44 BITS_IN_QUALITY, 45 BITS_IN_CAPABILITY, 46 "image/x-be-bitmap", 47 "Be Bitmap Format (ICNSTranslator)" 48 }, 49}; 50 51// The output formats that this translator supports. 52static const translation_format sOutputFormats[] = { 53 { 54 ICNS_IMAGE_FORMAT, 55 B_TRANSLATOR_BITMAP, 56 ICNS_OUT_QUALITY, 57 ICNS_OUT_CAPABILITY, 58 kICNSMimeType, 59 kICNSName 60 }, 61 { 62 B_TRANSLATOR_BITMAP, 63 B_TRANSLATOR_BITMAP, 64 BITS_OUT_QUALITY, 65 BITS_OUT_CAPABILITY, 66 "image/x-be-bitmap", 67 "Be Bitmap Format (ICNSTranslator)" 68 }, 69}; 70 71// Default settings for the Translator 72static const TranSetting sDefaultSettings[] = { 73 {B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false}, 74 {B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false} 75}; 76 77const uint32 kNumInputFormats = sizeof(sInputFormats) 78 / sizeof(translation_format); 79const uint32 kNumOutputFormats = sizeof(sOutputFormats) 80 / sizeof(translation_format); 81const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) 82 / sizeof(TranSetting); 83 84 85ICNSTranslator::ICNSTranslator() 86 : BaseTranslator(B_TRANSLATE("Apple icons"), 87 B_TRANSLATE("Apple icon translator"), 88 ICNS_TRANSLATOR_VERSION, 89 sInputFormats, kNumInputFormats, 90 sOutputFormats, kNumOutputFormats, 91 "ICNSTranslator", 92 sDefaultSettings, kNumDefaultSettings, 93 B_TRANSLATOR_BITMAP, ICNS_IMAGE_FORMAT) 94{ 95} 96 97 98ICNSTranslator::~ICNSTranslator() 99{ 100} 101 102 103status_t 104ICNSTranslator::DerivedIdentify(BPositionIO *stream, 105 const translation_format *format, BMessage *ioExtension, 106 translator_info *info, uint32 outType) 107{ 108 if (!outType) 109 outType = B_TRANSLATOR_BITMAP; 110 if (outType != B_TRANSLATOR_BITMAP && outType != ICNS_IMAGE_FORMAT) 111 return B_NO_TRANSLATOR; 112 113 uint32 signatureData; 114 ssize_t signatureSize = 4; 115 if (stream->Read(&signatureData, signatureSize) != signatureSize) 116 return B_IO_ERROR; 117 118 const uint32 kICNSMagic = B_HOST_TO_BENDIAN_INT32('icns'); 119 120 if (signatureData != kICNSMagic) 121 return B_ILLEGAL_DATA; 122 123 124 ICNSLoader icnsFile(stream); 125 if(!icnsFile.IsLoaded() || icnsFile.IconsCount() <= 0) 126 return B_ILLEGAL_DATA; 127 128 int32 documentCount = icnsFile.IconsCount(); 129 int32 documentIndex = 1; 130 131 if (ioExtension) { 132 if (ioExtension->FindInt32(DOCUMENT_INDEX, &documentIndex) != B_OK) 133 documentIndex = 1; 134 if (documentIndex < 1 || documentIndex > documentCount) 135 return B_NO_TRANSLATOR; 136 137 ioExtension->RemoveName(DOCUMENT_COUNT); 138 ioExtension->AddInt32(DOCUMENT_COUNT, documentCount); 139 } 140 141 info->type = ICNS_IMAGE_FORMAT; 142 info->group = B_TRANSLATOR_BITMAP; 143 info->quality = ICNS_IN_QUALITY; 144 info->capability = ICNS_IN_CAPABILITY; 145 BString iconName("Apple icon"); 146 if (documentCount > 1) 147 iconName << " #" << documentIndex; 148 strlcpy(info->name, iconName.String(), sizeof(info->name)); 149 strcpy(info->MIME, kICNSMimeType); 150 151 return B_OK; 152} 153 154 155status_t 156ICNSTranslator::DerivedTranslate(BPositionIO *source, 157 const translator_info *info, BMessage *ioExtension, 158 uint32 outType, BPositionIO *target, int32 baseType) 159{ 160 if (!outType) 161 outType = B_TRANSLATOR_BITMAP; 162 if (outType != B_TRANSLATOR_BITMAP && outType != ICNS_IMAGE_FORMAT) 163 return B_NO_TRANSLATOR; 164 165 switch (baseType) { 166 case 1: 167 { 168 TranslatorBitmap bitsHeader; 169 status_t result; 170 result = identify_bits_header(source, NULL, &bitsHeader); 171 if (result != B_OK) 172 return B_NO_TRANSLATOR; 173 174 icns_type_t type = ICNSFormat(bitsHeader.bounds.Width() + 1, 175 bitsHeader.bounds.Height() + 1, bitsHeader.colors); 176 if (type == ICNS_NULL_TYPE) 177 return B_NO_TRANSLATOR; 178 179 if (outType == ICNS_IMAGE_FORMAT) { 180 ICNSSaver icnsFile(source, bitsHeader.rowBytes, type); 181 if (icnsFile.IsCreated()) 182 return icnsFile.SaveData(target); 183 } 184 185 return B_NO_TRANSLATOR; 186 } 187 188 case 0: 189 { 190 if (outType != B_TRANSLATOR_BITMAP) 191 return B_NO_TRANSLATOR; 192 193 ICNSLoader icnsFile(source); 194 if (!icnsFile.IsLoaded() || icnsFile.IconsCount() <= 0) 195 return B_NO_TRANSLATOR; 196 197 int32 documentIndex = 1; 198 199 if (ioExtension) { 200 if (ioExtension->FindInt32(DOCUMENT_INDEX, &documentIndex) != B_OK) 201 documentIndex = 1; 202 } 203 204 return icnsFile.GetIcon(target, documentIndex); 205 } 206 207 default: 208 return B_NO_TRANSLATOR; 209 } 210} 211 212 213status_t 214ICNSTranslator::DerivedCanHandleImageSize(float width, float height) const 215{ 216 if (ICNSFormat(width, height, B_RGBA32) == ICNS_NULL_TYPE) 217 return B_NO_TRANSLATOR; 218 return B_OK; 219} 220 221 222BView * 223ICNSTranslator::NewConfigView(TranslatorSettings *settings) 224{ 225 return new ConfigView(settings); 226} 227 228 229// #pragma mark - 230 231 232BTranslator * 233make_nth_translator(int32 n, image_id you, uint32 flags, ...) 234{ 235 if (n != 0) 236 return NULL; 237 238 return new ICNSTranslator(); 239} 240 241