diff --git a/ChangeLog b/ChangeLog index 5e7a3331..11584840 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ What's New for OpenJPEG ! : changed + : added +September 18, 2007 +* [Parvatha] Fixed issues with Reading and Writing TIF images in convert.c to avoid segmentation fault. +* [Parvatha] Fixed issues relating to using user specified rates for CINEMA option for multiple images. + September 17, 2007 * [FOD] Fixed issues with cstr_info when codestream has components with different number of resolutions. ! [FOD] OpenJPEG library interface modified to retain compatibility with version 1.2 diff --git a/codec/convert.c b/codec/convert.c index 013bc152..5e9f4969 100644 --- a/codec/convert.c +++ b/codec/convert.c @@ -1423,8 +1423,9 @@ typedef struct tiff_infoheader{ }tiff_infoheader_t; int imagetotif(opj_image_t * image, const char *outfile) { - int width, height; - int bps,index; + int width, height, imgsize; + int bps,index,adjust = 0; + int last_i=0; TIFF *tif; tdata_t buf; tstrip_t strip; @@ -1448,7 +1449,8 @@ int imagetotif(opj_image_t * image, const char *outfile) { } width = image->comps[0].w; - height= image->comps[0].h; + height = image->comps[0].h; + imgsize = image->comps[0].w * image->comps[0].h ; bps = image->comps[0].prec; /* Set tags */ TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); @@ -1465,39 +1467,163 @@ int imagetotif(opj_image_t * image, const char *outfile) { index=0; strip_size=0; strip_size=TIFFStripSize(tif); + adjust = image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0; for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { unsigned char *dat8; - int i; + int i, ssize; + ssize = TIFFStripSize(tif); dat8 = buf; if (image->comps[0].prec == 8){ - for (i=0; icomps[0].data[index] ; // R - dat8[i+1] = image->comps[1].data[index] ; // G - dat8[i+2] = image->comps[2].data[index] ; // B - index++; + for (i=0; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r ; // R + dat8[i+1] = g ; // G + dat8[i+2] = b ; // B + index++; + last_i = i+3; + }else + break; + } + if(last_i < ssize){ + for (i=last_i; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r ; // R + if(i+1 comps[0].prec == 12){ - for (i=0; icomps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4); - dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[1].data[index]>>8)& 0x0f); - dat8[i+2] = (image->comps[1].data[index]); - dat8[i+3] = (image->comps[2].data[index]>>8)<<4 | (image->comps[2].data[index]>>4); - dat8[i+4] = (image->comps[2].data[index]<<4)|((image->comps[0].data[index+1]>>8)& 0x0f); - dat8[i+5] = (image->comps[0].data[index+1]); - dat8[i+6] = (image->comps[1].data[index+1]>>8)<<4 | (image->comps[1].data[index+1]>>4); - dat8[i+7] = (image->comps[1].data[index+1]<<4)|((image->comps[2].data[index+1]>>8)& 0x0f); - dat8[i+8] = (image->comps[2].data[index+1]); - index+=2; + for (i=0; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + r1 = image->comps[0].data[index+1]; + g1 = image->comps[1].data[index+1]; + b1 = image->comps[2].data[index+1]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + r1 += adjust; + g1 += adjust; + b1 += adjust; + } + dat8[i+0] = (r >> 4); + dat8[i+1] = ((r & 0x0f) << 4 )|((g >> 8)& 0x0f); + dat8[i+2] = g ; + dat8[i+3] = (b >> 4); + dat8[i+4] = ((b & 0x0f) << 4 )|((r1 >> 8)& 0x0f); + dat8[i+5] = r1; + dat8[i+6] = (g1 >> 4); + dat8[i+7] = ((g1 & 0x0f)<< 4 )|((b1 >> 8)& 0x0f); + dat8[i+8] = b1; + index+=2; + last_i = i+9; + }else + break; + } + if(last_i < ssize){ + for (i= last_i; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + r1 = image->comps[0].data[index+1]; + g1 = image->comps[1].data[index+1]; + b1 = image->comps[2].data[index+1]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + r1 += adjust; + g1 += adjust; + b1 += adjust; + } + dat8[i+0] = (r >> 4); + if(i+1 > 8)& 0x0f); else break; + if(i+2 > 4); else break; + if(i+4 > 8)& 0x0f);else break; + if(i+5 > 4); else break; + if(i+7 > 8)& 0x0f);else break; + if(i+8 comps[0].prec == 16){ - for (i=0; icomps[0].data[index];//LSB - dat8[i+1] = (image->comps[0].data[index]>> 8);//MSB - dat8[i+2] = image->comps[1].data[index]; - dat8[i+3] = (image->comps[1].data[index]>> 8); - dat8[i+4] = image->comps[2].data[index]; - dat8[i+5] = (image->comps[2].data[index]>> 8); - index++; + for (i=0 ; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r;//LSB + dat8[i+1] = (r >> 8);//MSB + dat8[i+2] = g; + dat8[i+3] = (g >> 8); + dat8[i+4] = b; + dat8[i+5] = (b >> 8); + index++; + last_i = i+6; + }else + break; + } + if(last_i < ssize){ + for (i=0 ; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r;//LSB + if(i+1 > 8);else break;//MSB + if(i+2 > 8);else break; + if(i+4 > 8);else break; + index++; + }else + break; + } } }else{ fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec); @@ -1544,20 +1670,37 @@ int imagetotif(opj_image_t * image, const char *outfile) { dat8 = buf; if (image->comps[0].prec == 8){ for (i=0; icomps[0].data[index] ; + int r = 0; + r = image->comps[0].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + } + dat8[i+0] = r; index++; } }else if (image->comps[0].prec == 12){ for (i = 0; icomps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4); - dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[0].data[index+1]>>8)& 0x0f); - dat8[i+2] = (image->comps[0].data[index+1]); + int r = 0, r1 = 0; + r = image->comps[0].data[index]; + r1 = image->comps[0].data[index+1]; + if (image->comps[0].sgnd){ + r += adjust; + r1 += adjust; + } + dat8[i+0] = (r >> 4); + dat8[i+1] = ((r & 0x0f) << 4 )|((r1 >> 8)& 0x0f); + dat8[i+2] = r1 ; index+=2; } }else if (image->comps[0].prec == 16){ for (i=0; icomps[0].data[index]; - dat8[i+1] = (image->comps[0].data[index]>> 8); + int r = 0; + r = image->comps[0].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + } + dat8[i+0] = r; + dat8[i+1] = r >> 8; index++; } }else{ @@ -1590,6 +1733,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters) OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[3]; opj_image_t * image = NULL; + int imgsize; tif = TIFFOpen(filename, "r"); @@ -1649,6 +1793,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters) strip_size=0; strip_size=TIFFStripSize(tif); index = 0; + imgsize = image->comps[0].w * image->comps[0].h ; /* Read the Image components*/ for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { unsigned char *dat8; @@ -1658,39 +1803,48 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters) if (Info.tiBps==12){ for (i=0; icomps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4); - image->comps[1].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; - image->comps[2].data[index] = ( dat8[i+3]<<4) |(dat8[i+4]>>4); - image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5]; - image->comps[1].data[index+1] = ( dat8[i+6] <<4) |(dat8[i+7]>>4); - image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8]; - index+=2; + if((index < imgsize)&(index+1 < imgsize)){ + image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4); + image->comps[1].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; + image->comps[2].data[index] = ( dat8[i+3]<<4) |(dat8[i+4]>>4); + image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5]; + image->comps[1].data[index+1] = ( dat8[i+6] <<4) |(dat8[i+7]>>4); + image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8]; + index+=2; + }else + break; } } else if( Info.tiBps==16){ for (i=0; icomps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; // R - image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; // G - image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; // B - if(parameters->cp_cinema){/* Rounding to 12 bits*/ - image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ; - image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ; - image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ; - } - index++; + if(index < imgsize){ + image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; // R + image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; // G + image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; // B + if(parameters->cp_cinema){/* Rounding to 12 bits*/ + image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ; + image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ; + image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ; + } + index++; + }else + break; } } else if ( Info.tiBps==8){ for (i=0; icomps[0].data[index] = dat8[i+0]; // R - image->comps[1].data[index] = dat8[i+1]; // G - image->comps[2].data[index] = dat8[i+2]; // B - if(parameters->cp_cinema){/* Rounding to 12 bits*/ - image->comps[0].data[index] = image->comps[0].data[index] << 4 ; - image->comps[1].data[index] = image->comps[1].data[index] << 4 ; - image->comps[2].data[index] = image->comps[2].data[index] << 4 ; - } - index++; + if(index < imgsize){ + image->comps[0].data[index] = dat8[i+0];// R + image->comps[1].data[index] = dat8[i+1];// G + image->comps[2].data[index] = dat8[i+2];// B + if(parameters->cp_cinema){/* Rounding to 12 bits*/ + image->comps[0].data[index] = image->comps[0].data[index] << 4 ; + image->comps[1].data[index] = image->comps[1].data[index] << 4 ; + image->comps[2].data[index] = image->comps[2].data[index] << 4 ; + } + index++; + }else + break; } } else{ @@ -1744,21 +1898,30 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters) if (Info.tiBps==12){ for (i=0; icomps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4) ; - image->comps[0].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; - index+=2; + if(index < imgsize){ + image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4) ; + image->comps[0].data[index+1] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; + index+=2; + }else + break; } } else if( Info.tiBps==16){ for (i=0; icomps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; - index++; + if(index < imgsize){ + image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; + index++; + }else + break; } } else if ( Info.tiBps==8){ for (i=0; icomps[0].data[index] = dat8[i+0]; - index++; + if(index < imgsize){ + image->comps[0].data[index] = dat8[i+0]; + index++; + }else + break; } } else{ diff --git a/codec/image_to_j2k.c b/codec/image_to_j2k.c index d3027a81..06b1215e 100644 --- a/codec/image_to_j2k.c +++ b/codec/image_to_j2k.c @@ -80,6 +80,8 @@ typedef struct img_folder{ char set_imgdir; /** Enable Cod Format for output*/ char set_out_format; + /** User specified rate stored in case of cinema option*/ + float *rates; }img_fol_t; void encode_help_display() { @@ -482,7 +484,7 @@ void cinema_parameters(opj_cparameters_t *parameters){ } -void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image){ +void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){ int i; float temp_rate; opj_poc_t *POC = NULL; @@ -520,17 +522,19 @@ void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image){ switch (parameters->cp_cinema){ case CINEMA2K_24: case CINEMA4K_24: - for(i=0;itcp_numlayers;i++){ + for(i=0 ; itcp_numlayers ; i++){ temp_rate = 0 ; - if (parameters->tcp_rates[i]== 0){ + if (img_fol->rates[i]== 0){ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); }else{ temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (parameters->tcp_rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); + (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); if (temp_rate > CINEMA_24_CS ){ parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); + (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); + }else{ + parameters->tcp_rates[i]= img_fol->rates[i]; } } } @@ -538,17 +542,19 @@ void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image){ break; case CINEMA2K_48: - for(i=0;itcp_numlayers;i++){ + for(i=0 ; itcp_numlayers ; i++){ temp_rate = 0 ; - if (parameters->tcp_rates[i]== 0){ + if (img_fol->rates[i]== 0){ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); }else{ temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (parameters->tcp_rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); + (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); if (temp_rate > CINEMA_48_CS ){ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); + (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); + }else{ + parameters->tcp_rates[i]= img_fol->rates[i]; } } } @@ -1766,6 +1772,10 @@ int main(int argc, char **argv) { } if (parameters.cp_cinema){ + img_fol.rates = (float*)malloc(parameters.tcp_numlayers * sizeof(float)); + for(i=0; i< parameters.tcp_numlayers; i++){ + img_fol.rates[i] = parameters.tcp_rates[i]; + } cinema_parameters(¶meters); } @@ -1894,7 +1904,7 @@ int main(int argc, char **argv) { parameters.tcp_mct = image->numcomps == 3 ? 1 : 0; if(parameters.cp_cinema){ - cinema_setup_encoder(¶meters,image); + cinema_setup_encoder(¶meters,image,&img_fol); } /* encode the destination image */ diff --git a/libopenjpeg/t2.c b/libopenjpeg/t2.c index 5692a1ec..84d8bee7 100644 --- a/libopenjpeg/t2.c +++ b/libopenjpeg/t2.c @@ -591,6 +591,7 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye int poc; opj_image_t *image = t2->image; opj_cp_t *cp = t2->cp; + opj_tcp_t *tcp = &cp->tcps[tileno]; int pocno = cp->cinema == CINEMA4K_24? 2: 1; int maxcomp = cp->max_comp_size > 0 ? image->numcomps : 1; @@ -645,7 +646,7 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye if (!cstr_info->packno) { info_PK->start_pos = info_TL->end_header + 1; } else { - info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; + info_PK->start_pos = ((cp->tp_on | tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; } info_PK->end_pos = info_PK->start_pos + e - 1; info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c index 8f59caa4..42c07384 100644 --- a/libopenjpeg/tcd.c +++ b/libopenjpeg/tcd.c @@ -1069,11 +1069,12 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre ==> possible to have some lossy layers and the last layer for sure lossless */ if ( ((cp->disto_alloc==1) && (tcd_tcp->rates[layno]>0)) || ((cp->fixed_quality==1) && (tcd_tcp->distoratio[layno]>0))) { opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->image, cp); + double thresh = 0; for (i = 0; i < 32; i++) { - double thresh = (lo + hi) / 2; int l = 0; double distoachieved = 0; /* fixed_quality */ + thresh = (lo + hi) / 2; tcd_makelayer(tcd, layno, thresh, 0); @@ -1117,7 +1118,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre } } success = 1; - goodthresh = stable_thresh; + goodthresh = stable_thresh == 0? thresh : stable_thresh; t2_destroy(t2); } else { success = 1;