Commit c3d42c2d authored by Philip A. Chou's avatar Philip A. Chou Committed by David Flynn
Browse files

m42634/tmc1: add mode to invoke TMC1 geometry compression

This commit does not add the triangle soup geometry compressor to TMC3,
rather.  Rather, it adds a means to call out to TMC1 binaries to perform
the compression, integrate the results into the bitstream.

Attribute compression is performed natively by the TMC13 codec.
parent 995703d8
......@@ -65,3 +65,19 @@ mpeg-pcc-tmc13$ make -f $PWD/scripts/Makefile.tmc13-step \
[md5sum] Ford_01_vox1mm-0100.ply.bin.decoded.ply.md5
[metric] Ford_01_vox1mm-0100.ply.bin.decoded.ply.pc_error <- Ford_01_vox1mm-0100.ply.bin.decoded.ply
```
## Notes regarding TMC1 functionality
NB: this applies to "Triangle Soup" geometry encoding only.
This implementation currently requires TMC1 in order to perform the data
compression. The following TMC1 (windows) binaries may be used to
install TMC1:
- `TMC1/tags/release-v1.1/TMC1_coordinateTransform/for_redistribution/MyAppInstaller_web.exe`
- `TMC1/tags/release-v1.1/TMC1_geometryEncode/for_redistribution/MyAppInstaller_web.exe`
- `TMC1/tags/release-v1.1/TMC1_geometryDecode/for_redistribution/MyAppInstaller_web.exe`
- `TMC1/tags/release-v1.1/TMC1_voxelize/for_redistribution/MyAppInstaller_web.exe`
- `TMC1/tags/release-v1.1/TMC1_colorEncode/for_redistribution/MyAppInstaller_web.exe`
- `TMC1/tags/release-v1.1/TMC1_colorDecode/for_redistribution/MyAppInstaller_web.exe`
......@@ -5,6 +5,10 @@ if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:tbb.lib")
endif()
if (UNIX)
add_definitions(-D_POSIX_C_SOURCE=200809L)
endif()
include(CheckSymbolExists)
check_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE)
......@@ -66,6 +70,7 @@ file(GLOB PROJECT_INC_FILES
"PCCTMC3Encoder.h"
"RAHT.h"
"TMC3.h"
"osspecific.h"
"pcc_chrono.h"
"ringbuf.h"
"tables.h"
......@@ -81,6 +86,7 @@ file(GLOB PROJECT_CPP_FILES
"AttributeEncoder.cpp"
"RAHT.cpp"
"TMC3.cpp"
"osspecific.cpp"
"pcc_chrono.cpp"
"tables.cpp"
"../dependencies/arithmetic-coding/src/*.cpp"
......
......@@ -470,7 +470,7 @@ class PCCPointSet3 {
return true;
}
bool read(const std::string &fileName) {
std::ifstream ifs(fileName, std::ifstream::in);
std::ifstream ifs(fileName, std::ifstream::in | std::ifstream::binary);
if (!ifs.is_open()) {
return false;
}
......
......@@ -45,6 +45,7 @@
#include "PCCMisc.h"
#include "PCCPointSet.h"
#include "PCCTMC3Common.h"
#include "osspecific.h"
#include "ArithmeticCodec.h"
#include "tables.h"
......@@ -182,6 +183,105 @@ class PCCTMC3Decoder3 {
return 0;
}
int decompressWithTrisoupGeometry(PCCBitstream &bitstream, PCCPointSet3 &pointCloud,
const bool roundOutputPositions) {
init();
uint32_t magicNumber = 0;
uint32_t formatVersion = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, magicNumber, bitstream.size);
if (magicNumber != PCCTMC3MagicNumber) {
std::cout << "Error: corrupted bistream!" << std::endl;
return -1;
}
PCCReadFromBuffer<uint32_t>(bitstream.buffer, formatVersion, bitstream.size);
if (formatVersion != PCCTMC3FormatVersion) {
std::cout << "Error: bistream version not supported!" << std::endl;
return -1;
}
uint64_t positionsSize = bitstream.size;
size_t depth;
size_t level;
double intToOrigScale;
PCCPoint3D intToOrigTranslation;
if (int ret = decodeTrisoupHeader(bitstream, pointCloud, depth, level, intToOrigScale,
intToOrigTranslation)) {
return ret;
}
// Write out TMC1 geometry bitstream from the converged TMC13 bitstream.
uint32_t binSize = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, binSize, bitstream.size);
std::ofstream fout("outbin/outbin_0000.bin", std::ios::binary);
if (!fout.is_open()) {
// maybe because directory does not exist; try again...
pcc::mkdir("outbin");
fout.open("outbin/outbin_0000.bin", std::ios::binary);
if (!fout.is_open()) return -1;
}
fout.write(reinterpret_cast<char *>(&bitstream.buffer[bitstream.size]), binSize);
if (!fout) {
return -1;
}
bitstream.size += binSize;
fout.close();
positionsSize = bitstream.size - positionsSize;
std::cout << "positions bitstream size " << positionsSize << " B" << std::endl;
// Decompress geometry with TMC1.
std::string cmd;
cmd = "7z e -aoa -bso0 -ooutbin outbin/outbin_0000.bin";
system(cmd.c_str());
cmd = "TMC1_geometryDecode -inbin outbin\\outbin -outref refinedVerticesDecoded.ply";
cmd += " -depth " + std::to_string(depth) + " -level " + std::to_string(level) +
" -format binary_little_endian";
system(cmd.c_str());
cmd = "TMC1_voxelize -inref refinedVerticesDecoded.ply -outvox quantizedPointCloudDecoded.ply";
cmd += " -depth " + std::to_string(depth) + " -format binary_little_endian";
system(cmd.c_str());
pointCloud.read("quantizedPointCloudDecoded.ply");
pointCloud.addColors();
pointCloud.removeReflectances();
if (pointCloud.hasColors()) {
AttributeDecoder attrDecoder;
uint64_t colorsSize = bitstream.size;
if (int ret = attrDecoder.decodeHeader("color", bitstream)) {
return ret;
}
attrDecoder.buildPredictors(pointCloud);
if (int ret = attrDecoder.decodeColors(bitstream, pointCloud)) {
return ret;
}
colorsSize = bitstream.size - colorsSize;
std::cout << "colors bitstream size " << colorsSize << " B" << std::endl;
std::cout << std::endl;
}
if (pointCloud.hasReflectances()) {
AttributeDecoder attrDecoder;
uint64_t reflectancesSize = bitstream.size;
if (int ret = attrDecoder.decodeHeader("reflectance", bitstream)) {
return ret;
}
attrDecoder.buildPredictors(pointCloud);
if (int ret = attrDecoder.decodeReflectances(bitstream, pointCloud)) {
return ret;
}
reflectancesSize = bitstream.size - reflectancesSize;
std::cout << "reflectances bitstream size " << reflectancesSize << " B" << std::endl;
}
// Optionally write out point cloud with lossy geometry and lossy color, for later comparison.
pcc::PCCPointSet3 tempPointCloud(pointCloud);
tempPointCloud.convertYUVToRGB();
tempPointCloud.write("decodedVoxelsAndDecodedColors.ply");
inverseQuantization(pointCloud, roundOutputPositions);
return 0;
}
private:
int decodePositionsHeader(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) {
uint32_t pointCount = 0;
......@@ -227,6 +327,44 @@ class PCCTMC3Decoder3 {
return 0;
}
int decodeTrisoupHeader(PCCBitstream &bitstream, PCCPointSet3 &pointCloud, size_t &depth,
size_t &level, double &intToOrigScale, PCCPoint3D &intToOrigTranslation) {
uint32_t pointCount = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, pointCount, bitstream.size);
uint8_t hasColors = 0;
PCCReadFromBuffer<uint8_t>(bitstream.buffer, hasColors, bitstream.size);
uint8_t hasReflectances = 0;
PCCReadFromBuffer<uint8_t>(bitstream.buffer, hasReflectances, bitstream.size);
if (hasColors) {
pointCloud.addColors();
} else {
pointCloud.removeColors();
}
if (hasReflectances) {
pointCloud.addReflectances();
} else {
pointCloud.removeReflectances();
}
pointCloud.resize(pointCount);
for (int k = 0; k < 3; ++k) {
PCCReadFromBuffer<double>(bitstream.buffer, minPositions[k], bitstream.size);
}
for (int k = 0; k < 3; ++k) {
PCCReadFromBuffer<uint32_t>(bitstream.buffer, boundingBox.max[k], bitstream.size);
}
PCCReadFromBuffer<double>(bitstream.buffer, positionQuantizationScale, bitstream.size);
const double minPositionQuantizationScale = 0.0000000001;
if (fabs(positionQuantizationScale) < minPositionQuantizationScale) {
positionQuantizationScale = 1.0;
}
PCCReadFromBuffer<size_t>(bitstream.buffer, depth, bitstream.size);
PCCReadFromBuffer<size_t>(bitstream.buffer, level, bitstream.size);
PCCReadFromBuffer<double>(bitstream.buffer, intToOrigScale, bitstream.size);
PCCReadFromBuffer<PCCPoint3D>(bitstream.buffer, intToOrigTranslation, bitstream.size);
return 0;
}
//-------------------------------------------------------------------------
// Decode the number of points in a leaf node of the octree.
......
......@@ -67,6 +67,21 @@ struct PCCTMC3Encoder3Parameters {
// by directly coding the position of isolated points.
bool inferredDirectCodingModeEnabled;
struct TriSoup {
// depth of voxels (reconstructed points) in trisoup geometry
int depth;
// level of triangles (reconstructed surface) in trisoup geometry
int level;
// orig_coords = integer_coords * intToOrigScale + intToOrigTranslation
double intToOrigScale;
// orig_coords = integer_coords * intToOrigScale + intToOrigTranslation
// todo(df): convert to PCCVector3
std::vector<double> intToOrigTranslation;
} triSoup;
std::map<std::string, PCCAttributeEncodeParamaters> attributeEncodeParameters;
};
......@@ -214,6 +229,134 @@ class PCCTMC3Encoder3 {
reconstructedPointCloud(params, reconstructedCloud);
return 0;
}
int compressWithTrisoupGeometry(const PCCPointSet3 &inputPointCloud,
const PCCTMC3Encoder3Parameters &params, PCCBitstream &bitstream,
PCCPointSet3 *reconstructedCloud = nullptr) {
init();
PCCWriteToBuffer<uint32_t>(PCCTMC3MagicNumber, bitstream.buffer, bitstream.size);
PCCWriteToBuffer<uint32_t>(PCCTMC3FormatVersion, bitstream.buffer, bitstream.size);
// Write out inputPointCloud file, just so that we can get it into the TMC1 pipeline.
pcc::PCCPointSet3 tempPointCloud(inputPointCloud);
tempPointCloud.write("verticesInWorldCoords.ply", true);
// Compress geometry with TMC1.
pcc::mkdir("outbin");
std::string cmd;
cmd =
"TMC1_coordinateTransform -inworld verticesInWorldCoords.ply -outframe "
"verticesInFrameCoords.ply";
cmd += " -depth " + std::to_string(params.triSoup.depth) + " -scale " +
std::to_string(params.triSoup.intToOrigScale) + " -format binary_little_endian";
system(cmd.c_str());
cmd =
"TMC1_geometryEncode -inframe verticesInFrameCoords.ply -outbin outbin -outref "
"refinedVertices.ply";
cmd += " -depth " + std::to_string(params.triSoup.depth) + " -level " + std::to_string(params.triSoup.level) +
" -format binary_little_endian";
system(cmd.c_str());
cmd = "TMC1_voxelize -inref refinedVertices.ply -outvox voxelizedVertices.ply";
cmd += " -depth " + std::to_string(params.triSoup.depth) + " -format binary_little_endian";
system(cmd.c_str());
// Read in quantizedPointCloud file, so that we can recolor it.
pointCloud.read("voxelizedVertices.ply");
// Transform from integer to original coordinates.
const size_t pointCount = pointCloud.getPointCount();
for (size_t pointIndex = 0; pointIndex < pointCount; ++pointIndex) {
pointCloud[pointIndex] *= params.triSoup.intToOrigScale;
// Should add intToOrigTranslation here.
}
// Transfer colors.
const bool compressColors =
inputPointCloud.hasColors() &&
params.attributeEncodeParameters.find("color") != params.attributeEncodeParameters.end();
if (compressColors) {
pointCloud.addColors();
const auto &attributeParams = params.attributeEncodeParameters.find("color")->second;
if (!PCCTransfertColors(inputPointCloud, int32_t(attributeParams.searchRange), pointCloud)) {
std::cout << "Error: can't transfer colors!" << std::endl;
return -1;
}
}
// Transform from original to integer coordinates.
for (size_t pointIndex = 0; pointIndex < pointCount; ++pointIndex) {
// Should subtract intToOrigTranslation here.
pointCloud[pointIndex] /= params.triSoup.intToOrigScale;
}
// Optionally write out point cloud with lossy geometry and lossless color, for later
// comparison.
tempPointCloud = pointCloud; // deep copy
tempPointCloud.convertYUVToRGB();
tempPointCloud.write("decodedVoxelsAndTransferredColors.ply");
// Encode positions.
uint64_t positionsSize = bitstream.size;
if (int ret = encodeTrisoupHeader(params, bitstream)) {
return ret;
}
// Read in TMC1 geometry bitstream and put it into the converged TMC13 bitstream.
std::ifstream fin("outbin/outbin_0000.bin", std::ios::binary);
if (!fin.is_open()) {
return -1;
}
fin.seekg(0, std::ios::end);
uint64_t binSize = fin.tellg();
fin.seekg(0, std::ios::beg);
std::unique_ptr<uint8_t[]> tempbuf(new uint8_t[binSize]);
PCCWriteToBuffer<uint32_t>(uint32_t(binSize), bitstream.buffer, bitstream.size);
fin.read(reinterpret_cast<char *>(&bitstream.buffer[bitstream.size]), binSize);
if (!fin) {
return -1;
}
bitstream.size += binSize;
fin.close();
positionsSize = bitstream.size - positionsSize;
std::cout << "positions bitstream size " << positionsSize << " B ("
<< (8.0 * positionsSize) / inputPointCloud.getPointCount() << " bpp)" << std::endl;
if (pointCloud.hasColors()) {
AttributeEncoder attrEncoder;
const auto &colorParams = params.attributeEncodeParameters.find("color")->second;
uint64_t colorsSize = bitstream.size;
attrEncoder.buildPredictors(colorParams, pointCloud);
if (int ret = attrEncoder.encodeHeader(colorParams, "color", bitstream)) {
return ret;
}
if (int ret = attrEncoder.encodeColors(colorParams, pointCloud, bitstream)) {
return ret;
}
colorsSize = bitstream.size - colorsSize;
std::cout << "colors bitstream size " << colorsSize << " B ("
<< (8.0 * colorsSize) / inputPointCloud.getPointCount() << " bpp)" << std::endl;
}
if (pointCloud.hasReflectances()) {
AttributeEncoder attrEncoder;
const auto &reflectanceParams = params.attributeEncodeParameters.find("reflectance")->second;
uint64_t reflectancesSize = bitstream.size;
attrEncoder.buildPredictors(reflectanceParams, pointCloud);
if (int ret = attrEncoder.encodeHeader(reflectanceParams, "reflectance", bitstream)) {
return ret;
}
if (int ret = attrEncoder.encodeReflectances(reflectanceParams, pointCloud, bitstream)) {
return ret;
}
reflectancesSize = bitstream.size - reflectancesSize;
std::cout << "reflectances bitstream size " << reflectancesSize << " B ("
<< (8.0 * reflectancesSize) / inputPointCloud.getPointCount() << " bpp)"
<< std::endl;
}
reconstructedPointCloud(params, reconstructedCloud);
return 0;
}
private:
void reconstructedPointCloud(const PCCTMC3Encoder3Parameters &params,
......@@ -654,6 +797,32 @@ class PCCTMC3Encoder3 {
PCCWriteToBuffer<double>(params.positionQuantizationScale, bitstream.buffer, bitstream.size);
return 0;
}
int encodeTrisoupHeader(const PCCTMC3Encoder3Parameters &params, PCCBitstream &bitstream) const {
PCCWriteToBuffer<uint32_t>(uint32_t(pointCloud.getPointCount()), bitstream.buffer,
bitstream.size);
PCCWriteToBuffer<uint8_t>(uint8_t(pointCloud.hasColors()), bitstream.buffer, bitstream.size);
PCCWriteToBuffer<uint8_t>(uint8_t(pointCloud.hasReflectances()), bitstream.buffer,
bitstream.size);
for (int k = 0; k < 3; ++k) {
PCCWriteToBuffer<double>(minPositions[k], bitstream.buffer, bitstream.size);
}
for (int k = 0; k < 3; ++k) {
PCCWriteToBuffer<uint32_t>(boundingBox.max[k], bitstream.buffer, bitstream.size);
}
PCCWriteToBuffer<double>(params.positionQuantizationScale, bitstream.buffer, bitstream.size);
PCCWriteToBuffer<size_t>(params.triSoup.depth, bitstream.buffer, bitstream.size);
PCCWriteToBuffer<size_t>(params.triSoup.level, bitstream.buffer, bitstream.size);
PCCWriteToBuffer<double>(params.triSoup.intToOrigScale, bitstream.buffer, bitstream.size);
PCCWriteToBuffer<PCCPoint3D>(
PCCPoint3D(
params.triSoup.intToOrigTranslation[0],
params.triSoup.intToOrigTranslation[1],
params.triSoup.intToOrigTranslation[2]
), bitstream.buffer, bitstream.size);
return 0;
}
void computeMinPositions(const PCCPointSet3 &inputPointCloud) {
const size_t inputPointCount = inputPointCloud.getPointCount();
minPositions = inputPointCloud[0];
......
......@@ -55,7 +55,8 @@ int main(int argc, char *argv[]) {
clock_wall.start();
int ret = 0;
if (params.mode == CODEC_MODE_ENCODE || params.mode == CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY) {
if (params.mode == CODEC_MODE_ENCODE || params.mode == CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY ||
params.mode == CODEC_MODE_ENCODE_TRISOUP_GEOMETRY) {
ret = Compress(params, clock_user);
} else {
ret = Decompress(params, clock_user);
......@@ -145,7 +146,9 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
" 0: encode\n"
" 1: decode\n"
" 2: encode with lossless geometry\n"
" 3: decode with lossless geometry")
" 3: decode with lossless geometry\n"
" 4: encode with trisoup geometry\n"
" 5: decode with trisoup geoemtry")
// i/o parameters
("reconstructedDataPath",
......@@ -188,6 +191,23 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
params.encodeParameters.inferredDirectCodingModeEnabled, true,
"Permits early termination of the geometry octree for isolated points")
// (trisoup) geometry parameters
("triSoupDepth", // log2(maxBB+1), where maxBB+1 is analogous to image width
params.encodeParameters.triSoup.depth, 10,
"Depth of voxels (reconstructed points) in trisoup geometry")
("triSoupLevel",
params.encodeParameters.triSoup.level, 7,
"Level of triangles (reconstructed surface) in trisoup geometry")
("triSoupIntToOrigScale", // reciprocal of positionQuantizationScale
params.encodeParameters.triSoup.intToOrigScale, 1.,
"orig_coords = integer_coords * intToOrigScale + intToOrigTranslation")
("triSoupIntToOrigTranslation",
params.encodeParameters.triSoup.intToOrigTranslation, {0., 0., 0.},
"orig_coords = integer_coords * intToOrigScale + intToOrigTranslation")
// attribute processing
// NB: Attribute options are special in the way they are applied (see above)
("attribute",
......@@ -235,6 +255,7 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
"Attribute's list of squared distances (one for each LoD)")
;
po::setDefaults(opts);
po::ErrorReporter err;
const list<const char*>& argv_unhandled =
......@@ -249,6 +270,14 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
return false;
}
// For trisoup, ensure that positionQuantizationScale is the exact inverse of intToOrigScale.
if (params.mode == 4 &&
params.encodeParameters.positionQuantizationScale !=
1.0 / params.encodeParameters.triSoup.intToOrigScale) {
params.encodeParameters.positionQuantizationScale =
1.0 / params.encodeParameters.triSoup.intToOrigScale;
}
// For RAHT, ensure that the unused lod count = 0 (prevents mishaps)
for (auto &attr : params.encodeParameters.attributeEncodeParameters) {
if (attr.second.transformType != TransformType::kIntegerLift) {
......@@ -287,7 +316,8 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
const bool encode =
params.mode == CODEC_MODE_ENCODE
|| params.mode == CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY;
|| params.mode == CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY
|| params.mode == CODEC_MODE_ENCODE_TRISOUP_GEOMETRY;
if (encode && params.uncompressedDataPath.empty())
err.error() << "uncompressedDataPath not set\n";
......@@ -315,10 +345,14 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
cout << "encode" << endl;
} else if (params.mode == CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY) {
cout << "encode with lossless geometry" << endl;
} else if (params.mode == CODEC_MODE_ENCODE_TRISOUP_GEOMETRY) {
cout << "encode with trisoup geometry" << endl;
} else if (params.mode == CODEC_MODE_DECODE) {
cout << "decode" << endl;
} else if (params.mode == CODEC_MODE_DECODE_LOSSLESS_GEOMETRY) {
cout << "decode with lossless geometry" << endl;
} else if (params.mode == CODEC_MODE_DECODE_TRISOUP_GEOMETRY) {
cout << "decode with trisoup geometry" << endl;
}
cout << "\t uncompressedDataPath " << params.uncompressedDataPath << endl;
cout << "\t compressedStreamPath " << params.compressedStreamPath << endl;
......@@ -331,6 +365,16 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
<< endl;
cout << "\t neighbourContextualisation " << params.encodeParameters.neighbourContextsEnabled
<< endl;
if (params.mode == CODEC_MODE_ENCODE_TRISOUP_GEOMETRY) {
cout << "\t triSoupDepth " << params.encodeParameters.triSoup.depth << endl;
cout << "\t triSoupLevel " << params.encodeParameters.triSoup.level << endl;
cout << "\t triSoupIntToOrigScale " << params.encodeParameters.triSoup.intToOrigScale << endl;
cout << "\t triSoupIntToOrigTranslation ";
for (const auto tr : params.encodeParameters.triSoup.intToOrigTranslation) {
cout << tr << " ";
}
cout << endl;
}
for (const auto & attributeEncodeParameters : params.encodeParameters.attributeEncodeParameters) {
cout << "\t " << attributeEncodeParameters.first << endl;
cout << "\t\t transformType "
......@@ -401,7 +445,10 @@ int Compress(const Parameters &params, Stopwatch& clock) {
reconstructedPointCloud.get())) ||
(params.mode == CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY &&
encoder.compressWithLosslessGeometry(pointCloud, params.encodeParameters, bitstream,
reconstructedPointCloud.get()))) {
reconstructedPointCloud.get())) ||
(params.mode == CODEC_MODE_ENCODE_TRISOUP_GEOMETRY &&
encoder.compressWithTrisoupGeometry(pointCloud, params.encodeParameters, bitstream,
reconstructedPointCloud.get()))) {
cout << "Error: can't compress point cloud!" << endl;
return -1;
}
......@@ -460,7 +507,9 @@ int Decompress(const Parameters &params, Stopwatch &clock) {
if ((params.mode == CODEC_MODE_DECODE && decoder.decompress(bitstream, pointCloud, params.roundOutputPositions)) ||
(params.mode == CODEC_MODE_DECODE_LOSSLESS_GEOMETRY &&
decoder.decompressWithLosslessGeometry(bitstream, pointCloud))) {
decoder.decompressWithLosslessGeometry(bitstream, pointCloud)) ||
(params.mode == CODEC_MODE_DECODE_TRISOUP_GEOMETRY &&
decoder.decompressWithTrisoupGeometry(bitstream, pointCloud, params.roundOutputPositions))) {
cout << "Error: can't decompress point cloud!" << endl;
return -1;
}
......
......@@ -63,6 +63,8 @@ enum CodecMode {
CODEC_MODE_DECODE = 1,
CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY = 2,
CODEC_MODE_DECODE_LOSSLESS_GEOMETRY = 3,
CODEC_MODE_ENCODE_TRISOUP_GEOMETRY = 4,
CODEC_MODE_DECODE_TRISOUP_GEOMETRY = 5,
};
struct Parameters {
......
/* The copyright in this software is being made available under the BSD
* Licence, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such
* rights are granted under this licence.
*
* Copyright (c) 2017-2018, ISO/IEC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the ISO/IEC nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "osspecific.h"
#if _POSIX_C_SOURCE
# include <fcntl.h>
# include <sys/stat.h>
#endif
#if _WIN32
# include <direct.h>
#endif
/* NB: if this file gets large, split into per-os variants */
#if _WIN32
int pcc::mkdir(const char* path)
{
return _mkdir(path);
}
#endif
#if _POSIX_C_SOURCE
int pcc::mkdir(const char* path)
{
return ::mkdir(path, 0775);
}
#endif
tmc3/osspecific.h 0 → 100644