Ejemplo n.º 1
0
void J2KReader::decode(bool headeronly)
{
	if( !_fileData || !_dataLength )
	{
		BOOST_THROW_EXCEPTION( exception::Bug()
			<< exception::dev( "Need to open the file before decoding." ) );
	}
	opj_dparameters_t       parameters;       // decompression parameters
	opj_dinfo_t             *dinfo = NULL;    // handle to a decompressor
	opj_cio_t               *cio = NULL;

	_openjpeg.event_mgr.error_handler = NULL;
	_openjpeg.event_mgr.warning_handler = NULL;
	_openjpeg.event_mgr.info_handler = NULL;
	opj_set_default_decoder_parameters(&parameters);

	if (headeronly)
	{
		parameters.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
	}

	// Decompress a JPEG-2000 codestream
	// get a decoder handle
	dinfo = opj_create_decompress(CODEC_J2K);
	// Catch events using our callbacks and give a local context
	opj_set_event_mgr((opj_common_ptr) dinfo, &_openjpeg.event_mgr, stderr );
	// setup the decoder decoding parameters using user parameters
	opj_setup_decoder(dinfo, &parameters);
	if( !dinfo )
	{
		BOOST_THROW_EXCEPTION( exception::Unknown()
			<< exception::dev( "Failed to open decoder for image." ) );
	}
	// open a byte stream
	cio = opj_cio_open((opj_common_ptr)dinfo, _fileData, _dataLength);
	if( !cio )
	{
		opj_destroy_decompress( dinfo );
		BOOST_THROW_EXCEPTION( exception::Unknown()
			<< exception::dev( "Failed to open decoder for image." ) );
	}
	// Start decoding to get an image
	if( _openjpeg.image )
	{
		opj_image_destroy( _openjpeg.image );
	}
	_openjpeg.image = opj_decode( dinfo, cio );
	// close the byte stream
	opj_destroy_decompress( dinfo );
	opj_cio_close( cio );
	if( !_openjpeg.image )
	{
		BOOST_THROW_EXCEPTION( exception::Unknown()
			<< exception::dev( "Failed to decode image." ) );
	}
}
Ejemplo n.º 2
0
static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
{
    LibOpenJPEGContext *ctx = avctx->priv_data;
    int err = AVERROR(ENOMEM);

    opj_set_default_encoder_parameters(&ctx->enc_params);

    ctx->enc_params.cp_rsiz          = ctx->profile;
    ctx->enc_params.mode             = !!avctx->global_quality;
    ctx->enc_params.cp_cinema        = ctx->cinema_mode;
    ctx->enc_params.prog_order       = ctx->prog_order;
    ctx->enc_params.numresolution    = ctx->numresolution;
    ctx->enc_params.cp_disto_alloc   = ctx->disto_alloc;
    ctx->enc_params.cp_fixed_alloc   = ctx->fixed_alloc;
    ctx->enc_params.cp_fixed_quality = ctx->fixed_quality;
    ctx->enc_params.tcp_numlayers    = ctx->numlayers;
    ctx->enc_params.tcp_rates[0]     = FFMAX(avctx->compression_level, 0) * 2;

    ctx->compress = opj_create_compress(ctx->format);
    if (!ctx->compress) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
        return AVERROR(ENOMEM);
    }

    avctx->coded_frame = avcodec_alloc_frame();
    if (!avctx->coded_frame) {
        av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
        goto fail;
    }

    ctx->image = libopenjpeg_create_image(avctx, &ctx->enc_params);
    if (!ctx->image) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
        err = AVERROR(EINVAL);
        goto fail;
    }

    ctx->event_mgr.info_handler    = info_callback;
    ctx->event_mgr.error_handler   = error_callback;
    ctx->event_mgr.warning_handler = warning_callback;
    opj_set_event_mgr((opj_common_ptr)ctx->compress, &ctx->event_mgr, avctx);

    return 0;

fail:
    av_freep(&ctx->compress);
    av_freep(&avctx->coded_frame);
    return err;
}
Ejemplo n.º 3
0
void JPXStream::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format)
{
  opj_cio_t *cio = NULL;

  /* Use default decompression parameters */
  opj_dparameters_t parameters;
  opj_set_default_decoder_parameters(&parameters);

  /* Configure the event manager to receive errors and warnings */
  opj_event_mgr_t event_mgr;
  memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
  event_mgr.error_handler = libopenjpeg_error_callback;
  event_mgr.warning_handler = libopenjpeg_warning_callback;

  /* Get the decoder handle of the format */
  dinfo = opj_create_decompress(format);
  if (dinfo == NULL) goto error;

  /* Catch events using our callbacks */
  opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);

  /* Setup the decoder decoding parameters */
  opj_setup_decoder(dinfo, &parameters);

  /* Open a byte stream */
  cio = opj_cio_open((opj_common_ptr)dinfo, buf, bufLen);
  if (cio == NULL) goto error;

  /* Decode the stream and fill the image structure */
  image = opj_decode(dinfo, cio);

  /* Close the byte stream */
  opj_cio_close(cio);

  if (image == NULL) goto error;
  else return;

error:
  if (format == CODEC_JP2) {
    error(-1, "Did no succeed opening JPX Stream as JP2, trying as J2K.");
    init2(buf, bufLen, CODEC_J2K);
  } else if (format == CODEC_J2K) {
    error(-1, "Did no succeed opening JPX Stream as J2K, trying as JPT.");
    init2(buf, bufLen, CODEC_JPT);
  } else {
    error(-1, "Did no succeed opening JPX Stream.");
  }
}
Ejemplo n.º 4
0
static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
{
    LibOpenJPEGContext *ctx = avctx->priv_data;

    opj_set_default_encoder_parameters(&ctx->enc_params);
    ctx->enc_params.tcp_numlayers = 1;
    ctx->enc_params.tcp_rates[0] = avctx->compression_level > 0 ? avctx->compression_level : 0;
    ctx->enc_params.cp_disto_alloc = 1;

    ctx->compress = opj_create_compress(CODEC_J2K);
    if (!ctx->compress) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
        return AVERROR(ENOMEM);
    }

    avctx->coded_frame = avcodec_alloc_frame();
    if (!avctx->coded_frame) {
        av_freep(&ctx->compress);
        ctx->compress = NULL;
        av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
        return AVERROR(ENOMEM);
    }

    ctx->image = mj2_create_image(avctx, &ctx->enc_params);
    if (!ctx->image) {
        av_freep(&ctx->compress);
        ctx->compress = NULL;
        av_freep(&avctx->coded_frame);
        avctx->coded_frame = NULL;
        av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
        return AVERROR(EINVAL);
    }

    memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t));
    ctx->event_mgr.error_handler = error_callback;
    ctx->event_mgr.warning_handler = warning_callback;
    ctx->event_mgr.info_handler = NULL;
    opj_set_event_mgr((opj_common_ptr)ctx->compress, &ctx->event_mgr, avctx);

    return 0;
}
bool _openslide_jp2k_decode_buffer(uint32_t *dest,
                                   int32_t w, int32_t h,
                                   void *data, int32_t datalen,
                                   enum _openslide_jp2k_colorspace space,
                                   GError **err) {
  GError *tmp_err = NULL;
  bool success = false;

  // opj_cio_open interprets a NULL buffer as opening for write
  g_assert(data != NULL);

  // init decompressor
  opj_cio_t *stream = NULL;
  opj_dinfo_t *dinfo = NULL;
  opj_image_t *image = NULL;

  // note: don't use info_handler, it outputs lots of junk
  opj_event_mgr_t event_callbacks = {
    .error_handler = error_callback,
    .warning_handler = warning_callback,
  };

  opj_dparameters_t parameters;
  dinfo = opj_create_decompress(CODEC_J2K);
  opj_set_default_decoder_parameters(&parameters);
  opj_setup_decoder(dinfo, &parameters);
  stream = opj_cio_open((opj_common_ptr) dinfo, data, datalen);
  opj_set_event_mgr((opj_common_ptr) dinfo, &event_callbacks, &tmp_err);

  // decode
  image = opj_decode(dinfo, stream);

  // check error
  if (tmp_err) {
    g_propagate_error(err, tmp_err);
    goto DONE;
  }

  // sanity check
  if (image->numcomps != 3) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "image->numcomps != 3");
    goto DONE;
  }

  // TODO more checks?

  unpack_argb(space, image->comps, dest, w, h);

  success = true;

DONE:
  if (image) {
    opj_image_destroy(image);
  }
  if (stream) {
    opj_cio_close(stream);
  }
  if (dinfo) {
    opj_destroy_decompress(dinfo);
  }
  return success;
}
Ejemplo n.º 6
0
/* --------------------------------------------------------------------------
   --------------------   MAIN METHOD, CALLED BY JAVA -----------------------*/
JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2KtoImage(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_dparameters_t parameters;	/* decompression parameters */
	img_fol_t img_fol;
	opj_event_mgr_t event_mgr;		/* event manager */
	opj_image_t *image = NULL;
	FILE *fsrc = NULL;
	unsigned char *src = NULL;
	int file_length;
	int num_images;
	int i,j,imageno;
	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
	opj_cio_t *cio = NULL;
	int w,h;
	long min_value, max_value;
	short tempS; unsigned char tempUC, tempUC1, tempUC2;
	/* ==> Access variables to the Java member variables*/
	jsize		arraySize;
	jclass		cls;
	jobject		object;
	jboolean	isCopy;
	jfieldID	fid;
	jbyteArray	jba;
	jshortArray jsa;
	jintArray	jia;
	jbyte		*jbBody, *ptrBBody;
	jshort		*jsBody, *ptrSBody;
	jint		*jiBody, *ptrIBody;
	callback_variables_t msgErrorCallback_vars;
	/* <=== access variable to Java member variables */
	int *ptr, *ptr1, *ptr2;				/* <== To transfer the decoded image to Java*/

	/* 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;

	/* 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");

	/* Get the String[] containing the parameters, and converts it into a char** to simulate command line arguments.*/
	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: decoder params = ");
	for (i=0; i<argc; i++) {
		printf("[%s]",argv[i]);
	}
	printf("\n");*/

	/* set decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);
	parameters.decod_format = J2K_CFMT;

	/* parse input and get user encoding parameters */
	if(parse_cmdline_decoder(argc, argv, &parameters,&img_fol) == 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]);

	num_images=1;

	/* Get additional information from the Java object variables*/
	fid = (*env)->GetFieldID(env, cls,"skippedResolutions", "I");
	parameters.cp_reduce = (short) (*env)->GetIntField(env, obj, fid);

	/*Decoding image one by one*/
	for(imageno = 0; imageno < num_images ; imageno++)
	{
		image = NULL;
		fprintf(stderr,"\n");

		/* read the input file and put it in memory into the 'src' object, if the -i option is given in JavaParameters.
		   Implemented for debug purpose. */
		/* -------------------------------------------------------------- */
		if (parameters.infile && parameters.infile[0]!='\0') {
			/*printf("C: opening [%s]\n", parameters.infile);*/
			fsrc = fopen(parameters.infile, "rb");
			if (!fsrc) {
				fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
				return 1;
			}
			fseek(fsrc, 0, SEEK_END);
			file_length = ftell(fsrc);
			fseek(fsrc, 0, SEEK_SET);
			src = (unsigned char *) opj_malloc(file_length);
			fread(src, 1, file_length, fsrc);
			fclose(fsrc);
			/*printf("C: %d bytes read from file\n",file_length);*/
		} else {
			/* Preparing the transfer of the codestream from Java to C*/
			/*printf("C: before transfering codestream\n");*/
			fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
			jba = (*env)->GetObjectField(env, obj, fid);
			file_length = (*env)->GetArrayLength(env, jba);
			jbBody = (*env)->GetByteArrayElements(env, jba, &isCopy);
			src = (unsigned char*)jbBody;
		}

		/* decode the code-stream */
		/* ---------------------- */

		switch(parameters.decod_format) {
		case J2K_CFMT:
		{
			/* JPEG-2000 codestream */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_J2K);

			/* catch events using our callbacks and give a local context */
			opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);

			/* setup the decoder decoding parameters using user parameters */
			opj_setup_decoder(dinfo, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			image = opj_decode(dinfo, cio);
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				return 1;
			}

			/* close the byte stream */
			opj_cio_close(cio);
		}
		break;

		case JP2_CFMT:
		{
			/* JPEG 2000 compressed image data */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_JP2);

			/* catch events using our callbacks and give a local context */
			opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);

			/* setup the decoder decoding parameters using the current image and user parameters */
			opj_setup_decoder(dinfo, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			image = opj_decode(dinfo, cio);
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				return 1;
			}

			/* close the byte stream */
			opj_cio_close(cio);

		}
		break;

		case JPT_CFMT:
		{
			/* JPEG 2000, JPIP */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_JPT);

			/* catch events using our callbacks and give a local context */
			opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);

			/* setup the decoder decoding parameters using user parameters */
			opj_setup_decoder(dinfo, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			image = opj_decode(dinfo, cio);
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				return 1;
			}

			/* close the byte stream */
			opj_cio_close(cio);
		}
		break;

		default:
			fprintf(stderr, "skipping file..\n");
			continue;
	}

		/* free the memory containing the code-stream */
		if (parameters.infile && parameters.infile[0]!='\0') {
			opj_free(src);
		} else {
			(*env)->ReleaseByteArrayElements(env, jba, jbBody, 0);
		}
		src = NULL;

		/* create output image.
			If the -o parameter is given in the JavaParameters, write the decoded version into a file.
			Implemented for debug purpose. */
		/* ---------------------------------- */
		switch (parameters.cod_format) {
		case PXM_DFMT:			/* PNM PGM PPM */
			if (imagetopnm(image, parameters.outfile)) {
				fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
			}
			break;

		case PGX_DFMT:			/* PGX */
			if(imagetopgx(image, parameters.outfile)){
				fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
			}
			break;

		case BMP_DFMT:			/* BMP */
			if(imagetobmp(image, parameters.outfile)){
				fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
			}
			break;

		}

		/* ========= Return the image to the Java structure ===============*/
#ifdef CHECK_THRESHOLDS
		printf("C: checking thresholds\n");
