/*
- * The copyright in this software is being made available under the 2-clauses
- * BSD License, included below. This software may be subject to other third
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such rights
* are granted under this license.
*
#include "wx/wxprec.h"
#ifdef __BORLANDC__
- #pragma hdrstop
+#pragma hdrstop
#endif
#if wxUSE_IMAGE && wxUSE_LIBOPENJPEG
#include "imagjpeg2000.h"
#ifndef WX_PRECOMP
- #include "wx/log.h"
- #include "wx/app.h"
- #include "wx/intl.h"
- #include "wx/bitmap.h"
- #include "wx/module.h"
+#include "wx/log.h"
+#include "wx/app.h"
+#include "wx/intl.h"
+#include "wx/bitmap.h"
+#include "wx/module.h"
#endif
#include "openjp2/openjpeg.h"
// wxJPEG2000Handler
//-----------------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxJPEG2000Handler,wxImageHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxJPEG2000Handler, wxImageHandler)
#if wxUSE_STREAMS
int
jpeg2000familytype(unsigned char *hdr, int hdr_len)
{
- // check length
- if (hdr_len < 24)
+ // check length
+ if (hdr_len < 24) {
return -1;
-
- // check format
- if (hdr[0] == 0x00 &&
- hdr[1] == 0x00 &&
- hdr[2] == 0x00 &&
- hdr[3] == 0x0C &&
- hdr[4] == 0x6A &&
- hdr[5] == 0x50 &&
- hdr[6] == 0x20 &&
- hdr[7] == 0x20 &&
- hdr[20] == 0x6A &&
- hdr[21] == 0x70 &&
- hdr[22] == 0x32)
- // JP2 file format
- return JP2_CFMT;
- else if (hdr[0] == 0x00 &&
- hdr[1] == 0x00 &&
- hdr[2] == 0x00 &&
- hdr[3] == 0x0C &&
- hdr[4] == 0x6A &&
- hdr[5] == 0x50 &&
- hdr[6] == 0x20 &&
- hdr[7] == 0x20 &&
- hdr[20] == 0x6D &&
- hdr[21] == 0x6A &&
- hdr[22] == 0x70 &&
- hdr[23] == 0x32)
- // MJ2 file format
- return MJ2_CFMT;
- else if (hdr[0] == 0xFF &&
- hdr[1] == 0x4F)
- // J2K file format
- return J2K_CFMT;
- else
- // unknown format
- return -1;
+ }
+
+ // check format
+ if (hdr[0] == 0x00 &&
+ hdr[1] == 0x00 &&
+ hdr[2] == 0x00 &&
+ hdr[3] == 0x0C &&
+ hdr[4] == 0x6A &&
+ hdr[5] == 0x50 &&
+ hdr[6] == 0x20 &&
+ hdr[7] == 0x20 &&
+ hdr[20] == 0x6A &&
+ hdr[21] == 0x70 &&
+ hdr[22] == 0x32)
+ // JP2 file format
+ {
+ return JP2_CFMT;
+ } else if (hdr[0] == 0x00 &&
+ hdr[1] == 0x00 &&
+ hdr[2] == 0x00 &&
+ hdr[3] == 0x0C &&
+ hdr[4] == 0x6A &&
+ hdr[5] == 0x50 &&
+ hdr[6] == 0x20 &&
+ hdr[7] == 0x20 &&
+ hdr[20] == 0x6D &&
+ hdr[21] == 0x6A &&
+ hdr[22] == 0x70 &&
+ hdr[23] == 0x32)
+ // MJ2 file format
+ {
+ return MJ2_CFMT;
+ } else if (hdr[0] == 0xFF &&
+ hdr[1] == 0x4F)
+ // J2K file format
+ {
+ return J2K_CFMT;
+ } else
+ // unknown format
+ {
+ return -1;
+ }
}
/* we have to use this to avoid GUI-noGUI threads crashing */
void printevent(const char *msg)
{
-#ifndef __WXGTK__
- wxMutexGuiEnter();
+#ifndef __WXGTK__
+ wxMutexGuiEnter();
#endif /* __WXGTK__ */
- wxLogMessage(wxT("%s"), msg);
-#ifndef __WXGTK__
+ wxLogMessage(wxT("%s"), msg);
+#ifndef __WXGTK__
wxMutexGuiLeave();
#endif /* __WXGTK__ */
}
/* sample error callback expecting a FILE* client object */
-void jpeg2000_error_callback(const char *msg, void *client_data) {
- char mess[MAX_MESSAGE_LEN + 20];
- int message_len = strlen(msg);
-
- if (message_len > MAX_MESSAGE_LEN)
- message_len = MAX_MESSAGE_LEN;
-
- if (msg[message_len - 1] == '\n')
- message_len--;
-
- sprintf(mess, "[ERROR] %.*s", message_len, msg);
- printevent(mess);
+void jpeg2000_error_callback(const char *msg, void *client_data)
+{
+ char mess[MAX_MESSAGE_LEN + 20];
+ int message_len = strlen(msg);
+
+ if (message_len > MAX_MESSAGE_LEN) {
+ message_len = MAX_MESSAGE_LEN;
+ }
+
+ if (msg[message_len - 1] == '\n') {
+ message_len--;
+ }
+
+ sprintf(mess, "[ERROR] %.*s", message_len, msg);
+ printevent(mess);
}
/* sample warning callback expecting a FILE* client object */
-void jpeg2000_warning_callback(const char *msg, void *client_data) {
- char mess[MAX_MESSAGE_LEN + 20];
- int message_len = strlen(msg);
-
- if (message_len > MAX_MESSAGE_LEN)
- message_len = MAX_MESSAGE_LEN;
-
- if (msg[message_len - 1] == '\n')
- message_len--;
-
- sprintf(mess, "[WARNING] %.*s", message_len, msg);
- printevent(mess);
+void jpeg2000_warning_callback(const char *msg, void *client_data)
+{
+ char mess[MAX_MESSAGE_LEN + 20];
+ int message_len = strlen(msg);
+
+ if (message_len > MAX_MESSAGE_LEN) {
+ message_len = MAX_MESSAGE_LEN;
+ }
+
+ if (msg[message_len - 1] == '\n') {
+ message_len--;
+ }
+
+ sprintf(mess, "[WARNING] %.*s", message_len, msg);
+ printevent(mess);
}
/* sample debug callback expecting no client object */
-void jpeg2000_info_callback(const char *msg, void *client_data) {
- char mess[MAX_MESSAGE_LEN + 20];
- int message_len = strlen(msg);
-
- if (message_len > MAX_MESSAGE_LEN)
- message_len = MAX_MESSAGE_LEN;
-
- if (msg[message_len - 1] == '\n')
- message_len--;
-
- sprintf(mess, "[INFO] %.*s", message_len, msg);
- printevent(mess);
+void jpeg2000_info_callback(const char *msg, void *client_data)
+{
+ char mess[MAX_MESSAGE_LEN + 20];
+ int message_len = strlen(msg);
+
+ if (message_len > MAX_MESSAGE_LEN) {
+ message_len = MAX_MESSAGE_LEN;
+ }
+
+ if (msg[message_len - 1] == '\n') {
+ message_len--;
+ }
+
+ sprintf(mess, "[INFO] %.*s", message_len, msg);
+ printevent(mess);
}
/* macro functions */
/* From little endian to big endian, 2 and 4 bytes */
-#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)
-#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)
+#define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)
+#define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)
#ifdef __WXGTK__
-#define BYTE_SWAP8(X) ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \
+#define BYTE_SWAP8(X) ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \
((X & 0x0000000000FF0000ULL) << 24) | ((X & 0x00000000FF000000ULL) << 8) | \
- ((X & 0x000000FF00000000ULL) >> 8) | ((X & 0x0000FF0000000000ULL) >> 24) | \
- ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56)
+ ((X & 0x000000FF00000000ULL) >> 8) | ((X & 0x0000FF0000000000ULL) >> 24) | \
+ ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56)
#else
-#define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \
+#define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \
((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \
- ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \
- ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56)
+ ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \
+ ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56)
#endif
/* From codestream to int values */
-#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \
- ((unsigned long int) (C)[(P) + 1] << 16) + \
- ((unsigned long int) (C)[(P) + 2] << 8) + \
- ((unsigned long int) (C)[(P) + 3] << 0))
+#define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \
+ ((unsigned long int) (C)[(P) + 1] << 16) + \
+ ((unsigned long int) (C)[(P) + 2] << 8) + \
+ ((unsigned long int) (C)[(P) + 3] << 0))
-#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \
- ((unsigned long int) (C)[(P) + 1] << 0))
+#define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \
+ ((unsigned long int) (C)[(P) + 1] << 0))
/* defines */
#define SHORT_DESCR_LEN 32
#define JPEG2000FILENUM 4
typedef enum {
- JP2_FILE,
- J2K_FILE,
- MJ2_FILE,
- UNK_FILE
+ JP2_FILE,
+ J2K_FILE,
+ MJ2_FILE,
+ UNK_FILE
} jpeg2000filetype;
#define JPEG2000BOXNUM 23
typedef enum {
- FILE_BOX,
- JP_BOX,
- FTYP_BOX,
- JP2H_BOX,
- IHDR_BOX,
- COLR_BOX,
- JP2C_BOX,
- JP2I_BOX,
- XML_BOX,
- UUID_BOX,
- UINF_BOX,
- MOOV_BOX,
- MVHD_BOX,
- TRAK_BOX,
- TKHD_BOX,
- MDIA_BOX,
- MINF_BOX,
- STBL_BOX,
- STSD_BOX,
- MJP2_BOX,
- MDAT_BOX,
- ANY_BOX,
- UNK_BOX
+ FILE_BOX,
+ JP_BOX,
+ FTYP_BOX,
+ JP2H_BOX,
+ IHDR_BOX,
+ COLR_BOX,
+ JP2C_BOX,
+ JP2I_BOX,
+ XML_BOX,
+ UUID_BOX,
+ UINF_BOX,
+ MOOV_BOX,
+ MVHD_BOX,
+ TRAK_BOX,
+ TKHD_BOX,
+ MDIA_BOX,
+ MINF_BOX,
+ STBL_BOX,
+ STSD_BOX,
+ MJP2_BOX,
+ MDAT_BOX,
+ ANY_BOX,
+ UNK_BOX
} jpeg2000boxtype;
#define STSD_SIGN "stsd"
#define MJP2_SIGN "mjp2"
#define MDAT_SIGN "mdat"
-#define ANY_SIGN ""
+#define ANY_SIGN ""
#define UNK_SIGN ""
/* the box structure itself */
struct jpeg2000boxdef {
- char value[5]; /* hexadecimal value/string*/
- char name[SHORT_DESCR_LEN]; /* short description */
- char descr[LONG_DESCR_LEN]; /* long description */
- int sbox; /* is it a superbox? */
- int req[JPEG2000FILENUM]; /* mandatory box */
- jpeg2000boxtype ins; /* contained in box... */
+ char value[5]; /* hexadecimal value/string*/
+ char name[SHORT_DESCR_LEN]; /* short description */
+ char descr[LONG_DESCR_LEN]; /* long description */
+ int sbox; /* is it a superbox? */
+ int req[JPEG2000FILENUM]; /* mandatory box */
+ jpeg2000boxtype ins; /* contained in box... */
};
/* the possible boxes */
-struct jpeg2000boxdef jpeg2000box[] =
-{
-/* sign */ {FILE_SIGN,
-/* short */ "placeholder for nothing",
-/* long */ "Nothing to say",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ FILE_BOX},
-
-/* sign */ {JP_SIGN,
-/* short */ "JPEG 2000 Signature box",
-/* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ FILE_BOX},
-
-/* sign */ {FTYP_SIGN,
-/* short */ "File Type box",
-/* long */ "This box specifies file type, version and compatibility information, including specifying if this file "
- "is a conforming JP2 file or if it can be read by a conforming JP2 reader",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ FILE_BOX},
-
-/* sign */ {JP2H_SIGN,
-/* short */ "JP2 Header box",
-/* long */ "This box contains a series of boxes that contain header-type information about the file",
-/* sbox */ 1,
-/* req */ {1, 1, 1},
-/* ins */ FILE_BOX},
-
-/* sign */ {IHDR_SIGN,
-/* short */ "Image Header box",
-/* long */ "This box specifies the size of the image and other related fields",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ JP2H_BOX},
-
-/* sign */ {COLR_SIGN,
-/* short */ "Colour Specification box",
-/* long */ "This box specifies the colourspace of the image",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ JP2H_BOX},
-
-/* sign */ {JP2C_SIGN,
-/* short */ "Contiguous Codestream box",
-/* long */ "This box contains the codestream as defined by Annex A",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ FILE_BOX},
-
-/* sign */ {JP2I_SIGN,
-/* short */ "Intellectual Property box",
-/* long */ "This box contains intellectual property information about the image",
-/* sbox */ 0,
-/* req */ {0, 0, 0},
-/* ins */ FILE_BOX},
-
-/* sign */ {XML_SIGN,
-/* short */ "XML box",
-/* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file",
-/* sbox */ 0,
-/* req */ {0, 0, 0},
-/* ins */ FILE_BOX},
-
-/* sign */ {UUID_SIGN,
-/* short */ "UUID box",
-/* long */ "This box provides a tool by which vendors can add additional information to a file "
- "without risking conflict with other vendors",
-/* sbox */ 0,
-/* req */ {0, 0, 0},
-/* ins */ FILE_BOX},
-
-/* sign */ {UINF_SIGN,
-/* short */ "UUID Info box",
-/* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID",
-/* sbox */ 0,
-/* req */ {0, 0, 0},
-/* ins */ FILE_BOX},
-
-/* sign */ {MOOV_SIGN,
-/* short */ "Movie box",
-/* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames",
-/* sbox */ 1,
-/* req */ {1, 1, 1},
-/* ins */ FILE_BOX},
-
-/* sign */ {MVHD_SIGN,
-/* short */ "Movie Header box",
-/* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation "
- "considered as a whole",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ MOOV_BOX},
-
-/* sign */ {TRAK_SIGN,
-/* short */ "Track box",
-/* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks",
-/* sbox */ 1,
-/* req */ {1, 1, 1},
-/* ins */ MOOV_BOX},
-
-/* sign */ {TKHD_SIGN,
-/* short */ "Track Header box",
-/* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ TRAK_BOX},
-
-/* sign */ {MDIA_SIGN,
-/* short */ "Media box",
-/* long */ "The media declaration container contains all the objects which declare information about the media data "
- "within a track",
-/* sbox */ 1,
-/* req */ {1, 1, 1},
-/* ins */ TRAK_BOX},
-
-/* sign */ {MINF_SIGN,
-/* short */ "Media Information box",
-/* long */ "This box contains all the objects which declare characteristic information of the media in the track",
-/* sbox */ 1,
-/* req */ {1, 1, 1},
-/* ins */ MDIA_BOX},
-
-/* sign */ {STBL_SIGN,
-/* short */ "Sample Table box",
-/* long */ "The sample table contains all the time and data indexing of the media samples in a track",
-/* sbox */ 1,
-/* req */ {1, 1, 1},
-/* ins */ MINF_BOX},
-
-/* sign */ {STSD_SIGN,
-/* short */ "Sample Description box",
-/* long */ "The sample description table gives detailed information about the coding type used, and any initialization "
- "information needed for that coding",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ MINF_BOX},
-
-/* sign */ {MJP2_SIGN,
-/* short */ "MJP2 Sample Description box",
-/* long */ "The MJP2 sample description table gives detailed information about the coding type used, and any initialization "
- "information needed for that coding",
-/* sbox */ 0,
-/* req */ {1, 1, 1},
-/* ins */ MINF_BOX},
-
-/* sign */ {MDAT_SIGN,
-/* short */ "Media Data box",
-/* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file",
-/* sbox */ 1,
-/* req */ {1, 1, 1},
-/* ins */ FILE_BOX},
-
-/* sign */ {ANY_SIGN,
-/* short */ "Any box",
-/* long */ "All the existing boxes",
-/* sbox */ 0,
-/* req */ {0, 0, 0},
-/* ins */ FILE_BOX},
-
-/* sign */ {UNK_SIGN,
-/* short */ "Unknown Type box",
-/* long */ "The signature is not recognised to be that of an existing box",
-/* sbox */ 0,
-/* req */ {0, 0, 0},
-/* ins */ ANY_BOX}
+struct jpeg2000boxdef jpeg2000box[] = {
+ /* sign */ {
+ FILE_SIGN,
+ /* short */ "placeholder for nothing",
+ /* long */ "Nothing to say",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ JP_SIGN,
+ /* short */ "JPEG 2000 Signature box",
+ /* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ FTYP_SIGN,
+ /* short */ "File Type box",
+ /* long */ "This box specifies file type, version and compatibility information, including specifying if this file "
+ "is a conforming JP2 file or if it can be read by a conforming JP2 reader",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ JP2H_SIGN,
+ /* short */ "JP2 Header box",
+ /* long */ "This box contains a series of boxes that contain header-type information about the file",
+ /* sbox */ 1,
+ /* req */ {1, 1, 1},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ IHDR_SIGN,
+ /* short */ "Image Header box",
+ /* long */ "This box specifies the size of the image and other related fields",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ JP2H_BOX
+ },
+
+ /* sign */ {
+ COLR_SIGN,
+ /* short */ "Colour Specification box",
+ /* long */ "This box specifies the colourspace of the image",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ JP2H_BOX
+ },
+
+ /* sign */ {
+ JP2C_SIGN,
+ /* short */ "Contiguous Codestream box",
+ /* long */ "This box contains the codestream as defined by Annex A",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ JP2I_SIGN,
+ /* short */ "Intellectual Property box",
+ /* long */ "This box contains intellectual property information about the image",
+ /* sbox */ 0,
+ /* req */ {0, 0, 0},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ XML_SIGN,
+ /* short */ "XML box",
+ /* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file",
+ /* sbox */ 0,
+ /* req */ {0, 0, 0},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ UUID_SIGN,
+ /* short */ "UUID box",
+ /* long */ "This box provides a tool by which vendors can add additional information to a file "
+ "without risking conflict with other vendors",
+ /* sbox */ 0,
+ /* req */ {0, 0, 0},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ UINF_SIGN,
+ /* short */ "UUID Info box",
+ /* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID",
+ /* sbox */ 0,
+ /* req */ {0, 0, 0},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ MOOV_SIGN,
+ /* short */ "Movie box",
+ /* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames",
+ /* sbox */ 1,
+ /* req */ {1, 1, 1},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ MVHD_SIGN,
+ /* short */ "Movie Header box",
+ /* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation "
+ "considered as a whole",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ MOOV_BOX
+ },
+
+ /* sign */ {
+ TRAK_SIGN,
+ /* short */ "Track box",
+ /* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks",
+ /* sbox */ 1,
+ /* req */ {1, 1, 1},
+ /* ins */ MOOV_BOX
+ },
+
+ /* sign */ {
+ TKHD_SIGN,
+ /* short */ "Track Header box",
+ /* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ TRAK_BOX
+ },
+
+ /* sign */ {
+ MDIA_SIGN,
+ /* short */ "Media box",
+ /* long */ "The media declaration container contains all the objects which declare information about the media data "
+ "within a track",
+ /* sbox */ 1,
+ /* req */ {1, 1, 1},
+ /* ins */ TRAK_BOX
+ },
+
+ /* sign */ {
+ MINF_SIGN,
+ /* short */ "Media Information box",
+ /* long */ "This box contains all the objects which declare characteristic information of the media in the track",
+ /* sbox */ 1,
+ /* req */ {1, 1, 1},
+ /* ins */ MDIA_BOX
+ },
+
+ /* sign */ {
+ STBL_SIGN,
+ /* short */ "Sample Table box",
+ /* long */ "The sample table contains all the time and data indexing of the media samples in a track",
+ /* sbox */ 1,
+ /* req */ {1, 1, 1},
+ /* ins */ MINF_BOX
+ },
+
+ /* sign */ {
+ STSD_SIGN,
+ /* short */ "Sample Description box",
+ /* long */ "The sample description table gives detailed information about the coding type used, and any initialization "
+ "information needed for that coding",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ MINF_BOX
+ },
+
+ /* sign */ {
+ MJP2_SIGN,
+ /* short */ "MJP2 Sample Description box",
+ /* long */ "The MJP2 sample description table gives detailed information about the coding type used, and any initialization "
+ "information needed for that coding",
+ /* sbox */ 0,
+ /* req */ {1, 1, 1},
+ /* ins */ MINF_BOX
+ },
+
+ /* sign */ {
+ MDAT_SIGN,
+ /* short */ "Media Data box",
+ /* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file",
+ /* sbox */ 1,
+ /* req */ {1, 1, 1},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ ANY_SIGN,
+ /* short */ "Any box",
+ /* long */ "All the existing boxes",
+ /* sbox */ 0,
+ /* req */ {0, 0, 0},
+ /* ins */ FILE_BOX
+ },
+
+ /* sign */ {
+ UNK_SIGN,
+ /* short */ "Unknown Type box",
+ /* long */ "The signature is not recognised to be that of an existing box",
+ /* sbox */ 0,
+ /* req */ {0, 0, 0},
+ /* ins */ ANY_BOX
+ }
};
/* declaration */
int
-jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream, unsigned long int filepoint,
- unsigned long int filelimit, int level, char *scansign,
- unsigned long int *scanpoint);
+jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream,
+ unsigned long int filepoint,
+ unsigned long int filelimit, int level, char *scansign,
+ unsigned long int *scanpoint);
#ifdef __WXMSW__
typedef unsigned __int64 int8byte;
/* internal mini-search for a box signature */
int
-jpeg2000_file_parse(wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level,
- char *scansign, unsigned long int *scanpoint)
+jpeg2000_file_parse(wxInputStream& stream, unsigned long int filepoint,
+ unsigned long int filelimit, int level,
+ char *scansign, unsigned long int *scanpoint)
{
- unsigned long int LBox = 0x00000000;
- char TBox[5] = "\0\0\0\0";
- int8byte XLBox = 0x0000000000000000;
- unsigned long int box_length = 0;
- int last_box = 0, box_num = 0;
- int box_type = ANY_BOX;
- unsigned char fourbytes[4];
- int box_number = 0;
-
- /* cycle all over the file */
- box_num = 0;
- last_box = 0;
- while (!last_box) {
-
- /* do not exceed file limit */
- if (filepoint >= filelimit)
- return (0);
-
- /* seek on file */
- if (stream.SeekI(filepoint, wxFromStart) == wxInvalidOffset)
- return (-1);
-
- /* read the mandatory LBox, 4 bytes */
- if (!stream.Read(fourbytes, 4)) {
- wxLogError(wxT("Problem reading LBox from the file (file ended?)"));
- return -1;
- };
- LBox = STREAM_TO_UINT32(fourbytes, 0);
-
- /* read the mandatory TBox, 4 bytes */
- if (!stream.Read(TBox, 4)) {
- wxLogError(wxT("Problem reading TBox from the file (file ended?)"));
- return -1;
- };
-
- /* look if scansign is got */
- if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) {
- /* hack/exploit */
- // stop as soon as you find the level-th codebox
- if (box_number == level) {
- memcpy(scansign, " ", 4);
- *scanpoint = filepoint;
- return (0);
- } else
- box_number++;
-
- };
-
- /* determine the box type */
- for (box_type = JP_BOX; box_type < UNK_BOX; box_type++)
- if (memcmp(TBox, jpeg2000box[box_type].value, 4) == 0)
- break;
-
- /* read the optional XLBox, 8 bytes */
- if (LBox == 1) {
-
- if (!stream.Read(&XLBox, 8)) {
- wxLogError(wxT("Problem reading XLBox from the file (file ended?)"));
- return -1;
- };
- box_length = (unsigned long int) BYTE_SWAP8(XLBox);
-
- } else if (LBox == 0x00000000) {
-
- /* last box in file */
- last_box = 1;
- box_length = filelimit - filepoint;
-
- } else
-
- box_length = LBox;
-
-
- /* go deep in the box */
- jpeg2000_box_handler_function((jpeg2000boxtype) box_type,
- stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8),
- filepoint + box_length, level, scansign, scanpoint);
-
- /* if it's a superbox go inside it */
- if (jpeg2000box[box_type].sbox)
- jpeg2000_file_parse(stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,
- level, scansign, scanpoint);
-
- /* increment box number and filepoint*/
- box_num++;
- filepoint += box_length;
-
- };
-
- /* all good */
- return (0);
+ unsigned long int LBox = 0x00000000;
+ char TBox[5] = "\0\0\0\0";
+ int8byte XLBox = 0x0000000000000000;
+ unsigned long int box_length = 0;
+ int last_box = 0, box_num = 0;
+ int box_type = ANY_BOX;
+ unsigned char fourbytes[4];
+ int box_number = 0;
+
+ /* cycle all over the file */
+ box_num = 0;
+ last_box = 0;
+ while (!last_box) {
+
+ /* do not exceed file limit */
+ if (filepoint >= filelimit) {
+ return (0);
+ }
+
+ /* seek on file */
+ if (stream.SeekI(filepoint, wxFromStart) == wxInvalidOffset) {
+ return (-1);
+ }
+
+ /* read the mandatory LBox, 4 bytes */
+ if (!stream.Read(fourbytes, 4)) {
+ wxLogError(wxT("Problem reading LBox from the file (file ended?)"));
+ return -1;
+ };
+ LBox = STREAM_TO_UINT32(fourbytes, 0);
+
+ /* read the mandatory TBox, 4 bytes */
+ if (!stream.Read(TBox, 4)) {
+ wxLogError(wxT("Problem reading TBox from the file (file ended?)"));
+ return -1;
+ };
+
+ /* look if scansign is got */
+ if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) {
+ /* hack/exploit */
+ // stop as soon as you find the level-th codebox
+ if (box_number == level) {
+ memcpy(scansign, " ", 4);
+ *scanpoint = filepoint;
+ return (0);
+ } else {
+ box_number++;
+ }
+
+ };
+
+ /* determine the box type */
+ for (box_type = JP_BOX; box_type < UNK_BOX; box_type++)
+ if (memcmp(TBox, jpeg2000box[box_type].value, 4) == 0) {
+ break;
+ }
+
+ /* read the optional XLBox, 8 bytes */
+ if (LBox == 1) {
+
+ if (!stream.Read(&XLBox, 8)) {
+ wxLogError(wxT("Problem reading XLBox from the file (file ended?)"));
+ return -1;
+ };
+ box_length = (unsigned long int) BYTE_SWAP8(XLBox);
+
+ } else if (LBox == 0x00000000) {
+
+ /* last box in file */
+ last_box = 1;
+ box_length = filelimit - filepoint;
+
+ } else
+
+ {
+ box_length = LBox;
+ }
+
+
+ /* go deep in the box */
+ jpeg2000_box_handler_function((jpeg2000boxtype) box_type,
+ stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8),
+ filepoint + box_length, level, scansign, scanpoint);
+
+ /* if it's a superbox go inside it */
+ if (jpeg2000box[box_type].sbox)
+ jpeg2000_file_parse(stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8),
+ filepoint + box_length,
+ level, scansign, scanpoint);
+
+ /* increment box number and filepoint*/
+ box_num++;
+ filepoint += box_length;
+
+ };
+
+ /* all good */
+ return (0);
}
// search first contiguos codestream box in an mj2 file
unsigned long int
searchjpeg2000c(wxInputStream& stream, unsigned long int fsize, int number)
{
- char scansign[] = "jp2c";
- unsigned long int scanpoint = 0L;
+ char scansign[] = "jp2c";
+ unsigned long int scanpoint = 0L;
- wxLogMessage(wxT("Searching jp2c box... "));
+ wxLogMessage(wxT("Searching jp2c box... "));
- /* do the parsing */
- if (jpeg2000_file_parse(stream, 0, fsize, number, scansign, &scanpoint) < 0)
- wxLogMessage(wxT("Unrecoverable error during JPEG 2000 box parsing: stopping"));
+ /* do the parsing */
+ if (jpeg2000_file_parse(stream, 0, fsize, number, scansign, &scanpoint) < 0) {
+ wxLogMessage(
+ wxT("Unrecoverable error during JPEG 2000 box parsing: stopping"));
+ }
- if (strcmp(scansign, " "))
- wxLogMessage(wxT("Box not found"));
- else {
+ if (strcmp(scansign, " ")) {
+ wxLogMessage(wxT("Box not found"));
+ } else {
- wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint));
+ wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint));
- };
+ };
- return (scanpoint);
+ return (scanpoint);
}
// search the jp2h box in the file
unsigned long int
searchjpeg2000headerbox(wxInputStream& stream, unsigned long int fsize)
{
- char scansign[] = "jp2h";
- unsigned long int scanpoint = 0L;
+ char scansign[] = "jp2h";
+ unsigned long int scanpoint = 0L;
- wxLogMessage(wxT("Searching jp2h box... "));
+ wxLogMessage(wxT("Searching jp2h box... "));
- /* do the parsing */
- if (jpeg2000_file_parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0)
- wxLogMessage(wxT("Unrecoverable error during JPEG 2000 box parsing: stopping"));
+ /* do the parsing */
+ if (jpeg2000_file_parse(stream, 0, fsize, 0, scansign, &scanpoint) < 0) {
+ wxLogMessage(
+ wxT("Unrecoverable error during JPEG 2000 box parsing: stopping"));
+ }
- if (strcmp(scansign, " "))
- wxLogMessage(wxT("Box not found"));
- else
- wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint));
+ if (strcmp(scansign, " ")) {
+ wxLogMessage(wxT("Box not found"));
+ } else {
+ wxLogMessage(wxString::Format(wxT("Box found at byte %d"), scanpoint));
+ }
- return (scanpoint);
+ return (scanpoint);
}
/* handling functions */
-#define ITEM_PER_ROW 10
+#define ITEM_PER_ROW 10
/* Box handler function */
int
-jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream, unsigned long int filepoint,
- unsigned long int filelimit, int level,
- char *scansign, unsigned long int *scanpoint)
+jpeg2000_box_handler_function(jpeg2000boxtype boxtype, wxInputStream& stream,
+ unsigned long int filepoint,
+ unsigned long int filelimit, int level,
+ char *scansign, unsigned long int *scanpoint)
{
- switch (boxtype) {
+ switch (boxtype) {
- /* Sample Description box */
- case (STSD_BOX):
- jpeg2000_file_parse(stream, filepoint + 8, filelimit, level, scansign, scanpoint);
- break;
+ /* Sample Description box */
+ case (STSD_BOX):
+ jpeg2000_file_parse(stream, filepoint + 8, filelimit, level, scansign,
+ scanpoint);
+ break;
- /* MJP2 Sample Description box */
- case (MJP2_BOX):
- jpeg2000_file_parse(stream, filepoint + 78, filelimit, level, scansign, scanpoint);
- break;
-
- /* not yet implemented */
- default:
- break;
+ /* MJP2 Sample Description box */
+ case (MJP2_BOX):
+ jpeg2000_file_parse(stream, filepoint + 78, filelimit, level, scansign,
+ scanpoint);
+ break;
- };
+ /* not yet implemented */
+ default:
+ break;
- return (0);
+ };
+
+ return (0);
}
// the jP and ftyp parts of the header
-#define jpeg2000headSIZE 32
+#define jpeg2000headSIZE 32
unsigned char jpeg2000head[jpeg2000headSIZE] = {
- 0x00, 0x00, 0x00, 0x0C, 'j', 'P', ' ', ' ',
- 0x0D, 0x0A, 0x87, 0x0A, 0x00, 0x00, 0x00, 0x14,
- 'f', 't', 'y', 'p', 'j', 'p', '2', ' ',
- 0x00, 0x00, 0x00, 0x00, 'j', 'p', '2', ' '
+ 0x00, 0x00, 0x00, 0x0C, 'j', 'P', ' ', ' ',
+ 0x0D, 0x0A, 0x87, 0x0A, 0x00, 0x00, 0x00, 0x14,
+ 'f', 't', 'y', 'p', 'j', 'p', '2', ' ',
+ 0x00, 0x00, 0x00, 0x00, 'j', 'p', '2', ' '
};
/////////////////////////////////////////////////
/////////////////////////////////////////////////
// load the jpeg2000 file format
-bool wxJPEG2000Handler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, int index)
+bool wxJPEG2000Handler::LoadFile(wxImage *image, wxInputStream& stream,
+ bool verbose, int index)
{
- opj_dparameters_t parameters; /* decompression parameters */
- opj_event_mgr_t event_mgr; /* event manager */
- opj_image_t *opjimage = NULL;
- unsigned char *src = NULL;
+ opj_dparameters_t parameters; /* decompression parameters */
+ opj_event_mgr_t event_mgr; /* event manager */
+ opj_image_t *opjimage = NULL;
+ unsigned char *src = NULL;
unsigned char *ptr;
- int file_length, jp2c_point, jp2h_point;
- unsigned long int jp2hboxlen, jp2cboxlen;
- opj_codestream_info_t cstr_info; /* Codestream information structure */
+ int file_length, jp2c_point, jp2h_point;
+ unsigned long int jp2hboxlen, jp2cboxlen;
+ opj_codestream_info_t cstr_info; /* Codestream information structure */
unsigned char hdr[24];
- int jpfamform;
+ int jpfamform;
- // destroy the image
+ // destroy the image
image->Destroy();
- /* read the beginning of the file to check the type */
- if (!stream.Read(hdr, WXSIZEOF(hdr)))
+ /* read the beginning of the file to check the type */
+ if (!stream.Read(hdr, WXSIZEOF(hdr))) {
+ return false;
+ }
+ if ((jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr))) < 0) {
return false;
- if ((jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr))) < 0)
- return false;
- stream.SeekI(0, wxFromStart);
-
- /* handle to a decompressor */
- opj_dinfo_t* dinfo = NULL;
- opj_cio_t *cio = NULL;
-
- /* configure the event callbacks */
- memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
- event_mgr.error_handler = jpeg2000_error_callback;
- event_mgr.warning_handler = jpeg2000_warning_callback;
- event_mgr.info_handler = jpeg2000_info_callback;
-
- /* set decoding parameters to default values */
- opj_set_default_decoder_parameters(¶meters);
-
- /* prepare parameters */
- strncpy(parameters.infile, "", sizeof(parameters.infile) - 1);
- strncpy(parameters.outfile, "", sizeof(parameters.outfile) - 1);
- parameters.decod_format = jpfamform;
- parameters.cod_format = BMP_DFMT;
- if (m_reducefactor)
- parameters.cp_reduce = m_reducefactor;
- if (m_qualitylayers)
- parameters.cp_layer = m_qualitylayers;
- /*if (n_components)
- parameters. = n_components;*/
-
- /* JPWL only */
+ }
+ stream.SeekI(0, wxFromStart);
+
+ /* handle to a decompressor */
+ opj_dinfo_t* dinfo = NULL;
+ opj_cio_t *cio = NULL;
+
+ /* configure the event callbacks */
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+ event_mgr.error_handler = jpeg2000_error_callback;
+ event_mgr.warning_handler = jpeg2000_warning_callback;
+ event_mgr.info_handler = jpeg2000_info_callback;
+
+ /* set decoding parameters to default values */
+ opj_set_default_decoder_parameters(¶meters);
+
+ /* prepare parameters */
+ strncpy(parameters.infile, "", sizeof(parameters.infile) - 1);
+ strncpy(parameters.outfile, "", sizeof(parameters.outfile) - 1);
+ parameters.decod_format = jpfamform;
+ parameters.cod_format = BMP_DFMT;
+ if (m_reducefactor) {
+ parameters.cp_reduce = m_reducefactor;
+ }
+ if (m_qualitylayers) {
+ parameters.cp_layer = m_qualitylayers;
+ }
+ /*if (n_components)
+ parameters. = n_components;*/
+
+ /* JPWL only */
#ifdef USE_JPWL
- parameters.jpwl_exp_comps = m_expcomps;
- parameters.jpwl_max_tiles = m_maxtiles;
- parameters.jpwl_correct = m_enablejpwl;
+ parameters.jpwl_exp_comps = m_expcomps;
+ parameters.jpwl_max_tiles = m_maxtiles;
+ parameters.jpwl_correct = m_enablejpwl;
#endif /* USE_JPWL */
- /* get a decoder handle */
- if (jpfamform == JP2_CFMT || jpfamform == MJ2_CFMT)
- dinfo = opj_create_decompress(CODEC_JP2);
- else if (jpfamform == J2K_CFMT)
- dinfo = opj_create_decompress(CODEC_J2K);
- else
- return false;
-
- /* find length of the stream */
- stream.SeekI(0, wxFromEnd);
- file_length = (int) stream.TellI();
-
- /* it's a movie */
- if (jpfamform == MJ2_CFMT) {
- /* search for the first codestream box and the movie header box */
- jp2c_point = searchjpeg2000c(stream, file_length, m_framenum);
- jp2h_point = searchjpeg2000headerbox(stream, file_length);
-
- // read the jp2h box and store it
- stream.SeekI(jp2h_point, wxFromStart);
- stream.Read(&jp2hboxlen, sizeof(unsigned long int));
- jp2hboxlen = BYTE_SWAP4(jp2hboxlen);
-
- // read the jp2c box and store it
- stream.SeekI(jp2c_point, wxFromStart);
- stream.Read(&jp2cboxlen, sizeof(unsigned long int));
- jp2cboxlen = BYTE_SWAP4(jp2cboxlen);
-
- // malloc memory source
- src = (unsigned char *) malloc(jpeg2000headSIZE + jp2hboxlen + jp2cboxlen);
-
- // copy the jP and ftyp
- memcpy(src, jpeg2000head, jpeg2000headSIZE);
-
- // copy the jp2h
- stream.SeekI(jp2h_point, wxFromStart);
- stream.Read(&src[jpeg2000headSIZE], jp2hboxlen);
-
- // copy the jp2c
- stream.SeekI(jp2c_point, wxFromStart);
- stream.Read(&src[jpeg2000headSIZE + jp2hboxlen], jp2cboxlen);
- } else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT) {
- /* It's a plain image */
- /* get data */
- stream.SeekI(0, wxFromStart);
- src = (unsigned char *) malloc(file_length);
- stream.Read(src, file_length);
- } else
- return false;
-
- /* catch events using our callbacks and give a local context */
- opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
-
- /* setup the decoder decoding parameters using user parameters */
- opj_setup_decoder(dinfo, ¶meters);
-
- /* open a byte stream */
- if (jpfamform == MJ2_CFMT)
- cio = opj_cio_open((opj_common_ptr)dinfo, src, jpeg2000headSIZE + jp2hboxlen + jp2cboxlen);
- else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT)
- cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
- else {
- free(src);
- return false;
- }
-
- /* decode the stream and fill the image structure */
- opjimage = opj_decode_with_info(dinfo, cio, &cstr_info);
- if (!opjimage) {
- wxMutexGuiEnter();
- wxLogError(wxT("JPEG 2000 failed to decode image!"));
- wxMutexGuiLeave();
- opj_destroy_decompress(dinfo);
- opj_cio_close(cio);
- free(src);
- return false;
- }
-
- /* close the byte stream */
- opj_cio_close(cio);
-
- /*
-
- - At this point, we have the structure "opjimage" that is filled with decompressed
- data, as processed by the OpenJPEG decompression engine
-
- - We need to fill the class "image" with the proper pixel sample values
-
- */
- {
- int shiftbpp;
- int c, tempcomps;
-
- // check components number
- if (m_components > opjimage->numcomps)
- m_components = opjimage->numcomps;
-
- // check image depth (only on the first one, for now)
- if (m_components)
- shiftbpp = opjimage->comps[m_components - 1].prec - 8;
- else
- shiftbpp = opjimage->comps[0].prec - 8;
-
- // prepare image size
- if (m_components)
- image->Create(opjimage->comps[m_components - 1].w, opjimage->comps[m_components - 1].h, true);
- else
- image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true);
-
- // access image raw data
- image->SetMask(false);
- ptr = image->GetData();
-
- // workaround for components different from 1 or 3
- if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {
-#ifndef __WXGTK__
- wxMutexGuiEnter();
-#endif /* __WXGTK__ */
- wxLogMessage(wxT("JPEG2000: weird number of components"));
-#ifndef __WXGTK__
- wxMutexGuiLeave();
-#endif /* __WXGTK__ */
- tempcomps = 1;
- } else
- tempcomps = opjimage->numcomps;
-
- // workaround for subsampled components
- for (c = 1; c < tempcomps; c++) {
- if ((opjimage->comps[c].w != opjimage->comps[c - 1].w) || (opjimage->comps[c].h != opjimage->comps[c - 1].h)) {
- tempcomps = 1;
- break;
- }
- }
-
- // workaround for different precision components
- for (c = 1; c < tempcomps; c++) {
- if (opjimage->comps[c].bpp != opjimage->comps[c - 1].bpp) {
- tempcomps = 1;
- break;
- }
- }
-
- // only one component selected
- if (m_components)
- tempcomps = 1;
-
- // RGB color picture
- if (tempcomps == 3) {
- int row, col;
- int *r = opjimage->comps[0].data;
- int *g = opjimage->comps[1].data;
- int *b = opjimage->comps[2].data;
- if (shiftbpp > 0) {
- for (row = 0; row < opjimage->comps[0].h; row++) {
- for (col = 0; col < opjimage->comps[0].w; col++) {
-
- *(ptr++) = (*(r++)) >> shiftbpp;
- *(ptr++) = (*(g++)) >> shiftbpp;
- *(ptr++) = (*(b++)) >> shiftbpp;
-
- }
- }
-
- } else if (shiftbpp < 0) {
- for (row = 0; row < opjimage->comps[0].h; row++) {
- for (col = 0; col < opjimage->comps[0].w; col++) {
-
- *(ptr++) = (*(r++)) << -shiftbpp;
- *(ptr++) = (*(g++)) << -shiftbpp;
- *(ptr++) = (*(b++)) << -shiftbpp;
-
- }
- }
-
- } else {
- for (row = 0; row < opjimage->comps[0].h; row++) {
- for (col = 0; col < opjimage->comps[0].w; col++) {
-
- *(ptr++) = *(r++);
- *(ptr++) = *(g++);
- *(ptr++) = *(b++);
-
- }
- }
- }
- }
-
- // B/W picture
- if (tempcomps == 1) {
- int row, col;
- int selcomp;
-
- if (m_components)
- selcomp = m_components - 1;
- else
- selcomp = 0;
-
- int *y = opjimage->comps[selcomp].data;
- if (shiftbpp > 0) {
- for (row = 0; row < opjimage->comps[selcomp].h; row++) {
- for (col = 0; col < opjimage->comps[selcomp].w; col++) {
-
- *(ptr++) = (*(y)) >> shiftbpp;
- *(ptr++) = (*(y)) >> shiftbpp;
- *(ptr++) = (*(y++)) >> shiftbpp;
-
- }
- }
- } else if (shiftbpp < 0) {
- for (row = 0; row < opjimage->comps[selcomp].h; row++) {
- for (col = 0; col < opjimage->comps[selcomp].w; col++) {
-
- *(ptr++) = (*(y)) << -shiftbpp;
- *(ptr++) = (*(y)) << -shiftbpp;
- *(ptr++) = (*(y++)) << -shiftbpp;
-
- }
- }
- } else {
- for (row = 0; row < opjimage->comps[selcomp].h; row++) {
- for (col = 0; col < opjimage->comps[selcomp].w; col++) {
-
- *(ptr++) = *(y);
- *(ptr++) = *(y);
- *(ptr++) = *(y++);
-
- }
- }
- }
- }
-
-
- }
+ /* get a decoder handle */
+ if (jpfamform == JP2_CFMT || jpfamform == MJ2_CFMT) {
+ dinfo = opj_create_decompress(CODEC_JP2);
+ } else if (jpfamform == J2K_CFMT) {
+ dinfo = opj_create_decompress(CODEC_J2K);
+ } else {
+ return false;
+ }
+
+ /* find length of the stream */
+ stream.SeekI(0, wxFromEnd);
+ file_length = (int) stream.TellI();
+
+ /* it's a movie */
+ if (jpfamform == MJ2_CFMT) {
+ /* search for the first codestream box and the movie header box */
+ jp2c_point = searchjpeg2000c(stream, file_length, m_framenum);
+ jp2h_point = searchjpeg2000headerbox(stream, file_length);
+
+ // read the jp2h box and store it
+ stream.SeekI(jp2h_point, wxFromStart);
+ stream.Read(&jp2hboxlen, sizeof(unsigned long int));
+ jp2hboxlen = BYTE_SWAP4(jp2hboxlen);
+
+ // read the jp2c box and store it
+ stream.SeekI(jp2c_point, wxFromStart);
+ stream.Read(&jp2cboxlen, sizeof(unsigned long int));
+ jp2cboxlen = BYTE_SWAP4(jp2cboxlen);
+
+ // malloc memory source
+ src = (unsigned char *) malloc(jpeg2000headSIZE + jp2hboxlen + jp2cboxlen);
+
+ // copy the jP and ftyp
+ memcpy(src, jpeg2000head, jpeg2000headSIZE);
+
+ // copy the jp2h
+ stream.SeekI(jp2h_point, wxFromStart);
+ stream.Read(&src[jpeg2000headSIZE], jp2hboxlen);
+
+ // copy the jp2c
+ stream.SeekI(jp2c_point, wxFromStart);
+ stream.Read(&src[jpeg2000headSIZE + jp2hboxlen], jp2cboxlen);
+ } else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT) {
+ /* It's a plain image */
+ /* get data */
+ stream.SeekI(0, wxFromStart);
+ src = (unsigned char *) malloc(file_length);
+ stream.Read(src, file_length);
+ } else {
+ return false;
+ }
+
+ /* catch events using our callbacks and give a local context */
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
+
+ /* setup the decoder decoding parameters using user parameters */
+ opj_setup_decoder(dinfo, ¶meters);
+
+ /* open a byte stream */
+ if (jpfamform == MJ2_CFMT) {
+ cio = opj_cio_open((opj_common_ptr)dinfo, src,
+ jpeg2000headSIZE + jp2hboxlen + jp2cboxlen);
+ } else if (jpfamform == JP2_CFMT || jpfamform == J2K_CFMT) {
+ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
+ } else {
+ free(src);
+ return false;
+ }
+
+ /* decode the stream and fill the image structure */
+ opjimage = opj_decode_with_info(dinfo, cio, &cstr_info);
+ if (!opjimage) {
+ wxMutexGuiEnter();
+ wxLogError(wxT("JPEG 2000 failed to decode image!"));
+ wxMutexGuiLeave();
+ opj_destroy_decompress(dinfo);
+ opj_cio_close(cio);
+ free(src);
+ return false;
+ }
- wxMutexGuiEnter();
- wxLogMessage(wxT("JPEG 2000 image loaded."));
- wxMutexGuiLeave();
+ /* close the byte stream */
+ opj_cio_close(cio);
- /* close openjpeg structs */
- opj_destroy_decompress(dinfo);
- opj_image_destroy(opjimage);
- free(src);
+ /*
- if (!image->Ok())
- return false;
- else
- return true;
+ - At this point, we have the structure "opjimage" that is filled with decompressed
+ data, as processed by the OpenJPEG decompression engine
-}
+ - We need to fill the class "image" with the proper pixel sample values
-#define CINEMA_24_CS 1302083 /* Codestream length for 24fps */
-#define CINEMA_48_CS 651041 /* Codestream length for 48fps */
-#define COMP_24_CS 1041666 /* Maximum size per color component for 2K & 4K @ 24fps */
-#define COMP_48_CS 520833 /* Maximum size per color component for 2K @ 48fps */
+ */
+ {
+ int shiftbpp;
+ int c, tempcomps;
-// save the j2k codestream
-bool wxJPEG2000Handler::SaveFile( wxImage *wimage, wxOutputStream& stream, bool verbose )
-{
- opj_cparameters_t parameters; /* compression parameters */
- opj_event_mgr_t event_mgr; /* event manager */
- opj_image_t *oimage = NULL;
- opj_image_cmptparm_t *cmptparm;
- opj_cio_t *cio = NULL;
- opj_codestream_info_t cstr_info;
- int codestream_length;
- bool bSuccess;
- int i;
- char indexfilename[OPJ_PATH_LEN] = ""; /* index file name */
-
- /*
- configure the event callbacks (not required)
- setting of each callback is optionnal
- */
- memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
- event_mgr.error_handler = jpeg2000_error_callback;
- event_mgr.warning_handler = jpeg2000_warning_callback;
- event_mgr.info_handler = jpeg2000_info_callback;
-
- /* set encoding parameters to default values */
- opj_set_default_encoder_parameters(¶meters);
-
- /* load parameters */
- parameters.cp_cinema = OFF;
-
- /* subsampling */
- if (sscanf(m_subsampling.ToAscii(), "%d,%d", &(parameters.subsampling_dx), &(parameters.subsampling_dy)) != 2) {
- wxLogError(wxT("Wrong sub-sampling encoder setting: dx,dy"));
- return false;
+ // check components number
+ if (m_components > opjimage->numcomps) {
+ m_components = opjimage->numcomps;
}
- /* compression rates */
- if ((m_rates != wxT("")) && (!m_enablequality)) {
- const char *s1 = m_rates.ToAscii();
- wxLogMessage(wxT("rates %s"), s1);
- while (sscanf(s1, "%f", &(parameters.tcp_rates[parameters.tcp_numlayers])) == 1) {
- parameters.tcp_numlayers++;
- while (*s1 && *s1 != ',') {
- s1++;
- }
- if (!*s1)
- break;
- s1++;
- }
- wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers);
- parameters.cp_disto_alloc = 1;
+ // check image depth (only on the first one, for now)
+ if (m_components) {
+ shiftbpp = opjimage->comps[m_components - 1].prec - 8;
+ } else {
+ shiftbpp = opjimage->comps[0].prec - 8;
}
- /* image quality, dB */
- if ((m_quality != wxT("")) && (m_enablequality)) {
- const char *s2 = m_quality.ToAscii();
- wxLogMessage(wxT("qualities %s"), s2);
- while (sscanf(s2, "%f", ¶meters.tcp_distoratio[parameters.tcp_numlayers]) == 1) {
- parameters.tcp_numlayers++;
- while (*s2 && *s2 != ',') {
- s2++;
- }
- if (!*s2)
- break;
- s2++;
- }
- wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers);
- parameters.cp_fixed_quality = 1;
+ // prepare image size
+ if (m_components) {
+ image->Create(opjimage->comps[m_components - 1].w,
+ opjimage->comps[m_components - 1].h, true);
+ } else {
+ image->Create(opjimage->comps[0].w, opjimage->comps[0].h, true);
}
- /* image origin */
- if (sscanf(m_origin.ToAscii(), "%d,%d", ¶meters.image_offset_x0, ¶meters.image_offset_y0) != 2) {
- wxLogError(wxT("bad coordinate of the image origin: x0,y0"));
- return false;
- }
-
- /* Create comment for codestream */
- if(m_enablecomm) {
- parameters.cp_comment = (char *) malloc(strlen(m_comment.ToAscii()) + 1);
- if(parameters.cp_comment) {
- strcpy(parameters.cp_comment, m_comment.ToAscii());
- }
+ // access image raw data
+ image->SetMask(false);
+ ptr = image->GetData();
+
+ // workaround for components different from 1 or 3
+ if ((opjimage->numcomps != 1) && (opjimage->numcomps != 3)) {
+#ifndef __WXGTK__
+ wxMutexGuiEnter();
+#endif /* __WXGTK__ */
+ wxLogMessage(wxT("JPEG2000: weird number of components"));
+#ifndef __WXGTK__
+ wxMutexGuiLeave();
+#endif /* __WXGTK__ */
+ tempcomps = 1;
} else {
- parameters.cp_comment = NULL;
+ tempcomps = opjimage->numcomps;
}
- /* indexing file */
- if (m_enableidx) {
- strncpy(indexfilename, m_index.ToAscii(), OPJ_PATH_LEN);
- wxLogMessage(wxT("index file is %s"), indexfilename);
+ // workaround for subsampled components
+ for (c = 1; c < tempcomps; c++) {
+ if ((opjimage->comps[c].w != opjimage->comps[c - 1].w) ||
+ (opjimage->comps[c].h != opjimage->comps[c - 1].h)) {
+ tempcomps = 1;
+ break;
+ }
}
- /* if no rate entered, lossless by default */
- if (parameters.tcp_numlayers == 0) {
- parameters.tcp_rates[0] = 0; /* MOD antonin : losslessbug */
- parameters.tcp_numlayers++;
- parameters.cp_disto_alloc = 1;
+ // workaround for different precision components
+ for (c = 1; c < tempcomps; c++) {
+ if (opjimage->comps[c].bpp != opjimage->comps[c - 1].bpp) {
+ tempcomps = 1;
+ break;
+ }
}
- /* irreversible transform */
- parameters.irreversible = (m_irreversible == true) ? 1 : 0;
+ // only one component selected
+ if (m_components) {
+ tempcomps = 1;
+ }
- /* resolutions */
- parameters.numresolution = m_resolutions;
+ // RGB color picture
+ if (tempcomps == 3) {
+ int row, col;
+ int *r = opjimage->comps[0].data;
+ int *g = opjimage->comps[1].data;
+ int *b = opjimage->comps[2].data;
+ if (shiftbpp > 0) {
+ for (row = 0; row < opjimage->comps[0].h; row++) {
+ for (col = 0; col < opjimage->comps[0].w; col++) {
+
+ *(ptr++) = (*(r++)) >> shiftbpp;
+ *(ptr++) = (*(g++)) >> shiftbpp;
+ *(ptr++) = (*(b++)) >> shiftbpp;
+
+ }
+ }
- /* codeblocks size */
- if (m_cbsize != wxT("")) {
- int cblockw_init = 0, cblockh_init = 0;
- sscanf(m_cbsize.ToAscii(), "%d,%d", &cblockw_init, &cblockh_init);
- if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
- wxLogError(wxT("!! Size of code_block error !! Restrictions:\n width*height<=4096\n 4<=width,height<= 1024"));
- return false;
+ } else if (shiftbpp < 0) {
+ for (row = 0; row < opjimage->comps[0].h; row++) {
+ for (col = 0; col < opjimage->comps[0].w; col++) {
+
+ *(ptr++) = (*(r++)) << -shiftbpp;
+ *(ptr++) = (*(g++)) << -shiftbpp;
+ *(ptr++) = (*(b++)) << -shiftbpp;
+
+ }
}
- parameters.cblockw_init = cblockw_init;
- parameters.cblockh_init = cblockh_init;
- }
- /* precincts size */
- if (m_prsize != wxT("")) {
- char sep;
- int res_spec = 0;
- char *s = (char *) m_prsize.c_str();
- do {
- sep = 0;
- sscanf(s, "[%d,%d]%c", ¶meters.prcw_init[res_spec], ¶meters.prch_init[res_spec], &sep);
- parameters.csty |= 0x01;
- res_spec++;
- s = strpbrk(s, "]") + 2;
- } while (sep == ',');
- parameters.res_spec = res_spec;
- }
+ } else {
+ for (row = 0; row < opjimage->comps[0].h; row++) {
+ for (col = 0; col < opjimage->comps[0].w; col++) {
- /* tiles */
- if (m_tsize != wxT("")) {
- sscanf(m_tsize.ToAscii(), "%d,%d", ¶meters.cp_tdx, ¶meters.cp_tdy);
- parameters.tile_size_on = true;
- }
+ *(ptr++) = *(r++);
+ *(ptr++) = *(g++);
+ *(ptr++) = *(b++);
- /* tile origin */
- if (sscanf(m_torigin.ToAscii(), "%d,%d", ¶meters.cp_tx0, ¶meters.cp_ty0) != 2) {
- wxLogError(wxT("tile offset setting error: X0,Y0"));
- return false;
+ }
+ }
+ }
}
- /* use SOP */
- if (m_enablesop)
- parameters.csty |= 0x02;
+ // B/W picture
+ if (tempcomps == 1) {
+ int row, col;
+ int selcomp;
- /* use EPH */
- if (m_enableeph)
- parameters.csty |= 0x04;
+ if (m_components) {
+ selcomp = m_components - 1;
+ } else {
+ selcomp = 0;
+ }
- /* multiple component transform */
- if (m_multicomp)
- parameters.tcp_mct = 1;
- else
- parameters.tcp_mct = 0;
+ int *y = opjimage->comps[selcomp].data;
+ if (shiftbpp > 0) {
+ for (row = 0; row < opjimage->comps[selcomp].h; row++) {
+ for (col = 0; col < opjimage->comps[selcomp].w; col++) {
- /* mode switch */
- parameters.mode = (m_enablebypass ? 1 : 0) + (m_enablereset ? 2 : 0)
- + (m_enablerestart ? 4 : 0) + (m_enablevsc ? 8 : 0)
- + (m_enableerterm ? 16 : 0) + (m_enablesegmark ? 32 : 0);
+ *(ptr++) = (*(y)) >> shiftbpp;
+ *(ptr++) = (*(y)) >> shiftbpp;
+ *(ptr++) = (*(y++)) >> shiftbpp;
- /* progression order */
- switch (m_progression) {
+ }
+ }
+ } else if (shiftbpp < 0) {
+ for (row = 0; row < opjimage->comps[selcomp].h; row++) {
+ for (col = 0; col < opjimage->comps[selcomp].w; col++) {
- /* LRCP */
- case 0:
- parameters.prog_order = LRCP;
- break;
+ *(ptr++) = (*(y)) << -shiftbpp;
+ *(ptr++) = (*(y)) << -shiftbpp;
+ *(ptr++) = (*(y++)) << -shiftbpp;
- /* RLCP */
- case 1:
- parameters.prog_order = RLCP;
- break;
+ }
+ }
+ } else {
+ for (row = 0; row < opjimage->comps[selcomp].h; row++) {
+ for (col = 0; col < opjimage->comps[selcomp].w; col++) {
- /* RPCL */
- case 2:
- parameters.prog_order = RPCL;
- break;
+ *(ptr++) = *(y);
+ *(ptr++) = *(y);
+ *(ptr++) = *(y++);
- /* PCRL */
- case 3:
- parameters.prog_order = PCRL;
- break;
+ }
+ }
+ }
+ }
- /* CPRL */
- case 4:
- parameters.prog_order = CPRL;
- break;
- /* DCI2K24 */
- case 5:
- parameters.cp_cinema = CINEMA2K_24;
- parameters.cp_rsiz = CINEMA2K;
- break;
+ }
- /* DCI2K48 */
- case 6:
- parameters.cp_cinema = CINEMA2K_48;
- parameters.cp_rsiz = CINEMA2K;
- break;
+ wxMutexGuiEnter();
+ wxLogMessage(wxT("JPEG 2000 image loaded."));
+ wxMutexGuiLeave();
- /* DCI4K */
- case 7:
- parameters.cp_cinema = CINEMA4K_24;
- parameters.cp_rsiz = CINEMA4K;
- break;
+ /* close openjpeg structs */
+ opj_destroy_decompress(dinfo);
+ opj_image_destroy(opjimage);
+ free(src);
+
+ if (!image->Ok()) {
+ return false;
+ } else {
+ return true;
+ }
- default:
+}
+
+#define CINEMA_24_CS 1302083 /* Codestream length for 24fps */
+#define CINEMA_48_CS 651041 /* Codestream length for 48fps */
+#define COMP_24_CS 1041666 /* Maximum size per color component for 2K & 4K @ 24fps */
+#define COMP_48_CS 520833 /* Maximum size per color component for 2K @ 48fps */
+
+// save the j2k codestream
+bool wxJPEG2000Handler::SaveFile(wxImage *wimage, wxOutputStream& stream,
+ bool verbose)
+{
+ opj_cparameters_t parameters; /* compression parameters */
+ opj_event_mgr_t event_mgr; /* event manager */
+ opj_image_t *oimage = NULL;
+ opj_image_cmptparm_t *cmptparm;
+ opj_cio_t *cio = NULL;
+ opj_codestream_info_t cstr_info;
+ int codestream_length;
+ bool bSuccess;
+ int i;
+ char indexfilename[OPJ_PATH_LEN] = ""; /* index file name */
+
+ /*
+ configure the event callbacks (not required)
+ setting of each callback is optionnal
+ */
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+ event_mgr.error_handler = jpeg2000_error_callback;
+ event_mgr.warning_handler = jpeg2000_warning_callback;
+ event_mgr.info_handler = jpeg2000_info_callback;
+
+ /* set encoding parameters to default values */
+ opj_set_default_encoder_parameters(¶meters);
+
+ /* load parameters */
+ parameters.cp_cinema = OFF;
+
+ /* subsampling */
+ if (sscanf(m_subsampling.ToAscii(), "%d,%d", &(parameters.subsampling_dx),
+ &(parameters.subsampling_dy)) != 2) {
+ wxLogError(wxT("Wrong sub-sampling encoder setting: dx,dy"));
+ return false;
+ }
+
+ /* compression rates */
+ if ((m_rates != wxT("")) && (!m_enablequality)) {
+ const char *s1 = m_rates.ToAscii();
+ wxLogMessage(wxT("rates %s"), s1);
+ while (sscanf(s1, "%f", &(parameters.tcp_rates[parameters.tcp_numlayers])) ==
+ 1) {
+ parameters.tcp_numlayers++;
+ while (*s1 && *s1 != ',') {
+ s1++;
+ }
+ if (!*s1) {
break;
+ }
+ s1++;
}
-
- /* check cinema */
- if (parameters.cp_cinema) {
-
- /* set up */
- parameters.tile_size_on = false;
- parameters.cp_tdx=1;
- parameters.cp_tdy=1;
-
- /*Tile part*/
- parameters.tp_flag = 'C';
- parameters.tp_on = 1;
-
- /*Tile and Image shall be at (0,0)*/
- parameters.cp_tx0 = 0;
- parameters.cp_ty0 = 0;
- parameters.image_offset_x0 = 0;
- parameters.image_offset_y0 = 0;
-
- /*Codeblock size= 32*32*/
- parameters.cblockw_init = 32;
- parameters.cblockh_init = 32;
- parameters.csty |= 0x01;
-
- /*The progression order shall be CPRL*/
- parameters.prog_order = CPRL;
-
- /* No ROI */
- parameters.roi_compno = -1;
-
- parameters.subsampling_dx = 1;
- parameters.subsampling_dy = 1;
-
- /* 9-7 transform */
- parameters.irreversible = 1;
-
- }
-
- /* convert wx image into opj image */
- cmptparm = (opj_image_cmptparm_t*) malloc(3 * sizeof(opj_image_cmptparm_t));
-
- /* initialize opj image components */
- memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
- for(i = 0; i < 3; i++) {
- cmptparm[i].prec = 8;
- cmptparm[i].bpp = 8;
- cmptparm[i].sgnd = false;
- cmptparm[i].dx = parameters.subsampling_dx;
- cmptparm[i].dy = parameters.subsampling_dy;
- cmptparm[i].w = wimage->GetWidth();
- cmptparm[i].h = wimage->GetHeight();
+ wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers);
+ parameters.cp_disto_alloc = 1;
+ }
+
+ /* image quality, dB */
+ if ((m_quality != wxT("")) && (m_enablequality)) {
+ const char *s2 = m_quality.ToAscii();
+ wxLogMessage(wxT("qualities %s"), s2);
+ while (sscanf(s2, "%f", ¶meters.tcp_distoratio[parameters.tcp_numlayers]) ==
+ 1) {
+ parameters.tcp_numlayers++;
+ while (*s2 && *s2 != ',') {
+ s2++;
+ }
+ if (!*s2) {
+ break;
+ }
+ s2++;
}
+ wxLogMessage(wxT("%d layers"), parameters.tcp_numlayers);
+ parameters.cp_fixed_quality = 1;
+ }
+
+ /* image origin */
+ if (sscanf(m_origin.ToAscii(), "%d,%d", ¶meters.image_offset_x0,
+ ¶meters.image_offset_y0) != 2) {
+ wxLogError(wxT("bad coordinate of the image origin: x0,y0"));
+ return false;
+ }
- /* create the image */
- oimage = opj_image_create(3, &cmptparm[0], CLRSPC_SRGB);
- if(!oimage) {
- if (cmptparm)
- free(cmptparm);
- return false;
+ /* Create comment for codestream */
+ if (m_enablecomm) {
+ parameters.cp_comment = (char *) malloc(strlen(m_comment.ToAscii()) + 1);
+ if (parameters.cp_comment) {
+ strcpy(parameters.cp_comment, m_comment.ToAscii());
}
-
- /* set image offset and reference grid */
- oimage->x0 = parameters.image_offset_x0;
- oimage->y0 = parameters.image_offset_y0;
- oimage->x1 = parameters.image_offset_x0 + (wimage->GetWidth() - 1) * 1 + 1;
- oimage->y1 = parameters.image_offset_y0 + (wimage->GetHeight() - 1) * 1 + 1;
-
- /* load image data */
- unsigned char *value = wimage->GetData();
- int area = wimage->GetWidth() * wimage->GetHeight();
- for (i = 0; i < area; i++) {
- oimage->comps[0].data[i] = *(value++);
- oimage->comps[1].data[i] = *(value++);
- oimage->comps[2].data[i] = *(value++);
+ } else {
+ parameters.cp_comment = NULL;
+ }
+
+ /* indexing file */
+ if (m_enableidx) {
+ strncpy(indexfilename, m_index.ToAscii(), OPJ_PATH_LEN);
+ wxLogMessage(wxT("index file is %s"), indexfilename);
+ }
+
+ /* if no rate entered, lossless by default */
+ if (parameters.tcp_numlayers == 0) {
+ parameters.tcp_rates[0] = 0; /* MOD antonin : losslessbug */
+ parameters.tcp_numlayers++;
+ parameters.cp_disto_alloc = 1;
+ }
+
+ /* irreversible transform */
+ parameters.irreversible = (m_irreversible == true) ? 1 : 0;
+
+ /* resolutions */
+ parameters.numresolution = m_resolutions;
+
+ /* codeblocks size */
+ if (m_cbsize != wxT("")) {
+ int cblockw_init = 0, cblockh_init = 0;
+ sscanf(m_cbsize.ToAscii(), "%d,%d", &cblockw_init, &cblockh_init);
+ if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 ||
+ cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
+ wxLogError(
+ wxT("!! Size of code_block error !! Restrictions:\n width*height<=4096\n 4<=width,height<= 1024"));
+ return false;
+ }
+ parameters.cblockw_init = cblockw_init;
+ parameters.cblockh_init = cblockh_init;
+ }
+
+ /* precincts size */
+ if (m_prsize != wxT("")) {
+ char sep;
+ int res_spec = 0;
+ char *s = (char *) m_prsize.c_str();
+ do {
+ sep = 0;
+ sscanf(s, "[%d,%d]%c", ¶meters.prcw_init[res_spec],
+ ¶meters.prch_init[res_spec], &sep);
+ parameters.csty |= 0x01;
+ res_spec++;
+ s = strpbrk(s, "]") + 2;
+ } while (sep == ',');
+ parameters.res_spec = res_spec;
+ }
+
+ /* tiles */
+ if (m_tsize != wxT("")) {
+ sscanf(m_tsize.ToAscii(), "%d,%d", ¶meters.cp_tdx, ¶meters.cp_tdy);
+ parameters.tile_size_on = true;
+ }
+
+ /* tile origin */
+ if (sscanf(m_torigin.ToAscii(), "%d,%d", ¶meters.cp_tx0,
+ ¶meters.cp_ty0) != 2) {
+ wxLogError(wxT("tile offset setting error: X0,Y0"));
+ return false;
+ }
+
+ /* use SOP */
+ if (m_enablesop) {
+ parameters.csty |= 0x02;
+ }
+
+ /* use EPH */
+ if (m_enableeph) {
+ parameters.csty |= 0x04;
+ }
+
+ /* multiple component transform */
+ if (m_multicomp) {
+ parameters.tcp_mct = 1;
+ } else {
+ parameters.tcp_mct = 0;
+ }
+
+ /* mode switch */
+ parameters.mode = (m_enablebypass ? 1 : 0) + (m_enablereset ? 2 : 0)
+ + (m_enablerestart ? 4 : 0) + (m_enablevsc ? 8 : 0)
+ + (m_enableerterm ? 16 : 0) + (m_enablesegmark ? 32 : 0);
+
+ /* progression order */
+ switch (m_progression) {
+
+ /* LRCP */
+ case 0:
+ parameters.prog_order = LRCP;
+ break;
+
+ /* RLCP */
+ case 1:
+ parameters.prog_order = RLCP;
+ break;
+
+ /* RPCL */
+ case 2:
+ parameters.prog_order = RPCL;
+ break;
+
+ /* PCRL */
+ case 3:
+ parameters.prog_order = PCRL;
+ break;
+
+ /* CPRL */
+ case 4:
+ parameters.prog_order = CPRL;
+ break;
+
+ /* DCI2K24 */
+ case 5:
+ parameters.cp_cinema = CINEMA2K_24;
+ parameters.cp_rsiz = CINEMA2K;
+ break;
+
+ /* DCI2K48 */
+ case 6:
+ parameters.cp_cinema = CINEMA2K_48;
+ parameters.cp_rsiz = CINEMA2K;
+ break;
+
+ /* DCI4K */
+ case 7:
+ parameters.cp_cinema = CINEMA4K_24;
+ parameters.cp_rsiz = CINEMA4K;
+ break;
+
+ default:
+ break;
+ }
+
+ /* check cinema */
+ if (parameters.cp_cinema) {
+
+ /* set up */
+ parameters.tile_size_on = false;
+ parameters.cp_tdx = 1;
+ parameters.cp_tdy = 1;
+
+ /*Tile part*/
+ parameters.tp_flag = 'C';
+ parameters.tp_on = 1;
+
+ /*Tile and Image shall be at (0,0)*/
+ parameters.cp_tx0 = 0;
+ parameters.cp_ty0 = 0;
+ parameters.image_offset_x0 = 0;
+ parameters.image_offset_y0 = 0;
+
+ /*Codeblock size= 32*32*/
+ parameters.cblockw_init = 32;
+ parameters.cblockh_init = 32;
+ parameters.csty |= 0x01;
+
+ /*The progression order shall be CPRL*/
+ parameters.prog_order = CPRL;
+
+ /* No ROI */
+ parameters.roi_compno = -1;
+
+ parameters.subsampling_dx = 1;
+ parameters.subsampling_dy = 1;
+
+ /* 9-7 transform */
+ parameters.irreversible = 1;
+
+ }
+
+ /* convert wx image into opj image */
+ cmptparm = (opj_image_cmptparm_t*) malloc(3 * sizeof(opj_image_cmptparm_t));
+
+ /* initialize opj image components */
+ memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
+ for (i = 0; i < 3; i++) {
+ cmptparm[i].prec = 8;
+ cmptparm[i].bpp = 8;
+ cmptparm[i].sgnd = false;
+ cmptparm[i].dx = parameters.subsampling_dx;
+ cmptparm[i].dy = parameters.subsampling_dy;
+ cmptparm[i].w = wimage->GetWidth();
+ cmptparm[i].h = wimage->GetHeight();
+ }
+
+ /* create the image */
+ oimage = opj_image_create(3, &cmptparm[0], CLRSPC_SRGB);
+ if (!oimage) {
+ if (cmptparm) {
+ free(cmptparm);
+ }
+ return false;
+ }
+
+ /* set image offset and reference grid */
+ oimage->x0 = parameters.image_offset_x0;
+ oimage->y0 = parameters.image_offset_y0;
+ oimage->x1 = parameters.image_offset_x0 + (wimage->GetWidth() - 1) * 1 + 1;
+ oimage->y1 = parameters.image_offset_y0 + (wimage->GetHeight() - 1) * 1 + 1;
+
+ /* load image data */
+ unsigned char *value = wimage->GetData();
+ int area = wimage->GetWidth() * wimage->GetHeight();
+ for (i = 0; i < area; i++) {
+ oimage->comps[0].data[i] = *(value++);
+ oimage->comps[1].data[i] = *(value++);
+ oimage->comps[2].data[i] = *(value++);
+ }
+
+ /* check cinema again */
+ if (parameters.cp_cinema) {
+ int i;
+ float temp_rate;
+ opj_poc_t *POC = NULL;
+
+ switch (parameters.cp_cinema) {
+
+ case CINEMA2K_24:
+ case CINEMA2K_48:
+ if (parameters.numresolution > 6) {
+ parameters.numresolution = 6;
+ }
+ if (!((oimage->comps[0].w == 2048) | (oimage->comps[0].h == 1080))) {
+ wxLogWarning(
+ wxT("Image coordinates %d x %d is not 2K compliant. JPEG Digital Cinema Profile-3 "
+ "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080"),
+ oimage->comps[0].w, oimage->comps[0].h);
+ parameters.cp_rsiz = STD_RSIZ;
+ }
+ break;
+
+ case CINEMA4K_24:
+ if (parameters.numresolution < 1) {
+ parameters.numresolution = 1;
+ } else if (parameters.numresolution > 7) {
+ parameters.numresolution = 7;
+ }
+ if (!((oimage->comps[0].w == 4096) | (oimage->comps[0].h == 2160))) {
+ wxLogWarning(
+ wxT("Image coordinates %d x %d is not 4K compliant. JPEG Digital Cinema Profile-4"
+ "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160"),
+ oimage->comps[0].w, oimage->comps[0].h);
+ parameters.cp_rsiz = STD_RSIZ;
+ }
+ parameters.POC[0].tile = 1;
+ parameters.POC[0].resno0 = 0;
+ parameters.POC[0].compno0 = 0;
+ parameters.POC[0].layno1 = 1;
+ parameters.POC[0].resno1 = parameters.numresolution - 1;
+ parameters.POC[0].compno1 = 3;
+ parameters.POC[0].prg1 = CPRL;
+ parameters.POC[1].tile = 1;
+ parameters.POC[1].resno0 = parameters.numresolution - 1;
+ parameters.POC[1].compno0 = 0;
+ parameters.POC[1].layno1 = 1;
+ parameters.POC[1].resno1 = parameters.numresolution;
+ parameters.POC[1].compno1 = 3;
+ parameters.POC[1].prg1 = CPRL;
+ parameters.numpocs = 2;
+ break;
}
- /* check cinema again */
- if (parameters.cp_cinema) {
- int i;
- float temp_rate;
- opj_poc_t *POC = NULL;
-
- switch (parameters.cp_cinema) {
-
- case CINEMA2K_24:
- case CINEMA2K_48:
- if (parameters.numresolution > 6) {
- parameters.numresolution = 6;
- }
- if (!((oimage->comps[0].w == 2048) | (oimage->comps[0].h == 1080))) {
- wxLogWarning(wxT("Image coordinates %d x %d is not 2K compliant. JPEG Digital Cinema Profile-3 "
- "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080"),
- oimage->comps[0].w, oimage->comps[0].h);
- parameters.cp_rsiz = STD_RSIZ;
- }
- break;
-
- case CINEMA4K_24:
- if (parameters.numresolution < 1) {
- parameters.numresolution = 1;
- } else if (parameters.numresolution > 7) {
- parameters.numresolution = 7;
- }
- if (!((oimage->comps[0].w == 4096) | (oimage->comps[0].h == 2160))) {
- wxLogWarning(wxT("Image coordinates %d x %d is not 4K compliant. JPEG Digital Cinema Profile-4"
- "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160"),
- oimage->comps[0].w, oimage->comps[0].h);
- parameters.cp_rsiz = STD_RSIZ;
- }
- parameters.POC[0].tile = 1;
- parameters.POC[0].resno0 = 0;
- parameters.POC[0].compno0 = 0;
- parameters.POC[0].layno1 = 1;
- parameters.POC[0].resno1 = parameters.numresolution - 1;
- parameters.POC[0].compno1 = 3;
- parameters.POC[0].prg1 = CPRL;
- parameters.POC[1].tile = 1;
- parameters.POC[1].resno0 = parameters.numresolution - 1;
- parameters.POC[1].compno0 = 0;
- parameters.POC[1].layno1 = 1;
- parameters.POC[1].resno1 = parameters.numresolution;
- parameters.POC[1].compno1 = 3;
- parameters.POC[1].prg1 = CPRL;
- parameters.numpocs = 2;
- break;
+ switch (parameters.cp_cinema) {
+ case CINEMA2K_24:
+ case CINEMA4K_24:
+ for (i = 0 ; i < parameters.tcp_numlayers; i++) {
+ temp_rate = 0;
+ if (parameters.tcp_rates[i] == 0) {
+ parameters.tcp_rates[0] = ((float)(oimage->numcomps * oimage->comps[0].w *
+ oimage->comps[0].h * oimage->comps[0].prec)) /
+ (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
+ } else {
+ temp_rate = ((float)(oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h
+ * oimage->comps[0].prec)) /
+ (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
+ if (temp_rate > CINEMA_24_CS) {
+ parameters.tcp_rates[i] = ((float)(oimage->numcomps * oimage->comps[0].w *
+ oimage->comps[0].h * oimage->comps[0].prec)) /
+ (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
+ } else {
+ /* do nothing */
+ }
}
-
- switch (parameters.cp_cinema) {
- case CINEMA2K_24:
- case CINEMA4K_24:
- for (i = 0 ; i < parameters.tcp_numlayers; i++) {
- temp_rate = 0;
- if (parameters.tcp_rates[i] == 0) {
- parameters.tcp_rates[0] = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) /
- (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
- }else{
- temp_rate = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) /
- (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
- if (temp_rate > CINEMA_24_CS ) {
- parameters.tcp_rates[i]= ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) /
- (CINEMA_24_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
- } else {
- /* do nothing */
- }
- }
- }
- parameters.max_comp_size = COMP_24_CS;
- break;
-
- case CINEMA2K_48:
- for (i = 0; i < parameters.tcp_numlayers; i++) {
- temp_rate = 0 ;
- if (parameters.tcp_rates[i] == 0) {
- parameters.tcp_rates[0] = ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) /
- (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
- }else{
- temp_rate =((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) /
- (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
- if (temp_rate > CINEMA_48_CS ){
- parameters.tcp_rates[0]= ((float) (oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h * oimage->comps[0].prec)) /
- (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
- }else{
- /* do nothing */
- }
- }
- }
- parameters.max_comp_size = COMP_48_CS;
- break;
+ }
+ parameters.max_comp_size = COMP_24_CS;
+ break;
+
+ case CINEMA2K_48:
+ for (i = 0; i < parameters.tcp_numlayers; i++) {
+ temp_rate = 0 ;
+ if (parameters.tcp_rates[i] == 0) {
+ parameters.tcp_rates[0] = ((float)(oimage->numcomps * oimage->comps[0].w *
+ oimage->comps[0].h * oimage->comps[0].prec)) /
+ (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
+ } else {
+ temp_rate = ((float)(oimage->numcomps * oimage->comps[0].w * oimage->comps[0].h
+ * oimage->comps[0].prec)) /
+ (parameters.tcp_rates[i] * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
+ if (temp_rate > CINEMA_48_CS) {
+ parameters.tcp_rates[0] = ((float)(oimage->numcomps * oimage->comps[0].w *
+ oimage->comps[0].h * oimage->comps[0].prec)) /
+ (CINEMA_48_CS * 8 * oimage->comps[0].dx * oimage->comps[0].dy);
+ } else {
+ /* do nothing */
+ }
}
+ }
+ parameters.max_comp_size = COMP_48_CS;
+ break;
+ }
+
+ parameters.cp_disto_alloc = 1;
+ }
+
+ /* get a J2K compressor handle */
+ opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
+
+ /* catch events using our callbacks and give a local context */
+ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
+
+ /* setup the encoder parameters using the current image and user parameters */
+ opj_setup_encoder(cinfo, ¶meters, oimage);
+
+ /* open a byte stream for writing */
+ /* allocate memory for all tiles */
+ cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
+
+ /* encode the image */
+ bSuccess = opj_encode_with_info(cinfo, cio, oimage, &cstr_info);
+ if (!bSuccess) {
- parameters.cp_disto_alloc = 1;
+ opj_cio_close(cio);
+ opj_destroy_compress(cinfo);
+ opj_image_destroy(oimage);
+ if (cmptparm) {
+ free(cmptparm);
}
-
- /* get a J2K compressor handle */
- opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
-
- /* catch events using our callbacks and give a local context */
- opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
-
- /* setup the encoder parameters using the current image and user parameters */
- opj_setup_encoder(cinfo, ¶meters, oimage);
-
- /* open a byte stream for writing */
- /* allocate memory for all tiles */
- cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
-
- /* encode the image */
- bSuccess = opj_encode_with_info(cinfo, cio, oimage, &cstr_info);
- if (!bSuccess) {
-
- opj_cio_close(cio);
- opj_destroy_compress(cinfo);
- opj_image_destroy(oimage);
- if (cmptparm)
- free(cmptparm);
- if(parameters.cp_comment)
- free(parameters.cp_comment);
- if(parameters.cp_matrice)
- free(parameters.cp_matrice);
-
-#ifndef __WXGTK__
- wxMutexGuiEnter();
+ if (parameters.cp_comment) {
+ free(parameters.cp_comment);
+ }
+ if (parameters.cp_matrice) {
+ free(parameters.cp_matrice);
+ }
+
+#ifndef __WXGTK__
+ wxMutexGuiEnter();
#endif /* __WXGTK__ */
- wxLogError(wxT("failed to encode image"));
+ wxLogError(wxT("failed to encode image"));
-#ifndef __WXGTK__
- wxMutexGuiLeave();
+#ifndef __WXGTK__
+ wxMutexGuiLeave();
#endif /* __WXGTK__ */
- return false;
- }
- codestream_length = cio_tell(cio);
- wxLogMessage(wxT("Codestream: %d bytes"), codestream_length);
+ return false;
+ }
+ codestream_length = cio_tell(cio);
+ wxLogMessage(wxT("Codestream: %d bytes"), codestream_length);
- /* write the buffer to stream */
- stream.Write(cio->buffer, codestream_length);
+ /* write the buffer to stream */
+ stream.Write(cio->buffer, codestream_length);
- /* close and free the byte stream */
- opj_cio_close(cio);
+ /* close and free the byte stream */
+ opj_cio_close(cio);
- /* Write the index to disk */
- if (*indexfilename) {
- if (write_index_file(&cstr_info, indexfilename)) {
- wxLogError(wxT("Failed to output index file"));
- }
+ /* Write the index to disk */
+ if (*indexfilename) {
+ if (write_index_file(&cstr_info, indexfilename)) {
+ wxLogError(wxT("Failed to output index file"));
}
+ }
- /* free remaining compression structures */
- opj_destroy_compress(cinfo);
+ /* free remaining compression structures */
+ opj_destroy_compress(cinfo);
- /* free image data */
- opj_image_destroy(oimage);
+ /* free image data */
+ opj_image_destroy(oimage);
- if (cmptparm)
- free(cmptparm);
- if(parameters.cp_comment)
- free(parameters.cp_comment);
- if(parameters.cp_matrice)
- free(parameters.cp_matrice);
+ if (cmptparm) {
+ free(cmptparm);
+ }
+ if (parameters.cp_comment) {
+ free(parameters.cp_comment);
+ }
+ if (parameters.cp_matrice) {
+ free(parameters.cp_matrice);
+ }
-#ifndef __WXGTK__
+#ifndef __WXGTK__
wxMutexGuiEnter();
#endif /* __WXGTK__ */
wxLogMessage(wxT("J2K: Image encoded!"));
-#ifndef __WXGTK__
+#ifndef __WXGTK__
wxMutexGuiLeave();
#endif /* __WXGTK__ */
}
#ifdef __VISUALC__
- #pragma warning(default:4611)
+#pragma warning(default:4611)
#endif /* VC++ */
// recognize the JPEG 2000 family starting box or the 0xFF4F JPEG 2000 SOC marker
bool wxJPEG2000Handler::DoCanRead(wxInputStream& stream)
{
unsigned char hdr[24];
- int jpfamform;
+ int jpfamform;
- if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
+ if (!stream.Read(hdr, WXSIZEOF(hdr))) {
return false;
+ }
- jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr));
+ jpfamform = jpeg2000familytype(hdr, WXSIZEOF(hdr));
- return ((jpfamform == JP2_CFMT) || (jpfamform == MJ2_CFMT) || (jpfamform == J2K_CFMT));
+ return ((jpfamform == JP2_CFMT) || (jpfamform == MJ2_CFMT) ||
+ (jpfamform == J2K_CFMT));
}
#endif // wxUSE_STREAMS
#endif // wxUSE_LIBOPENJPEG
+
-/*\r
- * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium\r
- * Copyright (c) 2002-2014, Professor Benoit Macq\r
- * Copyright (c) 2001-2003, David Janssens\r
- * Copyright (c) 2002-2003, Yannick Verschueren\r
- * Copyright (c) 2003-2007, Francois-Olivier Devaux
- * Copyright (c) 2003-2014, Antonin Descampe\r
- * Copyright (c) 2005, Herve Drolon, FreeImage Team \r
- * Copyright (c) 2006-2007, Parvatha Elangovan\r
- * Copyright (c) 2007, Patrick Piscaglia (Telemis)\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <jni.h>\r
-#include <math.h>\r
-\r
-#include "openjpeg.h"\r
-#include "opj_includes.h"\r
-#include "opj_getopt.h"\r
-#include "convert.h"\r
-#include "index.h"\r
-#include "dirent.h"\r
-#include "org_openJpeg_OpenJPEGJavaEncoder.h"\r
-\r
-#ifndef _WIN32\r
-#define stricmp strcasecmp\r
-#define strnicmp strncasecmp\r
-#endif\r
-\r
-#include "format_defs.h"\r
-\r
-#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/\r
-#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/\r
-#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/\r
-#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/\r
-\r
-extern int get_file_format(char *filename);\r
-extern void error_callback(const char *msg, void *client_data);\r
-extern void warning_callback(const char *msg, void *client_data);\r
-extern void info_callback(const char *msg, void *client_data);\r
-\r
-typedef struct callback_variables {\r
- JNIEnv *env;\r
- /** 'jclass' object used to call a Java method from the C */\r
- jobject *jobj;\r
- /** 'jclass' object used to call a Java method from the C */\r
- jmethodID message_mid;\r
- jmethodID error_mid;\r
-} callback_variables_t;\r
-\r
-typedef struct dircnt{\r
- /** Buffer for holding images read from Directory*/\r
- char *filename_buf;\r
- /** Pointer to the buffer*/\r
- char **filename;\r
-}dircnt_t;\r
-\r
-typedef struct img_folder{\r
- /** The directory path of the folder containing input images*/\r
- char *imgdirpath;\r
- /** Output format*/\r
- char *out_format;\r
- /** Enable option*/\r
- char set_imgdir;\r
- /** Enable Cod Format for output*/\r
- char set_out_format;\r
- /** User specified rate stored in case of cinema option*/\r
- float *rates;\r
-}img_fol_t;\r
-\r
-static void encode_help_display() {\r
- fprintf(stdout,"HELP\n----\n\n");\r
- fprintf(stdout,"- the -h option displays this help information on screen\n\n");\r
-\r
-/* UniPG>> */\r
- fprintf(stdout,"List of parameters for the JPEG 2000 "\r
-#ifdef USE_JPWL\r
- "+ JPWL "\r
-#endif /* USE_JPWL */\r
- "encoder:\n");\r
-/* <<UniPG */\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"REMARKS:\n");\r
- fprintf(stdout,"---------\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");\r
- fprintf(stdout,"COD and QCD never appear in the tile_header.\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");\r
- fprintf(stdout,"color image. You need enough disk space memory (twice the original) to encode \n");\r
- fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"By default:\n");\r
- fprintf(stdout,"------------\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," * Lossless\n");\r
- fprintf(stdout," * 1 tile\n");\r
- fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");\r
- fprintf(stdout," * Size of code-block : 64 x 64\n");\r
- fprintf(stdout," * Number of resolutions: 6\n");\r
- fprintf(stdout," * No SOP marker in the codestream\n");\r
- fprintf(stdout," * No EPH marker in the codestream\n");\r
- fprintf(stdout," * No sub-sampling in x or y direction\n");\r
- fprintf(stdout," * No mode switch activated\n");\r
- fprintf(stdout," * Progression order: LRCP\n");\r
- fprintf(stdout," * No index file\n");\r
- fprintf(stdout," * No ROI upshifted\n");\r
- fprintf(stdout," * No offset of the origin of the image\n");\r
- fprintf(stdout," * No offset of the origin of the tiles\n");\r
- fprintf(stdout," * Reversible DWT 5-3\n");\r
-/* UniPG>> */\r
-#ifdef USE_JPWL\r
- fprintf(stdout," * No JPWL protection\n");\r
-#endif /* USE_JPWL */\r
-/* <<UniPG */\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"Parameters:\n");\r
- fprintf(stdout,"------------\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"Required Parameters (except with -h):\n");\r
- fprintf(stdout,"One of the two options -ImgDir or -i must be used\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-ImgDir : Image file Directory path (example ../Images) \n");\r
- fprintf(stdout," When using this option -OutFor must be used\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-OutFor \n");\r
- fprintf(stdout," REQUIRED only if -ImgDir is used\n");\r
- fprintf(stdout," Need to specify only format without filename <BMP> \n");\r
- fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");\r
- fprintf(stdout," When using this option -o must be used\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"Optional Parameters:\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-h : display the help information \n ");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");\r
- fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n"); \r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n");\r
- fprintf(stdout," Frames per second not required. Default value is 24fps\n"); \r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n ");\r
- fprintf(stdout," - The rate specified for each quality level is the desired \n");\r
- fprintf(stdout," compression factor.\n");\r
- fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n");\r
- fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," (options -r and -q cannot be used together)\n ");\r
- fprintf(stdout,"\n");\r
-\r
- fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n ");\r
-\r
- fprintf(stdout," (options -r and -q cannot be used together)\n ");\r
-\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-n : number of resolutions (-n 3) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-b : size of code block (-b 32,32) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-c : size of precinct (-c 128,128) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-t : size of tile (-t 512,512) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n");\r
- fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");\r
- fprintf(stdout," Example: T1=0,0,1,5,3,CPRL \n");\r
- fprintf(stdout," : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-SOP : write SOP marker before each packet \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-EPH : write EPH marker after each header packet \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");\r
- fprintf(stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");\r
- fprintf(stdout," Indicate multiple modes by adding their values. \n");\r
- fprintf(stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-TP : divide packets of every tile into tile-parts (-TP R) [R, L, C]\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n");\r
- fprintf(stdout," for component c=%%d [%%d = 0,1,2]\n");\r
- fprintf(stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"-jpip : write jpip codestream index box in JP2 output file\n");\r
- fprintf(stdout," NOTICE: currently supports only RPCL order\n");\r
- fprintf(stdout,"\n");\r
-/* UniPG>> */\r
-#ifdef USE_JPWL\r
- fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n");\r
- fprintf(stdout," The parameters can be written and repeated in any order:\n");\r
- fprintf(stdout," [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");\r
- fprintf(stdout," ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n");\r
- fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");\r
- fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n");\r
- fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");\r
- fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n");\r
- fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n");\r
- fprintf(stdout," to be applied to raw data: 'type' can be\n");\r
- fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");\r
- fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");\r
- fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n");\r
- fprintf(stdout," and that packet onwards, up to the next packet spec\n");\r
- fprintf(stdout," or to the last packet in the last tilepart in the stream\n");\r
- fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS);\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n");\r
- fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");\r
- fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");\r
- fprintf(stdout," if 'tilepart' is absent, it is for main header only\n");\r
- fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");\r
- fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n");\r
- fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," g determines the addressing mode: <range> can be\n");\r
- fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," a determines the size of data addressing: <addr> can be\n");\r
- fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," z determines the size of sensitivity values: <size> can be\n");\r
- fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," ex.:\n");\r
- fprintf(stdout," h,h0=64,h3=16,h5=32,p0=78,p0:24=56,p1,p3:0=0,p3:20=32,s=0,\n");\r
- fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n");\r
- fprintf(stdout," means\n");\r
- fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");\r
- fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");\r
- fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n");\r
- fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");\r
- fprintf(stdout," UEP rs default for packets of tilepart 1,\n");\r
- fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n");\r
- fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");\r
- fprintf(stdout," relative sensitivity ESD for MH,\n");\r
- fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");\r
- fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," ex.:\n");\r
- fprintf(stdout," h,s,p\n");\r
- fprintf(stdout," means\n");\r
- fprintf(stdout," default protection to headers (MH and TPHs) as well as\n");\r
- fprintf(stdout," data packets, one ESD in MH\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout," N.B.: use the following recommendations when specifying\n");\r
- fprintf(stdout," the JPWL parameters list\n");\r
- fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n");\r
- fprintf(stdout," \n");\r
-#endif /* USE_JPWL */\r
-/* <<UniPG */\r
- fprintf(stdout,"IMPORTANT:\n");\r
- fprintf(stdout,"-----------\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"The index file has the structure below:\n");\r
- fprintf(stdout,"---------------------------------------\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"Image_height Image_width\n");\r
- fprintf(stdout,"progression order\n");\r
- fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");\r
- fprintf(stdout,"Tiles_nb_X Tiles_nb_Y\n");\r
- fprintf(stdout,"Components_nb\n");\r
- fprintf(stdout,"Layers_nb\n");\r
- fprintf(stdout,"decomposition_levels\n");\r
- fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");\r
- fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");\r
- fprintf(stdout,"Main_header_start_position\n");\r
- fprintf(stdout,"Main_header_end_position\n");\r
- fprintf(stdout,"Codestream_size\n");\r
- fprintf(stdout,"\n");\r
- fprintf(stdout,"INFO ON TILES\n");\r
- fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");\r
- fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");\r
- fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n");\r
- fprintf(stdout,"...\n");\r
- fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n");\r
- fprintf(stdout,"...\n");\r
- fprintf(stdout,"TILE 0 DETAILS\n");\r
- fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n");\r
- fprintf(stdout,"...\n");\r
- fprintf(stdout,"Progression_string\n");\r
- fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");\r
- fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");\r
- fprintf(stdout,"...\n");\r
- fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n");\r
-\r
- fprintf(stdout,"MaxDisto\n");\r
-\r
- fprintf(stdout,"TotalDisto\n\n");\r
-}\r
-\r
-\r
-static OPJ_PROG_ORDER give_progression(const char progression[4]) {\r
- if(strncmp(progression, "LRCP", 4) == 0) {\r
- return LRCP;\r
- }\r
- if(strncmp(progression, "RLCP", 4) == 0) {\r
- return RLCP;\r
- }\r
- if(strncmp(progression, "RPCL", 4) == 0) {\r
- return RPCL;\r
- }\r
- if(strncmp(progression, "PCRL", 4) == 0) {\r
- return PCRL;\r
- }\r
- if(strncmp(progression, "CPRL", 4) == 0) {\r
- return CPRL;\r
- }\r
-\r
- return PROG_UNKNOWN;\r
-}\r
-\r
-static int initialise_4K_poc(opj_poc_t *POC, int numres){\r
- POC[0].tile = 1; \r
- POC[0].resno0 = 0; \r
- POC[0].compno0 = 0;\r
- POC[0].layno1 = 1;\r
- POC[0].resno1 = numres-1;\r
- POC[0].compno1 = 3;\r
- POC[0].prg1 = CPRL;\r
- POC[1].tile = 1;\r
- POC[1].resno0 = numres-1; \r
- POC[1].compno0 = 0;\r
- POC[1].layno1 = 1;\r
- POC[1].resno1 = numres;\r
- POC[1].compno1 = 3;\r
- POC[1].prg1 = CPRL;\r
- return 2;\r
-}\r
-\r
-static void cinema_parameters(opj_cparameters_t *parameters){\r
- parameters->tile_size_on = OPJ_FALSE;\r
- parameters->cp_tdx=1;\r
- parameters->cp_tdy=1;\r
- \r
- /*Tile part*/\r
- parameters->tp_flag = 'C';\r
- parameters->tp_on = 1;\r
-\r
- /*Tile and Image shall be at (0,0)*/\r
- parameters->cp_tx0 = 0;\r
- parameters->cp_ty0 = 0;\r
- parameters->image_offset_x0 = 0;\r
- parameters->image_offset_y0 = 0;\r
-\r
- /*Codeblock size= 32*32*/\r
- parameters->cblockw_init = 32; \r
- parameters->cblockh_init = 32;\r
- parameters->csty |= 0x01;\r
-\r
- /*The progression order shall be CPRL*/\r
- parameters->prog_order = CPRL;\r
-\r
- /* No ROI */\r
- parameters->roi_compno = -1;\r
-\r
- parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;\r
-\r
- /* 9-7 transform */\r
- parameters->irreversible = 1;\r
-\r
-}\r
-\r
-static void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){\r
- int i;\r
- float temp_rate;\r
- opj_poc_t *POC = NULL;\r
-\r
- switch (parameters->cp_cinema){\r
- case CINEMA2K_24:\r
- case CINEMA2K_48:\r
- if(parameters->numresolution > 6){\r
- parameters->numresolution = 6;\r
- }\r
- if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){\r
- fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"\r
- "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",\r
- image->comps[0].w,image->comps[0].h);\r
- parameters->cp_rsiz = STD_RSIZ;\r
- }\r
- break;\r
- \r
- case CINEMA4K_24:\r
- if(parameters->numresolution < 1){\r
- parameters->numresolution = 1;\r
- }else if(parameters->numresolution > 7){\r
- parameters->numresolution = 7;\r
- }\r
- if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){\r
- fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4" \r
- "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",\r
- image->comps[0].w,image->comps[0].h);\r
- parameters->cp_rsiz = STD_RSIZ;\r
- }\r
- parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);\r
- break;\r
- }\r
-\r
- switch (parameters->cp_cinema){\r
- case CINEMA2K_24:\r
- case CINEMA4K_24:\r
- for(i=0 ; i<parameters->tcp_numlayers ; i++){\r
- temp_rate = 0 ;\r
- if (img_fol->rates[i]== 0){\r
- parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
- (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
- }else{\r
- temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
- (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);\r
- if (temp_rate > CINEMA_24_CS ){\r
- parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
- (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
- }else{\r
- parameters->tcp_rates[i]= img_fol->rates[i];\r
- }\r
- }\r
- }\r
- parameters->max_comp_size = COMP_24_CS;\r
- break;\r
- \r
- case CINEMA2K_48:\r
- for(i=0 ; i<parameters->tcp_numlayers ; i++){\r
- temp_rate = 0 ;\r
- if (img_fol->rates[i]== 0){\r
- parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
- (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
- }else{\r
- temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
- (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);\r
- if (temp_rate > CINEMA_48_CS ){\r
- parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
- (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
- }else{\r
- parameters->tcp_rates[i]= img_fol->rates[i];\r
- }\r
- }\r
- }\r
- parameters->max_comp_size = COMP_48_CS;\r
- break;\r
- }\r
- parameters->cp_disto_alloc = 1;\r
-}\r
-\r
-\r
-/* ------------------------------------------------------------------------------------ */\r
-static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,\r
- img_fol_t *img_fol, char *indexfilename) {\r
- int i, j,totlen;\r
- opj_option_t long_option[]={\r
- {"cinema2K",REQ_ARG, NULL ,'w'},\r
- {"cinema4K",NO_ARG, NULL ,'y'},\r
- {"ImgDir",REQ_ARG, NULL ,'z'},\r
- {"TP",REQ_ARG, NULL ,'u'},\r
- {"SOP",NO_ARG, NULL ,'S'},\r
- {"EPH",NO_ARG, NULL ,'E'},\r
- {"OutFor",REQ_ARG, NULL ,'O'},\r
- {"POC",REQ_ARG, NULL ,'P'},\r
- {"ROI",REQ_ARG, NULL ,'R'},\r
- {"jpip",NO_ARG, NULL, 'J'}\r
- };\r
-\r
- /* parse the command line */\r
-/* UniPG>> */\r
- const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:"\r
-#ifdef USE_JPWL\r
- "W:"\r
-#endif /* USE_JPWL */\r
- ;\r
-\r
- /*printf("C: parse_cmdline_encoder:");\r
- for (i=0; i<argc; i++) {\r
- printf("[%s]",argv[i]);\r
- }\r
- printf("\n");*/\r
-\r
- totlen=sizeof(long_option);\r
- img_fol->set_out_format=0;\r
- reset_options_reading();\r
-\r
- while (1) {\r
- int c = opj_getopt_long(argc, argv, optlist,long_option,totlen);\r
- if (c == -1)\r
- break;\r
- switch (c) {\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'o': /* output file */\r
- {\r
- char *outfile = opj_optarg;\r
- parameters->cod_format = get_file_format(outfile);\r
- switch(parameters->cod_format) {\r
- case J2K_CFMT:\r
- case JP2_CFMT:\r
- break;\r
- default:\r
- fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);\r
- return 1;\r
- }\r
- strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
- case 'O': /* output format */\r
- {\r
- char outformat[50];\r
- char *of = opj_optarg;\r
- sprintf(outformat,".%s",of);\r
- img_fol->set_out_format = 1;\r
- parameters->cod_format = get_file_format(outformat);\r
- switch(parameters->cod_format) {\r
- case J2K_CFMT:\r
- case JP2_CFMT:\r
- img_fol->out_format = opj_optarg;\r
- break;\r
- default:\r
- fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");\r
- return 1;\r
- }\r
- }\r
- break;\r
-\r
-\r
- /* ----------------------------------------------------- */\r
-\r
-\r
- case 'r': /* rates rates/distorsion */\r
- {\r
- char *s = opj_optarg;\r
- while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) {\r
- parameters->tcp_numlayers++;\r
- while (*s && *s != ',') {\r
- s++;\r
- }\r
- if (!*s)\r
- break;\r
- s++;\r
- }\r
- parameters->cp_disto_alloc = 1;\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'q': /* add fixed_quality */\r
- {\r
- char *s = opj_optarg;\r
- while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {\r
- parameters->tcp_numlayers++;\r
- while (*s && *s != ',') {\r
- s++;\r
- }\r
- if (!*s)\r
- break;\r
- s++;\r
- }\r
- parameters->cp_fixed_quality = 1;\r
- }\r
- break;\r
-\r
- /* dda */\r
- /* ----------------------------------------------------- */\r
-\r
- case 'f': /* mod fixed_quality (before : -q) */\r
- {\r
- int *row = NULL, *col = NULL;\r
- int numlayers = 0, numresolution = 0, matrix_width = 0;\r
-\r
- char *s = opj_optarg;\r
- sscanf(s, "%d", &numlayers);\r
- s++;\r
- if (numlayers > 9)\r
- s++;\r
-\r
- parameters->tcp_numlayers = numlayers;\r
- numresolution = parameters->numresolution;\r
- matrix_width = numresolution * 3;\r
- parameters->cp_matrice = (int *) opj_malloc(numlayers * matrix_width * sizeof(int));\r
- s = s + 2;\r
-\r
- for (i = 0; i < numlayers; i++) {\r
- row = ¶meters->cp_matrice[i * matrix_width];\r
- col = row;\r
- parameters->tcp_rates[i] = 1;\r
- sscanf(s, "%d,", &col[0]);\r
- s += 2;\r
- if (col[0] > 9)\r
- s++;\r
- col[1] = 0;\r
- col[2] = 0;\r
- for (j = 1; j < numresolution; j++) {\r
- col += 3;\r
- sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);\r
- s += 6;\r
- if (col[0] > 9)\r
- s++;\r
- if (col[1] > 9)\r
- s++;\r
- if (col[2] > 9)\r
- s++;\r
- }\r
- if (i < numlayers - 1)\r
- s++;\r
- }\r
- parameters->cp_fixed_alloc = 1;\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 't': /* tiles */\r
- {\r
- sscanf(opj_optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);\r
- parameters->tile_size_on = OPJ_TRUE;\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'n': /* resolution */\r
- {\r
- sscanf(opj_optarg, "%d", ¶meters->numresolution);\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
- case 'c': /* precinct dimension */\r
- {\r
- char sep;\r
- int res_spec = 0;\r
-\r
- char *s = opj_optarg;\r
- do {\r
- sep = 0;\r
- sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],\r
- ¶meters->prch_init[res_spec], &sep);\r
- parameters->csty |= 0x01;\r
- res_spec++;\r
- s = strpbrk(s, "]") + 2;\r
- }\r
- while (sep == ',');\r
- parameters->res_spec = res_spec;\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'b': /* code-block dimension */\r
- {\r
- int cblockw_init = 0, cblockh_init = 0;\r
- sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);\r
- if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024\r
- || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {\r
- fprintf(stderr,\r
- "!! Size of code_block error (option -b) !!\n\nRestriction :\n"\r
- " * width*height<=4096\n * 4<=width,height<= 1024\n\n");\r
- return 1;\r
- }\r
- parameters->cblockw_init = cblockw_init;\r
- parameters->cblockh_init = cblockh_init;\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'x': /* creation of index file */\r
- {\r
- char *index = opj_optarg;\r
- strncpy(indexfilename, index, OPJ_PATH_LEN);\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'p': /* progression order */\r
- {\r
- char progression[4];\r
-\r
- strncpy(progression, opj_optarg, 4);\r
- parameters->prog_order = give_progression(progression);\r
- if (parameters->prog_order == -1) {\r
- fprintf(stderr, "Unrecognized progression order "\r
- "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");\r
- return 1;\r
- }\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 's': /* subsampling factor */\r
- {\r
- if (sscanf(opj_optarg, "%d,%d", ¶meters->subsampling_dx,\r
- ¶meters->subsampling_dy) != 2) {\r
- fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");\r
- return 1;\r
- }\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'd': /* coordonnate of the reference grid */\r
- {\r
- if (sscanf(opj_optarg, "%d,%d", ¶meters->image_offset_x0,\r
- ¶meters->image_offset_y0) != 2) {\r
- fprintf(stderr, "-d 'coordonnate of the reference grid' argument "\r
- "error !! [-d x0,y0]\n");\r
- return 1;\r
- }\r
- }\r
- break;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'h': /* display an help description */\r
- encode_help_display();\r
- return 1;\r
-\r
- /* ----------------------------------------------------- */\r
-\r
- case 'P': /* POC */\r
- {\r
- int numpocs = 0; /* number of progression order change (POC) default 0 */\r
- opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */\r
-\r
- char *s = opj_optarg;\r
- POC = parameters->POC;\r
-\r
- while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,\r
- &POC[numpocs].resno0, &POC[numpocs].compno0,\r
- &POC[numpocs].layno1, &POC[numpocs].resno1,\r
- &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {\r
- POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);\r
- numpocs++;\r
- while (*s && *s != '/') {\r
- s++;\r
- }\r
- if (!*s) {\r
- break;\r
- }\r
- s++;\r
- }\r
- parameters->numpocs = numpocs;\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
-\r
- case 'S': /* SOP marker */\r
- {\r
- parameters->csty |= 0x02;\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
-\r
- case 'E': /* EPH marker */\r
- {\r
- parameters->csty |= 0x04;\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
-\r
- case 'M': /* Mode switch pas tous au point !! */\r
- {\r
- int value = 0;\r
- if (sscanf(opj_optarg, "%d", &value) == 1) {\r
- for (i = 0; i <= 5; i++) {\r
- int cache = value & (1 << i);\r
- if (cache)\r
- parameters->mode |= (1 << i);\r
- }\r
- }\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
-\r
- case 'R': /* ROI */\r
- {\r
- if (sscanf(opj_optarg, "c=%d,U=%d", ¶meters->roi_compno,\r
- ¶meters->roi_shift) != 2) {\r
- fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");\r
- return 1;\r
- }\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
-\r
- case 'T': /* Tile offset */\r
- {\r
- if (sscanf(opj_optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) {\r
- fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");\r
- return 1;\r
- }\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
-\r
- case 'C': /* add a comment */\r
- {\r
- parameters->cp_comment = (char*)opj_malloc(strlen(opj_optarg) + 1);\r
- if(parameters->cp_comment) {\r
- strcpy(parameters->cp_comment, opj_optarg);\r
- }\r
- }\r
- break;\r
-\r
-\r
- /* ------------------------------------------------------ */\r
-\r
- case 'I': /* reversible or not */\r
- {\r
- parameters->irreversible = 1;\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
- \r
- case 'u': /* Tile part generation*/\r
- {\r
- parameters->tp_flag = opj_optarg[0];\r
- parameters->tp_on = 1;\r
- }\r
- break; \r
-\r
- /* ------------------------------------------------------ */\r
- \r
- case 'z': /* Image Directory path */\r
- {\r
- img_fol->imgdirpath = (char*)opj_malloc(strlen(opj_optarg) + 1);\r
- strcpy(img_fol->imgdirpath,opj_optarg);\r
- img_fol->set_imgdir=1;\r
- }\r
- break;\r
-\r
- /* ------------------------------------------------------ */\r
- \r
- case 'w': /* Digital Cinema 2K profile compliance*/\r
- {\r
- int fps=0;\r
- sscanf(opj_optarg,"%d",&fps);\r
- if(fps == 24){\r
- parameters->cp_cinema = CINEMA2K_24;\r
- }else if(fps == 48 ){\r
- parameters->cp_cinema = CINEMA2K_48;\r
- }else {\r
- fprintf(stderr,"Incorrect value!! must be 24 or 48\n");\r
- return 1;\r
- }\r
- fprintf(stdout,"CINEMA 2K compliant codestream\n");\r
- parameters->cp_rsiz = CINEMA2K;\r
- \r
- }\r
- break;\r
- \r
- /* ------------------------------------------------------ */\r
- \r
- case 'y': /* Digital Cinema 4K profile compliance*/\r
- {\r
- parameters->cp_cinema = CINEMA4K_24;\r
- fprintf(stdout,"CINEMA 4K compliant codestream\n");\r
- parameters->cp_rsiz = CINEMA4K;\r
- }\r
- break;\r
- \r
- /* ------------------------------------------------------ */\r
-\r
-/* UniPG>> */\r
-#ifdef USE_JPWL\r
- /* ------------------------------------------------------ */\r
- \r
- case 'W': /* JPWL capabilities switched on */\r
- {\r
- char *token = NULL;\r
- int hprot, pprot, sens, addr, size, range;\r
-\r
- /* we need to enable indexing */\r
- if (!indexfilename) {\r
- strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);\r
- }\r
-\r
- /* search for different protection methods */\r
-\r
- /* break the option in comma points and parse the result */\r
- token = strtok(opj_optarg, ",");\r
- while(token != NULL) {\r
-\r
- /* search header error protection method */\r
- if (*token == 'h') {\r
-\r
- static int tile = 0, tilespec = 0, lasttileno = 0;\r
-\r
- hprot = 1; /* predefined method */\r
-\r
- if(sscanf(token, "h=%d", &hprot) == 1) {\r
- /* Main header, specified */\r
- if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||\r
- ((hprot >= 37) && (hprot <= 128)))) {\r
- fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot);\r
- return 1;\r
- }\r
- parameters->jpwl_hprot_MH = hprot;\r
-\r
- } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) {\r
- /* Tile part header, specified */\r
- if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||\r
- ((hprot >= 37) && (hprot <= 128)))) {\r
- fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot);\r
- return 1;\r
- }\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);\r
- return 1;\r
- }\r
- if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
- parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;\r
- parameters->jpwl_hprot_TPH[tilespec++] = hprot;\r
- }\r
-\r
- } else if(sscanf(token, "h%d", &tile) == 1) {\r
- /* Tile part header, unspecified */\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);\r
- return 1;\r
- }\r
- if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
- parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;\r
- parameters->jpwl_hprot_TPH[tilespec++] = hprot;\r
- }\r
-\r
-\r
- } else if (!strcmp(token, "h")) {\r
- /* Main header, unspecified */\r
- parameters->jpwl_hprot_MH = hprot;\r
-\r
- } else {\r
- fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);\r
- return 1;\r
- };\r
-\r
- }\r
-\r
- /* search packet error protection method */\r
- if (*token == 'p') {\r
-\r
- static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;\r
-\r
- pprot = 1; /* predefined method */\r
-\r
- if (sscanf(token, "p=%d", &pprot) == 1) {\r
- /* Method for all tiles and all packets */\r
- if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
- ((pprot >= 37) && (pprot <= 128)))) {\r
- fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot);\r
- return 1;\r
- }\r
- parameters->jpwl_pprot_tileno[0] = 0;\r
- parameters->jpwl_pprot_packno[0] = 0;\r
- parameters->jpwl_pprot[0] = pprot;\r
-\r
- } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {\r
- /* method specified from that tile on */\r
- if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
- ((pprot >= 37) && (pprot <= 128)))) {\r
- fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);\r
- return 1;\r
- }\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
- return 1;\r
- }\r
- if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
- parameters->jpwl_pprot_tileno[packspec] = tile;\r
- parameters->jpwl_pprot_packno[packspec] = 0;\r
- parameters->jpwl_pprot[packspec++] = pprot;\r
- }\r
-\r
- } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {\r
- /* method fully specified from that tile and that packet on */\r
- if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
- ((pprot >= 37) && (pprot <= 128)))) {\r
- fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);\r
- return 1;\r
- }\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
- return 1;\r
- }\r
- if (pack < 0) {\r
- fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);\r
- return 1;\r
- }\r
- if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
- parameters->jpwl_pprot_tileno[packspec] = tile;\r
- parameters->jpwl_pprot_packno[packspec] = pack;\r
- parameters->jpwl_pprot[packspec++] = pprot;\r
- }\r
-\r
- } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {\r
- /* default method from that tile and that packet on */\r
- if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
- ((pprot >= 37) && (pprot <= 128)))) {\r
- fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);\r
- return 1;\r
- }\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
- return 1;\r
- }\r
- if (pack < 0) {\r
- fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);\r
- return 1;\r
- }\r
- if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
- parameters->jpwl_pprot_tileno[packspec] = tile;\r
- parameters->jpwl_pprot_packno[packspec] = pack;\r
- parameters->jpwl_pprot[packspec++] = pprot;\r
- }\r
-\r
- } else if (sscanf(token, "p%d", &tile) == 1) {\r
- /* default from a tile on */\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
- return 1;\r
- }\r
- if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
- parameters->jpwl_pprot_tileno[packspec] = tile;\r
- parameters->jpwl_pprot_packno[packspec] = 0;\r
- parameters->jpwl_pprot[packspec++] = pprot;\r
- }\r
-\r
-\r
- } else if (!strcmp(token, "p")) {\r
- /* all default */\r
- parameters->jpwl_pprot_tileno[0] = 0;\r
- parameters->jpwl_pprot_packno[0] = 0;\r
- parameters->jpwl_pprot[0] = pprot;\r
-\r
- } else {\r
- fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);\r
- return 1;\r
- };\r
-\r
- }\r
-\r
- /* search sensitivity method */\r
- if (*token == 's') {\r
-\r
- static int tile = 0, tilespec = 0, lasttileno = 0;\r
-\r
- sens = 0; /* predefined: relative error */\r
-\r
- if(sscanf(token, "s=%d", &sens) == 1) {\r
- /* Main header, specified */\r
- if ((sens < -1) || (sens > 7)) {\r
- fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens);\r
- return 1;\r
- }\r
- parameters->jpwl_sens_MH = sens;\r
-\r
- } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) {\r
- /* Tile part header, specified */\r
- if ((sens < -1) || (sens > 7)) {\r
- fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens);\r
- return 1;\r
- }\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);\r
- return 1;\r
- }\r
- if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
- parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;\r
- parameters->jpwl_sens_TPH[tilespec++] = sens;\r
- }\r
-\r
- } else if(sscanf(token, "s%d", &tile) == 1) {\r
- /* Tile part header, unspecified */\r
- if (tile < 0) {\r
- fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);\r
- return 1;\r
- }\r
- if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
- parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;\r
- parameters->jpwl_sens_TPH[tilespec++] = hprot;\r
- }\r
-\r
- } else if (!strcmp(token, "s")) {\r
- /* Main header, unspecified */\r
- parameters->jpwl_sens_MH = sens;\r
-\r
- } else {\r
- fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);\r
- return 1;\r
- };\r
- \r
- parameters->jpwl_sens_size = 2; /* 2 bytes for default size */\r
- }\r
-\r
- /* search addressing size */\r
- if (*token == 'a') {\r
-\r
- static int tile = 0, tilespec = 0, lasttileno = 0;\r
-\r
- addr = 0; /* predefined: auto */\r
-\r
- if(sscanf(token, "a=%d", &addr) == 1) {\r
- /* Specified */\r
- if ((addr != 0) && (addr != 2) && (addr != 4)) {\r
- fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);\r
- return 1;\r
- }\r
- parameters->jpwl_sens_addr = addr;\r
-\r
- } else if (!strcmp(token, "a")) {\r
- /* default */\r
- parameters->jpwl_sens_addr = addr; /* auto for default size */\r
-\r
- } else {\r
- fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);\r
- return 1;\r
- };\r
- \r
- }\r
-\r
- /* search sensitivity size */\r
- if (*token == 'z') {\r
-\r
- static int tile = 0, tilespec = 0, lasttileno = 0;\r
-\r
- size = 1; /* predefined: 1 byte */\r
-\r
- if(sscanf(token, "z=%d", &size) == 1) {\r
- /* Specified */\r
- if ((size != 0) && (size != 1) && (size != 2)) {\r
- fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);\r
- return 1;\r
- }\r
- parameters->jpwl_sens_size = size;\r
-\r
- } else if (!strcmp(token, "a")) {\r
- /* default */\r
- parameters->jpwl_sens_size = size; /* 1 for default size */\r
-\r
- } else {\r
- fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);\r
- return 1;\r
- };\r
- \r
- }\r
-\r
- /* search range method */\r
- if (*token == 'g') {\r
-\r
- static int tile = 0, tilespec = 0, lasttileno = 0;\r
-\r
- range = 0; /* predefined: 0 (packet) */\r
-\r
- if(sscanf(token, "g=%d", &range) == 1) {\r
- /* Specified */\r
- if ((range < 0) || (range > 3)) {\r
- fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);\r
- return 1;\r
- }\r
- parameters->jpwl_sens_range = range;\r
-\r
- } else if (!strcmp(token, "g")) {\r
- /* default */\r
- parameters->jpwl_sens_range = range;\r
-\r
- } else {\r
- fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);\r
- return 1;\r
- };\r
- \r
- }\r
-\r
- /* next token or bust */\r
- token = strtok(NULL, ",");\r
- };\r
-\r
-\r
- /* some info */\r
- fprintf(stdout, "Info: JPWL capabilities enabled\n");\r
- parameters->jpwl_epc_on = true;\r
-\r
- }\r
- break;\r
-#endif /* USE_JPWL */\r
-/* <<UniPG */\r
-/* ------------------------------------------------------ */\r
- \r
- break;\r
- /* ------------------------------------------------------ */\r
-\r
- default:\r
- fprintf(stderr, "ERROR -> Command line not valid\n");\r
- return 1;\r
- }\r
- }\r
-\r
- /* check for possible errors */\r
- if (parameters->cp_cinema){\r
- if(parameters->tcp_numlayers > 1){\r
- parameters->cp_rsiz = STD_RSIZ;\r
- fprintf(stdout,"Warning: DC profiles do not allow more than one quality layer. The codestream created will not be compliant with the DC profile\n");\r
- }\r
- }\r
-\r
- if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)\r
- && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {\r
- fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");\r
- return 1;\r
- } /* mod fixed_quality */\r
-\r
- /* if no rate entered, lossless by default */\r
- if (parameters->tcp_numlayers == 0) {\r
- parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */\r
- parameters->tcp_numlayers++;\r
- parameters->cp_disto_alloc = 1;\r
- }\r
-\r
- if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {\r
- fprintf(stderr,\r
- "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",\r
- parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);\r
- return 1;\r
- }\r
-\r
- for (i = 0; i < parameters->numpocs; i++) {\r
- if (parameters->POC[i].prg == -1) {\r
- fprintf(stderr,\r
- "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",\r
- i + 1);\r
- }\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-\r
-/** Create the same index as j2k_create_index does, but in an int[] instead of in a file ==> easy to pass it back to Java, to transfer it etc.\r
- @param buffer_size, increased by the length of the compressed index, in number of bytes\r
- @return a pointer to a char[]\r
- Syntax of the index:\r
- one char for the version number (1): one byte because no problem with little endian, big endian etc.\r
- one int for each of the following informations:\r
- Image Width \r
- Image Height \r
- progression order \r
- Tile width \r
- Tile height \r
- Nb tiles in X \r
- Nb tiles in Y \r
- Nb of components \r
- Nb of layers \r
- Nb of resolutions \r
-\r
- for each resolution: \r
- Precinct width\r
- Precinct height\r
-\r
- End main header position \r
- codestream size \r
-\r
- For each tile: \r
- tile number\r
- tile start pos in codestream\r
- tile header end position\r
- tile end position in codestream\r
-\r
- For each LRCP, RLCP etc.: \r
- packet number\r
- tile number\r
- layer number\r
- resolution number\r
- component number\r
- precinct number\r
- start position in the codestream\r
- end position of this packet\r
- */\r
-static char* create_index_into_byte_array(opj_codestream_info_t *cstr_info, int* buffer_size) {\r
- int tileno, compno, layno, resno, precno, pack_nb, x, y;\r
- char* buffer = NULL;\r
- int buffer_pos = 0;\r
- int prec_max = 0;\r
- \r
- prec_max = 0;\r
- for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
- for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {\r
- prec_max = int_max(prec_max,cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);\r
- }\r
- }\r
-\r
- /* Compute the size of the index buffer, in number of bytes*/\r
- *buffer_size = \r
- 1 /* version */\r
- + (10 /* image_w until decomposition */\r
- + (cstr_info->numdecompos[0]+1) * 2 /* pdx size for each tile */\r
- + 2 /* main_head_end + codestream_size */\r
- + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */\r
- + cstr_info->tw*cstr_info->th * cstr_info->numlayers * (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max *8\r
- ) * sizeof(int);\r
- /*printf("C: index buffer size = %d bytes\n", *buffer_size);*/\r
- buffer = (char*) opj_malloc(*buffer_size);\r
-\r
- if (!buffer) {\r
- /*opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);*/\r
- fprintf(stderr, "failed to allocate index buffer for writing %d int\n", *buffer_size);\r
- return 0;\r
- }\r
- \r
- buffer[0] = 1; /* Version stored on a byte*/\r
- buffer++;\r
- /* Remaining informations are stored on a int.*/\r
- ((int*)buffer)[buffer_pos++] = cstr_info->image_w;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->image_h;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->prog;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->tw;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->th;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];\r
- \r
- for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {\r
- /* based on tile 0 */\r
- ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);\r
- ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);\r
- }\r
- ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;\r
- \r
- for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
- ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;\r
- ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;\r
- }\r
- \r
- for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
- int start_pos, end_pos;\r
- int max_numdecompos = 0;\r
- pack_nb = 0;\r
- \r
- for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
- if (max_numdecompos < cstr_info->numdecompos[compno])\r
- max_numdecompos = cstr_info->numdecompos[compno];\r
- } \r
-\r
- if (cstr_info->prog == LRCP) { /* LRCP */\r
-\r
- for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
- for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
- for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
- int prec_max;\r
- if (resno > cstr_info->numdecompos[compno])\r
- break;\r
- prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
- for (precno = 0; precno < prec_max; precno++) {\r
- start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
- end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
- ((int*)buffer)[buffer_pos++] = pack_nb;\r
- ((int*)buffer)[buffer_pos++] = tileno;\r
- ((int*)buffer)[buffer_pos++] = layno;\r
- ((int*)buffer)[buffer_pos++] = resno;\r
- ((int*)buffer)[buffer_pos++] = compno;\r
- ((int*)buffer)[buffer_pos++] = precno;\r
- ((int*)buffer)[buffer_pos++] = start_pos;\r
- ((int*)buffer)[buffer_pos++] = end_pos;\r
- pack_nb++;\r
- }\r
- }\r
- }\r
- }\r
- } /* LRCP */\r
- else if (cstr_info->prog == RLCP) { /* RLCP */\r
-\r
- for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
- for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
- for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
- int prec_max; \r
- if (resno > cstr_info->numdecompos[compno])\r
- break;\r
- prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
- for (precno = 0; precno < prec_max; precno++) {\r
- start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
- end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
- ((int*)buffer)[buffer_pos++] = pack_nb;\r
- ((int*)buffer)[buffer_pos++] = tileno;\r
- ((int*)buffer)[buffer_pos++] = resno;\r
- ((int*)buffer)[buffer_pos++] = layno;\r
- ((int*)buffer)[buffer_pos++] = compno;\r
- ((int*)buffer)[buffer_pos++] = precno;\r
- ((int*)buffer)[buffer_pos++] = start_pos;\r
- ((int*)buffer)[buffer_pos++] = end_pos;\r
- pack_nb++;\r
- }\r
- }\r
- }\r
- }\r
- } /* RLCP */\r
- else if (cstr_info->prog == RPCL) { /* RPCL */\r
-\r
- for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
- /* I suppose components have same XRsiz, YRsiz */\r
- int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
- int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
- int x1 = x0 + cstr_info->tile_x;\r
- int y1 = y0 + cstr_info->tile_y;\r
- for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
- int prec_max; \r
- if (resno > cstr_info->numdecompos[compno])\r
- break;\r
- prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
- for (precno = 0; precno < prec_max; precno++) {\r
- int pcnx = cstr_info->tile[tileno].pw[resno];\r
- int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
- int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
- int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
- int precno_y = (int) floor( (float)precno/(float)pcnx );\r
- for(y = y0; y < y1; y++) { \r
- if (precno_y*pcy == y ) {\r
- for (x = x0; x < x1; x++) { \r
- if (precno_x*pcx == x ) {\r
- for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
- start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
- end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
- ((int*)buffer)[buffer_pos++] = pack_nb;\r
- ((int*)buffer)[buffer_pos++] = tileno;\r
- ((int*)buffer)[buffer_pos++] = resno;\r
- ((int*)buffer)[buffer_pos++] = precno;\r
- ((int*)buffer)[buffer_pos++] = compno;\r
- ((int*)buffer)[buffer_pos++] = layno;\r
- ((int*)buffer)[buffer_pos++] = start_pos;\r
- ((int*)buffer)[buffer_pos++] = end_pos;\r
- pack_nb++; \r
- }\r
- }\r
- }/* x = x0..x1 */\r
- } \r
- } /* y = y0..y1 */\r
- } /* precno */\r
- } /* compno */\r
- } /* resno */\r
- } /* RPCL */\r
- else if (cstr_info->prog == PCRL) { /* PCRL */\r
- /* I suppose components have same XRsiz, YRsiz */\r
- int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
- int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
- int x1 = x0 + cstr_info->tile_x;\r
- int y1 = y0 + cstr_info->tile_y;\r
-\r
- for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
- for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
- int prec_max; \r
- if (resno > cstr_info->numdecompos[compno])\r
- break;\r
- prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
- for (precno = 0; precno < prec_max; precno++) {\r
- int pcnx = cstr_info->tile[tileno].pw[resno];\r
- int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
- int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
- int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
- int precno_y = (int) floor( (float)precno/(float)pcnx );\r
- for(y = y0; y < y1; y++) { \r
- if (precno_y*pcy == y ) {\r
- for (x = x0; x < x1; x++) { \r
- if (precno_x*pcx == x ) {\r
- for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
- start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
- end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
- ((int*)buffer)[buffer_pos++] = pack_nb;\r
- ((int*)buffer)[buffer_pos++] = tileno;\r
- ((int*)buffer)[buffer_pos++] = precno;\r
- ((int*)buffer)[buffer_pos++] = compno;\r
- ((int*)buffer)[buffer_pos++] = resno;\r
- ((int*)buffer)[buffer_pos++] = layno;\r
- ((int*)buffer)[buffer_pos++] = start_pos;\r
- ((int*)buffer)[buffer_pos++] = end_pos;\r
- pack_nb++; \r
- }\r
- }\r
- }/* x = x0..x1 */\r
- } \r
- } /* y = y0..y1 */\r
- } /* precno */\r
- } /* resno */\r
- } /* compno */\r
- } /* PCRL */\r
- else { /* CPRL */\r
-\r
- for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
- /* I suppose components have same XRsiz, YRsiz */\r
- int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
- int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
- int x1 = x0 + cstr_info->tile_x;\r
- int y1 = y0 + cstr_info->tile_y;\r
- \r
- for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
- int prec_max; \r
- if (resno > cstr_info->numdecompos[compno])\r
- break;\r
- prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
- for (precno = 0; precno < prec_max; precno++) {\r
- int pcnx = cstr_info->tile[tileno].pw[resno];\r
- int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
- int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
- int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
- int precno_y = (int) floor( (float)precno/(float)pcnx );\r
- for(y = y0; y < y1; y++) {\r
- if (precno_y*pcy == y ) {\r
- for (x = x0; x < x1; x++) {\r
- if (precno_x*pcx == x ) {\r
- for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
- start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
- end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
- ((int*)buffer)[buffer_pos++] = pack_nb;\r
- ((int*)buffer)[buffer_pos++] = tileno;\r
- ((int*)buffer)[buffer_pos++] = compno;\r
- ((int*)buffer)[buffer_pos++] = precno;\r
- ((int*)buffer)[buffer_pos++] = resno;\r
- ((int*)buffer)[buffer_pos++] = layno;\r
- ((int*)buffer)[buffer_pos++] = start_pos;\r
- ((int*)buffer)[buffer_pos++] = end_pos;\r
- pack_nb++; \r
- }\r
- }\r
- }/* x = x0..x1 */\r
- }\r
- } /* y = y0..y1 */\r
- } /* precno */\r
- } /* resno */\r
- } /* compno */\r
- } /* CPRL */ \r
- } /* tileno */\r
-\r
- if (buffer_pos > *buffer_size) {\r
- /*opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);*/\r
- fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);\r
- return 0;\r
- }\r
-\r
- return --buffer;\r
-}\r
-\r
-\r
-\r
-\r
-/* -------------------------------------------------------------------------- \r
- ------------ Get the image byte[] from the Java object -------------------*/\r
-\r
-static opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj, jclass cls) {\r
- int i,max,shift,w,h,depth;\r
- opj_image_t * img = NULL;\r
- int compno, numcomps;\r
- opj_image_t * image = NULL;\r
- opj_image_comp_t *comp;\r
- opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */\r
- OPJ_COLOR_SPACE color_space;\r
- jfieldID fid;\r
- jint ji;\r
- jbyteArray jba;\r
- jshortArray jsa;\r
- jintArray jia;\r
- int len;\r
- jbyte *jbBody;\r
- jshort *jsBody;\r
- jint *jiBody;\r
- jboolean isCopy;\r
-\r
- /* Image width, height and depth*/\r
- fid = (*env)->GetFieldID(env, cls,"width", "I");\r
- ji = (*env)->GetIntField(env, obj, fid);\r
- w = ji;\r
-\r
- fid = (*env)->GetFieldID(env, cls,"height", "I");\r
- ji = (*env)->GetIntField(env, obj, fid);\r
- h = ji;\r
- \r
- fid = (*env)->GetFieldID(env, cls,"depth", "I");\r
- ji = (*env)->GetIntField(env, obj, fid);\r
- depth = ji;\r
-\r
- /* Read the image*/\r
- if (depth <=16) {\r
- numcomps = 1;\r
- color_space = CLRSPC_GRAY;\r
- } else {\r
- numcomps = 3;\r
- color_space = CLRSPC_SRGB;\r
- }\r
- memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));\r
-\r
- if (numcomps == 1) {\r
- cmptparm[0].x0 = parameters->image_offset_x0;\r
- cmptparm[0].y0 = parameters->image_offset_y0;\r
- cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;\r
- cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;\r
- /* Java types are always signed but we use them as unsigned types (shift of the negative part of \r
- the pixels of the images in Telemis before entering the encoder).*/\r
- cmptparm[0].sgnd = 0;\r
- if (depth<=16) \r
- cmptparm[0].prec=depth;\r
- else \r
- cmptparm[0].prec = 8;\r
- cmptparm[0].bpp = cmptparm[0].prec;\r
- cmptparm[0].dx = parameters->subsampling_dx;\r
- cmptparm[0].dy = parameters->subsampling_dy;\r
- /*printf("C: component 0 initialised: x0=%d, y0=%d, w=%d, h=%d, sgnd=%d, bpp=%d, dx=%d, dy=%d, color_space=%d\n", cmptparm[0].x0, cmptparm[0].y0, cmptparm[0].w,\r
- cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/\r
- } else {\r
- for(i = 0; i < numcomps; i++) {\r
- cmptparm[i].prec = 8;\r
- cmptparm[i].bpp = 8;\r
- cmptparm[i].sgnd = 0;\r
- cmptparm[i].dx = parameters->subsampling_dx;\r
- cmptparm[i].dy = parameters->subsampling_dy;\r
- cmptparm[i].w = w;\r
- cmptparm[i].h = h;\r
- }\r
- }\r
- \r
- /* create the image */\r
- image = opj_image_create(numcomps, &cmptparm[0], color_space);\r
-\r
- if (!image)\r
- return NULL;\r
-\r
- if (depth <=16) {\r
- image->numcomps=1;\r
- } else {\r
- image->numcomps = 3;\r
- }\r
-\r
- /* set image offset and reference grid */\r
- image->x0 = cmptparm[0].x0;\r
- image->y0 = cmptparm[0].x0;\r
- image->x1 = cmptparm[0].w;\r
- image->y1 = cmptparm[0].h;\r
-\r
- /* set image data */\r
- for (compno=0; compno<numcomps; compno++) {\r
- comp = &image->comps[compno];\r
- max = -100000;\r
- if (depth == 8) {\r
- fid = (*env)->GetFieldID(env, cls,"image8", "[B"); /* byteArray []*/\r
- jba = (*env)->GetObjectField(env, obj, fid);\r
- len = (*env)->GetArrayLength(env, jba);\r
- \r
- jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);\r
- /*printf("C: before transferring 8 bpp image\n");*/\r
- if (comp->sgnd) {\r
- for(i=0; i< len;i++) {\r
- comp->data[i] = (char) jbBody[i];\r
- if (comp->data[i] > max) max = comp->data[i];\r
- }\r
- } else {\r
- for(i=0; i< len;i++) {\r
- comp->data[i] = (unsigned char) jbBody[i];\r
- if (comp->data[i] > max) max = comp->data[i];\r
- }\r
- }\r
- (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);\r
- } else if(depth == 16) {\r
- fid = (*env)->GetFieldID(env, cls,"image16", "[S"); /* shortArray []*/\r
- jsa = (*env)->GetObjectField(env, obj, fid);\r
- len = (*env)->GetArrayLength(env, jsa);\r
- \r
- jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);\r
- /*printf("C: before transferring 16 bpp image\n");*/\r
- if (comp->sgnd) { /* Special behaviour to deal with signed elements ??*/\r
- comp->data[i] = (short) jsBody[i];\r
- for(i=0; i< len;i++) {\r
- if (comp->data[i] > max) max = comp->data[i];\r
- }\r
- } else {\r
- for(i=0; i< len;i++) {\r
- comp->data[i] = (unsigned short) jsBody[i];\r
- if (comp->data[i] > max) max = comp->data[i];\r
- }\r
- }\r
- (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);\r
- } else if (depth == 24) {\r
- fid = (*env)->GetFieldID(env, cls,"image24", "[I"); /* intArray []*/\r
- jia = (*env)->GetObjectField(env, obj, fid);\r
- len = (*env)->GetArrayLength(env, jia);\r
- shift = compno*8;\r
-\r
- jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);\r
- /*printf("C: before transferring 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);*/\r
- if (comp->sgnd) { /* Special behaviour to deal with signed elements ?? XXXXX*/\r
- for(i=0; i< len;i++) {\r
- comp->data[i] = ( ((int) jiBody[i]) & (0xFF << shift) ) >> shift;\r
- if (comp->data[i] > max) max = comp->data[i];\r
- }\r
- } else {\r
- for(i=0; i< len;i++) {\r
- comp->data[i] = ( ((unsigned int) jiBody[i]) & (0xFF << shift) ) >> shift;\r
- if (comp->data[i] > max) max = comp->data[i];\r
- }\r
- }\r
- (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);\r
- }\r
- comp->bpp = int_floorlog2(max)+1;\r
- comp->prec = comp->bpp;\r
- /*printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);*/\r
- }\r
- return image;\r
-}\r
-\r
-\r
-/* --------------------------------------------------------------------------\r
- -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/\r
-JNIEXPORT jlong JNICALL Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env, jobject obj, jobjectArray javaParameters) {\r
- int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */\r
- char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */\r
- opj_bool bSuccess;\r
- opj_cparameters_t parameters; /* compression parameters */\r
- img_fol_t img_fol;\r
- opj_event_mgr_t event_mgr; /* event manager */\r
- opj_image_t *image = NULL;\r
- int i,j,num_images;\r
- int imageno;\r
- opj_codestream_info_t cstr_info; /* Codestream information structure */\r
- char indexfilename[OPJ_PATH_LEN]; /* index file name */\r
-\r
- char* compressed_index = NULL;\r
- int compressed_index_size=-1;\r
- /* ==> Access variables to the Java member variables*/\r
- jsize arraySize;\r
- jclass cls;\r
- jobject object;\r
- jboolean isCopy;\r
- jfieldID fid;\r
- jbyteArray jba;\r
- jbyte *jbBody;\r
- callback_variables_t msgErrorCallback_vars;\r
- /* <== access variable to the Java member variables.*/\r
-\r
- /* For the encoding and storage into the file*/\r
- opj_cinfo_t* cinfo;\r
- int codestream_length;\r
- opj_cio_t *cio = NULL;\r
- FILE *f = NULL;\r
-\r
- /* JNI reference to the calling class*/\r
- cls = (*env)->GetObjectClass(env, obj);\r
- \r
- /* Pointers to be able to call a Java method for all the info and error messages*/\r
- msgErrorCallback_vars.env = env;\r
- msgErrorCallback_vars.jobj = &obj;\r
- msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");\r
- msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");\r
-\r
- arraySize = (*env)->GetArrayLength(env, javaParameters);\r
- argc = (int) arraySize +1;\r
- argv = opj_malloc(argc*sizeof(char*));\r
- argv[0] = "ProgramName.exe"; /* The program name: useless*/\r
- j=0;\r
- for (i=1; i<argc; i++) {\r
- object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);\r
- argv[i] = (char*)(*env)->GetStringUTFChars(env, object, &isCopy);\r
- }\r
-\r
- /*printf("C: ");\r
- for (i=0; i<argc; i++) {\r
- printf("[%s]",argv[i]);\r
- }\r
- printf("\n");*/\r
-\r
- /*\r
- configure the event callbacks\r
- */\r
- memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
- event_mgr.error_handler = error_callback;\r
- event_mgr.warning_handler = warning_callback;\r
- event_mgr.info_handler = info_callback;\r
-\r
- /* set encoding parameters to default values */\r
- opj_set_default_encoder_parameters(¶meters);\r
- parameters.cod_format = J2K_CFMT;\r
- /*parameters.index_on = 1;*/\r
-\r
- /* Initialize indexfilename and img_fol */\r
- *indexfilename = 0;\r
- memset(&img_fol,0,sizeof(img_fol_t));\r
-\r
- /* parse input and get user encoding parameters */\r
- if (parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {\r
- /* Release the Java arguments array*/\r
- for (i=1; i<argc; i++)\r
- (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);\r
- return -1;\r
- }\r
-\r
- /* Release the Java arguments array*/\r
- for (i=1; i<argc; i++)\r
- (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);\r
-\r
- if (parameters.cp_cinema){\r
- cinema_parameters(¶meters);\r
- }\r
- \r
-\r
- /* Create comment for codestream */\r
- if(parameters.cp_comment == NULL) {\r
- const char comment[] = "Created by JavaOpenJPEG version ";\r
- const size_t clen = strlen(comment);\r
- const char *version = opj_version();\r
-/* UniPG>> */\r
-#ifdef USE_JPWL\r
- parameters.cp_comment = (char*)opj_malloc(clen+strlen(version)+11);\r
- sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version);\r
-#else\r
- parameters.cp_comment = (char*)opj_malloc(clen+strlen(version)+1);\r
- sprintf(parameters.cp_comment,"%s%s", comment, version);\r
-#endif\r
-/* <<UniPG */\r
-\r
- }\r
-\r
- /* Read directory if necessary */\r
- num_images=1;\r
-\r
- /*Encoding image one by one*/\r
- for(imageno=0;imageno<num_images;imageno++)\r
- {\r
- image = NULL;\r
- fprintf(stderr,"\n");\r
-\r
- image = loadImage(¶meters, env, obj, cls);\r
- /*printf("C: after load image: image = %d\n", image);*/\r
- if (!image) {\r
- fprintf(stderr, "Unable to load image\n");\r
- return -1; \r
- }\r
-\r
- /* Decide if MCT should be used */\r
- parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;\r
-\r
- if(parameters.cp_cinema){\r
- cinema_setup_encoder(¶meters,image,&img_fol);\r
- }\r
-\r
- /* encode the destination image */\r
- /* ---------------------------- */\r
- /* get a J2K compressor handle */\r
- if (parameters.cod_format == J2K_CFMT) { /* J2K format output */\r
- cinfo = opj_create_compress(CODEC_J2K);\r
- } else { /* JP2 format output */\r
- cinfo = opj_create_compress(CODEC_JP2);\r
- }\r
- /* catch events using our callbacks and give a local context */\r
- opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);\r
-\r
- /* setup the encoder parameters using the current image and user parameters */\r
- opj_setup_encoder(cinfo, ¶meters, image);\r
-\r
- /* open a byte stream for writing */\r
- /* allocate memory for all tiles */\r
- cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);\r
-\r
- /* encode the image */\r
- bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);\r
- printf("C: after opj_encode_with_info\n");\r
- if (!bSuccess) {\r
- opj_cio_close(cio);\r
- fprintf(stderr, "failed to encode image\n");\r
- return -1;\r
- }\r
- codestream_length = cio_tell(cio);\r
-\r
- /* write the index on disk, if needed (-x 'filename') */\r
- if (*indexfilename) {\r
- bSuccess = write_index_file(&cstr_info, indexfilename);\r
- if (bSuccess) {\r
- fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);\r
- }\r
- }\r
-\r
- compressed_index = create_index_into_byte_array(&cstr_info, &compressed_index_size);\r
- /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */\r
- fid = (*env)->GetFieldID(env, cls,"compressedIndex", "[B");\r
- jba = (*env)->NewByteArray(env, compressed_index_size+1);\r
- jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);\r
- memcpy(jbBody, compressed_index, compressed_index_size);\r
- (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);\r
- (*env)->SetObjectField(env, obj, fid, jba); \r
- opj_free(compressed_index);\r
-\r
- /* write the generated codestream to disk ? */\r
- if (parameters.outfile[0]!='\0') {\r
- f = fopen(parameters.outfile, "wb");\r
- if (!f) {\r
- fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);\r
- return -1;\r
- }\r
- fwrite(cio->buffer, 1, codestream_length, f);\r
- fclose(f);\r
- fprintf(stdout,"Generated outfile [%s]\n",parameters.outfile);\r
- }\r
-\r
- /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */\r
- fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");\r
- jba = (*env)->GetObjectField(env, obj, fid);\r
- jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);\r
- memcpy(jbBody, cio->buffer, codestream_length);\r
- (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);\r
-\r
- /* close and free the byte stream */\r
- opj_cio_close(cio);\r
-\r
- /* free remaining compression structures */\r
- opj_destroy_compress(cinfo);\r
- opj_destroy_cstr_info(&cstr_info);\r
-\r
- /* free image data */\r
- opj_image_destroy(image);\r
- }\r
-\r
- /* free user parameters structure */\r
- if(parameters.cp_comment) opj_free(parameters.cp_comment);\r
- if(parameters.cp_matrice) opj_free(parameters.cp_matrice);\r
-\r
- return codestream_length;\r
-}\r
+/*
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux
+ * Copyright (c) 2003-2014, Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * Copyright (c) 2007, Patrick Piscaglia (Telemis)
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <jni.h>
+#include <math.h>
+
+#include "openjpeg.h"
+#include "opj_includes.h"
+#include "opj_getopt.h"
+#include "convert.h"
+#include "index.h"
+#include "dirent.h"
+#include "org_openJpeg_OpenJPEGJavaEncoder.h"
+
+#ifndef _WIN32
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif
+
+#include "format_defs.h"
+
+#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
+#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
+#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
+#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
+
+extern int get_file_format(char *filename);
+extern void error_callback(const char *msg, void *client_data);
+extern void warning_callback(const char *msg, void *client_data);
+extern void info_callback(const char *msg, void *client_data);
+
+typedef struct callback_variables {
+ JNIEnv *env;
+ /** 'jclass' object used to call a Java method from the C */
+ jobject *jobj;
+ /** 'jclass' object used to call a Java method from the C */
+ jmethodID message_mid;
+ jmethodID error_mid;
+} callback_variables_t;
+
+typedef struct dircnt {
+ /** Buffer for holding images read from Directory*/
+ char *filename_buf;
+ /** Pointer to the buffer*/
+ char **filename;
+} dircnt_t;
+
+typedef struct img_folder {
+ /** The directory path of the folder containing input images*/
+ char *imgdirpath;
+ /** Output format*/
+ char *out_format;
+ /** Enable option*/
+ char set_imgdir;
+ /** Enable Cod Format for output*/
+ char set_out_format;
+ /** User specified rate stored in case of cinema option*/
+ float *rates;
+} img_fol_t;
+
+static void encode_help_display()
+{
+ fprintf(stdout, "HELP\n----\n\n");
+ fprintf(stdout, "- the -h option displays this help information on screen\n\n");
+
+ /* UniPG>> */
+ fprintf(stdout, "List of parameters for the JPEG 2000 "
+#ifdef USE_JPWL
+ "+ JPWL "
+#endif /* USE_JPWL */
+ "encoder:\n");
+ /* <<UniPG */
+ fprintf(stdout, "\n");
+ fprintf(stdout, "REMARKS:\n");
+ fprintf(stdout, "---------\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
+ fprintf(stdout, "COD and QCD never appear in the tile_header.\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");
+ fprintf(stdout,
+ "color image. You need enough disk space memory (twice the original) to encode \n");
+ fprintf(stdout,
+ "the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "By default:\n");
+ fprintf(stdout, "------------\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, " * Lossless\n");
+ fprintf(stdout, " * 1 tile\n");
+ fprintf(stdout, " * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
+ fprintf(stdout, " * Size of code-block : 64 x 64\n");
+ fprintf(stdout, " * Number of resolutions: 6\n");
+ fprintf(stdout, " * No SOP marker in the codestream\n");
+ fprintf(stdout, " * No EPH marker in the codestream\n");
+ fprintf(stdout, " * No sub-sampling in x or y direction\n");
+ fprintf(stdout, " * No mode switch activated\n");
+ fprintf(stdout, " * Progression order: LRCP\n");
+ fprintf(stdout, " * No index file\n");
+ fprintf(stdout, " * No ROI upshifted\n");
+ fprintf(stdout, " * No offset of the origin of the image\n");
+ fprintf(stdout, " * No offset of the origin of the tiles\n");
+ fprintf(stdout, " * Reversible DWT 5-3\n");
+ /* UniPG>> */
+#ifdef USE_JPWL
+ fprintf(stdout, " * No JPWL protection\n");
+#endif /* USE_JPWL */
+ /* <<UniPG */
+ fprintf(stdout, "\n");
+ fprintf(stdout, "Parameters:\n");
+ fprintf(stdout, "------------\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "Required Parameters (except with -h):\n");
+ fprintf(stdout, "One of the two options -ImgDir or -i must be used\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-ImgDir : Image file Directory path (example ../Images) \n");
+ fprintf(stdout, " When using this option -OutFor must be used\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-OutFor \n");
+ fprintf(stdout, " REQUIRED only if -ImgDir is used\n");
+ fprintf(stdout, " Need to specify only format without filename <BMP> \n");
+ fprintf(stdout,
+ " Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-i : source file (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");
+ fprintf(stdout, " When using this option -o must be used\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-o : destination file (-o dest.j2k or .jp2) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "Optional Parameters:\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-h : display the help information \n ");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");
+ fprintf(stdout,
+ " Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n");
+ fprintf(stdout, " Frames per second not required. Default value is 24fps\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-r : different compression ratios for successive layers (-r 20,10,5)\n ");
+ fprintf(stdout,
+ " - The rate specified for each quality level is the desired \n");
+ fprintf(stdout, " compression factor.\n");
+ fprintf(stdout, " Example: -r 20,10,1 means quality 1: compress 20x, \n");
+ fprintf(stdout,
+ " quality 2: compress 10x and quality 3: compress lossless\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " (options -r and -q cannot be used together)\n ");
+ fprintf(stdout, "\n");
+
+ fprintf(stdout,
+ "-q : different psnr for successive layers (-q 30,40,50) \n ");
+
+ fprintf(stdout,
+ " (options -r and -q cannot be used together)\n ");
+
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-n : number of resolutions (-n 3) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-b : size of code block (-b 32,32) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-c : size of precinct (-c 128,128) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-t : size of tile (-t 512,512) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-s : subsampling factor (-s 2,2) [-s X,Y] \n");
+ fprintf(stdout, " Remark: subsampling bigger than 2 can produce error\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");
+ fprintf(stdout, " Example: T1=0,0,1,5,3,CPRL \n");
+ fprintf(stdout,
+ " : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-SOP : write SOP marker before each packet \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-EPH : write EPH marker after each header packet \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
+ fprintf(stdout,
+ " 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
+ fprintf(stdout,
+ " Indicate multiple modes by adding their values. \n");
+ fprintf(stdout,
+ " ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-TP : divide packets of every tile into tile-parts (-TP R) [R, L, C]\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-x : create an index file *.Idx (-x index_name.Idx) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-ROI : c=%%d,U=%%d : quantization indices upshifted \n");
+ fprintf(stdout, " for component c=%%d [%%d = 0,1,2]\n");
+ fprintf(stdout,
+ " with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-d : offset of the origin of the image (-d 150,300) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-T : offset of the origin of the tiles (-T 100,75) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "-I : use the irreversible DWT 9-7 (-I) \n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "-jpip : write jpip codestream index box in JP2 output file\n");
+ fprintf(stdout, " NOTICE: currently supports only RPCL order\n");
+ fprintf(stdout, "\n");
+ /* UniPG>> */
+#ifdef USE_JPWL
+ fprintf(stdout,
+ "-W : adoption of JPWL (Part 11) capabilities (-W params)\n");
+ fprintf(stdout,
+ " The parameters can be written and repeated in any order:\n");
+ fprintf(stdout,
+ " [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");
+ fprintf(stdout,
+ " ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " h selects the header error protection (EPB): 'type' can be\n");
+ fprintf(stdout,
+ " [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
+ fprintf(stdout,
+ " if 'tilepart' is absent, it is for main and tile headers\n");
+ fprintf(stdout,
+ " if 'tilepart' is present, it applies from that tile\n");
+ fprintf(stdout,
+ " onwards, up to the next h<> spec, or to the last tilepart\n");
+ fprintf(stdout, " in the codestream (max. %d specs)\n",
+ JPWL_MAX_NO_TILESPECS);
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " p selects the packet error protection (EEP/UEP with EPBs)\n");
+ fprintf(stdout, " to be applied to raw data: 'type' can be\n");
+ fprintf(stdout,
+ " [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
+ fprintf(stdout,
+ " if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");
+ fprintf(stdout,
+ " if 'tilepart:pack' is present, it applies from that tile\n");
+ fprintf(stdout,
+ " and that packet onwards, up to the next packet spec\n");
+ fprintf(stdout,
+ " or to the last packet in the last tilepart in the stream\n");
+ fprintf(stdout, " (max. %d specs)\n",
+ JPWL_MAX_NO_PACKSPECS);
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " s enables sensitivity data insertion (ESD): 'method' can be\n");
+ fprintf(stdout,
+ " [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");
+ fprintf(stdout,
+ " 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");
+ fprintf(stdout,
+ " if 'tilepart' is absent, it is for main header only\n");
+ fprintf(stdout,
+ " if 'tilepart' is present, it applies from that tile\n");
+ fprintf(stdout,
+ " onwards, up to the next s<> spec, or to the last tilepart\n");
+ fprintf(stdout, " in the codestream (max. %d specs)\n",
+ JPWL_MAX_NO_TILESPECS);
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " g determines the addressing mode: <range> can be\n");
+ fprintf(stdout, " [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " a determines the size of data addressing: <addr> can be\n");
+ fprintf(stdout,
+ " 2/4 bytes (small/large codestreams). If not set, auto-mode\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " z determines the size of sensitivity values: <size> can be\n");
+ fprintf(stdout,
+ " 1/2 bytes, for the transformed pseudo-floating point value\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, " ex.:\n");
+ fprintf(stdout,
+ " h,h0=64,h3=16,h5=32,p0=78,p0:24=56,p1,p3:0=0,p3:20=32,s=0,\n");
+ fprintf(stdout, " s0=6,s3=-1,a=0,g=1,z=1\n");
+ fprintf(stdout, " means\n");
+ fprintf(stdout,
+ " predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");
+ fprintf(stdout,
+ " CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");
+ fprintf(stdout,
+ " UEP rs(78,32) for packets 0 to 23 of tile 0,\n");
+ fprintf(stdout,
+ " UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");
+ fprintf(stdout,
+ " UEP rs default for packets of tilepart 1,\n");
+ fprintf(stdout,
+ " no UEP for packets 0 to 19 of tilepart 3,\n");
+ fprintf(stdout,
+ " UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");
+ fprintf(stdout, " relative sensitivity ESD for MH,\n");
+ fprintf(stdout,
+ " TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");
+ fprintf(stdout,
+ " size of addresses and 1 byte for each sensitivity value\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, " ex.:\n");
+ fprintf(stdout, " h,s,p\n");
+ fprintf(stdout, " means\n");
+ fprintf(stdout,
+ " default protection to headers (MH and TPHs) as well as\n");
+ fprintf(stdout, " data packets, one ESD in MH\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ " N.B.: use the following recommendations when specifying\n");
+ fprintf(stdout, " the JPWL parameters list\n");
+ fprintf(stdout,
+ " - when you use UEP, always pair the 'p' option with 'h'\n");
+ fprintf(stdout, " \n");
+#endif /* USE_JPWL */
+ /* <<UniPG */
+ fprintf(stdout, "IMPORTANT:\n");
+ fprintf(stdout, "-----------\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "The index file has the structure below:\n");
+ fprintf(stdout, "---------------------------------------\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "Image_height Image_width\n");
+ fprintf(stdout, "progression order\n");
+ fprintf(stdout, "Tiles_size_X Tiles_size_Y\n");
+ fprintf(stdout, "Tiles_nb_X Tiles_nb_Y\n");
+ fprintf(stdout, "Components_nb\n");
+ fprintf(stdout, "Layers_nb\n");
+ fprintf(stdout, "decomposition_levels\n");
+ fprintf(stdout, "[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
+ fprintf(stdout, " [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
+ fprintf(stdout, "Main_header_start_position\n");
+ fprintf(stdout, "Main_header_end_position\n");
+ fprintf(stdout, "Codestream_size\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "INFO ON TILES\n");
+ fprintf(stdout,
+ "tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
+ fprintf(stdout,
+ "Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");
+ fprintf(stdout,
+ "Tile_1 '' '' '' '' '' '' ''\n");
+ fprintf(stdout, "...\n");
+ fprintf(stdout,
+ "Tile_Nt '' '' '' '' '' '' ''\n");
+ fprintf(stdout, "...\n");
+ fprintf(stdout, "TILE 0 DETAILS\n");
+ fprintf(stdout, "part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
+ fprintf(stdout, "...\n");
+ fprintf(stdout, "Progression_string\n");
+ fprintf(stdout,
+ "pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");
+ fprintf(stdout,
+ "Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
+ fprintf(stdout, "...\n");
+ fprintf(stdout,
+ "Tpacket_Np '' '' '' '' '' '' '' ''\n");
+
+ fprintf(stdout, "MaxDisto\n");
+
+ fprintf(stdout, "TotalDisto\n\n");
+}
+
+
+static OPJ_PROG_ORDER give_progression(const char progression[4])
+{
+ if (strncmp(progression, "LRCP", 4) == 0) {
+ return LRCP;
+ }
+ if (strncmp(progression, "RLCP", 4) == 0) {
+ return RLCP;
+ }
+ if (strncmp(progression, "RPCL", 4) == 0) {
+ return RPCL;
+ }
+ if (strncmp(progression, "PCRL", 4) == 0) {
+ return PCRL;
+ }
+ if (strncmp(progression, "CPRL", 4) == 0) {
+ return CPRL;
+ }
+
+ return PROG_UNKNOWN;
+}
+
+static int initialise_4K_poc(opj_poc_t *POC, int numres)
+{
+ POC[0].tile = 1;
+ POC[0].resno0 = 0;
+ POC[0].compno0 = 0;
+ POC[0].layno1 = 1;
+ POC[0].resno1 = numres - 1;
+ POC[0].compno1 = 3;
+ POC[0].prg1 = CPRL;
+ POC[1].tile = 1;
+ POC[1].resno0 = numres - 1;
+ POC[1].compno0 = 0;
+ POC[1].layno1 = 1;
+ POC[1].resno1 = numres;
+ POC[1].compno1 = 3;
+ POC[1].prg1 = CPRL;
+ return 2;
+}
+
+static void cinema_parameters(opj_cparameters_t *parameters)
+{
+ parameters->tile_size_on = OPJ_FALSE;
+ parameters->cp_tdx = 1;
+ parameters->cp_tdy = 1;
+
+ /*Tile part*/
+ parameters->tp_flag = 'C';
+ parameters->tp_on = 1;
+
+ /*Tile and Image shall be at (0,0)*/
+ parameters->cp_tx0 = 0;
+ parameters->cp_ty0 = 0;
+ parameters->image_offset_x0 = 0;
+ parameters->image_offset_y0 = 0;
+
+ /*Codeblock size= 32*32*/
+ parameters->cblockw_init = 32;
+ parameters->cblockh_init = 32;
+ parameters->csty |= 0x01;
+
+ /*The progression order shall be CPRL*/
+ parameters->prog_order = CPRL;
+
+ /* No ROI */
+ parameters->roi_compno = -1;
+
+ parameters->subsampling_dx = 1;
+ parameters->subsampling_dy = 1;
+
+ /* 9-7 transform */
+ parameters->irreversible = 1;
+
+}
+
+static void cinema_setup_encoder(opj_cparameters_t *parameters,
+ opj_image_t *image, img_fol_t *img_fol)
+{
+ int i;
+ float temp_rate;
+ opj_poc_t *POC = NULL;
+
+ switch (parameters->cp_cinema) {
+ case CINEMA2K_24:
+ case CINEMA2K_48:
+ if (parameters->numresolution > 6) {
+ parameters->numresolution = 6;
+ }
+ if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))) {
+ fprintf(stdout,
+ "Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"
+ "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
+ image->comps[0].w, image->comps[0].h);
+ parameters->cp_rsiz = STD_RSIZ;
+ }
+ break;
+
+ case CINEMA4K_24:
+ if (parameters->numresolution < 1) {
+ parameters->numresolution = 1;
+ } else if (parameters->numresolution > 7) {
+ parameters->numresolution = 7;
+ }
+ if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))) {
+ fprintf(stdout,
+ "Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
+ "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
+ image->comps[0].w, image->comps[0].h);
+ parameters->cp_rsiz = STD_RSIZ;
+ }
+ parameters->numpocs = initialise_4K_poc(parameters->POC,
+ parameters->numresolution);
+ break;
+ }
+
+ switch (parameters->cp_cinema) {
+ case CINEMA2K_24:
+ case CINEMA4K_24:
+ for (i = 0 ; i < parameters->tcp_numlayers ; i++) {
+ temp_rate = 0 ;
+ if (img_fol->rates[i] == 0) {
+ parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ } else {
+ temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
+ image->comps[0].prec)) /
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
+ if (temp_rate > CINEMA_24_CS) {
+ parameters->tcp_rates[i] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ } else {
+ parameters->tcp_rates[i] = img_fol->rates[i];
+ }
+ }
+ }
+ parameters->max_comp_size = COMP_24_CS;
+ break;
+
+ case CINEMA2K_48:
+ for (i = 0 ; i < parameters->tcp_numlayers ; i++) {
+ temp_rate = 0 ;
+ if (img_fol->rates[i] == 0) {
+ parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ } else {
+ temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
+ image->comps[0].prec)) /
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
+ if (temp_rate > CINEMA_48_CS) {
+ parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ } else {
+ parameters->tcp_rates[i] = img_fol->rates[i];
+ }
+ }
+ }
+ parameters->max_comp_size = COMP_48_CS;
+ break;
+ }
+ parameters->cp_disto_alloc = 1;
+}
+
+
+/* ------------------------------------------------------------------------------------ */
+static int parse_cmdline_encoder(int argc, char **argv,
+ opj_cparameters_t *parameters,
+ img_fol_t *img_fol, char *indexfilename)
+{
+ int i, j, totlen;
+ opj_option_t long_option[] = {
+ {"cinema2K", REQ_ARG, NULL, 'w'},
+ {"cinema4K", NO_ARG, NULL, 'y'},
+ {"ImgDir", REQ_ARG, NULL, 'z'},
+ {"TP", REQ_ARG, NULL, 'u'},
+ {"SOP", NO_ARG, NULL, 'S'},
+ {"EPH", NO_ARG, NULL, 'E'},
+ {"OutFor", REQ_ARG, NULL, 'O'},
+ {"POC", REQ_ARG, NULL, 'P'},
+ {"ROI", REQ_ARG, NULL, 'R'},
+ {"jpip", NO_ARG, NULL, 'J'}
+ };
+
+ /* parse the command line */
+ /* UniPG>> */
+ const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:"
+#ifdef USE_JPWL
+ "W:"
+#endif /* USE_JPWL */
+ ;
+
+ /*printf("C: parse_cmdline_encoder:");
+ for (i=0; i<argc; i++) {
+ printf("[%s]",argv[i]);
+ }
+ printf("\n");*/
+
+ totlen = sizeof(long_option);
+ img_fol->set_out_format = 0;
+ reset_options_reading();
+
+ while (1) {
+ int c = opj_getopt_long(argc, argv, optlist, long_option, totlen);
+ if (c == -1) {
+ break;
+ }
+ switch (c) {
+
+ /* ----------------------------------------------------- */
+
+ case 'o': { /* output file */
+ char *outfile = opj_optarg;
+ parameters->cod_format = get_file_format(outfile);
+ switch (parameters->cod_format) {
+ case J2K_CFMT:
+ case JP2_CFMT:
+ break;
+ default:
+ fprintf(stderr,
+ "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);
+ return 1;
+ }
+ strncpy(parameters->outfile, outfile, sizeof(parameters->outfile) - 1);
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+ case 'O': { /* output format */
+ char outformat[50];
+ char *of = opj_optarg;
+ sprintf(outformat, ".%s", of);
+ img_fol->set_out_format = 1;
+ parameters->cod_format = get_file_format(outformat);
+ switch (parameters->cod_format) {
+ case J2K_CFMT:
+ case JP2_CFMT:
+ img_fol->out_format = opj_optarg;
+ break;
+ default:
+ fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");
+ return 1;
+ }
+ }
+ break;
+
+
+ /* ----------------------------------------------------- */
+
+
+ case 'r': { /* rates rates/distorsion */
+ char *s = opj_optarg;
+ while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) ==
+ 1) {
+ parameters->tcp_numlayers++;
+ while (*s && *s != ',') {
+ s++;
+ }
+ if (!*s) {
+ break;
+ }
+ s++;
+ }
+ parameters->cp_disto_alloc = 1;
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 'q': { /* add fixed_quality */
+ char *s = opj_optarg;
+ while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers])
+ == 1) {
+ parameters->tcp_numlayers++;
+ while (*s && *s != ',') {
+ s++;
+ }
+ if (!*s) {
+ break;
+ }
+ s++;
+ }
+ parameters->cp_fixed_quality = 1;
+ }
+ break;
+
+ /* dda */
+ /* ----------------------------------------------------- */
+
+ case 'f': { /* mod fixed_quality (before : -q) */
+ int *row = NULL, *col = NULL;
+ int numlayers = 0, numresolution = 0, matrix_width = 0;
+
+ char *s = opj_optarg;
+ sscanf(s, "%d", &numlayers);
+ s++;
+ if (numlayers > 9) {
+ s++;
+ }
+
+ parameters->tcp_numlayers = numlayers;
+ numresolution = parameters->numresolution;
+ matrix_width = numresolution * 3;
+ parameters->cp_matrice = (int *) opj_malloc(numlayers * matrix_width * sizeof(
+ int));
+ s = s + 2;
+
+ for (i = 0; i < numlayers; i++) {
+ row = ¶meters->cp_matrice[i * matrix_width];
+ col = row;
+ parameters->tcp_rates[i] = 1;
+ sscanf(s, "%d,", &col[0]);
+ s += 2;
+ if (col[0] > 9) {
+ s++;
+ }
+ col[1] = 0;
+ col[2] = 0;
+ for (j = 1; j < numresolution; j++) {
+ col += 3;
+ sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
+ s += 6;
+ if (col[0] > 9) {
+ s++;
+ }
+ if (col[1] > 9) {
+ s++;
+ }
+ if (col[2] > 9) {
+ s++;
+ }
+ }
+ if (i < numlayers - 1) {
+ s++;
+ }
+ }
+ parameters->cp_fixed_alloc = 1;
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 't': { /* tiles */
+ sscanf(opj_optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);
+ parameters->tile_size_on = OPJ_TRUE;
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 'n': { /* resolution */
+ sscanf(opj_optarg, "%d", ¶meters->numresolution);
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+ case 'c': { /* precinct dimension */
+ char sep;
+ int res_spec = 0;
+
+ char *s = opj_optarg;
+ do {
+ sep = 0;
+ sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],
+ ¶meters->prch_init[res_spec], &sep);
+ parameters->csty |= 0x01;
+ res_spec++;
+ s = strpbrk(s, "]") + 2;
+ } while (sep == ',');
+ parameters->res_spec = res_spec;
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 'b': { /* code-block dimension */
+ int cblockw_init = 0, cblockh_init = 0;
+ sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);
+ if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
+ || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
+ fprintf(stderr,
+ "!! Size of code_block error (option -b) !!\n\nRestriction :\n"
+ " * width*height<=4096\n * 4<=width,height<= 1024\n\n");
+ return 1;
+ }
+ parameters->cblockw_init = cblockw_init;
+ parameters->cblockh_init = cblockh_init;
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 'x': { /* creation of index file */
+ char *index = opj_optarg;
+ strncpy(indexfilename, index, OPJ_PATH_LEN);
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 'p': { /* progression order */
+ char progression[4];
+
+ strncpy(progression, opj_optarg, 4);
+ parameters->prog_order = give_progression(progression);
+ if (parameters->prog_order == -1) {
+ fprintf(stderr, "Unrecognized progression order "
+ "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
+ return 1;
+ }
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 's': { /* subsampling factor */
+ if (sscanf(opj_optarg, "%d,%d", ¶meters->subsampling_dx,
+ ¶meters->subsampling_dy) != 2) {
+ fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");
+ return 1;
+ }
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 'd': { /* coordonnate of the reference grid */
+ if (sscanf(opj_optarg, "%d,%d", ¶meters->image_offset_x0,
+ ¶meters->image_offset_y0) != 2) {
+ fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
+ "error !! [-d x0,y0]\n");
+ return 1;
+ }
+ }
+ break;
+
+ /* ----------------------------------------------------- */
+
+ case 'h': /* display an help description */
+ encode_help_display();
+ return 1;
+
+ /* ----------------------------------------------------- */
+
+ case 'P': { /* POC */
+ int numpocs = 0; /* number of progression order change (POC) default 0 */
+ opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
+
+ char *s = opj_optarg;
+ POC = parameters->POC;
+
+ while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
+ &POC[numpocs].resno0, &POC[numpocs].compno0,
+ &POC[numpocs].layno1, &POC[numpocs].resno1,
+ &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {
+ POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
+ numpocs++;
+ while (*s && *s != '/') {
+ s++;
+ }
+ if (!*s) {
+ break;
+ }
+ s++;
+ }
+ parameters->numpocs = numpocs;
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'S': { /* SOP marker */
+ parameters->csty |= 0x02;
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'E': { /* EPH marker */
+ parameters->csty |= 0x04;
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'M': { /* Mode switch pas tous au point !! */
+ int value = 0;
+ if (sscanf(opj_optarg, "%d", &value) == 1) {
+ for (i = 0; i <= 5; i++) {
+ int cache = value & (1 << i);
+ if (cache) {
+ parameters->mode |= (1 << i);
+ }
+ }
+ }
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'R': { /* ROI */
+ if (sscanf(opj_optarg, "c=%d,U=%d", ¶meters->roi_compno,
+ ¶meters->roi_shift) != 2) {
+ fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");
+ return 1;
+ }
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'T': { /* Tile offset */
+ if (sscanf(opj_optarg, "%d,%d", ¶meters->cp_tx0,
+ ¶meters->cp_ty0) != 2) {
+ fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
+ return 1;
+ }
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'C': { /* add a comment */
+ parameters->cp_comment = (char*)opj_malloc(strlen(opj_optarg) + 1);
+ if (parameters->cp_comment) {
+ strcpy(parameters->cp_comment, opj_optarg);
+ }
+ }
+ break;
+
+
+ /* ------------------------------------------------------ */
+
+ case 'I': { /* reversible or not */
+ parameters->irreversible = 1;
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'u': { /* Tile part generation*/
+ parameters->tp_flag = opj_optarg[0];
+ parameters->tp_on = 1;
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'z': { /* Image Directory path */
+ img_fol->imgdirpath = (char*)opj_malloc(strlen(opj_optarg) + 1);
+ strcpy(img_fol->imgdirpath, opj_optarg);
+ img_fol->set_imgdir = 1;
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'w': { /* Digital Cinema 2K profile compliance*/
+ int fps = 0;
+ sscanf(opj_optarg, "%d", &fps);
+ if (fps == 24) {
+ parameters->cp_cinema = CINEMA2K_24;
+ } else if (fps == 48) {
+ parameters->cp_cinema = CINEMA2K_48;
+ } else {
+ fprintf(stderr, "Incorrect value!! must be 24 or 48\n");
+ return 1;
+ }
+ fprintf(stdout, "CINEMA 2K compliant codestream\n");
+ parameters->cp_rsiz = CINEMA2K;
+
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ case 'y': { /* Digital Cinema 4K profile compliance*/
+ parameters->cp_cinema = CINEMA4K_24;
+ fprintf(stdout, "CINEMA 4K compliant codestream\n");
+ parameters->cp_rsiz = CINEMA4K;
+ }
+ break;
+
+ /* ------------------------------------------------------ */
+
+ /* UniPG>> */
+#ifdef USE_JPWL
+ /* ------------------------------------------------------ */
+
+ case 'W': { /* JPWL capabilities switched on */
+ char *token = NULL;
+ int hprot, pprot, sens, addr, size, range;
+
+ /* we need to enable indexing */
+ if (!indexfilename) {
+ strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);
+ }
+
+ /* search for different protection methods */
+
+ /* break the option in comma points and parse the result */
+ token = strtok(opj_optarg, ",");
+ while (token != NULL) {
+
+ /* search header error protection method */
+ if (*token == 'h') {
+
+ static int tile = 0, tilespec = 0, lasttileno = 0;
+
+ hprot = 1; /* predefined method */
+
+ if (sscanf(token, "h=%d", &hprot) == 1) {
+ /* Main header, specified */
+ if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
+ ((hprot >= 37) && (hprot <= 128)))) {
+ fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n",
+ hprot);
+ return 1;
+ }
+ parameters->jpwl_hprot_MH = hprot;
+
+ } else if (sscanf(token, "h%d=%d", &tile, &hprot) == 2) {
+ /* Tile part header, specified */
+ if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
+ ((hprot >= 37) && (hprot <= 128)))) {
+ fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n",
+ hprot);
+ return 1;
+ }
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on protection method t = %d\n", tile);
+ return 1;
+ }
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {
+ parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
+ parameters->jpwl_hprot_TPH[tilespec++] = hprot;
+ }
+
+ } else if (sscanf(token, "h%d", &tile) == 1) {
+ /* Tile part header, unspecified */
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on protection method t = %d\n", tile);
+ return 1;
+ }
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {
+ parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
+ parameters->jpwl_hprot_TPH[tilespec++] = hprot;
+ }
+
+
+ } else if (!strcmp(token, "h")) {
+ /* Main header, unspecified */
+ parameters->jpwl_hprot_MH = hprot;
+
+ } else {
+ fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
+ return 1;
+ };
+
+ }
+
+ /* search packet error protection method */
+ if (*token == 'p') {
+
+ static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;
+
+ pprot = 1; /* predefined method */
+
+ if (sscanf(token, "p=%d", &pprot) == 1) {
+ /* Method for all tiles and all packets */
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
+ ((pprot >= 37) && (pprot <= 128)))) {
+ fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n",
+ pprot);
+ return 1;
+ }
+ parameters->jpwl_pprot_tileno[0] = 0;
+ parameters->jpwl_pprot_packno[0] = 0;
+ parameters->jpwl_pprot[0] = pprot;
+
+ } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {
+ /* method specified from that tile on */
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
+ ((pprot >= 37) && (pprot <= 128)))) {
+ fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
+ return 1;
+ }
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on protection method p = %d\n", tile);
+ return 1;
+ }
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {
+ parameters->jpwl_pprot_tileno[packspec] = tile;
+ parameters->jpwl_pprot_packno[packspec] = 0;
+ parameters->jpwl_pprot[packspec++] = pprot;
+ }
+
+ } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {
+ /* method fully specified from that tile and that packet on */
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
+ ((pprot >= 37) && (pprot <= 128)))) {
+ fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
+ return 1;
+ }
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on protection method p = %d\n", tile);
+ return 1;
+ }
+ if (pack < 0) {
+ fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n",
+ pack);
+ return 1;
+ }
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {
+ parameters->jpwl_pprot_tileno[packspec] = tile;
+ parameters->jpwl_pprot_packno[packspec] = pack;
+ parameters->jpwl_pprot[packspec++] = pprot;
+ }
+
+ } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {
+ /* default method from that tile and that packet on */
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
+ ((pprot >= 37) && (pprot <= 128)))) {
+ fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
+ return 1;
+ }
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on protection method p = %d\n", tile);
+ return 1;
+ }
+ if (pack < 0) {
+ fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n",
+ pack);
+ return 1;
+ }
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {
+ parameters->jpwl_pprot_tileno[packspec] = tile;
+ parameters->jpwl_pprot_packno[packspec] = pack;
+ parameters->jpwl_pprot[packspec++] = pprot;
+ }
+
+ } else if (sscanf(token, "p%d", &tile) == 1) {
+ /* default from a tile on */
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on protection method p = %d\n", tile);
+ return 1;
+ }
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {
+ parameters->jpwl_pprot_tileno[packspec] = tile;
+ parameters->jpwl_pprot_packno[packspec] = 0;
+ parameters->jpwl_pprot[packspec++] = pprot;
+ }
+
+
+ } else if (!strcmp(token, "p")) {
+ /* all default */
+ parameters->jpwl_pprot_tileno[0] = 0;
+ parameters->jpwl_pprot_packno[0] = 0;
+ parameters->jpwl_pprot[0] = pprot;
+
+ } else {
+ fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
+ return 1;
+ };
+
+ }
+
+ /* search sensitivity method */
+ if (*token == 's') {
+
+ static int tile = 0, tilespec = 0, lasttileno = 0;
+
+ sens = 0; /* predefined: relative error */
+
+ if (sscanf(token, "s=%d", &sens) == 1) {
+ /* Main header, specified */
+ if ((sens < -1) || (sens > 7)) {
+ fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n",
+ sens);
+ return 1;
+ }
+ parameters->jpwl_sens_MH = sens;
+
+ } else if (sscanf(token, "s%d=%d", &tile, &sens) == 2) {
+ /* Tile part header, specified */
+ if ((sens < -1) || (sens > 7)) {
+ fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n",
+ sens);
+ return 1;
+ }
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
+ return 1;
+ }
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {
+ parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
+ parameters->jpwl_sens_TPH[tilespec++] = sens;
+ }
+
+ } else if (sscanf(token, "s%d", &tile) == 1) {
+ /* Tile part header, unspecified */
+ if (tile < 0) {
+ fprintf(stderr,
+ "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
+ return 1;
+ }
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {
+ parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
+ parameters->jpwl_sens_TPH[tilespec++] = hprot;
+ }
+
+ } else if (!strcmp(token, "s")) {
+ /* Main header, unspecified */
+ parameters->jpwl_sens_MH = sens;
+
+ } else {
+ fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);
+ return 1;
+ };
+
+ parameters->jpwl_sens_size = 2; /* 2 bytes for default size */
+ }
+
+ /* search addressing size */
+ if (*token == 'a') {
+
+ static int tile = 0, tilespec = 0, lasttileno = 0;
+
+ addr = 0; /* predefined: auto */
+
+ if (sscanf(token, "a=%d", &addr) == 1) {
+ /* Specified */
+ if ((addr != 0) && (addr != 2) && (addr != 4)) {
+ fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);
+ return 1;
+ }
+ parameters->jpwl_sens_addr = addr;
+
+ } else if (!strcmp(token, "a")) {
+ /* default */
+ parameters->jpwl_sens_addr = addr; /* auto for default size */
+
+ } else {
+ fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);
+ return 1;
+ };
+
+ }
+
+ /* search sensitivity size */
+ if (*token == 'z') {
+
+ static int tile = 0, tilespec = 0, lasttileno = 0;
+
+ size = 1; /* predefined: 1 byte */
+
+ if (sscanf(token, "z=%d", &size) == 1) {
+ /* Specified */
+ if ((size != 0) && (size != 1) && (size != 2)) {
+ fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);
+ return 1;
+ }
+ parameters->jpwl_sens_size = size;
+
+ } else if (!strcmp(token, "a")) {
+ /* default */
+ parameters->jpwl_sens_size = size; /* 1 for default size */
+
+ } else {
+ fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);
+ return 1;
+ };
+
+ }
+
+ /* search range method */
+ if (*token == 'g') {
+
+ static int tile = 0, tilespec = 0, lasttileno = 0;
+
+ range = 0; /* predefined: 0 (packet) */
+
+ if (sscanf(token, "g=%d", &range) == 1) {
+ /* Specified */
+ if ((range < 0) || (range > 3)) {
+ fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);
+ return 1;
+ }
+ parameters->jpwl_sens_range = range;
+
+ } else if (!strcmp(token, "g")) {
+ /* default */
+ parameters->jpwl_sens_range = range;
+
+ } else {
+ fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);
+ return 1;
+ };
+
+ }
+
+ /* next token or bust */
+ token = strtok(NULL, ",");
+ };
+
+
+ /* some info */
+ fprintf(stdout, "Info: JPWL capabilities enabled\n");
+ parameters->jpwl_epc_on = true;
+
+ }
+ break;
+#endif /* USE_JPWL */
+ /* <<UniPG */
+ /* ------------------------------------------------------ */
+
+ break;
+ /* ------------------------------------------------------ */
+
+ default:
+ fprintf(stderr, "ERROR -> Command line not valid\n");
+ return 1;
+ }
+ }
+
+ /* check for possible errors */
+ if (parameters->cp_cinema) {
+ if (parameters->tcp_numlayers > 1) {
+ parameters->cp_rsiz = STD_RSIZ;
+ fprintf(stdout,
+ "Warning: DC profiles do not allow more than one quality layer. The codestream created will not be compliant with the DC profile\n");
+ }
+ }
+
+ if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc ||
+ parameters->cp_fixed_quality)
+ && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^
+ parameters->cp_fixed_quality))) {
+ fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
+ return 1;
+ } /* mod fixed_quality */
+
+ /* if no rate entered, lossless by default */
+ if (parameters->tcp_numlayers == 0) {
+ parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
+ parameters->tcp_numlayers++;
+ parameters->cp_disto_alloc = 1;
+ }
+
+ if ((parameters->cp_tx0 > parameters->image_offset_x0) ||
+ (parameters->cp_ty0 > parameters->image_offset_y0)) {
+ fprintf(stderr,
+ "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
+ parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0,
+ parameters->image_offset_y0);
+ return 1;
+ }
+
+ for (i = 0; i < parameters->numpocs; i++) {
+ if (parameters->POC[i].prg == -1) {
+ fprintf(stderr,
+ "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
+ i + 1);
+ }
+ }
+
+ return 0;
+}
+
+
+/** Create the same index as j2k_create_index does, but in an int[] instead of in a file ==> easy to pass it back to Java, to transfer it etc.
+ @param buffer_size, increased by the length of the compressed index, in number of bytes
+ @return a pointer to a char[]
+ Syntax of the index:
+ one char for the version number (1): one byte because no problem with little endian, big endian etc.
+ one int for each of the following informations:
+ Image Width
+ Image Height
+ progression order
+ Tile width
+ Tile height
+ Nb tiles in X
+ Nb tiles in Y
+ Nb of components
+ Nb of layers
+ Nb of resolutions
+
+ for each resolution:
+ Precinct width
+ Precinct height
+
+ End main header position
+ codestream size
+
+ For each tile:
+ tile number
+ tile start pos in codestream
+ tile header end position
+ tile end position in codestream
+
+ For each LRCP, RLCP etc.:
+ packet number
+ tile number
+ layer number
+ resolution number
+ component number
+ precinct number
+ start position in the codestream
+ end position of this packet
+ */
+static char* create_index_into_byte_array(opj_codestream_info_t *cstr_info,
+ int* buffer_size)
+{
+ int tileno, compno, layno, resno, precno, pack_nb, x, y;
+ char* buffer = NULL;
+ int buffer_pos = 0;
+ int prec_max = 0;
+
+ prec_max = 0;
+ for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
+ for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {
+ prec_max = int_max(prec_max,
+ cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);
+ }
+ }
+
+ /* Compute the size of the index buffer, in number of bytes*/
+ *buffer_size =
+ 1 /* version */
+ + (10 /* image_w until decomposition */
+ + (cstr_info->numdecompos[0] + 1) * 2 /* pdx size for each tile */
+ + 2 /* main_head_end + codestream_size */
+ + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */
+ + cstr_info->tw * cstr_info->th * cstr_info->numlayers *
+ (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max * 8
+ ) * sizeof(int);
+ /*printf("C: index buffer size = %d bytes\n", *buffer_size);*/
+ buffer = (char*) opj_malloc(*buffer_size);
+
+ if (!buffer) {
+ /*opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);*/
+ fprintf(stderr, "failed to allocate index buffer for writing %d int\n",
+ *buffer_size);
+ return 0;
+ }
+
+ buffer[0] = 1; /* Version stored on a byte*/
+ buffer++;
+ /* Remaining informations are stored on a int.*/
+ ((int*)buffer)[buffer_pos++] = cstr_info->image_w;
+ ((int*)buffer)[buffer_pos++] = cstr_info->image_h;
+ ((int*)buffer)[buffer_pos++] = cstr_info->prog;
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;
+ ((int*)buffer)[buffer_pos++] = cstr_info->tw;
+ ((int*)buffer)[buffer_pos++] = cstr_info->th;
+ ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;
+ ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;
+ ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];
+
+ for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
+ /* based on tile 0 */
+ ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
+ ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
+ }
+ ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;
+ ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;
+
+ for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;
+ }
+
+ for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
+ int start_pos, end_pos;
+ int max_numdecompos = 0;
+ pack_nb = 0;
+
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {
+ if (max_numdecompos < cstr_info->numdecompos[compno]) {
+ max_numdecompos = cstr_info->numdecompos[compno];
+ }
+ }
+
+ if (cstr_info->prog == LRCP) { /* LRCP */
+
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {
+ int prec_max;
+ if (resno > cstr_info->numdecompos[compno]) {
+ break;
+ }
+ prec_max = cstr_info->tile[tileno].pw[resno] *
+ cstr_info->tile[tileno].ph[resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
+ ((int*)buffer)[buffer_pos++] = pack_nb;
+ ((int*)buffer)[buffer_pos++] = tileno;
+ ((int*)buffer)[buffer_pos++] = layno;
+ ((int*)buffer)[buffer_pos++] = resno;
+ ((int*)buffer)[buffer_pos++] = compno;
+ ((int*)buffer)[buffer_pos++] = precno;
+ ((int*)buffer)[buffer_pos++] = start_pos;
+ ((int*)buffer)[buffer_pos++] = end_pos;
+ pack_nb++;
+ }
+ }
+ }
+ }
+ } /* LRCP */
+ else if (cstr_info->prog == RLCP) { /* RLCP */
+
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {
+ int prec_max;
+ if (resno > cstr_info->numdecompos[compno]) {
+ break;
+ }
+ prec_max = cstr_info->tile[tileno].pw[resno] *
+ cstr_info->tile[tileno].ph[resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
+ ((int*)buffer)[buffer_pos++] = pack_nb;
+ ((int*)buffer)[buffer_pos++] = tileno;
+ ((int*)buffer)[buffer_pos++] = resno;
+ ((int*)buffer)[buffer_pos++] = layno;
+ ((int*)buffer)[buffer_pos++] = compno;
+ ((int*)buffer)[buffer_pos++] = precno;
+ ((int*)buffer)[buffer_pos++] = start_pos;
+ ((int*)buffer)[buffer_pos++] = end_pos;
+ pack_nb++;
+ }
+ }
+ }
+ }
+ } /* RLCP */
+ else if (cstr_info->prog == RPCL) { /* RPCL */
+
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {
+ /* I suppose components have same XRsiz, YRsiz */
+ int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
+ (float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
+ int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
+ (float)cstr_info->tw) * cstr_info->tile_y;
+ int x1 = x0 + cstr_info->tile_x;
+ int y1 = y0 + cstr_info->tile_y;
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {
+ int prec_max;
+ if (resno > cstr_info->numdecompos[compno]) {
+ break;
+ }
+ prec_max = cstr_info->tile[tileno].pw[resno] *
+ cstr_info->tile[tileno].ph[resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ int pcnx = cstr_info->tile[tileno].pw[resno];
+ int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
+ cstr_info->numdecompos[compno] - resno);
+ int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
+ cstr_info->numdecompos[compno] - resno);
+ int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
+ int precno_y = (int) floor((float)precno / (float)pcnx);
+ for (y = y0; y < y1; y++) {
+ if (precno_y * pcy == y) {
+ for (x = x0; x < x1; x++) {
+ if (precno_x * pcx == x) {
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
+ ((int*)buffer)[buffer_pos++] = pack_nb;
+ ((int*)buffer)[buffer_pos++] = tileno;
+ ((int*)buffer)[buffer_pos++] = resno;
+ ((int*)buffer)[buffer_pos++] = precno;
+ ((int*)buffer)[buffer_pos++] = compno;
+ ((int*)buffer)[buffer_pos++] = layno;
+ ((int*)buffer)[buffer_pos++] = start_pos;
+ ((int*)buffer)[buffer_pos++] = end_pos;
+ pack_nb++;
+ }
+ }
+ }/* x = x0..x1 */
+ }
+ } /* y = y0..y1 */
+ } /* precno */
+ } /* compno */
+ } /* resno */
+ } /* RPCL */
+ else if (cstr_info->prog == PCRL) { /* PCRL */
+ /* I suppose components have same XRsiz, YRsiz */
+ int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
+ (float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
+ int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
+ (float)cstr_info->tw) * cstr_info->tile_y;
+ int x1 = x0 + cstr_info->tile_x;
+ int y1 = y0 + cstr_info->tile_y;
+
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {
+ int prec_max;
+ if (resno > cstr_info->numdecompos[compno]) {
+ break;
+ }
+ prec_max = cstr_info->tile[tileno].pw[resno] *
+ cstr_info->tile[tileno].ph[resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ int pcnx = cstr_info->tile[tileno].pw[resno];
+ int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
+ cstr_info->numdecompos[compno] - resno);
+ int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
+ cstr_info->numdecompos[compno] - resno);
+ int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
+ int precno_y = (int) floor((float)precno / (float)pcnx);
+ for (y = y0; y < y1; y++) {
+ if (precno_y * pcy == y) {
+ for (x = x0; x < x1; x++) {
+ if (precno_x * pcx == x) {
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
+ ((int*)buffer)[buffer_pos++] = pack_nb;
+ ((int*)buffer)[buffer_pos++] = tileno;
+ ((int*)buffer)[buffer_pos++] = precno;
+ ((int*)buffer)[buffer_pos++] = compno;
+ ((int*)buffer)[buffer_pos++] = resno;
+ ((int*)buffer)[buffer_pos++] = layno;
+ ((int*)buffer)[buffer_pos++] = start_pos;
+ ((int*)buffer)[buffer_pos++] = end_pos;
+ pack_nb++;
+ }
+ }
+ }/* x = x0..x1 */
+ }
+ } /* y = y0..y1 */
+ } /* precno */
+ } /* resno */
+ } /* compno */
+ } /* PCRL */
+ else { /* CPRL */
+
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {
+ /* I suppose components have same XRsiz, YRsiz */
+ int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
+ (float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
+ int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
+ (float)cstr_info->tw) * cstr_info->tile_y;
+ int x1 = x0 + cstr_info->tile_x;
+ int y1 = y0 + cstr_info->tile_y;
+
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {
+ int prec_max;
+ if (resno > cstr_info->numdecompos[compno]) {
+ break;
+ }
+ prec_max = cstr_info->tile[tileno].pw[resno] *
+ cstr_info->tile[tileno].ph[resno];
+ for (precno = 0; precno < prec_max; precno++) {
+ int pcnx = cstr_info->tile[tileno].pw[resno];
+ int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
+ cstr_info->numdecompos[compno] - resno);
+ int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
+ cstr_info->numdecompos[compno] - resno);
+ int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
+ int precno_y = (int) floor((float)precno / (float)pcnx);
+ for (y = y0; y < y1; y++) {
+ if (precno_y * pcy == y) {
+ for (x = x0; x < x1; x++) {
+ if (precno_x * pcx == x) {
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
+ ((int*)buffer)[buffer_pos++] = pack_nb;
+ ((int*)buffer)[buffer_pos++] = tileno;
+ ((int*)buffer)[buffer_pos++] = compno;
+ ((int*)buffer)[buffer_pos++] = precno;
+ ((int*)buffer)[buffer_pos++] = resno;
+ ((int*)buffer)[buffer_pos++] = layno;
+ ((int*)buffer)[buffer_pos++] = start_pos;
+ ((int*)buffer)[buffer_pos++] = end_pos;
+ pack_nb++;
+ }
+ }
+ }/* x = x0..x1 */
+ }
+ } /* y = y0..y1 */
+ } /* precno */
+ } /* resno */
+ } /* compno */
+ } /* CPRL */
+ } /* tileno */
+
+ if (buffer_pos > *buffer_size) {
+ /*opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);*/
+ fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n",
+ buffer_pos, *buffer_size);
+ return 0;
+ }
+
+ return --buffer;
+}
+
+
+
+
+/* --------------------------------------------------------------------------
+ ------------ Get the image byte[] from the Java object -------------------*/
+
+static opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env,
+ jobject obj, jclass cls)
+{
+ int i, max, shift, w, h, depth;
+ opj_image_t * img = NULL;
+ int compno, numcomps;
+ opj_image_t * image = NULL;
+ opj_image_comp_t *comp;
+ opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
+ OPJ_COLOR_SPACE color_space;
+ jfieldID fid;
+ jint ji;
+ jbyteArray jba;
+ jshortArray jsa;
+ jintArray jia;
+ int len;
+ jbyte *jbBody;
+ jshort *jsBody;
+ jint *jiBody;
+ jboolean isCopy;
+
+ /* Image width, height and depth*/
+ fid = (*env)->GetFieldID(env, cls, "width", "I");
+ ji = (*env)->GetIntField(env, obj, fid);
+ w = ji;
+
+ fid = (*env)->GetFieldID(env, cls, "height", "I");
+ ji = (*env)->GetIntField(env, obj, fid);
+ h = ji;
+
+ fid = (*env)->GetFieldID(env, cls, "depth", "I");
+ ji = (*env)->GetIntField(env, obj, fid);
+ depth = ji;
+
+ /* Read the image*/
+ if (depth <= 16) {
+ numcomps = 1;
+ color_space = CLRSPC_GRAY;
+ } else {
+ numcomps = 3;
+ color_space = CLRSPC_SRGB;
+ }
+ memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
+
+ if (numcomps == 1) {
+ cmptparm[0].x0 = parameters->image_offset_x0;
+ cmptparm[0].y0 = parameters->image_offset_y0;
+ cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 :
+ cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;
+ cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 :
+ cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;
+ /* Java types are always signed but we use them as unsigned types (shift of the negative part of
+ the pixels of the images in Telemis before entering the encoder).*/
+ cmptparm[0].sgnd = 0;
+ if (depth <= 16) {
+ cmptparm[0].prec = depth;
+ } else {
+ cmptparm[0].prec = 8;
+ }
+ cmptparm[0].bpp = cmptparm[0].prec;
+ cmptparm[0].dx = parameters->subsampling_dx;
+ cmptparm[0].dy = parameters->subsampling_dy;
+ /*printf("C: component 0 initialised: x0=%d, y0=%d, w=%d, h=%d, sgnd=%d, bpp=%d, dx=%d, dy=%d, color_space=%d\n", cmptparm[0].x0, cmptparm[0].y0, cmptparm[0].w,
+ cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/
+ } else {
+ for (i = 0; i < numcomps; i++) {
+ cmptparm[i].prec = 8;
+ cmptparm[i].bpp = 8;
+ cmptparm[i].sgnd = 0;
+ cmptparm[i].dx = parameters->subsampling_dx;
+ cmptparm[i].dy = parameters->subsampling_dy;
+ cmptparm[i].w = w;
+ cmptparm[i].h = h;
+ }
+ }
+
+ /* create the image */
+ image = opj_image_create(numcomps, &cmptparm[0], color_space);
+
+ if (!image) {
+ return NULL;
+ }
+
+ if (depth <= 16) {
+ image->numcomps = 1;
+ } else {
+ image->numcomps = 3;
+ }
+
+ /* set image offset and reference grid */
+ image->x0 = cmptparm[0].x0;
+ image->y0 = cmptparm[0].x0;
+ image->x1 = cmptparm[0].w;
+ image->y1 = cmptparm[0].h;
+
+ /* set image data */
+ for (compno = 0; compno < numcomps; compno++) {
+ comp = &image->comps[compno];
+ max = -100000;
+ if (depth == 8) {
+ fid = (*env)->GetFieldID(env, cls, "image8", "[B"); /* byteArray []*/
+ jba = (*env)->GetObjectField(env, obj, fid);
+ len = (*env)->GetArrayLength(env, jba);
+
+ jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
+ /*printf("C: before transferring 8 bpp image\n");*/
+ if (comp->sgnd) {
+ for (i = 0; i < len; i++) {
+ comp->data[i] = (char) jbBody[i];
+ if (comp->data[i] > max) {
+ max = comp->data[i];
+ }
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ comp->data[i] = (unsigned char) jbBody[i];
+ if (comp->data[i] > max) {
+ max = comp->data[i];
+ }
+ }
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
+ } else if (depth == 16) {
+ fid = (*env)->GetFieldID(env, cls, "image16", "[S"); /* shortArray []*/
+ jsa = (*env)->GetObjectField(env, obj, fid);
+ len = (*env)->GetArrayLength(env, jsa);
+
+ jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
+ /*printf("C: before transferring 16 bpp image\n");*/
+ if (comp->sgnd) { /* Special behaviour to deal with signed elements ??*/
+ comp->data[i] = (short) jsBody[i];
+ for (i = 0; i < len; i++) {
+ if (comp->data[i] > max) {
+ max = comp->data[i];
+ }
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ comp->data[i] = (unsigned short) jsBody[i];
+ if (comp->data[i] > max) {
+ max = comp->data[i];
+ }
+ }
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);
+ } else if (depth == 24) {
+ fid = (*env)->GetFieldID(env, cls, "image24", "[I"); /* intArray []*/
+ jia = (*env)->GetObjectField(env, obj, fid);
+ len = (*env)->GetArrayLength(env, jia);
+ shift = compno * 8;
+
+ jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
+ /*printf("C: before transferring 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);*/
+ if (comp->sgnd) { /* Special behaviour to deal with signed elements ?? XXXXX*/
+ for (i = 0; i < len; i++) {
+ comp->data[i] = (((int) jiBody[i]) & (0xFF << shift)) >> shift;
+ if (comp->data[i] > max) {
+ max = comp->data[i];
+ }
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ comp->data[i] = (((unsigned int) jiBody[i]) & (0xFF << shift)) >> shift;
+ if (comp->data[i] > max) {
+ max = comp->data[i];
+ }
+ }
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);
+ }
+ comp->bpp = int_floorlog2(max) + 1;
+ comp->prec = comp->bpp;
+ /*printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);*/
+ }
+ return image;
+}
+
+
+/* --------------------------------------------------------------------------
+ -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/
+JNIEXPORT jlong JNICALL
+Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env,
+ jobject obj, jobjectArray javaParameters)
+{
+ int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
+ char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */
+ opj_bool bSuccess;
+ opj_cparameters_t parameters; /* compression parameters */
+ img_fol_t img_fol;
+ opj_event_mgr_t event_mgr; /* event manager */
+ opj_image_t *image = NULL;
+ int i, j, num_images;
+ int imageno;
+ opj_codestream_info_t cstr_info; /* Codestream information structure */
+ char indexfilename[OPJ_PATH_LEN]; /* index file name */
+
+ char* compressed_index = NULL;
+ int compressed_index_size = -1;
+ /* ==> Access variables to the Java member variables*/
+ jsize arraySize;
+ jclass cls;
+ jobject object;
+ jboolean isCopy;
+ jfieldID fid;
+ jbyteArray jba;
+ jbyte *jbBody;
+ callback_variables_t msgErrorCallback_vars;
+ /* <== access variable to the Java member variables.*/
+
+ /* For the encoding and storage into the file*/
+ opj_cinfo_t* cinfo;
+ int codestream_length;
+ opj_cio_t *cio = NULL;
+ FILE *f = NULL;
+
+ /* JNI reference to the calling class*/
+ cls = (*env)->GetObjectClass(env, obj);
+
+ /* Pointers to be able to call a Java method for all the info and error messages*/
+ msgErrorCallback_vars.env = env;
+ msgErrorCallback_vars.jobj = &obj;
+ msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage",
+ "(Ljava/lang/String;)V");
+ msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError",
+ "(Ljava/lang/String;)V");
+
+ arraySize = (*env)->GetArrayLength(env, javaParameters);
+ argc = (int) arraySize + 1;
+ argv = opj_malloc(argc * sizeof(char*));
+ argv[0] = "ProgramName.exe"; /* The program name: useless*/
+ j = 0;
+ for (i = 1; i < argc; i++) {
+ object = (*env)->GetObjectArrayElement(env, javaParameters, i - 1);
+ argv[i] = (char*)(*env)->GetStringUTFChars(env, object, &isCopy);
+ }
+
+ /*printf("C: ");
+ for (i=0; i<argc; i++) {
+ printf("[%s]",argv[i]);
+ }
+ printf("\n");*/
+
+ /*
+ configure the event callbacks
+ */
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+ event_mgr.error_handler = error_callback;
+ event_mgr.warning_handler = warning_callback;
+ event_mgr.info_handler = info_callback;
+
+ /* set encoding parameters to default values */
+ opj_set_default_encoder_parameters(¶meters);
+ parameters.cod_format = J2K_CFMT;
+ /*parameters.index_on = 1;*/
+
+ /* Initialize indexfilename and img_fol */
+ *indexfilename = 0;
+ memset(&img_fol, 0, sizeof(img_fol_t));
+
+ /* parse input and get user encoding parameters */
+ if (parse_cmdline_encoder(argc, argv, ¶meters, &img_fol,
+ indexfilename) == 1) {
+ /* Release the Java arguments array*/
+ for (i = 1; i < argc; i++) {
+ (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env,
+ javaParameters, i - 1), argv[i]);
+ }
+ return -1;
+ }
+
+ /* Release the Java arguments array*/
+ for (i = 1; i < argc; i++) {
+ (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env,
+ javaParameters, i - 1), argv[i]);
+ }
+
+ if (parameters.cp_cinema) {
+ cinema_parameters(¶meters);
+ }
+
+
+ /* Create comment for codestream */
+ if (parameters.cp_comment == NULL) {
+ const char comment[] = "Created by JavaOpenJPEG version ";
+ const size_t clen = strlen(comment);
+ const char *version = opj_version();
+ /* UniPG>> */
+#ifdef USE_JPWL
+ parameters.cp_comment = (char*)opj_malloc(clen + strlen(version) + 11);
+ sprintf(parameters.cp_comment, "%s%s with JPWL", comment, version);
+#else
+ parameters.cp_comment = (char*)opj_malloc(clen + strlen(version) + 1);
+ sprintf(parameters.cp_comment, "%s%s", comment, version);
+#endif
+ /* <<UniPG */
+
+ }
+
+ /* Read directory if necessary */
+ num_images = 1;
+
+ /*Encoding image one by one*/
+ for (imageno = 0; imageno < num_images; imageno++) {
+ image = NULL;
+ fprintf(stderr, "\n");
+
+ image = loadImage(¶meters, env, obj, cls);
+ /*printf("C: after load image: image = %d\n", image);*/
+ if (!image) {
+ fprintf(stderr, "Unable to load image\n");
+ return -1;
+ }
+
+ /* Decide if MCT should be used */
+ parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
+
+ if (parameters.cp_cinema) {
+ cinema_setup_encoder(¶meters, image, &img_fol);
+ }
+
+ /* encode the destination image */
+ /* ---------------------------- */
+ /* get a J2K compressor handle */
+ if (parameters.cod_format == J2K_CFMT) { /* J2K format output */
+ cinfo = opj_create_compress(CODEC_J2K);
+ } else { /* JP2 format output */
+ cinfo = opj_create_compress(CODEC_JP2);
+ }
+ /* catch events using our callbacks and give a local context */
+ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);
+
+ /* setup the encoder parameters using the current image and user parameters */
+ opj_setup_encoder(cinfo, ¶meters, image);
+
+ /* open a byte stream for writing */
+ /* allocate memory for all tiles */
+ cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
+
+ /* encode the image */
+ bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
+ printf("C: after opj_encode_with_info\n");
+ if (!bSuccess) {
+ opj_cio_close(cio);
+ fprintf(stderr, "failed to encode image\n");
+ return -1;
+ }
+ codestream_length = cio_tell(cio);
+
+ /* write the index on disk, if needed (-x 'filename') */
+ if (*indexfilename) {
+ bSuccess = write_index_file(&cstr_info, indexfilename);
+ if (bSuccess) {
+ fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
+ }
+ }
+
+ compressed_index = create_index_into_byte_array(&cstr_info,
+ &compressed_index_size);
+ /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */
+ fid = (*env)->GetFieldID(env, cls, "compressedIndex", "[B");
+ jba = (*env)->NewByteArray(env, compressed_index_size + 1);
+ jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
+ memcpy(jbBody, compressed_index, compressed_index_size);
+ (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
+ (*env)->SetObjectField(env, obj, fid, jba);
+ opj_free(compressed_index);
+
+ /* write the generated codestream to disk ? */
+ if (parameters.outfile[0] != '\0') {
+ f = fopen(parameters.outfile, "wb");
+ if (!f) {
+ fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);
+ return -1;
+ }
+ fwrite(cio->buffer, 1, codestream_length, f);
+ fclose(f);
+ fprintf(stdout, "Generated outfile [%s]\n", parameters.outfile);
+ }
+
+ /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */
+ fid = (*env)->GetFieldID(env, cls, "compressedStream", "[B");
+ jba = (*env)->GetObjectField(env, obj, fid);
+ jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
+ memcpy(jbBody, cio->buffer, codestream_length);
+ (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
+
+ /* close and free the byte stream */
+ opj_cio_close(cio);
+
+ /* free remaining compression structures */
+ opj_destroy_compress(cinfo);
+ opj_destroy_cstr_info(&cstr_info);
+
+ /* free image data */
+ opj_image_destroy(image);
+ }
+
+ /* free user parameters structure */
+ if (parameters.cp_comment) {
+ opj_free(parameters.cp_comment);
+ }
+ if (parameters.cp_matrice) {
+ opj_free(parameters.cp_matrice);
+ }
+
+ return codestream_length;
+}
+