diff --git a/openbr/core/qtutils.cpp b/openbr/core/qtutils.cpp index fdfd004..9203c71 100644 --- a/openbr/core/qtutils.cpp +++ b/openbr/core/qtutils.cpp @@ -500,14 +500,15 @@ QString getAbsolutePath(const QString &filename) return QFileInfo(filename).absoluteFilePath(); } +const int base_block = 100000000; + BlockCompression::BlockCompression(QIODevice *_basis) { - blockSize = 100000000; + blockSize = base_block; setBasis(_basis); } -BlockCompression::BlockCompression() { blockSize = 100000000; }; - +BlockCompression::BlockCompression() { blockSize = base_block;}; bool BlockCompression::open(QIODevice::OpenMode mode) { @@ -521,14 +522,22 @@ bool BlockCompression::open(QIODevice::OpenMode mode) blockWriter.setDevice(basis); if (mode & QIODevice::WriteOnly) { - precompressedBlockWriter = new QBuffer; - precompressedBlockWriter->open(QIODevice::ReadWrite); + precompressedBlockWriter.open(QIODevice::WriteOnly); } else if (mode & QIODevice::ReadOnly) { + + // Read an initial compressed block from the underlying QIODevice, + // decompress, and set up a reader on it QByteArray compressedBlock; - blockReader >> compressedBlock; + quint32 block_size; + blockReader >> block_size; + compressedBlock.resize(block_size); + int read_count = blockReader.readRawData(compressedBlock.data(), block_size); + if (read_count != block_size) + qFatal("Failed to read initial block"); decompressedBlock = qUncompress(compressedBlock); + decompressedBlockReader.setBuffer(&decompressedBlock); decompressedBlockReader.open(QIODevice::ReadOnly); } @@ -538,11 +547,17 @@ bool BlockCompression::open(QIODevice::OpenMode mode) void BlockCompression::close() { - // flush output buffer - if ((openMode() & QIODevice::WriteOnly) && precompressedBlockWriter) { - QByteArray compressedBlock = qCompress(precompressedBlockWriter->buffer(), -1); - blockWriter << compressedBlock; + // flush output buffer, since we may have a partial block which hasn't been + // written to disk yet. + if ((openMode() & QIODevice::WriteOnly) && precompressedBlockWriter.isOpen()) { + QByteArray compressedBlock = qCompress(precompressedBlockWriter.buffer()); + precompressedBlockWriter.close(); + + quint32 bsize= compressedBlock.size(); + blockWriter << bsize; + blockWriter.writeRawData(compressedBlock.data(), compressedBlock.size()); } + // close the underlying device. basis->close(); } @@ -557,8 +572,10 @@ void BlockCompression::setBasis(QIODevice *_basis) // block from basis qint64 BlockCompression::readData(char *data, qint64 remaining) { + qint64 initial = remaining; qint64 read = 0; while (remaining > 0) { + // attempt to read the target amount of data qint64 single_read = decompressedBlockReader.read(data, remaining); if (single_read == -1) qFatal("miss read"); @@ -567,13 +584,21 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) read += single_read; data += single_read; - // need a new block + // need a new block if we didn't get enough bytes from the previous read if (remaining > 0) { QByteArray compressedBlock; - blockReader >> compressedBlock; - if (compressedBlock.size() == 0) { - return read; - } + + // read the size of the next block + quint32 block_size; + blockReader >> block_size; + if (block_size == 0) + break; + + compressedBlock.resize(block_size); + int actualRead = blockReader.readRawData(compressedBlock.data(), block_size); + if (actualRead != block_size) + qFatal("Bad read on nominal block size: %d, only got %d", block_size, remaining); + decompressedBlock = qUncompress(compressedBlock); decompressedBlockReader.close(); @@ -581,7 +606,12 @@ qint64 BlockCompression::readData(char *data, qint64 remaining) decompressedBlockReader.open(QIODevice::ReadOnly); } } - return blockReader.atEnd() && !basis->isReadable() ? -1 : read; + + bool condition = blockReader.atEnd() && !basis->isReadable() ; + if (condition) + qWarning("Returning -1 from read"); + + return condition ? -1 : read; } bool BlockCompression::isSequential() const @@ -591,36 +621,57 @@ bool BlockCompression::isSequential() const qint64 BlockCompression::writeData(const char *data, qint64 remaining) { + const char * endPoint = data + remaining; + qint64 initial = remaining; + qint64 written = 0; while (remaining > 0) { // how much more can be put in this buffer? - qint64 capacity = blockSize - precompressedBlockWriter->pos(); + qint64 capacity = blockSize - precompressedBlockWriter.pos(); + if (capacity < 0) + qFatal("Negative capacity!!!"); // don't try to write beyond capacity qint64 write_size = qMin(capacity, remaining); - qint64 singleWrite = precompressedBlockWriter->write(data, write_size); - // ignore the error case here, we consdier basis's failure mode the real - // end case + qint64 singleWrite = precompressedBlockWriter.write(data, write_size); + if (singleWrite == -1) - singleWrite = 0; + qFatal("matrix write failure?"); remaining -= singleWrite; data += singleWrite; written += singleWrite; + if (data > endPoint) + qFatal("Wrote past the end"); if (remaining > 0) { - QByteArray compressedBlock = qCompress(precompressedBlockWriter->buffer(), -1); + QByteArray compressedBlock = qCompress(precompressedBlockWriter.buffer(), -1); - if (compressedBlock.size() != 0) - blockWriter << compressedBlock; + if (precompressedBlockWriter.buffer().size() != 0) { + quint32 block_size = compressedBlock.size(); + blockWriter << block_size; - delete precompressedBlockWriter; - precompressedBlockWriter = new QBuffer; - precompressedBlockWriter->open(QIODevice::ReadWrite); + int write_count = blockWriter.writeRawData(compressedBlock.data(), block_size); + if (write_count != block_size) + qFatal("Didn't write enough data"); + } + else + qFatal("serialized empty compressed block (?)"); + + precompressedBlockWriter.close(); + precompressedBlockWriter.open(QIODevice::WriteOnly); } } + + if (written != initial) + qFatal("didn't write enough bytes"); + + bool condition = basis->isWritable(); + if (!condition) + qWarning("Returning -1 from write"); + return basis->isWritable() ? written : -1; } diff --git a/openbr/core/qtutils.h b/openbr/core/qtutils.h index 257ccd8..fc93059 100644 --- a/openbr/core/qtutils.h +++ b/openbr/core/qtutils.h @@ -122,7 +122,7 @@ namespace QtUtils // write to a QByteArray, when max block sized is reached, compress and write // it to basis - QBuffer * precompressedBlockWriter; + QBuffer precompressedBlockWriter; QDataStream blockWriter; qint64 writeData(const char *data, qint64 remaining); }; diff --git a/openbr/plugins/gallery/binary.cpp b/openbr/plugins/gallery/binary.cpp index c8229f4..b2c30b3 100644 --- a/openbr/plugins/gallery/binary.cpp +++ b/openbr/plugins/gallery/binary.cpp @@ -247,7 +247,8 @@ class utGallery : public BinaryGallery const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get("AlgorithmID"); const QByteArray url = t.file.get("URL", t.file.name).toLatin1(); - uint32_t x = 0, y = 0, width = 0, height = 0; + int32_t x = 0, y = 0; + uint32_t width = 0, height = 0; QByteArray header; if ((algorithmID <= -1) && (algorithmID >= -3)) { const QRectF frontalFace = t.file.get("FrontalFace"); @@ -268,8 +269,8 @@ class utGallery : public BinaryGallery header.append((const char*)&leftEyeX , sizeof(uint32_t)); header.append((const char*)&leftEyeY , sizeof(uint32_t)); } else { - x = t.file.get("X", 0); - y = t.file.get("Y", 0); + x = t.file.get("X", 0); + y = t.file.get("Y", 0); width = t.file.get("Width", 0); height = t.file.get("Height", 0); } @@ -277,8 +278,8 @@ class utGallery : public BinaryGallery gallery.write(imageID); gallery.write((const char*) &algorithmID, sizeof(int32_t)); - gallery.write((const char*) &x , sizeof(uint32_t)); - gallery.write((const char*) &y , sizeof(uint32_t)); + gallery.write((const char*) &x , sizeof(int32_t)); + gallery.write((const char*) &y , sizeof(int32_t)); gallery.write((const char*) &width , sizeof(uint32_t)); gallery.write((const char*) &height , sizeof(uint32_t)); gallery.write((const char*) &label , sizeof(uint32_t)); diff --git a/openbr/plugins/imgproc/revertaffine.cpp b/openbr/plugins/imgproc/revertaffine.cpp index b40c581..868fa3b 100644 --- a/openbr/plugins/imgproc/revertaffine.cpp +++ b/openbr/plugins/imgproc/revertaffine.cpp @@ -43,4 +43,4 @@ BR_REGISTER(Transform, RevertAffineTransform) } // namespace br -#include "imgproc/revertaffine.cpp" +#include "imgproc/revertaffine.moc" diff --git a/openbr/universal_template.cpp b/openbr/universal_template.cpp index 79731ac..8b7d18d 100644 --- a/openbr/universal_template.cpp +++ b/openbr/universal_template.cpp @@ -8,7 +8,7 @@ #include "universal_template.h" -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) +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) { const uint32_t urlSize = strlen(url) + 1; br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + urlSize + fvSize); diff --git a/openbr/universal_template.h b/openbr/universal_template.h index 979871d..733175e 100644 --- a/openbr/universal_template.h +++ b/openbr/universal_template.h @@ -37,8 +37,8 @@ struct br_universal_template { unsigned char imageID[16]; /*!< MD5 hash of the undecoded origin file. */ int32_t algorithmID; /*!< interpretation of _data_ after _urlSize_. */ - uint32_t x; /*!< region of interest horizontal offset (pixels). */ - uint32_t y; /*!< region of interest vertical offset (pixels). */ + int32_t x; /*!< region of interest horizontal offset (pixels). */ + int32_t y; /*!< region of interest vertical offset (pixels). */ uint32_t width; /*!< region of interest horizontal size (pixels). */ uint32_t height; /*!< region of interest vertical size (pixels). */ uint32_t label; /*!< supervised training class or manually annotated ground truth. */ @@ -57,7 +57,7 @@ typedef const struct br_universal_template *br_const_utemplate; * \brief br_universal_template constructor. * \see br_free_utemplate */ -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); +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); /*! * \brief br_universal_template destructor.