#endif
		/* First compute the real with and height, in function of the resolutions decoded.*/
		/*wr = (image->comps[0].w + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;*/
		/*hr = (image->comps[0].h + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;*/
		w = image->comps[0].w;
		h = image->comps[0].h;

		if (image->numcomps==3) {	/* 3 components color image*/
			ptr = image->comps[0].data;
			ptr1 = image->comps[1].data;
			ptr2 = image->comps[2].data;
#ifdef CHECK_THRESHOLDS 
			if (image->comps[0].sgnd) {
				min_value = -128;
				max_value = 127;
			} else {
				min_value = 0;
				max_value = 255;
			}
#endif			
			/* Get the pointer to the Java structure where the data must be copied*/
			fid = (*env)->GetFieldID(env, cls,"image24", "[I");
			jia = (*env)->GetObjectField(env, obj, fid);
			jiBody = (*env)->GetIntArrayElements(env, jia, 0);
			ptrIBody = jiBody;
			printf("C: transfering image24: %d int to Java pointer=%d\n",image->numcomps*w*h, ptrIBody);

			for (i=0; i<w*h; i++) {
				tempUC = (unsigned char)(ptr[i]);
				tempUC1 = (unsigned char)(ptr1[i]);
				tempUC2 = (unsigned char)(ptr2[i]);
#ifdef CHECK_THRESHOLDS
				if (tempUC < min_value)
					tempUC=min_value;
				else if (tempUC > max_value)
					tempUC=max_value;
				if (tempUC1 < min_value)
					tempUC1=min_value;
				else if (tempUC1 > max_value)
					tempUC1=max_value;
				if (tempUC2 < min_value)
					tempUC2=min_value;
				else if (tempUC2 > max_value)
					tempUC2=max_value;
#endif
				*(ptrIBody++)  = (int) ( (tempUC2<<16) + (tempUC1<<8) + tempUC );
			}
			(*env)->ReleaseIntArrayElements(env, jia, jiBody, 0);

		} else {	/* 1 component 8 or 16 bpp image*/
			ptr = image->comps[0].data;
			printf("C: before transfering a %d bpp image to java (length = %d)\n",image->comps[0].prec ,w*h);
			if (image->comps[0].prec<=8) {
				fid = (*env)->GetFieldID(env, cls,"image8", "[B");
				jba = (*env)->GetObjectField(env, obj, fid);
				jbBody = (*env)->GetByteArrayElements(env, jba, 0);
				ptrBBody = jbBody;
#ifdef CHECK_THRESHOLDS 
				if (image->comps[0].sgnd) {
					min_value = -128;
					max_value = 127;
				} else {
					min_value = 0;
					max_value = 255;
				}
#endif								
				/*printf("C: transfering %d shorts to Java image8 pointer = %d\n", wr*hr,ptrSBody);*/
				for (i=0; i<w*h; i++) {
					tempUC = (unsigned char) (ptr[i]);
#ifdef CHECK_THRESHOLDS
					if (tempUC<min_value)
						tempUC = min_value;
					else if (tempUC > max_value)
						tempUC = max_value;
#endif
					*(ptrBBody++) = tempUC;
				}
				(*env)->ReleaseByteArrayElements(env, jba, jbBody, 0);
				printf("C: image8 transfered to Java\n");
			} else {
				fid = (*env)->GetFieldID(env, cls,"image16", "[S");
				jsa = (*env)->GetObjectField(env, obj, fid);
				jsBody = (*env)->GetShortArrayElements(env, jsa, 0);
				ptrSBody = jsBody;
#ifdef CHECK_THRESHOLDS 
				if (image->comps[0].sgnd) {
					min_value = -32768;
					max_value = 32767;
				} else {
					min_value = 0;
					max_value = 65535;
				}
				printf("C: minValue = %d, maxValue = %d\n", min_value, max_value);
#endif				
				printf("C: transfering %d shorts to Java image16 pointer = %d\n", w*h,ptrSBody);
				for (i=0; i<w*h; i++) {
					tempS = (short) (ptr[i]);
#ifdef CHECK_THRESHOLDS
					if (tempS<min_value) {
						printf("C: value %d truncated to %d\n", tempS, min_value);
						tempS = min_value;
					} else if (tempS > max_value) {
						printf("C: value %d truncated to %d\n", tempS, max_value);
						tempS = max_value;
					}
#endif
					*(ptrSBody++) = tempS;
				}
				(*env)->ReleaseShortArrayElements(env, jsa, jsBody, 0);
				printf("C: image16 completely filled\n");
			}
		}	


		/* free remaining structures */
		if(dinfo) {
			opj_destroy_decompress(dinfo);
		}
		/* free image data structure */
		opj_image_destroy(image);

	}
	return 1; /* OK */
}
Ejemplo n.º 7
0
static int libopenjpeg_decode_frame(AVCodecContext *avctx,
                                    void *data, int *data_size,
                                    AVPacket *avpkt)
{
    uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    LibOpenJPEGContext *ctx = avctx->priv_data;
    AVFrame *picture = &ctx->image, *output = data;
    opj_dinfo_t *dec;
    opj_cio_t *stream;
    opj_image_t *image;
    int width, height, ret = -1;
    int pixel_size = 0;
    int ispacked = 0;

    *data_size = 0;

    // Check if input is a raw jpeg2k codestream or in jp2 wrapping
    if((AV_RB32(buf) == 12) &&
       (AV_RB32(buf + 4) == JP2_SIG_TYPE) &&
       (AV_RB32(buf + 8) == JP2_SIG_VALUE)) {
        dec = opj_create_decompress(CODEC_JP2);
    } else {
        // If the AVPacket contains a jp2c box, then skip to
        // the starting byte of the codestream.
        if (AV_RB32(buf + 4) == AV_RB32("jp2c"))
            buf += 8;
        dec = opj_create_decompress(CODEC_J2K);
    }

    if(!dec) {
        av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
        return -1;
    }
    opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);

    ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
    // Tie decoder with decoding parameters
    opj_setup_decoder(dec, &ctx->dec_params);
    stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
    if(!stream) {
        av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
        opj_destroy_decompress(dec);
        return -1;
    }

    // Decode the header only
    image = opj_decode_with_info(dec, stream, NULL);
    opj_cio_close(stream);
    if(!image) {
        av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
        opj_destroy_decompress(dec);
        return -1;
    }
    width  = image->x1 - image->x0;
    height = image->y1 - image->y0;
    if(av_image_check_size(width, height, 0, avctx) < 0) {
        av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
        goto done;
    }
    avcodec_set_dimensions(avctx, width, height);

    if (avctx->pix_fmt != PIX_FMT_NONE) {
        if (!libopenjpeg_matches_pix_fmt(image, avctx->pix_fmt)) {
            avctx->pix_fmt = PIX_FMT_NONE;
        }
    }

    if (avctx->pix_fmt == PIX_FMT_NONE) {
        avctx->pix_fmt = libopenjpeg_guess_pix_fmt(image);
    }

    if (avctx->pix_fmt == PIX_FMT_NONE) {
        av_log(avctx, AV_LOG_ERROR, "Unable to determine pixel format\n");
        goto done;
    }

    if(picture->data[0])
        ff_thread_release_buffer(avctx, picture);

    if(ff_thread_get_buffer(avctx, picture) < 0){
        av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n");
        goto done;
    }

    ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
    ctx->dec_params.cp_reduce = avctx->lowres;
    // Tie decoder with decoding parameters
    opj_setup_decoder(dec, &ctx->dec_params);
    stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
    if(!stream) {
        av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
        goto done;
    }

    opj_image_destroy(image);
    // Decode the codestream
    image = opj_decode_with_info(dec, stream, NULL);
    opj_cio_close(stream);
    if(!image) {
        av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
        goto done;
    }

    pixel_size = av_pix_fmt_descriptors[avctx->pix_fmt].comp[0].step_minus1 + 1;
    ispacked = libopenjpeg_ispacked(avctx->pix_fmt);

    switch (pixel_size) {
    case 1:
        if (ispacked) {
            libopenjpeg_copy_to_packed8(picture, image);
        } else {
            libopenjpeg_copyto8(picture, image);
        }
        break;
    case 2:
        if (ispacked) {
            libopenjpeg_copy_to_packed8(picture, image);
        } else {
            libopenjpeg_copyto16(picture, image);
        }
        break;
    case 3:
    case 4:
        if (ispacked) {
            libopenjpeg_copy_to_packed8(picture, image);
        }
        break;
    case 6:
    case 8:
        if (ispacked) {
            libopenjpeg_copy_to_packed16(picture, image);
        }
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size);
        goto done;
    }

    *output    = ctx->image;
    *data_size = sizeof(AVPicture);
    ret = buf_size;

