2007-06-30 20:25:49 +00:00
|
|
|
// This is the main DLL file.
|
|
|
|
|
|
2008-07-22 19:39:19 +00:00
|
|
|
#include "dotnet.h"
|
2007-06-30 20:25:49 +00:00
|
|
|
extern "C" {
|
|
|
|
|
#include "../libopenjpeg/openjpeg.h"
|
|
|
|
|
}
|
2007-08-25 09:36:33 +00:00
|
|
|
#include <algorithm>
|
2007-06-30 20:25:49 +00:00
|
|
|
|
|
|
|
|
|
2008-07-22 19:39:19 +00:00
|
|
|
bool DotNetAllocEncoded(MarshalledImage* image)
|
2007-06-30 20:25:49 +00:00
|
|
|
{
|
2008-08-27 02:36:28 +00:00
|
|
|
DotNetFree(image);
|
|
|
|
|
|
2007-06-30 20:25:49 +00:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
image->encoded = new unsigned char[image->length];
|
|
|
|
|
image->decoded = 0;
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-22 19:39:19 +00:00
|
|
|
bool DotNetAllocDecoded(MarshalledImage* image)
|
2007-06-30 20:25:49 +00:00
|
|
|
{
|
2008-08-27 02:36:28 +00:00
|
|
|
DotNetFree(image);
|
|
|
|
|
|
2007-06-30 20:25:49 +00:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
image->decoded = new unsigned char[image->width * image->height * image->components];
|
|
|
|
|
image->encoded = 0;
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-22 19:39:19 +00:00
|
|
|
void DotNetFree(MarshalledImage* image)
|
2007-06-30 20:25:49 +00:00
|
|
|
{
|
2007-08-25 09:36:33 +00:00
|
|
|
if (image->encoded != 0) delete[] image->encoded;
|
|
|
|
|
if (image->decoded != 0) delete[] image->decoded;
|
2007-06-30 20:25:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-07-22 19:39:19 +00:00
|
|
|
bool DotNetEncode(MarshalledImage* image, bool lossless)
|
2007-07-08 04:35:04 +00:00
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
opj_cparameters cparameters;
|
|
|
|
|
opj_set_default_encoder_parameters(&cparameters);
|
|
|
|
|
cparameters.cp_disto_alloc = 1;
|
2007-07-11 09:17:46 +00:00
|
|
|
|
2007-07-08 04:35:04 +00:00
|
|
|
if (lossless)
|
|
|
|
|
{
|
|
|
|
|
cparameters.tcp_numlayers = 1;
|
|
|
|
|
cparameters.tcp_rates[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-05-26 04:45:08 +00:00
|
|
|
cparameters.tcp_numlayers = 5;
|
|
|
|
|
cparameters.tcp_rates[0] = 1920;
|
|
|
|
|
cparameters.tcp_rates[1] = 480;
|
|
|
|
|
cparameters.tcp_rates[2] = 120;
|
|
|
|
|
cparameters.tcp_rates[3] = 30;
|
|
|
|
|
cparameters.tcp_rates[4] = 10;
|
|
|
|
|
cparameters.irreversible = 1;
|
|
|
|
|
if (image->components >= 3)
|
|
|
|
|
{
|
|
|
|
|
cparameters.tcp_mct = 1;
|
|
|
|
|
}
|
2007-07-08 04:35:04 +00:00
|
|
|
}
|
|
|
|
|
|
2008-07-22 19:39:19 +00:00
|
|
|
cparameters.cp_comment = (char*)"";
|
2008-07-22 19:22:27 +00:00
|
|
|
|
2007-06-30 20:25:49 +00:00
|
|
|
opj_image_comptparm comptparm[5];
|
2007-08-25 09:36:33 +00:00
|
|
|
|
2007-06-30 20:25:49 +00:00
|
|
|
for (int i = 0; i < image->components; i++)
|
|
|
|
|
{
|
|
|
|
|
comptparm[i].bpp = 8;
|
|
|
|
|
comptparm[i].prec = 8;
|
|
|
|
|
comptparm[i].sgnd = 0;
|
|
|
|
|
comptparm[i].dx = 1;
|
|
|
|
|
comptparm[i].dy = 1;
|
|
|
|
|
comptparm[i].x0 = 0;
|
|
|
|
|
comptparm[i].y0 = 0;
|
|
|
|
|
comptparm[i].w = image->width;
|
|
|
|
|
comptparm[i].h = image->height;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-27 02:36:28 +00:00
|
|
|
opj_image_t* jp2_image = opj_image_create(image->components, comptparm, CLRSPC_SRGB);
|
2009-01-07 02:28:26 +00:00
|
|
|
if (jp2_image == NULL)
|
2008-08-27 02:36:28 +00:00
|
|
|
throw "opj_image_create failed";
|
|
|
|
|
|
|
|
|
|
jp2_image->x0 = 0;
|
|
|
|
|
jp2_image->y0 = 0;
|
|
|
|
|
jp2_image->x1 = image->width;
|
|
|
|
|
jp2_image->y1 = image->height;
|
2007-08-25 09:36:33 +00:00
|
|
|
int n = image->width * image->height;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < image->components; i++)
|
2008-08-27 02:36:28 +00:00
|
|
|
std::copy(image->decoded + i * n, image->decoded + (i + 1) * n, jp2_image->comps[i].data);
|
2007-08-25 09:36:33 +00:00
|
|
|
|
2008-08-27 02:36:28 +00:00
|
|
|
opj_cinfo* cinfo = opj_create_compress(CODEC_J2K);
|
|
|
|
|
opj_setup_encoder(cinfo, &cparameters, jp2_image);
|
|
|
|
|
opj_cio* cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
|
|
|
|
|
if (cio == NULL)
|
|
|
|
|
throw "opj_cio_open failed";
|
2007-06-30 20:25:49 +00:00
|
|
|
|
2008-08-27 02:36:28 +00:00
|
|
|
if (!opj_encode(cinfo, cio, jp2_image, cparameters.index))
|
2007-08-25 09:36:33 +00:00
|
|
|
return false;
|
|
|
|
|
|
2008-08-27 02:36:28 +00:00
|
|
|
image->length = cio_tell(cio);
|
2007-08-25 09:36:33 +00:00
|
|
|
image->encoded = new unsigned char[image->length];
|
2008-08-27 02:36:28 +00:00
|
|
|
std::copy(cio->buffer, cio->buffer + image->length, image->encoded);
|
2007-08-25 09:36:33 +00:00
|
|
|
|
2008-08-27 02:36:28 +00:00
|
|
|
opj_image_destroy(jp2_image);
|
|
|
|
|
opj_destroy_compress(cinfo);
|
|
|
|
|
opj_cio_close(cio);
|
|
|
|
|
|
2007-08-25 09:36:33 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2007-06-30 20:25:49 +00:00
|
|
|
}
|
|
|
|
|
|
2008-07-27 10:06:45 +00:00
|
|
|
bool DotNetDecode(MarshalledImage* image)
|
2007-06-30 20:25:49 +00:00
|
|
|
{
|
|
|
|
|
opj_dparameters dparameters;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
opj_set_default_decoder_parameters(&dparameters);
|
2008-08-27 02:36:28 +00:00
|
|
|
opj_dinfo_t* dinfo = opj_create_decompress(CODEC_J2K);
|
|
|
|
|
opj_setup_decoder(dinfo, &dparameters);
|
|
|
|
|
opj_cio* cio = opj_cio_open((opj_common_ptr)dinfo, image->encoded, image->length);
|
|
|
|
|
|
|
|
|
|
opj_image* jp2_image = opj_decode(dinfo, cio); // decode happens here
|
2009-01-07 02:28:26 +00:00
|
|
|
if (jp2_image == NULL)
|
2008-08-27 02:36:28 +00:00
|
|
|
throw "opj_decode failed";
|
|
|
|
|
|
|
|
|
|
image->width = jp2_image->x1 - jp2_image->x0;
|
|
|
|
|
image->height = jp2_image->y1 - jp2_image->y0;
|
|
|
|
|
image->components = jp2_image->numcomps;
|
2007-08-25 09:36:33 +00:00
|
|
|
int n = image->width * image->height;
|
2008-08-27 02:36:28 +00:00
|
|
|
image->decoded = new unsigned char[n * image->components];
|
2007-08-25 09:36:33 +00:00
|
|
|
|
|
|
|
|
for (int i = 0; i < image->components; i++)
|
2008-08-27 02:36:28 +00:00
|
|
|
std::copy(jp2_image->comps[i].data, jp2_image->comps[i].data + n, image->decoded + i * n);
|
|
|
|
|
|
|
|
|
|
opj_image_destroy(jp2_image);
|
|
|
|
|
opj_destroy_decompress(dinfo);
|
|
|
|
|
opj_cio_close(cio);
|
2007-08-25 09:36:33 +00:00
|
|
|
|
2007-06-30 20:25:49 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2008-08-27 02:36:28 +00:00
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DotNetDecodeWithInfo(MarshalledImage* image)
|
|
|
|
|
{
|
|
|
|
|
opj_dparameters dparameters;
|
|
|
|
|
opj_codestream_info_t info;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
opj_set_default_decoder_parameters(&dparameters);
|
|
|
|
|
opj_dinfo_t* dinfo = opj_create_decompress(CODEC_J2K);
|
|
|
|
|
opj_setup_decoder(dinfo, &dparameters);
|
|
|
|
|
opj_cio* cio = opj_cio_open((opj_common_ptr)dinfo, image->encoded, image->length);
|
|
|
|
|
|
|
|
|
|
opj_image* jp2_image = opj_decode_with_info(dinfo, cio, &info); // decode happens here
|
2009-01-07 02:28:26 +00:00
|
|
|
if (jp2_image == NULL)
|
2008-08-27 02:36:28 +00:00
|
|
|
throw "opj_decode failed";
|
2007-06-30 20:25:49 +00:00
|
|
|
|
2008-08-27 02:36:28 +00:00
|
|
|
// maximum number of decompositions
|
|
|
|
|
int max_numdecompos = 0;
|
|
|
|
|
for (int compno = 0; compno < info.numcomps; compno++)
|
|
|
|
|
{
|
|
|
|
|
if (max_numdecompos < info.numdecompos[compno])
|
|
|
|
|
max_numdecompos = info.numdecompos[compno];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
image->width = jp2_image->x1 - jp2_image->x0;
|
|
|
|
|
image->height = jp2_image->y1 - jp2_image->y0;
|
|
|
|
|
image->layers = info.numlayers;
|
|
|
|
|
image->resolutions = max_numdecompos + 1;
|
|
|
|
|
image->components = info.numcomps;
|
|
|
|
|
image->packet_count = info.packno;
|
|
|
|
|
image->packets = info.tile->packet;
|
|
|
|
|
int n = image->width * image->height;
|
|
|
|
|
image->decoded = new unsigned char[n * image->components];
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < image->components; i++)
|
|
|
|
|
std::copy(jp2_image->comps[i].data, jp2_image->comps[i].data + n, image->decoded + i * n);
|
|
|
|
|
|
|
|
|
|
opj_image_destroy(jp2_image);
|
|
|
|
|
opj_destroy_decompress(dinfo);
|
|
|
|
|
opj_cio_close(cio);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2007-06-30 20:25:49 +00:00
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|