Commit ec66957c5152a6a876403f13c4c6892482a3f0b4
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
6 changed files
with
90 additions
and
38 deletions
openbr/core/qtutils.cpp
| ... | ... | @@ -500,14 +500,15 @@ QString getAbsolutePath(const QString &filename) |
| 500 | 500 | return QFileInfo(filename).absoluteFilePath(); |
| 501 | 501 | } |
| 502 | 502 | |
| 503 | +const int base_block = 100000000; | |
| 504 | + | |
| 503 | 505 | BlockCompression::BlockCompression(QIODevice *_basis) |
| 504 | 506 | { |
| 505 | - blockSize = 100000000; | |
| 507 | + blockSize = base_block; | |
| 506 | 508 | setBasis(_basis); |
| 507 | 509 | } |
| 508 | 510 | |
| 509 | -BlockCompression::BlockCompression() { blockSize = 100000000; }; | |
| 510 | - | |
| 511 | +BlockCompression::BlockCompression() { blockSize = base_block;}; | |
| 511 | 512 | |
| 512 | 513 | bool BlockCompression::open(QIODevice::OpenMode mode) |
| 513 | 514 | { |
| ... | ... | @@ -521,14 +522,22 @@ bool BlockCompression::open(QIODevice::OpenMode mode) |
| 521 | 522 | blockWriter.setDevice(basis); |
| 522 | 523 | |
| 523 | 524 | if (mode & QIODevice::WriteOnly) { |
| 524 | - precompressedBlockWriter = new QBuffer; | |
| 525 | - precompressedBlockWriter->open(QIODevice::ReadWrite); | |
| 525 | + precompressedBlockWriter.open(QIODevice::WriteOnly); | |
| 526 | 526 | } |
| 527 | 527 | else if (mode & QIODevice::ReadOnly) { |
| 528 | + | |
| 529 | + // Read an initial compressed block from the underlying QIODevice, | |
| 530 | + // decompress, and set up a reader on it | |
| 528 | 531 | QByteArray compressedBlock; |
| 529 | - blockReader >> compressedBlock; | |
| 532 | + quint32 block_size; | |
| 533 | + blockReader >> block_size; | |
| 534 | + compressedBlock.resize(block_size); | |
| 535 | + int read_count = blockReader.readRawData(compressedBlock.data(), block_size); | |
| 536 | + if (read_count != block_size) | |
| 537 | + qFatal("Failed to read initial block"); | |
| 530 | 538 | |
| 531 | 539 | decompressedBlock = qUncompress(compressedBlock); |
| 540 | + | |
| 532 | 541 | decompressedBlockReader.setBuffer(&decompressedBlock); |
| 533 | 542 | decompressedBlockReader.open(QIODevice::ReadOnly); |
| 534 | 543 | } |
| ... | ... | @@ -538,11 +547,17 @@ bool BlockCompression::open(QIODevice::OpenMode mode) |
| 538 | 547 | |
| 539 | 548 | void BlockCompression::close() |
| 540 | 549 | { |
| 541 | - // flush output buffer | |
| 542 | - if ((openMode() & QIODevice::WriteOnly) && precompressedBlockWriter) { | |
| 543 | - QByteArray compressedBlock = qCompress(precompressedBlockWriter->buffer(), -1); | |
| 544 | - blockWriter << compressedBlock; | |
| 550 | + // flush output buffer, since we may have a partial block which hasn't been | |
| 551 | + // written to disk yet. | |
| 552 | + if ((openMode() & QIODevice::WriteOnly) && precompressedBlockWriter.isOpen()) { | |
| 553 | + QByteArray compressedBlock = qCompress(precompressedBlockWriter.buffer()); | |
| 554 | + precompressedBlockWriter.close(); | |
| 555 | + | |
| 556 | + quint32 bsize= compressedBlock.size(); | |
| 557 | + blockWriter << bsize; | |
| 558 | + blockWriter.writeRawData(compressedBlock.data(), compressedBlock.size()); | |
| 545 | 559 | } |
| 560 | + // close the underlying device. | |
| 546 | 561 | basis->close(); |
| 547 | 562 | } |
| 548 | 563 | |
| ... | ... | @@ -557,8 +572,10 @@ void BlockCompression::setBasis(QIODevice *_basis) |
| 557 | 572 | // block from basis |
| 558 | 573 | qint64 BlockCompression::readData(char *data, qint64 remaining) |
| 559 | 574 | { |
| 575 | + qint64 initial = remaining; | |
| 560 | 576 | qint64 read = 0; |
| 561 | 577 | while (remaining > 0) { |
| 578 | + // attempt to read the target amount of data | |
| 562 | 579 | qint64 single_read = decompressedBlockReader.read(data, remaining); |
| 563 | 580 | if (single_read == -1) |
| 564 | 581 | qFatal("miss read"); |
| ... | ... | @@ -567,13 +584,21 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) |
| 567 | 584 | read += single_read; |
| 568 | 585 | data += single_read; |
| 569 | 586 | |
| 570 | - // need a new block | |
| 587 | + // need a new block if we didn't get enough bytes from the previous read | |
| 571 | 588 | if (remaining > 0) { |
| 572 | 589 | QByteArray compressedBlock; |
| 573 | - blockReader >> compressedBlock; | |
| 574 | - if (compressedBlock.size() == 0) { | |
| 575 | - return read; | |
| 576 | - } | |
| 590 | + | |
| 591 | + // read the size of the next block | |
| 592 | + quint32 block_size; | |
| 593 | + blockReader >> block_size; | |
| 594 | + if (block_size == 0) | |
| 595 | + break; | |
| 596 | + | |
| 597 | + compressedBlock.resize(block_size); | |
| 598 | + int actualRead = blockReader.readRawData(compressedBlock.data(), block_size); | |
| 599 | + if (actualRead != block_size) | |
| 600 | + qFatal("Bad read on nominal block size: %d, only got %d", block_size, remaining); | |
| 601 | + | |
| 577 | 602 | decompressedBlock = qUncompress(compressedBlock); |
| 578 | 603 | |
| 579 | 604 | decompressedBlockReader.close(); |
| ... | ... | @@ -581,7 +606,12 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) |
| 581 | 606 | decompressedBlockReader.open(QIODevice::ReadOnly); |
| 582 | 607 | } |
| 583 | 608 | } |
| 584 | - return blockReader.atEnd() && !basis->isReadable() ? -1 : read; | |
| 609 | + | |
| 610 | + bool condition = blockReader.atEnd() && !basis->isReadable() ; | |
| 611 | + if (condition) | |
| 612 | + qWarning("Returning -1 from read"); | |
| 613 | + | |
| 614 | + return condition ? -1 : read; | |
| 585 | 615 | } |
| 586 | 616 | |
| 587 | 617 | bool BlockCompression::isSequential() const |
| ... | ... | @@ -591,36 +621,57 @@ bool BlockCompression::isSequential() const |
| 591 | 621 | |
| 592 | 622 | qint64 BlockCompression::writeData(const char *data, qint64 remaining) |
| 593 | 623 | { |
| 624 | + const char * endPoint = data + remaining; | |
| 625 | + qint64 initial = remaining; | |
| 626 | + | |
| 594 | 627 | qint64 written = 0; |
| 595 | 628 | |
| 596 | 629 | while (remaining > 0) { |
| 597 | 630 | // how much more can be put in this buffer? |
| 598 | - qint64 capacity = blockSize - precompressedBlockWriter->pos(); | |
| 631 | + qint64 capacity = blockSize - precompressedBlockWriter.pos(); | |
| 632 | + if (capacity < 0) | |
| 633 | + qFatal("Negative capacity!!!"); | |
| 599 | 634 | |
| 600 | 635 | // don't try to write beyond capacity |
| 601 | 636 | qint64 write_size = qMin(capacity, remaining); |
| 602 | 637 | |
| 603 | - qint64 singleWrite = precompressedBlockWriter->write(data, write_size); | |
| 604 | - // ignore the error case here, we consdier basis's failure mode the real | |
| 605 | - // end case | |
| 638 | + qint64 singleWrite = precompressedBlockWriter.write(data, write_size); | |
| 639 | + | |
| 606 | 640 | if (singleWrite == -1) |
| 607 | - singleWrite = 0; | |
| 641 | + qFatal("matrix write failure?"); | |
| 608 | 642 | |
| 609 | 643 | remaining -= singleWrite; |
| 610 | 644 | data += singleWrite; |
| 611 | 645 | written += singleWrite; |
| 646 | + if (data > endPoint) | |
| 647 | + qFatal("Wrote past the end"); | |
| 612 | 648 | |
| 613 | 649 | if (remaining > 0) { |
| 614 | - QByteArray compressedBlock = qCompress(precompressedBlockWriter->buffer(), -1); | |
| 650 | + QByteArray compressedBlock = qCompress(precompressedBlockWriter.buffer(), -1); | |
| 615 | 651 | |
| 616 | - if (compressedBlock.size() != 0) | |
| 617 | - blockWriter << compressedBlock; | |
| 652 | + if (precompressedBlockWriter.buffer().size() != 0) { | |
| 653 | + quint32 block_size = compressedBlock.size(); | |
| 654 | + blockWriter << block_size; | |
| 618 | 655 | |
| 619 | - delete precompressedBlockWriter; | |
| 620 | - precompressedBlockWriter = new QBuffer; | |
| 621 | - precompressedBlockWriter->open(QIODevice::ReadWrite); | |
| 656 | + int write_count = blockWriter.writeRawData(compressedBlock.data(), block_size); | |
| 657 | + if (write_count != block_size) | |
| 658 | + qFatal("Didn't write enough data"); | |
| 659 | + } | |
| 660 | + else | |
| 661 | + qFatal("serialized empty compressed block (?)"); | |
| 662 | + | |
| 663 | + precompressedBlockWriter.close(); | |
| 664 | + precompressedBlockWriter.open(QIODevice::WriteOnly); | |
| 622 | 665 | } |
| 623 | 666 | } |
| 667 | + | |
| 668 | + if (written != initial) | |
| 669 | + qFatal("didn't write enough bytes"); | |
| 670 | + | |
| 671 | + bool condition = basis->isWritable(); | |
| 672 | + if (!condition) | |
| 673 | + qWarning("Returning -1 from write"); | |
| 674 | + | |
| 624 | 675 | return basis->isWritable() ? written : -1; |
| 625 | 676 | } |
| 626 | 677 | ... | ... |
openbr/core/qtutils.h
| ... | ... | @@ -122,7 +122,7 @@ namespace QtUtils |
| 122 | 122 | |
| 123 | 123 | // write to a QByteArray, when max block sized is reached, compress and write |
| 124 | 124 | // it to basis |
| 125 | - QBuffer * precompressedBlockWriter; | |
| 125 | + QBuffer precompressedBlockWriter; | |
| 126 | 126 | QDataStream blockWriter; |
| 127 | 127 | qint64 writeData(const char *data, qint64 remaining); |
| 128 | 128 | }; | ... | ... |
openbr/plugins/gallery/binary.cpp
| ... | ... | @@ -247,7 +247,8 @@ class utGallery : public BinaryGallery |
| 247 | 247 | const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get<int32_t>("AlgorithmID"); |
| 248 | 248 | const QByteArray url = t.file.get<QString>("URL", t.file.name).toLatin1(); |
| 249 | 249 | |
| 250 | - uint32_t x = 0, y = 0, width = 0, height = 0; | |
| 250 | + int32_t x = 0, y = 0; | |
| 251 | + uint32_t width = 0, height = 0; | |
| 251 | 252 | QByteArray header; |
| 252 | 253 | if ((algorithmID <= -1) && (algorithmID >= -3)) { |
| 253 | 254 | const QRectF frontalFace = t.file.get<QRectF>("FrontalFace"); |
| ... | ... | @@ -268,8 +269,8 @@ class utGallery : public BinaryGallery |
| 268 | 269 | header.append((const char*)&leftEyeX , sizeof(uint32_t)); |
| 269 | 270 | header.append((const char*)&leftEyeY , sizeof(uint32_t)); |
| 270 | 271 | } else { |
| 271 | - x = t.file.get<uint32_t>("X", 0); | |
| 272 | - y = t.file.get<uint32_t>("Y", 0); | |
| 272 | + x = t.file.get<int32_t>("X", 0); | |
| 273 | + y = t.file.get<int32_t>("Y", 0); | |
| 273 | 274 | width = t.file.get<uint32_t>("Width", 0); |
| 274 | 275 | height = t.file.get<uint32_t>("Height", 0); |
| 275 | 276 | } |
| ... | ... | @@ -277,8 +278,8 @@ class utGallery : public BinaryGallery |
| 277 | 278 | |
| 278 | 279 | gallery.write(imageID); |
| 279 | 280 | gallery.write((const char*) &algorithmID, sizeof(int32_t)); |
| 280 | - gallery.write((const char*) &x , sizeof(uint32_t)); | |
| 281 | - gallery.write((const char*) &y , sizeof(uint32_t)); | |
| 281 | + gallery.write((const char*) &x , sizeof(int32_t)); | |
| 282 | + gallery.write((const char*) &y , sizeof(int32_t)); | |
| 282 | 283 | gallery.write((const char*) &width , sizeof(uint32_t)); |
| 283 | 284 | gallery.write((const char*) &height , sizeof(uint32_t)); |
| 284 | 285 | gallery.write((const char*) &label , sizeof(uint32_t)); | ... | ... |
openbr/plugins/imgproc/revertaffine.cpp
openbr/universal_template.cpp
| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | |
| 9 | 9 | #include "universal_template.h" |
| 10 | 10 | |
| 11 | -br_utemplate br_new_utemplate(const char *imageID, int32_t algorithmID, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t label, const char *url, const char *fv, uint32_t fvSize) | |
| 11 | +br_utemplate br_new_utemplate(const char *imageID, int32_t algorithmID, int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t label, const char *url, const char *fv, uint32_t fvSize) | |
| 12 | 12 | { |
| 13 | 13 | const uint32_t urlSize = strlen(url) + 1; |
| 14 | 14 | br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + urlSize + fvSize); | ... | ... |
openbr/universal_template.h
| ... | ... | @@ -37,8 +37,8 @@ struct br_universal_template |
| 37 | 37 | { |
| 38 | 38 | unsigned char imageID[16]; /*!< MD5 hash of the undecoded origin file. */ |
| 39 | 39 | int32_t algorithmID; /*!< interpretation of _data_ after _urlSize_. */ |
| 40 | - uint32_t x; /*!< region of interest horizontal offset (pixels). */ | |
| 41 | - uint32_t y; /*!< region of interest vertical offset (pixels). */ | |
| 40 | + int32_t x; /*!< region of interest horizontal offset (pixels). */ | |
| 41 | + int32_t y; /*!< region of interest vertical offset (pixels). */ | |
| 42 | 42 | uint32_t width; /*!< region of interest horizontal size (pixels). */ |
| 43 | 43 | uint32_t height; /*!< region of interest vertical size (pixels). */ |
| 44 | 44 | uint32_t label; /*!< supervised training class or manually annotated ground truth. */ |
| ... | ... | @@ -57,7 +57,7 @@ typedef const struct br_universal_template *br_const_utemplate; |
| 57 | 57 | * \brief br_universal_template constructor. |
| 58 | 58 | * \see br_free_utemplate |
| 59 | 59 | */ |
| 60 | -BR_EXPORT br_utemplate br_new_utemplate(const char *imageID, int32_t algorithmID, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t label, const char *url, const char *fv, uint32_t fvSize); | |
| 60 | +BR_EXPORT br_utemplate br_new_utemplate(const char *imageID, int32_t algorithmID, int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t label, const char *url, const char *fv, uint32_t fvSize); | |
| 61 | 61 | |
| 62 | 62 | /*! |
| 63 | 63 | * \brief br_universal_template destructor. | ... | ... |