done:
    opj_image_destroy(image);
    opj_destroy_decompress(dec);
    return ret;
}
Ejemplo n.º 8
0
int main(int argc, char *argv[]) {
  opj_dinfo_t* dinfo;
  opj_event_mgr_t event_mgr;    /* event manager */
  int tnum;
  unsigned int snum;
  opj_mj2_t *movie;
  mj2_tk_t *track;
  mj2_sample_t *sample;
  unsigned char* frame_codestream;
  FILE *file, *outfile;
  char outfilename[50];
  mj2_dparameters_t parameters;

  if (argc != 3) {
    printf("Bad syntax: Usage: MJ2_extractor mj2filename output_location\n");
    printf("Example: MJ2_extractor foreman.mj2 output/foreman\n");
    return 1;
  }

  file = fopen(argv[1], "rb");

  if (!file) {
    fprintf(stderr, "failed to open %s for reading\n", argv[1]);
    return 1;
  }

  /*
  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 = error_callback;
  event_mgr.warning_handler = warning_callback;
  event_mgr.info_handler = info_callback;

  /* get a MJ2 decompressor handle */
  dinfo = mj2_create_decompress();

  /* 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 */
  movie = (opj_mj2_t*) dinfo->mj2_handle;
  mj2_setup_decoder(dinfo->mj2_handle, &parameters);

  if (mj2_read_struct(file, movie)) // Creating the movie structure
    return 1;

  // Decode first video track
  tnum = 0;
  while (movie->tk[tnum].track_type != 0)
    tnum ++;

  track = &movie->tk[tnum];

  fprintf(stdout,"Extracting %d frames from file...\n",track->num_samples);

  for (snum=0; snum < track->num_samples; snum++)
  {
    sample = &track->sample[snum];
    frame_codestream = (unsigned char*) malloc (sample->sample_size-8); // Skipping JP2C marker
    fseek(file,sample->offset+8,SEEK_SET);
    fread(frame_codestream,sample->sample_size-8,1, file);  // Assuming that jp and ftyp markers size do

    sprintf(outfilename,"%s_%05d.j2k",argv[2],snum);
    outfile = fopen(outfilename, "wb");
    if (!outfile) {
      fprintf(stderr, "failed to open %s for writing\n",outfilename);
      return 1;
    }
    fwrite(frame_codestream,sample->sample_size-8,1,outfile);
    fclose(outfile);
    free(frame_codestream);
    }
  fclose(file);
  fprintf(stdout, "%d frames correctly extracted\n", snum);

  /* free remaining structures */
  if(dinfo) {
    mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle);
  }

  return 0;
}
Ejemplo n.º 9
0
BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
{
	const S32 MAX_COMPS = 5;
	opj_cparameters_t parameters;	/* compression parameters */
	opj_event_mgr_t event_mgr;		/* event manager */


	/* 
	configure the event callbacks (not required)
	setting of each callback is optional 
	*/
	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(&parameters);
	parameters.cod_format = 0;
	parameters.cp_disto_alloc = 1;

	if (reversible)
	{
		parameters.tcp_numlayers = 1;
		parameters.tcp_rates[0] = 0.0f;
	}
	else
	{
		parameters.tcp_numlayers = 5;
                parameters.tcp_rates[0] = 1920.0f;
                parameters.tcp_rates[1] = 480.0f;
                parameters.tcp_rates[2] = 120.0f;
                parameters.tcp_rates[3] = 30.0f;
		parameters.tcp_rates[4] = 10.0f;
		parameters.irreversible = 1;
		if (raw_image.getComponents() >= 3)
		{
			parameters.tcp_mct = 1;
		}
	}

	if (!comment_text)
	{
		parameters.cp_comment = (char *) "";
	}
	else
	{
		// Awful hacky cast, too lazy to copy right now.
		parameters.cp_comment = (char *) comment_text;
	}

	//
	// Fill in the source image from our raw image
	//
	OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
	opj_image_cmptparm_t cmptparm[MAX_COMPS];
	opj_image_t * image = NULL;
	S32 numcomps = raw_image.getComponents();
	S32 width = raw_image.getWidth();
	S32 height = raw_image.getHeight();

	memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t));
	for(S32 c = 0; c < numcomps; c++) {
		cmptparm[c].prec = 8;
		cmptparm[c].bpp = 8;
		cmptparm[c].sgnd = 0;
		cmptparm[c].dx = parameters.subsampling_dx;
		cmptparm[c].dy = parameters.subsampling_dy;
		cmptparm[c].w = width;
		cmptparm[c].h = height;
	}

	/* create the image */
	image = opj_image_create(numcomps, &cmptparm[0], color_space);

	image->x1 = width;
	image->y1 = height;

	S32 i = 0;
	const U8 *src_datap = raw_image.getData();
	for (S32 y = height - 1; y >= 0; y--)
	{
		for (S32 x = 0; x < width; x++)
		{
			const U8 *pixel = src_datap + (y*width + x) * numcomps;
			for (S32 c = 0; c < numcomps; c++)
			{
				image->comps[c].data[i] = *pixel;
				pixel++;
			}
			i++;
		}
	}



	/* encode the destination image */
	/* ---------------------------- */

	int codestream_length;
	opj_cio_t *cio = NULL;

	/* 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 using user parameters */
	opj_setup_encoder(cinfo, &parameters, 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 */
	bool bSuccess = opj_encode(cinfo, cio, image, NULL);
	if (!bSuccess)
	{
		opj_cio_close(cio);
		LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL;
		return FALSE;
	}
	codestream_length = cio_tell(cio);

	base.copyData(cio->buffer, codestream_length);
	base.updateData(); // set width, height

	/* close and free the byte stream */
	opj_cio_close(cio);

	/* free remaining compression structures */
	opj_destroy_compress(cinfo);


	/* free user parameters structure */
	if(parameters.cp_matrice) free(parameters.cp_matrice);

	/* free image data */
	opj_image_destroy(image);
	return TRUE;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[]) {

	opj_dinfo_t* dinfo; 
	opj_event_mgr_t event_mgr;		/* event manager */

  FILE *file, *xmlout;
/*  char xmloutname[50]; */
  opj_mj2_t *movie;

  char* infile = 0;
  char* outfile = 0;
  char* s, S1, S2, S3;
  int len;
  unsigned int sampleframe = 1; /* First frame */
  char* stringDTD = NULL;
  BOOL notes = TRUE;
  BOOL sampletables = FALSE;
  BOOL raw = TRUE;
  BOOL derived = TRUE;
	mj2_dparameters_t parameters;

  while (TRUE) {
	/* ':' after letter means it takes an argument */
    int c = getopt(argc, argv, "i:o:f:v:hntrd");
	/* FUTURE:  Reserve 'p' for pruning file (which will probably make -t redundant) */
    if (c == -1)
      break;
    switch (c) {
    case 'i':			/* IN file */
      infile = optarg;
      s = optarg;
      while (*s) { s++; } /* Run to filename end */
      s--;
      S3 = *s;
      s--;
      S2 = *s;
      s--;
      S1 = *s;
      
      if ((S1 == 'm' && S2 == 'j' && S3 == '2')
      || (S1 == 'M' && S2 == 'J' && S3 == '2')) {
       break;
      }
      fprintf(stderr, "Input file name must have .mj2 extension, not .%c%c%c.\n", S1, S2, S3);
      return 1;

      /* ----------------------------------------------------- */
    case 'o':			/* OUT file */
      outfile = optarg;
      while (*outfile) { outfile++; } /* Run to filename end */
      outfile--;
      S3 = *outfile;
      outfile--;
      S2 = *outfile;
      outfile--;
      S1 = *outfile;
      
      outfile = optarg;
      
      if ((S1 == 'x' && S2 == 'm' && S3 == 'l')
	  || (S1 == 'X' && S2 == 'M' && S3 == 'L'))
        break;
    
      fprintf(stderr,
	  "Output file name must have .xml extension, not .%c%c%c\n", S1, S2, S3);
	  return 1;

      /* ----------------------------------------------------- */
    case 'f':			/* Choose sample frame.  0 = none */
      sscanf(optarg, "%u", &sampleframe);
      break;

      /* ----------------------------------------------------- */
    case 'v':			/* Verification by DTD. */
      stringDTD = optarg;
	  /* We will not insist upon last 3 chars being "dtd", since non-file
	  access protocol may be used. */
	  if(strchr(stringDTD,'"') != NULL) {
        fprintf(stderr, "-D's string must not contain any embedded double-quote characters.\n");
	    return 1;
	  }

      if (strncmp(stringDTD,"PUBLIC ",7) == 0 || strncmp(stringDTD,"SYSTEM ",7) == 0)
        break;
    
      fprintf(stderr, "-D's string must start with \"PUBLIC \" or \"SYSTEM \"\n");
	  return 1;

    /* ----------------------------------------------------- */
    case 'n':			/* Suppress comments */
      notes = FALSE;
      break;

    /* ----------------------------------------------------- */
    case 't':			/* Show sample size and chunk offset tables */
      sampletables = TRUE;
      break;

    /* ----------------------------------------------------- */
    case 'h':			/* Display an help description */
      help_display();
      return 0;

    /* ----------------------------------------------------- */
    case 'r':			/* Suppress raw data */
      raw = FALSE;
      break;

    /* ----------------------------------------------------- */
    case 'd':			/* Suppress derived data */
      derived = FALSE;
      break;

   /* ----------------------------------------------------- */
    default:
      return 1;
    } /* switch */
  } /* while */

  if(!raw && !derived)
	  raw = TRUE; /* At least one of 'raw' and 'derived' must be true */

    /* Error messages */
  /* -------------- */
  if (!infile || !outfile) {
    fprintf(stderr,"Correct usage: mj2_to_metadata -i mj2-file -o xml-file (plus options)\n");
    return 1;
  }

/* was:
  if (argc != 3) {
    printf("Bad syntax: Usage: MJ2_to_metadata inputfile.mj2 outputfile.xml\n"); 
    printf("Example: MJ2_to_metadata foreman.mj2 foreman.xml\n");
    return 1;
  }
*/
  len = strlen(infile);
  if(infile[0] == ' ')
  {
    infile++; /* There may be a leading blank if user put space after -i */
  }
  
  file = fopen(infile, "rb"); /* was: argv[1] */
  
  if (!file) {
    fprintf(stderr, "Failed to open %s for reading.\n", infile); /* was: argv[1] */
    return 1;
  }

  len = strlen(outfile);
  if(outfile[0] == ' ')
  {
    outfile++; /* There may be a leading blank if user put space after -o */
  }

  // Checking output file
  xmlout = fopen(outfile, "w"); /* was: argv[2] */
  if (!xmlout) {
    fprintf(stderr, "Failed to open %s for writing.\n", outfile); /* was: argv[2] */
    return 1;
  }
  // Leave it open

	/*
	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 = error_callback;
	event_mgr.warning_handler = warning_callback;
	event_mgr.info_handler = info_callback;

	/* get a MJ2 decompressor handle */
	dinfo = mj2_create_decompress();

	/* 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 */
	movie = (opj_mj2_t*) dinfo->mj2_handle;
	mj2_setup_decoder(dinfo->mj2_handle, &parameters);

  if (mj2_read_struct(file, movie)) // Creating the movie structure
  {
    fclose(xmlout);
    return 1;
  }

  xml_write_init(notes, sampletables, raw, derived);
  xml_write_struct(file, xmlout, movie, sampleframe, stringDTD, &event_mgr);
  fclose(xmlout);

	fprintf(stderr,"Metadata correctly extracted to XML file \n");;	

	/* free remaining structures */
	if(dinfo) {
		mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle);
	}

  return 0;
}
Ejemplo n.º 11
0
int write_image (dt_imageio_j2k_t *j2k, const char *filename, const float *in, void *exif, int exif_len, int imgid)
{
  opj_cparameters_t parameters;     /* compression parameters */
  float *rates = NULL;
  opj_event_mgr_t event_mgr;        /* event manager */
  opj_image_t *image = NULL;
  int quality = CLAMP(j2k->quality, 1, 100);

  /*
  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 = 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(&parameters);

  /* compression ratio */
  /* invert range, from 10-100, 100-1
  * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/
  parameters.tcp_rates[0] = 100 - quality + 1;

  parameters.tcp_numlayers = 1; /* only one resolution */
  parameters.cp_disto_alloc = 1;
  parameters.cp_rsiz = STD_RSIZ;

  parameters.cod_format = j2k->format;
  parameters.cp_cinema = j2k->preset;

  if(parameters.cp_cinema)
  {
    rates = (float*)malloc(parameters.tcp_numlayers * sizeof(float));
    for(int i=0; i< parameters.tcp_numlayers; i++)
    {
      rates[i] = parameters.tcp_rates[i];
    }
    cinema_parameters(&parameters);
  }

  /* Create comment for codestream */
  const char comment[] = "Created by "PACKAGE_STRING;
  parameters.cp_comment = g_strdup(comment);

  /*Converting the image to a format suitable for encoding*/
  {
    int subsampling_dx = parameters.subsampling_dx;
    int subsampling_dy = parameters.subsampling_dy;
    int numcomps = 3;
    int prec = 12; //TODO: allow other bitdepths!
    int w = j2k->width, h = j2k->height;

    opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */
    memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));

    for(int i = 0; i < numcomps; i++)
    {
      cmptparm[i].prec = prec;
      cmptparm[i].bpp = prec;
      cmptparm[i].sgnd = 0;
      cmptparm[i].dx = subsampling_dx;
      cmptparm[i].dy = subsampling_dy;
      cmptparm[i].w = w;
      cmptparm[i].h = h;
    }
    image = opj_image_create(numcomps, &cmptparm[0], CLRSPC_SRGB);
    if(!image)
    {
      fprintf(stderr, "Error: opj_image_create() failed\n");
      return 1;
    }

    /* set image offset and reference grid */
    image->x0 = parameters.image_offset_x0;
    image->y0 = parameters.image_offset_y0;
    image->x1 = parameters.image_offset_x0 + (w - 1) * subsampling_dx + 1;
    image->y1 = parameters.image_offset_y0 + (h - 1) * subsampling_dy + 1;

    switch(prec)
    {
      case 8:
        for(int i = 0; i < w * h; i++)
        {
          for(int k = 0; k < numcomps; k++) image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(in[i*4 + k]);
        }
        break;
      case 12:
        for(int i = 0; i < w * h; i++)
        {
          for(int k = 0; k < numcomps; k++) image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(in[i*4 + k]);
        }
        break;
      case 16:
        for(int i = 0; i < w * h; i++)
        {
          for(int k = 0; k < numcomps; k++) image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(in[i*4 + k]);
        }
        break;
      default:
        fprintf(stderr, "Error: this shouldn't happen, there is no bit depth of %d for jpeg 2000 images.\n", prec);
        return 1;
    }
  }

  /*Encoding image*/

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

  if(parameters.cp_cinema)
  {
    cinema_setup_encoder(&parameters,image,rates);
  }

  /* encode the destination image */
  /* ---------------------------- */
  int rc = 1;
  OPJ_CODEC_FORMAT codec;
  if(parameters.cod_format == J2K_CFMT)        /* J2K format output */
    codec = CODEC_J2K;
  else
    codec = CODEC_JP2;

  int codestream_length;
  size_t res;
  opj_cio_t *cio = NULL;
  FILE *f = NULL;

  /* get a J2K/JP2 compressor handle */
  opj_cinfo_t* cinfo = opj_create_compress(codec);

  /* 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, &parameters, 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 */
  if(!opj_encode(cinfo, cio, image, NULL))
  {
    opj_cio_close(cio);
    fprintf(stderr, "failed to encode image\n");
    return 1;
  }
  codestream_length = cio_tell(cio);

  /* write the buffer to disk */
  f = fopen(filename, "wb");
  if(!f)
  {
    fprintf(stderr, "failed to open %s for writing\n", filename);
    return 1;
  }
  res = fwrite(cio->buffer, 1, codestream_length, f);
  if(res < (size_t)codestream_length) /* FIXME */
  {
    fprintf(stderr, "failed to write %d (%s)\n", codestream_length, filename);
    fclose(f);
    return 1;
  }
  fclose(f);

  /* close and free the byte stream */
  opj_cio_close(cio);

  /* free remaining compression structures */
  opj_destroy_compress(cinfo);

  /* add exif data blob. seems to not work for j2k files :( */
  if(exif && j2k->format == JP2_CFMT)
    rc = dt_exif_write_blob(exif,exif_len,filename);

  /* free image data */
  opj_image_destroy(image);

  /* free user parameters structure */
  g_free(parameters.cp_comment);
  if(parameters.cp_matrice) free(parameters.cp_matrice);

  return ((rc == 1) ? 0 : 1);
}
Ejemplo n.º 12
0
static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                    const AVFrame *frame, int *got_packet)
{
    LibOpenJPEGContext *ctx = avctx->priv_data;
    opj_image_t *image      = ctx->image;
    opj_cinfo_t *compress   = NULL;
    opj_cio_t *stream       = NULL;
    int cpyresult = 0;
    int ret, len;
    AVFrame *gbrframe;

    switch (avctx->pix_fmt) {
    case AV_PIX_FMT_RGB24:
    case AV_PIX_FMT_RGBA:
    case AV_PIX_FMT_YA8:
        cpyresult = libopenjpeg_copy_packed8(avctx, frame, image);
        break;
    case AV_PIX_FMT_XYZ12:
        cpyresult = libopenjpeg_copy_packed12(avctx, frame, image);
        break;
    case AV_PIX_FMT_RGB48:
    case AV_PIX_FMT_RGBA64:
    case AV_PIX_FMT_YA16:
        cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
        break;
    case AV_PIX_FMT_GBR24P:
    case AV_PIX_FMT_GBRP9:
    case AV_PIX_FMT_GBRP10:
    case AV_PIX_FMT_GBRP12:
    case AV_PIX_FMT_GBRP14:
    case AV_PIX_FMT_GBRP16:
        gbrframe = av_frame_clone(frame);
        if (!gbrframe)
            return AVERROR(ENOMEM);
        gbrframe->data[0] = frame->data[2]; // swap to be rgb
        gbrframe->data[1] = frame->data[0];
        gbrframe->data[2] = frame->data[1];
        gbrframe->linesize[0] = frame->linesize[2];
        gbrframe->linesize[1] = frame->linesize[0];
        gbrframe->linesize[2] = frame->linesize[1];
        if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) {
            cpyresult = libopenjpeg_copy_unpacked8(avctx, gbrframe, image);
        } else {
            cpyresult = libopenjpeg_copy_unpacked16(avctx, gbrframe, image);
        }
        av_frame_free(&gbrframe);
        break;
    case AV_PIX_FMT_GRAY8:
    case AV_PIX_FMT_YUV410P:
    case AV_PIX_FMT_YUV411P:
    case AV_PIX_FMT_YUV420P:
    case AV_PIX_FMT_YUV422P:
    case AV_PIX_FMT_YUV440P:
    case AV_PIX_FMT_YUV444P:
    case AV_PIX_FMT_YUVA420P:
    case AV_PIX_FMT_YUVA422P:
    case AV_PIX_FMT_YUVA444P:
        cpyresult = libopenjpeg_copy_unpacked8(avctx, frame, image);
        break;
    case AV_PIX_FMT_GRAY16:
    case AV_PIX_FMT_YUV420P9:
    case AV_PIX_FMT_YUV422P9:
    case AV_PIX_FMT_YUV444P9:
    case AV_PIX_FMT_YUVA420P9:
    case AV_PIX_FMT_YUVA422P9:
    case AV_PIX_FMT_YUVA444P9:
    case AV_PIX_FMT_YUV444P10:
    case AV_PIX_FMT_YUV422P10:
    case AV_PIX_FMT_YUV420P10:
    case AV_PIX_FMT_YUVA444P10:
    case AV_PIX_FMT_YUVA422P10:
    case AV_PIX_FMT_YUVA420P10:
    case AV_PIX_FMT_YUV420P12:
    case AV_PIX_FMT_YUV422P12:
    case AV_PIX_FMT_YUV444P12:
    case AV_PIX_FMT_YUV420P14:
    case AV_PIX_FMT_YUV422P14:
    case AV_PIX_FMT_YUV444P14:
    case AV_PIX_FMT_YUV444P16:
    case AV_PIX_FMT_YUV422P16:
    case AV_PIX_FMT_YUV420P16:
    case AV_PIX_FMT_YUVA444P16:
    case AV_PIX_FMT_YUVA422P16:
    case AV_PIX_FMT_YUVA420P16:
        cpyresult = libopenjpeg_copy_unpacked16(avctx, frame, image);
        break;
    default:
        av_log(avctx, AV_LOG_ERROR,
               "The frame's pixel format '%s' is not supported\n",
               av_get_pix_fmt_name(avctx->pix_fmt));
        return AVERROR(EINVAL);
        break;
    }

    if (!cpyresult) {
        av_log(avctx, AV_LOG_ERROR,
               "Could not copy the frame data to the internal image buffer\n");
        return -1;
    }

    compress = opj_create_compress(ctx->format);
    if (!compress) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
        return AVERROR(ENOMEM);
    }

    opj_setup_encoder(compress, &ctx->enc_params, image);

    stream = opj_cio_open((opj_common_ptr) compress, NULL, 0);
    if (!stream) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n");
        return AVERROR(ENOMEM);
    }

    memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t));
    ctx->event_mgr.info_handler    = info_callback;
    ctx->event_mgr.error_handler   = error_callback;
    ctx->event_mgr.warning_handler = warning_callback;
    opj_set_event_mgr((opj_common_ptr) compress, &ctx->event_mgr, avctx);

    if (!opj_encode(compress, stream, image, NULL)) {
        av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n");
        return -1;
    }

    len = cio_tell(stream);
    if ((ret = ff_alloc_packet2(avctx, pkt, len)) < 0) {
        return ret;
    }

    memcpy(pkt->data, stream->buffer, len);
    pkt->flags |= AV_PKT_FLAG_KEY;
    *got_packet = 1;

    opj_cio_close(stream);
    stream = NULL;
    opj_destroy_compress(compress);
    compress = NULL;

    return 0;
}
Ejemplo n.º 13
0
// load the jpeg2000 file format
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;
    unsigned char *ptr;
	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;

	// destroy the image
    image->Destroy();

	/* 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;
	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(&parameters);

	/* 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;
#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, &parameters);

	/* 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++);
					
					}
				}
			}
		}
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
	LLTimer decode_timer;

	/* Extract metadata */
	/* ---------------- */
	U8* c_data = base.getData();
	size_t c_size =  base.getDataSize();
	size_t position = 0;
	
	while (position < 1024 && position < (c_size - 7)) // the comment field should be in the first 1024 bytes.
	{
		if (c_data[position] == 0xff && c_data[position + 1] == 0x64)
		{
			U8 high_byte = c_data[position + 2];
			U8 low_byte = c_data[position + 3];
			S32 c_length = (high_byte * 256) + low_byte; // This size also counts the markers, 00 01 and itself
			if (c_length > 200) // sanity check
			{
				// While comments can be very long, anything longer then 200 is suspect.
				break;
			}
			
			if (position + 2 + c_length > c_size)
			{
				// comment extends past end of data, corruption, or all data not retrived yet.
				break;
			}
			
			// if the comment block does not end at the end of data, check to see if the next
			// block starts with 0xFF
			if (position + 2 + c_length < c_size && c_data[position + 2 + c_length] != 0xff)
			{
				// invalied comment block
				break;
			}
			
			// extract the comment minus the markers, 00 01
			raw_image.mComment.assign((char*)c_data + position + 6, c_length - 4);
			break;
		}
		++position;
	}
	
	opj_dparameters_t parameters;	/* decompression parameters */
	opj_event_mgr_t event_mgr = { };		/* event manager */
	opj_image_t *image = nullptr;

	opj_dinfo_t* dinfo = nullptr;	/* handle to a decompressor */
	opj_cio_t *cio = nullptr;


	/* configure the event callbacks (not required) */
	event_mgr.error_handler = error_callback;
	event_mgr.warning_handler = warning_callback;
	event_mgr.info_handler = info_callback;

	/* set decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);

	parameters.cp_reduce = base.getRawDiscardLevel();

	if(parameters.cp_reduce == 0 && *(U16*)(base.getData() + base.getDataSize() - 2) != 0xD9FF)
	{
		bool failed = true;
		for(S32 i = base.getDataSize()-1; i > 42; --i)
		{
			if(base.getData()[i] != 0x00)
			{
				failed = *(U16*)(base.getData()+i-1) != 0xD9FF;
				break;
			}
		}
		if(failed)
		{
			opj_image_destroy(image);
			base.decodeFailed();
			return TRUE;
		}
	}


	/* decode the code-stream */
	/* ---------------------- */

	/* JPEG-2000 codestream */

	/* get a decoder handle */
	dinfo = opj_create_decompress(CODEC_J2K);

	/* 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, &parameters);

	/* open a byte stream */
	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());

	/* decode the stream and fill the image structure */
	image = opj_decode(dinfo, cio);

	/* close the byte stream */
	opj_cio_close(cio);

	/* free remaining structures */
	if(dinfo)
	{
		opj_destroy_decompress(dinfo);
	}

	// The image decode failed if the return was NULL or the component
	// count was zero.  The latter is just a sanity check before we
	// dereference the array.
	if(!image || !image->numcomps)
	{
		LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
		if (image)
		{
			opj_image_destroy(image);
		}
		base.decodeFailed();
		return TRUE; // done
	}

	// sometimes we get bad data out of the cache - check to see if the decode succeeded
	for (S32 i = 0; i < image->numcomps; i++)
	{
		if (image->comps[i].factor != base.getRawDiscardLevel())
		{
			// if we didn't get the discard level we're expecting, fail
			opj_image_destroy(image);
			base.decodeFailed();
			return TRUE;
		}
	}
	
	if(image->numcomps <= first_channel)
	{
		LL_WARNS("Texture") << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << LL_ENDL;
		if (image)
		{
			opj_image_destroy(image);
		}

		base.decodeFailed();
		return TRUE;
	}

	// Copy image data into our raw image format (instead of the separate channel format

	S32 img_components = image->numcomps;
	S32 channels = img_components - first_channel;
	if( channels > max_channel_count )
		channels = max_channel_count;

	// Component buffers are allocated in an image width by height buffer.
	// The image placed in that buffer is ceil(width/2^factor) by
	// ceil(height/2^factor) and if the factor isn't zero it will be at the
	// top left of the buffer with black filled in the rest of the pixels.
	// It is integer math so the formula is written in ceildivpo2.
	// (Assuming all the components have the same width, height and
	// factor.)
	S32 comp_width = image->comps[0].w;
	S32 f=image->comps[0].factor;
	S32 width = ceildivpow2(image->x1 - image->x0, f);
	S32 height = ceildivpow2(image->y1 - image->y0, f);
	raw_image.resize(width, height, channels);
	U8 *rawp = raw_image.getData();
	if (!rawp)
	{
		opj_image_destroy(image);
		base.setLastError("Memory error");
		base.decodeFailed();
		return true; // done
	}

	// first_channel is what channel to start copying from
	// dest is what channel to copy to.  first_channel comes from the
	// argument, dest always starts writing at channel zero.
	for (S32 comp = first_channel, dest=0; comp < first_channel + channels;
		comp++, dest++)
	{
		if (image->comps[comp].data)
		{
			S32 offset = dest;
			for (S32 y = (height - 1); y >= 0; y--)
			{
				for (S32 x = 0; x < width; x++)
				{
					rawp[offset] = image->comps[comp].data[y*comp_width + x];
					offset += channels;
				}
			}
		}
		else // Some rare OpenJPEG versions have this bug.
		{
			LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
			if (image)
			{
				opj_image_destroy(image);
			}
			base.decodeFailed();
			return TRUE; // done
		}
	}

	/* free image data structure */
	opj_image_destroy(image);

	return TRUE; // done
}
Ejemplo n.º 15
0
int main(int argc, char **argv)
{
	mj2_cparameters_t mj2_parameters;	/* MJ2 compression parameters */
	opj_cparameters_t *j2k_parameters;	/* J2K compression parameters */
	opj_event_mgr_t event_mgr;		/* event manager */
	opj_cio_t *cio;
	int value;
	opj_mj2_t *movie;
	opj_image_t *img;
	int i, j;
	char *s, S1, S2, S3;
	unsigned char *buf;
	int x1, y1,  len;
	long mdat_initpos, offset;
	FILE *mj2file;
	int sampleno;  
	opj_cinfo_t* cinfo;
	opj_bool bSuccess;
	int numframes;
	int prec = 8;/* DEFAULT */
	double total_time = 0;	

	memset(&mj2_parameters, 0, sizeof(mj2_cparameters_t));
  /* default value */
  /* ------------- */
	mj2_parameters.w = 352;			/* CIF default value*/
	mj2_parameters.h = 288;			/* CIF default value*/
	mj2_parameters.CbCr_subsampling_dx = 2;	/* CIF default value*/
	mj2_parameters.CbCr_subsampling_dy = 2;	/* CIF default value*/
	mj2_parameters.frame_rate = 25;
	mj2_parameters.prec = 8; /* DEFAULT */
	mj2_parameters.enumcs = ENUMCS_SYCC; /* FIXME: ENUMCS_YUV420 */
	mj2_parameters.meth = 1; /* enumerated color space */

/*
	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 = error_callback;
	event_mgr.warning_handler = warning_callback;
	event_mgr.info_handler = NULL;
    
	/* set J2K encoding parameters to default values */
	opj_set_default_encoder_parameters(&mj2_parameters.j2k_parameters);
	j2k_parameters = &mj2_parameters.j2k_parameters;

	/* Create comment for codestream */
	if(j2k_parameters->cp_comment == NULL) {
    const char comment[] = "Created by OpenJPEG version ";
		const size_t clen = strlen(comment);
    const char *version = opj_version();
		j2k_parameters->cp_comment = (char*)malloc(clen+strlen(version)+1);
		sprintf(j2k_parameters->cp_comment,"%s%s", comment, version);
	}

  while (1) {
    int c = opj_getopt(argc, argv,
      "i:o:r:q:f:t:n:c:b:p:s:d:P:S:E:M:R:T:C:I:W:F:D:h");
    if (c == -1)
      break;
    switch (c) {
    case 'i':			/* IN fill */
			{
				char *infile = opj_optarg;
				s = opj_optarg;
				while (*s) {
					s++;
				}
				s--;
				S3 = *s;
				s--;
				S2 = *s;
				s--;
				S1 = *s;
				
				if ((S1 == 'y' && S2 == 'u' && S3 == 'v')
					|| (S1 == 'Y' && S2 == 'U' && S3 == 'V')) {
					mj2_parameters.decod_format = YUV_DFMT;				
				}
				else {
					fprintf(stderr,
						"!! Unrecognized format for infile : %c%c%c [accept only *.yuv] !!\n\n",
						S1, S2, S3);
					return 1;
				}
				strncpy(mj2_parameters.infile, infile, sizeof(mj2_parameters.infile)-1);
			}
      break;
      /* ----------------------------------------------------- */
    case 'o':			/* OUT fill */
			{
				char *outfile = opj_optarg;
				while (*outfile) {
					outfile++;
				}
				outfile--;
				S3 = *outfile;
				outfile--;
				S2 = *outfile;
				outfile--;
				S1 = *outfile;
				
				outfile = opj_optarg;
				
				if ((S1 == 'm' && S2 == 'j' && S3 == '2')
					|| (S1 == 'M' && S2 == 'J' && S3 == '2'))
					mj2_parameters.cod_format = MJ2_CFMT;
				else {
					fprintf(stderr,
						"Unknown output format image *.%c%c%c [only *.mj2]!! \n",
						S1, S2, S3);
					return 1;
				}
				strncpy(mj2_parameters.outfile, outfile, sizeof(mj2_parameters.outfile)-1);      
      }
      break;
      /* ----------------------------------------------------- */
    case 'r':			/* rates rates/distorsion */
			{
				float rate;
				s = opj_optarg;
				while (sscanf(s, "%f", &rate) == 1) {
					j2k_parameters->tcp_rates[j2k_parameters->tcp_numlayers] = rate * 2;
					j2k_parameters->tcp_numlayers++;
					while (*s && *s != ',') {
						s++;
					}
					if (!*s)
						break;
					s++;
				}
				j2k_parameters->cp_disto_alloc = 1;
			}
      break;
      /* ----------------------------------------------------- */
    case 'q':			/* add fixed_quality */
      s = opj_optarg;
			while (sscanf(s, "%f", &j2k_parameters->tcp_distoratio[j2k_parameters->tcp_numlayers]) == 1) {
				j2k_parameters->tcp_numlayers++;
				while (*s && *s != ',') {
					s++;
				}
				if (!*s)
					break;
				s++;
			}
			j2k_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;
				
				s = opj_optarg;
				sscanf(s, "%d", &numlayers);
				s++;
				if (numlayers > 9)
					s++;
				
				j2k_parameters->tcp_numlayers = numlayers;
				numresolution = j2k_parameters->numresolution;
				matrix_width = numresolution * 3;
				j2k_parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
				s = s + 2;
				
				for (i = 0; i < numlayers; i++) {
					row = &j2k_parameters->cp_matrice[i * matrix_width];
					col = row;
					j2k_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++;
				}
				j2k_parameters->cp_fixed_alloc = 1;
			}
			break;
      /* ----------------------------------------------------- */
    case 't':			/* tiles */
      sscanf(opj_optarg, "%d,%d", &j2k_parameters->cp_tdx, &j2k_parameters->cp_tdy);
			j2k_parameters->tile_size_on = OPJ_TRUE;
      break;
      /* ----------------------------------------------------- */
    case 'n':			/* resolution */
      sscanf(opj_optarg, "%d", &j2k_parameters->numresolution);
      break;
      /* ----------------------------------------------------- */
    case 'c':			/* precinct dimension */
			{
				char sep;
				int res_spec = 0;

				char *s = opj_optarg;
				do {
					sep = 0;
					sscanf(s, "[%d,%d]%c", &j2k_parameters->prcw_init[res_spec],
                                 &j2k_parameters->prch_init[res_spec], &sep);
					j2k_parameters->csty |= 0x01;
					res_spec++;
					s = strpbrk(s, "]") + 2;
				}
				while (sep == ',');
				j2k_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;
				}
				j2k_parameters->cblockw_init = cblockw_init;
				j2k_parameters->cblockh_init = cblockh_init;
			}
			break;
      /* ----------------------------------------------------- */
    case 'p':			/* progression order */
			{
				char progression[5];
				
				strncpy(progression, opj_optarg, 5);
				j2k_parameters->prog_order = give_progression(progression);
				if (j2k_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", &j2k_parameters->subsampling_dx,
                                    &j2k_parameters->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", &j2k_parameters->image_offset_x0,
                                    &j2k_parameters->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 */
      help_display();
      return 0;
      break;
      /* ----------------------------------------------------- */
    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 = j2k_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++;
				}
				j2k_parameters->numpocs = numpocs;
			}
			break;
      /* ------------------------------------------------------ */
    case 'S':			/* SOP marker */
      j2k_parameters->csty |= 0x02;
      break;
      /* ------------------------------------------------------ */
    case 'E':			/* EPH marker */
      j2k_parameters->csty |= 0x04;
      break;
      /* ------------------------------------------------------ */
    case 'M':			/* Mode switch pas tous au point !! */
      if (sscanf(opj_optarg, "%d", &value) == 1) {
				for (i = 0; i <= 5; i++) {
					int cache = value & (1 << i);
					if (cache)
						j2k_parameters->mode |= (1 << i);
				}
      }
      break;
      /* ------------------------------------------------------ */
    case 'R':			/* ROI */
      {
				if (sscanf(opj_optarg, "OI:c=%d,U=%d", &j2k_parameters->roi_compno,
                                           &j2k_parameters->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", &j2k_parameters->cp_tx0, &j2k_parameters->cp_ty0) != 2) {
					fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
					return 1;
				}
			}
			break;
      /* ------------------------------------------------------ */
    case 'C':			/* Add a comment */
			{
				j2k_parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1);
				if(j2k_parameters->cp_comment) {
					strcpy(j2k_parameters->cp_comment, opj_optarg);
				}
			}
			break;
      /* ------------------------------------------------------ */
    case 'I':			/* reversible or not */
			{
				j2k_parameters->irreversible = 1;
			}
			break;
      /* ------------------------------------------------------ */
    case 'W':			/* Width and Height and Cb and Cr subsampling in case of YUV format files */
      if (sscanf
				(opj_optarg, "%d,%d,%d,%d", &mj2_parameters.w, &mj2_parameters.h, &mj2_parameters.CbCr_subsampling_dx,
				&mj2_parameters.CbCr_subsampling_dy) != 4) {
				fprintf(stderr, "-W argument error");
				return 1;
      }
      break;
      /* ------------------------------------------------------ */
    case 'F':			/* Video frame rate */
      if (sscanf(opj_optarg, "%d", &mj2_parameters.frame_rate) != 1) {
				fprintf(stderr, "-F argument error");
				return 1;
      }
      break;
      /* ------------------------------------------------------ */
	case 'D': /* Depth: the precision */
		if(sscanf(opj_optarg, "%d", &prec) != 1) prec = 0;
		break;

    default:
      return 1;
    }
  }
    
  /* Error messages */
  /* -------------- */
	if (!mj2_parameters.cod_format || !mj2_parameters.decod_format) {
    fprintf(stderr,
      "Usage: %s -i yuv-file -o mj2-file (+ options)\n",argv[0]);
    return 1;
  }
    if(prec < 1 || prec > 16)
  {
	fprintf(stderr, "Error: Depth %d must be in the range 8 .. 16\n",prec);
	return 1;	
  }
	if ((j2k_parameters->cp_disto_alloc || j2k_parameters->cp_fixed_alloc || j2k_parameters->cp_fixed_quality)
		&& (!(j2k_parameters->cp_disto_alloc ^ j2k_parameters->cp_fixed_alloc ^ j2k_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 (j2k_parameters->tcp_numlayers == 0) {
		j2k_parameters->tcp_rates[0] = 0;	/* MOD antonin : losslessbug */
		j2k_parameters->tcp_numlayers++;
		j2k_parameters->cp_disto_alloc = 1;
	}

	if((j2k_parameters->cp_tx0 > j2k_parameters->image_offset_x0) || (j2k_parameters->cp_ty0 > j2k_parameters->image_offset_y0)) {
		fprintf(stderr,
			"Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
			j2k_parameters->cp_tx0, j2k_parameters->image_offset_x0, j2k_parameters->cp_ty0, j2k_parameters->image_offset_y0);
		return 1;
	}

	for (i = 0; i < j2k_parameters->numpocs; i++) {
		if (j2k_parameters->POC[i].prg == -1) {
			fprintf(stderr,
				"Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
				i + 1);
		}
	}
  
  if (j2k_parameters->cp_tdx > mj2_parameters.Dim[0] || j2k_parameters->cp_tdy > mj2_parameters.Dim[1]) {
    fprintf(stderr,
      "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
      j2k_parameters->cp_tdx, mj2_parameters.Dim[0], j2k_parameters->cp_tdy, mj2_parameters.Dim[1]);
    return 1;
  }
    
  /* to respect profile - 0 */
  /* ---------------------- */
  
  x1 = !mj2_parameters.Dim[0] ? (mj2_parameters.w - 1) * j2k_parameters->subsampling_dx 
		+ 1 : mj2_parameters.Dim[0] + (mj2_parameters.w - 1) * j2k_parameters->subsampling_dx + 1;
  y1 = !mj2_parameters.Dim[1] ? (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy 
		+ 1 : mj2_parameters.Dim[1] + (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy + 1;   
	mj2_parameters.numcomps = 3; /* YUV files only have 3 components */ 

	mj2_parameters.prec = prec;

	j2k_parameters->tcp_mct = 0;
    
	mj2file = fopen(mj2_parameters.outfile, "wb");
  
	if (!mj2file) {
    fprintf(stderr, "failed to open %s for writing\n", argv[2]);
    return 1;
	}
    
	/* get a MJ2 decompressor handle */
	cinfo = mj2_create_compress();
	movie = (opj_mj2_t*)cinfo->mj2_handle;
	
	/* catch events using our callbacks and give a local context */
	opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);

	/* setup encoder parameters */
	mj2_setup_encoder(movie, &mj2_parameters);   
  
	movie->tk[0].num_samples = 
	 yuv_num_frames(&movie->tk[0],mj2_parameters.infile);

	if (movie->tk[0].num_samples == 0) {
		return 1;
	}

  /* One sample per chunk*/
	movie->tk[0].chunk = (mj2_chunk_t*) 
	 malloc(movie->tk[0].num_samples * sizeof(mj2_chunk_t));     
	movie->tk[0].sample = (mj2_sample_t*) 
	 malloc(movie->tk[0].num_samples * sizeof(mj2_sample_t));
  
	if (mj2_init_stdmovie(movie)) {
    fprintf(stderr, "Error with movie initialization");
    return 1;
	}    
  
/* Writing JP, FTYP and MDAT boxes */
/* Assuming that the JP and FTYP boxes won't be longer than 300 bytes:*/
	buf = (unsigned char*) 
	 malloc (300 * sizeof(unsigned char));

	cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, 300);

	mj2_write_jp(cio);
	mj2_write_ftyp(movie, cio);

	mdat_initpos = cio_tell(cio);
	cio_skip(cio, 4);

	cio_write(cio, MJ2_MDAT, 4);	

	fwrite(buf,cio_tell(cio),1,mj2file);

	offset = cio_tell(cio);
	opj_cio_close(cio);
	free(buf);

	for(i = 0; i < movie->num_stk + movie->num_htk + movie->num_vtk; i++) 
   {
    if(movie->tk[i].track_type != 0) 
  {
	fprintf(stderr, "Unable to write sound or hint tracks\n");
  }
	else 
  {
	mj2_tk_t *tk;
	int buflen = 0;
  
	tk = &movie->tk[i];     
	tk->num_chunks = tk->num_samples;
	numframes = tk->num_samples;
	tk->depth = prec; 

	fprintf(stderr, "Video Track number %d\n", i);

	img = mj2_image_create(tk, j2k_parameters);          

	buflen = 2 * (tk->w * tk->h * 8);
	buf = (unsigned char *) malloc(buflen*sizeof(unsigned char));	

	for(sampleno = 0; sampleno < numframes; sampleno++) 
 {
	double init_time = opj_clock();
	double elapsed_time;

		if(yuvtoimage(tk, img, sampleno, j2k_parameters, 
			mj2_parameters.infile))
	   {
		fprintf(stderr, "Error with frame number %d in YUV file\n", sampleno);
		return 1;
	   }

/* setup the encoder parameters using the current image and user parameters */
	opj_setup_encoder(cinfo, j2k_parameters, img);

	cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, buflen);
								
	cio_skip(cio, 4);
	cio_write(cio, JP2_JP2C, 4);	/* JP2C*/

/* encode the image */
	bSuccess = opj_encode(cinfo, cio, img, NULL);

	if (!bSuccess) {
	opj_cio_close(cio);
	fprintf(stderr, "failed to encode image\n");
	return 1;
	}

	len = cio_tell(cio) - 8;
	cio_seek(cio, 0);
	cio_write(cio, len+8,4);
	opj_cio_close(cio);

	tk->sample[sampleno].sample_size = len+8;				
	tk->sample[sampleno].offset = offset;
	tk->chunk[sampleno].offset = offset;	/* There is one sample per chunk */
	fwrite(buf, 1, len+8, mj2file);				
	offset += len+8;				

	elapsed_time = opj_clock()-init_time;
	fprintf(stderr, "Frame number %d/%d encoded in %.2f mseconds\n", 
		sampleno + 1, numframes, elapsed_time*1000);
	total_time += elapsed_time;
 }	/* for(sampleno */

	free(buf);
	opj_image_destroy(img);
  }
   }/* for(i */
  
	fseek(mj2file, mdat_initpos, SEEK_SET);
	
	buf = (unsigned char*) malloc(4*sizeof(unsigned char));

/* Init a cio to write box length variable in a little endian way */
	cio = opj_cio_open(NULL, buf, 4);
	cio_write(cio, offset - mdat_initpos, 4);
	fwrite(buf, 4, 1, mj2file);
	fseek(mj2file,0,SEEK_END);
	free(buf);

/* Writing MOOV box */
	buf = (unsigned char*) 
	 malloc ((TEMP_BUF+numframes*20) * sizeof(unsigned char));
	cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF+numframes*20));
	mj2_write_moov(movie, cio);
	fwrite(buf,cio_tell(cio),1,mj2file);
	free(buf);

	fprintf(stdout,"Total encoding time: %.2f s for %d frames (%.1f fps)\n",
	 total_time, numframes, (float)numframes/total_time);

  /* Ending program */
  
	fclose(mj2file);
