Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add encoding using a buffer and bug fixes #89

Merged
merged 12 commits into from
Mar 23, 2024
Prev Previous commit
Next Next commit
Locate bugs in py_seek, JP2 encoding
scaramallion committed Mar 21, 2024
commit d599ce90c440a2da30490466441b672965a573a2
1 change: 1 addition & 0 deletions lib/interface/decode.c
Original file line number Diff line number Diff line change
@@ -562,6 +562,7 @@ extern int Decode(PyObject* fd, unsigned char *out, int codec_format)
}

// Convert colour space (if required)
// I don't think this does anything unless decoding JP2
if (
image->color_space != OPJ_CLRSPC_SYCC
&& image->numcomps == 3
36 changes: 20 additions & 16 deletions lib/interface/encode.c
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ extern int EncodeArray(
codec_format : int
The format of the encoded JPEG 2000 data, one of:
* ``0`` - OPJ_CODEC_J2K : JPEG-2000 codestream
* ``2`` - OPJ_CODEC_JP2 : JP2 file format
* ``1`` - OPJ_CODEC_JP2 : JP2 file format

Returns
-------
@@ -203,7 +203,7 @@ extern int EncodeArray(
}

// Check the encoding format
if (codec_format != 0 && codec_format != 2) {
if (codec_format != 0 && codec_format != 1) {
py_error("The value of the 'codec_format' parameter is invalid");
return 10;
}
@@ -390,7 +390,7 @@ extern int EncodeArray(
codec = opj_create_compress(OPJ_CODEC_J2K);
break;
}
case 2: { // JP2 codestream
case 1: { // JP2 codestream
codec = opj_create_compress(OPJ_CODEC_JP2);
break;
}
@@ -479,7 +479,7 @@ extern int EncodeBuffer(
unsigned int use_mct,
PyObject *compression_ratios,
PyObject *signal_noise_ratios,
unsigned int codec_format
int codec_format
)
{
/* Encode image data using JPEG 2000.
@@ -501,6 +501,9 @@ extern int EncodeBuffer(
0 for unsigned, 1 for signed
photometric_interpretation : int
Supported values: 0-5
dst : PyObject *
The destination for the encoded codestream, should be a BinaryIO or
an object with write(), tell() and seek().
use_mct : int
Supported values 0-1, can't be used with subsampling
compression_ratios : list[float]
@@ -514,10 +517,7 @@ extern int EncodeBuffer(
codec_format : int
The format of the encoded JPEG 2000 data, one of:
* ``0`` - OPJ_CODEC_J2K : JPEG-2000 codestream
* ``2`` - OPJ_CODEC_JP2 : JP2 file format
dst : PyObject *
The destination for the encoded codestream, should be a BinaryIO or
an object with write(), tell() and seek().
* ``1`` - OPJ_CODEC_JP2 : JP2 file format

Returns
-------
@@ -622,17 +622,17 @@ extern int EncodeBuffer(
return 9;
}

// Disable MCT if the input is not RGB
if (samples_per_pixel != 3 || photometric_interpretation != 1) {
use_mct = 0;
}

// Check the encoding format
if (codec_format != 0 && codec_format != 2) {
if (codec_format != 0 && codec_format != 1) {
py_error("The value of the 'codec_format' parameter is invalid");
return 10;
}

// Disable MCT if the input is not RGB
if (samples_per_pixel != 3 || photometric_interpretation != 1) {
use_mct = 0;
}

// Encoding parameters
unsigned int return_code;
opj_cparameters_t parameters;
@@ -819,7 +819,7 @@ extern int EncodeBuffer(
codec = opj_create_compress(OPJ_CODEC_J2K);
break;
}
case 2: { // JP2 codestream
case 1: { // JP2 codestream
codec = opj_create_compress(OPJ_CODEC_JP2);
break;
}
@@ -841,6 +841,7 @@ extern int EncodeBuffer(
}

// Creates an abstract output stream; allocates memory
// cio::opj_stream_create(buffer size, is_input)
stream = opj_stream_create(BUFFER_SIZE, OPJ_FALSE);

if (!stream) {
@@ -850,10 +851,13 @@ extern int EncodeBuffer(
}

// Functions for the stream
// JP2 isn't working with buffer-like...
opj_stream_set_user_data(stream, dst, NULL);
opj_stream_set_user_data_length(stream, py_length(dst));
opj_stream_set_read_function(stream, py_read);
opj_stream_set_write_function(stream, py_write);
opj_stream_set_skip_function(stream, py_skip);
opj_stream_set_seek_function(stream, py_seek_set);
opj_stream_set_user_data(stream, dst, NULL);

OPJ_BOOL result;

11 changes: 8 additions & 3 deletions lib/interface/utils.c
Original file line number Diff line number Diff line change
@@ -208,15 +208,20 @@ OPJ_OFF_T py_skip(OPJ_OFF_T offset, void *stream)

Returns
-------
off_t
The new position in the `stream`.
int
The number of bytes skipped.
*/
off_t current;
current = py_tell(stream);

py_seek(offset, stream, SEEK_CUR);

off_t pos;
pos = py_tell(stream);

return pos ? pos : (OPJ_OFF_T) -1;
printf("Skipping from %d by %d\n", pos, offset);

return pos ? pos - current : (OPJ_OFF_T) -1;
}


Loading