eccodes/src/grib_jasper_encoding.c

234 lines
6.5 KiB
C
Raw Normal View History

2013-03-25 14:23:07 +00:00
/*
2019-04-15 13:44:45 +00:00
* Copyright 2005-2019 ECMWF.
2013-03-25 14:23:07 +00:00
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
*
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
*/
2013-03-25 12:04:10 +00:00
#include "grib_api_internal.h"
#if HAVE_LIBJASPER
/* Remove compiler warnings re macros being redefined */
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
2013-03-25 12:04:10 +00:00
#include "jasper/jasper.h"
#define MAXOPTSSIZE 1024
2020-01-22 13:10:59 +00:00
int grib_jasper_decode(grib_context* c, unsigned char* buf, size_t* buflen, double* values, size_t* no_values)
2016-08-03 10:30:19 +00:00
{
/*jas_setdbglevel(99999);*/
2020-01-22 13:10:59 +00:00
jas_image_t* image = NULL;
jas_stream_t* jpeg = NULL;
int code = GRIB_SUCCESS;
jas_matrix_t* matrix = NULL;
jas_image_cmpt_t* p;
int i, j, k;
jpeg = jas_stream_memopen((char*)buf, *buflen);
if (!jpeg) {
code = GRIB_DECODING_ERROR;
goto cleanup;
}
2013-03-25 12:04:10 +00:00
2016-08-03 10:30:19 +00:00
grib_context_log(c, GRIB_LOG_DEBUG, "grib_jasper_decode: Jasper version %s", jas_getversion());
2020-01-22 13:10:59 +00:00
image = jpc_decode(jpeg, NULL);
if (!image) {
code = GRIB_DECODING_ERROR;
goto cleanup;
}
2013-03-25 12:04:10 +00:00
p = image->cmpts_[0];
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
if (image->numcmpts_ != 1) {
/* Image not gray scale */
code = GRIB_DECODING_ERROR;
goto cleanup;
}
2013-03-25 12:04:10 +00:00
matrix = jas_matrix_create(jas_image_height(image), jas_image_width(image));
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
if (!matrix) {
code = GRIB_DECODING_ERROR;
goto cleanup;
}
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
jas_image_readcmpt(image, 0, 0, 0, jas_image_width(image), jas_image_height(image), matrix);
2013-03-25 12:04:10 +00:00
Assert(p->height_ * p->width_ == *no_values);
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
k = 0;
for (i = 0; i < p->height_; i++)
for (j = 0; j < p->width_; j++) {
values[k++] = matrix->rows_[i][j];
}
2013-03-25 12:04:10 +00:00
cleanup:
2020-01-22 13:10:59 +00:00
if (matrix)
jas_matrix_destroy(matrix);
if (image)
jas_image_destroy(image);
if (jpeg)
jas_stream_close(jpeg);
2013-03-25 12:04:10 +00:00
return code;
2013-03-25 12:04:10 +00:00
}
2020-01-22 13:10:59 +00:00
int grib_jasper_encode(grib_context* c, j2k_encode_helper* helper)
2016-08-03 10:30:19 +00:00
{
int code = GRIB_SUCCESS;
int jaserr;
char opts[MAXOPTSSIZE];
double reference_value = helper->reference_value;
2020-01-22 13:10:59 +00:00
double decimal = helper->decimal;
double divisor = helper->divisor;
const double* values = helper->values;
long no_values = helper->no_values;
long bits8;
int i;
2020-01-22 13:10:59 +00:00
size_t buflen = 0;
unsigned char* encoded = NULL;
unsigned char* p = NULL;
2020-01-22 13:10:59 +00:00
jas_image_t image = { 0 };
jas_stream_t* jpcstream = 0;
jas_stream_t* istream = 0;
2020-01-22 14:48:06 +00:00
jas_image_cmpt_t cmpt = {0,};
2020-01-22 13:10:59 +00:00
jas_image_cmpt_t* pcmpt = 0;
image.tlx_ = 0;
image.tly_ = 0;
image.brx_ = helper->width;
image.bry_ = helper->height;
image.numcmpts_ = 1;
image.maxcmpts_ = 1;
image.clrspc_ = JAS_CLRSPC_SGRAY;
image.cmprof_ = 0;
2016-12-06 11:51:41 +00:00
#if JASPER_VERSION_MAJOR == 1
/* ECC-396: Support for Jasper 2.0
* Jasper version 1 had the 'inmem_' data member but
* version 2 removed it from the interface */
2020-01-22 13:10:59 +00:00
image.inmem_ = 1;
2016-12-06 11:51:41 +00:00
#endif
2020-01-22 13:10:59 +00:00
cmpt.tlx_ = 0;
cmpt.tly_ = 0;
cmpt.hstep_ = 1;
cmpt.vstep_ = 1;
cmpt.width_ = helper->width;
cmpt.height_ = helper->height;
cmpt.type_ = JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y);
cmpt.prec_ = helper->bits_per_value;
cmpt.sgnd_ = 0;
cmpt.cps_ = (helper->bits_per_value + 7) / 8;
/* Simple packing encoding */
2020-01-22 13:10:59 +00:00
bits8 = (helper->bits_per_value + 7) / 8 * 8;
Assert(bits8 > 0);
2020-01-22 13:10:59 +00:00
encoded = (unsigned char*)grib_context_malloc_clear(c, bits8 / 8 * no_values);
2020-01-22 13:10:59 +00:00
if (!encoded) {
code = GRIB_OUT_OF_MEMORY;
goto cleanup;
}
buflen = 0;
2016-08-03 10:30:19 +00:00
p = encoded;
2020-01-22 13:10:59 +00:00
for (i = 0; i < no_values; i++) {
long blen = bits8;
unsigned long unsigned_val = (unsigned long)((((values[i] * decimal) - (reference_value)) * divisor) + 0.5);
while (blen >= 8) {
blen -= 8;
*p = (unsigned_val >> blen);
p++;
buflen++;
}
}
/*jas_init();*/
opts[0] = 0;
2020-01-22 13:10:59 +00:00
if (helper->compression != 0) {
/* Lossy */
2020-01-22 13:10:59 +00:00
ecc_snprintf(opts, MAXOPTSSIZE, "mode=real\nrate=%f", 1.0 / helper->compression);
}
2013-03-25 12:04:10 +00:00
Assert(cmpt.width_ * cmpt.height_ * cmpt.cps_ == buflen);
2016-08-03 10:30:19 +00:00
grib_context_log(c, GRIB_LOG_DEBUG, "grib_jasper_encode: Jasper version %s", jas_getversion());
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
pcmpt = &cmpt;
image.cmpts_ = &pcmpt;
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
istream = jas_stream_memopen((char*)encoded, buflen);
cmpt.stream_ = istream;
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
jpcstream = jas_stream_memopen((char*)helper->jpeg_buffer, helper->buffer_size);
jaserr = jpc_encode(&image, jpcstream, opts);
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
if (jaserr != 0) {
/* increase the number of guard bits */
2020-01-22 13:10:59 +00:00
strcat(opts, "\nnumgbits=4");
grib_context_log(c, GRIB_LOG_ERROR, "JASPER: error %d, increasing the number of guard bits", jaserr);
2020-01-22 13:10:59 +00:00
jas_stream_close(istream);
istream = 0;
jas_stream_close(jpcstream);
jpcstream = 0;
istream = jas_stream_memopen((char*)encoded, buflen);
cmpt.stream_ = istream;
jpcstream = jas_stream_memopen((char*)helper->jpeg_buffer, helper->buffer_size);
jaserr = jpc_encode(&image, jpcstream, opts);
}
2013-03-25 12:04:10 +00:00
2020-01-22 13:10:59 +00:00
if (jaserr != 0) {
grib_context_log(c, GRIB_LOG_ERROR, "JASPER: error %d", jaserr);
code = GRIB_ENCODING_ERROR;
goto cleanup;
}
2013-03-25 12:04:10 +00:00
helper->jpeg_length = jpcstream->rwcnt_;
2020-01-22 13:10:59 +00:00
jaserr = jas_stream_close(istream);
istream = 0;
jaserr = jas_stream_close(jpcstream);
jpcstream = 0;
2013-03-25 12:04:10 +00:00
cleanup:
2020-01-22 13:10:59 +00:00
grib_context_free(c, encoded);
if (istream)
jas_stream_close(istream);
if (jpcstream)
jas_stream_close(jpcstream);
2013-03-25 12:04:10 +00:00
return code;
2013-03-25 12:04:10 +00:00
}
#else
2020-01-22 13:10:59 +00:00
int grib_jasper_decode(grib_context* c, unsigned char* buf, size_t* buflen, double* val, size_t* n_vals)
2016-08-03 10:30:19 +00:00
{
grib_context_log(c, GRIB_LOG_ERROR,
2020-01-22 13:10:59 +00:00
"grib_accessor_data_jpeg2000_packing: Jasper JPEG support not enabled.");
return GRIB_FUNCTIONALITY_NOT_ENABLED;
2013-03-25 12:04:10 +00:00
}
2020-01-22 13:10:59 +00:00
int grib_jasper_encode(grib_context* c, j2k_encode_helper* helper)
2016-08-03 10:30:19 +00:00
{
grib_context_log(c, GRIB_LOG_ERROR,
2020-01-22 13:10:59 +00:00
"grib_accessor_data_jpeg2000_packing: Jasper JPEG support not enabled.");
return GRIB_FUNCTIONALITY_NOT_ENABLED;
2013-03-25 12:04:10 +00:00
}
#endif