/* free remaining compression structures */
	mj2_destroy_compress(movie);
	free(cinfo);

	if(j2k_parameters->cp_comment) free(j2k_parameters->cp_comment);
	if(j2k_parameters->cp_matrice) free(j2k_parameters->cp_matrice);
	opj_cio_close(cio);

	return 0;
}
Ejemplo n.º 16
0
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
	raw_image.decodedComment = LLImageMetaDataReader::ExtractKDUUploadComment(base.getData(), base.getDataSize());

	LLTimer decode_timer;

	opj_dparameters_t parameters;	/* decompression parameters */
	opj_event_mgr_t event_mgr;		/* event manager */
	opj_image_t *image = NULL;

	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
	opj_cio_t *cio = NULL;


	/* configure the event callbacks (not required) */
	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 decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);

	parameters.cp_reduce = base.getRawDiscardLevel();

	/* decode the code-stream */
	/* ---------------------- */

	/* JPEG-2000 codestream */

	/* get a decoder handle */
	dinfo = opj_create_decompress(CODEC_J2K);

	/* 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, &parameters);

	/* open a byte stream */
	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());

	/* decode the stream and fill the image structure.
	   Also fill in an additional structur to get the decoding result.
	   This structure is a bit unusual in that it is not received through
	   opj, but still has somt dynamically allocated fields that need to
	   be cleared up at the end by calling a destroy function. */
	opj_codestream_info_t cinfo;
	memset(&cinfo, 0, sizeof(opj_codestream_info_t));
	image = opj_decode_with_info(dinfo, cio, &cinfo);

	/* close the byte stream */
	opj_cio_close(cio);

	/* free remaining structures */
	if(dinfo)
	{
		opj_destroy_decompress(dinfo);
	}

	// The image decode failed if the return was NULL or the component
	// count was zero.  The latter is just a sanity check before we
	// dereference the array.
	if(!image) 
	{
		LL_WARNS ("Openjpeg")  << "Failed to decode image at discard: " << (S32)base.getRawDiscardLevel() << ". No image." << LL_ENDL;
		if (base.getRawDiscardLevel() == 0)
		{
			base.decodeFailed();
		}
		return TRUE; // done
	}

	S32 img_components = image->numcomps;

	if( !img_components ) // < 1 ||img_components > 4 )
	{
		LL_WARNS("Openjpeg") << "Failed to decode image at discard: " << (S32)base.getRawDiscardLevel() << ". Wrong number of components: " << img_components << LL_ENDL;
		if (image)
		{
			opj_destroy_cstr_info(&cinfo);
			opj_image_destroy(image);
		}
		if (base.getRawDiscardLevel() == 0)
		{
			base.decodeFailed();
		}
		return TRUE; // done
	}

	// sometimes we get bad data out of the cache - check to see if the decode succeeded
	int decompdifference = 0;
	if (cinfo.numdecompos) // sanity
	{
		for (int comp = 0; comp < image->numcomps; comp++)
		{	
			/* get maximum decomposition level difference, first
			   field is from the COD header and the second
			   is what is actually met in the codestream, NB: if
			   everything was ok, this calculation will return
			   what was set in the cp_reduce value! */
			decompdifference = llmax(decompdifference, cinfo.numdecompos[comp] - image->comps[comp].resno_decoded);
		}
		if (decompdifference < 0) // sanity
		{
			decompdifference = 0;
		}
	}
	

	/* if OpenJPEG failed to decode all requested decomposition levels
	   the difference will be greater than this level */
	if (decompdifference > base.getRawDiscardLevel())
	{
		LL_WARNS("Openjpeg") << "Not enough data for requested discard level " << (S32)base.getRawDiscardLevel() << ", difference: " << (decompdifference - base.getRawDiscardLevel()) << llendl;
		opj_destroy_cstr_info(&cinfo);
		opj_image_destroy(image);
		if (base.getRawDiscardLevel() == 0)
		{
			base.decodeFailed();
		}
		return TRUE;
	}

	if(img_components <= first_channel)
	{
		LL_WARNS("Openjpeg") << "Trying to decode more channels than are present in image, numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL;
		if (image)
		{
			opj_destroy_cstr_info(&cinfo);
			opj_image_destroy(image);
		}
		if (base.getRawDiscardLevel() == 0)
		{
			base.decodeFailed();
		}
		return TRUE;
	}

	// Copy image data into our raw image format (instead of the separate channel format


	S32 channels = img_components - first_channel;
	if( channels > max_channel_count )
		channels = max_channel_count;

	// Component buffers are allocated in an image width by height buffer.
	// The image placed in that buffer is ceil(width/2^factor) by
	// ceil(height/2^factor) and if the factor isn't zero it will be at the
	// top left of the buffer with black filled in the rest of the pixels.
	// It is integer math so the formula is written in ceildivpo2.
	// (Assuming all the components have the same width, height and
	// factor.)
	S32 comp_width = image->comps[0].w;
	S32 f=image->comps[0].factor;
	S32 width = ceildivpow2(image->x1 - image->x0, f);
	S32 height = ceildivpow2(image->y1 - image->y0, f);
	raw_image.resize(width, height, channels);
	U8 *rawp = raw_image.getData();

	// first_channel is what channel to start copying from
	// dest is what channel to copy to.  first_channel comes from the
	// argument, dest always starts writing at channel zero.
	for (S32 comp = first_channel, dest=0; comp < first_channel + channels;
		comp++, dest++)
	{
		if (image->comps[comp].data)
		{
			S32 offset = dest;
			for (S32 y = (height - 1); y >= 0; y--)
			{
				for (S32 x = 0; x < width; x++)
				{
					rawp[offset] = image->comps[comp].data[y*comp_width + x];
					offset += channels;
				}
			}
		}
		else // Some rare OpenJPEG versions have this bug.
		{
			LL_WARNS("Openjpeg") << "Failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
			opj_destroy_cstr_info(&cinfo);
			opj_image_destroy(image);

			if (base.getRawDiscardLevel() == 0)
			{
				base.decodeFailed();
			}
			return TRUE; // done
		}
	}

	/* free opj data structures */
	if (image)
	{
		opj_destroy_cstr_info(&cinfo);
		opj_image_destroy(image);
	}
	
	return TRUE; // done
}
Ejemplo n.º 17
0
struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
{
	struct ImBuf *ibuf = NULL;
	bool use_float = false; /* for precision higher then 8 use float */
	bool use_alpha = false;
	
	long signed_offsets[4] = {0, 0, 0, 0};
	int float_divs[4] = {1, 1, 1, 1};

	unsigned int i, i_next, w, h, planes;
	unsigned int y;
	int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
	int is_jp2, is_j2k;
	
	opj_dparameters_t parameters;   /* decompression parameters */
	
	opj_event_mgr_t event_mgr;      /* event manager */
	opj_image_t *image = NULL;

	opj_dinfo_t *dinfo = NULL;  /* handle to a decompressor */
	opj_cio_t *cio = NULL;

	is_jp2 = check_jp2(mem);
	is_j2k = check_j2k(mem);

	if (!is_jp2 && !is_j2k)
		return(NULL);

	/* both 8, 12 and 16 bit JP2Ks are default to standard byte colorspace */
	colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);

	/* configure the event callbacks (not required) */
	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 decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);


	/* JPEG 2000 compressed image data */

	/* get a decoder handle */
	dinfo = opj_create_decompress(is_jp2 ? CODEC_JP2 : CODEC_J2K);

	/* 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 the current image and user parameters */
	opj_setup_decoder(dinfo, &parameters);

	/* open a byte stream */
	cio = opj_cio_open((opj_common_ptr)dinfo, mem, size);

	/* decode the stream and fill the image structure */
	image = opj_decode(dinfo, cio);
	
	if (!image) {
		fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
		opj_destroy_decompress(dinfo);
		opj_cio_close(cio);
		return NULL;
	}

	/* close the byte stream */
	opj_cio_close(cio);


	if ((image->numcomps * image->x1 * image->y1) == 0) {
		fprintf(stderr, "\nError: invalid raw image parameters\n");
		return NULL;
	}
	
	w = image->comps[0].w;
	h = image->comps[0].h;
	
	switch (image->numcomps) {
		case 1: /* Grayscale */
		case 3: /* Color */
			planes = 24;
			use_alpha = false;
			break;
		default: /* 2 or 4 - Grayscale or Color + alpha */
			planes = 32; /* grayscale + alpha */
			use_alpha = true;
			break;
	}
	
	
	i = image->numcomps;
	if (i > 4) i = 4;
	
	while (i) {
		i--;
		
		if (image->comps[i].prec > 8)
			use_float = true;
		
		if (image->comps[i].sgnd)
			signed_offsets[i] =  1 << (image->comps[i].prec - 1);
		
		/* only needed for float images but dosnt hurt to calc this */
		float_divs[i] = (1 << image->comps[i].prec) - 1;
	}
	
	ibuf = IMB_allocImBuf(w, h, planes, use_float ? IB_rectfloat : IB_rect);
	
	if (ibuf == NULL) {
		if (dinfo)
			opj_destroy_decompress(dinfo);
		return NULL;
	}
	
	ibuf->ftype = JP2;
	if (is_jp2)
		ibuf->ftype |= JP2_JP2;
	else
		ibuf->ftype |= JP2_J2K;
	
	if (use_float) {
		float *rect_float = ibuf->rect_float;

		if (image->numcomps < 3) {
			r = image->comps[0].data;
			a = (use_alpha) ? image->comps[1].data : NULL;

			/* grayscale 12bits+ */
			if (use_alpha) {
				a = image->comps[1].data;
				PIXEL_LOOPER_BEGIN(rect_float) {
					rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
					rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1];
				}
				PIXEL_LOOPER_END;
			}
			else {
				PIXEL_LOOPER_BEGIN(rect_float) {
					rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
					rect_float[3] = 1.0f;
				}
				PIXEL_LOOPER_END;
			}
		}
