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,14 +500,15 @@ QString getAbsolutePath(const QString &filename) | ||
| 500 | return QFileInfo(filename).absoluteFilePath(); | 500 | return QFileInfo(filename).absoluteFilePath(); |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | +const int base_block = 100000000; | ||
| 504 | + | ||
| 503 | BlockCompression::BlockCompression(QIODevice *_basis) | 505 | BlockCompression::BlockCompression(QIODevice *_basis) |
| 504 | { | 506 | { |
| 505 | - blockSize = 100000000; | 507 | + blockSize = base_block; |
| 506 | setBasis(_basis); | 508 | setBasis(_basis); |
| 507 | } | 509 | } |
| 508 | 510 | ||
| 509 | -BlockCompression::BlockCompression() { blockSize = 100000000; }; | ||
| 510 | - | 511 | +BlockCompression::BlockCompression() { blockSize = base_block;}; |
| 511 | 512 | ||
| 512 | bool BlockCompression::open(QIODevice::OpenMode mode) | 513 | bool BlockCompression::open(QIODevice::OpenMode mode) |
| 513 | { | 514 | { |
| @@ -521,14 +522,22 @@ bool BlockCompression::open(QIODevice::OpenMode mode) | @@ -521,14 +522,22 @@ bool BlockCompression::open(QIODevice::OpenMode mode) | ||
| 521 | blockWriter.setDevice(basis); | 522 | blockWriter.setDevice(basis); |
| 522 | 523 | ||
| 523 | if (mode & QIODevice::WriteOnly) { | 524 | if (mode & QIODevice::WriteOnly) { |
| 524 | - precompressedBlockWriter = new QBuffer; | ||
| 525 | - precompressedBlockWriter->open(QIODevice::ReadWrite); | 525 | + precompressedBlockWriter.open(QIODevice::WriteOnly); |
| 526 | } | 526 | } |
| 527 | else if (mode & QIODevice::ReadOnly) { | 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 | QByteArray compressedBlock; | 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 | decompressedBlock = qUncompress(compressedBlock); | 539 | decompressedBlock = qUncompress(compressedBlock); |
| 540 | + | ||
| 532 | decompressedBlockReader.setBuffer(&decompressedBlock); | 541 | decompressedBlockReader.setBuffer(&decompressedBlock); |
| 533 | decompressedBlockReader.open(QIODevice::ReadOnly); | 542 | decompressedBlockReader.open(QIODevice::ReadOnly); |
| 534 | } | 543 | } |
| @@ -538,11 +547,17 @@ bool BlockCompression::open(QIODevice::OpenMode mode) | @@ -538,11 +547,17 @@ bool BlockCompression::open(QIODevice::OpenMode mode) | ||
| 538 | 547 | ||
| 539 | void BlockCompression::close() | 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 | basis->close(); | 561 | basis->close(); |
| 547 | } | 562 | } |
| 548 | 563 | ||
| @@ -557,8 +572,10 @@ void BlockCompression::setBasis(QIODevice *_basis) | @@ -557,8 +572,10 @@ void BlockCompression::setBasis(QIODevice *_basis) | ||
| 557 | // block from basis | 572 | // block from basis |
| 558 | qint64 BlockCompression::readData(char *data, qint64 remaining) | 573 | qint64 BlockCompression::readData(char *data, qint64 remaining) |
| 559 | { | 574 | { |
| 575 | + qint64 initial = remaining; | ||
| 560 | qint64 read = 0; | 576 | qint64 read = 0; |
| 561 | while (remaining > 0) { | 577 | while (remaining > 0) { |
| 578 | + // attempt to read the target amount of data | ||
| 562 | qint64 single_read = decompressedBlockReader.read(data, remaining); | 579 | qint64 single_read = decompressedBlockReader.read(data, remaining); |
| 563 | if (single_read == -1) | 580 | if (single_read == -1) |
| 564 | qFatal("miss read"); | 581 | qFatal("miss read"); |
| @@ -567,13 +584,21 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) | @@ -567,13 +584,21 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) | ||
| 567 | read += single_read; | 584 | read += single_read; |
| 568 | data += single_read; | 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 | if (remaining > 0) { | 588 | if (remaining > 0) { |
| 572 | QByteArray compressedBlock; | 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 | decompressedBlock = qUncompress(compressedBlock); | 602 | decompressedBlock = qUncompress(compressedBlock); |
| 578 | 603 | ||
| 579 | decompressedBlockReader.close(); | 604 | decompressedBlockReader.close(); |
| @@ -581,7 +606,12 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) | @@ -581,7 +606,12 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) | ||
| 581 | decompressedBlockReader.open(QIODevice::ReadOnly); | 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 | bool BlockCompression::isSequential() const | 617 | bool BlockCompression::isSequential() const |
| @@ -591,36 +621,57 @@ bool BlockCompression::isSequential() const | @@ -591,36 +621,57 @@ bool BlockCompression::isSequential() const | ||
| 591 | 621 | ||
| 592 | qint64 BlockCompression::writeData(const char *data, qint64 remaining) | 622 | qint64 BlockCompression::writeData(const char *data, qint64 remaining) |
| 593 | { | 623 | { |
| 624 | + const char * endPoint = data + remaining; | ||
| 625 | + qint64 initial = remaining; | ||
| 626 | + | ||
| 594 | qint64 written = 0; | 627 | qint64 written = 0; |
| 595 | 628 | ||
| 596 | while (remaining > 0) { | 629 | while (remaining > 0) { |
| 597 | // how much more can be put in this buffer? | 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 | // don't try to write beyond capacity | 635 | // don't try to write beyond capacity |
| 601 | qint64 write_size = qMin(capacity, remaining); | 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 | if (singleWrite == -1) | 640 | if (singleWrite == -1) |
| 607 | - singleWrite = 0; | 641 | + qFatal("matrix write failure?"); |
| 608 | 642 | ||
| 609 | remaining -= singleWrite; | 643 | remaining -= singleWrite; |
| 610 | data += singleWrite; | 644 | data += singleWrite; |
| 611 | written += singleWrite; | 645 | written += singleWrite; |
| 646 | + if (data > endPoint) | ||
| 647 | + qFatal("Wrote past the end"); | ||
| 612 | 648 | ||
| 613 | if (remaining > 0) { | 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 | return basis->isWritable() ? written : -1; | 675 | return basis->isWritable() ? written : -1; |
| 625 | } | 676 | } |
| 626 | 677 |
openbr/core/qtutils.h
| @@ -122,7 +122,7 @@ namespace QtUtils | @@ -122,7 +122,7 @@ namespace QtUtils | ||
| 122 | 122 | ||
| 123 | // write to a QByteArray, when max block sized is reached, compress and write | 123 | // write to a QByteArray, when max block sized is reached, compress and write |
| 124 | // it to basis | 124 | // it to basis |
| 125 | - QBuffer * precompressedBlockWriter; | 125 | + QBuffer precompressedBlockWriter; |
| 126 | QDataStream blockWriter; | 126 | QDataStream blockWriter; |
| 127 | qint64 writeData(const char *data, qint64 remaining); | 127 | qint64 writeData(const char *data, qint64 remaining); |
| 128 | }; | 128 | }; |
openbr/plugins/gallery/binary.cpp
| @@ -247,7 +247,8 @@ class utGallery : public BinaryGallery | @@ -247,7 +247,8 @@ class utGallery : public BinaryGallery | ||
| 247 | const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get<int32_t>("AlgorithmID"); | 247 | const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get<int32_t>("AlgorithmID"); |
| 248 | const QByteArray url = t.file.get<QString>("URL", t.file.name).toLatin1(); | 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 | QByteArray header; | 252 | QByteArray header; |
| 252 | if ((algorithmID <= -1) && (algorithmID >= -3)) { | 253 | if ((algorithmID <= -1) && (algorithmID >= -3)) { |
| 253 | const QRectF frontalFace = t.file.get<QRectF>("FrontalFace"); | 254 | const QRectF frontalFace = t.file.get<QRectF>("FrontalFace"); |
| @@ -268,8 +269,8 @@ class utGallery : public BinaryGallery | @@ -268,8 +269,8 @@ class utGallery : public BinaryGallery | ||
| 268 | header.append((const char*)&leftEyeX , sizeof(uint32_t)); | 269 | header.append((const char*)&leftEyeX , sizeof(uint32_t)); |
| 269 | header.append((const char*)&leftEyeY , sizeof(uint32_t)); | 270 | header.append((const char*)&leftEyeY , sizeof(uint32_t)); |
| 270 | } else { | 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 | width = t.file.get<uint32_t>("Width", 0); | 274 | width = t.file.get<uint32_t>("Width", 0); |
| 274 | height = t.file.get<uint32_t>("Height", 0); | 275 | height = t.file.get<uint32_t>("Height", 0); |
| 275 | } | 276 | } |
| @@ -277,8 +278,8 @@ class utGallery : public BinaryGallery | @@ -277,8 +278,8 @@ class utGallery : public BinaryGallery | ||
| 277 | 278 | ||
| 278 | gallery.write(imageID); | 279 | gallery.write(imageID); |
| 279 | gallery.write((const char*) &algorithmID, sizeof(int32_t)); | 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 | gallery.write((const char*) &width , sizeof(uint32_t)); | 283 | gallery.write((const char*) &width , sizeof(uint32_t)); |
| 283 | gallery.write((const char*) &height , sizeof(uint32_t)); | 284 | gallery.write((const char*) &height , sizeof(uint32_t)); |
| 284 | gallery.write((const char*) &label , sizeof(uint32_t)); | 285 | gallery.write((const char*) &label , sizeof(uint32_t)); |
openbr/plugins/imgproc/revertaffine.cpp
openbr/universal_template.cpp
| @@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
| 8 | 8 | ||
| 9 | #include "universal_template.h" | 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 | const uint32_t urlSize = strlen(url) + 1; | 13 | const uint32_t urlSize = strlen(url) + 1; |
| 14 | br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + urlSize + fvSize); | 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,8 +37,8 @@ struct br_universal_template | ||
| 37 | { | 37 | { |
| 38 | unsigned char imageID[16]; /*!< MD5 hash of the undecoded origin file. */ | 38 | unsigned char imageID[16]; /*!< MD5 hash of the undecoded origin file. */ |
| 39 | int32_t algorithmID; /*!< interpretation of _data_ after _urlSize_. */ | 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 | uint32_t width; /*!< region of interest horizontal size (pixels). */ | 42 | uint32_t width; /*!< region of interest horizontal size (pixels). */ |
| 43 | uint32_t height; /*!< region of interest vertical size (pixels). */ | 43 | uint32_t height; /*!< region of interest vertical size (pixels). */ |
| 44 | uint32_t label; /*!< supervised training class or manually annotated ground truth. */ | 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,7 +57,7 @@ typedef const struct br_universal_template *br_const_utemplate; | ||
| 57 | * \brief br_universal_template constructor. | 57 | * \brief br_universal_template constructor. |
| 58 | * \see br_free_utemplate | 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 | * \brief br_universal_template destructor. | 63 | * \brief br_universal_template destructor. |