[trunk] implement Large File support in the library
authorJulien Malik <julien.malik@paraiso.me>
Wed, 30 Nov 2011 16:55:25 +0000 (16:55 +0000)
committerJulien Malik <julien.malik@paraiso.me>
Wed, 30 Nov 2011 16:55:25 +0000 (16:55 +0000)
CHANGES
applications/codec/index.c
libopenjpeg/cio.c
libopenjpeg/cio.h
libopenjpeg/j2k.c
libopenjpeg/j2k.h
libopenjpeg/openjpeg.c
libopenjpeg/openjpeg.h
libopenjpeg/opj_includes.h
tests/CMakeLists.txt
tests/j2k_random_tile_access.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index bdf2138637c5893ffb3a3d1b33d3db768074668b..33a592f9d5b511744707201d7a3e3487fe484870 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,15 @@ What's New for OpenJPEG
 ! : changed
 + : added
 
+November 30, 2011
+* [jmalik] implement Large File support in the library :
+           - fix portability layer for windows (need WIN32)
+           - include opj_config.h before any system header (index)
+           - change types related to buffer size to OPJ_SIZE_T, for anything sent to memcpy, fread, fwrite
+           - change types related to index in stream to OPJ_OFF_T, thus resolving to a 64 bit signed integer
+           - change types related to size of stream to OPJ_UINT64_T
+           - change calls to fseek/ftell to LFS-capable OPJ_SEEK/OPJ_TELL
+
 November 29, 2011
 * [mickael] fix error with new way to detect kdu_expand
 
index 27a40740a285b13f27e69590087a1ddc6b53b2bb..d500ce5e93830fe68cbc82a5471b1688fa8af9c1 100644 (file)
@@ -25,6 +25,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
  * POSSIBILITY OF SUCH DAMAGE.\r
  */\r
+#include "opj_config.h"\r
 \r
 #include <stdio.h>\r
 #include <math.h>\r
index 32203a459182b2a27a3245c2b2e8e70915ced346..1628c215e2870cb38d74af6205a456252b771482 100644 (file)
@@ -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)
+OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
 {
-       return (OPJ_UINT32) -1;
+       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_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 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 (OPJ_UINT32) -1;
+       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_SIZE_T opj_stream_default_skip (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)
 {
-       return (OPJ_SIZE_T) -1;
+       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_SIZE_T p_nb_bytes, void * p_user_data)
+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;
 }
-
-
-
-
index 55df189f73f5bae039d36b7dac84b788bda2d234..b276930806e6ef703690eabdb5eccf1630c584a1 100644 (file)
@@ -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);
 
 
 
index f1171d6a9c8004cc0151bfba54e2a15b2440cf63..19b4d2b4dc9aabed8d43d944dda01c37b38f322a 100644 (file)
@@ -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;
index 360d869929c47c19da3716fabba0b5a771c5a551..2ec8980d3d1b2e648a9be00678fa1a49b4570fc1 100644 (file)
@@ -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.
index 73b136d6fe4675ad15d34f113ccc1441cac425e3..4470887d4894f6b50a448865640238ba6112b118 100644 (file)
@@ -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;
 