Ejemplo n.º 18
0
static int libopenjpeg_decode_frame(AVCodecContext *avctx,
                                    void *data, int *data_size,
                                    AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    LibOpenJPEGContext *ctx = avctx->priv_data;
    AVFrame *picture = &ctx->image, *output = data;
    opj_dinfo_t *dec;
    opj_cio_t *stream;
    opj_image_t *image;
    int width, height, has_alpha = 0, ret = -1;
    int x, y, index;
    uint8_t *img_ptr;
    int adjust[4];

    *data_size = 0;

    // Check if input is a raw jpeg2k codestream or in jp2 wrapping
    if((AV_RB32(buf) == 12) &&
       (AV_RB32(buf + 4) == JP2_SIG_TYPE) &&
       (AV_RB32(buf + 8) == JP2_SIG_VALUE)) {
        dec = opj_create_decompress(CODEC_JP2);
    } else {
        // If the AVPacket contains a jp2c box, then skip to
        // the starting byte of the codestream.
        if (AV_RB32(buf + 4) == AV_RB32("jp2c"))
            buf += 8;
        dec = opj_create_decompress(CODEC_J2K);
    }

    if(!dec) {
        av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
        return -1;
    }
    opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);

    ctx->dec_params.cp_reduce = avctx->lowres;
    // Tie decoder with decoding parameters
    opj_setup_decoder(dec, &ctx->dec_params);
    stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
    if(!stream) {
        av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
        opj_destroy_decompress(dec);
        return -1;
    }

    // Decode the codestream
    image = opj_decode_with_info(dec, stream, NULL);
    opj_cio_close(stream);
    if(!image) {
        av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
        opj_destroy_decompress(dec);
        return -1;
    }
    width  = image->comps[0].w << avctx->lowres;
    height = image->comps[0].h << avctx->lowres;
    if(av_check_image_size(width, height, 0, avctx) < 0) {
        av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
        goto done;
    }
    avcodec_set_dimensions(avctx, width, height);

    switch(image->numcomps)
    {
        case 1:  avctx->pix_fmt = PIX_FMT_GRAY8;
                 break;
        case 3:  if(check_image_attributes(image)) {
                     avctx->pix_fmt = PIX_FMT_RGB24;
                 } else {
                     avctx->pix_fmt = PIX_FMT_GRAY8;
                     av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n");
                 }
                 break;
        case 4:  has_alpha = 1;
                 avctx->pix_fmt = PIX_FMT_RGBA;
                 break;
        default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps);
                 goto done;
    }

    if(picture->data[0])
        avctx->release_buffer(avctx, picture);

    if(avctx->get_buffer(avctx, picture) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n");
        return -1;
    }

    for(x = 0; x < image->numcomps; x++) {
        adjust[x] = FFMAX(image->comps[x].prec - 8, 0);
    }

    for(y = 0; y < avctx->height; y++) {
        index = y*avctx->width;
        img_ptr = picture->data[0] + y*picture->linesize[0];
        for(x = 0; x < avctx->width; x++, index++) {
            *img_ptr++ = image->comps[0].data[index] >> adjust[0];
            if(image->numcomps > 2 && check_image_attributes(image)) {
                *img_ptr++ = image->comps[1].data[index] >> adjust[1];
                *img_ptr++ = image->comps[2].data[index] >> adjust[2];
                if(has_alpha)
                    *img_ptr++ = image->comps[3].data[index] >> adjust[3];
            }
        }
    }
