[trunk] implement Large File support in the library
This commit is contained in:
@@ -371,7 +371,7 @@ void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
|
||||
* Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
|
||||
* @return a stream object.
|
||||
*/
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_UINT32 p_size,opj_bool l_is_input)
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,opj_bool l_is_input)
|
||||
{
|
||||
opj_stream_private_t * l_stream = 00;
|
||||
l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
|
||||
@@ -380,8 +380,8 @@ opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_UINT32 p_size,opj_bool l_is_inp
|
||||
}
|
||||
|
||||
memset(l_stream,0,sizeof(opj_stream_private_t));
|
||||
l_stream->m_buffer_size = p_size;
|
||||
l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_size);
|
||||
l_stream->m_buffer_size = p_buffer_size;
|
||||
l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size);
|
||||
if (! l_stream->m_stored_data) {
|
||||
opj_free(l_stream);
|
||||
return 00;
|
||||
@@ -506,10 +506,9 @@ OPJ_API void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_data the data to set.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT32 data_length)
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
|
||||
l_stream->m_user_data_length = data_length;
|
||||
}
|
||||
|
||||
@@ -521,9 +520,9 @@ OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr)
|
||||
OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_UINT32 l_read_nb_bytes = 0;
|
||||
OPJ_SIZE_T l_read_nb_bytes = 0;
|
||||
if (p_stream->m_bytes_in_buffer >= p_size) {
|
||||
memcpy(p_buffer,p_stream->m_current_data,p_size);
|
||||
p_stream->m_current_data += p_size;
|
||||
@@ -637,10 +636,10 @@ OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes writtent, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr)
|
||||
OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_UINT32 l_remaining_bytes = 0;
|
||||
OPJ_UINT32 l_write_nb_bytes = 0;
|
||||
OPJ_SIZE_T l_remaining_bytes = 0;
|
||||
OPJ_SIZE_T l_write_nb_bytes = 0;
|
||||
|
||||
if
|
||||
(p_stream->m_status & opj_stream_e_error)
|
||||
@@ -693,7 +692,7 @@ OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE
|
||||
opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
// the number of bytes written on the media.
|
||||
OPJ_UINT32 l_current_write_nb_bytes = 0;
|
||||
OPJ_SIZE_T l_current_write_nb_bytes = 0;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
|
||||
while
|
||||
@@ -723,16 +722,18 @@ opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_SIZE_T l_skip_nb_bytes = 0;
|
||||
OPJ_SIZE_T l_current_skip_nb_bytes = 0;
|
||||
OPJ_OFF_T l_skip_nb_bytes = 0;
|
||||
OPJ_OFF_T l_current_skip_nb_bytes = 0;
|
||||
|
||||
if
|
||||
(p_stream->m_bytes_in_buffer >= p_size)
|
||||
{
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer -= p_size;
|
||||
// it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer
|
||||
// which is of type OPJ_SIZE_T
|
||||
p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size;
|
||||
l_skip_nb_bytes += p_size;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes;
|
||||
@@ -746,7 +747,7 @@ OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_s
|
||||
p_stream->m_current_data += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
|
||||
}
|
||||
|
||||
// the flag is not set, we copy data and then do an actual skip on the stream
|
||||
@@ -765,14 +766,14 @@ OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_s
|
||||
// we should do an actual skip on the media
|
||||
l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
|
||||
if
|
||||
(l_current_skip_nb_bytes == (OPJ_SIZE_T) -1)
|
||||
(l_current_skip_nb_bytes == (OPJ_OFF_T) -1)
|
||||
{
|
||||
opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
|
||||
p_stream->m_status |= opj_stream_e_end;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
// end if stream
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
|
||||
}
|
||||
p_size -= l_current_skip_nb_bytes;
|
||||
l_skip_nb_bytes += l_current_skip_nb_bytes;
|
||||
@@ -788,16 +789,16 @@ OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_s
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
opj_bool l_is_written = 0;
|
||||
OPJ_SIZE_T l_current_skip_nb_bytes = 0;
|
||||
OPJ_SIZE_T l_skip_nb_bytes = 0;
|
||||
OPJ_OFF_T l_current_skip_nb_bytes = 0;
|
||||
OPJ_OFF_T l_skip_nb_bytes = 0;
|
||||
|
||||
if
|
||||
(p_stream->m_status & opj_stream_e_error)
|
||||
{
|
||||
return (OPJ_SIZE_T) -1;
|
||||
return (OPJ_OFF_T) -1;
|
||||
}
|
||||
|
||||
// we should flush data
|
||||
@@ -808,7 +809,7 @@ OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_
|
||||
p_stream->m_status |= opj_stream_e_error;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_current_data = p_stream->m_current_data;
|
||||
return (OPJ_SIZE_T) -1;
|
||||
return (OPJ_OFF_T) -1;
|
||||
}
|
||||
// then skip
|
||||
|
||||
@@ -818,14 +819,14 @@ OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_
|
||||
// we should do an actual skip on the media
|
||||
l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
|
||||
if
|
||||
(l_current_skip_nb_bytes == (OPJ_SIZE_T)-1)
|
||||
(l_current_skip_nb_bytes == (OPJ_OFF_T)-1)
|
||||
{
|
||||
opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream error!\n");
|
||||
|
||||
p_stream->m_status |= opj_stream_e_error;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
// end if stream
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T)-1;
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1;
|
||||
}
|
||||
p_size -= l_current_skip_nb_bytes;
|
||||
l_skip_nb_bytes += l_current_skip_nb_bytes;
|
||||
@@ -841,7 +842,7 @@ OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_
|
||||
*
|
||||
* @return the current position of the stream.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
|
||||
OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream)
|
||||
{
|
||||
return p_stream->m_byte_offset;
|
||||
}
|
||||
@@ -854,7 +855,7 @@ OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
|
||||
*
|
||||
* @return Number of bytes left before the end of the stream.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
|
||||
OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
|
||||
{
|
||||
return p_stream->m_user_data_length ?
|
||||
p_stream->m_user_data_length - p_stream->m_byte_offset :
|
||||
@@ -868,8 +869,9 @@ OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_strea
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
assert(p_size >= 0);
|
||||
return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
|
||||
}
|
||||
|
||||
@@ -881,8 +883,9 @@ OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size,
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_event_mgr);
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
|
||||
@@ -907,7 +910,7 @@ opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_siz
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
if
|
||||
(! opj_stream_flush(p_stream,p_event_mgr))
|
||||
@@ -940,8 +943,9 @@ opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_si
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return true if the stream is seekable.
|
||||
*/
|
||||
opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr)
|
||||
opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr)
|
||||
{
|
||||
assert(p_size >= 0);
|
||||
return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
|
||||
}
|
||||
|
||||
@@ -953,28 +957,32 @@ opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream)
|
||||
return p_stream->m_seek_fn != opj_stream_default_seek;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
return (OPJ_UINT32) -1;
|
||||
}
|
||||
OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
return (OPJ_UINT32) -1;
|
||||
}
|
||||
OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
|
||||
OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_buffer);
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return (OPJ_SIZE_T) -1;
|
||||
}
|
||||
|
||||
opj_bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
|
||||
OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
OPJ_ARG_NOT_USED(p_buffer);
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return (OPJ_SIZE_T) -1;
|
||||
}
|
||||
|
||||
OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return (OPJ_OFF_T) -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
opj_bool opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
OPJ_ARG_NOT_USED(p_nb_bytes);
|
||||
OPJ_ARG_NOT_USED(p_user_data);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ typedef struct opj_stream_private
|
||||
/**
|
||||
* User data length
|
||||
*/
|
||||
OPJ_UINT32 m_user_data_length;
|
||||
OPJ_UINT64 m_user_data_length;
|
||||
|
||||
/**
|
||||
* Pointer to actual read function (NULL at the initialization of the cio.
|
||||
@@ -165,24 +165,24 @@ typedef struct opj_stream_private
|
||||
*/
|
||||
OPJ_BYTE * m_current_data;
|
||||
|
||||
OPJ_SIZE_T (* m_opj_skip)(struct opj_stream_private * ,OPJ_SIZE_T , struct opj_event_mgr *);
|
||||
OPJ_OFF_T (* m_opj_skip)(struct opj_stream_private * ,OPJ_OFF_T , struct opj_event_mgr *);
|
||||
|
||||
opj_bool (* m_opj_seek) (struct opj_stream_private * , OPJ_SIZE_T , struct opj_event_mgr *);
|
||||
opj_bool (* m_opj_seek) (struct opj_stream_private * , OPJ_OFF_T , struct opj_event_mgr *);
|
||||
|
||||
/**
|
||||
* number of bytes containing in the buffer.
|
||||
*/
|
||||
OPJ_UINT32 m_bytes_in_buffer;
|
||||
OPJ_SIZE_T m_bytes_in_buffer;
|
||||
|
||||
/**
|
||||
* The number of bytes read/written.
|
||||
* The number of bytes read/written from the beginning of the stream
|
||||
*/
|
||||
OPJ_SIZE_T m_byte_offset;
|
||||
OPJ_OFF_T m_byte_offset;
|
||||
|
||||
/**
|
||||
* The size of the buffer.
|
||||
*/
|
||||
OPJ_UINT32 m_buffer_size;
|
||||
OPJ_SIZE_T m_buffer_size;
|
||||
|
||||
/**
|
||||
* Flags to tell the status of the stream.
|
||||
@@ -293,7 +293,7 @@ void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, struct opj_event_mgr * p_event_mgr);
|
||||
OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Writes some bytes to the stream.
|
||||
@@ -303,7 +303,7 @@ OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes writtent, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, struct opj_event_mgr * p_event_mgr);
|
||||
OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Writes the content of the stream buffer to the stream.
|
||||
@@ -320,7 +320,7 @@ opj_bool opj_stream_flush (opj_stream_private_t * p_stream, struct opj_event_mgr
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Tells the byte offset on the stream (similar to ftell).
|
||||
@@ -329,7 +329,7 @@ OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_SIZE_T p_size, s
|
||||
*
|
||||
* @return the current position o fthe stream.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream);
|
||||
OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream);
|
||||
|
||||
|
||||
/**
|
||||
@@ -339,7 +339,7 @@ OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream);
|
||||
*
|
||||
* @return Number of bytes left before the end of the stream.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream);
|
||||
OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
@@ -348,7 +348,7 @@ OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_strea
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
@@ -357,7 +357,7 @@ OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
@@ -366,7 +366,7 @@ OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_s
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
@@ -375,7 +375,7 @@ opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_siz
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Seeks a number of bytes from the stream.
|
||||
@@ -384,17 +384,17 @@ opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_si
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return true if the stream is seekable.
|
||||
*/
|
||||
opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Tells if the given stream is seekable.
|
||||
*/
|
||||
opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream);
|
||||
|
||||
OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data);
|
||||
OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data);
|
||||
OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data);
|
||||
opj_bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data);
|
||||
OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data);
|
||||
OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data);
|
||||
OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data);
|
||||
opj_bool opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -669,7 +669,7 @@ Add main header marker information
|
||||
*/
|
||||
static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
|
||||
|
||||
static void j2k_add_mhmarker_v2(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_UINT32 pos, OPJ_UINT32 len) ;
|
||||
static void j2k_add_mhmarker_v2(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) ;
|
||||
/**
|
||||
Add tile header marker information
|
||||
@param tileno tile index number
|
||||
@@ -680,7 +680,7 @@ Add tile header marker information
|
||||
*/
|
||||
static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
|
||||
|
||||
static void j2k_add_tlmarker_v2(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_UINT32 pos, OPJ_UINT32 len);
|
||||
static void j2k_add_tlmarker_v2(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len);
|
||||
|
||||
/**
|
||||
* Reads an unknown marker
|
||||
@@ -1239,7 +1239,7 @@ static opj_bool j2k_read_soc_v2( opj_j2k_v2_t *p_j2k,
|
||||
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSIZ;
|
||||
|
||||
/* FIXME move it in a index structure included in p_j2k*/
|
||||
p_j2k->cstr_index->main_head_start = (OPJ_UINT32) opj_stream_tell(p_stream) - 2;
|
||||
p_j2k->cstr_index->main_head_start = opj_stream_tell(p_stream) - 2;
|
||||
|
||||
opj_event_msg_v2(p_manager, EVT_INFO, "Start to read j2k main header (%d).\n", p_j2k->cstr_index->main_head_start);
|
||||
|
||||
@@ -3914,8 +3914,13 @@ opj_bool j2k_read_sod_v2 (
|
||||
|
||||
l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
|
||||
|
||||
if (p_j2k->m_specific_param.m_decoder.m_last_tile_part)
|
||||
p_j2k->m_specific_param.m_decoder.m_sot_length = opj_stream_get_number_byte_left(p_stream) - 2;
|
||||
if (p_j2k->m_specific_param.m_decoder.m_last_tile_part) {
|
||||
// opj_stream_get_number_byte_left returns OPJ_OFF_T
|
||||
// but we are in the last tile part,
|
||||
// so its result will fit on OPJ_UINT32 unless we find
|
||||
// a file with a single tile part of more than 4 GB...
|
||||
p_j2k->m_specific_param.m_decoder.m_sot_length = (OPJ_UINT32)(opj_stream_get_number_byte_left(p_stream) - 2);
|
||||
}
|
||||
else
|
||||
p_j2k->m_specific_param.m_decoder.m_sot_length -= 2;
|
||||
|
||||
@@ -3923,10 +3928,10 @@ opj_bool j2k_read_sod_v2 (
|
||||
l_tile_len = &l_tcp->m_data_size;
|
||||
|
||||
if (! *l_current_data) {
|
||||
*l_current_data = (OPJ_BYTE*) opj_malloc/*FIXME V2 -> my_opj_malloc*/(p_j2k->m_specific_param.m_decoder.m_sot_length);
|
||||
*l_current_data = (OPJ_BYTE*) opj_malloc(p_j2k->m_specific_param.m_decoder.m_sot_length);
|
||||
}
|
||||
else {
|
||||
*l_current_data = (OPJ_BYTE*) opj_realloc/*FIXME V2 -> my_opj_realloc*/(*l_current_data, *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length);
|
||||
*l_current_data = (OPJ_BYTE*) opj_realloc(*l_current_data, *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length);
|
||||
}
|
||||
|
||||
if (*l_current_data == 00) {
|
||||
@@ -3938,8 +3943,9 @@ opj_bool j2k_read_sod_v2 (
|
||||
/* Index */
|
||||
l_cstr_index = p_j2k->cstr_index;
|
||||
if (l_cstr_index) {
|
||||
OPJ_SIZE_T l_current_pos = opj_stream_tell(p_stream) - 2;
|
||||
OPJ_UINT32 l_current_tile_part =l_cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno;
|
||||
OPJ_OFF_T l_current_pos = opj_stream_tell(p_stream) - 2;
|
||||
|
||||
OPJ_UINT32 l_current_tile_part = l_cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno;
|
||||
l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_header =
|
||||
l_current_pos;
|
||||
l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_pos =
|
||||
@@ -3954,12 +3960,6 @@ opj_bool j2k_read_sod_v2 (
|
||||
/*l_cstr_index->packno = 0;*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
l_current_read_size = opj_stream_read_data( p_stream,
|
||||
*l_current_data + *l_tile_len,
|
||||
p_j2k->m_specific_param.m_decoder.m_sot_length,
|
||||
@@ -5770,7 +5770,7 @@ static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short in
|
||||
|
||||
}
|
||||
|
||||
static void j2k_add_mhmarker_v2(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_UINT32 pos, OPJ_UINT32 len) {
|
||||
static void j2k_add_mhmarker_v2(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) {
|
||||
|
||||
if (!cstr_index)
|
||||
return;
|
||||
@@ -5812,7 +5812,7 @@ static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsi
|
||||
cstr_info->tile[tileno].marknum++;
|
||||
}
|
||||
|
||||
static void j2k_add_tlmarker_v2(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_UINT32 pos, OPJ_UINT32 len)
|
||||
static void j2k_add_tlmarker_v2(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
|
||||
{
|
||||
|
||||
if (!cstr_index)
|
||||
@@ -6307,7 +6307,7 @@ opj_bool j2k_copy_default_tcp_and_create_tcd
|
||||
*
|
||||
* @return the handler associated with the id.
|
||||
*/
|
||||
const opj_dec_memory_marker_handler_t * j2k_get_marker_handler (const OPJ_UINT32 p_id)
|
||||
const opj_dec_memory_marker_handler_t * j2k_get_marker_handler (OPJ_UINT32 p_id)
|
||||
{
|
||||
const opj_dec_memory_marker_handler_t *e;
|
||||
for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) {
|
||||
@@ -6785,7 +6785,7 @@ opj_bool j2k_decode_tile ( opj_j2k_v2_t * p_j2k,
|
||||
|
||||
l_tcp = &(p_j2k->m_cp.tcps[p_tile_index]);
|
||||
if (! l_tcp->m_data) {
|
||||
j2k_tcp_destroy(&(p_j2k->m_cp.tcps[p_tile_index]));
|
||||
j2k_tcp_destroy(&l_tcp);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
@@ -8220,14 +8220,14 @@ opj_bool j2k_decode_one_tile ( opj_j2k_v2_t *p_j2k,
|
||||
if (!j2k_allocate_tile_element_cstr_index(p_j2k))
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
/* Move into the codestream to the first SOT used to decode the desired tile */
|
||||
l_tile_no_to_dec = p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec;
|
||||
if (p_j2k->cstr_index->tile_index)
|
||||
if(p_j2k->cstr_index->tile_index->tp_index)
|
||||
{
|
||||
if ( ! p_j2k->cstr_index->tile_index[l_tile_no_to_dec].nb_tps) {
|
||||
/* not build the index for this tile, so we will move to the last SOT read*/
|
||||
/* the index for this tile has not been built,
|
||||
* so move to the last SOT read */
|
||||
if ( opj_stream_read_seek(p_stream, p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos+2, p_manager) ){
|
||||
opj_event_msg_v2(p_manager, EVT_ERROR, "Problem with seek function\n");
|
||||
return OPJ_FALSE;
|
||||
|
||||
@@ -611,7 +611,7 @@ typedef struct opj_j2k_dec
|
||||
/** Index of the tile to decode (used in get_tile) */
|
||||
OPJ_INT32 m_tile_ind_to_dec;
|
||||
/** Position of the last SOT marker read */
|
||||
OPJ_UINT32 m_last_sot_read_pos;
|
||||
OPJ_OFF_T m_last_sot_read_pos;
|
||||
|
||||
/**
|
||||
* Indicate that the current tile-part is assume as the last tile part of the codestream.
|
||||
|
||||
@@ -132,40 +132,40 @@ opj_codec_private_t;
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
|
||||
OPJ_UINT32 opj_read_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_file)
|
||||
OPJ_SIZE_T opj_read_from_file (void * p_buffer, OPJ_SIZE_T p_nb_bytes, FILE * p_file)
|
||||
{
|
||||
OPJ_UINT32 l_nb_read = fread(p_buffer,1,p_nb_bytes,p_file);
|
||||
OPJ_SIZE_T l_nb_read = fread(p_buffer,1,p_nb_bytes,p_file);
|
||||
return l_nb_read ? l_nb_read : -1;
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_get_data_length_from_file (FILE * p_file)
|
||||
OPJ_UINT64 opj_get_data_length_from_file (FILE * p_file)
|
||||
{
|
||||
OPJ_UINT32 file_length = 0;
|
||||
OPJ_OFF_T file_length = 0;
|
||||
|
||||
fseek(p_file, 0, SEEK_END);
|
||||
file_length = ftell(p_file);
|
||||
fseek(p_file, 0, SEEK_SET);
|
||||
OPJ_FSEEK(p_file, 0, SEEK_END);
|
||||
file_length = (OPJ_UINT64)OPJ_FTELL(p_file);
|
||||
OPJ_FSEEK(p_file, 0, SEEK_SET);
|
||||
|
||||
return file_length;
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_write_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_file)
|
||||
OPJ_SIZE_T opj_write_from_file (void * p_buffer, OPJ_SIZE_T p_nb_bytes, FILE * p_file)
|
||||
{
|
||||
return fwrite(p_buffer,1,p_nb_bytes,p_file);
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opj_skip_from_file (OPJ_SIZE_T p_nb_bytes, FILE * p_user_data)
|
||||
OPJ_OFF_T opj_skip_from_file (OPJ_OFF_T p_nb_bytes, FILE * p_user_data)
|
||||
{
|
||||
if (fseek(p_user_data,p_nb_bytes,SEEK_CUR)) {
|
||||
if (OPJ_FSEEK(p_user_data,p_nb_bytes,SEEK_CUR)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return p_nb_bytes;
|
||||
}
|
||||
|
||||
opj_bool opj_seek_from_file (OPJ_SIZE_T p_nb_bytes, FILE * p_user_data)
|
||||
opj_bool opj_seek_from_file (OPJ_OFF_T p_nb_bytes, FILE * p_user_data)
|
||||
{
|
||||
if (fseek(p_user_data,p_nb_bytes,SEEK_SET)) {
|
||||
if (OPJ_FSEEK(p_user_data,p_nb_bytes,SEEK_SET)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -617,7 +617,7 @@ opj_stream_t* OPJ_CALLCONV opj_stream_create_default_file_stream (FILE * p_file,
|
||||
return opj_stream_create_file_stream(p_file,J2K_STREAM_CHUNK_SIZE,p_is_read_stream);
|
||||
}
|
||||
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream (FILE * p_file, OPJ_UINT32 p_size, opj_bool p_is_read_stream)
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream (FILE * p_file, OPJ_SIZE_T p_size, opj_bool p_is_read_stream)
|
||||
{
|
||||
opj_stream_t* l_stream = 00;
|
||||
|
||||
|
||||
@@ -572,10 +572,10 @@ typedef struct opj_cio {
|
||||
/*
|
||||
* FIXME DOC
|
||||
*/
|
||||
typedef OPJ_UINT32 (* opj_stream_read_fn) (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data) ;
|
||||
typedef OPJ_UINT32 (* opj_stream_write_fn) (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data) ;
|
||||
typedef OPJ_SIZE_T (* opj_stream_skip_fn) (OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
|
||||
typedef opj_bool (* opj_stream_seek_fn) (OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
|
||||
typedef OPJ_SIZE_T (* opj_stream_read_fn) (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
|
||||
typedef OPJ_SIZE_T (* opj_stream_write_fn) (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
|
||||
typedef OPJ_OFF_T (* opj_stream_skip_fn) (OPJ_OFF_T p_nb_bytes, void * p_user_data) ;
|
||||
typedef opj_bool (* opj_stream_seek_fn) (OPJ_OFF_T p_nb_bytes, void * p_user_data) ;
|
||||
|
||||
/*
|
||||
* JPEG2000 Stream.
|
||||
@@ -679,11 +679,11 @@ typedef struct opj_image_comptparm {
|
||||
* */
|
||||
typedef struct opj_packet_info {
|
||||
/** packet start position (including SOP marker if it exists) */
|
||||
int start_pos;
|
||||
OPJ_OFF_T start_pos;
|
||||
/** end of packet header position (including EPH marker if it exists)*/
|
||||
int end_ph_pos;
|
||||
OPJ_OFF_T end_ph_pos;
|
||||
/** packet end position */
|
||||
int end_pos;
|
||||
OPJ_OFF_T end_pos;
|
||||
/** packet distorsion */
|
||||
double disto;
|
||||
} opj_packet_info_t;
|
||||
@@ -697,7 +697,7 @@ typedef struct opj_marker_info_t {
|
||||
/** marker type */
|
||||
unsigned short int type;
|
||||
/** position in codestream */
|
||||
int pos;
|
||||
OPJ_OFF_T pos;
|
||||
/** length, marker val included */
|
||||
int len;
|
||||
} opj_marker_info_t;
|
||||
@@ -906,14 +906,11 @@ typedef struct opj_codestream_info_v2 {
|
||||
*/
|
||||
typedef struct opj_tp_index {
|
||||
/** start position */
|
||||
OPJ_UINT32 start_pos;
|
||||
OPJ_OFF_T start_pos;
|
||||
/** end position of the header */
|
||||
OPJ_UINT32 end_header;
|
||||
OPJ_OFF_T end_header;
|
||||
/** end position */
|
||||
OPJ_UINT32 end_pos;
|
||||
|
||||
|
||||
|
||||
OPJ_OFF_T end_pos;
|
||||
|
||||
} opj_tp_index_t;
|
||||
|
||||
@@ -954,12 +951,12 @@ typedef struct opj_tile_index {
|
||||
*/
|
||||
typedef struct opj_codestream_index_ {
|
||||
/** main header start position (SOC position) */
|
||||
OPJ_UINT32 main_head_start;
|
||||
OPJ_OFF_T main_head_start;
|
||||
/** main header end position (first SOT position) */
|
||||
OPJ_UINT32 main_head_end;
|
||||
OPJ_OFF_T main_head_end;
|
||||
|
||||
/** codestream's size */
|
||||
OPJ_UINT32 codestream_size;
|
||||
OPJ_UINT64 codestream_size;
|
||||
|
||||
/* UniPG>> */
|
||||
/** number of markers */
|
||||
@@ -1089,7 +1086,7 @@ OPJ_API void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos);
|
||||
* @return a stream object.
|
||||
*/
|
||||
OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_default_create(opj_bool p_is_input);
|
||||
OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_UINT32 p_size, opj_bool p_is_input);
|
||||
OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size, opj_bool p_is_input);
|
||||
|
||||
/**
|
||||
* Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. If needed the user must
|
||||
@@ -1140,7 +1137,7 @@ OPJ_API void OPJ_CALLCONV opj_stream_set_user_data (opj_stream_t* p_stream, void
|
||||
* @param p_stream the stream to modify
|
||||
* @param data_length length of the user_data.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT32 data_length);
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MSWINDOWS) && !defined(Windows95) && !defined(__BORLANDC__) && \
|
||||
#if defined(WIN32) && !defined(Windows95) && !defined(__BORLANDC__) && \
|
||||
!(defined(_MSC_VER) && _MSC_VER < 1400) && \
|
||||
!(defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x800)
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user