diff --git a/.gitignore b/.gitignore index 795929c780..34191bf1e7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ third-party/SVT-AV1/ third-party/dav1d/ third-party/libwebp/ third-party/rav1e/ +buildjs/ \ No newline at end of file diff --git a/build-emscripten.sh b/build-emscripten.sh index f9449c2888..c617c4e218 100755 --- a/build-emscripten.sh +++ b/build-emscripten.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +DIR=$PWD if [[ $# -ne 1 ]] ; then echo "Usage: $0 SRCDIR" @@ -27,7 +27,7 @@ STANDALONE="${STANDALONE:-0}" DEBUG="${DEBUG:-0}" USE_WASM="${USE_WASM:-1}" -echo "Build using ${CORES} CPU cores" +echo "Build using ${CORES} CPU cores in dir ${DIR}" LIBRARY_LINKER_FLAGS="" LIBRARY_INCLUDE_FLAGS="" @@ -50,6 +50,7 @@ if [ "$ENABLE_LIBDE265" = "1" ]; then LIBRARY_LINKER_FLAGS="$LIBRARY_LINKER_FLAGS -lde265" LIBRARY_INCLUDE_FLAGS="$LIBRARY_INCLUDE_FLAGS -L${DIR}/libde265-${LIBDE265_VERSION}/libde265/.libs" fi +echo "libde265: $CONFIGURE_ARGS_LIBDE265" CONFIGURE_ARGS_AOM="" if [ "$ENABLE_AOM" = "1" ]; then diff --git a/libheif/error.h b/libheif/error.h index af2af88f07..75769b315e 100644 --- a/libheif/error.h +++ b/libheif/error.h @@ -104,14 +104,4 @@ inline std::ostream& operator<<(std::ostream& ostr, const Error& err) return ostr; } - -template class Result -{ -public: - operator bool() const { return error.error_code == heif_error_Ok; } - - T value; - Error error; -}; - #endif diff --git a/libheif/heif_emscripten.h b/libheif/heif_emscripten.h index 395e1a7566..7705f0eff6 100644 --- a/libheif/heif_emscripten.h +++ b/libheif/heif_emscripten.h @@ -259,6 +259,95 @@ static emscripten::val heif_js_decode_image2(struct heif_image_handle* handle, return result; } +static emscripten::val heif_js_depth_img_decode(struct heif_image_handle *handle, heif_item_id depth_image_id) +{ + emscripten::val depth_result = emscripten::val::object(); + struct heif_image_handle *depth_handle; + heif_image_handle_get_depth_image_handle(handle, depth_image_id, &depth_handle); + if (!depth_handle) + { + depth_result.set("err", "could not get handle of depth image"); + depth_result.set("id", depth_image_id); + return depth_result; + } + + int width = heif_image_handle_get_width(depth_handle); + depth_result.set("width", width); + + int height = heif_image_handle_get_height(depth_handle); + depth_result.set("height", height); + + struct heif_image *depth_image; + struct heif_error err = heif_decode_image(depth_handle, &depth_image, heif_colorspace_monochrome, heif_chroma_monochrome, nullptr); + if (err.code) + { + depth_result.set("err", "could not get image of depth image"); + depth_result.set("msg", err.message); + depth_result.set("id", depth_image_id); + return depth_result; + } + + depth_result.set("testdata", emscripten::val(emscripten::typed_memory_view(10, "123456890"))); + return depth_result; + std::vector channels{ + heif_channel_Y, + heif_channel_Cb, + heif_channel_Cr, + heif_channel_R, + heif_channel_G, + heif_channel_B, + heif_channel_Alpha, + heif_channel_interleaved}; + + for (auto &&channel : channels) + { + if (heif_image_has_channel(depth_image, channel)) + { + depth_result.set("c_width", heif_image_get_width(depth_image, channel)); + depth_result.set("c_height", heif_image_get_height(depth_image, channel)); + + int stride; + const uint8_t *plane = heif_image_get_plane_readonly(depth_image, channel, &stride); + if (plane) + { + depth_result.set("stride", stride); + depth_result.set("data", emscripten::val(emscripten::typed_memory_view(stride * height, plane))); + depth_result.set("buffersize", stride * height); + depth_result.set("channel", channel); + depth_result.set("testdata", emscripten::val(emscripten::typed_memory_view(10, "123456890"))); + return depth_result; + } + } + } + + depth_result.set("err", "could get no plane of depth image"); + depth_result.set("id", depth_image_id); + return depth_result; +} +static emscripten::val heif_js_get_depth_imgs_decoded(struct heif_image_handle *handle) +{ + // similar to https://github.com/bigcat88/pillow_heif/blob/b2bf2744d0e4203088481b938af91974b3a2006f/pillow_heif/_pillow_heif.c#L1094 + emscripten::val results = emscripten::val::array(); + if (!handle) + { + return results; + } + int n_images = heif_image_handle_get_number_of_depth_images(handle); + if (n_images == 0) + return results; + heif_item_id *ids = (heif_item_id *)malloc(n_images * sizeof(heif_item_id)); + + n_images = heif_image_handle_get_list_of_depth_image_IDs(handle, ids, n_images); + for (int i = 0; i < n_images; i++) + { + + struct heif_image_handle *depth_handle; + heif_image_handle_get_depth_image_handle(handle, ids[i], &depth_handle); + results.call("push", emscripten::val(depth_handle)); + } + free(ids); + return results; +} #define EXPORT_HEIF_FUNCTION(name) \ emscripten::function(#name, &name, emscripten::allow_raw_pointers()) @@ -280,10 +369,18 @@ EMSCRIPTEN_BINDINGS(libheif) { //emscripten::function("heif_js_decode_image", //&heif_js_decode_image, emscripten::allow_raw_pointers()); emscripten::function("heif_js_decode_image2", - &heif_js_decode_image2, emscripten::allow_raw_pointers()); + &heif_js_decode_image2, emscripten::allow_raw_pointers()); + emscripten::function("heif_js_depth_img_decode", + &heif_js_depth_img_decode, emscripten::allow_raw_pointers()); + emscripten::function("heif_js_get_depth_imgs_decoded", + &heif_js_get_depth_imgs_decoded, emscripten::allow_raw_pointers()); EXPORT_HEIF_FUNCTION(heif_image_handle_release); EXPORT_HEIF_FUNCTION(heif_image_handle_get_width); EXPORT_HEIF_FUNCTION(heif_image_handle_get_height); + EXPORT_HEIF_FUNCTION(heif_image_handle_get_number_of_depth_images); + EXPORT_HEIF_FUNCTION(heif_image_handle_get_list_of_depth_image_IDs); + EXPORT_HEIF_FUNCTION(heif_image_handle_get_depth_image_handle); + EXPORT_HEIF_FUNCTION(heif_image_handle_is_primary_image); EXPORT_HEIF_FUNCTION(heif_image_handle_is_primary_image); EXPORT_HEIF_FUNCTION(heif_image_release); diff --git a/libheif/hevc.cc b/libheif/hevc.cc index 4c23510a22..4abbaa6c4e 100644 --- a/libheif/hevc.cc +++ b/libheif/hevc.cc @@ -20,7 +20,6 @@ #include "hevc.h" #include "bitstream.h" -#include "error.h" #include #include @@ -347,10 +346,8 @@ static double read_depth_rep_info_element(BitReader& reader) } -static Result> read_depth_representation_info(BitReader& reader) +static std::shared_ptr read_depth_representation_info(BitReader& reader) { - Result> result; - auto msg = std::make_shared(); @@ -372,15 +369,9 @@ static Result> read_depth_representation_info(BitRea int rep_type; if (!reader.get_uvlc(&rep_type)) { - result.error = {heif_error_Invalid_input, heif_suberror_Invalid_parameter_value, "invalid depth representation type in input"}; - return result; - } - - if (rep_type < 0 || rep_type > 3) { - result.error = {heif_error_Invalid_input, heif_suberror_Invalid_parameter_value, "input depth representation type out of range"}; - return result; + // TODO error } - + // TODO: check rep_type range msg->depth_representation_type = (enum heif_depth_representation_type) rep_type; //printf("flags: %d %d %d %d\n",msg->has_z_near,msg->has_z_far,msg->has_d_min,msg->has_d_max); @@ -389,8 +380,7 @@ static Result> read_depth_representation_info(BitRea if (msg->has_d_min || msg->has_d_max) { int ref_view; if (!reader.get_uvlc(&ref_view)) { - result.error = {heif_error_Invalid_input, heif_suberror_Invalid_parameter_value, "invalid disparity_reference_view in input"}; - return result; + // TODO error } msg->disparity_reference_view = ref_view; @@ -413,8 +403,7 @@ static Result> read_depth_representation_info(BitRea // TODO: load non-uniform response curve } - result.value = msg; - return result; + return msg; } @@ -455,12 +444,8 @@ Error decode_hevc_aux_sei_messages(const std::vector& data, switch (payload_id) { case 177: // depth_representation_info - Result> seiResult = read_depth_representation_info(sei_reader); - if (seiResult.error) { - return seiResult.error; - } - - msgs.push_back(seiResult.value); + std::shared_ptr sei = read_depth_representation_info(sei_reader); + msgs.push_back(sei); break; } }