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