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