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 }