예제 #1
0
OpenJPEGWriter_write(J2K_USER_DATA *data, nrt_IOInterface *io, nrt_Error *error)
{
    OpenJPEGWriterImpl *impl = (OpenJPEGWriterImpl*) data;
    NRT_BOOL rc = NRT_SUCCESS;
    size_t compressedSize;

    memset(error->message, 0, NRT_MAX_EMESSAGE);
    if(!opj_set_error_handler(impl->codec,
                              OpenJPEG_errorHandler,
                              error))
    {
        nrt_Error_init(error, "Unable to set OpenJPEG error handler", NRT_CTXT,
                       NRT_ERR_UNK);
        goto CATCH_ERROR;
    }

    if (!opj_end_compress(impl->codec, impl->stream))
    {
        /*nrt_Error_init(error, "Error ending compression", NRT_CTXT,
          NRT_ERR_INVALID_OBJECT);*/
        goto CATCH_ERROR;
    }

    /* just copy/write the compressed data to the output IO */
    compressedSize = (size_t)nrt_IOInterface_tell(impl->compressed, error);
    if (!nrt_IOInterface_write(io, impl->compressedBuf, compressedSize, error))
    {
        nrt_Error_init(error, "Error writing data", NRT_CTXT,
                       NRT_ERR_INVALID_OBJECT);
        goto CATCH_ERROR;
    }

    goto CLEANUP;

    CATCH_ERROR:
    {
        rc = NRT_FAILURE;
    }

    CLEANUP:
    {
    }

    return rc;
}
예제 #2
0
void ossimOpjCompressor::finish()
{
   if ( m_stream )
   {
      // Every opj_start_compress must have an end.
      opj_end_compress( m_codec, m_stream );

      opj_stream_destroy( m_stream );
      m_stream = 0;
   }
   if ( m_codec )
   {
      opj_destroy_codec( m_codec );
      m_codec = 0;
   }
   if ( m_image )
   {
      opj_image_destroy( m_image );
      m_image = 0;
   }
}
예제 #3
0
int main (int argc, char *argv[])
{
	opj_cparameters_t l_param;
	opj_codec_t * l_codec;
	opj_image_t * l_image;
	opj_image_cmptparm_t l_params [NUM_COMPS_MAX];
	opj_stream_t * l_stream;
	OPJ_UINT32 l_nb_tiles;
	OPJ_UINT32 l_data_size;
	unsigned char len;

#ifdef USING_MCT
	const OPJ_FLOAT32 l_mct [] =
	{
		1 , 0 , 0 ,
		0 , 1 , 0 ,
		0 , 0 , 1
	};

	const OPJ_INT32 l_offsets [] =
	{
		128 , 128 , 128
	};
#endif

	opj_image_cmptparm_t * l_current_param_ptr;
	OPJ_UINT32 i;
	OPJ_BYTE *l_data;

  OPJ_UINT32 num_comps;
  int image_width;
  int image_height;
  int tile_width;
  int tile_height;
  int comp_prec;
  int irreversible;
  char output_file[64];

  /* should be test_tile_encoder 3 2000 2000 1000 1000 8 tte1.j2k */
  if( argc == 9 )
    {
    num_comps = (OPJ_UINT32)atoi( argv[1] );
    image_width = atoi( argv[2] );
    image_height = atoi( argv[3] );
    tile_width = atoi( argv[4] );
    tile_height = atoi( argv[5] );
    comp_prec = atoi( argv[6] );
    irreversible = atoi( argv[7] );
    strcpy(output_file, argv[8] );
    }
  else
    {
    num_comps = 3;
    image_width = 2000;
    image_height = 2000;
    tile_width = 1000;
    tile_height = 1000;
    comp_prec = 8;
    irreversible = 1;
    strcpy(output_file, "test.j2k" );
    }
  if( num_comps > NUM_COMPS_MAX )
    {
    return 1;
    }
	l_nb_tiles = (OPJ_UINT32)(image_width/tile_width) * (OPJ_UINT32)(image_height/tile_height);
	l_data_size = (OPJ_UINT32)tile_width * (OPJ_UINT32)tile_height * (OPJ_UINT32)num_comps * (OPJ_UINT32)(comp_prec/8);

	l_data = (OPJ_BYTE*) malloc(l_data_size * sizeof(OPJ_BYTE));

	fprintf(stdout, "Encoding random values -> keep in mind that this is very hard to compress\n");
	for (i=0;i<l_data_size;++i)	{
		l_data[i] = (OPJ_BYTE)i; /*rand();*/
	}

	opj_set_default_encoder_parameters(&l_param);
	/** you may here add custom encoding parameters */
	/* rate specifications */
	/** number of quality layers in the stream */
	l_param.tcp_numlayers = 1;
	l_param.cp_fixed_quality = 1;
	l_param.tcp_distoratio[0] = 20;
	/* is using others way of calculation */
	/* l_param.cp_disto_alloc = 1 or l_param.cp_fixed_alloc = 1 */
	/* l_param.tcp_rates[0] = ... */


	/* tile definitions parameters */
	/* position of the tile grid aligned with the image */
	l_param.cp_tx0 = 0;
	l_param.cp_ty0 = 0;
	/* tile size, we are using tile based encoding */
	l_param.tile_size_on = OPJ_TRUE;
	l_param.cp_tdx = tile_width;
	l_param.cp_tdy = tile_height;

	/* use irreversible encoding ?*/
	l_param.irreversible = irreversible;

	/* do not bother with mct, the rsiz is set when calling opj_set_MCT*/
	/*l_param.cp_rsiz = OPJ_STD_RSIZ;*/

	/* no cinema */
	/*l_param.cp_cinema = 0;*/

	/* no not bother using SOP or EPH markers, do not use custom size precinct */
	/* number of precincts to specify */
	/* l_param.csty = 0;*/
	/* l_param.res_spec = ... */
	/* l_param.prch_init[i] = .. */
	/* l_param.prcw_init[i] = .. */


	/* do not use progression order changes */
	/*l_param.numpocs = 0;*/
	/* l_param.POC[i].... */

	/* do not restrain the size for a component.*/
	/* l_param.max_comp_size = 0; */

	/** block encoding style for each component, do not use at the moment */
	/** J2K_CCP_CBLKSTY_TERMALL, J2K_CCP_CBLKSTY_LAZY, J2K_CCP_CBLKSTY_VSC, J2K_CCP_CBLKSTY_SEGSYM, J2K_CCP_CBLKSTY_RESET */
	/* l_param.mode = 0;*/

	/** number of resolutions */
	l_param.numresolution = 6;

	/** progression order to use*/
	/** OPJ_LRCP, OPJ_RLCP, OPJ_RPCL, PCRL, CPRL */
	l_param.prog_order = OPJ_LRCP;

	/** no "region" of interest, more precisally component */
	/* l_param.roi_compno = -1; */
	/* l_param.roi_shift = 0; */

	/* we are not using multiple tile parts for a tile. */
	/* l_param.tp_on = 0; */
	/* l_param.tp_flag = 0; */

	/* if we are using mct */
#ifdef USING_MCT
	opj_set_MCT(&l_param,l_mct,l_offsets,NUM_COMPS);
#endif


	/* image definition */
	l_current_param_ptr = l_params;
	for (i=0;i<num_comps;++i) {
		/* do not bother bpp useless */
		/*l_current_param_ptr->bpp = COMP_PREC;*/
		l_current_param_ptr->dx = 1;
		l_current_param_ptr->dy = 1;

		l_current_param_ptr->h = (OPJ_UINT32)image_height;
		l_current_param_ptr->w = (OPJ_UINT32)image_width;

		l_current_param_ptr->sgnd = 0;
		l_current_param_ptr->prec = (OPJ_UINT32)comp_prec;

		l_current_param_ptr->x0 = 0;
		l_current_param_ptr->y0 = 0;

		++l_current_param_ptr;
	}

  /* should we do j2k or jp2 ?*/
  len = (unsigned char)strlen( output_file );
  if( strcmp( output_file + len - 4, ".jp2" ) == 0 )
    {
    l_codec = opj_create_compress(OPJ_CODEC_JP2);
    }
  else
    {
    l_codec = opj_create_compress(OPJ_CODEC_J2K);
    }
	if (!l_codec) {
		return 1;
	}

	/* catch events using our callbacks and give a local context */
	opj_set_info_handler(l_codec, info_callback,00);
	opj_set_warning_handler(l_codec, warning_callback,00);
	opj_set_error_handler(l_codec, error_callback,00);

	l_image = opj_image_tile_create(num_comps,l_params,OPJ_CLRSPC_SRGB);
	if (! l_image) {
		opj_destroy_codec(l_codec);
		return 1;
	}

	l_image->x0 = 0;
	l_image->y0 = 0;
	l_image->x1 = (OPJ_UINT32)image_width;
	l_image->y1 = (OPJ_UINT32)image_height;
	l_image->color_space = OPJ_CLRSPC_SRGB;

	if (! opj_setup_encoder(l_codec,&l_param,l_image)) {
		fprintf(stderr, "ERROR -> test_tile_encoder: failed to setup the codec!\n");
		opj_destroy_codec(l_codec);
		opj_image_destroy(l_image);
		return 1;
	}

	l_stream = opj_stream_create_default_file_stream_v3(output_file, OPJ_FALSE);
    if (! l_stream) {
		fprintf(stderr, "ERROR -> test_tile_encoder: failed to create the stream from the output file %s !\n",output_file );
		opj_destroy_codec(l_codec);
		opj_image_destroy(l_image);
		return 1;
	}

	if (! opj_start_compress(l_codec,l_image,l_stream)) {
		fprintf(stderr, "ERROR -> test_tile_encoder: failed to start compress!\n");
		opj_stream_destroy_v3(l_stream);
		opj_destroy_codec(l_codec);
		opj_image_destroy(l_image);
		return 1;
	}

	for (i=0;i<l_nb_tiles;++i) {
		if (! opj_write_tile(l_codec,i,l_data,l_data_size,l_stream)) {
			fprintf(stderr, "ERROR -> test_tile_encoder: failed to write the tile %d!\n",i);
			opj_stream_destroy_v3(l_stream);
			opj_destroy_codec(l_codec);
			opj_image_destroy(l_image);
			return 1;
		}
	}

	if (! opj_end_compress(l_codec,l_stream)) {
		fprintf(stderr, "ERROR -> test_tile_encoder: failed to end compress!\n");
		opj_stream_destroy_v3(l_stream);
		opj_destroy_codec(l_codec);
		opj_image_destroy(l_image);
		return 1;
	}

	opj_stream_destroy_v3(l_stream);
	opj_destroy_codec(l_codec);
	opj_image_destroy(l_image);

	free(l_data);

	/* Print profiling*/
	/*PROFPRINT();*/

	return 0;
}
예제 #4
0
static GstFlowReturn
gst_openjpeg_enc_handle_frame (GstVideoEncoder * encoder,
    GstVideoCodecFrame * frame)
{
  GstOpenJPEGEnc *self = GST_OPENJPEG_ENC (encoder);
  GstFlowReturn ret = GST_FLOW_OK;
#ifdef HAVE_OPENJPEG_1
  opj_cinfo_t *enc;
  GstMapInfo map;
  guint length;
  opj_cio_t *io;
#else
  opj_codec_t *enc;
  opj_stream_t *stream;
  MemStream mstream;
#endif
  opj_image_t *image;
  GstVideoFrame vframe;

  GST_DEBUG_OBJECT (self, "Handling frame");

  enc = opj_create_compress (self->codec_format);
  if (!enc)
    goto initialization_error;

#ifdef HAVE_OPENJPEG_1
  if (G_UNLIKELY (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >=
          GST_LEVEL_TRACE)) {
    opj_event_mgr_t callbacks;

    callbacks.error_handler = gst_openjpeg_enc_opj_error;
    callbacks.warning_handler = gst_openjpeg_enc_opj_warning;
    callbacks.info_handler = gst_openjpeg_enc_opj_info;
    opj_set_event_mgr ((opj_common_ptr) enc, &callbacks, self);
  } else {
    opj_set_event_mgr ((opj_common_ptr) enc, NULL, NULL);
  }
#else
  if (G_UNLIKELY (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >=
          GST_LEVEL_TRACE)) {
    opj_set_info_handler (enc, gst_openjpeg_enc_opj_info, self);
    opj_set_warning_handler (enc, gst_openjpeg_enc_opj_warning, self);
    opj_set_error_handler (enc, gst_openjpeg_enc_opj_error, self);
  } else {
    opj_set_info_handler (enc, NULL, NULL);
    opj_set_warning_handler (enc, NULL, NULL);
    opj_set_error_handler (enc, NULL, NULL);
  }
#endif

  if (!gst_video_frame_map (&vframe, &self->input_state->info,
          frame->input_buffer, GST_MAP_READ))
    goto map_read_error;

  image = gst_openjpeg_enc_fill_image (self, &vframe);
  if (!image)
    goto fill_image_error;
  gst_video_frame_unmap (&vframe);

  opj_setup_encoder (enc, &self->params, image);

#ifdef HAVE_OPENJPEG_1
  io = opj_cio_open ((opj_common_ptr) enc, NULL, 0);
  if (!io)
    goto open_error;

  if (!opj_encode (enc, io, image, NULL))
    goto encode_error;

  opj_image_destroy (image);

  length = cio_tell (io);

  ret =
      gst_video_encoder_allocate_output_frame (encoder, frame,
      length + (self->is_jp2c ? 8 : 0));
  if (ret != GST_FLOW_OK)
    goto allocate_error;

  gst_buffer_fill (frame->output_buffer, self->is_jp2c ? 8 : 0, io->buffer,
      length);
  if (self->is_jp2c) {
    gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
    GST_WRITE_UINT32_BE (map.data, length + 8);
    GST_WRITE_UINT32_BE (map.data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c'));
    gst_buffer_unmap (frame->output_buffer, &map);
  }

  opj_cio_close (io);
  opj_destroy_compress (enc);
#else
  stream = opj_stream_create (4096, OPJ_FALSE);
  if (!stream)
    goto open_error;

  mstream.allocsize = 4096;
  mstream.data = g_malloc (mstream.allocsize);
  mstream.offset = 0;
  mstream.size = 0;

  opj_stream_set_read_function (stream, read_fn);
  opj_stream_set_write_function (stream, write_fn);
  opj_stream_set_skip_function (stream, skip_fn);
  opj_stream_set_seek_function (stream, seek_fn);
  opj_stream_set_user_data (stream, &mstream);
  opj_stream_set_user_data_length (stream, mstream.size);

  if (!opj_start_compress (enc, image, stream))
    goto encode_error;

  if (!opj_encode (enc, stream))
    goto encode_error;

  if (!opj_end_compress (enc, stream))
    goto encode_error;

  opj_image_destroy (image);
  opj_stream_destroy (stream);
  opj_destroy_codec (enc);

  frame->output_buffer = gst_buffer_new ();

  if (self->is_jp2c) {
    GstMapInfo map;
    GstMemory *mem;

    mem = gst_allocator_alloc (NULL, 8, NULL);
    gst_memory_map (mem, &map, GST_MAP_WRITE);
    GST_WRITE_UINT32_BE (map.data, mstream.size + 8);
    GST_WRITE_UINT32_BE (map.data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c'));
    gst_memory_unmap (mem, &map);
    gst_buffer_append_memory (frame->output_buffer, mem);
  }

  gst_buffer_append_memory (frame->output_buffer,
      gst_memory_new_wrapped (0, mstream.data, mstream.allocsize, 0,
          mstream.size, NULL, (GDestroyNotify) g_free));
#endif

  ret = gst_video_encoder_finish_frame (encoder, frame);

  return ret;

initialization_error:
  {
    gst_video_codec_frame_unref (frame);
    GST_ELEMENT_ERROR (self, LIBRARY, INIT,
        ("Failed to initialize OpenJPEG encoder"), (NULL));
    return GST_FLOW_ERROR;
  }
map_read_error:
  {
#ifdef HAVE_OPENJPEG_1
    opj_destroy_compress (enc);
#else
    opj_destroy_codec (enc);
#endif
    gst_video_codec_frame_unref (frame);

    GST_ELEMENT_ERROR (self, CORE, FAILED,
        ("Failed to map input buffer"), (NULL));
    return GST_FLOW_ERROR;
  }
fill_image_error:
  {
#ifdef HAVE_OPENJPEG_1
    opj_destroy_compress (enc);
#else
    opj_destroy_codec (enc);
#endif
    gst_video_frame_unmap (&vframe);
    gst_video_codec_frame_unref (frame);

    GST_ELEMENT_ERROR (self, LIBRARY, INIT,
        ("Failed to fill OpenJPEG image"), (NULL));
    return GST_FLOW_ERROR;
  }
open_error:
  {
    opj_image_destroy (image);
#ifdef HAVE_OPENJPEG_1
    opj_destroy_compress (enc);
#else
    opj_destroy_codec (enc);
#endif
    gst_video_codec_frame_unref (frame);

    GST_ELEMENT_ERROR (self, LIBRARY, INIT,
        ("Failed to open OpenJPEG data"), (NULL));
    return GST_FLOW_ERROR;
  }
encode_error:
  {
#ifdef HAVE_OPENJPEG_1
    opj_cio_close (io);
    opj_image_destroy (image);
    opj_destroy_compress (enc);
#else
    opj_stream_destroy (stream);
    g_free (mstream.data);
    opj_image_destroy (image);
    opj_destroy_codec (enc);
#endif
    gst_video_codec_frame_unref (frame);

    GST_ELEMENT_ERROR (self, STREAM, ENCODE,
        ("Failed to encode OpenJPEG stream"), (NULL));
    return GST_FLOW_ERROR;
  }
#ifdef HAVE_OPENJPEG_1
allocate_error:
  {
    opj_cio_close (io);
    opj_destroy_compress (enc);
    gst_video_codec_frame_unref (frame);

    GST_ELEMENT_ERROR (self, CORE, FAILED,
        ("Failed to allocate output buffer"), (NULL));
    return ret;
  }
#endif
}
예제 #5
0
OFCondition DJCompressJP2K::encode( 
  Uint16 columns,
  Uint16 rows,
  EP_Interpretation colorSpace,
  Uint16 samplesPerPixel,
  Uint16 * image_buffer,
  Uint16 * & to,
  Uint32 & length,
  Uint8 bitsAllocated,
  Uint8 pixelRepresentation,
  double minUsed, double maxUsed)
{
	int bitsstored = bitsAllocated;
	
    if( samplesPerPixel > 1)
        bitsstored = bitsAllocated = 8;
    
	OFBool isSigned = pixelRepresentation;
	
	if( bitsAllocated >= 16)
	{
		int amplitude = maxUsed;
		
		if( minUsed < 0)
			amplitude -= minUsed;
		
		int bits = 1, value = 2;
		
		while( value < amplitude && bits <= 16)
		{
			value *= 2;
			bits++;
		}
		
		if( minUsed < 0) // K A10009536850 22.06.12
			bits++;
		
		if( bits < 9)
			bits = 9;
		
		// avoid the artifacts... switch to lossless
		if( (maxUsed >= 32000 && minUsed <= -32000) || maxUsed >= 65000 || bits > 16)
			quality = 0;
		
		if( bits > 16) bits = 16;
		
		bitsstored = bits;
	}
    opj_cparameters_t parameters;
    opj_image_t *image = NULL;
		
//    printf( "JP2K OPJ-DCMTK-Encode ");
		
    opj_set_default_encoder_parameters(&parameters);

    parameters.tcp_numlayers = 1;
    parameters.cp_disto_alloc = 1;
		
    switch( quality)
    {
    case 0: // DCMLosslessQuality
        parameters.tcp_rates[0] = 0;
        break;
            
    case 1: // DCMHighQuality
        parameters.tcp_rates[0] = 4;
        break;
            
    case 2: // DCMMediumQuality
        if( columns <= 600 || rows <= 600)
            parameters.tcp_rates[0] = 6;
        else
            parameters.tcp_rates[0] = 8;
        break;
            
    case 3: // DCMLowQuality
        parameters.tcp_rates[0] = 16;
        break;
            
    default:
        //printf( "****** warning unknown compression rate -> MediumQuality : %d", quality);
        if( columns <= 600 || rows <= 600)
            parameters.tcp_rates[0] = 6;
        else
            parameters.tcp_rates[0] = 8;
        break;
    }

    int image_width = columns;
    int image_height = rows;
    int sample_pixel = samplesPerPixel;

    if (colorSpace == EPI_Monochrome1 || colorSpace == EPI_Monochrome2)
    {

    }
    else
    {
        if( sample_pixel != 3)
            printf( "*** RGB Photometric?, but... SamplesPerPixel != 3 ?");
        sample_pixel = 3;
    }

    image = rawtoimage( (char *)image_buffer, &parameters,  static_cast<int>( columns*rows*samplesPerPixel*bitsAllocated/8),  image_width, image_height, sample_pixel, bitsAllocated, bitsstored, isSigned, quality, 0);

    if(!image) {
        fprintf(stderr, "Unable to load buffer image\n");
        return EC_Normal;
    } 
        
    parameters.cod_format = 0; /* J2K format output */
    int codestream_length;

    opj_codec_t *l_codec = 00;
    l_codec = opj_create_compress(OPJ_CODEC_J2K);
    opj_set_info_handler(l_codec, info_callback,00);
    opj_set_warning_handler(l_codec, warning_callback,00);
    opj_set_error_handler(l_codec, error_callback,00);

    /* setup the encoder parameters using the current image and using user parameters */
    opj_setup_encoder(l_codec, &parameters, image);

    char * l_out;
    size_t l_size;
    FILE * l_file = open_memstream(&l_out, &l_size);

    opj_stream_t * l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, OPJ_FALSE);
    if (! l_stream){
        fprintf(stderr, "failed to create stream\n");
        return EC_Normal;
    }

    opj_stream_set_user_data(l_stream, l_file, (opj_stream_free_user_data_fn)NULL);
    opj_stream_set_write_function(l_stream, (opj_stream_write_fn)_write);
    /* encode the image */
    int bSuccess = opj_start_compress(l_codec, image, l_stream);
    if (!bSuccess) {
        fprintf(stderr, "failed to encode image\n");
        return EC_Normal;
    }

    bSuccess = bSuccess && opj_encode(l_codec, l_stream);
    if (!bSuccess) {
        opj_stream_destroy(l_stream);
        opj_destroy_codec(l_codec);
        opj_image_destroy(image);
        fprintf(stderr, "failed to encode image 2\n");
        remove(parameters.outfile);
        return EC_Normal;
    }

    bSuccess = bSuccess && opj_end_compress(l_codec, l_stream);
    if (!bSuccess)  {
        fprintf(stderr, "failed to encode image: opj_end_compress\n");
        return EC_Normal;
    }

    /* l_file memstream must be flushed to allow accessint to l_out and l_size values */
    fflush(l_file);
#ifdef _WIN32
	get_buffer_and_size(l_file);
#endif
    fclose(l_file);
    /* copy compressed stream to "to" UINT8*  */
    to = new Uint16[l_size];
    memcpy( to, l_out, l_size);
    length = l_size;

    /* free remaining compression structures */
    free(l_out);
    opj_stream_destroy(l_stream);
    opj_destroy_codec(l_codec);
    opj_image_destroy(image);
//	}
    return EC_Normal;
}
예제 #6
0
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	J2KFIO_t *fio = (J2KFIO_t*)data;
	if (dib && handle && fio) {
		BOOL bSuccess;
		opj_codec_t *c_codec = NULL;	// handle to a compressor
		opj_cparameters_t parameters;	// compression parameters
		opj_image_t *image = NULL;		// image to encode

		// get the OpenJPEG stream
		opj_stream_t *c_stream = fio->stream;

		// set encoding parameters to default values
		opj_set_default_encoder_parameters(&parameters);

		try {
			parameters.tcp_numlayers = 0;
			// if no rate entered, apply a 16:1 rate by default
			if(flags == J2K_DEFAULT) {
				parameters.tcp_rates[0] = (float)16;
			} else {
				// for now, the flags parameter is only used to specify the rate
				parameters.tcp_rates[0] = (float)(flags & 0x3FF);
			}
			parameters.tcp_numlayers++;
			parameters.cp_disto_alloc = 1;

			// convert the dib to a OpenJPEG image
			image = FIBITMAPToJ2KImage(s_format_id, dib, &parameters);
			if(!image) {
				return FALSE;
			}

			// decide if MCT should be used
			parameters.tcp_mct = (image->numcomps == 3) ? 1 : 0;

			// encode the destination image

			// get a J2K compressor handle
			c_codec = opj_create_compress(OPJ_CODEC_J2K);

			// configure the event callbacks
			// catch events using our callbacks (no local context needed here)
			opj_set_info_handler(c_codec, NULL, NULL);
			opj_set_warning_handler(c_codec, j2k_warning_callback, NULL);
			opj_set_error_handler(c_codec, j2k_error_callback, NULL);

			// setup the encoder parameters using the current image and using user parameters
			opj_setup_encoder(c_codec, &parameters, image);

			// encode the image
			bSuccess = opj_start_compress(c_codec, image, c_stream);
			if(bSuccess) {
				bSuccess = bSuccess && opj_encode(c_codec, c_stream);
				if(bSuccess) {
					bSuccess = bSuccess && opj_end_compress(c_codec, c_stream);
				}
			}
			if (!bSuccess) {
				throw "Failed to encode image";
			}

			// free remaining compression structures
			opj_destroy_codec(c_codec);
			
			// free image data
			opj_image_destroy(image);

			return TRUE;

		} catch (const char *text) {
			if(c_codec) opj_destroy_codec(c_codec);
			if(image) opj_image_destroy(image);
			FreeImage_OutputMessageProc(s_format_id, text);
			return FALSE;
		}
	}

	return FALSE;
}
예제 #7
0
static int
j2k_encode_entry(Imaging im, ImagingCodecState state,
                 ImagingIncrementalCodec encoder)
{
    JPEG2KENCODESTATE *context = (JPEG2KENCODESTATE *)state->context;
    opj_stream_t *stream = NULL;
    opj_image_t *image = NULL;
    opj_codec_t *codec = NULL;
    opj_cparameters_t params;
    unsigned components;
    OPJ_COLOR_SPACE color_space;
    opj_image_cmptparm_t image_params[4];
    unsigned xsiz, ysiz;
    unsigned tile_width, tile_height;
    unsigned tiles_x, tiles_y, num_tiles;
    unsigned x, y, tile_ndx;
    unsigned n;
    j2k_pack_tile_t pack;
    int ret = -1;

    stream = opj_stream_default_create(OPJ_FALSE);

    if (!stream) {
        state->errcode = IMAGING_CODEC_BROKEN;
        state->state = J2K_STATE_FAILED;
        goto quick_exit;
    }

    opj_stream_set_write_function(stream, j2k_write);
    opj_stream_set_skip_function(stream, j2k_skip);
    opj_stream_set_seek_function(stream, j2k_seek);

    opj_stream_set_user_data(stream, encoder);

    /* Setup an opj_image */
    if (strcmp (im->mode, "L") == 0) {
        components = 1;
        color_space = OPJ_CLRSPC_GRAY;
        pack = j2k_pack_l;
    } else if (strcmp (im->mode, "LA") == 0) {
        components = 2;
        color_space = OPJ_CLRSPC_GRAY;
        pack = j2k_pack_la;
    } else if (strcmp (im->mode, "RGB") == 0) {
        components = 3;
        color_space = OPJ_CLRSPC_SRGB;
        pack = j2k_pack_rgb;
    } else if (strcmp (im->mode, "YCbCr") == 0) {
        components = 3;
        color_space = OPJ_CLRSPC_SYCC;
        pack = j2k_pack_rgb;
    } else if (strcmp (im->mode, "RGBA") == 0) {
        components = 4;
        color_space = OPJ_CLRSPC_SRGB;
        pack = j2k_pack_rgba;
    } else {
        state->errcode = IMAGING_CODEC_BROKEN;
        state->state = J2K_STATE_FAILED;
        goto quick_exit;
    }

    for (n = 0; n < components; ++n) {
        image_params[n].dx = image_params[n].dy = 1;
        image_params[n].w = im->xsize;
        image_params[n].h = im->ysize;
        image_params[n].x0 = image_params[n].y0 = 0;
        image_params[n].prec = 8;
        image_params[n].bpp = 8;
        image_params[n].sgnd = 0;
    }

    image = opj_image_create(components, image_params, color_space);

    /* Setup compression context */
    context->error_msg = NULL;

    opj_set_default_encoder_parameters(&params);

    params.image_offset_x0 = context->offset_x;
    params.image_offset_y0 = context->offset_y;

    if (context->tile_size_x && context->tile_size_y) {
        params.tile_size_on = OPJ_TRUE;
        params.cp_tx0 = context->tile_offset_x;
        params.cp_ty0 = context->tile_offset_y;
        params.cp_tdx = context->tile_size_x;
        params.cp_tdy = context->tile_size_y;

        tile_width = params.cp_tdx;
        tile_height = params.cp_tdy;
    } else {
        params.cp_tx0 = 0;
        params.cp_ty0 = 0;
        params.cp_tdx = 1;
        params.cp_tdy = 1;

        tile_width = im->xsize;
        tile_height = im->ysize;
    }

    if (context->quality_layers && PySequence_Check(context->quality_layers)) {
        Py_ssize_t len = PySequence_Length(context->quality_layers);
        Py_ssize_t n;
        float *pq;

        if (len) {
            if (len > sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0]))
                len = sizeof(params.tcp_rates)/sizeof(params.tcp_rates[0]);

            params.tcp_numlayers = (int)len;

            if (context->quality_is_in_db) {
                params.cp_disto_alloc = params.cp_fixed_alloc = 0;
                params.cp_fixed_quality = 1;
                pq = params.tcp_distoratio;
            } else {
                params.cp_disto_alloc = 1;
                params.cp_fixed_alloc = params.cp_fixed_quality = 0;
                pq = params.tcp_rates;
            }

            for (n = 0; n < len; ++n) {
                PyObject *obj = PySequence_ITEM(context->quality_layers, n);
                pq[n] = PyFloat_AsDouble(obj);
            }
        }
    } else {
        params.tcp_numlayers = 1;
        params.tcp_rates[0] = 0;
        params.cp_disto_alloc = 1;
    }

    if (context->num_resolutions)
        params.numresolution = context->num_resolutions;

    if (context->cblk_width >= 4 && context->cblk_width <= 1024
            && context->cblk_height >= 4 && context->cblk_height <= 1024
            && context->cblk_width * context->cblk_height <= 4096) {
        params.cblockw_init = context->cblk_width;
        params.cblockh_init = context->cblk_height;
    }

    if (context->precinct_width >= 4 && context->precinct_height >= 4
            && context->precinct_width >= context->cblk_width
            && context->precinct_height > context->cblk_height) {
        params.prcw_init[0] = context->precinct_width;
        params.prch_init[0] = context->precinct_height;
        params.res_spec = 1;
        params.csty |= 0x01;
    }

    params.irreversible = context->irreversible;

    params.prog_order = context->progression;

    params.cp_cinema = context->cinema_mode;

    switch (params.cp_cinema) {
    case OPJ_OFF:
        params.cp_rsiz = OPJ_STD_RSIZ;
        break;
    case OPJ_CINEMA2K_24:
    case OPJ_CINEMA2K_48:
        params.cp_rsiz = OPJ_CINEMA2K;
        if (params.numresolution > 6)
            params.numresolution = 6;
        break;
    case OPJ_CINEMA4K_24:
        params.cp_rsiz = OPJ_CINEMA4K;
        if (params.numresolution > 7)
            params.numresolution = 7;
        break;
    }

    if (context->cinema_mode != OPJ_OFF)
        j2k_set_cinema_params(im, components, &params);

    /* Set up the reference grid in the image */
    image->x0 = params.image_offset_x0;
    image->y0 = params.image_offset_y0;
    image->x1 = xsiz = im->xsize + params.image_offset_x0;
    image->y1 = ysiz = im->ysize + params.image_offset_y0;

    /* Create the compressor */
    codec = opj_create_compress(context->format);

    if (!codec) {
        state->errcode = IMAGING_CODEC_BROKEN;
        state->state = J2K_STATE_FAILED;
        goto quick_exit;
    }

    opj_set_error_handler(codec, j2k_error, context);
    opj_setup_encoder(codec, &params, image);

    /* Start encoding */
    if (!opj_start_compress(codec, image, stream)) {
        state->errcode = IMAGING_CODEC_BROKEN;
        state->state = J2K_STATE_FAILED;
        goto quick_exit;
    }

    /* Write each tile */
    tiles_x = (im->xsize + (params.image_offset_x0 - params.cp_tx0)
               + tile_width - 1) / tile_width;
    tiles_y = (im->ysize + (params.image_offset_y0 - params.cp_ty0)
               + tile_height - 1) / tile_height;

    num_tiles = tiles_x * tiles_y;

    state->buffer = malloc (tile_width * tile_height * components);

    tile_ndx = 0;
    for (y = 0; y < tiles_y; ++y) {
        unsigned ty0 = params.cp_ty0 + y * tile_height;
        unsigned ty1 = ty0 + tile_height;
        unsigned pixy, pixh;

        if (ty0 < params.image_offset_y0)
            ty0 = params.image_offset_y0;
        if (ty1 > ysiz)
            ty1 = ysiz;

        pixy = ty0 - params.image_offset_y0;
        pixh = ty1 - ty0;

        for (x = 0; x < tiles_x; ++x) {
            unsigned tx0 = params.cp_tx0 + x * tile_width;
            unsigned tx1 = tx0 + tile_width;
            unsigned pixx, pixw;
            unsigned data_size;

            if (tx0 < params.image_offset_x0)
                tx0 = params.image_offset_x0;
            if (tx1 > xsiz)
                tx1 = xsiz;

            pixx = tx0 - params.image_offset_x0;
            pixw = tx1 - tx0;

            pack(im, state->buffer, pixx, pixy, pixw, pixh);

            data_size = pixw * pixh * components;

            if (!opj_write_tile(codec, tile_ndx++, state->buffer,
                                data_size, stream)) {
                state->errcode = IMAGING_CODEC_BROKEN;
                state->state = J2K_STATE_FAILED;
                goto quick_exit;
            }
        }
    }

    if (!opj_end_compress(codec, stream)) {
        state->errcode = IMAGING_CODEC_BROKEN;
        state->state = J2K_STATE_FAILED;
        goto quick_exit;
    }

    state->errcode = IMAGING_CODEC_END;
    state->state = J2K_STATE_DONE;
    ret = (int)ImagingIncrementalCodecBytesInBuffer(encoder);

