Blender V2.61 - r43446

jp2.c

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