From e023107e97039221f408e0ff9eca8a5a5e23466b Mon Sep 17 00:00:00 2001 From: Antonin Descampe Date: Thu, 17 Feb 2011 20:01:14 +0000 Subject: [PATCH] now allows 16-bit precision for mj2 encoding and decoding (solves Issue 49 and Issue 63). Credit to Winfried. --- CHANGES | 7 ++-- mj2/frames_to_mj2.c | 11 +++--- mj2/mj2_convert.c | 84 +++++++++++++++++++++++++++++++-------------- 3 files changed, 70 insertions(+), 32 deletions(-) diff --git a/CHANGES b/CHANGES index d9f2ed64..1b24c435 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,9 @@ What's New for OpenJPEG ! : changed + : added +February 17, 2011 +* [antonin] now allows 16-bit precision for mj2 encoding and decoding (solves Issue 49 and Issue 63). Credit to Winfried. + February 9, 2011 ! [antonin] renamed "java sources" to "java-sources" to avoid blank space - [antonin] removed opj_config.h.in from svn, as it is automaticaly generated by autoheader when calling ./bootstrap.sh @@ -17,7 +20,7 @@ January 30, 2011 - [antonin] removed depcomp file from trunk (automatically copied by automake in main folder) January 29, 2011 -* [antonin] removed 'é' in license header to prevent warning C4819 (see http://code.google.com/p/openjpeg/issues/detail?id=57). +* [antonin] removed 'é' in license header to prevent warning C4819 (see Issue 57). January 24, 2011 - [antonin] remove more obsolete VS files. Left only mj2_to_metadata VS files, as this is the only executable not yet handled by CMake. @@ -34,7 +37,7 @@ January 18, 2011 ! [rdieter] cmake: SOVERSION change to 1 (from 1.4) to match auto-tools January 17, 2011 -- [rdieter] remove generated files (ticket 52) +- [rdieter] remove generated files (Issue 52) January 16, 2011 * [antonin] convert.c: inclusion of endian.h has to be different on APPLE platforms diff --git a/mj2/frames_to_mj2.c b/mj2/frames_to_mj2.c index f689b00d..f6b77658 100644 --- a/mj2/frames_to_mj2.c +++ b/mj2/frames_to_mj2.c @@ -251,7 +251,7 @@ int main(int argc, char **argv) opj_cinfo_t* cinfo; bool bSuccess; int numframes; - int prec = 0; + int prec = 8;/* DEFAULT */ double total_time = 0; memset(&mj2_parameters, 0, sizeof(mj2_cparameters_t)); @@ -623,7 +623,11 @@ int main(int argc, char **argv) "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"); @@ -668,9 +672,6 @@ int main(int argc, char **argv) + 1 : mj2_parameters.Dim[1] + (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy + 1; mj2_parameters.numcomps = 3; /* YUV files only have 3 components */ - - if(prec < 1 || prec > 32) prec = 8; /* DEFAULT */ - mj2_parameters.prec = prec; j2k_parameters->tcp_mct = 0; diff --git a/mj2/mj2_convert.c b/mj2/mj2_convert.c index d0c1860f..3e6c1229 100644 --- a/mj2/mj2_convert.c +++ b/mj2/mj2_convert.c @@ -104,23 +104,26 @@ opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters) char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters_t *parameters, char* infile) { int i, compno; - int offset, size, max, prec_size; + int offset, size, max, prec_bytes, is_16, v; long end_of_f, position; int numcomps = 3; int subsampling_dx = parameters->subsampling_dx; int subsampling_dy = parameters->subsampling_dy; FILE *yuvfile; - + int *data; + unsigned char uc; + yuvfile = fopen(infile,"rb"); if (!yuvfile) { fprintf(stderr, "failed to open %s for readings\n",parameters->infile); return 1; } - prec_size = (tk->depth + 7)/8;/* bytes of precision */ + is_16 = (tk->depth > 8); + prec_bytes = (is_16?2:1); offset = (int) ((double) (frame_num * tk->w * tk->h) * (1.0 + 1.0 * (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy))); - offset *= prec_size; + offset *= prec_bytes; fseek(yuvfile, 0, SEEK_END); end_of_f = ftell(yuvfile); @@ -140,19 +143,25 @@ char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters img->y1 = !tk->Dim[1] ? (tk->h - 1) * subsampling_dy + 1 : tk->Dim[1] + (tk->h - 1) * subsampling_dy + 1; - size = tk->w * tk->h * prec_size; + size = tk->w * tk->h * prec_bytes; for(compno = 0; compno < numcomps; compno++) { max = size/(img->comps[compno].dx * img->comps[compno].dy); + data = img->comps[compno].data; for (i = 0; i < max && !feof(yuvfile); i++) { - if (!fread(&img->comps[compno].data[i], 1, 1, yuvfile)) + v = 0; + fread(&uc, 1, 1, yuvfile); + v = uc; + + if(is_16) { - fprintf(stderr, "Error reading %s file !!\n", infile); - return 1; + fread(&uc, 1, 1, yuvfile); + v |= (uc<<8); } + *data++ = v; } } fclose(yuvfile); @@ -173,8 +182,10 @@ char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters bool imagetoyuv(opj_image_t * img, char *outfile) { FILE *f; - int i; - + int *data; + int i, v, is_16, prec_bytes; + unsigned char buf[2]; + if (img->numcomps == 3) { if (img->comps[0].dx != img->comps[1].dx / 2 || img->comps[1].dx != img->comps[2].dx) { @@ -193,38 +204,61 @@ bool imagetoyuv(opj_image_t * img, char *outfile) fprintf(stderr, "failed to open %s for writing\n", outfile); return false; } - + is_16 = (img->comps[0].prec > 8); + prec_bytes = (is_16?2:1); + data = img->comps[0].data; for (i = 0; i < (img->comps[0].w * img->comps[0].h); i++) { - unsigned char y; - y = img->comps[0].data[i]; - fwrite(&y, 1, 1, f); + v = *data++; + buf[0] = (unsigned char)v; + + if(is_16) buf[1] = (unsigned char)(v>>8); + + fwrite(buf, 1, prec_bytes, f); } if (img->numcomps == 3) { + data = img->comps[1].data; + for (i = 0; i < (img->comps[1].w * img->comps[1].h); i++) { - unsigned char cb; - cb = img->comps[1].data[i]; - fwrite(&cb, 1, 1, f); + v = *data++; + buf[0] = (unsigned char)v; + + if(is_16) buf[1] = (unsigned char)(v>>8); + + fwrite(buf, 1, prec_bytes, f); } - + data = img->comps[2].data; for (i = 0; i < (img->comps[2].w * img->comps[2].h); i++) { - unsigned char cr; - cr = img->comps[2].data[i]; - fwrite(&cr, 1, 1, f); + v = *data++; + buf[0] = (unsigned char)v; + + if(is_16) buf[1] = (unsigned char)(v>>8); + + fwrite(buf, 1, prec_bytes, f); } } else if (img->numcomps == 1) { +/* fake CbCr values */ + if(is_16) + { + buf[0] = 255; + if(img->comps[0].prec == 10) buf[1] = 1; + else + if(img->comps[0].prec == 12) buf[1] = 3; + else + buf[1] = 125; + } + else buf[0] = 125; + for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) { - unsigned char cb = 125; - fwrite(&cb, 1, 1, f); + fwrite(buf, 1, prec_bytes, f); } for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) { - unsigned char cr = 125; - fwrite(&cr, 1, 1, f); + fwrite(buf, 1, prec_bytes, f); } } fclose(f);