xref: /haiku/src/tests/add-ons/translators/bmptranslator/BMPTranslatorTest.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 // BMPTranslatorTest.cpp
2 #include "BMPTranslatorTest.h"
3 #include <cppunit/Test.h>
4 #include <cppunit/TestCaller.h>
5 #include <cppunit/TestSuite.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <image.h>
10 #include <Application.h>
11 #include <Translator.h>
12 #include <TranslatorFormats.h>
13 #include <TranslatorRoster.h>
14 #include <Message.h>
15 #include <View.h>
16 #include <Rect.h>
17 #include <File.h>
18 #include <DataIO.h>
19 #include <Errors.h>
20 #include <OS.h>
21 #include "TranslatorTestAddOn.h"
22 #include "../../../../add-ons/translators/bmptranslator/BMPTranslator.h"
23 
24 // Suite
25 CppUnit::Test *
26 BMPTranslatorTest::Suite()
27 {
28 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
29 	typedef CppUnit::TestCaller<BMPTranslatorTest> TC;
30 
31 	suite->addTest(
32 		new TC("BMPTranslator IdentifyTest",
33 			&BMPTranslatorTest::IdentifyTest));
34 
35 	suite->addTest(
36 		new TC("BMPTranslator TranslateTest",
37 			&BMPTranslatorTest::TranslateTest));
38 
39 	suite->addTest(
40 		new TC("BMPTranslator ConfigMessageTest",
41 			&BMPTranslatorTest::ConfigMessageTest));
42 
43 #if !TEST_R5
44 	suite->addTest(
45 		new TC("BMPTranslator LoadAddOnTest",
46 			&BMPTranslatorTest::LoadAddOnTest));
47 #endif
48 
49 	return suite;
50 }
51 
52 // setUp
53 void
54 BMPTranslatorTest::setUp()
55 {
56 	BTestCase::setUp();
57 }
58 
59 // tearDown
60 void
61 BMPTranslatorTest::tearDown()
62 {
63 	BTestCase::tearDown();
64 }
65 
66 void
67 CheckBits_Bmp(translator_info *pti)
68 {
69 	CheckTranslatorInfo(pti, B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP,
70 		0.6f, 0.8f, "Be Bitmap Format (BMPTranslator)",
71 		"image/x-be-bitmap");
72 }
73 
74 void
75 CheckBmp(translator_info *pti, const char *imageType)
76 {
77 	CheckTranslatorInfo(pti, B_BMP_FORMAT, B_TRANSLATOR_BITMAP,
78 		1.0f, 0.8f, imageType, "image/x-bmp");
79 }
80 
81 // coveniently group path of image with
82 // the expected Identify() string for that image
83 struct IdentifyInfo {
84 	const char *imagePath;
85 	const char *identifyString;
86 };
87 
88 void
89 IdentifyTests(BMPTranslatorTest *ptest, BTranslatorRoster *proster,
90 	const IdentifyInfo *pinfo, int32 len, bool bbits)
91 {
92 	translator_info ti;
93 	printf(" [%d] ", (int) bbits);
94 
95 	for (int32 i = 0; i < len; i++) {
96 		ptest->NextSubTest();
97 		BFile file;
98 		printf(" [%s] ", pinfo[i].imagePath);
99 		CPPUNIT_ASSERT(file.SetTo(pinfo[i].imagePath, B_READ_ONLY) == B_OK);
100 
101 		// Identify (output: B_TRANSLATOR_ANY_TYPE)
102 		ptest->NextSubTest();
103 		memset(&ti, 0, sizeof(translator_info));
104 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti) == B_OK);
105 		if (bbits)
106 			CheckBits_Bmp(&ti);
107 		else
108 			CheckBmp(&ti, pinfo[i].identifyString);
109 
110 		// Identify (output: B_TRANSLATOR_BITMAP)
111 		ptest->NextSubTest();
112 		memset(&ti, 0, sizeof(translator_info));
113 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
114 			B_TRANSLATOR_BITMAP) == B_OK);
115 		if (bbits)
116 			CheckBits_Bmp(&ti);
117 		else
118 			CheckBmp(&ti, pinfo[i].identifyString);
119 
120 		// Identify (output: B_BMP_FORMAT)
121 		ptest->NextSubTest();
122 		memset(&ti, 0, sizeof(translator_info));
123 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
124 			B_BMP_FORMAT) == B_OK);
125 		if (bbits)
126 			CheckBits_Bmp(&ti);
127 		else
128 			CheckBmp(&ti, pinfo[i].identifyString);
129 	}
130 }
131 
132 void
133 BMPTranslatorTest::IdentifyTest()
134 {
135 	// Init
136 	NextSubTest();
137 	status_t result = B_ERROR;
138 	BTranslatorRoster *proster = new BTranslatorRoster();
139 	CPPUNIT_ASSERT(proster);
140 	CPPUNIT_ASSERT(proster->AddTranslators(
141 		"/boot/home/config/add-ons/Translators/BMPTranslator") == B_OK);
142 	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
143 		B_READ_ONLY);
144 	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
145 
146 	// Identify (bad input, output types)
147 	NextSubTest();
148 	translator_info ti;
149 	memset(&ti, 0, sizeof(translator_info));
150 	result = proster->Identify(&wronginput, NULL, &ti, 0,
151 		NULL, B_TRANSLATOR_TEXT);
152 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
153 	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
154 
155 	// Identify (wrong type of input data)
156 	NextSubTest();
157 	memset(&ti, 0, sizeof(translator_info));
158 	result = proster->Identify(&wronginput, NULL, &ti);
159 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
160 	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
161 
162 	// empty
163 	NextSubTest();
164 	BMallocIO mallempty;
165 	CPPUNIT_ASSERT(proster->Identify(&mallempty, NULL, &ti) == B_NO_TRANSLATOR);
166 
167 	// weird, non-image data
168 	NextSubTest();
169 	const char *strmonkey = "monkey monkey monkey";
170 	BMemoryIO memmonkey(strmonkey, strlen(strmonkey));
171 	CPPUNIT_ASSERT(proster->Identify(&memmonkey, NULL, &ti) == B_NO_TRANSLATOR);
172 
173 	// abreviated BMPFileHeader
174 	NextSubTest();
175 	BMPFileHeader fheader;
176 	fheader.magic = 'MB';
177 	fheader.fileSize = 1028;
178 	BMallocIO mallabrev;
179 	CPPUNIT_ASSERT(mallabrev.Write(&fheader.magic, 2) == 2);
180 	CPPUNIT_ASSERT(mallabrev.Write(&fheader.fileSize, 4) == 4);
181 	CPPUNIT_ASSERT(proster->Identify(&mallabrev, NULL, &ti) == B_NO_TRANSLATOR);
182 
183 	// Write out the MS and OS/2 headers with various fields being corrupt, only one
184 	// corrupt field at a time, also do abrev test for MS header and OS/2 header
185 	NextSubTest();
186 	fheader.magic = 'MB';
187 	fheader.fileSize = 53; // bad value, too small to contain all of MS header data
188 	fheader.reserved = 0;
189 	fheader.dataOffset = 54;
190 	MSInfoHeader msheader;
191 	msheader.size = 40;
192 	msheader.width = 5;
193 	msheader.height = 5;
194 	msheader.planes = 1;
195 	msheader.bitsperpixel = 24;
196 	msheader.compression = BMP_NO_COMPRESS;
197 	msheader.imagesize = 0;
198 	msheader.xpixperm = 23275;
199 	msheader.ypixperm = 23275;
200 	msheader.colorsused = 0;
201 	msheader.colorsimportant = 0;
202 	BMallocIO mallbadfs;
203 	CPPUNIT_ASSERT(mallbadfs.Write(&fheader.magic, 2) == 2);
204 	CPPUNIT_ASSERT(mallbadfs.Write(&fheader.fileSize, 4) == 4);
205 	CPPUNIT_ASSERT(mallbadfs.Write(&fheader.reserved, 4) == 4);
206 	CPPUNIT_ASSERT(mallbadfs.Write(&fheader.dataOffset, 4) == 4);
207 	CPPUNIT_ASSERT(mallbadfs.Write(&msheader, 40) == 40);
208 	CPPUNIT_ASSERT(proster->Identify(&mallbadfs, NULL, &ti) == B_NO_TRANSLATOR);
209 
210 	NextSubTest();
211 	fheader.magic = 'MB';
212 	fheader.fileSize = 1028;
213 	fheader.reserved = 7; // bad value, should be zero
214 	fheader.dataOffset = 54;
215 	msheader.size = 40;
216 	msheader.width = 5;
217 	msheader.height = 5;
218 	msheader.planes = 1;
219 	msheader.bitsperpixel = 24;
220 	msheader.compression = BMP_NO_COMPRESS;
221 	msheader.imagesize = 0;
222 	msheader.xpixperm = 23275;
223 	msheader.ypixperm = 23275;
224 	msheader.colorsused = 0;
225 	msheader.colorsimportant = 0;
226 	BMallocIO mallbadr;
227 	CPPUNIT_ASSERT(mallbadr.Write(&fheader.magic, 2) == 2);
228 	CPPUNIT_ASSERT(mallbadr.Write(&fheader.fileSize, 4) == 4);
229 	CPPUNIT_ASSERT(mallbadr.Write(&fheader.reserved, 4) == 4);
230 	CPPUNIT_ASSERT(mallbadr.Write(&fheader.dataOffset, 4) == 4);
231 	CPPUNIT_ASSERT(mallbadr.Write(&msheader, 40) == 40);
232 	CPPUNIT_ASSERT(proster->Identify(&mallbadr, NULL, &ti) == B_NO_TRANSLATOR);
233 
234 	NextSubTest();
235 	fheader.magic = 'MB';
236 	fheader.fileSize = 1028;
237 	fheader.reserved = 0;
238 	fheader.dataOffset = 53; // bad value, for MS format, needs to be at least 54
239 	msheader.size = 40;
240 	msheader.width = 5;
241 	msheader.height = 5;
242 	msheader.planes = 1;
243 	msheader.bitsperpixel = 24;
244 	msheader.compression = BMP_NO_COMPRESS;
245 	msheader.imagesize = 0;
246 	msheader.xpixperm = 23275;
247 	msheader.ypixperm = 23275;
248 	msheader.colorsused = 0;
249 	msheader.colorsimportant = 0;
250 	BMallocIO mallbaddo1;
251 	CPPUNIT_ASSERT(mallbaddo1.Write(&fheader.magic, 2) == 2);
252 	CPPUNIT_ASSERT(mallbaddo1.Write(&fheader.fileSize, 4) == 4);
253 	CPPUNIT_ASSERT(mallbaddo1.Write(&fheader.reserved, 4) == 4);
254 	CPPUNIT_ASSERT(mallbaddo1.Write(&fheader.dataOffset, 4) == 4);
255 	CPPUNIT_ASSERT(mallbaddo1.Write(&msheader, 40) == 40);
256 	CPPUNIT_ASSERT(proster->Identify(&mallbaddo1, NULL, &ti) == B_NO_TRANSLATOR);
257 
258 	NextSubTest();
259 	fheader.magic = 'MB';
260 	fheader.fileSize = 1028;
261 	fheader.reserved = 0;
262 	fheader.dataOffset = 25; // bad value, for OS/2 format, needs to be at least 26
263 	OS2InfoHeader os2header;
264 	os2header.size = 12;
265 	os2header.width = 5;
266 	os2header.height = 5;
267 	os2header.planes = 1;
268 	os2header.bitsperpixel = 24;
269 	BMallocIO mallbaddo2;
270 	CPPUNIT_ASSERT(mallbaddo2.Write(&fheader.magic, 2) == 2);
271 	CPPUNIT_ASSERT(mallbaddo2.Write(&fheader.fileSize, 4) == 4);
272 	CPPUNIT_ASSERT(mallbaddo2.Write(&fheader.reserved, 4) == 4);
273 	CPPUNIT_ASSERT(mallbaddo2.Write(&fheader.dataOffset, 4) == 4);
274 	CPPUNIT_ASSERT(mallbaddo2.Write(&os2header, 12) == 12);
275 	CPPUNIT_ASSERT(proster->Identify(&mallbaddo2, NULL, &ti) == B_NO_TRANSLATOR);
276 
277 	NextSubTest();
278 	fheader.magic = 'MB';
279 	fheader.fileSize = 1028;
280 	fheader.reserved = 0;
281 	fheader.dataOffset = 1029; // bad value, larger than the fileSize
282 	os2header.size = 12;
283 	os2header.width = 5;
284 	os2header.height = 5;
285 	os2header.planes = 1;
286 	os2header.bitsperpixel = 24;
287 	BMallocIO mallbaddo3;
288 	CPPUNIT_ASSERT(mallbaddo3.Write(&fheader.magic, 2) == 2);
289 	CPPUNIT_ASSERT(mallbaddo3.Write(&fheader.fileSize, 4) == 4);
290 	CPPUNIT_ASSERT(mallbaddo3.Write(&fheader.reserved, 4) == 4);
291 	CPPUNIT_ASSERT(mallbaddo3.Write(&fheader.dataOffset, 4) == 4);
292 	CPPUNIT_ASSERT(mallbaddo3.Write(&os2header, 12) == 12);
293 	CPPUNIT_ASSERT(proster->Identify(&mallbaddo3, NULL, &ti) == B_NO_TRANSLATOR);
294 
295 	NextSubTest();
296 	fheader.magic = 'MB';
297 	fheader.fileSize = 1028;
298 	fheader.reserved = 0;
299 	fheader.dataOffset = 26;
300 	os2header.size = 12;
301 	os2header.width = 5;
302 	os2header.height = 5;
303 	os2header.planes = 1;
304 	os2header.bitsperpixel = 24;
305 	BMallocIO mallos2abrev;
306 	CPPUNIT_ASSERT(mallos2abrev.Write(&fheader.magic, 2) == 2);
307 	CPPUNIT_ASSERT(mallos2abrev.Write(&fheader.fileSize, 4) == 4);
308 	CPPUNIT_ASSERT(mallos2abrev.Write(&fheader.reserved, 4) == 4);
309 	CPPUNIT_ASSERT(mallos2abrev.Write(&fheader.dataOffset, 4) == 4);
310 	CPPUNIT_ASSERT(mallos2abrev.Write(&os2header, 1) == 1); // only 1 byte of the os2 header included
311 	CPPUNIT_ASSERT(proster->Identify(&mallos2abrev, NULL, &ti) == B_NO_TRANSLATOR);
312 
313 	NextSubTest();
314 	fheader.magic = 'MB';
315 	fheader.fileSize = 1028;
316 	fheader.reserved = 0;
317 	fheader.dataOffset = 26;
318 	os2header.size = 12;
319 	os2header.width = 5;
320 	os2header.height = 5;
321 	os2header.planes = 1;
322 	os2header.bitsperpixel = 24;
323 	BMallocIO mallos2abrev2;
324 	CPPUNIT_ASSERT(mallos2abrev2.Write(&fheader.magic, 2) == 2);
325 	CPPUNIT_ASSERT(mallos2abrev2.Write(&fheader.fileSize, 4) == 4);
326 	CPPUNIT_ASSERT(mallos2abrev2.Write(&fheader.reserved, 4) == 4);
327 	CPPUNIT_ASSERT(mallos2abrev2.Write(&fheader.dataOffset, 4) == 4);
328 	CPPUNIT_ASSERT(mallos2abrev2.Write(&os2header, 5) == 5); // most of the os2 header missing
329 	CPPUNIT_ASSERT(proster->Identify(&mallos2abrev2, NULL, &ti) == B_NO_TRANSLATOR);
330 
331 	NextSubTest();
332 	fheader.magic = 'MB';
333 	fheader.fileSize = 1028;
334 	fheader.reserved = 0;
335 	fheader.dataOffset = 54;
336 	msheader.size = 40;
337 	msheader.width = 5;
338 	msheader.height = 5;
339 	msheader.planes = 1;
340 	msheader.bitsperpixel = 24;
341 	msheader.compression = BMP_NO_COMPRESS;
342 	msheader.imagesize = 0;
343 	msheader.xpixperm = 23275;
344 	msheader.ypixperm = 23275;
345 	msheader.colorsused = 0;
346 	msheader.colorsimportant = 0;
347 	BMallocIO mallmsabrev1;
348 	CPPUNIT_ASSERT(mallmsabrev1.Write(&fheader.magic, 2) == 2);
349 	CPPUNIT_ASSERT(mallmsabrev1.Write(&fheader.fileSize, 4) == 4);
350 	CPPUNIT_ASSERT(mallmsabrev1.Write(&fheader.reserved, 4) == 4);
351 	CPPUNIT_ASSERT(mallmsabrev1.Write(&fheader.dataOffset, 4) == 4);
352 	CPPUNIT_ASSERT(mallmsabrev1.Write(&msheader, 1) == 1); // only 1 byte of ms header written
353 	CPPUNIT_ASSERT(proster->Identify(&mallmsabrev1, NULL, &ti) == B_NO_TRANSLATOR);
354 
355 	NextSubTest();
356 	fheader.magic = 'MB';
357 	fheader.fileSize = 1028;
358 	fheader.reserved = 0;
359 	fheader.dataOffset = 54;
360 	msheader.size = 40;
361 	msheader.width = 5;
362 	msheader.height = 5;
363 	msheader.planes = 1;
364 	msheader.bitsperpixel = 24;
365 	msheader.compression = BMP_NO_COMPRESS;
366 	msheader.imagesize = 0;
367 	msheader.xpixperm = 23275;
368 	msheader.ypixperm = 23275;
369 	msheader.colorsused = 0;
370 	msheader.colorsimportant = 0;
371 	BMallocIO mallmsabrev2;
372 	CPPUNIT_ASSERT(mallmsabrev2.Write(&fheader.magic, 2) == 2);
373 	CPPUNIT_ASSERT(mallmsabrev2.Write(&fheader.fileSize, 4) == 4);
374 	CPPUNIT_ASSERT(mallmsabrev2.Write(&fheader.reserved, 4) == 4);
375 	CPPUNIT_ASSERT(mallmsabrev2.Write(&fheader.dataOffset, 4) == 4);
376 	CPPUNIT_ASSERT(mallmsabrev2.Write(&msheader, 15) == 15); // less than half of ms header written
377 	CPPUNIT_ASSERT(proster->Identify(&mallmsabrev2, NULL, &ti) == B_NO_TRANSLATOR);
378 
379 	NextSubTest();
380 	fheader.magic = 'MB';
381 	fheader.fileSize = 1028;
382 	fheader.reserved = 0;
383 	fheader.dataOffset = 54;
384 	msheader.size = 39; // size too small for MS format
385 	msheader.width = 5;
386 	msheader.height = 5;
387 	msheader.planes = 1;
388 	msheader.bitsperpixel = 24;
389 	msheader.compression = BMP_NO_COMPRESS;
390 	msheader.imagesize = 0;
391 	msheader.xpixperm = 23275;
392 	msheader.ypixperm = 23275;
393 	msheader.colorsused = 0;
394 	msheader.colorsimportant = 0;
395 	BMallocIO mallmssize;
396 	CPPUNIT_ASSERT(mallmssize.Write(&fheader.magic, 2) == 2);
397 	CPPUNIT_ASSERT(mallmssize.Write(&fheader.fileSize, 4) == 4);
398 	CPPUNIT_ASSERT(mallmssize.Write(&fheader.reserved, 4) == 4);
399 	CPPUNIT_ASSERT(mallmssize.Write(&fheader.dataOffset, 4) == 4);
400 	CPPUNIT_ASSERT(mallmssize.Write(&msheader, 40) == 40);
401 	CPPUNIT_ASSERT(proster->Identify(&mallmssize, NULL, &ti) == B_NO_TRANSLATOR);
402 
403 	NextSubTest();
404 	fheader.magic = 'MB';
405 	fheader.fileSize = 1028;
406 	fheader.reserved = 0;
407 	fheader.dataOffset = 54;
408 	msheader.size = 41; // size too large for MS format
409 	msheader.width = 5;
410 	msheader.height = 5;
411 	msheader.planes = 1;
412 	msheader.bitsperpixel = 24;
413 	msheader.compression = BMP_NO_COMPRESS;
414 	msheader.imagesize = 0;
415 	msheader.xpixperm = 23275;
416 	msheader.ypixperm = 23275;
417 	msheader.colorsused = 0;
418 	msheader.colorsimportant = 0;
419 	BMallocIO mallmssize2;
420 	CPPUNIT_ASSERT(mallmssize2.Write(&fheader.magic, 2) == 2);
421 	CPPUNIT_ASSERT(mallmssize2.Write(&fheader.fileSize, 4) == 4);
422 	CPPUNIT_ASSERT(mallmssize2.Write(&fheader.reserved, 4) == 4);
423 	CPPUNIT_ASSERT(mallmssize2.Write(&fheader.dataOffset, 4) == 4);
424 	CPPUNIT_ASSERT(mallmssize2.Write(&msheader, 40) == 40);
425 	CPPUNIT_ASSERT(proster->Identify(&mallmssize2, NULL, &ti) == B_NO_TRANSLATOR);
426 
427 	NextSubTest();
428 	fheader.magic = 'MB';
429 	fheader.fileSize = 1028;
430 	fheader.reserved = 0;
431 	fheader.dataOffset = 26;
432 	os2header.size = 11; // os2 header size should be 12
433 	os2header.width = 5;
434 	os2header.height = 5;
435 	os2header.planes = 1;
436 	os2header.bitsperpixel = 24;
437 	BMallocIO mallos2size;
438 	CPPUNIT_ASSERT(mallos2size.Write(&fheader.magic, 2) == 2);
439 	CPPUNIT_ASSERT(mallos2size.Write(&fheader.fileSize, 4) == 4);
440 	CPPUNIT_ASSERT(mallos2size.Write(&fheader.reserved, 4) == 4);
441 	CPPUNIT_ASSERT(mallos2size.Write(&fheader.dataOffset, 4) == 4);
442 	CPPUNIT_ASSERT(mallos2size.Write(&os2header, 12) == 12);
443 	CPPUNIT_ASSERT(proster->Identify(&mallos2size, NULL, &ti) == B_NO_TRANSLATOR);
444 
445 	NextSubTest();
446 	fheader.magic = 'MB';
447 	fheader.fileSize = 1028;
448 	fheader.reserved = 0;
449 	fheader.dataOffset = 26;
450 	os2header.size = 13; // os2 header size should be 12
451 	os2header.width = 5;
452 	os2header.height = 5;
453 	os2header.planes = 1;
454 	os2header.bitsperpixel = 24;
455 	BMallocIO mallos2size2;
456 	CPPUNIT_ASSERT(mallos2size2.Write(&fheader.magic, 2) == 2);
457 	CPPUNIT_ASSERT(mallos2size2.Write(&fheader.fileSize, 4) == 4);
458 	CPPUNIT_ASSERT(mallos2size2.Write(&fheader.reserved, 4) == 4);
459 	CPPUNIT_ASSERT(mallos2size2.Write(&fheader.dataOffset, 4) == 4);
460 	CPPUNIT_ASSERT(mallos2size2.Write(&os2header, 12) == 12);
461 	CPPUNIT_ASSERT(proster->Identify(&mallos2size2, NULL, &ti) == B_NO_TRANSLATOR);
462 
463 	NextSubTest();
464 	fheader.magic = 'MB';
465 	fheader.fileSize = 1028;
466 	fheader.reserved = 0;
467 	fheader.dataOffset = 54;
468 	msheader.size = 40;
469 	msheader.width = 0; // width of zero is ridiculous
470 	msheader.height = 5;
471 	msheader.planes = 1;
472 	msheader.bitsperpixel = 24;
473 	msheader.compression = BMP_NO_COMPRESS;
474 	msheader.imagesize = 0;
475 	msheader.xpixperm = 23275;
476 	msheader.ypixperm = 23275;
477 	msheader.colorsused = 0;
478 	msheader.colorsimportant = 0;
479 	BMallocIO mallmswidth;
480 	CPPUNIT_ASSERT(mallmswidth.Write(&fheader.magic, 2) == 2);
481 	CPPUNIT_ASSERT(mallmswidth.Write(&fheader.fileSize, 4) == 4);
482 	CPPUNIT_ASSERT(mallmswidth.Write(&fheader.reserved, 4) == 4);
483 	CPPUNIT_ASSERT(mallmswidth.Write(&fheader.dataOffset, 4) == 4);
484 	CPPUNIT_ASSERT(mallmswidth.Write(&msheader, 40) == 40);
485 	CPPUNIT_ASSERT(proster->Identify(&mallmswidth, NULL, &ti) == B_NO_TRANSLATOR);
486 
487 	NextSubTest();
488 	fheader.magic = 'MB';
489 	fheader.fileSize = 1028;
490 	fheader.reserved = 0;
491 	fheader.dataOffset = 26;
492 	os2header.size = 12;
493 	os2header.width = 0; // width of zero is ridiculous
494 	os2header.height = 5;
495 	os2header.planes = 1;
496 	os2header.bitsperpixel = 24;
497 	BMallocIO mallos2width;
498 	CPPUNIT_ASSERT(mallos2width.Write(&fheader.magic, 2) == 2);
499 	CPPUNIT_ASSERT(mallos2width.Write(&fheader.fileSize, 4) == 4);
500 	CPPUNIT_ASSERT(mallos2width.Write(&fheader.reserved, 4) == 4);
501 	CPPUNIT_ASSERT(mallos2width.Write(&fheader.dataOffset, 4) == 4);
502 	CPPUNIT_ASSERT(mallos2width.Write(&os2header, 12) == 12);
503 	CPPUNIT_ASSERT(proster->Identify(&mallos2width, NULL, &ti) == B_NO_TRANSLATOR);
504 
505 	NextSubTest();
506 	fheader.magic = 'MB';
507 	fheader.fileSize = 1028;
508 	fheader.reserved = 0;
509 	fheader.dataOffset = 54;
510 	msheader.size = 40;
511 	msheader.width = 5;
512 	msheader.height = 0; // zero is not a good value
513 	msheader.planes = 1;
514 	msheader.bitsperpixel = 24;
515 	msheader.compression = BMP_NO_COMPRESS;
516 	msheader.imagesize = 0;
517 	msheader.xpixperm = 23275;
518 	msheader.ypixperm = 23275;
519 	msheader.colorsused = 0;
520 	msheader.colorsimportant = 0;
521 	BMallocIO mallmsheight;
522 	CPPUNIT_ASSERT(mallmsheight.Write(&fheader.magic, 2) == 2);
523 	CPPUNIT_ASSERT(mallmsheight.Write(&fheader.fileSize, 4) == 4);
524 	CPPUNIT_ASSERT(mallmsheight.Write(&fheader.reserved, 4) == 4);
525 	CPPUNIT_ASSERT(mallmsheight.Write(&fheader.dataOffset, 4) == 4);
526 	CPPUNIT_ASSERT(mallmsheight.Write(&msheader, 40) == 40);
527 	CPPUNIT_ASSERT(proster->Identify(&mallmsheight, NULL, &ti) == B_NO_TRANSLATOR);
528 
529 	NextSubTest();
530 	fheader.magic = 'MB';
531 	fheader.fileSize = 1028;
532 	fheader.reserved = 0;
533 	fheader.dataOffset = 26;
534 	os2header.size = 12;
535 	os2header.width = 5;
536 	os2header.height = 0; // bad value
537 	os2header.planes = 1;
538 	os2header.bitsperpixel = 24;
539 	BMallocIO mallos2height;
540 	CPPUNIT_ASSERT(mallos2height.Write(&fheader.magic, 2) == 2);
541 	CPPUNIT_ASSERT(mallos2height.Write(&fheader.fileSize, 4) == 4);
542 	CPPUNIT_ASSERT(mallos2height.Write(&fheader.reserved, 4) == 4);
543 	CPPUNIT_ASSERT(mallos2height.Write(&fheader.dataOffset, 4) == 4);
544 	CPPUNIT_ASSERT(mallos2height.Write(&os2header, 12) == 12);
545 	CPPUNIT_ASSERT(proster->Identify(&mallos2height, NULL, &ti) == B_NO_TRANSLATOR);
546 
547 	NextSubTest();
548 	fheader.magic = 'MB';
549 	fheader.fileSize = 1028;
550 	fheader.reserved = 0;
551 	fheader.dataOffset = 54;
552 	msheader.size = 40;
553 	msheader.width = 5;
554 	msheader.height = 5;
555 	msheader.planes = 0; // should always be 1
556 	msheader.bitsperpixel = 24;
557 	msheader.compression = BMP_NO_COMPRESS;
558 	msheader.imagesize = 0;
559 	msheader.xpixperm = 23275;
560 	msheader.ypixperm = 23275;
561 	msheader.colorsused = 0;
562 	msheader.colorsimportant = 0;
563 	BMallocIO mallmsplanes;
564 	CPPUNIT_ASSERT(mallmsplanes.Write(&fheader.magic, 2) == 2);
565 	CPPUNIT_ASSERT(mallmsplanes.Write(&fheader.fileSize, 4) == 4);
566 	CPPUNIT_ASSERT(mallmsplanes.Write(&fheader.reserved, 4) == 4);
567 	CPPUNIT_ASSERT(mallmsplanes.Write(&fheader.dataOffset, 4) == 4);
568 	CPPUNIT_ASSERT(mallmsplanes.Write(&msheader, 40) == 40);
569 	CPPUNIT_ASSERT(proster->Identify(&mallmsplanes, NULL, &ti) == B_NO_TRANSLATOR);
570 
571 	NextSubTest();
572 	fheader.magic = 'MB';
573 	fheader.fileSize = 1028;
574 	fheader.reserved = 0;
575 	fheader.dataOffset = 54;
576 	msheader.size = 40;
577 	msheader.width = 5;
578 	msheader.height = 5;
579 	msheader.planes = 2; // should always be 1
580 	msheader.bitsperpixel = 24;
581 	msheader.compression = BMP_NO_COMPRESS;
582 	msheader.imagesize = 0;
583 	msheader.xpixperm = 23275;
584 	msheader.ypixperm = 23275;
585 	msheader.colorsused = 0;
586 	msheader.colorsimportant = 0;
587 	BMallocIO mallmsplanes2;
588 	CPPUNIT_ASSERT(mallmsplanes2.Write(&fheader.magic, 2) == 2);
589 	CPPUNIT_ASSERT(mallmsplanes2.Write(&fheader.fileSize, 4) == 4);
590 	CPPUNIT_ASSERT(mallmsplanes2.Write(&fheader.reserved, 4) == 4);
591 	CPPUNIT_ASSERT(mallmsplanes2.Write(&fheader.dataOffset, 4) == 4);
592 	CPPUNIT_ASSERT(mallmsplanes2.Write(&msheader, 40) == 40);
593 	CPPUNIT_ASSERT(proster->Identify(&mallmsplanes2, NULL, &ti) == B_NO_TRANSLATOR);
594 
595 	NextSubTest();
596 	fheader.magic = 'MB';
597 	fheader.fileSize = 1028;
598 	fheader.reserved = 0;
599 	fheader.dataOffset = 26;
600 	os2header.size = 12;
601 	os2header.width = 5;
602 	os2header.height = 5;
603 	os2header.planes = 0; // should always be 1
604 	os2header.bitsperpixel = 24;
605 	BMallocIO mallos2planes;
606 	CPPUNIT_ASSERT(mallos2planes.Write(&fheader.magic, 2) == 2);
607 	CPPUNIT_ASSERT(mallos2planes.Write(&fheader.fileSize, 4) == 4);
608 	CPPUNIT_ASSERT(mallos2planes.Write(&fheader.reserved, 4) == 4);
609 	CPPUNIT_ASSERT(mallos2planes.Write(&fheader.dataOffset, 4) == 4);
610 	CPPUNIT_ASSERT(mallos2planes.Write(&os2header, 12) == 12);
611 	CPPUNIT_ASSERT(proster->Identify(&mallos2planes, NULL, &ti) == B_NO_TRANSLATOR);
612 
613 	NextSubTest();
614 	fheader.magic = 'MB';
615 	fheader.fileSize = 1028;
616 	fheader.reserved = 0;
617 	fheader.dataOffset = 26;
618 	os2header.size = 12;
619 	os2header.width = 5;
620 	os2header.height = 5;
621 	os2header.planes = 2; // should always be 1
622 	os2header.bitsperpixel = 24;
623 	BMallocIO mallos2planes2;
624 	CPPUNIT_ASSERT(mallos2planes2.Write(&fheader.magic, 2) == 2);
625 	CPPUNIT_ASSERT(mallos2planes2.Write(&fheader.fileSize, 4) == 4);
626 	CPPUNIT_ASSERT(mallos2planes2.Write(&fheader.reserved, 4) == 4);
627 	CPPUNIT_ASSERT(mallos2planes2.Write(&fheader.dataOffset, 4) == 4);
628 	CPPUNIT_ASSERT(mallos2planes2.Write(&os2header, 12) == 12);
629 	CPPUNIT_ASSERT(proster->Identify(&mallos2planes2, NULL, &ti) == B_NO_TRANSLATOR);
630 
631 	// makes sure invalid bit depths aren't recognized
632 	const uint16 bitdepths[] = { 0, 2, 3, 5, 6, 7, 9, 23, 25, 31, 33 };
633 	const int32 knbitdepths = sizeof(bitdepths) / sizeof(uint16);
634 	for (int32 i = 0; i < knbitdepths; i++) {
635 		NextSubTest();
636 		fheader.magic = 'MB';
637 		fheader.fileSize = 1028;
638 		fheader.reserved = 0;
639 		fheader.dataOffset = 54;
640 		msheader.size = 40;
641 		msheader.width = 5;
642 		msheader.height = 5;
643 		msheader.planes = 1;
644 		msheader.bitsperpixel = bitdepths[i];
645 		msheader.compression = BMP_NO_COMPRESS;
646 		msheader.imagesize = 0;
647 		msheader.xpixperm = 23275;
648 		msheader.ypixperm = 23275;
649 		msheader.colorsused = 0;
650 		msheader.colorsimportant = 0;
651 		BMallocIO mallmsbitdepth;
652 		mallmsbitdepth.Seek(0, SEEK_SET);
653 		CPPUNIT_ASSERT(mallmsbitdepth.Write(&fheader.magic, 2) == 2);
654 		CPPUNIT_ASSERT(mallmsbitdepth.Write(&fheader.fileSize, 4) == 4);
655 		CPPUNIT_ASSERT(mallmsbitdepth.Write(&fheader.reserved, 4) == 4);
656 		CPPUNIT_ASSERT(mallmsbitdepth.Write(&fheader.dataOffset, 4) == 4);
657 		CPPUNIT_ASSERT(mallmsbitdepth.Write(&msheader, 40) == 40);
658 		CPPUNIT_ASSERT(proster->Identify(&mallmsbitdepth, NULL, &ti) == B_NO_TRANSLATOR);
659 
660 		NextSubTest();
661 		fheader.magic = 'MB';
662 		fheader.fileSize = 1028;
663 		fheader.reserved = 0;
664 		fheader.dataOffset = 26;
665 		os2header.size = 12;
666 		os2header.width = 5;
667 		os2header.height = 5;
668 		os2header.planes = 1;
669 		os2header.bitsperpixel = bitdepths[i];
670 		BMallocIO mallos2bitdepth;
671 		mallos2bitdepth.Seek(0, SEEK_SET);
672 		CPPUNIT_ASSERT(mallos2bitdepth.Write(&fheader.magic, 2) == 2);
673 		CPPUNIT_ASSERT(mallos2bitdepth.Write(&fheader.fileSize, 4) == 4);
674 		CPPUNIT_ASSERT(mallos2bitdepth.Write(&fheader.reserved, 4) == 4);
675 		CPPUNIT_ASSERT(mallos2bitdepth.Write(&fheader.dataOffset, 4) == 4);
676 		CPPUNIT_ASSERT(mallos2bitdepth.Write(&os2header, 12) == 12);
677 		CPPUNIT_ASSERT(proster->Identify(&mallos2bitdepth, NULL, &ti) == B_NO_TRANSLATOR);
678 	}
679 
680 	// makes sure invalid compression values aren't recognized
681 	const uint16 cbitdepths[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 23, 24, 25, 31, 32, 33 };
682 	const uint32 compvalues[] = { BMP_RLE4_COMPRESS, BMP_RLE8_COMPRESS, 3, 4, 5, 10 };
683 	const int32 kncdepths = sizeof(cbitdepths) / sizeof(uint16);
684 	const int32 kncomps = sizeof(compvalues) / sizeof(uint32);
685 	for (int32 i = 0; i < kncomps; i++)
686 		for (int32 n = 0; n < kncdepths; n++) {
687 			if (!(compvalues[i] == BMP_RLE4_COMPRESS && cbitdepths[n] == 4) &&
688 				!(compvalues[i] == BMP_RLE8_COMPRESS && cbitdepths[n] == 8)) {
689 				NextSubTest();
690 				fheader.magic = 'MB';
691 				fheader.fileSize = 1028;
692 				fheader.reserved = 0;
693 				fheader.dataOffset = 54;
694 				msheader.size = 40;
695 				msheader.width = 5;
696 				msheader.height = 5;
697 				msheader.planes = 1;
698 				msheader.bitsperpixel = cbitdepths[n];
699 				msheader.compression = compvalues[i];
700 				msheader.imagesize = 0;
701 				msheader.xpixperm = 23275;
702 				msheader.ypixperm = 23275;
703 				msheader.colorsused = 0;
704 				msheader.colorsimportant = 0;
705 				BMallocIO mallmscomp;
706 				mallmscomp.Seek(0, SEEK_SET);
707 				CPPUNIT_ASSERT(mallmscomp.Write(&fheader.magic, 2) == 2);
708 				CPPUNIT_ASSERT(mallmscomp.Write(&fheader.fileSize, 4) == 4);
709 				CPPUNIT_ASSERT(mallmscomp.Write(&fheader.reserved, 4) == 4);
710 				CPPUNIT_ASSERT(mallmscomp.Write(&fheader.dataOffset, 4) == 4);
711 				CPPUNIT_ASSERT(mallmscomp.Write(&msheader, 40) == 40);
712 				CPPUNIT_ASSERT(proster->Identify(&mallmscomp, NULL, &ti)
713 					== B_NO_TRANSLATOR);
714 			}
715 		}
716 
717 	// too many colorsused test!
718 	const uint16 colordepths[] = { 1, 4, 8, 24, 32 };
719 	const int32 kncolordepths = sizeof(colordepths) / sizeof(uint16);
720 	for (int32 i = 0; i < kncolordepths; i++) {
721 		NextSubTest();
722 		fheader.magic = 'BM';
723 		fheader.fileSize = 1028;
724 		fheader.reserved = 0;
725 		fheader.dataOffset = 54;
726 		msheader.size = 40;
727 		msheader.width = 5;
728 		msheader.height = 5;
729 		msheader.planes = 1;
730 		msheader.bitsperpixel = colordepths[i];
731 		msheader.compression = BMP_NO_COMPRESS;
732 		msheader.imagesize = 0;
733 		msheader.xpixperm = 23275;
734 		msheader.ypixperm = 23275;
735 		msheader.colorsused = 0; //(1 << colordepths[i])/* + 1*/;
736 		msheader.colorsimportant = 0; //(1 << colordepths[i])/* + 1*/;
737 		BMallocIO mallmscolors;
738 		mallmscolors.Seek(0, SEEK_SET);
739 		CPPUNIT_ASSERT(mallmscolors.Write(&fheader.magic, 2) == 2);
740 		CPPUNIT_ASSERT(mallmscolors.Write(&fheader.fileSize, 4) == 4);
741 		CPPUNIT_ASSERT(mallmscolors.Write(&fheader.reserved, 4) == 4);
742 		CPPUNIT_ASSERT(mallmscolors.Write(&fheader.dataOffset, 4) == 4);
743 		CPPUNIT_ASSERT(mallmscolors.Write(&msheader, 40) == 40);
744 		CPPUNIT_ASSERT(proster->Identify(&mallmscolors, NULL, &ti) == B_NO_TRANSLATOR);
745 	}
746 
747 	// Identify (successfully identify the following files)
748 	const IdentifyInfo aBitsPaths[] = {
749 		{ "/boot/home/resources/bmp/b_cmap8.bits", "" },
750 		{ "/boot/home/resources/bmp/b_gray1-2.bits", "" },
751 		{ "/boot/home/resources/bmp/b_gray1.bits", "" },
752 		{ "/boot/home/resources/bmp/b_rgb15.bits", "" },
753 		{ "/boot/home/resources/bmp/b_rgb16.bits", "" },
754 		{ "/boot/home/resources/bmp/b_rgb32.bits", "" },
755 		{ "/boot/home/resources/bmp/blocks.bits", "" },
756 		{ "/boot/home/resources/bmp/gnome_beer.bits", "" },
757 		{ "/boot/home/resources/bmp/vsmall.bits", "" }
758 	};
759 	const IdentifyInfo aBmpPaths[] = {
760 		{ "/boot/home/resources/bmp/blocks_24bit.bmp",
761 			"BMP image (MS format, 24 bits)" },
762 		{ "/boot/home/resources/bmp/blocks_4bit_rle.bmp",
763 			"BMP image (MS format, 4 bits, RLE)" },
764 		{ "/boot/home/resources/bmp/blocks_8bit_rle.bmp",
765 			"BMP image (MS format, 8 bits, RLE)" },
766 		{ "/boot/home/resources/bmp/color_scribbles_1bit.bmp",
767 			"BMP image (MS format, 1 bits)" },
768 		{ "/boot/home/resources/bmp/color_scribbles_1bit_os2.bmp",
769 			"BMP image (OS/2 format, 1 bits)" },
770 		{ "/boot/home/resources/bmp/color_scribbles_24bit.bmp",
771 			"BMP image (MS format, 24 bits)" },
772 		{ "/boot/home/resources/bmp/color_scribbles_24bit_os2.bmp",
773 			"BMP image (OS/2 format, 24 bits)" },
774 		{ "/boot/home/resources/bmp/color_scribbles_4bit.bmp",
775 			"BMP image (MS format, 4 bits)" },
776 		{ "/boot/home/resources/bmp/color_scribbles_4bit_os2.bmp",
777 			"BMP image (OS/2 format, 4 bits)" },
778 		{ "/boot/home/resources/bmp/color_scribbles_4bit_rle.bmp",
779 			"BMP image (MS format, 4 bits, RLE)" },
780 		{ "/boot/home/resources/bmp/color_scribbles_8bit.bmp",
781 			"BMP image (MS format, 8 bits)" },
782 		{ "/boot/home/resources/bmp/color_scribbles_8bit_os2.bmp",
783 			"BMP image (OS/2 format, 8 bits)" },
784 		{ "/boot/home/resources/bmp/color_scribbles_8bit_rle.bmp",
785 			"BMP image (MS format, 8 bits, RLE)" },
786 		{ "/boot/home/resources/bmp/gnome_beer_24bit.bmp",
787 			"BMP image (MS format, 24 bits)" },
788 		{ "/boot/home/resources/bmp/vsmall_1bit.bmp",
789 			"BMP image (MS format, 1 bits)" },
790 		{ "/boot/home/resources/bmp/vsmall_1bit_os2.bmp",
791 			"BMP image (OS/2 format, 1 bits)" },
792 		{ "/boot/home/resources/bmp/vsmall_24bit.bmp",
793 			"BMP image (MS format, 24 bits)" },
794 		{ "/boot/home/resources/bmp/vsmall_24bit_os2.bmp",
795 			"BMP image (OS/2 format, 24 bits)" },
796 		{ "/boot/home/resources/bmp/vsmall_4bit.bmp",
797 			"BMP image (MS format, 4 bits)" },
798 		{ "/boot/home/resources/bmp/vsmall_4bit_os2.bmp",
799 			"BMP image (OS/2 format, 4 bits)" },
800 		{ "/boot/home/resources/bmp/vsmall_4bit_rle.bmp",
801 			"BMP image (MS format, 4 bits, RLE)" },
802 		{ "/boot/home/resources/bmp/vsmall_8bit.bmp",
803 			"BMP image (MS format, 8 bits)" },
804 		{ "/boot/home/resources/bmp/vsmall_8bit_os2.bmp",
805 			"BMP image (OS/2 format, 8 bits)" },
806 		{ "/boot/home/resources/bmp/vsmall_8bit_rle.bmp",
807 			"BMP image (MS format, 8 bits, RLE)" },
808 		{ "/boot/home/resources/bmp/b_rgb32(32).bmp",
809 			"BMP image (MS format, 32 bits)" }
810 	};
811 
812 	IdentifyTests(this, proster, aBmpPaths,
813 		sizeof(aBmpPaths) / sizeof(IdentifyInfo), false);
814 	IdentifyTests(this, proster, aBitsPaths,
815 		sizeof(aBitsPaths) / sizeof(IdentifyInfo), true);
816 
817 	delete proster;
818 	proster = NULL;
819 }
820 
821 // coveniently group path of bmp image with
822 // path of bits image that it should translate to
823 struct TranslatePaths {
824 	const char *bmpPath;
825 	const char *bitsPath;
826 };
827 
828 void
829 TranslateTests(BMPTranslatorTest *ptest, BTranslatorRoster *proster,
830 	const TranslatePaths *paths, int32 len, bool bbmpinput)
831 {
832 	// Perform translations on every file in the array
833 	for (int32 i = 0; i < len; i++) {
834 		// Setup input files
835 		ptest->NextSubTest();
836 		BFile bmpfile, bitsfile, *pinput;
837 		CPPUNIT_ASSERT(bmpfile.SetTo(paths[i].bmpPath, B_READ_ONLY) == B_OK);
838 		CPPUNIT_ASSERT(bitsfile.SetTo(paths[i].bitsPath, B_READ_ONLY) == B_OK);
839 		if (bbmpinput) {
840 			printf(" [%s] ", paths[i].bmpPath);
841 			pinput = &bmpfile;
842 		} else {
843 			printf(" [%s] ", paths[i].bitsPath);
844 			pinput = &bitsfile;
845 		}
846 
847 		BMallocIO mallio, dmallio;
848 
849 		// Convert to B_TRANSLATOR_ANY_TYPE (should be B_TRANSLATOR_BITMAP)
850 		ptest->NextSubTest();
851 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
852 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
853 		CPPUNIT_ASSERT(proster->Translate(pinput, NULL, NULL, &mallio,
854 			B_TRANSLATOR_ANY_TYPE) == B_OK);
855 		CPPUNIT_ASSERT(CompareStreams(mallio, bitsfile) == true);
856 
857 		// Convert to B_TRANSLATOR_BITMAP
858 		ptest->NextSubTest();
859 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
860 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
861 		CPPUNIT_ASSERT(proster->Translate(pinput, NULL, NULL, &mallio,
862 			B_TRANSLATOR_BITMAP) == B_OK);
863 		CPPUNIT_ASSERT(CompareStreams(mallio, bitsfile) == true);
864 
865 		// Convert bits mallio to B_TRANSLATOR_BITMAP dmallio
866 		ptest->NextSubTest();
867 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
868 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
869 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
870 			B_TRANSLATOR_BITMAP) == B_OK);
871 		CPPUNIT_ASSERT(CompareStreams(dmallio, bitsfile) == true);
872 
873 		// Only perform the following tests if the BMP is not
874 		// an OS/2 format BMP image.
875 		// (Need to write special testing for OS/2 images)
876 		if (!strstr(paths[i].bmpPath, "os2")) {
877 			// Convert to B_BMP_FORMAT
878 			ptest->NextSubTest();
879 			CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
880 			CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
881 			CPPUNIT_ASSERT(proster->Translate(pinput, NULL, NULL, &mallio,
882 				B_BMP_FORMAT) == B_OK);
883 			CPPUNIT_ASSERT(CompareStreams(mallio, bmpfile) == true);
884 
885 			// Convert BMP mallio to B_TRANSLATOR_BITMAP dmallio
886 			if (bbmpinput) {
887 				ptest->NextSubTest();
888 				CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
889 				CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
890 				CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
891 					B_TRANSLATOR_BITMAP) == B_OK);
892 				CPPUNIT_ASSERT(CompareStreams(dmallio, bitsfile) == true);
893 			}
894 
895 			// Convert BMP mallio to B_BMP_FORMAT dmallio
896 			ptest->NextSubTest();
897 			CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
898 			CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
899 			CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
900 				B_BMP_FORMAT) == B_OK);
901 			CPPUNIT_ASSERT(CompareStreams(dmallio, bmpfile) == true);
902 		}
903 	}
904 }
905 
906 void
907 BMPTranslatorTest::TranslateTest()
908 {
909 	BApplication
910 		app("application/x-vnd.OpenBeOS-BMPTranslatorTest");
911 
912 	// Init
913 	NextSubTest();
914 	status_t result = B_ERROR;
915 	off_t filesize = -1;
916 	BTranslatorRoster *proster = new BTranslatorRoster();
917 	CPPUNIT_ASSERT(proster);
918 	CPPUNIT_ASSERT(proster->AddTranslators(
919 		"/boot/home/config/add-ons/Translators/BMPTranslator") == B_OK);
920 	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
921 		B_READ_ONLY);
922 	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
923 	BFile output("/tmp/bmp_test.out", B_WRITE_ONLY |
924 		B_CREATE_FILE | B_ERASE_FILE);
925 	CPPUNIT_ASSERT(output.InitCheck() == B_OK);
926 
927 	// Translate (bad input, output types)
928 	NextSubTest();
929 	result = proster->Translate(&wronginput, NULL, NULL, &output,
930 		B_TRANSLATOR_TEXT);
931 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
932 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
933 	CPPUNIT_ASSERT(filesize == 0);
934 
935 	// Translate (wrong type of input data)
936 	NextSubTest();
937 	result = proster->Translate(&wronginput, NULL, NULL, &output,
938 		B_BMP_FORMAT);
939 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
940 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
941 	CPPUNIT_ASSERT(filesize == 0);
942 
943 	// Translate (wrong type of input, B_TRANSLATOR_ANY_TYPE output)
944 	NextSubTest();
945 	result = proster->Translate(&wronginput, NULL, NULL, &output,
946 		B_TRANSLATOR_ANY_TYPE);
947 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
948 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
949 	CPPUNIT_ASSERT(filesize == 0);
950 
951 	// For translating BMP images to bits
952 	const TranslatePaths aBmpInput[] = {
953 		{ "/boot/home/resources/bmp/blocks_24bit.bmp",
954 			"/boot/home/resources/bmp/blocks.bits" },
955 		{ "/boot/home/resources/bmp/blocks_4bit_rle.bmp",
956 			"/boot/home/resources/bmp/blocks.bits" },
957 		{ "/boot/home/resources/bmp/blocks_8bit_rle.bmp",
958 			"/boot/home/resources/bmp/blocks.bits" },
959 		{ "/boot/home/resources/bmp/color_scribbles_1bit.bmp",
960 			"/boot/home/resources/bmp/color_scribbles_1bit.bits" },
961 		{ "/boot/home/resources/bmp/color_scribbles_1bit_os2.bmp",
962 			"/boot/home/resources/bmp/color_scribbles_1bit.bits" },
963 		{ "/boot/home/resources/bmp/color_scribbles_24bit.bmp",
964 			"/boot/home/resources/bmp/color_scribbles_24bit.bits" },
965 		{ "/boot/home/resources/bmp/color_scribbles_24bit_os2.bmp",
966 			"/boot/home/resources/bmp/color_scribbles_24bit.bits" },
967 		{ "/boot/home/resources/bmp/color_scribbles_4bit.bmp",
968 			"/boot/home/resources/bmp/color_scribbles_24bit.bits" },
969 		{ "/boot/home/resources/bmp/color_scribbles_4bit_os2.bmp",
970 			"/boot/home/resources/bmp/color_scribbles_24bit.bits" },
971 		{ "/boot/home/resources/bmp/color_scribbles_4bit_rle.bmp",
972 			"/boot/home/resources/bmp/color_scribbles_4bit_rle.bits" },
973 		{ "/boot/home/resources/bmp/color_scribbles_8bit.bmp",
974 			"/boot/home/resources/bmp/color_scribbles_24bit.bits" },
975 		{ "/boot/home/resources/bmp/color_scribbles_8bit_os2.bmp",
976 			"/boot/home/resources/bmp/color_scribbles_24bit.bits" },
977 		{ "/boot/home/resources/bmp/color_scribbles_8bit_rle.bmp",
978 			"/boot/home/resources/bmp/color_scribbles_24bit.bits" },
979 		{ "/boot/home/resources/bmp/gnome_beer_24bit.bmp",
980 			"/boot/home/resources/bmp/gnome_beer.bits" },
981 		{ "/boot/home/resources/bmp/vsmall_1bit.bmp",
982 			"/boot/home/resources/bmp/vsmall.bits" },
983 		{ "/boot/home/resources/bmp/vsmall_1bit_os2.bmp",
984 			"/boot/home/resources/bmp/vsmall.bits" },
985 		{ "/boot/home/resources/bmp/vsmall_24bit.bmp",
986 			"/boot/home/resources/bmp/vsmall.bits" },
987 		{ "/boot/home/resources/bmp/vsmall_24bit_os2.bmp",
988 			"/boot/home/resources/bmp/vsmall.bits" },
989 		{ "/boot/home/resources/bmp/vsmall_4bit.bmp",
990 			"/boot/home/resources/bmp/vsmall.bits" },
991 		{ "/boot/home/resources/bmp/vsmall_4bit_os2.bmp",
992 			"/boot/home/resources/bmp/vsmall.bits" },
993 		{ "/boot/home/resources/bmp/vsmall_4bit_rle.bmp",
994 			"/boot/home/resources/bmp/vsmall.bits" },
995 		{ "/boot/home/resources/bmp/vsmall_8bit.bmp",
996 			"/boot/home/resources/bmp/vsmall.bits" },
997 		{ "/boot/home/resources/bmp/vsmall_8bit_os2.bmp",
998 			"/boot/home/resources/bmp/vsmall.bits" },
999 		{ "/boot/home/resources/bmp/vsmall_8bit_rle.bmp",
1000 			"/boot/home/resources/bmp/vsmall.bits" },
1001 		{ "/boot/home/resources/bmp/b_rgb32(32).bmp",
1002 			"/boot/home/resources/bmp/b_rgb32.bits" }
1003 	};
1004 
1005 	// For translating bits images to BMP
1006 	const TranslatePaths aBitsInput[] = {
1007 		{ "/boot/home/resources/bmp/b_gray1-2.bmp",
1008 			"/boot/home/resources/bmp/b_gray1-2.bits" },
1009 		{ "/boot/home/resources/bmp/b_gray1.bmp",
1010 			"/boot/home/resources/bmp/b_gray1.bits" },
1011 		{ "/boot/home/resources/bmp/b_rgb15.bmp",
1012 			"/boot/home/resources/bmp/b_rgb15.bits" },
1013 		{ "/boot/home/resources/bmp/b_rgb16.bmp",
1014 			"/boot/home/resources/bmp/b_rgb16.bits" },
1015 		{ "/boot/home/resources/bmp/b_rgb32(24).bmp",
1016 			"/boot/home/resources/bmp/b_rgb32.bits" },
1017 		{ "/boot/home/resources/bmp/b_cmap8.bmp",
1018 			"/boot/home/resources/bmp/b_cmap8.bits" }
1019 	};
1020 
1021 	TranslateTests(this, proster, aBmpInput,
1022 		sizeof(aBmpInput) / sizeof(TranslatePaths), true);
1023 	TranslateTests(this, proster, aBitsInput,
1024 		sizeof(aBitsInput) / sizeof(TranslatePaths), false);
1025 
1026 	delete proster;
1027 	proster = NULL;
1028 }
1029 
1030 // Make certain that the BMPTranslator does not
1031 // provide a configuration message
1032 void
1033 BMPTranslatorTest::ConfigMessageTest()
1034 {
1035 	// Init
1036 	NextSubTest();
1037 	status_t result = B_ERROR;
1038 	BTranslatorRoster *proster = new BTranslatorRoster();
1039 	CPPUNIT_ASSERT(proster);
1040 	CPPUNIT_ASSERT(proster->AddTranslators(
1041 		"/boot/home/config/add-ons/Translators/BMPTranslator") == B_OK);
1042 
1043 	// GetAllTranslators
1044 	NextSubTest();
1045 	translator_id tid, *pids = NULL;
1046 	int32 count = 0;
1047 	CPPUNIT_ASSERT(proster->GetAllTranslators(&pids, &count) == B_OK);
1048 	CPPUNIT_ASSERT(pids);
1049 	CPPUNIT_ASSERT(count == 1);
1050 	tid = pids[0];
1051 	delete[] pids;
1052 	pids = NULL;
1053 
1054 	// GetConfigurationMessage
1055 	NextSubTest();
1056 	BMessage msg;
1057 	CPPUNIT_ASSERT(proster->GetConfigurationMessage(tid, &msg) == B_ERROR);
1058 	CPPUNIT_ASSERT(msg.IsEmpty());
1059 }
1060 
1061 #if !TEST_R5
1062 
1063 // The input formats that this translator is supposed to support
1064 translation_format gBMPInputFormats[] = {
1065 	{
1066 		B_TRANSLATOR_BITMAP,
1067 		B_TRANSLATOR_BITMAP,
1068 		0.6f, // quality
1069 		0.8f, // capability
1070 		"image/x-be-bitmap",
1071 		"Be Bitmap Format (BMPTranslator)"
1072 	},
1073 	{
1074 		B_BMP_FORMAT,
1075 		B_TRANSLATOR_BITMAP,
1076 		1.0f,
1077 		0.8f,
1078 		"image/x-bmp",
1079 		"BMP image"
1080 	}
1081 };
1082 
1083 // The output formats that this translator is supposed to support
1084 translation_format gBMPOutputFormats[] = {
1085 	{
1086 		B_TRANSLATOR_BITMAP,
1087 		B_TRANSLATOR_BITMAP,
1088 		0.6f, // quality
1089 		0.8f, // capability
1090 		"image/x-be-bitmap",
1091 		"Be Bitmap Format (BMPTranslator)"
1092 	},
1093 	{
1094 		B_BMP_FORMAT,
1095 		B_TRANSLATOR_BITMAP,
1096 		1.0f,
1097 		0.5f,
1098 		"image/x-bmp",
1099 		"BMP image (MS format)"
1100 	}
1101 };
1102 
1103 void
1104 BMPTranslatorTest::LoadAddOnTest()
1105 {
1106 	TranslatorLoadAddOnTest("/boot/home/config/add-ons/Translators/BMPTranslator",
1107 		this,
1108 		gBMPInputFormats, sizeof(gBMPInputFormats) / sizeof(translation_format),
1109 		gBMPOutputFormats, sizeof(gBMPOutputFormats) / sizeof(translation_format));
1110 }
1111 
1112 #endif // #if !TEST_R5
1113