00001 
00032 #include "linden_common.h"
00033 #include "llimagej2coj.h"
00034 
00035 
00036 #include "openjpeg/openjpeg.h"
00037 
00038 #include "lltimer.h"
00039 #include "llmemory.h"
00040 
00041 const char* fallbackEngineInfoLLImageJ2CImpl()
00042 {
00043         return (std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
00044                 + opj_version()).c_str();
00045 }
00046 
00047 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
00048 {
00049         return new LLImageJ2COJ();
00050 }
00051 
00052 void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
00053 {
00054         delete impl;
00055         impl = NULL;
00056 }
00057 
00061 void error_callback(const char* msg, void*)
00062 {
00063         lldebugs << "LLImageJ2CImpl error_callback: " << msg << llendl;
00064 }
00068 void warning_callback(const char* msg, void*)
00069 {
00070         lldebugs << "LLImageJ2CImpl warning_callback: " << msg << llendl;
00071 }
00075 void info_callback(const char* msg, void*)
00076 {
00077         lldebugs << "LLImageJ2CImpl info_callback: " << msg << llendl;
00078 }
00079 
00080 
00081 LLImageJ2COJ::LLImageJ2COJ() : LLImageJ2CImpl()
00082 {
00083 }
00084 
00085 
00086 LLImageJ2COJ::~LLImageJ2COJ()
00087 {
00088 }
00089 
00090 
00091 BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
00092 {
00093         
00094         
00095         
00096 
00097         LLTimer decode_timer;
00098 
00099         opj_dparameters_t parameters;   
00100         opj_event_mgr_t event_mgr;              
00101         opj_image_t *image = NULL;
00102 
00103         opj_dinfo_t* dinfo = NULL;      
00104         opj_cio_t *cio = NULL;
00105 
00106 
00107         
00108         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
00109         event_mgr.error_handler = error_callback;
00110         event_mgr.warning_handler = warning_callback;
00111         event_mgr.info_handler = info_callback;
00112 
00113         
00114         opj_set_default_decoder_parameters(¶meters);
00115 
00116         parameters.cp_reduce = base.getRawDiscardLevel();
00117 
00118         
00119         
00120 
00121         
00122 
00123         
00124         dinfo = opj_create_decompress(CODEC_J2K);
00125 
00126         
00127         opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);                   
00128 
00129         
00130         opj_setup_decoder(dinfo, ¶meters);
00131 
00132         
00133         cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
00134 
00135         
00136         image = opj_decode(dinfo, cio);
00137 
00138         
00139         opj_cio_close(cio);
00140 
00141         
00142         if(dinfo)
00143         {
00144                 opj_destroy_decompress(dinfo);
00145         }
00146 
00147         
00148         
00149         
00150         if(!image || !image->numcomps)
00151         {
00152                 fprintf(stderr, "ERROR -> decodeImpl: failed to decode image!\n");
00153                 if (image)
00154                         opj_image_destroy(image);
00155 
00156                 return TRUE; 
00157         }
00158 
00159         
00160 
00161         S32 img_components = image->numcomps;
00162         S32 channels = img_components - first_channel;
00163         if( channels > max_channel_count )
00164                 channels = max_channel_count;
00165 
00166         
00167         
00168         
00169         
00170         
00171         
00172         
00173         S32 comp_width = image->comps[0].w;
00174         S32 f=image->comps[0].factor;
00175         S32 width = ceildivpow2(image->x1 - image->x0, f);
00176         S32 height = ceildivpow2(image->y1 - image->y0, f);
00177         raw_image.resize(width, height, channels);
00178         U8 *rawp = raw_image.getData();
00179 
00180         
00181         
00182         
00183         for (S32 comp = first_channel, dest=0; comp < first_channel + channels;
00184                 comp++, dest++)
00185         {
00186                 S32 offset = dest;
00187                 for (S32 y = (height - 1); y >= 0; y--)
00188                 {
00189                         for (S32 x = 0; x < width; x++)
00190                         {
00191                                 rawp[offset] = image->comps[comp].data[y*comp_width + x];
00192                                 offset += channels;
00193                         }
00194                 }
00195         }
00196 
00197         
00198         opj_image_destroy(image);
00199 
00200         return TRUE; 
00201 }
00202 
00203 
00204 BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
00205 {
00206         const S32 MAX_COMPS = 5;
00207         opj_cparameters_t parameters;   
00208         opj_event_mgr_t event_mgr;              
00209 
00210 
00211         
00212 
00213 
00214 
00215         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
00216         event_mgr.error_handler = error_callback;
00217         event_mgr.warning_handler = warning_callback;
00218         event_mgr.info_handler = info_callback;
00219 
00220         
00221         opj_set_default_encoder_parameters(¶meters);
00222         parameters.tcp_rates[0] = 0;
00223         parameters.tcp_numlayers++;
00224         parameters.cp_disto_alloc = 1;
00225         parameters.cod_format = 0;
00226         if (!comment_text)
00227         {
00228                 parameters.cp_comment = "";
00229         }
00230         else
00231         {
00232                 
00233                 parameters.cp_comment = (char *)comment_text;
00234         }
00235 
00236         
00237         
00238         
00239         OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
00240         opj_image_cmptparm_t cmptparm[MAX_COMPS];
00241         opj_image_t * image = NULL;
00242         S32 numcomps = raw_image.getComponents();
00243         S32 width = raw_image.getWidth();
00244         S32 height = raw_image.getHeight();
00245 
00246         memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t));
00247         for(S32 c = 0; c < numcomps; c++) {
00248                 cmptparm[c].prec = 8;
00249                 cmptparm[c].bpp = 8;
00250                 cmptparm[c].sgnd = 0;
00251                 cmptparm[c].dx = parameters.subsampling_dx;
00252                 cmptparm[c].dy = parameters.subsampling_dy;
00253                 cmptparm[c].w = width;
00254                 cmptparm[c].h = height;
00255         }
00256 
00257         
00258         image = opj_image_create(numcomps, &cmptparm[0], color_space);
00259 
00260         image->x1 = width;
00261         image->y1 = height;
00262 
00263         S32 i = 0;
00264         const U8 *src_datap = raw_image.getData();
00265         for (S32 y = height - 1; y >= 0; y--)
00266         {
00267                 for (S32 x = 0; x < width; x++)
00268                 {
00269                         const U8 *pixel = src_datap + (y*width + x) * numcomps;
00270                         for (S32 c = 0; c < numcomps; c++)
00271                         {
00272                                 image->comps[c].data[i] = *pixel;
00273                                 pixel++;
00274                         }
00275                         i++;
00276                 }
00277         }
00278 
00279 
00280 
00281         
00282         
00283 
00284         int codestream_length;
00285         opj_cio_t *cio = NULL;
00286 
00287         
00288         opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
00289 
00290         
00291         opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);                   
00292 
00293         
00294         opj_setup_encoder(cinfo, ¶meters, image);
00295 
00296         
00297         
00298         cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
00299 
00300         
00301         bool bSuccess = opj_encode(cinfo, cio, image, parameters.index);
00302         if (!bSuccess)
00303         {
00304                 opj_cio_close(cio);
00305                 llinfos << "Failed to encode image." << llendl;
00306                 return FALSE;
00307         }
00308         codestream_length = cio_tell(cio);
00309 
00310         base.copyData(cio->buffer, codestream_length);
00311         base.updateData(); 
00312 
00313         
00314         opj_cio_close(cio);
00315 
00316         
00317         opj_destroy_compress(cinfo);
00318 
00319 
00320         
00321         if(parameters.cp_matrice) free(parameters.cp_matrice);
00322 
00323         
00324         opj_image_destroy(image);
00325         return TRUE;
00326 }
00327 
00328 BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
00329 {
00330         
00331         
00332         
00333 
00334         
00335         base.updateRawDiscardLevel();
00336 
00337         opj_dparameters_t parameters;   
00338         opj_event_mgr_t event_mgr;              
00339         opj_image_t *image = NULL;
00340 
00341         opj_dinfo_t* dinfo = NULL;      
00342         opj_cio_t *cio = NULL;
00343 
00344 
00345         
00346         memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
00347         event_mgr.error_handler = error_callback;
00348         event_mgr.warning_handler = warning_callback;
00349         event_mgr.info_handler = info_callback;
00350 
00351         
00352         opj_set_default_decoder_parameters(¶meters);
00353 
00354         
00355         parameters.cp_limit_decoding=LIMIT_TO_MAIN_HEADER;
00356 
00357         
00358 
00359         
00360         
00361 
00362         
00363 
00364         
00365         dinfo = opj_create_decompress(CODEC_J2K);
00366 
00367         
00368         opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);                   
00369 
00370         
00371         opj_setup_decoder(dinfo, ¶meters);
00372 
00373         
00374         cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
00375 
00376         
00377         image = opj_decode(dinfo, cio);
00378 
00379         
00380         opj_cio_close(cio);
00381 
00382         
00383         if(dinfo)
00384         {
00385                 opj_destroy_decompress(dinfo);
00386         }
00387 
00388         if(!image)
00389         {
00390                 fprintf(stderr, "ERROR -> getMetadata: failed to decode image!\n");
00391                 return FALSE;
00392         }
00393 
00394         
00395         S32 width = 0;
00396         S32 height = 0;
00397 
00398         S32 img_components = image->numcomps;
00399         width = image->x1 - image->x0;
00400         height = image->y1 - image->y0;
00401         base.setSize(width, height, img_components);
00402 
00403         
00404         opj_image_destroy(image);
00405         return TRUE;
00406 }