Blender  V2.59
jp2.c
Go to the documentation of this file.
00001 /*
00002  *
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * Contributor(s): Campbell Barton
00020  *
00021  * ***** END GPL LICENSE BLOCK *****
00022  */
00023 
00029 #ifdef WITH_OPENJPEG
00030 
00031 #include "MEM_guardedalloc.h"
00032 
00033 #include "BLI_blenlib.h"
00034 #include "BLI_math.h"
00035 
00036 #include "imbuf.h"
00037 
00038 #include "IMB_imbuf_types.h"
00039 #include "IMB_imbuf.h"
00040 #include "IMB_allocimbuf.h"
00041 #include "IMB_filetype.h"
00042 
00043 #include "openjpeg.h"
00044 
00045 #define JP2_FILEHEADER_SIZE 14
00046 
00047 static char JP2_HEAD[]= {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
00048 
00049 /* We only need this because of how the presets are set */
00050 typedef struct img_folder{
00052         char *imgdirpath;
00054         char *out_format;
00056         char set_imgdir;
00058         char set_out_format;
00060         float *rates;
00061 }img_fol_t;
00062 
00063 static int check_jp2(unsigned char *mem) /* J2K_CFMT */
00064 {
00065         return memcmp(JP2_HEAD, mem, 12) ? 0 : 1;
00066 }
00067 
00068 int imb_is_a_jp2(unsigned char *buf)
00069 {       
00070         return check_jp2(buf);
00071 }
00072 
00073 
00077 static void error_callback(const char *msg, void *client_data) {
00078         FILE *stream = (FILE*)client_data;
00079         fprintf(stream, "[ERROR] %s", msg);
00080 }
00084 static void warning_callback(const char *msg, void *client_data) {
00085         FILE *stream = (FILE*)client_data;
00086         fprintf(stream, "[WARNING] %s", msg);
00087 }
00091 static void info_callback(const char *msg, void *client_data) {
00092         (void)client_data;
00093         fprintf(stdout, "[INFO] %s", msg);
00094 }
00095 
00096 
00097 
00098 struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags)
00099 {
00100         struct ImBuf *ibuf = 0;
00101         int use_float = 0; /* for precision higher then 8 use float */
00102         
00103         long signed_offsets[4]= {0, 0, 0, 0};
00104         int float_divs[4]= {1, 1, 1, 1};
00105 
00106         int index;
00107         
00108         int w, h, depth;
00109         
00110         opj_dparameters_t parameters;   /* decompression parameters */
00111         
00112         opj_event_mgr_t event_mgr;              /* event manager */
00113         opj_image_t *image = NULL;
00114         
00115         int i;
00116         
00117         opj_dinfo_t* dinfo = NULL;      /* handle to a decompressor */
00118         opj_cio_t *cio = NULL;
00119 
00120         if (check_jp2(mem) == 0) return(0);
00121 
00122         /* configure the event callbacks (not required) */
00123         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
00124         event_mgr.error_handler = error_callback;
00125         event_mgr.warning_handler = warning_callback;
00126         event_mgr.info_handler = info_callback;
00127 
00128 
00129         /* set decoding parameters to default values */
00130         opj_set_default_decoder_parameters(&parameters);
00131 
00132 
00133         /* JPEG 2000 compressed image data */
00134 
00135         /* get a decoder handle */
00136         dinfo = opj_create_decompress(CODEC_JP2);
00137 
00138         /* catch events using our callbacks and give a local context */
00139         opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
00140 
00141         /* setup the decoder decoding parameters using the current image and user parameters */
00142         opj_setup_decoder(dinfo, &parameters);
00143 
00144         /* open a byte stream */
00145         cio = opj_cio_open((opj_common_ptr)dinfo, mem, size);
00146 
00147         /* decode the stream and fill the image structure */
00148         image = opj_decode(dinfo, cio);
00149         
00150         if(!image) {
00151                 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
00152                 opj_destroy_decompress(dinfo);
00153                 opj_cio_close(cio);
00154                 return NULL;
00155         }
00156 
00157         /* close the byte stream */
00158         opj_cio_close(cio);
00159 
00160 
00161         if((image->numcomps * image->x1 * image->y1) == 0)
00162         {
00163                 fprintf(stderr,"\nError: invalid raw image parameters\n");
00164                 return NULL;
00165         }
00166         
00167         w = image->comps[0].w;
00168         h = image->comps[0].h;
00169         
00170         switch (image->numcomps) {
00171         case 1: /* Greyscale */
00172         case 3: /* Color */
00173                 depth= 24; 
00174                 break;
00175         default: /* 2 or 4 - Greyscale or Color + alpha */
00176                 depth= 32; /* greyscale + alpha */
00177                 break;
00178         }
00179         
00180         
00181         i = image->numcomps;
00182         if (i>4) i= 4;
00183         
00184         while (i) {
00185                 i--;
00186                 
00187                 if (image->comps[i].prec > 8)
00188                         use_float = 1;
00189                 
00190                 if (image->comps[i].sgnd)
00191                         signed_offsets[i]=  1 << (image->comps[i].prec - 1); 
00192                 
00193                 /* only needed for float images but dosnt hurt to calc this */
00194                 float_divs[i]= (1<<image->comps[i].prec)-1;
00195         }
00196         
00197         ibuf= IMB_allocImBuf(w, h, depth, use_float ? IB_rectfloat : IB_rect);
00198         
00199         if (ibuf==NULL) {
00200                 if(dinfo)
00201                         opj_destroy_decompress(dinfo);
00202                 return NULL;
00203         }
00204         
00205         ibuf->ftype = JP2;
00206         
00207         if (use_float) {
00208                 float *rect_float= ibuf->rect_float;
00209 
00210                 if (image->numcomps < 3) {
00211                         /* greyscale 12bits+ */
00212                         for (i = 0; i < w * h; i++, rect_float+=4) {
00213                                 index = w * h - ((i) / (w) + 1) * w + (i) % (w);
00214                                 
00215                                 rect_float[0]= rect_float[1]= rect_float[2]= (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0];
00216                                 
00217                                 if (image->numcomps == 2)
00218                                         rect_float[3]= (image->comps[1].data[index] + signed_offsets[1]) / float_divs[1];
00219                                 else
00220                                         rect_float[3]= 1.0f;
00221                         }
00222                 } else {
00223                         /* rgb or rgba 12bits+ */
00224                         for (i = 0; i < w * h; i++, rect_float+=4) {
00225                                 index = w * h - ((i) / (w) + 1) * w + (i) % (w);
00226                                 
00227                                 rect_float[0]= (float)(image->comps[0].data[index] + signed_offsets[0]) / float_divs[0];
00228                                 rect_float[1]= (float)(image->comps[1].data[index] + signed_offsets[1]) / float_divs[1];
00229                                 rect_float[2]= (float)(image->comps[2].data[index] + signed_offsets[2]) / float_divs[2];
00230                                 
00231                                 if (image->numcomps >= 4)
00232                                         rect_float[3]= (float)(image->comps[3].data[index] + signed_offsets[3]) / float_divs[3];
00233                                 else
00234                                         rect_float[3]= 1.0f;
00235                         }
00236                 }
00237                 
00238         } else {
00239                 unsigned char *rect= (unsigned char *)ibuf->rect;
00240 
00241                 if (image->numcomps < 3) {
00242                         /* greyscale */
00243                         for (i = 0; i < w * h; i++, rect+=4) {
00244                                 index = w * h - ((i) / (w) + 1) * w + (i) % (w);
00245                                 
00246                                 rect[0]= rect[1]= rect[2]= (image->comps[0].data[index] + signed_offsets[0]);
00247                                 
00248                                 if (image->numcomps == 2)
00249                                         rect[3]= image->comps[1].data[index] + signed_offsets[1];
00250                                 else
00251                                         rect[3]= 255;
00252                         }
00253                 } else {
00254                         /* 8bit rgb or rgba */
00255                         for (i = 0; i < w * h; i++, rect+=4) {
00256                                 int index = w * h - ((i) / (w) + 1) * w + (i) % (w);
00257                                 
00258                                 rect[0]= image->comps[0].data[index] + signed_offsets[0];
00259                                 rect[1]= image->comps[1].data[index] + signed_offsets[1];
00260                                 rect[2]= image->comps[2].data[index] + signed_offsets[2];
00261                                 
00262                                 if (image->numcomps >= 4)
00263                                         rect[3]= image->comps[3].data[index] + signed_offsets[3];
00264                                 else
00265                                         rect[3]= 255;
00266                         }
00267                 }
00268         }
00269         
00270         /* free remaining structures */
00271         if(dinfo) {
00272                 opj_destroy_decompress(dinfo);
00273         }
00274         
00275         /* free image data structure */
00276         opj_image_destroy(image);
00277         
00278         if (flags & IB_rect) {
00279                 IMB_rect_from_float(ibuf);
00280         }
00281         
00282         return(ibuf);
00283 }
00284 
00285 //static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
00286 /* prec can be 8, 12, 16 */
00287 
00288 #define UPSAMPLE_8_TO_12(_val) ((_val<<4) | (_val & ((1<<4)-1)))
00289 #define UPSAMPLE_8_TO_16(_val) ((_val<<8)+_val)
00290 
00291 #define DOWNSAMPLE_FLOAT_TO_8BIT(_val)  (_val)<=0.0f?0: ((_val)>=1.0f?255: (int)(255.0f*(_val)))
00292 #define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val)<=0.0f?0: ((_val)>=1.0f?4095: (int)(4095.0f*(_val)))
00293 #define DOWNSAMPLE_FLOAT_TO_16BIT(_val) (_val)<=0.0f?0: ((_val)>=1.0f?65535: (int)(65535.0f*(_val)))
00294 
00295 
00296 /*
00297 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space
00298 
00299         * In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the imager is used
00300         * In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the imager is used
00301 */
00302 
00303 /* ****************************** COPIED FROM image_to_j2k.c */
00304 
00305 /* ----------------------------------------------------------------------- */
00306 #define CINEMA_24_CS 1302083    /*Codestream length for 24fps*/
00307 #define CINEMA_48_CS 651041             /*Codestream length for 48fps*/
00308 #define COMP_24_CS 1041666              /*Maximum size per color component for 2K & 4K @ 24fps*/
00309 #define COMP_48_CS 520833               /*Maximum size per color component for 2K @ 48fps*/
00310 
00311 
00312 static int initialise_4K_poc(opj_poc_t *POC, int numres){
00313         POC[0].tile  = 1; 
00314         POC[0].resno0  = 0; 
00315         POC[0].compno0 = 0;
00316         POC[0].layno1  = 1;
00317         POC[0].resno1  = numres-1;
00318         POC[0].compno1 = 3;
00319         POC[0].prg1 = CPRL;
00320         POC[1].tile  = 1;
00321         POC[1].resno0  = numres-1; 
00322         POC[1].compno0 = 0;
00323         POC[1].layno1  = 1;
00324         POC[1].resno1  = numres;
00325         POC[1].compno1 = 3;
00326         POC[1].prg1 = CPRL;
00327         return 2;
00328 }
00329 
00330 static void cinema_parameters(opj_cparameters_t *parameters){
00331         parameters->tile_size_on = false;
00332         parameters->cp_tdx=1;
00333         parameters->cp_tdy=1;
00334         
00335         /*Tile part*/
00336         parameters->tp_flag = 'C';
00337         parameters->tp_on = 1;
00338 
00339         /*Tile and Image shall be at (0,0)*/
00340         parameters->cp_tx0 = 0;
00341         parameters->cp_ty0 = 0;
00342         parameters->image_offset_x0 = 0;
00343         parameters->image_offset_y0 = 0;
00344 
00345         /*Codeblock size= 32*32*/
00346         parameters->cblockw_init = 32;  
00347         parameters->cblockh_init = 32;
00348         parameters->csty |= 0x01;
00349 
00350         /*The progression order shall be CPRL*/
00351         parameters->prog_order = CPRL;
00352 
00353         /* No ROI */
00354         parameters->roi_compno = -1;
00355 
00356         parameters->subsampling_dx = 1;         parameters->subsampling_dy = 1;
00357 
00358         /* 9-7 transform */
00359         parameters->irreversible = 1;
00360 
00361 }
00362 
00363 static void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){
00364         int i;
00365         float temp_rate;
00366 
00367         switch (parameters->cp_cinema){
00368         case CINEMA2K_24:
00369         case CINEMA2K_48:
00370                 if(parameters->numresolution > 6){
00371                         parameters->numresolution = 6;
00372                 }
00373                 if (!((image->comps[0].w == 2048) || (image->comps[0].h == 1080))){
00374                         fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3 "
00375                                 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
00376                                 image->comps[0].w,image->comps[0].h);
00377                         parameters->cp_rsiz = STD_RSIZ;
00378                 }
00379         break;
00380         
00381         case CINEMA4K_24:
00382                 if(parameters->numresolution < 1){
00383                                 parameters->numresolution = 1;
00384                         }else if(parameters->numresolution > 7){
00385                                 parameters->numresolution = 7;
00386                         }
00387                 if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))){
00388                         fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4" 
00389                                 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
00390                                 image->comps[0].w,image->comps[0].h);
00391                         parameters->cp_rsiz = STD_RSIZ;
00392                 }
00393                 parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
00394                 break;
00395         case OFF:
00396                 /* do nothing */
00397                 break;
00398         }
00399 
00400         switch (parameters->cp_cinema){
00401         case CINEMA2K_24:
00402         case CINEMA4K_24:
00403                 for(i=0 ; i<parameters->tcp_numlayers ; i++){
00404                         temp_rate = 0 ;
00405                         if (img_fol->rates[i]== 0){
00406                                 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ 
00407                                         (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
00408                         }else{
00409                                 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ 
00410                                         (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
00411                                 if (temp_rate > CINEMA_24_CS ){
00412                                         parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ 
00413                                                 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
00414                                 }else{
00415                                         parameters->tcp_rates[i]= img_fol->rates[i];
00416                                 }
00417                         }
00418                 }
00419                 parameters->max_comp_size = COMP_24_CS;
00420                 break;
00421                 
00422         case CINEMA2K_48:
00423                 for(i=0 ; i<parameters->tcp_numlayers ; i++){
00424                         temp_rate = 0 ;
00425                         if (img_fol->rates[i]== 0){
00426                                 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ 
00427                                         (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
00428                         }else{
00429                                 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ 
00430                                         (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
00431                                 if (temp_rate > CINEMA_48_CS ){
00432                                         parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ 
00433                                                 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
00434                                 }else{
00435                                         parameters->tcp_rates[i]= img_fol->rates[i];
00436                                 }
00437                         }
00438                 }
00439                 parameters->max_comp_size = COMP_48_CS;
00440                 break;
00441         case OFF:
00442                 /* do nothing */
00443                 break;
00444         }
00445         parameters->cp_disto_alloc = 1;
00446 }
00447 
00448 
00449 static opj_image_t* ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) {
00450         
00451         unsigned char *rect;
00452         float *rect_float;
00453         
00454         int subsampling_dx = parameters->subsampling_dx;
00455         int subsampling_dy = parameters->subsampling_dy;
00456         
00457 
00458         int i, numcomps, w, h, prec;
00459         int x,y, y_row;
00460         OPJ_COLOR_SPACE color_space;
00461         opj_image_cmptparm_t cmptparm[4];       /* maximum of 4 components */
00462         opj_image_t * image = NULL;
00463         
00464         img_fol_t img_fol; /* only needed for cinema presets */
00465         memset(&img_fol,0,sizeof(img_fol_t));
00466         
00467         if (ibuf->ftype & JP2_CINE) {
00468                 
00469                 if (ibuf->x==4096 || ibuf->y==2160)
00470                         parameters->cp_cinema= CINEMA4K_24;
00471                 else {
00472                         if (ibuf->ftype & JP2_CINE_48FPS) {
00473                                 parameters->cp_cinema= CINEMA2K_48;
00474                         }
00475                         else {
00476                                 parameters->cp_cinema= CINEMA2K_24;
00477                         }
00478                 }
00479                 if (parameters->cp_cinema){
00480                         img_fol.rates = (float*)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates");
00481                         for(i=0; i< parameters->tcp_numlayers; i++){
00482                                 img_fol.rates[i] = parameters->tcp_rates[i];
00483                         }
00484                         cinema_parameters(parameters);
00485                 }
00486                 
00487                 color_space= CLRSPC_SYCC;
00488                 prec= 12;
00489                 numcomps= 3;
00490         }
00491         else { 
00492                 /* Get settings from the imbuf */
00493                 color_space = (ibuf->ftype & JP2_YCC) ? CLRSPC_SYCC : CLRSPC_SRGB;
00494                 
00495                 if (ibuf->ftype & JP2_16BIT)            prec= 16;
00496                 else if (ibuf->ftype & JP2_12BIT)       prec= 12;
00497                 else                                            prec= 8;
00498                 
00499                 /* 32bit images == alpha channel */
00500                 /* grayscale not supported yet */
00501                 numcomps= (ibuf->depth==32) ? 4 : 3;
00502         }
00503         
00504         w= ibuf->x;
00505         h= ibuf->y;
00506         
00507         
00508         /* initialize image components */
00509         memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
00510         for(i = 0; i < numcomps; i++) {
00511                 cmptparm[i].prec = prec;
00512                 cmptparm[i].bpp = prec;
00513                 cmptparm[i].sgnd = 0;
00514                 cmptparm[i].dx = subsampling_dx;
00515                 cmptparm[i].dy = subsampling_dy;
00516                 cmptparm[i].w = w;
00517                 cmptparm[i].h = h;
00518         }
00519         /* create the image */
00520         image = opj_image_create(numcomps, &cmptparm[0], color_space);
00521         if(!image) {
00522                 printf("Error: opj_image_create() failed\n");
00523                 return NULL;
00524         }
00525 
00526         /* set image offset and reference grid */
00527         image->x0 = parameters->image_offset_x0;
00528         image->y0 = parameters->image_offset_y0;
00529         image->x1 = parameters->image_offset_x0 + (w - 1) *     subsampling_dx + 1;
00530         image->y1 = parameters->image_offset_y0 + (h - 1) *     subsampling_dy + 1;
00531         
00532         /* set image data */
00533         rect = (unsigned char*) ibuf->rect;
00534         rect_float= ibuf->rect_float;
00535         
00536         if (rect_float && rect && prec==8) {
00537                 /* No need to use the floating point buffer, just write the 8 bits from the char buffer */
00538                 rect_float= NULL;
00539         }
00540         
00541         
00542         if (rect_float) {
00543                 float rgb[3];
00544                 
00545                 switch (prec) {
00546                 case 8: /* Convert blenders float color channels to 8,12 or 16bit ints */
00547                         for(y=h-1; y>=0; y--) {
00548                                 y_row = y*w;
00549                                 for(x=0; x<w; x++, rect_float+=4) {
00550                                         i = y_row + x;
00551                                         
00552                                         if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
00553                                                 linearrgb_to_srgb_v3_v3(rgb, rect_float);
00554                                         else
00555                                                 copy_v3_v3(rgb, rect_float);
00556                                 
00557                                         image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[0]);
00558                                         image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[1]);
00559                                         image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[2]);
00560                                         if (numcomps>3)
00561                                                 image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]);
00562                                 }
00563                         }
00564                         break;
00565                         
00566                 case 12:
00567                         for(y=h-1; y>=0; y--) {
00568                                 y_row = y*w;
00569                                 for(x=0; x<w; x++, rect_float+=4) {
00570                                         i = y_row + x;
00571                                         
00572                                         if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
00573                                                 linearrgb_to_srgb_v3_v3(rgb, rect_float);
00574                                         else
00575                                                 copy_v3_v3(rgb, rect_float);
00576                                 
00577                                         image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[0]);
00578                                         image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[1]);
00579                                         image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[2]);
00580                                         if (numcomps>3)
00581                                                 image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]);
00582                                 }
00583                         }
00584                         break;
00585                 case 16:
00586                         for(y=h-1; y>=0; y--) {
00587                                 y_row = y*w;
00588                                 for(x=0; x<w; x++, rect_float+=4) {
00589                                         i = y_row + x;
00590                                         
00591                                         if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
00592                                                 linearrgb_to_srgb_v3_v3(rgb, rect_float);
00593                                         else
00594                                                 copy_v3_v3(rgb, rect_float);
00595                                 
00596                                         image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[0]);
00597                                         image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[1]);
00598                                         image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[2]);
00599                                         if (numcomps>3)
00600                                                 image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]);
00601                                 }
00602                         }
00603                         break;
00604                 }
00605         } else {
00606                 /* just use rect*/
00607                 switch (prec) {
00608                 case 8:
00609                         for(y=h-1; y>=0; y--) {
00610                                 y_row = y*w;
00611                                 for(x=0; x<w; x++, rect+=4) {
00612                                         i = y_row + x;
00613                                 
00614                                         image->comps[0].data[i] = rect[0];
00615                                         image->comps[1].data[i] = rect[1];
00616                                         image->comps[2].data[i] = rect[2];
00617                                         if (numcomps>3)
00618                                                 image->comps[3].data[i] = rect[3];
00619                                 }
00620                         }
00621                         break;
00622                         
00623                 case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */
00624                         for(y=h-1; y>=0; y--) {
00625                                 y_row = y*w;
00626                                 for(x=0; x<w; x++, rect+=4) {
00627                                         i = y_row + x;
00628                                 
00629                                         image->comps[0].data[i]= UPSAMPLE_8_TO_12(rect[0]);
00630                                         image->comps[1].data[i]= UPSAMPLE_8_TO_12(rect[1]);
00631                                         image->comps[2].data[i]= UPSAMPLE_8_TO_12(rect[2]);
00632                                         if (numcomps>3)
00633                                                 image->comps[3].data[i]= UPSAMPLE_8_TO_12(rect[3]);
00634                                 }
00635                         }
00636                         break;
00637                 case 16:
00638                         for(y=h-1; y>=0; y--) {
00639                                 y_row = y*w;
00640                                 for(x=0; x<w; x++, rect+=4) {
00641                                         i = y_row + x;
00642                                 
00643                                         image->comps[0].data[i]= UPSAMPLE_8_TO_16(rect[0]);
00644                                         image->comps[1].data[i]= UPSAMPLE_8_TO_16(rect[1]);
00645                                         image->comps[2].data[i]= UPSAMPLE_8_TO_16(rect[2]);
00646                                         if (numcomps>3)
00647                                                 image->comps[3].data[i]= UPSAMPLE_8_TO_16(rect[3]);
00648                                 }
00649                         }
00650                         break;
00651                 }
00652         }
00653         
00654         /* Decide if MCT should be used */
00655         parameters->tcp_mct = image->numcomps == 3 ? 1 : 0;
00656         
00657         if(parameters->cp_cinema){
00658                 cinema_setup_encoder(parameters,image,&img_fol);
00659         }
00660         
00661         if (img_fol.rates)
00662                 MEM_freeN(img_fol.rates);
00663         
00664         return image;
00665 }
00666 
00667 
00668 /* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */
00669 int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) {
00670         
00671         int quality = ibuf->ftype & 0xff;
00672         
00673         int bSuccess;
00674         opj_cparameters_t parameters;   /* compression parameters */
00675         opj_event_mgr_t event_mgr;              /* event manager */
00676         opj_image_t *image = NULL;
00677         
00678         (void)flags; /* unused */
00679         
00680         /*
00681         configure the event callbacks (not required)
00682         setting of each callback is optionnal
00683         */
00684         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
00685         event_mgr.error_handler = error_callback;
00686         event_mgr.warning_handler = warning_callback;
00687         event_mgr.info_handler = info_callback;
00688         
00689         /* set encoding parameters to default values */
00690         opj_set_default_encoder_parameters(&parameters);
00691         
00692         /* compression ratio */
00693         /* invert range, from 10-100, 100-1
00694         * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/
00695         parameters.tcp_rates[0]= ((100-quality)/90.0f*99.0f) + 1;
00696 
00697         
00698         parameters.tcp_numlayers = 1; // only one resolution
00699         parameters.cp_disto_alloc = 1;
00700 
00701         image= ibuftoimage(ibuf, &parameters);
00702         
00703         
00704         {                       /* JP2 format output */
00705                 int codestream_length;
00706                 opj_cio_t *cio = NULL;
00707                 FILE *f = NULL;
00708 
00709                 /* get a JP2 compressor handle */
00710                 opj_cinfo_t* cinfo = opj_create_compress(CODEC_JP2);
00711 
00712                 /* catch events using our callbacks and give a local context */
00713                 opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);                   
00714 
00715                 /* setup the encoder parameters using the current image and using user parameters */
00716                 opj_setup_encoder(cinfo, &parameters, image);
00717 
00718                 /* open a byte stream for writing */
00719                 /* allocate memory for all tiles */
00720                 cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
00721 
00722                 /* encode the image */
00723                 bSuccess = opj_encode(cinfo, cio, image, NULL); /* last arg used to be parameters.index but this deprecated */
00724                 
00725                 if (!bSuccess) {
00726                         opj_cio_close(cio);
00727                         fprintf(stderr, "failed to encode image\n");
00728                         return 0;
00729                 }
00730                 codestream_length = cio_tell(cio);
00731 
00732                 /* write the buffer to disk */
00733                 f = fopen(name, "wb");
00734                 
00735                 if (!f) {
00736                         fprintf(stderr, "failed to open %s for writing\n", name);
00737                         return 1;
00738                 }
00739                 fwrite(cio->buffer, 1, codestream_length, f);
00740                 fclose(f);
00741                 fprintf(stderr,"Generated outfile %s\n",name);
00742                 /* close and free the byte stream */
00743                 opj_cio_close(cio);
00744                 
00745                 /* free remaining compression structures */
00746                 opj_destroy_compress(cinfo);
00747         }
00748 
00749         /* free image data */
00750         opj_image_destroy(image);
00751         
00752         return 1;
00753 }
00754 
00755 #endif /* WITH_OPENJPEG */