Commit ec66957c5152a6a876403f13c4c6892482a3f0b4

Authored by Jordan Cheney
2 parents 4e1574bb 7b815975

Merge branch 'master' of https://github.com/biometrics/openbr

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
@@ -43,4 +43,4 @@ BR_REGISTER(Transform, RevertAffineTransform) @@ -43,4 +43,4 @@ BR_REGISTER(Transform, RevertAffineTransform)
43 43
44 } // namespace br 44 } // namespace br
45 45
46 -#include "imgproc/revertaffine.cpp" 46 +#include "imgproc/revertaffine.moc"
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.