diff --git a/README.md b/README.md index 1af8ad1..27febad 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ _**Contents**_ * [CMake Build Configuration](#cmake-build-config) * [Debugging and Optimization](#debugging-and-optimization) * [Googletest Integration](#googletest-integration) - * [Javascript Decoder](#build-javascript-decoder) + * [Javascript Decoder](#javascript-decoder) * [Android Studio Project Integration](#android-studio-project-integration) * [Usage](#usage) * [Command Line Applications](#command-line-applications) @@ -40,7 +40,7 @@ _**Contents**_ * [Encoding Point Clouds](#encoding-point-clouds) * [Decoding Tool](#decoding-tool) * [C++ Decoder API](#c-decoder-api) - * [Javascript Decoder](#javascript-decoder) + * [Javascript Decoder API](#javascript-decoder-api) * [Javascript Decoder Performance](#javascript-decoder-performance) * [three.js Renderer Example](#threejs-renderer-example) * [Support](#support) @@ -95,7 +95,7 @@ C:\Users\nobody> cmake path/to/draco -G "Visual Studio 14 2015" To generate 64-bit Windows Visual Studio 2015 projects: ~~~~~ bash -C:\Users\nobody> cmake path/to/draco "Visual Studio 14 2015 Win64" +C:\Users\nobody> cmake path/to/draco -G "Visual Studio 14 2015 Win64" ~~~~~ @@ -314,8 +314,8 @@ if (geom_type == draco::TRIANGULAR_MESH) { Please see `mesh/mesh.h` for the full Mesh class interface and `point_cloud/point_cloud.h` for the full `PointCloud` class interface. -Javascript Decoder ------------------- +Javascript Decoder API +---------------------- The Javascript decoder is located in `javascript/draco_decoder.js`. The Javascript decoder can decode mesh and point cloud. In order to use the diff --git a/cmake/compiler_flags.cmake b/cmake/compiler_flags.cmake index dd07caf..a613ade 100644 --- a/cmake/compiler_flags.cmake +++ b/cmake/compiler_flags.cmake @@ -66,13 +66,13 @@ function (require_cxx_flag cxx_flag) string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND) if (${CXX_FLAG_FOUND} EQUAL -1) - unset(DRACO_HAVE_CXX_FLAG) + unset(DRACO_HAVE_CXX_FLAG CACHE) message("Checking CXX compiler flag support for: " ${cxx_flag}) check_cxx_compiler_flag("${cxx_flag}" DRACO_HAVE_CXX_FLAG) if (NOT DRACO_HAVE_CXX_FLAG) - message(FATAL_ERROR "Draco requires support for CXX flag: ${flag}.") + message(FATAL_ERROR "Draco requires support for CXX flag: ${cxx_flag}.") endif () - set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_CXX_FLAGS "${cxx_flag} ${CMAKE_CXX_FLAGS}" CACHE STRING "" FORCE) endif () endfunction () diff --git a/compression/attributes/attributes_decoder.cc b/compression/attributes/attributes_decoder.cc index 1a0d487..6e6c341 100644 --- a/compression/attributes/attributes_decoder.cc +++ b/compression/attributes/attributes_decoder.cc @@ -28,7 +28,7 @@ bool AttributesDecoder::Initialize(PointCloudDecoder *decoder, PointCloud *pc) { bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) { // Decode and create attributes. int32_t num_attributes; - if (!in_buffer->Decode(&num_attributes)) + if (!in_buffer->Decode(&num_attributes) || num_attributes <= 0) return false; point_attribute_ids_.resize(num_attributes); PointCloud *pc = point_cloud_; diff --git a/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords.h b/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords.h index 776e46c..f9ef843 100644 --- a/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords.h +++ b/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords.h @@ -186,7 +186,8 @@ bool MeshPredictionSchemeTexCoords:: orientations_.resize(num_orientations); bool last_orientation = true; BinaryDecoder decoder; - decoder.StartDecoding(buffer); + if (!decoder.StartDecoding(buffer)) + return false; for (int i = 0; i < num_orientations; ++i) { if (!decoder.DecodeNextBit()) last_orientation = !last_orientation; diff --git a/compression/attributes/sequential_quantization_attribute_decoder.cc b/compression/attributes/sequential_quantization_attribute_decoder.cc index 8eda484..b038227 100644 --- a/compression/attributes/sequential_quantization_attribute_decoder.cc +++ b/compression/attributes/sequential_quantization_attribute_decoder.cc @@ -54,7 +54,8 @@ bool SequentialQuantizationAttributeDecoder::DecodeQuantizedDataInfo() { if (!decoder()->buffer()->Decode(&max_value_dif_)) return false; uint8_t quantization_bits; - if (!decoder()->buffer()->Decode(&quantization_bits)) + if (!decoder()->buffer()->Decode(&quantization_bits) || + quantization_bits > 31) return false; quantization_bits_ = quantization_bits; return true; diff --git a/compression/mesh/mesh_edgebreaker_decoder_impl.cc b/compression/mesh/mesh_edgebreaker_decoder_impl.cc index 6a9eccb..73e321c 100644 --- a/compression/mesh/mesh_edgebreaker_decoder_impl.cc +++ b/compression/mesh/mesh_edgebreaker_decoder_impl.cc @@ -220,7 +220,8 @@ bool MeshEdgeBreakerDecoderImpl::DecodeConnectivity() { last_vert_id_ = -1; int8_t num_attribute_data; - if (!decoder_->buffer()->Decode(&num_attribute_data)) + if (!decoder_->buffer()->Decode(&num_attribute_data) || + num_attribute_data < 0) return false; attribute_data_.clear(); diff --git a/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h b/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h index f1dabc0..15a4e2f 100644 --- a/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h +++ b/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h @@ -156,10 +156,14 @@ bool IntegerPointsKdTreeDecoder::DecodePoints( if (num_points_ == 0) return true; - numbers_decoder_.StartDecoding(buffer); - remaining_bits_decoder_.StartDecoding(buffer); - axis_decoder_.StartDecoding(buffer); - half_decoder_.StartDecoding(buffer); + if (!numbers_decoder_.StartDecoding(buffer)) + return false; + if (!remaining_bits_decoder_.StartDecoding(buffer)) + return false; + if (!axis_decoder_.StartDecoding(buffer)) + return false; + if (!half_decoder_.StartDecoding(buffer)) + return false; OctreeDecode(num_points_, PointTraits::Origin(), PointTraits::ZeroArray(), 0, oit); diff --git a/core/adaptive_rans_coding.cc b/core/adaptive_rans_coding.cc index e42cee4..694bfae 100644 --- a/core/adaptive_rans_coding.cc +++ b/core/adaptive_rans_coding.cc @@ -76,16 +76,21 @@ AdaptiveRAnsBitDecoder::AdaptiveRAnsBitDecoder() : p0_f_(0.5) {} AdaptiveRAnsBitDecoder::~AdaptiveRAnsBitDecoder() { Clear(); } -void AdaptiveRAnsBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { +bool AdaptiveRAnsBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { Clear(); uint32_t size_in_bytes; - source_buffer->Decode(&size_in_bytes); - - ans_read_init(&ans_decoder_, reinterpret_cast(const_cast( - source_buffer->data_head())), - size_in_bytes); + if (!source_buffer->Decode(&size_in_bytes)) + return false; + if (size_in_bytes > source_buffer->remaining_size()) + return false; + if (ans_read_init(&ans_decoder_, + reinterpret_cast( + const_cast(source_buffer->data_head())), + size_in_bytes) != 0) + return false; source_buffer->Advance(size_in_bytes); + return true; } bool AdaptiveRAnsBitDecoder::DecodeNextBit() { diff --git a/core/adaptive_rans_coding.h b/core/adaptive_rans_coding.h index 3858283..0e125c9 100644 --- a/core/adaptive_rans_coding.h +++ b/core/adaptive_rans_coding.h @@ -65,7 +65,7 @@ class AdaptiveRAnsBitDecoder { ~AdaptiveRAnsBitDecoder(); // Sets |source_buffer| as the buffer to decode bits from. - void StartDecoding(DecoderBuffer *source_buffer); + bool StartDecoding(DecoderBuffer *source_buffer); // Decode one bit. Returns true if the bit is a 1, otherwsie false. bool DecodeNextBit(); diff --git a/core/ans.h b/core/ans.h index fa48030..019db57 100644 --- a/core/ans.h +++ b/core/ans.h @@ -411,7 +411,8 @@ class RAnsDecoder { RAnsDecoder() {} // Initializes the decoder from the input buffer. The |offset| specifies the - // number of bytes encoded by the encoder. + // number of bytes encoded by the encoder. A non zero return value is an + // error. inline int read_init(const uint8_t *const buf, int offset) { unsigned x; if (offset < 1) @@ -485,7 +486,9 @@ class RAnsDecoder { } act_prob = cum_prob; } - assert(cum_prob == rans_precision); + if (cum_prob != rans_precision) { + return false; + } return true; } diff --git a/core/direct_bit_coding.cc b/core/direct_bit_coding.cc index 2e169e3..f7e9417 100644 --- a/core/direct_bit_coding.cc +++ b/core/direct_bit_coding.cc @@ -41,14 +41,19 @@ DirectBitDecoder::DirectBitDecoder() : pos_(bits_.end()), num_used_bits_(0) {} DirectBitDecoder::~DirectBitDecoder() { Clear(); } -void DirectBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { +bool DirectBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { Clear(); uint32_t size_in_bytes; - source_buffer->Decode(&size_in_bytes); + if (!source_buffer->Decode(&size_in_bytes)) + return false; + if (size_in_bytes > source_buffer->remaining_size()) + return false; bits_.resize(size_in_bytes / 4); - source_buffer->Decode(bits_.data(), size_in_bytes); + if (!source_buffer->Decode(bits_.data(), size_in_bytes)) + return false; pos_ = bits_.begin(); num_used_bits_ = 0; + return true; } void DirectBitDecoder::Clear() { diff --git a/core/direct_bit_coding.h b/core/direct_bit_coding.h index 20b5267..36b6c4f 100644 --- a/core/direct_bit_coding.h +++ b/core/direct_bit_coding.h @@ -91,7 +91,7 @@ class DirectBitDecoder { ~DirectBitDecoder(); // Sets |source_buffer| as the buffer to decode bits from. - void StartDecoding(DecoderBuffer *source_buffer); + bool StartDecoding(DecoderBuffer *source_buffer); // Decode one bit. Returns true if the bit is a 1, otherwsie false. bool DecodeNextBit() { diff --git a/core/folded_bit32_coding.h b/core/folded_bit32_coding.h index e0b3851..93d00a3 100644 --- a/core/folded_bit32_coding.h +++ b/core/folded_bit32_coding.h @@ -84,11 +84,12 @@ class FoldedBit32Decoder { ~FoldedBit32Decoder() {} // Sets |source_buffer| as the buffer to decode bits from. - void StartDecoding(DecoderBuffer *source_buffer) { + bool StartDecoding(DecoderBuffer *source_buffer) { for (int i = 0; i < 32; i++) { - folded_number_decoders_[i].StartDecoding(source_buffer); + if (!folded_number_decoders_[i].StartDecoding(source_buffer)) + return false; } - bit_decoder_.StartDecoding(source_buffer); + return bit_decoder_.StartDecoding(source_buffer); } // Decode one bit. Returns true if the bit is a 1, otherwise false. diff --git a/core/rans_coding.cc b/core/rans_coding.cc index c028a3e..dfb17f3 100644 --- a/core/rans_coding.cc +++ b/core/rans_coding.cc @@ -125,17 +125,21 @@ RAnsBitDecoder::~RAnsBitDecoder() { Clear(); } bool RAnsBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { Clear(); - source_buffer->Decode(&prob_zero_); + if (!source_buffer->Decode(&prob_zero_)) + return false; uint32_t size_in_bytes; - source_buffer->Decode(&size_in_bytes); + if (!source_buffer->Decode(&size_in_bytes)) + return false; if (size_in_bytes > source_buffer->remaining_size()) return false; - ans_read_init(&ans_decoder_, reinterpret_cast(const_cast( - source_buffer->data_head())), - size_in_bytes); + if (ans_read_init(&ans_decoder_, + reinterpret_cast( + const_cast(source_buffer->data_head())), + size_in_bytes) != 0) + return false; source_buffer->Advance(size_in_bytes); return true; } diff --git a/core/rans_symbol_decoder.h b/core/rans_symbol_decoder.h index ea0d0e3..566cd1b 100644 --- a/core/rans_symbol_decoder.h +++ b/core/rans_symbol_decoder.h @@ -36,7 +36,7 @@ class RAnsSymbolDecoder { // Starts decoding from the buffer. The buffer will be advanced past the // encoded data after this call. - void StartDecoding(DecoderBuffer *buffer); + bool StartDecoding(DecoderBuffer *buffer); uint32_t DecodeSymbol() { return ans_.rans_read(); } void EndDecoding(); @@ -84,16 +84,21 @@ bool RAnsSymbolDecoder::Create(DecoderBuffer *buffer) { } template -void RAnsSymbolDecoder::StartDecoding( +bool RAnsSymbolDecoder::StartDecoding( DecoderBuffer *buffer) { uint64_t bytes_encoded; // Decode the number of bytes encoded by the encoder. - buffer->Decode(&bytes_encoded); + if (!buffer->Decode(&bytes_encoded)) + return false; + if (bytes_encoded > buffer->remaining_size()) + return false; const uint8_t *const data_head = reinterpret_cast(buffer->data_head()); // Advance the buffer past the rANS data. buffer->Advance(bytes_encoded); - ans_.read_init(data_head, bytes_encoded); + if (ans_.read_init(data_head, bytes_encoded) != 0) + return false; + return true; } template diff --git a/core/symbol_decoding.cc b/core/symbol_decoding.cc index 4652fd8..e47a2f5 100644 --- a/core/symbol_decoding.cc +++ b/core/symbol_decoding.cc @@ -71,7 +71,8 @@ bool DecodeTaggedSymbols(int num_values, int num_components, if (!tag_decoder.Create(src_buffer)) return false; - tag_decoder.StartDecoding(src_buffer); + if (!tag_decoder.StartDecoding(src_buffer)) + return false; if (num_values > 0 && tag_decoder.num_symbols() == 0) return false; // Wrong number of symbols. @@ -106,7 +107,8 @@ bool DecodeRawSymbolsInternal(int num_values, DecoderBuffer *src_buffer, if (num_values > 0 && decoder.num_symbols() == 0) return false; // Wrong number of symbols. - decoder.StartDecoding(src_buffer); + if (!decoder.StartDecoding(src_buffer)) + return false; for (int i = 0; i < num_values; ++i) { // Decode a symbol into the value. const uint32_t value = decoder.DecodeSymbol(); diff --git a/javascript/example/DRACOLoader.js b/javascript/example/DRACOLoader.js index a6fdd9a..480f318 100644 --- a/javascript/example/DRACOLoader.js +++ b/javascript/example/DRACOLoader.js @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. // +'use strict'; + THREE.DRACOLoader = function(manager) { this.manager = (manager !== undefined) ? manager : THREE.DefaultLoadingManager; diff --git a/javascript/example/webgl_loader_draco.html b/javascript/example/webgl_loader_draco.html index 1c1e67f..e0330ea 100644 --- a/javascript/example/webgl_loader_draco.html +++ b/javascript/example/webgl_loader_draco.html @@ -45,11 +45,13 @@