diff options
| author | Giuseppe Baruffa <gbaruffa@users.noreply.github.com> | 2007-08-02 12:45:28 +0000 |
|---|---|---|
| committer | Giuseppe Baruffa <gbaruffa@users.noreply.github.com> | 2007-08-02 12:45:28 +0000 |
| commit | 9cf692e89773ac83cebbb2969039913ce761c11d (patch) | |
| tree | b898526c52dc07cfe15c3f180d6ba4cbcf7320ab /OPJViewer/source/imagj2k.cpp | |
| parent | 4f4aa1d49fc261185085a86c80e8b06e46a7d5db (diff) | |
Added a basic saving capability to OPJViewer
Diffstat (limited to 'OPJViewer/source/imagj2k.cpp')
| -rw-r--r-- | OPJViewer/source/imagj2k.cpp | 264 |
1 files changed, 261 insertions, 3 deletions
diff --git a/OPJViewer/source/imagj2k.cpp b/OPJViewer/source/imagj2k.cpp index 7897ee3c..6dc57fac 100644 --- a/OPJViewer/source/imagj2k.cpp +++ b/OPJViewer/source/imagj2k.cpp @@ -231,17 +231,275 @@ bool wxJ2KHandler::LoadFile(wxImage *image, wxInputStream& stream, bool verbose, }
// save the j2k codestream
-bool wxJ2KHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )
+bool wxJ2KHandler::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;
+ int codestream_length;
+ bool bSuccess;
+ int i;
+
+ /*
+ 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 = j2k_error_callback;
+ event_mgr.warning_handler = j2k_warning_callback;
+ event_mgr.info_handler = j2k_info_callback;
+
+ /* set encoding parameters to default values */
+ opj_set_default_encoder_parameters(¶meters);
+
+ /* load parameters */
+
+ /* subsampling */
+ if (sscanf(m_subsampling.c_str(), wxT("%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("")) {
+ char *s1 = (char *) m_rates.c_str();
+ wxLogMessage("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("%d layers", parameters.tcp_numlayers);
+ parameters.cp_disto_alloc = 1;
+ }
+
+ /* image quality, dB */
+ if (m_rates == wxT("")) {
+ char *s2 = (char *) m_quality.c_str();
+ wxLogMessage("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("%d layers", parameters.tcp_numlayers);
+ parameters.cp_fixed_quality = 1;
+ }
+
+ /* image origin */
+ if (sscanf(m_origin.c_str(), "%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.c_str()) + 1);
+ if(parameters.cp_comment) {
+ strcpy(parameters.cp_comment, m_comment.c_str());
+ }
+ } else {
+ parameters.cp_comment = NULL;
+ }
+
+ /* indexing file */
+ if (m_enableidx) {
+ strncpy(parameters.index, m_index.c_str(), m_index.Len());
+ wxLogMessage("index file is %s", parameters.index);
+ parameters.index_on = 1;
+ } else {
+ parameters.index_on = 0;
+ }
+
+ /* 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.c_str(), "%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("!! 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.c_str(), "%d,%d", ¶meters.cp_tdx, ¶meters.cp_tdy);
+ parameters.tile_size_on = true;
+ }
+
+ /* tile origin */
+ if (sscanf(m_torigin.c_str(), "%d,%d", ¶meters.cp_tx0, ¶meters.cp_ty0) != 2) {
+ wxLogError("tile offset setting error: X0,Y0");
+ return false;
+ }
+
+ /* use SOP */
+ if (m_enablesop)
+ parameters.csty |= 0x02;
+
+ /* use EPH */
+ if (m_enableeph)
+ parameters.csty |= 0x04;
+
+
+
+ /* compression settings */
+ //parameters.tcp_numlayers = 1;
+ //parameters.tcp_rates[0] = 10.0;
+ //parameters.cp_disto_alloc = 1;
+ //parameters.irreversible = 1;
+ parameters.tcp_mct = 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++);
+ }
+
+ /* 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(cinfo, cio, oimage, parameters.index);
+ 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();
#endif /* __WXGTK__ */
- wxLogError(wxT("J2K: Couldn't save image -> not implemented."));
+
+ wxLogError(wxT("failed to encode image"));
+
+#ifndef __WXGTK__
+ wxMutexGuiLeave();
+#endif /* __WXGTK__ */
+
+ 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);
+
+ /* close and free the byte stream */
+ opj_cio_close(cio);
+
+ /* free remaining compression structures */
+ opj_destroy_compress(cinfo);
+
+ /* 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);
+
+#ifndef __WXGTK__
+ wxMutexGuiEnter();
+#endif /* __WXGTK__ */
+
+ wxLogMessage(wxT("J2K: Image encoded!"));
+
#ifndef __WXGTK__
wxMutexGuiLeave();
#endif /* __WXGTK__ */
- return false;
+ return true;
}
#ifdef __VISUALC__
|