quick_exit:
    if (codec)
        opj_destroy_codec(codec);
    if (image)
        opj_image_destroy(image);
    if (stream)
        opj_stream_destroy(stream);

    return ret;
}
예제 #8
0
int main(int argc, char *argv[])
{
  const char * v = opj_version();

  const OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_GRAY;
  unsigned int numcomps = 1;
  unsigned int i;
  unsigned int image_width = 256;
  unsigned int image_height = 256;

  opj_cparameters_t parameters;

  unsigned int subsampling_dx;
  unsigned int subsampling_dy;
  const char outputfile[] = "testempty2.j2k";

  opj_image_cmptparm_t cmptparm;
  opj_image_t *image;
  opj_codec_t* l_codec = 00;
  OPJ_BOOL bSuccess;
  opj_stream_t *l_stream = 00;
  (void)argc;
  (void)argv;

  opj_set_default_encoder_parameters(&parameters);
  parameters.cod_format = J2K_CFMT;
  puts(v);
  subsampling_dx = (unsigned int)parameters.subsampling_dx;
  subsampling_dy = (unsigned int)parameters.subsampling_dy;
  cmptparm.prec = 8;
  cmptparm.bpp = 8;
  cmptparm.sgnd = 0;
  cmptparm.dx = subsampling_dx;
  cmptparm.dy = subsampling_dy;
  cmptparm.w = image_width;
  cmptparm.h = image_height;
  strncpy(parameters.outfile, outputfile, sizeof(parameters.outfile)-1);

  image = opj_image_create(numcomps, &cmptparm, color_space);
  assert( image );

  for (i = 0; i < image_width * image_height; i++)
    {
    unsigned int compno;
    for(compno = 0; compno < numcomps; compno++)
      {
      image->comps[compno].data[i] = 0;
      }
    }

  /* catch events using our callbacks and give a local context */
  opj_set_info_handler(l_codec, info_callback,00);
  opj_set_warning_handler(l_codec, warning_callback,00);
  opj_set_error_handler(l_codec, error_callback,00);

  l_codec = opj_create_compress(OPJ_CODEC_J2K);
  opj_set_info_handler(l_codec, info_callback,00);
  opj_set_warning_handler(l_codec, warning_callback,00);
  opj_set_error_handler(l_codec, error_callback,00);

  opj_setup_encoder(l_codec, &parameters, image);

  l_stream = opj_stream_create_default_file_stream_v3(parameters.outfile,OPJ_FALSE);
  if( !l_stream )
    {
    fprintf( stderr, "Something went wrong during creation of stream\n" );
    opj_destroy_codec(l_codec);
    opj_image_destroy(image);
    opj_stream_destroy_v3(l_stream);
    return 1;
    }
  assert(l_stream);
  bSuccess = opj_start_compress(l_codec,image,l_stream);
  if( !bSuccess )
    {
    opj_stream_destroy_v3(l_stream);
    opj_destroy_codec(l_codec);
    opj_image_destroy(image);
    return 0;
    }

  assert( bSuccess );
  bSuccess = opj_encode(l_codec, l_stream);
  assert( bSuccess );
  bSuccess = opj_end_compress(l_codec, l_stream);
  assert( bSuccess );

  opj_stream_destroy_v3(l_stream);

  opj_destroy_codec(l_codec);
  opj_image_destroy(image);


  /* read back the generated file */
{
  opj_codec_t* d_codec = 00;
  opj_dparameters_t dparameters;

  d_codec = opj_create_decompress(OPJ_CODEC_J2K);
  opj_set_info_handler(d_codec, info_callback,00);
  opj_set_warning_handler(d_codec, warning_callback,00);
  opj_set_error_handler(d_codec, error_callback,00);

  bSuccess = opj_setup_decoder(d_codec, &dparameters);
  assert( bSuccess );

  l_stream = opj_stream_create_default_file_stream_v3(outputfile,1);
  assert( l_stream );

  bSuccess = opj_read_header(l_stream, d_codec, &image);
  assert( bSuccess );

  bSuccess = opj_decode(l_codec, l_stream, image);
  assert( bSuccess );

  bSuccess = opj_end_decompress(l_codec, l_stream);
  assert( bSuccess );

  opj_stream_destroy_v3(l_stream);

  opj_destroy_codec(d_codec);

  opj_image_destroy(image);
}

  puts( "end" );
  return 0;
}
예제 #9
0
파일: OPJSupport.cpp 프로젝트: aglv/Horos
unsigned char *
OPJSupport::compressJPEG2K(void *data,
                           int samplesPerPixel,
                           int rows,
                           int columns,
                           int bitsstored, //precision,
                           unsigned char bitsAllocated,
                           bool sign,
                           int rate,
                           long *compressedDataSize)
{
    //enconderMutex.lock();
    
    opj_cparameters_t parameters;
    
    opj_stream_t *l_stream = 00;
    opj_codec_t* l_codec = 00;
    opj_image_t *image = NULL;
    
    OPJ_BOOL bSuccess;
    OPJ_BOOL bUseTiles = OPJ_FALSE; /* OPJ_TRUE */
    OPJ_UINT32 l_nb_tiles = 4;
    
    OPJ_BOOL fails = OPJ_FALSE;
    OPJ_CODEC_FORMAT codec_format;
    
    memset(&parameters, 0, sizeof(parameters));
    opj_set_default_encoder_parameters(&parameters);
    parameters.outfile[0] = '\0';
    parameters.tcp_numlayers = 1;
    parameters.cp_disto_alloc = 1;
    parameters.tcp_rates[0] = rate;
    parameters.cod_format = JP2_CFMT; //JP2_CFMT; //J2K_CFMT;
    OPJ_BOOL forceJ2K = (parameters.cod_format == J2K_CFMT ? OPJ_FALSE:(((OPJ_TRUE /*force here*/))));
    
#ifdef WITH_OPJ_FILE_STREAM
    tmpnam(parameters.outfile);
#endif
    
    image = rawtoimage( (char*) data,
                       &parameters,
                       static_cast<int>( columns*rows*samplesPerPixel*bitsAllocated/8), // [data length], fragment_size
                       columns, rows,
                       samplesPerPixel,
                       bitsAllocated,
                       bitsstored,
                       sign,
                       /*quality,*/ 0);
    
    if (image == NULL)
    {
        /* close and free the byte stream */
        if (l_stream) opj_stream_destroy(l_stream);
        
        /* free remaining compression structures */
        if (l_codec) opj_destroy_codec(l_codec);
        
        /* free image data */
        if (image) opj_image_destroy(image);
        
        *compressedDataSize = 0;
        
        //enconderMutex.unlock();
        
        return NULL;
    }
    
    /*-----------------------------------------------*/
    
    switch (parameters.cod_format)
    {
        case J2K_CFMT:                      /* JPEG-2000 codestream */
            codec_format = OPJ_CODEC_J2K;
            break;
            
        case JP2_CFMT:                      /* JPEG 2000 compressed image data */
            codec_format = OPJ_CODEC_JP2;
            break;
            
        case JPT_CFMT:                      /* JPEG 2000, JPIP */
            codec_format = OPJ_CODEC_JPT;
            break;
            
        case -1:
        default:
            fprintf(stderr,"%s:%d: encode format missing\n",__FILE__,__LINE__);
            
            /* close and free the byte stream */
            if (l_stream) opj_stream_destroy(l_stream);
            
            /* free remaining compression structures */
            if (l_codec) opj_destroy_codec(l_codec);
            
            /* free image data */
            if (image) opj_image_destroy(image);
            
            *compressedDataSize = 0;
            
            //enconderMutex.unlock();
            
            return NULL;
    }
    
    /* see test_tile_encoder.c:232 and opj_compress.c:1746 */
    l_codec = opj_create_compress(codec_format);
    if (!l_codec)
    {
        fprintf(stderr,"%s:%d:\n\tNO codec\n",__FILE__,__LINE__);
        
        /* close and free the byte stream */
        if (l_stream) opj_stream_destroy(l_stream);
        
        /* free remaining compression structures */
        if (l_codec) opj_destroy_codec(l_codec);
        
        /* free image data */
        if (image) opj_image_destroy(image);
        
        *compressedDataSize = 0;
        
        //enconderMutex.unlock();
        
        return NULL;
    }
    
    
#ifdef OPJ_VERBOSE
    opj_set_info_handler(l_codec, info_callback, this);
    opj_set_warning_handler(l_codec, warning_callback, this);
#endif
    
    opj_set_error_handler(l_codec, error_callback, this);
    
    if ( !opj_setup_encoder(l_codec, &parameters, image))
    {
        fprintf(stderr,"%s:%d:\n\topj_setup_encoder failed\n",__FILE__,__LINE__);
        
        /* close and free the byte stream */
        if (l_stream) opj_stream_destroy(l_stream);
        
        /* free remaining compression structures */
        if (l_codec) opj_destroy_codec(l_codec);
        
        /* free image data */
        if (image) opj_image_destroy(image);
        
        *compressedDataSize = 0;
        
        //enconderMutex.unlock();
        
        return NULL;
    }
    
    
    // Create the stream
#ifdef WITH_OPJ_BUFFER_STREAM
    opj_buffer_info_t bufferInfo;
    bufferInfo.cur = bufferInfo.buf = (OPJ_BYTE *)data;
    bufferInfo.len = (OPJ_SIZE_T) rows * columns;
    l_stream = opj_stream_create_buffer_stream(&bufferInfo, OPJ_STREAM_WRITE);
    
    //printf("%p\n",bufferInfo.buf);
    //printf("%lu\n",bufferInfo.len);
#endif
    
    
#ifdef WITH_OPJ_FILE_STREAM
    l_stream = opj_stream_create_default_file_stream(parameters.outfile, OPJ_STREAM_WRITE);
#endif
    
    
    if (!l_stream)
    {
        fprintf(stderr,"%s:%d:\n\tstream creation failed\n",__FILE__,__LINE__);
        
        /* close and free the byte stream */
        if (l_stream) opj_stream_destroy(l_stream);
        
        /* free remaining compression structures */
        if (l_codec) opj_destroy_codec(l_codec);
        
        /* free image data */
        if (image) opj_image_destroy(image);
        
        *compressedDataSize = 0;
        
        //enconderMutex.unlock();
        
        return NULL;
    }
    
    
    while(1)
    {
        //        int tile_index=-1, user_changed_tile=0, user_changed_reduction=0;
        //        int max_tiles=0, max_reduction=0;
        fails = OPJ_TRUE;
        
        /* encode the image */
        bSuccess = opj_start_compress(l_codec, image, l_stream);
        
        if (!bSuccess)
        {
            fprintf(stderr,"%s:%d:\n\topj_start_compress failed\n",__FILE__,__LINE__);
            break;
        }
        
        if ( bSuccess && bUseTiles )
        {
            OPJ_BYTE *l_data = NULL;
            OPJ_UINT32 l_data_size = 512*512*3; //FIXME
            l_data = (OPJ_BYTE*) malloc(l_data_size * sizeof(OPJ_BYTE));
            memset(l_data, 0, l_data_size * sizeof(OPJ_BYTE));
            
            //assert( l_data );
            if (!l_data)
            {
                /* close and free the byte stream */
                if (l_stream) opj_stream_destroy(l_stream);
                
                /* free remaining compression structures */
                if (l_codec) opj_destroy_codec(l_codec);
                
                /* free image data */
                if (image) opj_image_destroy(image);
                
                *compressedDataSize = 0;
                
                //enconderMutex.unlock();
                
                return NULL;
            }
            
            for (int i=0;i<l_nb_tiles;++i)
            {
                if (! opj_write_tile(l_codec,i,l_data,l_data_size,l_stream))
                {
                    fprintf(stderr, "\nERROR -> test_tile_encoder: failed to write the tile %d!\n",i);
                    /* close and free the byte stream */
                    if (l_stream) opj_stream_destroy(l_stream);
                    
                    /* free remaining compression structures */
                    if (l_codec) opj_destroy_codec(l_codec);
                    
                    /* free image data */
                    if (image) opj_image_destroy(image);
                    
                    free(l_data);
                    
                    *compressedDataSize = 0;
                    
                    //enconderMutex.unlock();
                    
                    return NULL;
                }
            }
            
            free(l_data);
        }
        else
        {
            if (!opj_encode(l_codec, l_stream))
            {
                fprintf(stderr,"%s:%d:\n\topj_encode failed\n",__FILE__,__LINE__);
                break;
            }
        }
        
        if (!opj_end_compress(l_codec, l_stream))
        {
            fprintf(stderr,"%s:%d:\n\topj_end_compress failed\n",__FILE__,__LINE__);
            break;
        }
        
        fails = OPJ_FALSE;
        break;
        
    } // while
    
    *compressedDataSize = 0;
    unsigned char *to = NULL;
    
    /* close and free the byte stream */
    if (l_stream) opj_stream_destroy(l_stream);
    
    /* free remaining compression structures */
    if (l_codec) opj_destroy_codec(l_codec);
    
    /* free image data */
    if (image) opj_image_destroy(image);
    
    if (fails)
    {
#ifdef WITH_OPJ_FILE_STREAM
        if (parameters.outfile[0] != '\0')
            remove(parameters.outfile);
#endif
    }
    else
    {
#ifdef WITH_OPJ_BUFFER_STREAM
        //printf("%p\n",bufferInfo.buf);
        //printf("%lu\n",bufferInfo.len);
        //to=(unsigned char *) malloc(bufferInfo.len);
        //memcpy(to,l_stream,bufferInfo.len);
#endif
        
#ifdef WITH_OPJ_FILE_STREAM
        // Open the temp file and get the encoded data into 'to'
        // and the length into 'length'
        FILE *f = NULL;
        if (parameters.outfile[0] != '\0')
        {
            f = fopen(parameters.outfile, "rb");
        }
        
        long length = 0;
        
        if (f != NULL)
        {
            fseek(f, 0, SEEK_END);
            length = ftell(f);
            fseek(f, 0, SEEK_SET);
            if (forceJ2K)
            {
                length -= 85;
                fseek(f, 85, SEEK_SET);
            }
            
            if (length % 2)
            {
                length++; // ensure even length
                //fprintf(stdout,"Padded to %li\n", length);
            }
            
            to = (unsigned char *) malloc(length);
            
            fread(to, length, 1, f);
            
            //printf("%s %lu\n",parameters.outfile,length);;
            
            fclose(f);
        }
        
        *compressedDataSize = length;
        
        if (parameters.outfile[0] != '\0')
        {
            remove(parameters.outfile);
        }
#endif
    }
    
    //enconderMutex.unlock();
    
    return to;
}
예제 #10
0
char* J2kConverter::encode(int16_t* data, unsigned int imageWidth, unsigned int imageHeight, size_t& outSize, float distoRatio) {
    opj_cparameters_t params;
    opj_image_cmptparm_t compParams;
    
    opj_set_default_encoder_parameters(&params);
    params.tcp_numlayers = 1;
    params.cp_fixed_quality = 1;
    params.tcp_distoratio[0] = distoRatio;
    
    params.cp_tx0 = 0;
    params.cp_ty0 = 0;
    params.tile_size_on = OPJ_FALSE;
    params.irreversible = true;

    params.numresolution = 1;
    params.prog_order = OPJ_LRCP;

    compParams.w = imageWidth;
    compParams.h = imageHeight;
    compParams.sgnd = 0;
    compParams.prec = 16;
    compParams.bpp = 16;
    compParams.x0 = 0;
    compParams.y0 = 0;
    compParams.dx = 1;
    compParams.dy = 1;
    
    opj_codec_t *codec = opj_create_compress(OPJ_CODEC_J2K);

    opj_set_info_handler(codec, infoCallback, nullptr);
    opj_set_warning_handler(codec, warningCallback, nullptr);
    opj_set_error_handler(codec, errorCallback, nullptr);

    opj_image_t *image = opj_image_create(1, &compParams, OPJ_CLRSPC_GRAY);
    if (!image) {
        opj_destroy_codec(codec);
        return nullptr;
    }
    
    unsigned int nPixels = imageWidth * imageHeight;
    for (unsigned int i = 0; i < nPixels; ++i) {
        image->comps[0].data[i] = data[i];
    }
    
    image->x0 = 0;
    image->y0 = 0;
    image->x1 = static_cast<OPJ_UINT32>(imageWidth);
    image->y1 = static_cast<OPJ_UINT32>(imageHeight);
    image->color_space = OPJ_CLRSPC_GRAY;
    
    if (!opj_setup_encoder(codec, &params, image)) {
        std::cout << "Could not set up encoder." << std::endl;
        opj_destroy_codec(codec);
        opj_image_destroy(image);
        return nullptr;
    }

    MemoryStream* ms = new MemoryStream;
    opj_stream_t *stream = createOpjMemoryStream(OPJ_FALSE, ms);
    if (!stream) {
        std::cout << "Could not set up stream" << std::endl;
        opj_destroy_codec(codec);
        opj_image_destroy(image);
        return nullptr;
    }

    if (!opj_start_compress(codec, image, stream)) {
        std::cout << "Could not start compression." << std::endl;
        opj_stream_destroy(stream);
        opj_destroy_codec(codec);
        opj_image_destroy(image);
        return nullptr;
    }

    if (!opj_encode(codec, stream)) {
        std::cout << "Could not encode data." << std::endl;
        opj_stream_destroy(stream);
        opj_destroy_codec(codec);
        opj_image_destroy(image);
        return nullptr;
    }

    if (!opj_end_compress(codec, stream)) {
        std::cout << "Could not end compression." << std::endl;
        opj_stream_destroy(stream);
        opj_destroy_codec(codec);
        opj_image_destroy(image);
        return nullptr;
    }

    outSize = ms->data.size();
    char* outData = new char[outSize];
    memcpy(outData, ms->data.data(), outSize);
    
    opj_stream_destroy(stream);
    opj_destroy_codec(codec);
    opj_image_destroy(image);

    delete ms;
    return outData;
}
예제 #11
0
/*!
 *  pixWriteStreamJp2k()
 *
 *      Input:  stream
 *              pix  (any depth, cmap is OK)
 *              quality (SNR > 0; default ~34; 0 for lossless encoding)
 *              nlevels (<= 10)
 *              hint (a bitwise OR of L_JP2K_* values; 0 for default)
 *              debug (output callback messages, etc)
 *      Return: 0 if OK, 1 on error
 *  Notes:
 *      (1) See pixWriteJp2k() for usage.
 *      (2) For an encoder with more encoding options, see, e.g.,
 *    https://github.com/OpenJPEG/openjpeg/blob/master/tests/test_tile_encoder.c
 */
