xref: /haiku/src/add-ons/translators/hvif/HVIFTranslator.cpp (revision 9d3da74deabb2eda5a8c7963db514fce6a586cc9)
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