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_VER(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 * 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 70 PNGTranslatorTest::setUp() 71 { 72 BTestCase::setUp(); 73 } 74 75 // tearDown 76 void 77 PNGTranslatorTest::tearDown() 78 { 79 BTestCase::tearDown(); 80 } 81 82 void 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 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 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 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 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 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 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 B_TRANSLATION_MAKE_VER(1,0,0)); 462 } 463 464 #endif // #if !TEST_R5 465