xref: /haiku/src/tests/add-ons/translators/pngtranslator/PNGTranslatorTest.cpp (revision dfb8c585c62977839ef1b23d60b197227de81231)
1 // PNGTranslatorTest.cpp
2 //
3 // NOTE: Most of the PNG images used in this test are from PNGSuite:
4 // http://www.schaik.com/pngsuite/pngsuite.html
5 #include "PNGTranslatorTest.h"
6 #include <cppunit/Test.h>
7 #include <cppunit/TestCaller.h>
8 #include <cppunit/TestSuite.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <image.h>
13 #include <Translator.h>
14 #include <TranslatorFormats.h>
15 #include <TranslatorRoster.h>
16 #include <Message.h>
17 #include <View.h>
18 #include <Rect.h>
19 #include <String.h>
20 #include <File.h>
21 #include <DataIO.h>
22 #include <Errors.h>
23 #include <OS.h>
24 #include "TranslatorTestAddOn.h"
25 
26 // PNG Translator Settings
27 #define PNG_SETTING_INTERLACE "png /interlace"
28 
29 #define PNG_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1,0,0)
30 
31 #define PNG_IN_QUALITY 0.8
32 #define PNG_IN_CAPABILITY 0.8
33 #define PNG_OUT_QUALITY 0.8
34 #define PNG_OUT_CAPABILITY 0.5
35 
36 #define BBT_IN_QUALITY 0.8
37 #define BBT_IN_CAPABILITY 0.6
38 #define BBT_OUT_QUALITY 0.5
39 #define BBT_OUT_CAPABILITY 0.4
40 
41 // Test Images Directory
42 #define IMAGES_DIR "/boot/home/resources/png/"
43 
44 // Suite
45 CppUnit::Test *
Suite()46 PNGTranslatorTest::Suite()
47 {
48 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
49 	typedef CppUnit::TestCaller<PNGTranslatorTest> TC;
50 
51 	suite->addTest(
52 		new TC("PNGTranslator IdentifyTest",
53 			&PNGTranslatorTest::IdentifyTest));
54 
55 	suite->addTest(
56 		new TC("PNGTranslator TranslateTest",
57 			&PNGTranslatorTest::TranslateTest));
58 
59 #if !TEST_R5
60 	suite->addTest(
61 		new TC("PNGTranslator LoadAddOnTest",
62 			&PNGTranslatorTest::LoadAddOnTest));
63 #endif
64 
65 	return suite;
66 }
67 
68 // setUp
69 void
setUp()70 PNGTranslatorTest::setUp()
71 {
72 	BTestCase::setUp();
73 }
74 
75 // tearDown
76 void
tearDown()77 PNGTranslatorTest::tearDown()
78 {
79 	BTestCase::tearDown();
80 }
81 
82 void
CheckBits_PNG(translator_info * pti)83 CheckBits_PNG(translator_info *pti)
84 {
85 	CheckTranslatorInfo(pti, B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP,
86 		BBT_IN_QUALITY, BBT_IN_CAPABILITY, "Be Bitmap Format (PNGTranslator)",
87 		"image/x-be-bitmap");
88 }
89 
90 void
CheckPNG(translator_info * pti)91 CheckPNG(translator_info *pti)
92 {
93 	CheckTranslatorInfo(pti, B_PNG_FORMAT, B_TRANSLATOR_BITMAP,
94 		PNG_IN_QUALITY, PNG_IN_CAPABILITY, "PNG image", "image/png");
95 }
96 
97 void
IdentifyTests(PNGTranslatorTest * ptest,BTranslatorRoster * proster,const char ** paths,int32 len,bool bbits)98 IdentifyTests(PNGTranslatorTest *ptest, BTranslatorRoster *proster,
99 	const char **paths, int32 len, bool bbits)
100 {
101 	translator_info ti;
102 	printf(" [%d] ", (int) bbits);
103 
104 	BString fullpath;
105 
106 	for (int32 i = 0; i < len; i++) {
107 		ptest->NextSubTest();
108 		BFile file;
109 		fullpath = IMAGES_DIR;
110 		fullpath += paths[i];
111 		printf(" [%s] ", fullpath.String());
112 		CPPUNIT_ASSERT(file.SetTo(fullpath.String(), B_READ_ONLY) == B_OK);
113 
114 		// Identify (output: B_TRANSLATOR_ANY_TYPE)
115 		ptest->NextSubTest();
116 		memset(&ti, 0, sizeof(translator_info));
117 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti) == B_OK);
118 		if (bbits)
119 			CheckBits_PNG(&ti);
120 		else
121 			CheckPNG(&ti);
122 
123 		// Identify (output: B_TRANSLATOR_BITMAP)
124 		ptest->NextSubTest();
125 		memset(&ti, 0, sizeof(translator_info));
126 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
127 			B_TRANSLATOR_BITMAP) == B_OK);
128 		if (bbits)
129 			CheckBits_PNG(&ti);
130 		else
131 			CheckPNG(&ti);
132 
133 		// Identify (output: B_PNG_FORMAT)
134 		ptest->NextSubTest();
135 		memset(&ti, 0, sizeof(translator_info));
136 		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
137 			B_PNG_FORMAT) == B_OK);
138 		if (bbits)
139 			CheckBits_PNG(&ti);
140 		else
141 			CheckPNG(&ti);
142 	}
143 }
144 
145 void
IdentifyTest()146 PNGTranslatorTest::IdentifyTest()
147 {
148 	// Init
149 	NextSubTest();
150 	status_t result = B_ERROR;
151 	BTranslatorRoster *proster = new BTranslatorRoster();
152 	CPPUNIT_ASSERT(proster);
153 	CPPUNIT_ASSERT(proster->AddTranslators(
154 		"/boot/home/config/add-ons/Translators/PNGTranslator") == B_OK);
155 	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
156 		B_READ_ONLY);
157 	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
158 
159 	// Identify (bad input, output types)
160 	NextSubTest();
161 	translator_info ti;
162 	memset(&ti, 0, sizeof(translator_info));
163 	result = proster->Identify(&wronginput, NULL, &ti, 0,
164 		NULL, B_TRANSLATOR_TEXT);
165 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
166 	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
167 
168 	// Identify (wrong type of input data)
169 	NextSubTest();
170 	memset(&ti, 0, sizeof(translator_info));
171 	result = proster->Identify(&wronginput, NULL, &ti);
172 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
173 	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
174 
175 	// Identify (bad PNG signature)
176 	NextSubTest();
177 	memset(&ti, 0, sizeof(translator_info));
178 	BFile badsig1(IMAGES_DIR "xlfn0g04.png", B_READ_ONLY);
179 	CPPUNIT_ASSERT(badsig1.InitCheck() == B_OK);
180 	result = proster->Identify(&badsig1, NULL, &ti);
181 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
182 	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
183 
184 	// Identify (bad PNG signature)
185 	NextSubTest();
186 	memset(&ti, 0, sizeof(translator_info));
187 	BFile badsig2(IMAGES_DIR "/xcrn0g04.png", B_READ_ONLY);
188 	CPPUNIT_ASSERT(badsig2.InitCheck() == B_OK);
189 	result = proster->Identify(&badsig2, NULL, &ti);
190 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
191 	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
192 
193 	// Identify (successfully identify the following files)
194 	const char * aBitsPaths[] = {
195 		"beer.bits",
196 		"blocks.bits"
197 	};
198 	const char * aPNGPaths[] = {
199 		"basi0g01.png",
200 		"basi0g02.png",
201 		"basn0g01.png",
202 		"basn0g04.png",
203 		"basi0g16.png",
204 		"basi4a08.png",
205 		"basn0g08.png",
206 		"basi4a16.png",
207 		"tp1n3p08.png",
208 		"tp0n2c08.png",
209 		"tbgn2c16.png",
210 		"s39i3p04.png",
211 		"basi6a08.png",
212 		"basi6a16.png",
213 		"basn6a08.png",
214 		"basi3p01.png",
215 		"basn3p02.png"
216 	};
217 
218 	IdentifyTests(this, proster, aPNGPaths,
219 		sizeof(aPNGPaths) / sizeof(const char *), false);
220 	IdentifyTests(this, proster, aBitsPaths,
221 		sizeof(aBitsPaths) / sizeof(const char *), true);
222 
223 	delete proster;
224 	proster = NULL;
225 }
226 
227 // coveniently group path of PNG image with
228 // path of bits image that it should translate to
229 struct TranslatePaths {
230 	const char *pngPath;
231 	const char *bitsPath;
232 };
233 
234 void
TranslateTests(PNGTranslatorTest * ptest,BTranslatorRoster * proster,const TranslatePaths * paths,int32 len)235 TranslateTests(PNGTranslatorTest *ptest, BTranslatorRoster *proster,
236 	const TranslatePaths *paths, int32 len)
237 {
238 	BString png_fpath, bits_fpath;
239 
240 	// Perform translations on every file in the array
241 	for (int32 i = 0; i < len; i++) {
242 		// Setup input files
243 		ptest->NextSubTest();
244 		png_fpath = bits_fpath = IMAGES_DIR;
245 		png_fpath += paths[i].pngPath;
246 		bits_fpath += paths[i].bitsPath;
247 		BFile png_file, bits_file;
248 		CPPUNIT_ASSERT(png_file.SetTo(png_fpath.String(), B_READ_ONLY) == B_OK);
249 		CPPUNIT_ASSERT(bits_file.SetTo(bits_fpath.String(), B_READ_ONLY) == B_OK);
250 		printf(" [%s] ", png_fpath.String());
251 
252 		BMallocIO mallio, dmallio;
253 
254 		// Convert to B_TRANSLATOR_ANY_TYPE (should be B_TRANSLATOR_BITMAP)
255 		ptest->NextSubTest();
256 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
257 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
258 		CPPUNIT_ASSERT(proster->Translate(&png_file, NULL, NULL, &mallio,
259 			B_TRANSLATOR_ANY_TYPE) == B_OK);
260 		CPPUNIT_ASSERT(CompareStreams(mallio, bits_file) == true);
261 
262 		// Convert to B_TRANSLATOR_BITMAP
263 		ptest->NextSubTest();
264 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
265 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
266 		CPPUNIT_ASSERT(proster->Translate(&png_file, NULL, NULL, &mallio,
267 			B_TRANSLATOR_BITMAP) == B_OK);
268 		CPPUNIT_ASSERT(CompareStreams(mallio, bits_file) == true);
269 
270 		// Convert bits mallio to B_TRANSLATOR_BITMAP dmallio
271 		ptest->NextSubTest();
272 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
273 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
274 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
275 			B_TRANSLATOR_BITMAP) == B_OK);
276 		CPPUNIT_ASSERT(CompareStreams(dmallio, bits_file) == true);
277 
278 		// Convert to B_PNG_FORMAT
279 		ptest->NextSubTest();
280 		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
281 		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
282 		CPPUNIT_ASSERT(proster->Translate(&png_file, NULL, NULL, &mallio,
283 			B_PNG_FORMAT) == B_OK);
284 		CPPUNIT_ASSERT(CompareStreams(mallio, png_file) == true);
285 
286 		// Convert PNG mallio to B_TRANSLATOR_BITMAP dmallio
287 		ptest->NextSubTest();
288 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
289 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
290 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
291 			B_TRANSLATOR_BITMAP) == B_OK);
292 		CPPUNIT_ASSERT(CompareStreams(dmallio, bits_file) == true);
293 
294 		// Convert PNG mallio to B_PNG_FORMAT dmallio
295 		ptest->NextSubTest();
296 		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
297 		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
298 		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
299 			B_PNG_FORMAT) == B_OK);
300 		CPPUNIT_ASSERT(CompareStreams(dmallio, png_file) == true);
301 	}
302 }
303 
304 void
TranslateTest()305 PNGTranslatorTest::TranslateTest()
306 {
307 	// Init
308 	NextSubTest();
309 	status_t result = B_ERROR;
310 	off_t filesize = -1;
311 	BTranslatorRoster *proster = new BTranslatorRoster();
312 	CPPUNIT_ASSERT(proster);
313 	CPPUNIT_ASSERT(proster->AddTranslators(
314 		"/boot/home/config/add-ons/Translators/PNGTranslator") == B_OK);
315 	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
316 		B_READ_ONLY);
317 	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
318 	BFile output("/tmp/png_test.out", B_WRITE_ONLY |
319 		B_CREATE_FILE | B_ERASE_FILE);
320 	CPPUNIT_ASSERT(output.InitCheck() == B_OK);
321 
322 	// Translate (bad input, output types)
323 	NextSubTest();
324 	result = proster->Translate(&wronginput, NULL, NULL, &output,
325 		B_TRANSLATOR_TEXT);
326 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
327 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
328 	CPPUNIT_ASSERT(filesize == 0);
329 
330 	// Translate (wrong type of input data)
331 	NextSubTest();
332 	result = proster->Translate(&wronginput, NULL, NULL, &output,
333 		B_PNG_FORMAT);
334 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
335 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
336 	CPPUNIT_ASSERT(filesize == 0);
337 
338 	// Translate (wrong type of input, B_TRANSLATOR_ANY_TYPE output)
339 	NextSubTest();
340 	result = proster->Translate(&wronginput, NULL, NULL, &output,
341 		B_TRANSLATOR_ANY_TYPE);
342 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
343 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
344 	CPPUNIT_ASSERT(filesize == 0);
345 
346 	// Translate (bad PNG signature)
347 	NextSubTest();
348 	BFile badsig1(IMAGES_DIR "xlfn0g04.png", B_READ_ONLY);
349 	CPPUNIT_ASSERT(badsig1.InitCheck() == B_OK);
350 	result = proster->Translate(&badsig1, NULL, NULL, &output,
351 		B_TRANSLATOR_ANY_TYPE);
352 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
353 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
354 	CPPUNIT_ASSERT(filesize == 0);
355 
356 	// Translate (bad PNG signature)
357 	NextSubTest();
358 	BFile badsig2(IMAGES_DIR "xcrn0g04.png", B_READ_ONLY);
359 	CPPUNIT_ASSERT(badsig2.InitCheck() == B_OK);
360 	result = proster->Translate(&badsig2, NULL, NULL, &output,
361 		B_TRANSLATOR_ANY_TYPE);
362 	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
363 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
364 	CPPUNIT_ASSERT(filesize == 0);
365 
366 	// Translate (bad width)
367 	NextSubTest();
368 	BFile badw(IMAGES_DIR "x00n0g01.png", B_READ_ONLY);
369 	CPPUNIT_ASSERT(badw.InitCheck() == B_OK);
370 	result = proster->Translate(&badw, NULL, NULL, &output,
371 		B_TRANSLATOR_ANY_TYPE);
372 	CPPUNIT_ASSERT(result == B_ERROR);
373 	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
374 	CPPUNIT_ASSERT(filesize == 0);
375 
376 	// Translate PNG images to bits
377 	const TranslatePaths aPaths[] = {
378 		{ "basi0g01.png", "basi0g01.bits" },
379 		{ "basi0g02.png", "basi0g02.bits" },
380 		{ "basn0g01.png", "basn0g01.bits" },
381 		{ "basn0g04.png", "basn0g04.bits" },
382 		{ "basi0g16.png", "basi0g16.bits" },
383 		{ "basi4a08.png", "basi4a08.bits" },
384 		{ "basn0g08.png", "basn0g08.bits" },
385 		{ "basi4a16.png", "basi4a16.bits" },
386 		{ "tp1n3p08.png", "tp1n3p08.bits" },
387 		{ "tp0n2c08.png", "tp0n2c08.bits" },
388 		{ "tbgn2c16.png", "tbgn2c16.bits" },
389 		{ "s39i3p04.png", "s39i3p04.bits" },
390 		{ "basi6a08.png", "basi6a08.bits" },
391 		{ "basi6a16.png", "basi6a16.bits" },
392 		{ "basn6a08.png", "basn6a08.bits" },
393 		{ "basi3p01.png", "basi3p01.bits" },
394 		{ "basn3p02.png", "basn3p02.bits" }
395 	};
396 
397 	TranslateTests(this, proster, aPaths,
398 		sizeof(aPaths) / sizeof(TranslatePaths));
399 
400 	delete proster;
401 	proster = NULL;
402 }
403 
404 #if !TEST_R5
405 
406 // The input formats that this translator supports.
407 translation_format gPNGInputFormats[] = {
408 	{
409 		B_PNG_FORMAT,
410 		B_TRANSLATOR_BITMAP,
411 		PNG_IN_QUALITY,
412 		PNG_IN_CAPABILITY,
413 		"image/png",
414 		"PNG image"
415 	},
416 	{
417 		B_PNG_FORMAT,
418 		B_TRANSLATOR_BITMAP,
419 		PNG_IN_QUALITY,
420 		PNG_IN_CAPABILITY,
421 		"image/x-png",
422 		"PNG image"
423 	},
424 	{
425 		B_TRANSLATOR_BITMAP,
426 		B_TRANSLATOR_BITMAP,
427 		BBT_IN_QUALITY,
428 		BBT_IN_CAPABILITY,
429 		"image/x-be-bitmap",
430 		"Be Bitmap Format (PNGTranslator)"
431 	}
432 };
433 
434 // The output formats that this translator supports.
435 translation_format gPNGOutputFormats[] = {
436 	{
437 		B_PNG_FORMAT,
438 		B_TRANSLATOR_BITMAP,
439 		PNG_OUT_QUALITY,
440 		PNG_OUT_CAPABILITY,
441 		"image/png",
442 		"PNG image"
443 	},
444 	{
445 		B_TRANSLATOR_BITMAP,
446 		B_TRANSLATOR_BITMAP,
447 		BBT_OUT_QUALITY,
448 		BBT_OUT_CAPABILITY,
449 		"image/x-be-bitmap",
450 		"Be Bitmap Format (PNGTranslator)"
451 	}
452 };
453 
454 void
LoadAddOnTest()455 PNGTranslatorTest::LoadAddOnTest()
456 {
457 	TranslatorLoadAddOnTest("/boot/home/config/add-ons/Translators/PNGTranslator",
458 		this,
459 		gPNGInputFormats, sizeof(gPNGInputFormats) / sizeof(translation_format),
460 		gPNGOutputFormats, sizeof(gPNGOutputFormats) / sizeof(translation_format),
461 		PNG_TRANSLATOR_VERSION);
462 }
463 
464 #endif // #if !TEST_R5
465