index 34915a16fafa7c4d1db5f58b3c5182ce3a426587..d8a332b3c78c8d8965e049989b80ba6c567c5552 100644 (file)
@@ -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);
 
 
 /**
index 4801ef69d8a0a698d8929d2219cddaa37f21fe16..0ee873a8139fcbfd4d07b62ed4509d7c289df3a1 100644 (file)
@@ -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)
   /*
index 0a6215c48df106466534b9467067ba0ac4efbcb5..1252948bc6c2e740dfaa4b5443fee1f3f7ef190b 100644 (file)
@@ -24,6 +24,9 @@ TARGET_LINK_LIBRARIES(comparePGXimages ${OPENJPEG_LIBRARY_NAME}
                                        
 ADD_EXECUTABLE(compare_dump_files ${compare_dump_files_SRCS})
 
+ADD_EXECUTABLE(j2k_random_tile_access j2k_random_tile_access.c)
+TARGET_LINK_LIBRARIES(j2k_random_tile_access ${OPENJPEG_LIBRARY_NAME})
+
 ADD_EXECUTABLE(compareRAWimages ${compareRAWimages_SRCS})
 
 # No image send to the dashboard if lib PNG is not available.
diff --git a/tests/j2k_random_tile_access.c b/tests/j2k_random_tile_access.c
new file mode 100644 (file)
index 0000000..ab08760
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "opj_config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <strings.h>
+#define _stricmp strcasecmp
+#define _strnicmp strncasecmp
+#endif /* _WIN32 */
+
+#include "openjpeg.h"
+#include "format_defs.h"
+
+/* -------------------------------------------------------------------------- */
+int get_file_format(const char *filename) {
+       unsigned int i;
+       static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
+       static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
+       char * ext = strrchr(filename, '.');
+       if (ext == NULL)
+               return -1;
+       ext++;
+       if(ext) {
+               for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
+                       if(_strnicmp(ext, extension[i], 3) == 0) {
+                               return format[i];
+                       }
+               }
+       }
+
+       return -1;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+sample error callback expecting a FILE* client object
+*/
+void error_callback(const char *msg, void *client_data) {
+       FILE *stream = (FILE*)client_data;
+       fprintf(stream, "[ERROR] %s", msg);
+}
+/**
+sample warning callback expecting a FILE* client object
+*/
+void warning_callback(const char *msg, void *client_data) {
+       FILE *stream = (FILE*)client_data;
+       fprintf(stream, "[WARNING] %s", msg);
+}
+/**
+sample debug callback expecting no client object
+*/
+void info_callback(const char *msg, void *client_data) {
+       (void)client_data;
+       fprintf(stdout, "[INFO] %s", msg);
+}
+
+
+/* -------------------------------------------------------------------------- */
+#define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
+#define JP2_MAGIC "\x0d\x0a\x87\x0a"
+/* position 45: "\xff\x52" */
+#define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
+
+static int infile_format(const char *fname)
+{
+       FILE *reader;
+       const char *s, *magic_s;
+       int ext_format, magic_format;
+       unsigned char buf[12];
+       unsigned int l_nb_read;
+
+       reader = fopen(fname, "rb");
+
+       if (reader == NULL)
+               return -1;
+
+       memset(buf, 0, 12);
+       l_nb_read = fread(buf, 1, 12, reader);
+       fclose(reader);
+       if (l_nb_read != 12)
+               return -1;
+
+
+
+       ext_format = get_file_format(fname);
+
+       if (ext_format == JPT_CFMT)
+               return JPT_CFMT;
+
+       if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
+               magic_format = JP2_CFMT;
+               magic_s = ".jp2";
+       }
+       else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
+               magic_format = J2K_CFMT;
+               magic_s = ".j2k or .jpc or .j2c";
+       }
+       else
+               return -1;
+
+       if (magic_format == ext_format)
+               return ext_format;
+
+       s = fname + strlen(fname) - 4;
+
+       fputs("\n===========================================\n", stderr);
+       fprintf(stderr, "The extension of this file is incorrect.\n"
+                                       "FOUND %s. SHOULD BE %s\n", s, magic_s);
+       fputs("===========================================\n", stderr);
+
+       return magic_format;
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * J2K_RANDOM_TILE_ACCESS MAIN
+ */
+/* -------------------------------------------------------------------------- */
+int main(int argc, char **argv)
+{
+       FILE *fsrc = NULL;
+
+       opj_dparameters_t parameters;                   /* decompression parameters */
+       opj_event_mgr_t event_mgr;                              /* event manager */
+       opj_image_t* image = NULL;
+       opj_stream_t *cio = NULL;                               /* Stream */
+       opj_codec_t* dinfo = NULL;                              /* Handle to a decompressor */
+       opj_codestream_info_v2_t* cstr_info = NULL;
+
+       if (argc != 2) {
+               fprintf(stderr, "Usage: %s <input_file>\n", argv[0]);
+               return EXIT_FAILURE;
+       }
+
+       /* Set event mgr */
+       event_mgr.error_handler = error_callback;
+       event_mgr.warning_handler = warning_callback;
+       event_mgr.info_handler = info_callback;
+       opj_initialize_default_event_handler(&event_mgr, 1);
+
+       /* Set decoding parameters to default values */
+       opj_set_default_decoder_parameters(&parameters);
+
+       strncpy(parameters.infile, argv[1], OPJ_PATH_LEN - 1);
+
+       /* read the input file */
+       /* ------------------- */
+       fsrc = fopen(parameters.infile, "rb");
+       if (!fsrc) {
+               fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
+               return EXIT_FAILURE;
+       }
+
+       /* decode the JPEG2000 stream */
+       /* -------------------------- */
+       parameters.decod_format = infile_format(parameters.infile);
+
+       switch(parameters.decod_format) {
+               case J2K_CFMT:  /* JPEG-2000 codestream */
+               {
+                       /* Get a decoder handle */
+                       dinfo = opj_create_decompress_v2(CODEC_J2K);
+                       break;
+               }
+               case JP2_CFMT:  /* JPEG 2000 compressed image data */
+               {
+                       /* Get a decoder handle */
+                       dinfo = opj_create_decompress_v2(CODEC_JP2);
+                       break;
+               }
+               case JPT_CFMT:  /* JPEG 2000, JPIP */
+               {
+                       /* Get a decoder handle */
+                       dinfo = opj_create_decompress_v2(CODEC_JPT);
+                       break;
+               }
+               default:
+                       fprintf(stderr,
+                               "Unrecognized format for input %s [accept only *.j2k, *.jp2, *.jpc or *.jpt]\n\n",
+                               parameters.infile);
+                       return EXIT_FAILURE;
+       }
+
+       cio = opj_stream_create_default_file_stream(fsrc,1);
+       if (!cio){
+               fclose(fsrc);
+               fprintf(stderr, "ERROR -> failed to create the stream from the file\n");
+               return EXIT_FAILURE;
+       }
+
+       /* Setup the decoder decoding parameters using user parameters */
+       if ( !opj_setup_decoder_v2(dinfo, &parameters, &event_mgr) ){
+               fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
+               opj_stream_destroy(cio);
+               fclose(fsrc);
+               opj_destroy_codec(dinfo);
+               return EXIT_FAILURE;
+       }
+
+       /* Read the main header of the codestream and if necessary the JP2 boxes*/
+       if(! opj_read_header(cio, dinfo, &image)){
+               fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
+               opj_stream_destroy(cio);
+               fclose(fsrc);
+               opj_destroy_codec(dinfo);
+               opj_image_destroy(image);
+               return EXIT_FAILURE;
+       }
+
+       /* Extract some info from the code stream */
+       cstr_info = opj_get_cstr_info(dinfo);
+
+       fprintf(stdout, "The file contains %dx%d tiles\n", cstr_info->tw, cstr_info->th);
+
+       OPJ_UINT32 tile_ul = 0;
+       OPJ_UINT32 tile_ur = cstr_info->tw - 1;
+       OPJ_UINT32 tile_lr = cstr_info->tw * cstr_info->th - 1;
+       OPJ_UINT32 tile_ll = tile_lr - cstr_info->tw;
+
+#define TEST_TILE( tile_index ) \
+       fprintf(stdout, "Decoding tile %d ...\n", tile_index); \
+       if(!opj_get_decoded_tile(dinfo, cio, image, tile_index )){ \
+               fprintf(stderr, "ERROR -> j2k_to_image: failed to decode tile %d\n", tile_index); \
+               opj_stream_destroy(cio); \
+               opj_destroy_cstr_info_v2(cstr_info); \
+               opj_destroy_codec(dinfo); \
+               opj_image_destroy(image); \
+               fclose(fsrc); \
+               return EXIT_FAILURE; \
+       } \
+       fprintf(stdout, "Tile %d is decoded successfully\n", tile_index);
+
+       TEST_TILE(tile_ul)
+       TEST_TILE(tile_lr)
+       TEST_TILE(tile_ul)
+       TEST_TILE(tile_ll)
+       TEST_TILE(tile_ur)
+       TEST_TILE(tile_lr)
+
+       /* Close the byte stream */
+       opj_stream_destroy(cio);
+
+       /* Destroy code stream info */
+       opj_destroy_cstr_info_v2(cstr_info);
+
+       /* Free remaining structures */
+       opj_destroy_codec(dinfo);
+
+       /* Free image data structure */
+       opj_image_destroy(image);
+
+       /* Close the input file */
+       fclose(fsrc);
+
+       return EXIT_SUCCESS;
+}
+//end main
+
+
+
+