Ejemplo n.º 19
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
}
Ejemplo n.º 20
0
int main(int argc, char *argv[])
{
	opj_dparameters_t parameters;	/* decompression parameters */
	img_fol_t img_fol;
	opj_event_mgr_t event_mgr;		/* event manager */
	opj_image_t *image = NULL;
	FILE *fsrc = NULL, *fout = NULL;
	unsigned char *src = NULL;
	int file_length;
	int num_images;
	int i,imageno;
	dircnt_t *dirptr = NULL;
	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
	opj_cio_t *cio = NULL;
	opj_codestream_info_t cstr_info;  /* Codestream information structure */
	char indexfilename[OPJ_PATH_LEN];	/* index file name */

	/* configure the event callbacks (not required) */
	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 decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);

	/* 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_decoder(argc, argv, &parameters,&img_fol, indexfilename) == 1) {
		return 1;
	}

	/* Initialize reading of directory */
	if(img_fol.set_imgdir==1){	
		num_images=get_num_images(img_fol.imgdirpath);

		dirptr=(dircnt_t*)malloc(sizeof(dircnt_t));
		if(dirptr){
			dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char));	/* Stores at max 10 image file names*/
			dirptr->filename = (char**) malloc(num_images*sizeof(char*));

			if(!dirptr->filename_buf){
				return 1;
			}
			for(i=0;i<num_images;i++){
				dirptr->filename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN;
			}
		}
		if(load_images(dirptr,img_fol.imgdirpath)==1){
			return 1;
		}
		if (num_images==0){
			fprintf(stdout,"Folder is empty\n");
			return 1;
		}
	}else{
		num_images=1;
	}

	/* */
	if (parameters.outfile[0] != 0)
	  {
	  fout = fopen(parameters.outfile,"w");
    if (!fout)
      {
      fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.outfile);
      return 1;
      }
	  }
	else
	  fout = stdout;

	/*Encoding image one by one*/
	for(imageno = 0; imageno < num_images ; imageno++)
  {
		image = NULL;
		fprintf(stderr,"\n");

		if(img_fol.set_imgdir==1){
			if (get_next_file(imageno, dirptr,&img_fol, &parameters)) {
				fprintf(stderr,"skipping file...\n");
				continue;
			}
		}

		/* read the input file and put it in memory */
		/* ---------------------------------------- */
		fsrc = fopen(parameters.infile, "rb");
		if (!fsrc) {
			fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
			return 1;
		}
		fseek(fsrc, 0, SEEK_END);
		file_length = ftell(fsrc);
		fseek(fsrc, 0, SEEK_SET);
		src = (unsigned char *) malloc(file_length);
		if (fread(src, 1, file_length, fsrc) != (size_t)file_length)
		{
			free(src);
			fclose(fsrc);
			fclose(fout);
			fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n");
			return 1;
		}
		fclose(fsrc);

		/* decode the code-stream */
		/* ---------------------- */

		switch(parameters.decod_format) {
		case J2K_CFMT:
		{
			/* JPEG-2000 codestream */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_J2K);

			/* 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, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			if (*indexfilename)				/* If need to extract codestream information*/
				image = opj_decode_with_info(dinfo, cio, &cstr_info);
			else
				image = opj_decode(dinfo, cio);
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				fclose(fout);
				free(src);
				return 1;
			}
			/* dump image */
      j2k_dump_image(fout, image);

			/* dump cp */
      j2k_dump_cp(fout, image, ((opj_j2k_t*)dinfo->j2k_handle)->cp);

			/* close the byte stream */
			opj_cio_close(cio);

			/* Write the index to disk */
			if (*indexfilename) {
				opj_bool bSuccess;
				bSuccess = write_index_file(&cstr_info, indexfilename);
				if (bSuccess) {
					fprintf(stderr, "Failed to output index file\n");
				}
			}
		}
		break;

		case JP2_CFMT:
		{
			/* JPEG 2000 compressed image data */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_JP2);

			/* 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 the current image and user parameters */
			opj_setup_decoder(dinfo, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			if (*indexfilename)				/* If need to extract codestream information*/
				image = opj_decode_with_info(dinfo, cio, &cstr_info);
			else
				image = opj_decode(dinfo, cio);			
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				fclose(fout);
				free(src);
				return 1;
			}
			/* dump image */
	  if(image->icc_profile_buf)
	 {
	  free(image->icc_profile_buf); image->icc_profile_buf = NULL;
	 }	
      j2k_dump_image(fout, image);

			/* dump cp */
      j2k_dump_cp(fout, image, ((opj_jp2_t*)dinfo->jp2_handle)->j2k->cp);

			/* close the byte stream */
			opj_cio_close(cio);

			/* Write the index to disk */
			if (*indexfilename) {
				opj_bool bSuccess;
				bSuccess = write_index_file(&cstr_info, indexfilename);
				if (bSuccess) {
					fprintf(stderr, "Failed to output index file\n");
				}
			}
		}
		break;

		case JPT_CFMT:
		{
			/* JPEG 2000, JPIP */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_JPT);

			/* 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, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			if (*indexfilename)				/* If need to extract codestream information*/
				image = opj_decode_with_info(dinfo, cio, &cstr_info);
			else
				image = opj_decode(dinfo, cio);
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				fclose(fout);
				free(src);
				return 1;
			}

			/* close the byte stream */
			opj_cio_close(cio);

			/* Write the index to disk */
			if (*indexfilename) {
				opj_bool bSuccess;
				bSuccess = write_index_file(&cstr_info, indexfilename);
				if (bSuccess) {
					fprintf(stderr, "Failed to output index file\n");
				}
			}
		}
		break;

		default:
			fprintf(stderr, "skipping file..\n");
			continue;
	}

		/* free the memory containing the code-stream */
		free(src);
		src = NULL;

		/* free remaining structures */
		if(dinfo) {
			opj_destroy_decompress(dinfo);
		}
		/* free codestream information structure */
		if (*indexfilename)	
			opj_destroy_cstr_info(&cstr_info);
		/* free image data structure */
		opj_image_destroy(image);

	}

	fclose(fout);

  return EXIT_SUCCESS;
}
Ejemplo n.º 21
0
static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
{
    LibOpenJPEGContext *ctx = avctx->priv_data;
    int err = AVERROR(ENOMEM);

    opj_set_default_encoder_parameters(&ctx->enc_params);

    ctx->enc_params.cp_rsiz = ctx->profile;
    ctx->enc_params.mode = !!avctx->global_quality;
    ctx->enc_params.cp_cinema = ctx->cinema_mode;
    ctx->enc_params.prog_order = ctx->prog_order;
    ctx->enc_params.numresolution = ctx->numresolution;
    ctx->enc_params.cp_disto_alloc = ctx->disto_alloc;
    ctx->enc_params.cp_fixed_alloc = ctx->fixed_alloc;
    ctx->enc_params.cp_fixed_quality = ctx->fixed_quality;
    ctx->enc_params.tcp_numlayers = ctx->numlayers;
    ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;

    if (ctx->cinema_mode > 0) {
        ctx->enc_params.irreversible = 1;
        ctx->enc_params.tcp_mct = 1;
        ctx->enc_params.tile_size_on = 0;
        /* no subsampling */
        ctx->enc_params.cp_tdx=1;
        ctx->enc_params.cp_tdy=1;
        ctx->enc_params.subsampling_dx = 1;
        ctx->enc_params.subsampling_dy = 1;
        /* Tile and Image shall be at (0,0) */
        ctx->enc_params.cp_tx0 = 0;
        ctx->enc_params.cp_ty0 = 0;
        ctx->enc_params.image_offset_x0 = 0;
        ctx->enc_params.image_offset_y0 = 0;
        /* Codeblock size= 32*32 */
        ctx->enc_params.cblockw_init = 32;
        ctx->enc_params.cblockh_init = 32;
        ctx->enc_params.csty |= 0x01;
        /* No ROI */
        ctx->enc_params.roi_compno = -1;

        if (ctx->enc_params.prog_order != CPRL) {
            av_log(avctx, AV_LOG_ERROR, "prog_order forced to CPRL\n");
            ctx->enc_params.prog_order = CPRL;
        }
        ctx->enc_params.tp_flag = 'C';
        ctx->enc_params.tp_on = 1;
    }

    ctx->compress = opj_create_compress(ctx->format);
    if (!ctx->compress) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n");
        return AVERROR(ENOMEM);
    }

    ctx->image = mj2_create_image(avctx, &ctx->enc_params);
    if (!ctx->image) {
        av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
        err = AVERROR(EINVAL);
        goto fail;
    }

    avctx->coded_frame = av_frame_alloc();
    if (!avctx->coded_frame) {
        av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
        goto fail;
    }

    memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t));
    ctx->event_mgr.info_handler    = info_callback;
    ctx->event_mgr.error_handler = error_callback;
    ctx->event_mgr.warning_handler = warning_callback;
    opj_set_event_mgr((opj_common_ptr) ctx->compress, &ctx->event_mgr, avctx);

    return 0;

