1// TIFFTranslatorTest.cpp
2#include "TIFFTranslatorTest.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 <Translator.h>
11#include <TranslatorFormats.h>
12#include <TranslatorRoster.h>
13#include <Message.h>
14#include <View.h>
15#include <Rect.h>
16#include <File.h>
17#include <DataIO.h>
18#include <Errors.h>
19#include <OS.h>
20#include "TranslatorTestAddOn.h"
21
22// Suite
23CppUnit::Test *
24TIFFTranslatorTest::Suite()
25{
26	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
27	typedef CppUnit::TestCaller<TIFFTranslatorTest> TC;
28
29	suite->addTest(
30		new TC("TIFFTranslator IdentifyTest",
31			&TIFFTranslatorTest::IdentifyTest));
32
33	suite->addTest(
34		new TC("TIFFTranslator TranslateTest",
35			&TIFFTranslatorTest::TranslateTest));
36
37#if !TEST_R5
38	suite->addTest(
39		new TC("TIFFTranslator LoadAddOnTest",
40			&TIFFTranslatorTest::LoadAddOnTest));
41#endif
42
43	return suite;
44}
45
46// setUp
47void
48TIFFTranslatorTest::setUp()
49{
50	BTestCase::setUp();
51}
52
53// tearDown
54void
55TIFFTranslatorTest::tearDown()
56{
57	BTestCase::tearDown();
58}
59
60void
61CheckBits_Tiff(translator_info *pti)
62{
63	CheckTranslatorInfo(pti, B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP,
64		0.7f, 0.6f, "Be Bitmap Format (TIFFTranslator)",
65		"image/x-be-bitmap");
66}
67
68void
69CheckTiff(translator_info *pti, const char *imageType)
70{
71	CheckTranslatorInfo(pti, B_TIFF_FORMAT, B_TRANSLATOR_BITMAP,
72		0.7f, 0.6f, imageType, "image/tiff");
73}
74
75// coveniently group path of image with
76// the expected Identify() string for that image
77struct IdentifyInfo {
78	const char *imagePath;
79	const char *identifyString;
80};
81
82void
83IdentifyTests(TIFFTranslatorTest *ptest, BTranslatorRoster *proster,
84	const IdentifyInfo *pinfo, int32 len, bool bbits)
85{
86	translator_info ti;
87	printf(" [%d] ", (int) bbits);
88
89	for (int32 i = 0; i < len; i++) {
90		ptest->NextSubTest();
91		BFile file;
92		printf(" [%s] ", pinfo[i].imagePath);
93		CPPUNIT_ASSERT(file.SetTo(pinfo[i].imagePath, B_READ_ONLY) == B_OK);
94
95		// Identify (output: B_TRANSLATOR_ANY_TYPE)
96		ptest->NextSubTest();
97		memset(&ti, 0, sizeof(translator_info));
98		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti) == B_OK);
99		if (bbits)
100			CheckBits_Tiff(&ti);
101		else
102			CheckTiff(&ti, pinfo[i].identifyString);
103
104		// Identify (output: B_TRANSLATOR_BITMAP)
105		ptest->NextSubTest();
106		memset(&ti, 0, sizeof(translator_info));
107		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
108			B_TRANSLATOR_BITMAP) == B_OK);
109		if (bbits)
110			CheckBits_Tiff(&ti);
111		else
112			CheckTiff(&ti, pinfo[i].identifyString);
113
114		// Identify (output: B_TIFF_FORMAT)
115		ptest->NextSubTest();
116		memset(&ti, 0, sizeof(translator_info));
117		CPPUNIT_ASSERT(proster->Identify(&file, NULL, &ti, 0, NULL,
118			B_TIFF_FORMAT) == B_OK);
119		if (bbits)
120			CheckBits_Tiff(&ti);
121		else
122			CheckTiff(&ti, pinfo[i].identifyString);
123	}
124}
125
126void
127TIFFTranslatorTest::IdentifyTest()
128{
129	// Init
130	NextSubTest();
131	status_t result = B_ERROR;
132	BTranslatorRoster *proster = new BTranslatorRoster();
133	CPPUNIT_ASSERT(proster);
134	CPPUNIT_ASSERT(proster->AddTranslators(
135		"/boot/home/config/add-ons/Translators/TIFFTranslator") == B_OK);
136	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
137		B_READ_ONLY);
138	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
139
140	// Identify (bad input, output types)
141	NextSubTest();
142	translator_info ti;
143	memset(&ti, 0, sizeof(translator_info));
144	result = proster->Identify(&wronginput, NULL, &ti, 0,
145		NULL, B_TRANSLATOR_TEXT);
146	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
147	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
148
149	// Identify (wrong type of input data)
150	NextSubTest();
151	memset(&ti, 0, sizeof(translator_info));
152	result = proster->Identify(&wronginput, NULL, &ti);
153	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
154	CPPUNIT_ASSERT(ti.type == 0 && ti.translator == 0);
155
156	// Identify (successfully identify the following files)
157	const IdentifyInfo aBitsPaths[] = {
158		{ "/boot/home/resources/tiff/beer.bits", "" },
159		{ "/boot/home/resources/tiff/blocks.bits", "" }
160	};
161	const IdentifyInfo aTiffPaths[] = {
162		{ "/boot/home/resources/tiff/beer_rgb_nocomp.tif",
163			"TIFF image (Little, RGB, None)" },
164		{ "/boot/home/resources/tiff/beer_rgb_nocomp_big.tif",
165			"TIFF image (Big, RGB, None)" },
166		{ "/boot/home/resources/tiff/blocks_rgb_nocomp.tif",
167			"TIFF image (Little, RGB, None)" },
168		{ "/boot/home/resources/tiff/hills_bw_huffman.tif",
169			"TIFF image (Little, Mono, Huffman)" },
170		{ "/boot/home/resources/tiff/hills_cmyk_nocomp.tif",
171			"TIFF image (Little, CMYK, None)" },
172		{ "/boot/home/resources/tiff/hills_cmyk_nocomp_big.tif",
173			"TIFF image (Big, CMYK, None)" },
174		{ "/boot/home/resources/tiff/hills_rgb_nocomp.tif",
175			"TIFF image (Little, RGB, None)" },
176		{ "/boot/home/resources/tiff/hills_rgb_packbits.tif",
177			"TIFF image (Little, RGB, PackBits)" },
178		{ "/boot/home/resources/tiff/homes_bw_fax.tif",
179			"TIFF image (Little, Mono, Group 3)" },
180		{ "/boot/home/resources/tiff/homes_bw_huffman.tif",
181			"TIFF image (Little, Mono, Huffman)" },
182		{ "/boot/home/resources/tiff/homes_bw_nocomp.tif",
183			"TIFF image (Little, Mono, None)" },
184		{ "/boot/home/resources/tiff/homes_bw_nocomp_big.tif",
185			"TIFF image (Big, Mono, None)" },
186		{ "/boot/home/resources/tiff/homes_bw_packbits.tif",
187			"TIFF image (Little, Mono, PackBits)" },
188		{ "/boot/home/resources/tiff/homes_cmap4_nocomp.tif",
189			"TIFF image (Little, Palette, None)" },
190		{ "/boot/home/resources/tiff/homes_cmap4_nocomp_big.tif",
191			"TIFF image (Big, Palette, None)" },
192		{ "/boot/home/resources/tiff/homes_cmap4_packbits.tif",
193			"TIFF image (Little, Palette, PackBits)" },
194		{ "/boot/home/resources/tiff/homes_gray8_nocomp.tif",
195			"TIFF image (Little, Gray, None)" },
196		{ "/boot/home/resources/tiff/homes_gray8_nocomp_big.tif",
197			"TIFF image (Big, Gray, None)" },
198		{ "/boot/home/resources/tiff/homes_gray8_packbits.tif",
199			"TIFF image (Little, Gray, PackBits)" },
200		{ "/boot/home/resources/tiff/logo_cmap4_nocomp.tif",
201			"TIFF image (Little, Palette, None)" },
202		{ "/boot/home/resources/tiff/logo_cmap4_nocomp_big.tif",
203			"TIFF image (Big, Palette, None)" },
204		{ "/boot/home/resources/tiff/logo_cmap4_packbits.tif",
205			"TIFF image (Little, Palette, PackBits)" },
206		{ "/boot/home/resources/tiff/logo_cmap8_nocomp.tif",
207			"TIFF image (Little, Palette, None)" },
208		{ "/boot/home/resources/tiff/logo_cmap8_nocomp_big.tif",
209			"TIFF image (Big, Palette, None)" },
210		{ "/boot/home/resources/tiff/logo_cmap8_packbits.tif",
211			"TIFF image (Little, Palette, PackBits)" },
212		{ "/boot/home/resources/tiff/logo_cmyk_nocomp.tif",
213			"TIFF image (Little, CMYK, None)" },
214		{ "/boot/home/resources/tiff/vsmall_cmap4_nocomp.tif",
215			"TIFF image (Little, Palette, None)" },
216		{ "/boot/home/resources/tiff/vsmall_rgb_nocomp.tif",
217			"TIFF image (Little, RGB, None)" },
218		{ "/boot/home/resources/tiff/backup_help.tif",
219			"TIFF image (Big, Mono, Group 3)" }
220	};
221
222	IdentifyTests(this, proster, aTiffPaths,
223		sizeof(aTiffPaths) / sizeof(IdentifyInfo), false);
224	IdentifyTests(this, proster, aBitsPaths,
225		sizeof(aBitsPaths) / sizeof(IdentifyInfo), true);
226
227	delete proster;
228	proster = NULL;
229}
230
231// coveniently group path of tiff image with
232// path of bits image that it should translate to
233struct TranslatePaths {
234	const char *tiffPath;
235	const char *bitsPath;
236};
237
238void
239TranslateTests(TIFFTranslatorTest *ptest, BTranslatorRoster *proster,
240	const TranslatePaths *paths, int32 len)
241{
242	// Perform translations on every file in the array
243	for (int32 i = 0; i < len; i++) {
244		// Setup input files
245		ptest->NextSubTest();
246		BFile tiff_file, bits_file;
247		CPPUNIT_ASSERT(tiff_file.SetTo(paths[i].tiffPath, B_READ_ONLY) == B_OK);
248		CPPUNIT_ASSERT(bits_file.SetTo(paths[i].bitsPath, B_READ_ONLY) == B_OK);
249		printf(" [%s] ", paths[i].tiffPath);
250
251		BMallocIO mallio, dmallio;
252
253		// Convert to B_TRANSLATOR_ANY_TYPE (should be B_TRANSLATOR_BITMAP)
254		ptest->NextSubTest();
255		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
256		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
257		CPPUNIT_ASSERT(proster->Translate(&tiff_file, NULL, NULL, &mallio,
258			B_TRANSLATOR_ANY_TYPE) == B_OK);
259		CPPUNIT_ASSERT(CompareStreams(mallio, bits_file) == true);
260
261		// Convert to B_TRANSLATOR_BITMAP
262		ptest->NextSubTest();
263		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
264		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
265		CPPUNIT_ASSERT(proster->Translate(&tiff_file, NULL, NULL, &mallio,
266			B_TRANSLATOR_BITMAP) == B_OK);
267		CPPUNIT_ASSERT(CompareStreams(mallio, bits_file) == true);
268
269		// Convert bits mallio to B_TRANSLATOR_BITMAP dmallio
270		/* Not Supported Yet
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
279		// Convert to B_TIFF_FORMAT
280		/* Not Supported Yet
281		ptest->NextSubTest();
282		CPPUNIT_ASSERT(mallio.Seek(0, SEEK_SET) == 0);
283		CPPUNIT_ASSERT(mallio.SetSize(0) == B_OK);
284		CPPUNIT_ASSERT(proster->Translate(&tiff_file, NULL, NULL, &mallio,
285			B_TIFF_FORMAT) == B_OK);
286		CPPUNIT_ASSERT(CompareStreams(mallio, tiff_file) == true);
287		*/
288
289		// Convert TIFF mallio to B_TRANSLATOR_BITMAP dmallio
290		/* Not Ready Yet
291		ptest->NextSubTest();
292		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
293		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
294		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
295			B_TRANSLATOR_BITMAP) == B_OK);
296		CPPUNIT_ASSERT(CompareStreams(dmallio, bits_file) == true);
297		*/
298
299		// Convert TIFF mallio to B_TIFF_FORMAT dmallio
300		/* Not Ready Yet
301		ptest->NextSubTest();
302		CPPUNIT_ASSERT(dmallio.Seek(0, SEEK_SET) == 0);
303		CPPUNIT_ASSERT(dmallio.SetSize(0) == B_OK);
304		CPPUNIT_ASSERT(proster->Translate(&mallio, NULL, NULL, &dmallio,
305			B_TIFF_FORMAT) == B_OK);
306		CPPUNIT_ASSERT(CompareStreams(dmallio, tiff_file) == true);
307		*/
308	}
309}
310
311void
312TIFFTranslatorTest::TranslateTest()
313{
314	// Init
315	NextSubTest();
316	status_t result = B_ERROR;
317	off_t filesize = -1;
318	BTranslatorRoster *proster = new BTranslatorRoster();
319	CPPUNIT_ASSERT(proster);
320	CPPUNIT_ASSERT(proster->AddTranslators(
321		"/boot/home/config/add-ons/Translators/TIFFTranslator") == B_OK);
322	BFile wronginput("../src/tests/kits/translation/data/images/image.jpg",
323		B_READ_ONLY);
324	CPPUNIT_ASSERT(wronginput.InitCheck() == B_OK);
325	BFile output("/tmp/tiff_test.out", B_WRITE_ONLY |
326		B_CREATE_FILE | B_ERASE_FILE);
327	CPPUNIT_ASSERT(output.InitCheck() == B_OK);
328
329	// Translate (bad input, output types)
330	NextSubTest();
331	result = proster->Translate(&wronginput, NULL, NULL, &output,
332		B_TRANSLATOR_TEXT);
333	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
334	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
335	CPPUNIT_ASSERT(filesize == 0);
336
337	// Translate (wrong type of input data)
338	NextSubTest();
339	result = proster->Translate(&wronginput, NULL, NULL, &output,
340		B_TIFF_FORMAT);
341	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
342	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
343	CPPUNIT_ASSERT(filesize == 0);
344
345	// Translate (wrong type of input, B_TRANSLATOR_ANY_TYPE output)
346	NextSubTest();
347	result = proster->Translate(&wronginput, NULL, NULL, &output,
348		B_TRANSLATOR_ANY_TYPE);
349	CPPUNIT_ASSERT(result == B_NO_TRANSLATOR);
350	CPPUNIT_ASSERT(output.GetSize(&filesize) == B_OK);
351	CPPUNIT_ASSERT(filesize == 0);
352
353	// Translate TIFF images to bits
354	const TranslatePaths aPaths[] = {
355		{ "/boot/home/resources/tiff/beer_rgb_nocomp.tif",
356			"/boot/home/resources/tiff/beer.bits" },
357		{ "/boot/home/resources/tiff/beer_rgb_nocomp_big.tif",
358			"/boot/home/resources/tiff/beer.bits" },
359		{ "/boot/home/resources/tiff/blocks_rgb_nocomp.tif",
360			"/boot/home/resources/tiff/blocks.bits" },
361		{ "/boot/home/resources/tiff/hills_bw_huffman.tif",
362			"/boot/home/resources/tiff/hills_bw.bits" },
363		{ "/boot/home/resources/tiff/hills_cmyk_nocomp.tif",
364			"/boot/home/resources/tiff/hills_cmyk.bits" },
365		{ "/boot/home/resources/tiff/hills_cmyk_nocomp_big.tif",
366			"/boot/home/resources/tiff/hills_cmyk.bits" },
367		{ "/boot/home/resources/tiff/hills_rgb_nocomp.tif",
368			"/boot/home/resources/tiff/hills_rgb.bits" },
369		{ "/boot/home/resources/tiff/hills_rgb_packbits.tif",
370			"/boot/home/resources/tiff/hills_rgb.bits" },
371		{ "/boot/home/resources/tiff/homes_bw_fax.tif",
372			"/boot/home/resources/tiff/homes_bw.bits" },
373		{ "/boot/home/resources/tiff/homes_bw_huffman.tif",
374			"/boot/home/resources/tiff/homes_bw.bits" },
375		{ "/boot/home/resources/tiff/homes_bw_nocomp.tif",
376			"/boot/home/resources/tiff/homes_bw.bits" },
377		{ "/boot/home/resources/tiff/homes_bw_nocomp_big.tif",
378			"/boot/home/resources/tiff/homes_bw.bits" },
379		{ "/boot/home/resources/tiff/homes_bw_packbits.tif",
380			"/boot/home/resources/tiff/homes_bw.bits" },
381		{ "/boot/home/resources/tiff/homes_cmap4_nocomp.tif",
382			"/boot/home/resources/tiff/homes_cmap4.bits" },
383		{ "/boot/home/resources/tiff/homes_cmap4_nocomp_big.tif",
384			"/boot/home/resources/tiff/homes_cmap4.bits" },
385		{ "/boot/home/resources/tiff/homes_cmap4_packbits.tif",
386			"/boot/home/resources/tiff/homes_cmap4.bits" },
387		{ "/boot/home/resources/tiff/homes_gray8_nocomp.tif",
388			"/boot/home/resources/tiff/homes_gray8.bits" },
389		{ "/boot/home/resources/tiff/homes_gray8_nocomp_big.tif",
390			"/boot/home/resources/tiff/homes_gray8.bits" },
391		{ "/boot/home/resources/tiff/homes_gray8_packbits.tif",
392			"/boot/home/resources/tiff/homes_gray8.bits" },
393		{ "/boot/home/resources/tiff/logo_cmap4_nocomp.tif",
394			"/boot/home/resources/tiff/logo_cmap4.bits" },
395		{ "/boot/home/resources/tiff/logo_cmap4_nocomp_big.tif",
396			"/boot/home/resources/tiff/logo_cmap4.bits" },
397		{ "/boot/home/resources/tiff/logo_cmap4_packbits.tif",
398			"/boot/home/resources/tiff/logo_cmap4.bits" },
399		{ "/boot/home/resources/tiff/logo_cmap8_nocomp.tif",
400			"/boot/home/resources/tiff/logo_rgb.bits" },
401		{ "/boot/home/resources/tiff/logo_cmap8_nocomp_big.tif",
402			"/boot/home/resources/tiff/logo_rgb.bits" },
403		{ "/boot/home/resources/tiff/logo_cmap8_packbits.tif",
404			"/boot/home/resources/tiff/logo_rgb.bits" },
405		{ "/boot/home/resources/tiff/logo_cmyk_nocomp.tif",
406			"/boot/home/resources/tiff/logo_cmyk.bits" },
407		{ "/boot/home/resources/tiff/vsmall_cmap4_nocomp.tif",
408			"/boot/home/resources/tiff/vsmall.bits" },
409		{ "/boot/home/resources/tiff/vsmall_rgb_nocomp.tif",
410			"/boot/home/resources/tiff/vsmall.bits" },
411		{ "/boot/home/resources/tiff/backup_help.tif",
412			"/boot/home/resources/tiff/backup_help.bits" }
413	};
414
415	TranslateTests(this, proster, aPaths,
416		sizeof(aPaths) / sizeof(TranslatePaths));
417
418	delete proster;
419	proster = NULL;
420}
421
422#if !TEST_R5
423
424// The input formats that this translator is supposed to support
425translation_format gTIFFInputFormats[] = {
426	{
427		B_TRANSLATOR_BITMAP,
428		B_TRANSLATOR_BITMAP,
429		0.7f, // quality
430		0.6f, // capability
431		"image/x-be-bitmap",
432		"Be Bitmap Format (TIFFTranslator)"
433	},
434	{
435		B_TIFF_FORMAT,
436		B_TRANSLATOR_BITMAP,
437		0.7f,
438		0.6f,
439		"image/tiff",
440		"TIFF image"
441	}
442};
443
444// The output formats that this translator is supposed to support
445translation_format gTIFFOutputFormats[] = {
446	{
447		B_TRANSLATOR_BITMAP,
448		B_TRANSLATOR_BITMAP,
449		0.7f, // quality
450		0.6f, // capability
451		"image/x-be-bitmap",
452		"Be Bitmap Format (TIFFTranslator)"
453	},
454	{
455		B_TIFF_FORMAT,
456		B_TRANSLATOR_BITMAP,
457		0.7f,
458		0.6f,
459		"image/tiff",
460		"TIFF image"
461	}
462};
463
464void
465TIFFTranslatorTest::LoadAddOnTest()
466{
467	TranslatorLoadAddOnTest("/boot/home/config/add-ons/Translators/TIFFTranslator",
468		this,
469		gTIFFInputFormats, sizeof(gTIFFInputFormats) / sizeof(translation_format),
470		gTIFFOutputFormats, sizeof(gTIFFOutputFormats) / sizeof(translation_format),
471		B_TRANSLATION_MAKE_VERSION(1,0,0));
472}
473
474#endif // #if !TEST_R5
475