diff --git a/oss-internship-2020/openjpeg/examples/CMakeLists.txt b/oss-internship-2020/openjpeg/examples/CMakeLists.txt index b988086..f85e392 100644 --- a/oss-internship-2020/openjpeg/examples/CMakeLists.txt +++ b/oss-internship-2020/openjpeg/examples/CMakeLists.txt @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# copy of one of the converting functions +# put here to omit the library's complex add_library(convert_helper STATIC convert_helper.h convert_helper.cc diff --git a/oss-internship-2020/openjpeg/examples/convert_helper.cc b/oss-internship-2020/openjpeg/examples/convert_helper.cc index eda1c3a..6763d4b 100644 --- a/oss-internship-2020/openjpeg/examples/convert_helper.cc +++ b/oss-internship-2020/openjpeg/examples/convert_helper.cc @@ -1,311 +1,342 @@ +/* + * The copyright in this software is being made available under the 2-clauses + * BSD License, 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 license. + * + * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2014, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux + * Copyright (c) 2003-2014, Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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 OWNER 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. + */ // copies of a few library tools #include "convert_helper.h" -const char* opj_version(void) -{ - return "2.3.1"; +const char *opj_version(void) { return "2.3.1"; } + +static int are_comps_similar(opj_image_t *image) { + unsigned int i; + for (i = 1; i < image->numcomps; i++) { + if (image->comps[0].dx != image->comps[i].dx || + image->comps[0].dy != image->comps[i].dy || + (i <= 2 && (image->comps[0].prec != image->comps[i].prec || + image->comps[0].sgnd != image->comps[i].sgnd))) { + return OPJ_FALSE; + } + } + return OPJ_TRUE; } -static int are_comps_similar(opj_image_t * image) -{ - unsigned int i; - for (i = 1; i < image->numcomps; i++) { - if (image->comps[0].dx != image->comps[i].dx || - image->comps[0].dy != image->comps[i].dy || - (i <= 2 && - (image->comps[0].prec != image->comps[i].prec || - image->comps[0].sgnd != image->comps[i].sgnd))) { - return OPJ_FALSE; +int imagetopnm(opj_image_t *image, const char *outfile, int force_split) { + int *red, *green, *blue, *alpha; + int wr, hr, max; + int i; + unsigned int compno, ncomp; + int adjustR, adjustG, adjustB, adjustA; + int fails, two, want_gray, has_alpha, triple; + int prec, v; + FILE *fdest = NULL; + const char *tmp = outfile; + char *destname; + + alpha = NULL; + + if ((prec = (int)image->comps[0].prec) > 16) { + fprintf(stderr, + "%s:%d:imagetopnm\n\tprecision %d is larger than 16" + "\n\t: refused.\n", + __FILE__, __LINE__, prec); + return 1; + } + + two = has_alpha = 0; + fails = 1; + ncomp = image->numcomps; + + while (*tmp) { + ++tmp; + } + tmp -= 2; + want_gray = (*tmp == 'g' || *tmp == 'G'); + ncomp = image->numcomps; + + if (want_gray) { + ncomp = 1; + } + + if ((force_split == 0) && ncomp >= 2 && are_comps_similar(image)) { + fdest = fopen(outfile, "wb"); + + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); + return fails; + } + two = (prec > 8); + triple = (ncomp > 2); + wr = (int)image->comps[0].w; + hr = (int)image->comps[0].h; + max = (1 << prec) - 1; + has_alpha = (ncomp == 4 || ncomp == 2); + + red = image->comps[0].data; + if (red == NULL) { + fprintf(stderr, "imagetopnm: planes[%d] == NULL.\n", 0); + fprintf(stderr, "\tAborting\n"); + fclose(fdest); + return fails; + } + + if (triple) { + green = image->comps[1].data; + blue = image->comps[2].data; + for (i = 1; i <= 2; i++) { + if (image->comps[i].data == NULL) { + fprintf(stderr, "imagetopnm: planes[%d] == NULL.\n", i); + fprintf(stderr, "\tAborting\n"); + fclose(fdest); + return fails; } - } - return OPJ_TRUE; -} - -int imagetopnm(opj_image_t * image, const char *outfile, int force_split) -{ - int *red, *green, *blue, *alpha; - int wr, hr, max; - int i; - unsigned int compno, ncomp; - int adjustR, adjustG, adjustB, adjustA; - int fails, two, want_gray, has_alpha, triple; - int prec, v; - FILE *fdest = NULL; - const char *tmp = outfile; - char *destname; - - alpha = NULL; - - if ((prec = (int)image->comps[0].prec) > 16) { - fprintf(stderr, "%s:%d:imagetopnm\n\tprecision %d is larger than 16" - "\n\t: refused.\n", __FILE__, __LINE__, prec); - return 1; + } + } else { + green = blue = NULL; } - two = has_alpha = 0; - fails = 1; - ncomp = image->numcomps; + if (has_alpha) { + const char *tt = (triple ? "RGB_ALPHA" : "GRAYSCALE_ALPHA"); - while (*tmp) { - ++tmp; + fprintf(fdest, + "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %u\n" + "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", + opj_version(), wr, hr, ncomp, max, tt); + alpha = image->comps[ncomp - 1].data; + adjustA = (image->comps[ncomp - 1].sgnd + ? 1 << (image->comps[ncomp - 1].prec - 1) + : 0); + } else { + fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n", opj_version(), wr, hr, + max); + adjustA = 0; } - tmp -= 2; - want_gray = (*tmp == 'g' || *tmp == 'G'); - ncomp = image->numcomps; + adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - if (want_gray) { - ncomp = 1; + if (triple) { + adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); + } else { + adjustG = adjustB = 0; } - if ((force_split == 0) && ncomp >= 2 && - are_comps_similar(image)) { - fdest = fopen(outfile, "wb"); - - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); - return fails; + for (i = 0; i < wr * hr; ++i) { + if (two) { + v = *red + adjustR; + ++red; + if (v > 65535) { + v = 65535; + } else if (v < 0) { + v = 0; } - two = (prec > 8); - triple = (ncomp > 2); - wr = (int)image->comps[0].w; - hr = (int)image->comps[0].h; - max = (1 << prec) - 1; - has_alpha = (ncomp == 4 || ncomp == 2); - red = image->comps[0].data; - if (red == NULL) { - fprintf(stderr, - "imagetopnm: planes[%d] == NULL.\n", 0); - fprintf(stderr, "\tAborting\n"); - fclose(fdest); - return fails; - } + /* netpbm: */ + fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); if (triple) { - green = image->comps[1].data; - blue = image->comps[2].data; - for (i = 1; i <= 2; i++) { - if (image->comps[i].data == NULL) { - fprintf(stderr, - "imagetopnm: planes[%d] == NULL.\n", i); - fprintf(stderr, "\tAborting\n"); - fclose(fdest); - return fails; - } - } - } else { - green = blue = NULL; - } + v = *green + adjustG; + ++green; + if (v > 65535) { + v = 65535; + } else if (v < 0) { + v = 0; + } + + /* netpbm: */ + fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); + + v = *blue + adjustB; + ++blue; + if (v > 65535) { + v = 65535; + } else if (v < 0) { + v = 0; + } + + /* netpbm: */ + fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); + + } /* if(triple) */ if (has_alpha) { - const char *tt = (triple ? "RGB_ALPHA" : "GRAYSCALE_ALPHA"); + v = *alpha + adjustA; + ++alpha; + if (v > 65535) { + v = 65535; + } else if (v < 0) { + v = 0; + } - fprintf(fdest, "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %u\n" - "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", opj_version(), - wr, hr, ncomp, max, tt); - alpha = image->comps[ncomp - 1].data; - adjustA = (image->comps[ncomp - 1].sgnd ? - 1 << (image->comps[ncomp - 1].prec - 1) : 0); - } else { - fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n", - opj_version(), wr, hr, max); - adjustA = 0; + /* netpbm: */ + fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); } - adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + continue; - if (triple) { - adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); - adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); - } else { - adjustG = adjustB = 0; + } /* if(two) */ + + /* prec <= 8: */ + v = *red++; + if (v > 255) { + v = 255; + } else if (v < 0) { + v = 0; + } + + fprintf(fdest, "%c", (unsigned char)v); + if (triple) { + v = *green++; + if (v > 255) { + v = 255; + } else if (v < 0) { + v = 0; } - for (i = 0; i < wr * hr; ++i) { - if (two) { - v = *red + adjustR; - ++red; - if (v > 65535) { - v = 65535; - } else if (v < 0) { - v = 0; - } - - /* netpbm: */ - fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); - - if (triple) { - v = *green + adjustG; - ++green; - if (v > 65535) { - v = 65535; - } else if (v < 0) { - v = 0; - } - - /* netpbm: */ - fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); - - v = *blue + adjustB; - ++blue; - if (v > 65535) { - v = 65535; - } else if (v < 0) { - v = 0; - } - - /* netpbm: */ - fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); - - }/* if(triple) */ - - if (has_alpha) { - v = *alpha + adjustA; - ++alpha; - if (v > 65535) { - v = 65535; - } else if (v < 0) { - v = 0; - } - - /* netpbm: */ - fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); - } - continue; - - } /* if(two) */ - - /* prec <= 8: */ - v = *red++; - if (v > 255) { - v = 255; - } else if (v < 0) { - v = 0; - } - - fprintf(fdest, "%c", (unsigned char)v); - if (triple) { - v = *green++; - if (v > 255) { - v = 255; - } else if (v < 0) { - v = 0; - } - - fprintf(fdest, "%c", (unsigned char)v); - v = *blue++; - if (v > 255) { - v = 255; - } else if (v < 0) { - v = 0; - } - - fprintf(fdest, "%c", (unsigned char)v); - } - if (has_alpha) { - v = *alpha++; - if (v > 255) { - v = 255; - } else if (v < 0) { - v = 0; - } - - fprintf(fdest, "%c", (unsigned char)v); - } - } /* for(i */ - - fclose(fdest); - return 0; - } - - /* YUV or MONO: */ - - if (image->numcomps > ncomp) { - fprintf(stderr, "WARNING -> [PGM file] Only the first component\n"); - fprintf(stderr, " is written to the file\n"); - } - destname = (char*)malloc(strlen(outfile) + 8); - if (destname == NULL) { - fprintf(stderr, "imagetopnm: memory out\n"); - return 1; - } - for (compno = 0; compno < ncomp; compno++) { - if (ncomp > 1) { - /*sprintf(destname, "%d.%s", compno, outfile);*/ - const size_t olen = strlen(outfile); - const size_t dotpos = olen - 4; - - strncpy(destname, outfile, dotpos); - sprintf(destname + dotpos, "_%u.pgm", compno); - } else { - sprintf(destname, "%s", outfile); + fprintf(fdest, "%c", (unsigned char)v); + v = *blue++; + if (v > 255) { + v = 255; + } else if (v < 0) { + v = 0; } - fdest = fopen(destname, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname); - free(destname); - return 1; - } - wr = (int)image->comps[compno].w; - hr = (int)image->comps[compno].h; - prec = (int)image->comps[compno].prec; - max = (1 << prec) - 1; - - fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n", - opj_version(), wr, hr, max); - - red = image->comps[compno].data; - - if (!red) { - fclose(fdest); - continue; + fprintf(fdest, "%c", (unsigned char)v); + } + if (has_alpha) { + v = *alpha++; + if (v > 255) { + v = 255; + } else if (v < 0) { + v = 0; } - adjustR = - (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); - - if (prec > 8) { - for (i = 0; i < wr * hr; i++) { - v = *red + adjustR; - ++red; - if (v > 65535) { - v = 65535; - } else if (v < 0) { - v = 0; - } - - /* netpbm: */ - fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); - - if (has_alpha) { - v = *alpha++; - if (v > 65535) { - v = 65535; - } else if (v < 0) { - v = 0; - } - - /* netpbm: */ - fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); - } - }/* for(i */ - } else { /* prec <= 8 */ - for (i = 0; i < wr * hr; ++i) { - v = *red + adjustR; - ++red; - if (v > 255) { - v = 255; - } else if (v < 0) { - v = 0; - } - fprintf(fdest, "%c", (unsigned char)v); - } - } - fclose(fdest); - } /* for (compno */ - free(destname); + fprintf(fdest, "%c", (unsigned char)v); + } + } /* for(i */ + fclose(fdest); return 0; -}/* imagetopnm() */ + } + + /* YUV or MONO: */ + + if (image->numcomps > ncomp) { + fprintf(stderr, "WARNING -> [PGM file] Only the first component\n"); + fprintf(stderr, " is written to the file\n"); + } + destname = (char *)malloc(strlen(outfile) + 8); + if (destname == NULL) { + fprintf(stderr, "imagetopnm: memory out\n"); + return 1; + } + for (compno = 0; compno < ncomp; compno++) { + if (ncomp > 1) { + /*sprintf(destname, "%d.%s", compno, outfile);*/ + const size_t olen = strlen(outfile); + const size_t dotpos = olen - 4; + + strncpy(destname, outfile, dotpos); + sprintf(destname + dotpos, "_%u.pgm", compno); + } else { + sprintf(destname, "%s", outfile); + } + + fdest = fopen(destname, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname); + free(destname); + return 1; + } + wr = (int)image->comps[compno].w; + hr = (int)image->comps[compno].h; + prec = (int)image->comps[compno].prec; + max = (1 << prec) - 1; + + fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n", opj_version(), wr, hr, max); + + red = image->comps[compno].data; + + if (!red) { + fclose(fdest); + continue; + } + + adjustR = + (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); + + if (prec > 8) { + for (i = 0; i < wr * hr; i++) { + v = *red + adjustR; + ++red; + if (v > 65535) { + v = 65535; + } else if (v < 0) { + v = 0; + } + + /* netpbm: */ + fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); + + if (has_alpha) { + v = *alpha++; + if (v > 65535) { + v = 65535; + } else if (v < 0) { + v = 0; + } + + /* netpbm: */ + fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); + } + } /* for(i */ + } else { /* prec <= 8 */ + for (i = 0; i < wr * hr; ++i) { + v = *red + adjustR; + ++red; + if (v > 255) { + v = 255; + } else if (v < 0) { + v = 0; + } + fprintf(fdest, "%c", (unsigned char)v); + } + } + fclose(fdest); + } /* for (compno */ + free(destname); + + return 0; +} /* imagetopnm() */ diff --git a/oss-internship-2020/openjpeg/examples/convert_helper.h b/oss-internship-2020/openjpeg/examples/convert_helper.h index 3c21b32..517e212 100644 --- a/oss-internship-2020/openjpeg/examples/convert_helper.h +++ b/oss-internship-2020/openjpeg/examples/convert_helper.h @@ -1,8 +1,11 @@ +// imagetopnm and the two functions it calls internaly are copied from the +// library's tools; from openjpeg/src/bin/jp2/convert.c + #include "openjp2_sapi.sapi.h" #define OPJ_TRUE 1 #define OPJ_FALSE 0 const char* opj_version(void); -int imagetopnm(opj_image_t * image, const char *outfile, int force_split); -static int are_comps_similar(opj_image_t * image); +static int are_comps_similar(opj_image_t* image); +int imagetopnm(opj_image_t* image, const char* outfile, int force_split); diff --git a/oss-internship-2020/openjpeg/examples/decompress_example.cc b/oss-internship-2020/openjpeg/examples/decompress_example.cc index 8189ccf..0c9ce22 100644 --- a/oss-internship-2020/openjpeg/examples/decompress_example.cc +++ b/oss-internship-2020/openjpeg/examples/decompress_example.cc @@ -12,19 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. - -// Perform decompression from *.jp2 to *.pnm format - +// Perform decompression from *.jp2 to *.pnm format #include #include -#include -#include #include +#include +#include #include "convert_helper.h" - #include "openjp2_sapi.sapi.h" #include "sandboxed_api/util/flag.h" @@ -33,8 +30,7 @@ class Opj_image_t : public sapi::v::Struct {}; class Openjp2SapiSandbox : public Openjp2Sandbox { public: - Openjp2SapiSandbox(const std::string& in_file) - : in_file_(in_file) {} + Openjp2SapiSandbox(const std::string& in_file) : in_file_(in_file) {} std::unique_ptr ModifyPolicy( sandbox2::PolicyBuilder*) override { @@ -47,9 +43,9 @@ class Openjp2SapiSandbox : public Openjp2Sandbox { .AllowSystemMalloc() .AllowExit() .AllowSyscalls({ - __NR_futex, - __NR_close, - __NR_lseek, + __NR_futex, + __NR_close, + __NR_lseek, }) .AddFile(in_file_) .BuildOrDie(); @@ -59,105 +55,105 @@ class Openjp2SapiSandbox : public Openjp2Sandbox { std::string in_file_; }; - int main(int argc, char* argv[]) { - gflags::ParseCommandLineFlags(&argc, &argv, true); + gflags::ParseCommandLineFlags(&argc, &argv, true); - if (argc != 3) { - std::cerr << "usage: " - << basename(argv[0]) - << " absolute/path/to/INPUT.jp2" - << " absolute/path/to/OUTPUT.pnm\n"; - return EXIT_FAILURE; - } + if (argc != 3) { + std::cerr << "usage: " << basename(argv[0]) << " absolute/path/to/INPUT.jp2" + << " absolute/path/to/OUTPUT.pnm\n"; + return EXIT_FAILURE; + } - std::string in_file(argv[1]); + std::string in_file(argv[1]); - Openjp2SapiSandbox sandbox(in_file); - absl::Status status = sandbox.Init(); - assert(status.ok()); + // initialize sandbox + Openjp2SapiSandbox sandbox(in_file); + absl::Status status = sandbox.Init(); + assert(status.ok()); - Openjp2Api api(&sandbox); - sapi::v::ConstCStr in_file_v(in_file.c_str()); + Openjp2Api api(&sandbox); + sapi::v::ConstCStr in_file_v(in_file.c_str()); - sapi::StatusOr stream_status - = api.opj_stream_create_default_file_stream(in_file_v.PtrBefore(), 1); - assert(stream_status.ok()); - void* stream_status_value = stream_status.value(); - sapi::v::RemotePtr stream_pointer(stream_status_value); + // initialize library's main data-holders + sapi::StatusOr stream_status = + api.opj_stream_create_default_file_stream(in_file_v.PtrBefore(), 1); + assert(stream_status.ok()); + void* stream_status_value = stream_status.value(); + sapi::v::RemotePtr stream_pointer(stream_status_value); - sapi::StatusOr codec_status - = api.opj_create_decompress(OPJ_CODEC_JP2); - assert(codec_status.ok()); - void* codec_status_value = codec_status.value(); - sapi::v::RemotePtr codec_pointer(codec_status_value); + sapi::StatusOr codec_status = + api.opj_create_decompress(OPJ_CODEC_JP2); + assert(codec_status.ok()); + void* codec_status_value = codec_status.value(); + sapi::v::RemotePtr codec_pointer(codec_status_value); - Parameters parameters; - status = api.opj_set_default_decoder_parameters(parameters.PtrBoth()); - assert(status.ok()); + Parameters parameters; + status = api.opj_set_default_decoder_parameters(parameters.PtrBoth()); + assert(status.ok()); - sapi::StatusOr bool_status - = api.opj_setup_decoder(&codec_pointer, parameters.PtrBefore()); - assert(bool_status.ok()); - assert(bool_status.value()); + sapi::StatusOr bool_status = + api.opj_setup_decoder(&codec_pointer, parameters.PtrBefore()); + assert(bool_status.ok()); + assert(bool_status.value()); - sapi::v::GenericPtr image_pointer; - bool_status = api.opj_read_header(&stream_pointer, - &codec_pointer, - image_pointer.PtrAfter()); - assert(bool_status.ok()); - assert(bool_status.value()); + // start reading image from the input file + sapi::v::GenericPtr image_pointer; + bool_status = api.opj_read_header(&stream_pointer, &codec_pointer, + image_pointer.PtrAfter()); + assert(bool_status.ok()); + assert(bool_status.value()); - Opj_image_t image; - image.SetRemote((void*)image_pointer.GetValue()); - assert(sandbox.TransferFromSandboxee(&image).ok()); + Opj_image_t image; + image.SetRemote((void*)image_pointer.GetValue()); + assert(sandbox.TransferFromSandboxee(&image).ok()); - bool_status = api.opj_decode(&codec_pointer, - &stream_pointer, - (sapi::v::Ptr*)&image_pointer); - assert(bool_status.ok()); - assert(bool_status.value()); + bool_status = api.opj_decode(&codec_pointer, &stream_pointer, + (sapi::v::Ptr*)&image_pointer); + assert(bool_status.ok()); + assert(bool_status.value()); - bool_status = api.opj_end_decompress(&codec_pointer, &stream_pointer); - assert(bool_status.ok()); - assert(bool_status.value()); + bool_status = api.opj_end_decompress(&codec_pointer, &stream_pointer); + assert(bool_status.ok()); + assert(bool_status.value()); - status = api.opj_stream_destroy(&stream_pointer); - assert(status.ok()); + int components = image.data().numcomps; - int components = image.data().numcomps; + // transfer the read data to the main process + sapi::v::Array image_components(components); + image_components.SetRemote(image.data().comps); + assert(sandbox.TransferFromSandboxee(&image_components).ok()); - sapi::v::Array image_components(components); - image_components.SetRemote(image.data().comps); - assert(sandbox.TransferFromSandboxee(&image_components).ok()); + image.mutable_data()->comps = (opj_image_comp_t*)image_components.GetLocal(); - image.mutable_data()->comps - = (opj_image_comp_t*)image_components.GetLocal(); + int width = (int)image.data().comps[0].w; + int height = (int)image.data().comps[0].h; - int width = (int)image.data().comps[0].w; - int height = (int)image.data().comps[0].h; + OPJ_INT32 data[components][width * height]; + sapi::v::Array image_components_data(width * height); - int data[components][width * height]; - sapi::v::Array image_components_data(width * height); + for (int i = 0; i < components; i++) { + image_components_data.SetRemote(image.data().comps[i].data); + assert(sandbox.TransferFromSandboxee(&image_components_data).ok()); + for (int j = 0; j < width * height; j++) { + data[i][j] = image_components_data[j]; + } + image_components[i].data = data[i]; + } - for (int i = 0; i < components; i++) { - image_components_data.SetRemote(image.data().comps[i].data); - assert(sandbox.TransferFromSandboxee(&image_components_data).ok()); - for (int j = 0; j < width * height; j++) { - data[i][j] = image_components_data[j]; - } - image_components[i].data = data[i]; - } + // convert the image to the desired format and save it to the file + int error = imagetopnm((opj_image_t*)image.GetLocal(), argv[2], 0); + assert(error == 0); - int error = imagetopnm((opj_image_t*)image.GetLocal(), argv[2], 0); - assert(error == 0); + // cleanup + sapi::v::RemotePtr remote_image_pointer(image.GetRemote()); + status = api.opj_image_destroy(&remote_image_pointer); + assert(status.ok()); - status = api.opj_destroy_codec(&codec_pointer); - assert(status.ok()); + status = api.opj_stream_destroy(&stream_pointer); + assert(status.ok()); - sapi::v::RemotePtr remote_image_pointer(image.GetRemote()); - status = api.opj_image_destroy(&remote_image_pointer); - assert(status.ok()); + status = api.opj_destroy_codec(&codec_pointer); + assert(status.ok()); - return EXIT_SUCCESS; + return EXIT_SUCCESS; }