fail:
    opj_destroy_compress(ctx->compress);
    ctx->compress = NULL;
    opj_image_destroy(ctx->image);
    ctx->image = NULL;
    av_freep(&avctx->coded_frame);
    return err;
}
Ejemplo n.º 22
0
int main(int argc, char **argv) {
	opj_dparameters_t parameters;	/* decompression parameters */
	img_fol_t img_fol;
	opj_event_mgr_t event_mgr;		/* event manager */
	opj_image_t *image = NULL;
	FILE *fsrc = NULL;
	unsigned char *src = NULL;
	int file_length;
	int num_images;
	int i,imageno;
	dircnt_t *dirptr = NULL;
	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
	opj_cio_t *cio = NULL;
	opj_codestream_info_t cstr_info;  /* Codestream information structure */
	char indexfilename[OPJ_PATH_LEN];	/* index file name */

	/* configure the event callbacks (not required) */
	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 decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);

	/* 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_decoder(argc, argv, &parameters,&img_fol, indexfilename) == 1) {
		return 1;
	}

	/* Initialize reading of directory */
	if(img_fol.set_imgdir==1){	
		num_images=get_num_images(img_fol.imgdirpath);

		dirptr=(dircnt_t*)malloc(sizeof(dircnt_t));
		if(dirptr){
			dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char));	/* Stores at max 10 image file names*/
			dirptr->filename = (char**) malloc(num_images*sizeof(char*));

			if(!dirptr->filename_buf){
				return 1;
			}
			for(i=0;i<num_images;i++){
				dirptr->filename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN;
			}
		}
		if(load_images(dirptr,img_fol.imgdirpath)==1){
			return 1;
		}
		if (num_images==0){
			fprintf(stdout,"Folder is empty\n");
			return 1;
		}
	}else{
		num_images=1;
	}

	/*Encoding image one by one*/
	for(imageno = 0; imageno < num_images ; imageno++)	{
		image = NULL;
		fprintf(stderr,"\n");

		if(img_fol.set_imgdir==1){
			if (get_next_file(imageno, dirptr,&img_fol, &parameters)) {
				fprintf(stderr,"skipping file...\n");
				continue;
			}
		}

		/* read the input file and put it in memory */
		/* ---------------------------------------- */
		fsrc = fopen(parameters.infile, "rb");
		if (!fsrc) {
			fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
			return 1;
		}
		fseek(fsrc, 0, SEEK_END);
		file_length = ftell(fsrc);
		fseek(fsrc, 0, SEEK_SET);
		src = (unsigned char *) malloc(file_length);
		if (fread(src, 1, file_length, fsrc) != (size_t)file_length)
		{
			free(src);
			fclose(fsrc);
			fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n");
			return 1;
		}
		fclose(fsrc);

		/* decode the code-stream */
		/* ---------------------- */

		switch(parameters.decod_format) {
		case J2K_CFMT:
		{
			/* JPEG-2000 codestream */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_J2K);

			/* 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, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			if (*indexfilename)				/* If need to extract codestream information*/
				image = opj_decode_with_info(dinfo, cio, &cstr_info);
			else
				image = opj_decode(dinfo, cio);
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				free(src);
				return 1;
			}

			/* close the byte stream */
			opj_cio_close(cio);

			/* Write the index to disk */
			if (*indexfilename) {
				opj_bool bSuccess;
				bSuccess = write_index_file(&cstr_info, indexfilename);
				if (bSuccess) {
					fprintf(stderr, "Failed to output index file\n");
				}
			}
		}
		break;

		case JP2_CFMT:
		{
			/* JPEG 2000 compressed image data */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_JP2);

			/* 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 the current image and user parameters */
			opj_setup_decoder(dinfo, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			if (*indexfilename)				/* If need to extract codestream information*/
				image = opj_decode_with_info(dinfo, cio, &cstr_info);
			else
				image = opj_decode(dinfo, cio);			
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				free(src);
				return 1;
			}

			/* close the byte stream */
			opj_cio_close(cio);

			/* Write the index to disk */
			if (*indexfilename) {
				opj_bool bSuccess;
				bSuccess = write_index_file(&cstr_info, indexfilename);
				if (bSuccess) {
					fprintf(stderr, "Failed to output index file\n");
				}
			}
		}
		break;

		case JPT_CFMT:
		{
			/* JPEG 2000, JPIP */

			/* get a decoder handle */
			dinfo = opj_create_decompress(CODEC_JPT);

			/* 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, &parameters);

			/* open a byte stream */
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			/* decode the stream and fill the image structure */
			if (*indexfilename)				/* If need to extract codestream information*/
				image = opj_decode_with_info(dinfo, cio, &cstr_info);
			else
				image = opj_decode(dinfo, cio);
			if(!image) {
				fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
				opj_destroy_decompress(dinfo);
				opj_cio_close(cio);
				free(src);
				return 1;
			}

			/* close the byte stream */
			opj_cio_close(cio);

			/* Write the index to disk */
			if (*indexfilename) {
				opj_bool bSuccess;
				bSuccess = write_index_file(&cstr_info, indexfilename);
				if (bSuccess) {
					fprintf(stderr, "Failed to output index file\n");
				}
			}
		}
		break;

		default:
			fprintf(stderr, "skipping file..\n");
			continue;
	}

		/* free the memory containing the code-stream */
		free(src);
		src = NULL;

	if(image->color_space == CLRSPC_SYCC)
   {
	color_sycc_to_rgb(image);
   }

	if(image->icc_profile_buf)
   {
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
	color_apply_icc_profile(image);
#endif

	free(image->icc_profile_buf);
	image->icc_profile_buf = NULL; image->icc_profile_len = 0;
   }

		/* create output image */
		/* ------------------- */
		switch (parameters.cod_format) {
		case PXM_DFMT:			/* PNM PGM PPM */
			if (imagetopnm(image, parameters.outfile)) {
				fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
			}
			break;

		case PGX_DFMT:			/* PGX */
			if(imagetopgx(image, parameters.outfile)){
				fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
			}
			break;

		case BMP_DFMT:			/* BMP */
			if(imagetobmp(image, parameters.outfile)){
				fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
			}
			break;
#ifdef HAVE_LIBTIFF
		case TIF_DFMT:			/* TIFF */
			if(imagetotif(image, parameters.outfile)){
				fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
			}
			break;
#endif /* HAVE_LIBTIFF */
		case RAW_DFMT:			/* RAW */
			if(imagetoraw(image, parameters.outfile)){
				fprintf(stdout,"Error generating raw file. Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile);
			}
			break;

		case TGA_DFMT:			/* TGA */
			if(imagetotga(image, parameters.outfile)){
				fprintf(stdout,"Error generating tga file. Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile);
			}
			break;
#ifdef HAVE_LIBPNG
		case PNG_DFMT:			/* PNG */
			if(imagetopng(image, parameters.outfile)){
				fprintf(stdout,"Error generating png file. Outfile %s not generated\n",parameters.outfile);
			}
			else {
				fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile);
			}
			break;
#endif /* HAVE_LIBPNG */
/* Can happen if output file is TIFF or PNG
 * and HAVE_LIBTIF or HAVE_LIBPNG is undefined
*/
			default:
				fprintf(stderr,"Outfile %s not generated\n",parameters.outfile);
		}

		/* free remaining structures */
		if(dinfo) {
			opj_destroy_decompress(dinfo);
		}
		/* free codestream information structure */
		if (*indexfilename)	
			opj_destroy_cstr_info(&cstr_info);
		/* free image data structure */
		opj_image_destroy(image);

	}
	return 0;
}
Ejemplo n.º 23
0
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
	//
	// FIXME: Get the comment field out of the texture
	//

	LLTimer decode_timer;

	opj_dparameters_t parameters;	/* decompression parameters */
	opj_event_mgr_t event_mgr;		/* event manager */
	opj_image_t *image = NULL;

	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
	opj_cio_t *cio = NULL;


	/* configure the event callbacks (not required) */
	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 decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);

	parameters.cp_reduce = base.getRawDiscardLevel();

	/* decode the code-stream */
	/* ---------------------- */

	/* JPEG-2000 codestream */

	/* get a decoder handle */
	dinfo = opj_create_decompress(CODEC_J2K);

	/* 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, &parameters);

	/* open a byte stream */
	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());

	/* decode the stream and fill the image structure */
	image = opj_decode(dinfo, cio);

	/* close the byte stream */
	opj_cio_close(cio);

	/* free remaining structures */
	if(dinfo)
	{
		opj_destroy_decompress(dinfo);
	}

	// The image decode failed if the return was NULL or the component
	// count was zero.  The latter is just a sanity check before we
	// dereference the array.
	if(!image || !image->numcomps)
	{
		LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
		if (image)
		{
			opj_image_destroy(image);
		}

		return TRUE; // done
	}

	// sometimes we get bad data out of the cache - check to see if the decode succeeded
	for (S32 i = 0; i < image->numcomps; i++)
	{
		if (image->comps[i].factor != base.getRawDiscardLevel())
		{
			// if we didn't get the discard level we're expecting, fail
			opj_image_destroy(image);
			base.mDecoding = FALSE;
			return TRUE;
		}
	}
	
	if(image->numcomps <= first_channel)
	{
		llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl;
		if (image)
		{
			opj_image_destroy(image);
		}
			
		return TRUE;
	}

	// Copy image data into our raw image format (instead of the separate channel format

	S32 img_components = image->numcomps;
	S32 channels = img_components - first_channel;
	if( channels > max_channel_count )
		channels = max_channel_count;

	// Component buffers are allocated in an image width by height buffer.
	// The image placed in that buffer is ceil(width/2^factor) by
	// ceil(height/2^factor) and if the factor isn't zero it will be at the
	// top left of the buffer with black filled in the rest of the pixels.
	// It is integer math so the formula is written in ceildivpo2.
	// (Assuming all the components have the same width, height and
	// factor.)
	S32 comp_width = image->comps[0].w;
	S32 f=image->comps[0].factor;
	S32 width = ceildivpow2(image->x1 - image->x0, f);
	S32 height = ceildivpow2(image->y1 - image->y0, f);
	raw_image.resize(width, height, channels);
	U8 *rawp = raw_image.getData();

	// first_channel is what channel to start copying from
	// dest is what channel to copy to.  first_channel comes from the
	// argument, dest always starts writing at channel zero.
	for (S32 comp = first_channel, dest=0; comp < first_channel + channels;
		comp++, dest++)
	{
		if (image->comps[comp].data)
		{
			S32 offset = dest;
			for (S32 y = (height - 1); y >= 0; y--)
			{
				for (S32 x = 0; x < width; x++)
				{
					rawp[offset] = image->comps[comp].data[y*comp_width + x];
					offset += channels;
				}
			}
		}
		else // Some rare OpenJPEG versions have this bug.
		{
			LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
			opj_image_destroy(image);

			return TRUE; // done
		}
	}

	/* free image data structure */
	opj_image_destroy(image);

	return TRUE; // done
}
Ejemplo n.º 24
0
dt_imageio_retval_t dt_imageio_open_j2k(dt_image_t *img, const char *filename, dt_mipmap_cache_allocator_t a)
{
  opj_dparameters_t parameters;   /* decompression parameters */
  opj_event_mgr_t event_mgr;      /* event manager */
  opj_image_t *image = NULL;
  FILE *fsrc = NULL;
  unsigned char *src = NULL;
  int file_length;
  opj_dinfo_t* dinfo = NULL;      /* handle to a decompressor */
  opj_cio_t *cio = NULL;
  OPJ_CODEC_FORMAT codec;
  int ret = DT_IMAGEIO_FILE_CORRUPTED;

  int file_format = get_file_format(filename);
  if(file_format == -1) return DT_IMAGEIO_FILE_CORRUPTED;

  if(!img->exif_inited)
    (void) dt_exif_read(img, filename);

  /* read the input file and put it in memory */
  /* ---------------------------------------- */
  fsrc = fopen(filename, "rb");
  if(!fsrc)
  {
    fprintf(stderr, "[j2k_open] Error: failed to open `%s' for reading\n", filename);
    return DT_IMAGEIO_FILE_NOT_FOUND;
  }
  fseek(fsrc, 0, SEEK_END);
  file_length = ftell(fsrc);
  fseek(fsrc, 0, SEEK_SET);
  src = (unsigned char *) malloc(file_length);
  if(fread(src, 1, file_length, fsrc) != (size_t)file_length)
  {
    free(src);
    fclose(fsrc);
    fprintf(stderr, "[j2k_open] Error: fread returned a number of elements different from the expected.\n");
    return DT_IMAGEIO_FILE_NOT_FOUND;
  }
  fclose(fsrc);

  if(memcmp(JP2_HEAD, src, sizeof(JP2_HEAD)) == 0)
  {
    file_format = JP2_CFMT; // just in case someone used the wrong extension
  }
  else if(memcmp(J2K_HEAD, src, sizeof(J2K_HEAD)) == 0)
  {
    file_format = J2K_CFMT; // just in case someone used the wrong extension
  }
  else // this will also reject jpt files.
  {
    free(src);
    fprintf(stderr, "[j2k_open] Error: `%s' has unsupported file format.\n", filename);
    return DT_IMAGEIO_FILE_CORRUPTED;
  }

  /* configure the event callbacks (not required) */
  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 decoding parameters to default values */
  opj_set_default_decoder_parameters(&parameters);

  /* decode the code-stream */
  /* ---------------------- */
  if(file_format == J2K_CFMT)        /* JPEG-2000 codestream */
    codec = CODEC_J2K;
  else if(file_format == JP2_CFMT)   /* JPEG 2000 compressed image data */
    codec = CODEC_JP2;
  else if(file_format == JPT_CFMT)   /* JPEG 2000, JPIP */
    codec = CODEC_JPT;
  else
  {
    free(src);
    return DT_IMAGEIO_FILE_CORRUPTED; // can't happen
  }

  /* get a decoder handle */
  dinfo = opj_create_decompress(codec);

  /* 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, &parameters);

  /* open a byte stream */
  cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

  /* decode the stream and fill the image structure */
  image = opj_decode(dinfo, cio);

  /* close the byte stream */
  opj_cio_close(cio);

  /* free the memory containing the code-stream */
  free(src);

  if(!image)
  {
    fprintf(stderr, "[j2k_open] Error: failed to decode image `%s'\n", filename);
    ret = DT_IMAGEIO_FILE_CORRUPTED;
    goto end_of_the_world;
  }

  if(image->color_space == CLRSPC_SYCC)
  {
    color_sycc_to_rgb(image);
  }

  //FIXME: openjpeg didn't have support for icc profiles before version 1.5
  // this needs some #ifdef magic and proper implementation
#ifdef HAVE_OPENJPEG_ICC
  if(image->icc_profile_buf)
  {
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
    color_apply_icc_profile(image);
#endif

    free(image->icc_profile_buf);
    image->icc_profile_buf = NULL;
    image->icc_profile_len = 0;
  }
#endif

  /* create output image */
  /* ------------------- */
  long signed_offsets[4] = {0, 0, 0, 0};
  int float_divs[4] = {1, 1, 1, 1};

  // some sanity checks
  if(image->numcomps == 0 || image->x1 == 0  || image->y1 == 0)
  {
    fprintf(stderr, "[j2k_open] Error: invalid raw image parameters in `%s'\n", filename);
    ret = DT_IMAGEIO_FILE_CORRUPTED;
    goto end_of_the_world;
  }

  for(int i = 0; i < image->numcomps; i++)
  {
    if(image->comps[i].w != image->x1 || image->comps[i].h != image->y1)
    {
      fprintf(stderr, "[j2k_open] Error: some component has different size in `%s'\n", filename);
      ret = DT_IMAGEIO_FILE_CORRUPTED;
      goto end_of_the_world;
    }
    if(image->comps[i].prec > 16)
    {
      fprintf(stderr,"[j2k_open] Error: precision %d is larger than 16 in `%s'\n", image->comps[1].prec, filename);
      ret = DT_IMAGEIO_FILE_CORRUPTED;
      goto end_of_the_world;
    }
  }

  img->width = image->x1;
  img->height = image->y1;
  img->bpp = 4*sizeof(float);

  float *buf = (float *)dt_mipmap_cache_alloc(img, DT_MIPMAP_FULL, a);
  if(!buf)
  {
    ret = DT_IMAGEIO_CACHE_FULL;
    goto end_of_the_world;
  }

  int i = image->numcomps;
  if(i > 4) i = 4;

  while(i)
  {
    i--;

    if(image->comps[i].sgnd)
      signed_offsets[i] =  1 << (image->comps[i].prec - 1);

    float_divs[i] = (1 << image->comps[i].prec) - 1;
  }

  // numcomps == 1 : grey  -> r = grey, g = grey, b = grey
  // numcomps == 2 : grey, alpha -> r = grey, g = grey, b = grey. put alpha into the mix?
  // numcomps == 3 : rgb -> rgb
  // numcomps == 4 : rgb, alpha -> rgb. put alpha into the mix?

  // first try: ignore alpha.
  if(image->numcomps < 3) // 1, 2 => grayscale
  {
    for(int i = 0; i < img->width * img->height; i++)
      buf[i*4 + 0] = buf[i*4 + 1] = buf[i*4 + 2] = (float)(image->comps[0].data[i] + signed_offsets[0]) / float_divs[0];
  }
  else // 3, 4 => rgb
  {
    for(int i = 0; i < img->width * img->height; i++)
      for(int k = 0; k < 3; k++) buf[i*4 + k] = (float)(image->comps[k].data[i] + signed_offsets[k]) / float_divs[k];
  }

  ret = DT_IMAGEIO_OK;

end_of_the_world:
  /* free remaining structures */
  if(dinfo)
    opj_destroy_decompress(dinfo);

  /* free image data structure */
  opj_image_destroy(image);

  return ret;
}
Ejemplo n.º 25
0
BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
{
	//
	// FIXME: We get metadata by decoding the ENTIRE image.
	//

	// Update the raw discard level
	base.updateRawDiscardLevel();

	opj_dparameters_t parameters;	/* decompression parameters */
	opj_event_mgr_t event_mgr;		/* event manager */
	opj_image_t *image = NULL;

	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
	opj_cio_t *cio = NULL;


	/* configure the event callbacks (not required) */
	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 decoding parameters to default values */
	opj_set_default_decoder_parameters(&parameters);

	// Only decode what's required to get the size data.
	parameters.cp_limit_decoding=LIMIT_TO_MAIN_HEADER;

	//parameters.cp_reduce = mRawDiscardLevel;

	/* decode the code-stream */
	/* ---------------------- */

	/* JPEG-2000 codestream */

	/* get a decoder handle */
	dinfo = opj_create_decompress(CODEC_J2K);

	/* 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, &parameters);

	/* open a byte stream */
	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());

	/* decode the stream and fill the image structure */
	image = opj_decode(dinfo, cio);

	/* close the byte stream */
	opj_cio_close(cio);

	/* free remaining structures */
	if(dinfo)
	{
		opj_destroy_decompress(dinfo);
	}

	if(!image)
	{
		llwarns << "ERROR -> getMetadata: failed to decode image!" << llendl;
		return FALSE;
	}

	// Copy image data into our raw image format (instead of the separate channel format
	S32 width = 0;
	S32 height = 0;

	S32 img_components = image->numcomps;
	width = image->x1 - image->x0;
	height = image->y1 - image->y0;
	base.setSize(width, height, img_components);

	/* free image data structure */
	opj_image_destroy(image);
	return TRUE;
}
Ejemplo n.º 26
0
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	if (handle) {
		opj_dparameters_t parameters;	// decompression parameters 
		opj_event_mgr_t event_mgr;		// event manager 
		opj_image_t *image = NULL;		// decoded image 

		BYTE *src = NULL; 
		long file_length;

		opj_dinfo_t* dinfo = NULL;	// handle to a decompressor 
		opj_cio_t *cio = NULL;

		FIBITMAP *dib = NULL;

		// check the file format
		if(!Validate(io, handle)) {
			return NULL;
		}

		// configure the event callbacks
		memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
		event_mgr.error_handler = jp2_error_callback;
		event_mgr.warning_handler = jp2_warning_callback;
		event_mgr.info_handler = NULL;

		// set decoding parameters to default values 
		opj_set_default_decoder_parameters(&parameters);

		try {
			// read the input file and put it in memory

			long start_pos = io->tell_proc(handle);
			io->seek_proc(handle, 0, SEEK_END);
			file_length = io->tell_proc(handle) - start_pos;
			io->seek_proc(handle, start_pos, SEEK_SET);
			src = (BYTE*)malloc(file_length * sizeof(BYTE));
			if(!src) {
				throw FI_MSG_ERROR_MEMORY;
			}
			if(io->read_proc(src, 1, file_length, handle) < 1) {
				throw "Error while reading input stream";
			}

			// decode the JPEG-2000 file

			// get a decoder handle 
			dinfo = opj_create_decompress(CODEC_JP2);
			
			// catch events using our callbacks
			opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);			

			// setup the decoder decoding parameters using user parameters 
			opj_setup_decoder(dinfo, &parameters);

			// open a byte stream 
			cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);

			// decode the stream and fill the image structure 
			image = opj_decode(dinfo, cio);
			if(!image) {
				throw "Failed to decode image!\n";
			}
			
			// close the byte stream 
			opj_cio_close(cio);
			cio = NULL;

			// free the memory containing the code-stream 
			free(src);
			src = NULL;

			// free the codec context
			opj_destroy_decompress(dinfo);

			// create output image 
			dib = J2KImageToFIBITMAP(s_format_id, image);
			if(!dib) throw "Failed to import JPEG2000 image";

			// free image data structure
			opj_image_destroy(image);

			return dib;

		} catch (const char *text) {
			if(src) free(src);
			if(dib) FreeImage_Unload(dib);
			// free remaining structures
			opj_destroy_decompress(dinfo);
			opj_image_destroy(image);
			// close the byte stream
			if(cio) opj_cio_close(cio);

			FreeImage_OutputMessageProc(s_format_id, text);

			return NULL;
		}
	}

	return NULL;
}
Ejemplo n.º 27
0
int main(int argc, char *argv[]) {
	mj2_dparameters_t mj2_parameters;			/* decompression parameters */
	opj_dinfo_t* dinfo; 
	opj_event_mgr_t event_mgr;		/* event manager */	
	opj_cio_t *cio = NULL;
  unsigned int tnum, snum;
  opj_mj2_t *movie;
  mj2_tk_t *track;
  mj2_sample_t *sample;
  unsigned char* frame_codestream;
  FILE *file, *outfile;
  char outfilename[50];
  opj_image_t *img = NULL;
	unsigned int max_codstrm_size = 0;
	double total_time = 0;
	unsigned int numframes = 0;
			
  if (argc != 3) {
    printf("Usage: %s inputfile.mj2 outputfile.yuv\n",argv[0]); 
    return 1;
  }
  
  file = fopen(argv[1], "rb");
  
  if (!file) {
    fprintf(stderr, "failed to open %s for reading\n", argv[1]);
    return 1;
  }
	
  /* Checking output file */
  outfile = fopen(argv[2], "w");
  if (!file) {
    fprintf(stderr, "failed to open %s for writing\n", argv[2]);
    return 1;
  }
  fclose(outfile);
	
	/*
	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 = error_callback;
	event_mgr.warning_handler = warning_callback;
	event_mgr.info_handler = NULL;
	
	/* get a MJ2 decompressor handle */
	dinfo = mj2_create_decompress();
	movie = (opj_mj2_t*)dinfo->mj2_handle;
	
	/* catch events using our callbacks and give a local context */
	opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);		

	memset(&mj2_parameters, 0, sizeof(mj2_dparameters_t));
	/* set J2K decoding parameters to default values */
	opj_set_default_decoder_parameters(&mj2_parameters.j2k_parameters);
	
	/* setup the decoder decoding parameters using user parameters */
	mj2_setup_decoder(movie, &mj2_parameters);
			
  if (mj2_read_struct(file, movie)) /* Creating the movie structure */
    return 1;	
	
  /* Decode first video track */
	for (tnum=0; tnum < (unsigned int)(movie->num_htk + movie->num_stk + movie->num_vtk); tnum++) {
		if (movie->tk[tnum].track_type == 0) 
			break;
	}
	
	if (movie->tk[tnum].track_type != 0) {
		printf("Error. Movie does not contain any video track\n");
		return 1;
	}
	
  track = &movie->tk[tnum];
	
  /* Output info on first video tracl */
  fprintf(stdout,"The first video track contains %d frames.\nWidth: %d, Height: %d \n\n",
    track->num_samples, track->w, track->h);
	
	max_codstrm_size = track->sample[0].sample_size-8;
	frame_codestream = (unsigned char*) malloc(max_codstrm_size * sizeof(unsigned char)); 

	numframes = track->num_samples;
	
  for (snum=0; snum < numframes; snum++)
  {
		double init_time = opj_clock();
		double elapsed_time;

    sample = &track->sample[snum];
		if (sample->sample_size-8 > max_codstrm_size) {
			max_codstrm_size =  sample->sample_size-8;
			if ((frame_codestream = (unsigned char*)
				realloc(frame_codestream, max_codstrm_size)) == NULL) {
				printf("Error reallocation memory\n");
				return 1;
			}; 		
		}
    fseek(file,sample->offset+8,SEEK_SET);
    fread(frame_codestream, sample->sample_size-8, 1, file);  /* Assuming that jp and ftyp markers size do */
		
		/* open a byte stream */
		cio = opj_cio_open((opj_common_ptr)dinfo, frame_codestream, sample->sample_size-8);
		
		img = opj_decode(dinfo, cio); /* Decode J2K to image */

#ifdef WANT_SYCC_TO_RGB
	if(img->color_space == CLRSPC_SYCC)
  {
	color_sycc_to_rgb(img);
  }
#endif

	if(img->icc_profile_buf)
  {
#if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2)
	color_apply_icc_profile(img);
#endif

	free(img->icc_profile_buf);
	img->icc_profile_buf = NULL; img->icc_profile_len = 0;
  }

    if (((img->numcomps == 3) && (img->comps[0].dx == img->comps[1].dx / 2) 
      && (img->comps[0].dx == img->comps[2].dx / 2 ) && (img->comps[0].dx == 1)) 
      || (img->numcomps == 1)) {
      
      if (!imagetoyuv(img, argv[2]))	/* Convert image to YUV */
				return 1;
    }
    else if ((img->numcomps == 3) && 
      (img->comps[0].dx == 1) && (img->comps[1].dx == 1)&&
      (img->comps[2].dx == 1))/* If YUV 4:4:4 input --> to bmp */
    {
      fprintf(stdout,"The frames will be output in a bmp format (output_1.bmp, ...)\n");
      sprintf(outfilename,"output_%d.bmp",snum);
      if (imagetobmp(img, outfilename))	/* Convert image to BMP */
				return 1;
      
    }
    else {
      fprintf(stdout,"Image component dimensions are unknown. Unable to output image\n");
      fprintf(stdout,"The frames will be output in a j2k file (output_1.j2k, ...)\n");
			
      sprintf(outfilename,"output_%d.j2k",snum);
      outfile = fopen(outfilename, "wb");
      if (!outfile) {
				fprintf(stderr, "failed to open %s for writing\n",outfilename);
				return 1;
      }
      fwrite(frame_codestream,sample->sample_size-8,1,outfile);
      fclose(outfile);
    }
		/* close the byte stream */
		opj_cio_close(cio);	
		/* free image data structure */
		opj_image_destroy(img);
		elapsed_time = opj_clock()-init_time;
		fprintf(stderr, "Frame number %d/%d decoded in %.2f mseconds\n", snum + 1, numframes, elapsed_time*1000);
		total_time += elapsed_time;

  }
	
	free(frame_codestream);	
  fclose(file);	

	/* free remaining structures */
	if(dinfo) {
		mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle);
	}
	free(dinfo);
	
	fprintf(stdout, "%d frame(s) correctly decompressed\n", snum);
	fprintf(stdout,"Total decoding time: %.2f seconds (%.1f fps)\n", total_time, (float)numframes/total_time);
		
  return 0;
}
Ejemplo n.º 28
0
    void OpenJpegDecoder::PerformDecode(DecodeRequestPtr request)
    {
        if (!request)
            return;

        DecodeResultPtr result(new DecodeResult());

        result->id_ = request->id_;
        result->level_ = -1; // no level decoded yet
        result->max_levels_ = 5;
        result->original_width_ = 0;
        result->original_height_ = 0;
        result->components_ = 0;
        result->tag_ = request->tag_;

        // Guard against OpenJpeg crash on illegal data at an early phase
        unsigned char *data = (unsigned char *)request->source_->GetData();
        if (data[0] != 0xFF)
        {
            TextureDecoderModule::LogError("Invalid data passed to PerformDecode!");
            QueueResult<DecodeResult>(result);
            return;
        }

        opj_dinfo_t* dinfo = 0; // decoder
        opj_image_t *image = 0; // decoded image
        opj_dparameters_t parameters; // decoder parameters
        opj_cio_t *cio = 0; // decode stream
        opj_codestream_info_t cstr_info;  // codestream info
        memset(&cstr_info, 0, sizeof(opj_codestream_info_t));
       
        opj_event_mgr_t event_mgr; // decode event manager
        memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
        event_mgr.error_handler = HandleError;
        //event_mgr.warning_handler = HandleWarning;
        //event_mgr.info_handler = HandleInfo;
        
        opj_set_default_decoder_parameters(&parameters);
        parameters.cp_reduce = request->level_;
        
        dinfo = opj_create_decompress(CODEC_J2K);
        opj_setup_decoder(dinfo, &parameters);
        opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, this);
        
        cio = opj_cio_open((opj_common_ptr)dinfo, (unsigned char *)request->source_->GetData(), request->source_->GetSize());
        
        image = opj_decode_with_info(dinfo, cio, &cstr_info);
        result->max_levels_ = cstr_info.numlayers;

        opj_cio_close(cio);
        opj_destroy_decompress(dinfo);
        
        if ((image) && (image->numcomps))
        {
            result->original_width_ = image->x1 - image->x0;
            result->original_height_ = image->y1 - image->y0;
            result->components_ = image->numcomps;
            result->level_ = request->level_;

            // Assume all components are same size
            int actual_width = image->comps[0].w;
            int actual_height = image->comps[0].h;

            // Create a (possibly temporary, if no-one stores the pointer) raw texture resource
            Foundation::ResourcePtr resource(new TextureResource(request->source_->GetId(), actual_width, actual_height, image->numcomps));
            TextureResource* texture = checked_static_cast<TextureResource*>(resource.get());
            u8* data = texture->GetData();
            texture->SetLevel(request->level_);
            for (int y = 0; y < actual_height; ++y)
            {
                for (int x = 0; x < actual_width; ++x)
                {
                    for (int c = 0; c < image->numcomps; ++c)
                    {
                        *data = image->comps[c].data[y * actual_width + x];
                        data++;
                    }
                }
            }
     
            result->texture_ = resource;
        }

        if (image)
            opj_image_destroy(image);

        QueueResult<DecodeResult>(result);
    }
