1/*****************************************************************************/ 2// Haiku Translation Kit Test 3// Authors: Brian Matzon <brian@matzon.dk>, Michael Wilber 4// Version: 5// 6// This is the Test application for BBitmapStream 7// 8// 9// This application and all source files used in its construction, except 10// where noted, are licensed under the MIT License, and have been written 11// and are: 12// 13// Copyright (c) 2002 Haiku Project 14// 15// Permission is hereby granted, free of charge, to any person obtaining a 16// copy of this software and associated documentation files (the "Software"), 17// to deal in the Software without restriction, including without limitation 18// the rights to use, copy, modify, merge, publish, distribute, sublicense, 19// and/or sell copies of the Software, and to permit persons to whom the 20// Software is furnished to do so, subject to the following conditions: 21// 22// The above copyright notice and this permission notice shall be included 23// in all copies or substantial portions of the Software. 24// 25// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 26// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 28// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 30// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 31// DEALINGS IN THE SOFTWARE. 32/*****************************************************************************/ 33#include "BitmapStreamTest.h" 34 35#include <TranslatorRoster.h> 36#include <Application.h> 37#include <Bitmap.h> 38 39#include <stdio.h> 40#include <string.h> 41 42/* cppunit framework */ 43#include <cppunit/Test.h> 44#include <cppunit/TestCaller.h> 45#include <cppunit/TestSuite.h> 46 47/** 48 * Default constructor - no work 49 */ 50BitmapStreamTest::BitmapStreamTest(std::string name) 51 : BTestCase(name) 52{ 53} 54 55/** 56 * Default destructor - no work 57 */ 58BitmapStreamTest::~BitmapStreamTest() 59{ 60} 61 62CppUnit::Test * 63BitmapStreamTest::Suite() 64{ 65 /* create our suite */ 66 CppUnit::TestSuite *suite = new CppUnit::TestSuite("BitmapStream"); 67 typedef CppUnit::TestCaller<BitmapStreamTest> TC; 68 69 /* add tests */ 70 suite->addTest(new TC("BitmapStreamTest::Constructor Test", 71 &BitmapStreamTest::ConstructorTest)); 72 73 suite->addTest(new TC("BitmapStreamTest::DetachBitmap Test", 74 &BitmapStreamTest::DetachBitmapTest)); 75 76 suite->addTest(new TC("BitmapStreamTest::Seek Test", 77 &BitmapStreamTest::SeekTest)); 78 79 suite->addTest(new TC("BitmapStreamTest::SetSize Test", 80 &BitmapStreamTest::SetSizeTest)); 81 82 suite->addTest(new TC("BitmapStreamTest::ReadWrite Test", 83 &BitmapStreamTest::ReadWriteTest)); 84 85 return suite; 86} 87 88/** 89 * Tests: 90 * BBitmapStream(BBitmap *map = NULL) 91 */ 92void 93BitmapStreamTest::ConstructorTest() 94{ 95 BApplication 96 app("application/x-vnd.Haiku-translationkit_bitmapstreamtest"); 97 98 //BBitmapStream with no bitmap supplied 99 NextSubTest(); 100 BBitmapStream streamEmpty; 101 BBitmap *pbits = NULL; 102 CPPUNIT_ASSERT(streamEmpty.Position() == 0); 103 CPPUNIT_ASSERT(streamEmpty.Size() == 0); 104 CPPUNIT_ASSERT(streamEmpty.DetachBitmap(&pbits) == B_ERROR); 105 CPPUNIT_ASSERT(pbits == NULL); 106 107 //BBitmapStream with an empty BBitmap 108 NextSubTest(); 109 pbits = new BBitmap(BRect(0,0,5,5), B_RGB32); 110 CPPUNIT_ASSERT(pbits); 111 112 BBitmapStream *pstreamWithBits; 113 pstreamWithBits = new BBitmapStream(pbits); 114 CPPUNIT_ASSERT(pstreamWithBits); 115 CPPUNIT_ASSERT(pstreamWithBits->Position() == 0); 116 CPPUNIT_ASSERT(pstreamWithBits->Size() == 176); 117 BBitmap *poutbits = NULL; 118 CPPUNIT_ASSERT(pstreamWithBits->DetachBitmap(&poutbits) == B_OK); 119 CPPUNIT_ASSERT(pbits == poutbits); 120 121 delete pstreamWithBits; 122 pstreamWithBits = NULL; 123 124 delete pbits; 125 pbits = NULL; 126 127 //constructor is also created with a value in DetachBitmapTest() 128} 129 130/** 131 * Tests: 132 * status_t DetachBitmap(BBitmap **outMap) 133 */ 134void 135BitmapStreamTest::DetachBitmapTest() 136{ 137 BApplication 138 app("application/x-vnd.Haiku-translationkit_bitmapstreamtest"); 139 140 NextSubTest(); 141 BFile file("../src/tests/kits/translation/data/images/image.jpg", 142 B_READ_ONLY); 143 CPPUNIT_ASSERT(file.InitCheck() == B_OK); 144 145 //translate a file into a BBitmapStream 146 NextSubTest(); 147 BBitmapStream *pstream = new BBitmapStream; 148 BBitmap *pbits = NULL; 149 BTranslatorRoster *proster = BTranslatorRoster::Default(); 150 CPPUNIT_ASSERT(proster->Translate(&file, NULL, NULL, pstream, 151 B_TRANSLATOR_BITMAP) == B_OK); 152 CPPUNIT_ASSERT(pstream->DetachBitmap(&pbits) == B_NO_ERROR); 153 CPPUNIT_ASSERT(pbits); 154 CPPUNIT_ASSERT(pbits->IsValid()); 155 156 //B_BAD_VALUE 157 NextSubTest(); 158 CPPUNIT_ASSERT(pstream->DetachBitmap(NULL) == B_BAD_VALUE); 159 160 //Attempt double detach 161 NextSubTest(); 162 BBitmap *pdbits = NULL; 163 CPPUNIT_ASSERT(pstream->DetachBitmap(&pdbits) == B_ERROR); 164 165 //make sure that deleting the stream 166 //does not destroy the detached BBitmap 167 NextSubTest(); 168 delete pstream; 169 pstream = NULL; 170 CPPUNIT_ASSERT(pbits->IsValid()); 171 CPPUNIT_ASSERT(pbits->BitsLength() > 0); 172 173 //create a new stream using the BBitmap 174 //created by the first stream 175 NextSubTest(); 176 BBitmapStream *pfullstream = new BBitmapStream(pbits); 177 CPPUNIT_ASSERT(pfullstream->Position() == 0); 178 CPPUNIT_ASSERT(pfullstream->Size() == 179 pbits->BitsLength() + sizeof(TranslatorBitmap)); 180 181 //deleting pfullstream should also destroy 182 //the bitmap attached to it (pbits) 183 NextSubTest(); 184 delete pfullstream; 185 pfullstream = NULL; 186 CPPUNIT_ASSERT(pbits->BitsLength() == 0); 187} 188 189/** 190 * Tests: 191 * ssize_t ReadAt(off_t pos, void *buffer, size_t numBytes) 192 * ssize_t WriteAt(off_t pos, void *buffer, size_t numBytes) 193 */ 194void 195BitmapStreamTest::ReadWriteTest() 196{ 197 NextSubTest(); 198 BApplication 199 app("application/x-vnd.Haiku-translationkit_bitmapstreamtest"); 200 char chbuf[sizeof(TranslatorBitmap)], 201 chheader[sizeof(TranslatorBitmap)], *pch; 202 TranslatorBitmap sheader; 203 BBitmapStream stream; 204 int32 width = 5, height = 5; 205 206 sheader.magic = B_TRANSLATOR_BITMAP; 207 sheader.bounds.left = 0; 208 sheader.bounds.top = 0; 209 sheader.bounds.right = width - 1; 210 sheader.bounds.bottom = height - 1; 211 sheader.rowBytes = width * 4; 212 sheader.colors = B_RGB32; 213 sheader.dataSize = sheader.rowBytes * height; 214 215 memcpy(&chheader, &sheader, sizeof(TranslatorBitmap)); 216 CPPUNIT_ASSERT(swap_data(B_UINT32_TYPE, &(chheader[0]), 217 sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN) == B_OK); 218 219 // Write header, 1 byte at a time 220 NextSubTest(); 221 off_t nPos; 222 for (nPos = 0; nPos < sizeof(TranslatorBitmap); nPos++) { 223 pch = (char *)(&(chheader[0])) + nPos; 224 CPPUNIT_ASSERT(stream.WriteAt(nPos, pch, 1) == 1); 225 } 226 // Check size 227 NextSubTest(); 228 CPPUNIT_ASSERT(stream.Size() == 229 sizeof(TranslatorBitmap) + sheader.dataSize); 230 231 // Read header, 1 byte at a time 232 NextSubTest(); 233 for (nPos = 0; nPos < sizeof(TranslatorBitmap); nPos++) { 234 pch = (char *)(&(chheader[0])) + nPos; 235 CPPUNIT_ASSERT(stream.ReadAt(nPos, &(chbuf[0]), 1) == 1); 236 CPPUNIT_ASSERT(pch[0] == chbuf[0]); 237 } 238 239 // Write header, all at once 240 NextSubTest(); 241 pch = (char *)(&(chheader[0])); 242 CPPUNIT_ASSERT(stream.WriteAt(0, pch, 243 sizeof(TranslatorBitmap)) == sizeof(TranslatorBitmap)); 244 // Check size 245 NextSubTest(); 246 CPPUNIT_ASSERT(stream.Size() == 247 sizeof(TranslatorBitmap) + sheader.dataSize); 248 249 // Read header, all at once 250 NextSubTest(); 251 CPPUNIT_ASSERT(stream.ReadAt(0, &(chbuf[0]), 252 sizeof(TranslatorBitmap)) == sizeof(TranslatorBitmap)); 253 CPPUNIT_ASSERT(memcmp(pch, &(chbuf[0]), sizeof(TranslatorBitmap)) == 0); 254 255 // Write bitmap data 256 NextSubTest(); 257 int32 bytesLeft = sheader.dataSize; 258 char byt = 0xCF; 259 nPos = sizeof(TranslatorBitmap); 260 while (bytesLeft--) 261 CPPUNIT_ASSERT(stream.WriteAt(nPos++, &byt, 1) == 1); 262 // Check size 263 NextSubTest(); 264 CPPUNIT_ASSERT(stream.Size() == 265 sizeof(TranslatorBitmap) + sheader.dataSize); 266 267 // Test reading zero bytes 268 NextSubTest(); 269 CPPUNIT_ASSERT(stream.ReadAt(stream.Size(), &(chbuf[0]), 0) == 0); 270 CPPUNIT_ASSERT(stream.ReadAt(sheader.dataSize + 1000, &(chbuf[0]), 0) == 0); 271 CPPUNIT_ASSERT(stream.ReadAt(-1, &(chbuf[0]), 0) == 0); 272 273 // Read bitmap data 274 NextSubTest(); 275 #if !TEST_R5 276 // This test fails with Be's version because of a bug. 277 // Be's BBitmapStream::ReadAt() has strange behavior in cases 278 // where the pos parameter of ReadAt() is != BBitmapStream::Position(). 279 // If BBitmapStream::Read() is used instead, it calls 280 // BBitmapStream::ReadAt() with pos = BBitmapStream::Position(), 281 // so, this issue is rarely a problem because Read() is most often used. 282 bytesLeft = sheader.dataSize; 283 nPos = sizeof(TranslatorBitmap); 284 while (bytesLeft--) { 285 chbuf[0] = 0x99; 286 ssize_t rd = stream.ReadAt(nPos++, &(chbuf[0]), 1); 287 CPPUNIT_ASSERT(rd == 1); 288 CPPUNIT_ASSERT(chbuf[0] == byt); 289 } 290 #endif 291 292 // Send erroneous and weird data to WriteAt() 293 NextSubTest(); 294 CPPUNIT_ASSERT(stream.WriteAt(0, &byt, 0) == 0); 295 CPPUNIT_ASSERT(stream.WriteAt(-1, &byt, 1) == B_BAD_VALUE); 296 CPPUNIT_ASSERT(stream.WriteAt(stream.Size(), &byt, 1) == B_BAD_VALUE); 297 CPPUNIT_ASSERT(stream.WriteAt(stream.Size() + 1, &byt, 1) == B_BAD_VALUE); 298 CPPUNIT_ASSERT(stream.WriteAt(0, NULL, 1) == B_BAD_VALUE); 299 300 // Send erroneous and weird data to ReadAt() 301 NextSubTest(); 302 CPPUNIT_ASSERT(stream.ReadAt(0, &(chbuf[0]), 0) == 0); 303 CPPUNIT_ASSERT(stream.ReadAt(-1, &(chbuf[0]), 1) == B_BAD_VALUE); 304 CPPUNIT_ASSERT(stream.ReadAt(stream.Size(), &(chbuf[0]), 305 1) == B_ERROR); 306 CPPUNIT_ASSERT(stream.ReadAt(stream.Size() + 1, 307 &(chbuf[0]), 1) == B_ERROR); 308 #if !TEST_R5 309 // Be's version doesn't check for NULL 310 CPPUNIT_ASSERT(stream.ReadAt(0, NULL, 1) == B_BAD_VALUE); 311 #endif 312 313 // There is a segment violation with Be's version when stream is destroyed. 314 // Don't yet know why. 315} 316 317/** 318 * Tests: 319 * off_t Seek(off_t position, uint32 whence) 320 * off_t Position() const 321 */ 322void 323BitmapStreamTest::SeekTest() 324{ 325 BApplication 326 app("application/x-vnd.Haiku-translationkit_bitmapstreamtest"); 327 328 NextSubTest(); 329 BFile file("../src/tests/kits/translation/data/images/image.jpg", 330 B_READ_ONLY); 331 CPPUNIT_ASSERT(file.InitCheck() == B_OK); 332 333 //translate a file into a BBitmapStream 334 NextSubTest(); 335 BBitmapStream stream; 336 BTranslatorRoster *proster = BTranslatorRoster::Default(); 337 CPPUNIT_ASSERT(proster->Translate(&file, NULL, NULL, &stream, 338 B_TRANSLATOR_BITMAP) == B_OK); 339 340 // Test SEEK_END 341 NextSubTest(); 342 off_t nPos; 343 nPos = stream.Size(); 344 CPPUNIT_ASSERT(stream.Seek(0, SEEK_END) == nPos); 345 CPPUNIT_ASSERT(stream.Position() == nPos); 346 347 nPos = 0; 348 CPPUNIT_ASSERT(stream.Seek(-stream.Size(), SEEK_END) == nPos); 349 CPPUNIT_ASSERT(stream.Position() == nPos); 350 351 nPos = stream.Size() - 15; 352 CPPUNIT_ASSERT(stream.Seek(-15, SEEK_END) == nPos); 353 CPPUNIT_ASSERT(stream.Position() == nPos); 354 355 CPPUNIT_ASSERT(stream.Seek(1, SEEK_END) == B_BAD_VALUE); 356 CPPUNIT_ASSERT(stream.Position() == nPos); 357 358 CPPUNIT_ASSERT(stream.Seek(-(stream.Size() + 1), 359 SEEK_END) == B_BAD_VALUE); 360 CPPUNIT_ASSERT(stream.Position() == nPos); 361 362 // Test SEEK_SET 363 NextSubTest(); 364 nPos = 0; 365 CPPUNIT_ASSERT(stream.Seek(0, SEEK_SET) == nPos); 366 CPPUNIT_ASSERT(stream.Position() == nPos); 367 368 nPos = stream.Size(); 369 CPPUNIT_ASSERT(stream.Seek(nPos, SEEK_SET) == nPos); 370 CPPUNIT_ASSERT(stream.Position() == nPos); 371 372 nPos /= 2; 373 CPPUNIT_ASSERT(stream.Seek(nPos, SEEK_SET) == nPos); 374 CPPUNIT_ASSERT(stream.Position() == nPos); 375 376 CPPUNIT_ASSERT(stream.Seek(-1, SEEK_SET) == B_BAD_VALUE); 377 CPPUNIT_ASSERT(stream.Position() == nPos); 378 379 CPPUNIT_ASSERT(stream.Seek(stream.Size() + 1, SEEK_SET) == B_BAD_VALUE); 380 CPPUNIT_ASSERT(stream.Position() == nPos); 381 382 // Test SEEK_CUR 383 NextSubTest(); 384 CPPUNIT_ASSERT(stream.Seek(-nPos, SEEK_CUR) == 0); 385 CPPUNIT_ASSERT(stream.Position() == 0); 386 387 nPos = stream.Size(); 388 CPPUNIT_ASSERT(stream.Seek(nPos, SEEK_CUR) == nPos); 389 CPPUNIT_ASSERT(stream.Position() == nPos); 390 391 nPos -= 11; 392 CPPUNIT_ASSERT(stream.Seek(-11, SEEK_CUR) == nPos); 393 CPPUNIT_ASSERT(stream.Position() == nPos); 394 395 nPos += 8; 396 CPPUNIT_ASSERT(stream.Seek(8, SEEK_CUR) == nPos); 397 CPPUNIT_ASSERT(stream.Position() == nPos); 398 399 CPPUNIT_ASSERT(stream.Seek(-(stream.Position() + 1), 400 SEEK_CUR) == B_BAD_VALUE); 401 CPPUNIT_ASSERT(stream.Position() == nPos); 402 403 CPPUNIT_ASSERT(stream.Seek((stream.Size() - stream.Position()) + 1, 404 SEEK_CUR) == B_BAD_VALUE); 405 CPPUNIT_ASSERT(stream.Position() == nPos); 406} 407 408/** 409 * Tests: 410 * status_t SetSize(off_t size) const 411 */ 412void 413BitmapStreamTest::SetSizeTest() 414{ 415 BApplication 416 app("application/x-vnd.Haiku-translationkit_bitmapstreamtest"); 417 418 NextSubTest(); 419 BFile file("../src/tests/kits/translation/data/images/image.jpg", 420 B_READ_ONLY); 421 CPPUNIT_ASSERT(file.InitCheck() == B_OK); 422 423 //translate a file into a BBitmapStream 424 NextSubTest(); 425 BBitmapStream stream; 426 BTranslatorRoster *proster = BTranslatorRoster::Default(); 427 CPPUNIT_ASSERT(proster->Translate(&file, NULL, NULL, &stream, 428 B_TRANSLATOR_BITMAP) == B_OK); 429 430 // Send crap to SetSize 431 NextSubTest(); 432 CPPUNIT_ASSERT(stream.SetSize(-1) == B_BAD_VALUE); 433 CPPUNIT_ASSERT(stream.SetSize(stream.Size() + 1) == B_BAD_VALUE); 434} 435