--
You are subscribed to the mailing-list of the OpenJPEG project (www.openjpeg.org)
To post: email to open...@googlegroups.com
To unsubscribe: email to openjpeg+u...@googlegroups.com
For more options: visit http://groups.google.com/group/openjpeg
OpenJPEG is mainly supported by :
* UCL Image and Signal Processing Group (http://sites.uclouvain.be/ispgroup)
* IntoPIX (www.intopix.com)
reader = fopen("PATH/TO/example.j2k", "rb");
fseek(reader, 0, SEEK_END);
buf_len = ftell(reader);
fseek(reader, 0, SEEK_SET);
buf = (unsigned char*) malloc(buf_len);
fread(buf, 1, buf_len, reader);
fclose(reader);
opj_set_default_decoder_parameters(¶meters);
dinfo = opj_create_decompress(FORMAT);
opj_setup_decoder(dinfo, ¶meters);
cio = opj_cio_open((opj_common_ptr)dinfo, buf, buf_len);
image = opj_decode(dinfo, cio);
typedef struct
{
OPJ_UINT8* pData;
OPJ_SIZE_T dataSize;
OPJ_SIZE_T offset;
}opj_input_memory_stream;
static OPJ_SIZE_T opj_input_memory_stream_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
{
opj_input_memory_stream* l_stream = (opj_input_memory_stream*)p_user_data;
OPJ_SIZE_T l_nb_bytes_read = p_nb_bytes;
if (l_stream->offset >= l_stream->dataSize) {
return (OPJ_SIZE_T)-1;
}
if (p_nb_bytes > (l_stream->dataSize - l_stream->offset)) {
l_nb_bytes_read = l_stream->dataSize - l_stream->offset;
}
memcpy(p_buffer, &(l_stream->pData[l_stream->offset]), l_nb_bytes_read);
l_stream->offset += l_nb_bytes_read;
return l_nb_bytes_read;
}
static OPJ_OFF_T opj_input_memory_stream_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data)
{
opj_input_memory_stream* l_stream = (opj_input_memory_stream*)p_user_data;
if (p_nb_bytes < 0) {
return -1;
}
l_stream->offset += (OPJ_SIZE_T)p_nb_bytes;
return p_nb_bytes;
}
static OPJ_BOOL opj_input_memory_stream_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data)
{
opj_input_memory_stream* l_stream = (opj_input_memory_stream*)p_user_data;
if (p_nb_bytes < 0) {
return OPJ_FALSE;
}
l_stream->offset = (OPJ_SIZE_T)p_nb_bytes;
return OPJ_TRUE;
}
static void opj_input_memory_stream_free (void * p_user_data)
{
opj_input_memory_stream* l_stream = (opj_input_memory_stream*)p_user_data;
if ((l_stream != NULL) && (l_stream->pData != NULL)) {
free(l_stream->pData);
l_stream->pData = NULL;
}
}
I modified opj_decompress with this. Now to use it :
/* read the input file and put it in memory */
/* ---------------------------------------- */
{
FILE* input = fopen(parameters.infile, "rb");
fseeko(input, 0, SEEK_END);
l_mem_stream.dataSize = ftello(input);
fseeko(input, 0, SEEK_SET);
l_mem_stream.offset = 0U;
l_mem_stream.pData = (OPJ_UINT8*)malloc(l_mem_stream.dataSize);
fread(l_mem_stream.pData, 1U, l_mem_stream.dataSize, input);
fclose(input);
}
l_stream = opj_stream_default_create(1);
if (!l_stream){
fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n", parameters.infile);
destroy_parameters(¶meters);
return EXIT_FAILURE;
}
opj_stream_set_read_function(l_stream, opj_input_memory_stream_read);
opj_stream_set_seek_function(l_stream, opj_input_memory_stream_seek);
opj_stream_set_skip_function(l_stream, opj_input_memory_stream_skip);
opj_stream_set_user_data(l_stream, &l_mem_stream, opj_input_memory_stream_free);
opj_stream_set_user_data_length(l_stream, l_mem_stream.dataSize);
/*l_stream = opj_stream_create_default_file_stream(parameters.infile,1);
if (!l_stream){
fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n", parameters.infile);
destroy_parameters(¶meters);
return EXIT_FAILURE;
}*/
The same as to be done for output streams but this gives you, I hope, an idea of what has to be done.
Hi Alexey,Here's how an input stream could look like. I did not add all necessary checks & type checking (assuming 64 bits here) :
.......................................
The same as to be done for output streams but this gives you, I hope, an idea of what has to be done.
// These routines are added to use memory instead of a file for input and output.
//Structure need to treat memory as a stream.
typedef struct
{
OPJ_UINT8* pData; //Our data.
OPJ_SIZE_T dataSize; //How big is our data.
OPJ_SIZE_T offset; //Where are we currently in our data.
}opj_memory_stream;
//This will read from our memory to the buffer.
static OPJ_SIZE_T opj_memory_stream_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
{
opj_memory_stream* l_memory_stream = (opj_memory_stream*)p_user_data;//Our data.
OPJ_SIZE_T l_nb_bytes_read = p_nb_bytes;//Amount to move to buffer.
//Check if the current offset is outside our data buffer.
if (l_memory_stream->offset >= l_memory_stream->dataSize) return (OPJ_SIZE_T)-1;
//Check if we are reading more than we have.
if (p_nb_bytes > (l_memory_stream->dataSize - l_memory_stream->offset))
l_nb_bytes_read = l_memory_stream->dataSize - l_memory_stream->offset;//Read all we have.
//Copy the data to the internal buffer.
memcpy(p_buffer, &(l_memory_stream->pData[l_memory_stream->offset]), l_nb_bytes_read);
l_memory_stream->offset += l_nb_bytes_read;//Update the pointer to the new location.
return l_nb_bytes_read;
}
//This will write from the buffer to our memory.
static OPJ_SIZE_T opj_memory_stream_write(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
{
opj_memory_stream* l_memory_stream = (opj_memory_stream*)p_user_data;//Our data.
OPJ_SIZE_T l_nb_bytes_write = p_nb_bytes;//Amount to move to buffer.
//Check if the current offset is outside our data buffer.
if (l_memory_stream->offset >= l_memory_stream->dataSize) return (OPJ_SIZE_T)-1;
//Check if we are write more than we have space for.
if (p_nb_bytes > (l_memory_stream->dataSize - l_memory_stream->offset))
l_nb_bytes_write = l_memory_stream->dataSize - l_memory_stream->offset;//Write the remaining space.
//Copy the data from the internal buffer.
memcpy(&(l_memory_stream->pData[l_memory_stream->offset]), p_buffer, l_nb_bytes_write);
l_memory_stream->offset += l_nb_bytes_write;//Update the pointer to the new location.
return l_nb_bytes_write;
}
//Moves the pointer forward, but never more than we have.
static OPJ_OFF_T opj_memory_stream_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data)
{
opj_memory_stream* l_memory_stream = (opj_memory_stream*)p_user_data;
OPJ_SIZE_T l_nb_bytes;
if (p_nb_bytes < 0) return -1;//No skipping backwards.
l_nb_bytes = (OPJ_SIZE_T)p_nb_bytes;//Allowed because it is positive.
// Do not allow jumping past the end.
if (l_nb_bytes >l_memory_stream->dataSize - l_memory_stream->offset)
l_nb_bytes = l_memory_stream->dataSize - l_memory_stream->offset;//Jump the max.
//Make the jump.
l_memory_stream->offset += l_nb_bytes;
//Returm how far we jumped.
return l_nb_bytes;
}
//Sets the pointer to anywhere in the memory.
static OPJ_BOOL opj_memory_stream_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data)
{
opj_memory_stream* l_memory_stream = (opj_memory_stream*)p_user_data;
if (p_nb_bytes < 0) return OPJ_FALSE;//No before the buffer.
if (p_nb_bytes >(OPJ_OFF_T)l_memory_stream->dataSize) return OPJ_FALSE;//No after the buffer.
l_memory_stream->offset = (OPJ_SIZE_T)p_nb_bytes;//Move to new position.
return OPJ_TRUE;
}
//The system needs a routine to do when finished, the name tells you what I want it to do.
static void opj_memory_stream_do_nothing(void * p_user_data)
{
OPJ_ARG_NOT_USED(p_user_data);
}
//Create a stream to use memory as the input or output.
opj_stream_t* opj_stream_create_default_memory_stream(opj_memory_stream* p_memoryStream, OPJ_BOOL p_is_read_stream)
{
opj_stream_t* l_stream;
if (!(l_stream = opj_stream_default_create(p_is_read_stream))) return (NULL);
//Set how to work with the frame buffer.
if(p_is_read_stream)
opj_stream_set_read_function(l_stream, opj_memory_stream_read);
else
opj_stream_set_write_function(l_stream, opj_memory_stream_write);
opj_stream_set_seek_function(l_stream, opj_memory_stream_seek);
opj_stream_set_skip_function(l_stream, opj_memory_stream_skip);
opj_stream_set_user_data(l_stream, p_memoryStream, opj_memory_stream_do_nothing);
opj_stream_set_user_data_length(l_stream, p_memoryStream->dataSize);
return l_stream;
}