l_int32
pixWriteStreamJp2k(FILE    *fp,
                   PIX     *pix,
                   l_int32  quality,
                   l_int32  nlevels,
                   l_int32  hint,
                   l_int32  debug)
{
l_int32            w, h, d, success, snr;
const char        *opjVersion;
PIX               *pixs;
opj_cparameters_t  parameters;   /* compression parameters */
opj_stream_t      *l_stream = NULL;
opj_codec_t*       l_codec = NULL;;
opj_image_t       *image = NULL;

    PROCNAME("pixWriteStreamJp2k");

    if (!fp)
        return ERROR_INT("stream not open", procName, 1);
    if (!pix)
        return ERROR_INT("pix not defined", procName, 1);
    if (quality < 0)
        return ERROR_INT("quality must be >= 0", procName, 1);
    if (quality > 0 && quality < 27)
        L_WARNING("SNR = %d < 27; very low\n", procName, quality);
    if (quality > 45)
        L_WARNING("SNR = %d > 45; nearly lossless\n", procName, quality);
    snr = (l_float32)quality;

    if (nlevels <= 0) nlevels = 5;  /* default */
    if (nlevels > 10) {
        L_WARNING("nlevels = %d > 10; setting to 10\n", procName, nlevels);
        nlevels = 10;
    }

    opjVersion = opj_version();
    if (opjVersion[0] != '2') {
        L_ERROR("version is %s; must be 2.0 or higher\n", procName, opjVersion);
        return 1;
    }
    if ((opjVersion[2] - 0x30) != OPJ_VERSION_MINOR) {
        L_ERROR("version %s: differs from minor = %d\n",
                procName, opjVersion, OPJ_VERSION_MINOR);
         return 1;
     }

        /* Remove colormap if it exists; result is 8 or 32 bpp */
    pixGetDimensions(pix, &w, &h, &d);
    if (d == 24) {
        pixs = pixConvert24To32(pix);
    } else if (d == 32) {
        pixs = pixClone(pix);
    } else if (pixGetColormap(pix) == NULL) {
        pixs = pixConvertTo8(pix, 0);
    } else {  /* colormap */
        L_INFO("removing colormap; may be better to compress losslessly\n",
               procName);
        pixs = pixRemoveColormap(pix, REMOVE_CMAP_BASED_ON_SRC);
    }

        /* Convert to opj image format. */
    image = pixConvertToOpjImage(pixs);
    pixDestroy(&pixs);

        /* Set encoding parameters to default values.
         * We use one layer with the input SNR. */
    opj_set_default_encoder_parameters(&parameters);
    parameters.cp_fixed_quality = 1;
    parameters.cp_disto_alloc = 0;
    parameters.cp_fixed_alloc =  0;
    parameters.tcp_distoratio[0] = snr;
    parameters.tcp_numlayers = 1;
    parameters.numresolution = nlevels + 1;

        /* Create comment for codestream */
    if (parameters.cp_comment == NULL) {
        const char comment1[] = "Created by Leptonica, version ";
        const char comment2[] = "; using OpenJPEG, version ";
        size_t len1 = strlen(comment1);
        size_t len2 = strlen(comment2);
        char *version1 = getLeptonicaVersion();
        const char *version2 = opj_version();
        len1 += len2 + strlen(version1) + strlen(version2) + 1;
        parameters.cp_comment = (char *)MALLOC(len1);
        snprintf(parameters.cp_comment, len1, "%s%s%s%s", comment1, version1,
                 comment2, version2);
        FREE(version1);
    }

        /* Get the encoder handle */
    if ((l_codec = opj_create_compress(OPJ_CODEC_JP2)) == NULL) {
        opj_image_destroy(image);
        FREE(parameters.cp_comment);
        return ERROR_INT("failed to get the encoder handle\n", procName, 1);
    }

        /* Catch and report events using callbacks */
    if (debug) {
        opj_set_info_handler(l_codec, info_callback, NULL);
        opj_set_warning_handler(l_codec, warning_callback, NULL);
        opj_set_error_handler(l_codec, error_callback, NULL);
    }

        /* Set up the encoder */
    if (!opj_setup_encoder(l_codec, &parameters, image)) {
        opj_destroy_codec(l_codec);
        opj_image_destroy(image);
        FREE(parameters.cp_comment);
        return ERROR_INT("failed to set up the encoder\n", procName, 1);
    }

        /* Open a compression stream for writing.  In 2.0 we could use this:
         *     opj_stream_create_default_file_stream(fp, 0)
         * but the file stream interface was removed in 2.1.  */
    rewind(fp);
    if ((l_stream = opjCreateStream(fp, 0)) == NULL) {
        opj_destroy_codec(l_codec);
        opj_image_destroy(image);
        FREE(parameters.cp_comment);
        return ERROR_INT("failed to open l_stream\n", procName, 1);
    }

        /* Encode the image */
    if (!opj_start_compress(l_codec, image, l_stream)) {
        opj_stream_destroy(l_stream);
        opj_destroy_codec(l_codec);
        opj_image_destroy(image);
        FREE(parameters.cp_comment);
        return ERROR_INT("opj_start_compress failed\n", procName, 1);
    }
    if (!opj_encode(l_codec, l_stream)) {
        opj_stream_destroy(l_stream);
        opj_destroy_codec(l_codec);
        opj_image_destroy(image);
        FREE(parameters.cp_comment);
        return ERROR_INT("opj_encode failed\n", procName, 1);
    }
    success = opj_end_compress(l_codec, l_stream);

        /* Clean up */
    opj_stream_destroy(l_stream);
    opj_destroy_codec(l_codec);
    opj_image_destroy(image);
    FREE(parameters.cp_comment);
    if (success)
        return 0;
    else
        return ERROR_INT("opj_end_compress failed\n", procName, 1);
}