xref: /haiku/src/add-ons/translators/hvif/HVIFTranslator.cpp (revision b46615c55ad2c8fe6de54412055a0713da3d610a)
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_TRANSLATE_CONTEXT
26 #define B_TRANSLATE_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("Native 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