Ejemplo n.º 29
0
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	if ((dib) && (handle)) {
		BOOL bSuccess;
		opj_cparameters_t parameters;		// compression parameters 
		opj_event_mgr_t event_mgr;			// event manager 
		opj_image_t *image = NULL;			// image to encode
		opj_cinfo_t* cinfo = NULL;			// codec context
		opj_cio_t *cio = NULL;				// memory byte stream

		// configure the event callbacks
		memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
		event_mgr.error_handler = jp2_error_callback;
		event_mgr.warning_handler = jp2_warning_callback;
		event_mgr.info_handler = NULL;

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

		parameters.tcp_numlayers = 0;
		// if no rate entered, apply a 16:1 rate by default
		if(flags == JP2_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;
		}
		parameters.tcp_numlayers++;
		parameters.cp_disto_alloc = 1;

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

			// encode the destination image

			// get a J2K compressor handle
			cinfo = opj_create_compress(CODEC_JP2);

			// catch events using our callbacks
			opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, NULL);			

			// setup the encoder parameters using the current image and using user parameters
			opj_setup_encoder(cinfo, &parameters, 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(cinfo, cio, image, NULL/*parameters.index*/);
			if (!bSuccess) {
				throw "Failed to encode image";
			}
			int codestream_length = cio_tell(cio);

			// write the buffer to user's IO handle
			io->write_proc(cio->buffer, 1, codestream_length, handle);

			// close and free the byte stream 
			opj_cio_close(cio);

			// free remaining compression structures
			opj_destroy_compress(cinfo);
			
			// free image data
			opj_image_destroy(image);

			return TRUE;

		} catch (const char *text) {
			if(cio) opj_cio_close(cio);
			if(cinfo) opj_destroy_compress(cinfo);
			if(image) opj_image_destroy(image);
			FreeImage_OutputMessageProc(s_format_id, text);
			return FALSE;
		}
	}

	return FALSE;
}
Ejemplo n.º 30
0
fz_pixmap *
fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *defcs)
{
	fz_pixmap *img;
	opj_event_mgr_t evtmgr;
	opj_dparameters_t params;
	opj_dinfo_t *info;
	opj_cio_t *cio;
	opj_image_t *jpx;
	fz_colorspace *colorspace;
	unsigned char *p;
	int format;
	int a, n, w, h, depth, sgnd;
	int x, y, k, v;

	if (size < 2)
		fz_throw(ctx, "not enough data to determine image format");

	/* Check for SOC marker -- if found we have a bare J2K stream */
	if (data[0] == 0xFF && data[1] == 0x4F)
		format = CODEC_J2K;
	else
		format = CODEC_JP2;

	memset(&evtmgr, 0, sizeof(evtmgr));
	evtmgr.error_handler = fz_opj_error_callback;
	evtmgr.warning_handler = fz_opj_warning_callback;
	evtmgr.info_handler = fz_opj_info_callback;

	opj_set_default_decoder_parameters(&params);

	info = opj_create_decompress(format);
	opj_set_event_mgr((opj_common_ptr)info, &evtmgr, ctx);
	opj_setup_decoder(info, &params);

	cio = opj_cio_open((opj_common_ptr)info, data, size);

	jpx = opj_decode(info, cio);

	opj_cio_close(cio);
	opj_destroy_decompress(info);

	if (!jpx)
		fz_throw(ctx, "opj_decode failed");

	for (k = 1; k < jpx->numcomps; k++)
	{
		if (jpx->comps[k].w != jpx->comps[0].w)
			fz_throw(ctx, "image components have different width");
		if (jpx->comps[k].h != jpx->comps[0].h)
			fz_throw(ctx, "image components have different height");
		if (jpx->comps[k].prec != jpx->comps[0].prec)
			fz_throw(ctx, "image components have different precision");
	}

	n = jpx->numcomps;
	w = jpx->comps[0].w;
	h = jpx->comps[0].h;
	depth = jpx->comps[0].prec;
	sgnd = jpx->comps[0].sgnd;

	if (jpx->color_space == CLRSPC_SRGB && n == 4) { n = 3; a = 1; }
	else if (jpx->color_space == CLRSPC_SYCC && n == 4) { n = 3; a = 1; }
	else if (n == 2) { n = 1; a = 1; }
	else if (n > 4) { n = 4; a = 1; }
	else { a = 0; }

	if (defcs)
	{
		if (defcs->n == n)
		{
			colorspace = defcs;
		}
		else
		{
			fz_warn(ctx, "jpx file and dict colorspaces do not match");
			defcs = NULL;
		}
	}

	if (!defcs)
	{
		switch (n)
		{
		case 1: colorspace = fz_device_gray; break;
		case 3: colorspace = fz_device_rgb; break;
		case 4: colorspace = fz_device_cmyk; break;
		}
	}

	fz_try(ctx)
	{
		img = fz_new_pixmap(ctx, colorspace, w, h);
	}
	fz_catch(ctx)
	{
		opj_image_destroy(jpx);
		fz_throw(ctx, "out of memory");
	}

	p = img->samples;
	for (y = 0; y < h; y++)
	{
		for (x = 0; x < w; x++)
		{
			for (k = 0; k < n + a; k++)
			{
				v = jpx->comps[k].data[y * w + x];
				if (sgnd)
					v = v + (1 << (depth - 1));
				if (depth > 8)
					v = v >> (depth - 8);
				*p++ = v;
			}
			if (!a)
				*p++ = 255;
		}
	}

	if (a)
	{
		if (n == 4)
		{
			fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb, w, h);
			fz_convert_pixmap(ctx, img, tmp);
			fz_drop_pixmap(ctx, img);
			img = tmp;
		}
		fz_premultiply_pixmap(ctx, img);
	}

	opj_image_destroy(jpx);

	return img;
}